8. 메모리 모델과 이름 공간(2) - 기억 존속 시간, 사용 범위, 링크

WanJu Kim·2022년 12월 8일
0

C++

목록 보기
36/81

프로그램 내에서 선언한 변수들은 메모리에 저장이 된다. 그리고 변수에 따라서 지속되는 시간이 다르다.

지역 변수

먼저 지역변수이다. 지역 변수는 코드 블럭 내에서 선언된 변수를 말한다. 그래서 지역(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에서만 사용 가능.
profile
Question, Think, Select

0개의 댓글