프로그램 내에서 선언한 변수들은 메모리에 저장이 된다. 그리고 변수에 따라서 지속되는 시간이 다르다.
먼저 지역변수이다. 지역 변수는 코드 블럭 내에서 선언된 변수를 말한다. 그래서 지역(local)이라는 단어를 사용한다. 이 변수는 코드 블럭을 나가면 사라지게 된다.
int main()
{
int value = 10;
{
int value1 = 20;
} //value1 변수는 사라진다.
}//value 변수는 사라진다.
만약 변수 이름이 중복이 되면 어떻게 될까? 최근에 선언한 변수를 따른다.
int value = 10;
{
int value = 20;
cout << "코드 블럭 나가기 전 : " << value << endl;
}
cout << "코드 블럭 나가고 후 : " << value << endl;
실행 결과.
지역 변수는 생성과 사라짐이 반복된다. 이를 저장하는 방식이 따로 있는데 이를 '스택'이라고 부른다. 스택은 LIFO(last in first out;후입선출) 방식인데 그림을 보면 쉽게 알 수 있다.
사진 출처
지역변수는 위의 코드와 같이, 나중에 생성된 변수일수록 더 빨리 사라지기 때문에 스택의 방식으로 저장한다. 이와 반대인 FIFO(first in first out;선입선출)방식도 있는데 이건 다음에 알아보겠다.
지역 변수와 대비대는 변수로 '전역 변수'가 있다. 이는 코드 블럭 밖에서 저장된 변수를 말한다. 이 변수는 선언된 파일 이외의 파일 즉, 프로그램 어디에서나 쓰일 수 있다.(물론 #include 시켜야 함.)
이와 비슷하게 '정적 변수'가 있는데 이는 코드 블럭 내외에서 선언이 가능하다. 외부에서 선언을 하면, 그 '파일 내'에서만 쓸 수 있고, 코드 블럭 내에서 선언을 하면, 그 코드 블럭 내에서만 쓸 수 있다. 하지만 지역 변수처럼 메모리에서 사라지는 게 아니라, 남아있다. 그래서 함수 내에서 static 변수를 초기화하면, 다음 호출 때도 값이 초기화되는 게 아니라, 값이 남아있다. (와우)
이 두 변수는 프로그램이 실행되는 동안 계속 존재한다. 그래서 컴파일러는 이를 위한 정해진 메모리 공간을 따로 마련해두었다. 또한 이 변수들은 초기화를 하지 않으면 자동으로 0으로 된다.
int global = 1000; // 프로그램 어디에서나 쓸 수 있는 전역 변수.
static int one_file = 50; // 선언된 파일 어디에서나 쓸 수 있는 정적 변수.
int main()
{
...
}
void func1(int n)
{
static int count = 0; // 코드 블럭 내에 쓰인 정적 변수. 코드 블럭이 끝나도 메모리에 남아있음.
int llama = 0; // 코드 블럭이 끝나고 사라짐.
}
아까 전역 변수를 다른 소스에서 사용하려면 조건이 필요하다고 했는데, 'extern'을 사용하면 된다. extern의 의미는, '다른 소스에 정의된 전역 변수를 찾아서 쓰겠다.'는 정도로 생각하면 된다.
source.cpp
int blem = 10; // 전역 변수 선언.
...
main.cpp
extern int blem; // 다른 어딘가에 선언되어 있는 blem 변수를 쓰겠다.
이를 좀 더 구체적으로 알아보는 코드는 다음과 같다.
support.cpp
#include <iostream>
extern double warming;
void update(double dt);
void local();
using namespace std;
void update(double dt)
{
extern double warming;
warming += dt;
cout << "전역 warming이 " << warming;
cout << "도로 갱신되었습니다." << endl;
}
void local()
{
double warming = 0.8;
cout << "지역 warming은" << warming << "도 입니다." << endl;
cout << "그러나, 전역 warming은 " << ::warming << "도 입니다." << endl; // ::(범위연산자)는 전역 버전 사용.
}
main.cpp
#include <iostream>
using namespace std;
double warming = 0.3;
void update(double dt);
void local();
int main()
{
cout << "전역 warming은 " << warming << "도 입니다." << endl;
update(0.1);
cout << "전역 warming은 " << warming << "도 입니다." << endl;
local();
cout << "전역 warming은 " << warming << "도 입니다." << endl;
}
실행 결과.
cpp를 따로 포함시키지 않았는데도 변수 및 함수가 여기서 쓰이고 저기서 쓰이는 데에 매우 놀랐다. 원래 include 시켜야 하는 거 아니었나..?
전역 변수가 쓰기에 참 좋아보이지만, 데이터를 차지하기 때문에 꼭 필요한 경우가 아니라면 전역 변수 사용은 좋지 않다. 지역 변수를 잘 활용하도록 하자.
만약 서로 다른 파일에서 다른 용도로 쓸거지만 변수 이름은 같게 쓰고 싶다. 어떻게 해야 할까?
file1.cpp
int value = 10;
file2.cpp
int value = 20; // 불가능.
이는 당연히 중복이라 안된다. 하지만 하나의 변수에 static을 붙이면, 이는 '그 파일 내에서만 사용되는 변수'라고 인식이 된다.
file1.cpp
int value = 10;
file2.cpp
static int value = 20; // 가능. file2.cpp에서만 사용 가능.