본 내용은 어소트락 무료 강의 <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 … 등 다 가능하다.