ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C] 변수 유효범위①
    C 2023. 4. 26. 11:51

     

     

    01 전역변수와 지역 변수


     

     

    변수 범위와 지역변수

     

    • 변수의 유효 범위(scope)
      • 선언된 변수가 사용될 수 있는 범위
      • 지역 유효 범위(local scope)와 전역 유효 범위(global scope)로 나눔

     

    • 지역 유효 범위
      • 함수 또는 블복 내부에서 선언된 변수는 선언된 이후의 함수나 블록에서 사용

     

    • 전역 유효 범위
      • 프로젝트나 파일에서 사용 가능한 범위
      • 하나의 파일에서만 변수의 참조가 가능할 수 있으며
      • 또는 프로젝트를 구성하는 모든 파일에서 변수의 참조가 가능

     

    • 전역변수
      • 전체 전역변수 : 프로젝트의 모든 파일에서 사용 가능한 변수
      • 파일 전역변수 : 선언된 파일에서만 사용 가능한 변수

     

    • 지역변수 
      • 함수 : 선언된 함수 내부에서 사용 가능한 변수
      • 블록 : 선언된 블록 내부에서 사용 가능한 변수

     


     

    지역과 전역

     

    • 프로젝트 : 파일 main.c 그리고 파일 sub1.c와 sub2.c, 3개의 소스 파일로 구성

     

    • 지역변수
      • 파일 main.c의 함수 asub()에서 선언된 변수 n은 함수 내부에서만 사용
      • 모든 함수 내부에서 선언된 변수는 모두 지역 변수

     

    • 전체 전역변수
      • 파일 main.c의 상단에 선언된 gdata는 프로젝트 전체 파일에서 사용
      • gdata를 파일 sub1.c에서 사용하려면 먼저 extern int gdata로 선언이 필요

     

    • 파일 전역변수
      • 파일 sub2.c의 svar는 파일 sub2.c에서만 사용
    파일 main.c
    
    # 전역변수 선언(전체 범위)
    int gdata;
    
    int main(void)
    {
    
    }
    
    void asub()
    {
    	int n; # 지역변수
    }
    
    void bsub()
    {
    
    }
    파일 sub1.c
    
    # 전역변수 사용 선언 
    extern int gdata;
    
    int sub1(void)
    {
    
    }
    
    void asub1()
    {
    	
    }
    
    void bsub1()
    {
    
    }
    파일 sub2.c
    
    # 전역변수 선언(파일 범위) 
    static int svar;
    
    int sub2(void)
    {
    
    }
    
    void asub2()
    {
    	
    }
    
    void bsub2()
    {
    
    }

     


     

    지역변수는 함수 또는 블록에서 선언된 변수

     

    • 지역변수는 내부변수 또는 자동변수(automatic variables)라고도 부름
      • 선언 문장 이후에 함수나 블록의 내부에서만 사용이 가능
      • 함수의 매개변수도 함수 전체에서 사용 가능한 지역변수
      • 선언 후 초기화하지 않으면 쓰레기 값이 저장되므로 주의
      • 할당되는 메모리 영역을 스택(stack)
      • 선언된 부분에서 자동으로 생성되고 함수나 블록이 종료되는 순간 메모리에서 자동으로 제거 이러한 이유로 지역변수는 자동변수(automatic variables)
      • 지역변수 선언에서 자료형 앞에 키워드 auto가 사용 가능
      • 키워드 aoto는 생략 가능해 일반적으로 auto가 없는 경우가 대부분
    int main(void) {
    	
    	int n = 10;		# 지역변수 선언
    
    	for (int m = 0, sum = 0; m < 3; m++)	# m, sum은 for문 내부의 블록 지역변수
    	{
    		sum += m;
    		printf("%d %d\n", m, sum);
    	}
    
    	printf("%d %d", n, sum);	# 오류 발생: error C2065: 'sum': 선언되지 않은 식별자입니다.
    
    	return 0;
    }

     


     

    지역변수 선언과 사용

     

    • for 문 블록에서 선언된 지역변수 m, sum
      • for 문 블록에서만 사용이 가능
      • 블록 외부에서 참조가 불가능

     

    • 매개변수 param
      • 함수 sub()내부에서 모두 사용 가능

     

    #include <stdio.h>
    
    void sub(int param); # 함수 원형
    
    int main(void) {
    
    	auto int n = 10;  # 지역변수 선언
    	printf("%d\n", n);
    
        for (int m = 0, sum = 0; m < 3; m++)  # m, sum은 for 문 내부의 블록 지역변수
    	{
    		sum += m;
    		printf("\t%d %d\n", m, sum);
    	}
    
    	printf("%d\n", n);  # n 참조 가능
    	// printf("%d %d", n, sum);  # m, sum 참조 불가능
        
        sub(20);  # 함수호출
    
    	return 0;
    }
    
    void sub(int param)  # 매개변수인 param도 지역변수로 사용
    {
    	auto int local = 100;  # 지역변수 local
    	printf("\t%d %d\n", param, local);  # param과 local 참조 가능
    	// printf("%d\n", n);  # n 참조 불가능
    }
    10
            0  0
            1  1
            2  3
    10
         	20 100

     


     

    전역변수(global variable)

    • 함수 외부에서 선언되는 변수
      • 전역변수는 외부변수라고도 부름
      • 모든 함수나 블록에서 참조 가능
      • 초기 값이 자료형에 맞는 0으로 저장
      • 함수나 블록에서 전역변수와 같은 이름으로 지역변수를 선언 가능
      • 함수 내부나 블록에서 그 이름을 참조하면 지역변수로 인식

     

    • 프로젝트의 다른 파일에서도 참조가 가능
      • 키워드 extern을 사용하여 이미 다른 파일에서 선언된 전역변수임을 선언
      • 이미 존재하는 전역변수의 유효 범위를 확장

     

    # file: globalvar.c
    
    # 전역변수 선언
    double PI = 3.14;
    
    int main(void) {    # 전역변수 PI 변수 범위
    
        # 지역변수 선언
        double r = 5.87;
        # 전역변수 PI와 같은 이름의 지역변수 선언
        const double PI = 3.141592;
    	
        # 지역변수 PI 변수 범위
        printf("PI: %f\n", PI);  # 지역변수 PI 참조
    
        return 0;
    }
    
    double getArea(double r)
    {
        return r * r * PI;	# 전역변수 PI 참조
    }
    # circumference.c
    
    # 이미 선언된 전역변수 선언
    extern double PI;
    
    double getCircum(double r)	# 전역변수 PI 변수 범위
    {
        return 2 * r * PI;
    }

     


     

    전역변수와 지역변수의 선언과 사용

    #include <stdio.h>
    
    double getArea(double);
    double getCircum(double);
    
    # 전역변수 선언
    double PI = 3.14;
    int gi;
    
    int main(void) {
        
        # 지역변수 선언
        double r = 5.87;
        # 전역변수 PI와 같은 이름의 지역변수 선언
        const double PI = 3.141592;
    
        printf("면적: %.2f\n", getArea(r));
        printf("둘레1: %.2f\n", 2 * PI * r);
        printf("둘레2: %.2f\n", getCircum(r));
        printf("PI: %f\n", PI);	# 지역변수 PI 참조
        printf("gi: %d\n", gi);	# 전역변수 gi 기본값
    
        return 0;
    }
    
    double getArea(double) 
    {
        return r * r * PI;	# 전역변수 PI 참조
    }
    # 이미 외부에서 선언된 전역변수임을 알리는 선언
    extern double PI;
    
    double getCircum(double) 
    {
        // extern double PI;	# 함수 내부에서만 참조 가능
        return 2 * r * PI;	# 전역변수 PI 참조
    }
    면적: 108.19
    둘레1: 36.88
    둘레2: 36.86
    PI: 3.141592
    gi: 0	# 전역변수 gi는 초기값이 저장되지 않았으나 자동으로 0이 저장됨.

     


     

    1~100 사이의 난수를 알아 맞히는 프로그램을 두 파일로 구현

     

    • 전역변수 guess
      • 시스템이 정한 정답이 저장되는 전역변수
      • 파일 lab1numguess.c에서 선언
      • 파일 lab2testnum.c에서도 사용

     

    • 지역변수 input
      • 입력한 정수가 저장되는 함수 main()의 지역변수

     

    lab1numguess.c
    
    #include <stdio.h>
    #include <stdlib.h>	# rand(), srand()를 위한 헤더파일 포함
    #include <time.h>	# time()을 위한 헤더파일 포함
    
    #define MAX 100
    
    int guess;	# 정답인 전역변수 선언
    
    int main(void) {
    
    	int input;	# 지역변수 선언
    
    	srand((long)time(NULL));
    	guess = rand() % MAX + 1;	# 정답 지정
    
    	printf("1에서 %d 사이에서 한 정수가 결정되었습니다.\n", MAX);
    	printf("이 정수는 무엇일까요? 입력해 부세요. : ");
    
    	while (scanf("%d", &input)) {
    		switch (testNum(input)) {
    		case 0:
    			puts("정답입니다.");
    			break;
    		case -1:
    			printf("입력한 수보다 작습니다. 다시 입력하세요. : ");
    			break;
    		case 1:
    			printf("입력한 수보다 큼니다.. 다시 입력하세요. : ");
    			break;
    		}
    	}
    
    	return 0;
    }
    lab2testnum.c
    
    int testNum(int input)
    {
    	# 전역변수 선언
    	extern int guess;	# 다른 파일에서 선언된 전역변수 guess를 선언하여 사용
    
    	int result = 0;
    	if (input > guess) result = -1;
    	else if (input < guess) result = 1;
    	else result = 0;
    
    	return result;
    }
    1에서 100 사이에서 한 정수가 결정되었습니다.
    이 정수는 무엇일까요? 입력해 부세요. : 50
    입력한 수보다 작습니다. 다시 입력하세요. : 25
    입력한 수보다 작습니다. 다시 입력하세요. : 13
    입력한 수보다 작습니다. 다시 입력하세요. : 7
    입력한 수보다 큼니다.. 다시 입력하세요. : 10
    입력한 수보다 큼니다.. 다시 입력하세요. : 11
    정답입니다.

     

     

     

    'C' 카테고리의 다른 글

    [C] 포인터①  (1) 2023.05.04
    [C] 변수 유효범위②  (0) 2023.05.02
    [C] 재귀함수와 라이브러리 함수  (0) 2023.04.13
    [C] 함수  (0) 2023.04.13
    [C] 배열②  (0) 2023.04.11
Designed by Tistory.