-
[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 - 변수의 유효 범위(scope)