본문 바로가기
프로그래밍 언어/cpp

[C++] 정적(static) 변수와 외부(extern) 변수, 분할구현에서의 전역변수 사용

by TyT. 2023. 2. 7.
반응형

정적변수 & 외부변수

지난 포스트에서 분할 구현을 할 때 전역변수를 사용하면 문제가 생긴다는걸 언급하고 넘어갔다. 이번 포스트에서 전역변수를 대신해 사용할 정적변수와 외부변수에 대해 알아보자.

정적변수(static)


변수를 선언할때 static 을 붙여 선언하면 된다. 전역변수와 마찬가지로 data영역에 변수가 생성되므로 만약 함수내에서 선언 할 경우, 함수가 끝나도 변수의 값이 소실되지 않고 유지된다는 특징이 있다.

#include <stdio.h>

void StaticVariable() {
    static int a = 0;   //최초로 호출될 때 한번만 실행됨.
    a++;
    printf("%d\n", a);
}

void main()
{
    StaticVariable();
    StaticVariable();
    StaticVariable();
}

실행 성공

결과에서 볼 수 있듯 변수 a의 값이 소실되지않고 유지됨을 알 수 있다. 여기서 변수를 선언하고 초기화하는 코드는 함수가 최초로 실행될때 한번만 초기화함을 알 수 있다.

이 점을 이용해 분할 구현된 코드의 헤더파일에 정적 변수를 선언하면 전역변수를 선언할때와 달리 컴파일 에러가 나타나지 않음을 알 수 있다.

  • main.cpp
#include <stdio.h>
#include "func.h"



void main()
{
    a = 100;
    printf("%d\n", a);
    StaticVariable();
    StaticVariable();
    StaticVariable();
}
  • func.cpp
#include "func.h"
#include <stdio.h>

void StaticVariable() {
    a++;
    printf("%d\n", a);
}
  • func.h (전역변수로 선언된 변수 a)
void StaticVariable();

int a = 0;

컴파일은 성공, 하지만 링크 실패

 

컴파일은 성공하지만 링크과정에서 에러가 발생한다.

  • func.h (정적 변수로 선언된 변수 a)
void StaticVariable();

static int a = 0;

 

실행 성공. 하지만 결과가?

정상적으로 실행이 되었다. 하지만 결과를 보면 출력값이 이상하다고 생각 할 수도 있다. 메인에서 a를 100으로 할당하고, 함수에서 a++을 통해 101, 102, 103을 예상했는데 1, 2, 3이 나왔다. 여기서 main.cpp와 func.cpp에서 정적변수 a는 다른 변수임을 알 수 있다. 정적변수로 프로그램을 실행은 할 수 있지만 우리가 원하는 전역변수의 역할은 할 수 없었다.

외부 변수(extern)


우리가 원하는 전역변수의 역할은 외부 변수를 통해서 할 수 있다. 외부변수는 extern을 헤더파일에서 변수선언할때 앞에 붙여주면 되는데, 이는 실제로 변수를 선언한 것이 아닌, 이러한 변수가 존재함을 알려 주는 것이다.

  • main.cpp
#include <stdio.h>
#include "func.h"

void main()
{
    a = 100;
    printf("%d\n", a);
    StaticVariable();
    StaticVariable();
    StaticVariable();
}
  • func.cpp
#include "func.h"
#include <stdio.h>

void StaticVariable() {
    a++;
    printf("%d\n", a);
}
  • func.h
void StaticVariable();

extern int a;

 

링크 실패

컴파일은 성공했지만 링크단계에서 실패했음을 알 수 있다. 이는 존재함을 알렸기 때문에 컴파일은 정상적으로 했지만, 실제로 변수가 존재하지 않았기 때문에 생긴 오류이다. 따라서 변수를 선언해 주면 된다. 전역변수 형태로 아무 소스코드(main.cpp 혹은 func.cpp)에 선언해 주면 된다.

  • main.cpp
#include <stdio.h>
#include "func.h"

int a=0; // func.cpp에 선언해도 문제없이 돌아간다.

void main()
{
    a = 100;
    printf("%d\n", a);
    StaticVariable();
    StaticVariable();
    StaticVariable();
}
  • func.cpp
#include "func.h"
#include <stdio.h>

void StaticVariable() {
    a++;
    printf("%d\n", a);
}
  • func.h
void StaticVariable();

extern int a;

 

성공!

전역변수가 정상적으로 작동함을 알 수 있다.

주의 할 점으로, 위에서 언급했듯이 외부변수는 변수를 실제로 선언하는 것이 아니기 때문에

extern int a = 1;

처럼 초기화를 할 시 오류가 발생한다.

반응형