70. 전역 변수(Global Variable)
1. 키워드
- 전역 변수(Global Variable)
- 변수 범위(Scope)
2. 전역 변수 사용하기
- 지금까지 함수 안에서 선언하는 지역 변수를 사용했다.
- 지역 변수는 선언된 함수 안에서만 사용할 수 있고 다른 함수에서는 사용할 수 없다.
- 왜냐하면 C는 범위에 따라 변수의 접근을 제한하기 때문이다.
- 따라서 지역 변수는 함수 안에서만 유효하다.
- 여기서 함수 범위는
{}
(중괄호) 사이를 말한다.
- 어떤 변수를 프로그램 전체에서 공유해야 할 때는 전역 변수를 쓰는데, 전역 변수는 범위에 제한을 받지 않고 모든 범위에서 사용할 수 있는 변수를 말한다.
3. 변수의 범위 알아보기
- C에서
{}
로 묶은 부분을 블록이라 부른다. - 즉,
if
,for
,switch
,while
,do while
, 함수에 사용한{}
가 블록이다. - 그냥
{}
만으로 이루어진 것도 블록이다. - 단, 배열, 구조체, 공용체 등을 초기화할 때 사용하는
{}
는 블록이 아니다.
- 이제 블록 안에 변수를 선언해 보자.
#include <stdio.h>
int main()
{
{
int num1 = 10; // 블록 안에 변수를 선언
}
printf("%d\n", num1); // 컴파일 에러. 블록 바깥에서는 num1을 사용할 수 없음
return 0;
}
- 소스 코드를 컴파일해 보면 컴파일 에러가 발생한다.
- 먼저 변수
num1
은{}
로 묶인 블록 안에 선언되어 있다. - 이때 블록 밖에서
num1
을 사용하려고 하면 변수를 찾을 수 없기 때문에 컴파일 에러가 발생한다. - 즉, 변수는 선언된 블록(영역) 안에서만 사용(접근)할 수 있으며 이를 변수의 범위라고 한다.
- 그럼 이번에는
main
함수에 변수를 선언하고 중첩된 블록 안에서 사용해 보자.
#include <stdio.h>
int main()
{
int num1 = 10; // main 함수 블록에 변수 선언
{
printf("%d\n", num1); // 10: 현재 블록 바깥의 변수는 사용할 수 있음
}
return 0;
}
// 10
- 컴파일도 문제없고 실행을 해보면 변수
num1
의 값이 잘 나온다. - 여기서 변수
num1
은main
함수 블록에 선언되어 있고,printf
가 있는 블록도 실제로는main
블록 안에 있다. - 따라서 변수가 선언된 블록 안에서 사용하는 것이 되므로 문제가 없다.
- 변수를 사용하는 입장에서 본다면 현재 블록 바깥에 선언된 변수를 사용할 수 있다는 뜻이 된다.
- 정리하자면 변수는 선언된 블록에 따라 사용할 수 있는 범위가 결정된다.
- 즉, 변수는 선언된 블록 안에서만 사용할 수 있고 블록 바깥에서는 사용할 수 없다.
4. 전역 변수 선언하기
- 이제 전역 변수를 선언해 보자.
- 전역 변수는 함수 바깥에서 선언한다.
#include <stdio.h>
int num1 = 10; // 전역 변수 선언 및 값 초기화
void printGlobal()
{
printf("%d\n", num1); // main 함수에서 저장한 값이 계속 유지됨
}
int main()
{
printf("%d\n", num1); // main 함수에서 전역 변수 num1의 값 출력
num1 = 20; // 전역 변수 num1에 20 저장
printGlobal(); // printGlobal 함수에서 전역 변수 num1의 값 출력
return 0;
}
// 10
// 20
#include
아래에int num1 = 10;
과 같이 변수가 선언되어 있다.- 이처럼 전역 변수는 함수 안이 아닌 함수 바깥에 선언한다.
num1
은 함수 블록 바깥에 선언되어 있으므로 모든 함수에서 값을 가져오거나 저장할 수 있다.- 또한, 파일 자체에 변수가 선언되어 있으므로 변수의 범위는 파일 범위이다.
- 이제 각 함수에서 전역 변수
num1
을 사용해 보자. - 먼저
main
함수에서num1
의 값을 출력해 보면10
이 나온다. - 그리고
num1
에20
을 저장한다.
printGlobal
함수에서num1
의 값을 출력해 보면main
함수에서 저장한20
이 출력된다.
- 즉, 전역 변수는 모든 함수에서 접근할 수 있으며 한 번 저장한 값이 계속 유지된다.
- 이번에는 전역 변수의 초깃값에 대해 알아보자.
#include <stdio.h>
int num1; // 전역 변수는 초깃값을 지정하지 않으면 0으로 초기화됨
int main()
{
printf("%d\n", num1);
return 0;
}
// 0
- 전역 변수는 초깃값을 지정하지 않으면
0
으로 초기화된다. - 이 부분은 초깃값을 지정하지 않으면 쓰레기 값이 들어가는 지역 변수와는 다른 점이다.
- 그리고 전역 변수는 프로그램이 시작될 때 생성 및 초기화되고 프로그램이 끝날 때 사라진다.
전역 변수 사용 시 주의할 점
- 전역 변수는 반환값이나 매개변수를 통하지 않고 손쉽게 사용할 수 있어서 모든 변수를 전역 변수로 선언하면 좋을 것 같지만 사실 좋은 방법이 아니다.
- 전역 변수는 꼭 필요한 부분에만 사용해야 하며 전역 변수를 무분별하게 사용했을 때 발생하는 문제점은 다음과 같다.
1] 프로그램이 커지다 보면 어떤 함수가 전역 변수의 값을 바꾸는지 알기 어려워지므로 유지보수도 힘들어지고 눈에 잘 띄지 않는 버그가 생기기 쉽다.
2] 지역 변수와 전역 변수의 이름이 겹칠 가능성이 커지고 의도하지 않은 결과가 나올 수 있으며 지역 변수와 전역 변수의 이름이 같을 때는 현재 블록의 변수를 우선으로 접근한다.
헝가리안 표기법과 전역 변수
- Windows API를 사용한 소스 코드에서 헝가리안 표기법을 자주 볼 수 있다.
- 변수의 이름에 자료형이나 주요 정보를 접두어로 함께 표기하는 방식이다.
- 특히 전역 변수는
g_num1
과 같이 앞에g_
를 붙인다. - 하지만 최근에는 개발 도구 편집기의 기능이 좋아진 점도 있어서 헝가리안 표기법을 잘 사용하지 않는 추세이다.
5. extern
으로 다른 소스 파일의 전역 변수 사용하기
- 이번에는 소스 파일이 여러 개로 분리되어 있을 때 전역 변수를 사용하는 방법이다.
print.c
소스 파일을 다음과 같이 작성해 보자.
- 이번에는
main
함수가 있는main.c
소스 파일이다.
main
함수에서 전역 변수num1
의 값을 출력하고 있다.- 하지만 컴파일을 해보면
num1
이 선언되지 않은 식별자라고 나온다.
- 다른 소스 파일(외부)에 선언된 전역 변수를 사용할 때는
extern
키워드를 사용한다.
main.c
소스 파일의 내용을 다음과 같이 수정해 보자.
#include <stdio.h>
extern int num1; // 다른 소스 파일(외부)에 있는 전역 변수 num1을 사용
int main()
{
printf("%d\n", num1); // 전역 변수 num1의 값 출력
return 0;
}
// 10
- 프로그램을 실행해 보면
print.c
에서 선언한 전역 변수의 값10
이 출력된다. - 다른 소스 파일에 선언된 전역 변수를 사용하려면
extern
뒤에 자료형과 전역 변수의 이름을 지정해 주면 된다.
- 이처럼 다른 소스 파일에 선언된 전역 변수도
extern
을 통하여 사용할 수 있으므로 소스 파일이 여러 개이면 전역 변수의 범위는 프로그램 범위이다.
- 여기서 주의할 점은 전역 변수 선언없이
extern int num1;
만 지정하면 컴파일(링크) 에러가 발생한다는 것이다. - 즉,
extern int num1;
은 전역 변수가 파일 외부에 있다는 것을 표시만 할 뿐이지 전역 변수 자체를 선언하지는 않는다.
extern
으로 다른 소스 파일의 함수 사용하기
extern
은 전역 변수뿐만 아니라 함수에서 사용할 수 있다.
- 먼저
print.c
파일에printNumber
함수가 있다.
- 여기서
extern void printNumber();
와 같이 지정해 주면 다른 소스 파일(외부)에 있는 함수를 사용할 수 있다.
#include <stdio.h>
extern void printNumber(); // 다른 소스 파일(외부)에 있는 함수 printNumber를 사용
int main()
{
printNumber(); // printNumber 호출
return 0;
}
- 사실
extern
을 붙이지 않고 함수 원형만 선언해도 다른 소스 파일에 있는 함수를 사용할 수 있다.
같은 파일 안에서 extern
사용하기
- 전역 변수를 사용하려면 함수보다 먼저 선언해야 한다.
- 만약 전역 변수가 함수 아래에 선언되면 컴파일 에러가 발생한다.
#include <stdio.h>
int main()
{
printf("%d\n", num1); // 컴파일 에러. 변수를 찾을 수 없음
return 0;
}
int num1 = 10; // 전역 변수를 함수 아래에 선언
- 이때는 전역 변수를 사용하고자 하는 함수 위에
extern
으로 변수가 선언되어 있다는 것을 미리 알려주면 된다. - 즉,
extern
은 다른 파일에 있는 전역 변수뿐만 아니라 같은 파일 안에 있는 전역 변수에도 사용할 수 있다.
#include <stdio.h>
extern int num1; // 변수 num1이 선언되어 있다는 것을 미리 알려줌
int main()
{
printf("%d\n", num1);
return 0;
}
int num1 = 10; // 전역 변수를 함수 아래에 선언
// 10
- 물론
extern
은 같은 파일 안에 있는 함수에도 사용할 수 있지만 함수 원형을 선언하는 것보다 입력해야 할 글자가 많으므로 잘 사용하지 않는 방법이다.