본문 바로가기

C & C++

C/C++ 기초 - 변수 ( Variable )

변수


#include <iostream>

using namespace std;

int main (void)
{
	int a = 10;
	int b;

	b = 20;

	return 0;
}

 변수는 값을 저장하는 메모리 공간을 프로그래머가 사용하기 쉽게 나타낸 것입니다. 변수를 사용하기 위해서 선언과 정의가 이루어져야 하고 선언과 정의를 각각 나눠서 할 수도 있으며 값을 재정의 할 수도 있습니다.

 


 선언


 변수의 선언은 '자료형 변수명'입니다. 예시 코드에서 'int b;' 부분이 선언입니다. int라는 자료형 변수 b를 만들겠다고 선언한 것입니다.

 


 정의


 변수의 정의는 '변수명 = 값'입니다. 예시 코드에서 'b = 20;'이 정의 부분입니다. b라는 변수에다 20이라는 값을 넣어주겠다는 의미입니다.

 


 선언 및 정의


 C/C++ 대부분의 상황에서 변수를 선언함과 동시에 정의할 수 있습니다. ( ex. int a = 10 ) const라는 키워드를 사용하여 상수로 선언하게 된다면 선언과 정의를 반드시 같이 해주어야 합니다.

 


변수의 종류


#include <iostream>

using namespace std;

int global_init = 100;
int global_not;

void function()
{
	int		fLocal = 100;
	static int	fStatic = 100;
	
	printf("함수에 선언된 지역 변수 : %d\n", fLocal++);
	printf("함수에 선언된 정적 변수 : %d\n", fStatic++);
	printf("함수에서 전역 변수 호출 : %d\n\n", global_init++);
}

int main(void)
{
	int		loop = 5;

	int		mLocal = 100;
	static int	mStatic;

	while (0 < loop--)
	{
		int		bLocal = 100;
		static int	bStatic = 100;
		
		printf("메인 함수에 선언된 지역 변수 : %d\n", mLocal++);
		printf("메인 함수에 선언된 정적 변수 : %d\n", mStatic++);
		printf("메인 함수 반복문 안에 선언된 지역 변수 : %d\n", bLocal++);
		printf("메인 함수 반복문 안에 선언된 정적 변수 : %d\n", bStatic++);
		printf("메인 함수에서 전역 변수 호출 : %d\n\n", global_init++);
		function();
		printf("-----------------------------------\n\n");
	}

	return 0;
}

 변수는 전역 변수 ( Global variable ), 정적 변수 ( Static variable ), 지역 변수 ( Local variable )로 구분됩니다.

 전역 변수와 정적 변수는 프로그램이 실행됨과 동시에 메모리가 할당되어 data 영역에 자리하게 되고 프로그램을 종료할 때까지 유지되다가 종료될 때 메모리가 해제됩니다.

 지역 변수는 해당 변수가 포함된 함수를 호출하면 Stack 영역에 Stack이 쌓이면서 지역 변수의 메모리도 같이 할당되고, 함수가 종료되면서 지역 변수의 메모리가 해제됩니다.

 이를 디버거 모드 ( Visual studio 2019, x64 플랫폼 )를 통해 확인해 보도록 하겠습니다.

 

 main 함수가 시작되는 시점입니다. 디버그에서 보이듯이 전역 변수와 정적 변수는 메모리가 할당되고 선언 및 초기화까지 끝난 상태입니다. 반면 지역 변수는 아직 메모리가 할당되지 않았습니다.

 

 어셈블리는 저도 잘 모르지만 00007FF6D45419CA 명령줄을 지나자 할당되지 않았던 지역 변수의 메모리가 할당되는 것을 확인할 수 있습니다. 여기서 반복문 블록 안의 지역 변수와 정적 변수가 정의되지 않았다고 표시되지만 정적 변수는 이미 선언 및 초기화까지 끝난 상태고, 블록 안의 지역 변수 또한 방금 다른 지역 변수들이 할당되면서 같이 할당되었습니다.

 

 while문 시작점에 메모리를 할당하는 작업이 없지만 이미 지역 변수에 메모리가 할당되어 있었다는 것을 통해 함수의 시작점에서 할당되었음을 알 수 있습니다.

 

 function 함수의 시작점입니다. main 함수에서 지역 변수 메모리 할당할 때 사용 되었던 명령어 코드가 보입니다. function 함수에서도 마찬가지로 호출될 때 지역 변수 메모리가 할당된다는 것을 알 수 있습니다.

 

 function 함수가 종료되기 직전의 모습입니다. fLocal 변수의 메모리가 할당되었다가 해제되는 것을 확인할 수 있습니다. 해제되고서 왜 main 함수에 있던 loop를 가리키는지는 모르겠지만.. 해제는 되었습니다.

 

 while 문이 한 번 끝나서 loop 값이 3이 되었지만 bLocal의 메모리 주소는 변하지 않은 것을 확인할 수 있습니다. while문도는 과정동안 값이 계속 100이 되니 마치 function 함수에서 메모리를 할당했다가 해제하는 것처럼 새로운 변수를 사용하는 것 같지만, 같은 메모리를 사용하며 정의 및 재정의를 계속해서 그런 것일 뿐입니다.

 

 다시 function 함수를 호출해서 진입했을 때 function 함수에서는 지역 변수 메모리가 새로 할당되는 것을 확인할 수 있습니다.

 

 여기서 초기화된 전역, 정적 변수끼리 나열되어있고, 초기화되지 않은 전역, 정적 변수끼리 나열되어 있는 것을 알 수 있습니다.

 


 global_init : 0x00007ff6d454d000

 fStatic      : 0x00007ff6d454d004

 bStatic     : 0x00007ff6d454d008

 

global_not : 0x00007ff6d454d180

mStatic     : 0x00007ff6d454d184


 이처럼 초기화된 전역, 정적 변수와 초기화되지 않은 전역, 정적 변수가 나뉘어 있는 것을 보고 데이터 영역 안에서도 data 세그먼트와 bss 세그먼트로 나뉘어서 메모리가 할당된 것을 알 수 있습니다.

 

 메인 함수의 종료 시점이 되면 main 함수의 지역 변수 역시 메모리가 해제되며 프로그램이 종료되게 됩니다.