C++ (10) - 정적변수와 외부변수
본 내용은 어소트락 무료 강의 <C/C++ 무료강의>을 기반으로 공부한 내용을 정리한 것이다. 틀린 내용이 있을 수도 있음.
정적(Static)변수
“정적(Static)”이 핵심 키워드!!
C/C++ 에서 Static : 선언된 곳에 틀어박혀 움직이지 않는다.
// 기본 형식
static int g_iStatic = 0; // static + 자료형 + 변수명 = 초기값;
Cpp파일에 전역변수 처럼 선언
함수 바깥에 전역변수처럼 정적변수를 선언 -> 해당 코드 파일에 선언된 것으로 생각하자.
선언된 출신파일이 다르므로 변수명이 같아도 구분이 가능 -> 중복 정의가 발생하지 않아 전역변수와 달리 링크단계에서 오류 X
static int g_iStatic = 0; // A.cpp 파일에 선언된 정적변수
static int g_iStatic = 0; // B.cpp 파일에 선언된 정적변수
// 같은 변수가 아니다!!
정적변수가 선언된 곳 바깥에서는 해당 변수가 선언된지를 모른다. 선언된 곳만 찾을 수 있다.
어떻게 보면 변수 선언에 “제한“을 준 것 -> 제한하는 것 또한 하나의 기능이라고 보자.
함수안에서 선언
(1) 전역변수의 경우
int g_i = 0;
void Test()
{
++g_i; // Test 함수 호출 횟수 증가
}
int main()
{
Test();
Test();
Test();
Test();
Test();
printf("Test 함수 호출 횟수 : %d\n", g_i);
return 0;
}
// 출력 결과 : 5
int g_i = 0;
void Test()
{
++g_i; // Test 함수 호출 횟수 증가
}
int main()
{
Test();
Test();
Test();
Test();
Test();
g_i; = 0; // 위 예제에서 추가하면?
printf("Test 함수 호출 횟수 : %d\n", g_i);
return 0;
}
// 출력 결과 : 0 -> 다른 함수에서 이 변수에 이상한 값을 넣을 수 있어 방어가 안됨.
(2) 정적변수의 경우
static int g_iStatic = 0; // 정적변수 선언
int Test()
{
static int i = 0; // 초기값 부여가 1번만 진행
++i; // Test 함수 호출 횟수 증가
return i;
}
int main()
{
g_istatic;
Test();
Test();
Test();
Test();
int iCall = Test();
printf("Test 함수 호출 횟수 : %d\n", iCall);
return 0;
}
// 출력 결과 : 5 -> Test 함수가 호출될때마다 정적변수 i에 0을 넣지 않는다.
정적변수의 특징과 한계
문법적으로는 정적변수에 접근이 불가능하다. -> 후에 포인터를 이용해 강제 접근 가능
그렇다면 모든 파일에서 인식할 수 있는 전역변수를 정적변수를 이용해 만들 수 있는가?
아! 모든 파일이 공통으로 접근할 수 있는 Header 파일에 정적변수를 선언하면 모든 파일에서 #include를 통해 참조할 수 있잖아?
그렇지 않다. 전역변수 Case 때와 마찬가지로 #include를 통해 똑같은 변수가 복붙이 되어 링크단계에서 같은 오류가 발생한다.
그렇다면 이를 해결할 수 있는 방법은? 바로 “외부변수”이다.
외부(Extern)변수
// Header 파일에서 기본형식
extern int g_iextern; // extern + 자료형 + 변수명;
// 주의!! 초기값 대입 하지 않는다.
초기값을 대입하지 말고 Header 파일에서 선언하지 말고 해당 변수가 “있다“라고만 정의 해두자.
이후 각 파일에서 해당 변수에 값을 선언하자.
그렇다면 컴파일 과정에서 어딘가에 외부 변수가 있다는 것을 인지하여 변수가 적용된다.
이떄 변수값은 어떤 파일에 있어도 상관이 없다.
변수값이 없으면 링크단계에서 오류가 발생한다.
// Header 파일
extern int g_iextern;
// A파일 (main 파일)
g_iextern = 500;
// B파일 (함수를 모아놓은 파일)
int Add(int a, int b)
{
printf("g_extern의 값은? : %d\n", g_iextern);
return a + b;
}
Add 함수를 통해 출력될때 500 변수값을 가진다.
이때 g_extern변수값은 어떤 파일에 놓아도 상관이 없다. A파일 말고도 B,C … 등 다 가능하다.