따배씨++ (8. Local scope)

김동우·2021년 2월 24일
0

안녕하십니까. 김동우입니다.

이번 노트에서는 지역 범위, Local Scope에 대해 적어보고자 합니다.

시작부터 코드를 넣겠습니다.

#include <iostream>

using namespace std;

void doSomething(int z)
{
	z = 123;
	cout <<" Z scope : doSomething "<< z << " " << &z << endl;
}

int main() 
{
	int x(0); // x=0; 인스턴스를 가짐. 메모리 내 존재가 생김.
	int y(0); // y=0; 인스턴스를 가짐. 메모리 내 존재가 생김.
	int z(0); // z=0; 인스턴스를 가짐. 메모리 내 존재가 생김.

	cout << " X scope : main " << x << " " << &x << endl; // 0인 x가 출력 + 메모리 주소(&)
	cout << " Y scope : main " << y << " " << &y << endl; // 0인 y가 출력 + 메모리 주소(&)
	cout << " Z scope : main " << z << " " << &z << endl; // 0인 z가 출력 + 메모리 주소(&)

	{
		int x = 1;
		y = 1; 

		cout << " X scope : nested block " << x << " " << &x << endl; // 1인 x가 출력
		cout << " Y scope : nested block " << y << " " << &y << endl; // 1인 y가 출력 메모리 주소 변경 없음
		
	 /* 영역 내 영역(nested block)을 선언하고, 내부에서 동명의 변수를 초기화해도 문제X
	 메모리의 주소가 다르다. 즉, 값이 대입되는 두 주소가 있을뿐이다.
	 이러한 변수 선언을 지역 변수 선언이라 하고,
	 지역 변수는 영역 외부에서는 사용할 수 없다. (소멸)
	 대입된 값은 소멸하고, 차지하던 메모리는 stack 메모리로 반납된다.
	 반납된 메모리는 다음 지역 변수가 사용할 수 있도록 대기하고 있다. */
	
	}

	doSomething(z); // 123인 z가 출력, 메모리 주소 다름


	cout << " X scope : main " << x << " " << &x << endl; // 0인 x가 출력 1이 대입된 x 소멸
	cout << " Y scope : main " << y << " " << &y << endl; // 1인 y가 출력 메모리 주소 변경 없음
	cout << " Z scope : main " << z << " " << &z << endl; // 0인 z가 출력

	return 0;

} // x,y,z 소멸

자, x, y, z 3 변수들의 생성과 소멸이 모두 담겨있는 아주 기특한 코드입니다. 차근차근 풀어드리고 싶지만, 실습에 사용한 코드들을 보기 좋게 작성한 것이기 때문에 실제로 실행시키고 읽어보시는 것이 더 낫지 않을까 생각합니다.

다만, 이번 노트에서는 코드에 대한 설명보다는 왜 이런 상황이 발생할까? 에 포커스를 맞춰보도록 하겠습니다.

  1. 지역 범위와 지역 변수

    많은 언어를 경험하신 분이라면 쉽게 감을 잡으시지만, 대부분 처음 하시는 분들이라면 감을 잡기 어려운 구간이 등장했습니다. 바로 지역 변수에 대한 설명입니다.

    local variables 라는 이름을 가지는 이 변수들은 특정 블럭 내에서만 값을 가지는 특별한 변수들입니다.

    이 블럭의 영역을 우린 local scope, 지역 범위라 부르고, 대표적인 예시가 바로 함수와 nested block입니다. 이후에는 클래스와 다양한 statement가 등장하겠지만, 우선은 두 가지면 충분합니다.

    이런 녀석들이 왜 필요할까? 하시는 분들도 있겠지만, 이 변수들이 존재하기 때문에 우리의 프로그램은 더욱 빠른 처리 속도를 가지는 성능이 좋은 프로그램이 되는 것입니다.

    또한 지역 변수를 통해 함수의 존재 이유를 더욱 효과적으로 설득할 수 있게 됩니다.

    우리가 사용하는 C++ 내에서 동명의 변수 초기화는 원칙적으로 하나의 블럭, 범위 내에서는 불가능한 일입니다.

    그런데 함수는 호출과 동시에 해당 블럭 내 새로운 중첩된 블럭을 만드는 것을 포함하고 있습니다.

    선언 당시 중괄호를 사용하는 것은 괜한 이유가 있었네요.

    만약, 코딩이 끝난 다음 "함수 내의 변수 초기화와 main 함수 내의 변수 초기화를 동명의 변수로 진행했더니 디버깅 오류가 발생했어요!"

    이런 경우가 존재한다면 얼마나 황당하고, 어이없을까요? 심지어 네이밍은 온전히 본인의 잘못이니 우린 분을 삭히며 결국 다시 자리에 앉아야 할겁니다.

    그런데 이런 과정을 아예 없애버릴 수 있도록 C++은 지역 변수의 개념을 등장시킨겁니다. 즉, 편하다는 말이죠.

    지역 변수는 심지어 변수를 일시적으로 생성하고, 사용 이후에는 즉시 소멸시킵니다. 이는 다시 메모리의 낭비를 줄일 수 있다는 말로 바꿔 말할 수 있습니다.

    자, 예를 들어 우리가 고사양 RPG 게임을 만든다고 가정합시다. 다양한 모션과 기능을 지원하기 위한 함수들이 시간의 흐름에 따라 메모리를 비우지 않고 새 주소에 지속적으로 데이터를 가득 채운다고 생각하면, 이는 어떤 문제가 발생할까요?

    네, 아마 캐릭터 선택창은 가보지도 못하고 그 이전 함수들에 의해 메모리를 사용하는 다양한 하드웨어에서 ran out error를 남발하게 될겁니다.

    즉, 우린 지역변수를 통해 메모리를 효율적으로 관리할 수 있는 방법을 하나 터득하게 되는 것입니다.

    이러한 지역변수가 생성되고 소멸하는 과정은 위 코드에 자세히 나와있으니, 한 번 실행시켜 보시고, 생각하는 시간을 잠시 가져보시면 쉽게 이해하실 수 있을겁니다.

    자, 이번 글은 여기서 마치겠습니다.

0개의 댓글

관련 채용 정보