정적변수 & 외부변수
지난 포스트에서 분할 구현을 할 때 전역변수를 사용하면 문제가 생긴다는걸 언급하고 넘어갔다. 이번 포스트에서 전역변수를 대신해 사용할 정적변수와 외부변수에 대해 알아보자.
정적변수(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;
처럼 초기화를 할 시 오류가 발생한다.
'프로그래밍 언어 > cpp' 카테고리의 다른 글
[C++] 클래스 기초와 생성자, 소멸자 (0) | 2023.02.08 |
---|---|
[C++] 함수 포인터 (0) | 2023.02.08 |
[C++] void* 보이드 포인터 (0) | 2023.02.08 |
[C++] 상수(const)와 포인터 (0) | 2023.02.08 |
[C++] 헤더파일을 이용한 분할 구현 (0) | 2023.02.07 |