프로그래밍 언어/C언어

C언어 16. 변수의 영역

닉네임못짓는사람 2020. 7. 22. 00:17
반응형

이번 글에선 변수의 영역에 대해서 알아보도록 하겠습니다.

사실 이와 관련된 이야기는 지금까지도 몇 번씩 이야기했었는데,이번 기회에 더 자세히 알아봅시다.

변수에는 자신의 영역이 존재한다.


우리가 사용하는 변수에는 각각 자신들이 속한 영역이 존재합니다.

변수들은 이 영역 안에 존재하며, 자신의 삶을 이 영역과 함께합니다.

이러한 변수들이 속한 영역의 범위에 따라서 그 변수를 부르는 호칭이 따로 존재합니다.

 

먼저 이전에도 한번 이야기했던 자동변수라는것이 있습니다.

이는 지역변수라고도 이야기하는데, 보통 하나의 함수에 종속되어 사용되는 변수입니다.

이 자동변수들은 함수 내에서 변수를 선언하면 메모리 공간을 할당받으며,

오직 그 함수 내에서만 해당 변수를 사용할 수 있습니다.

그리고 그 함수가 종료함과 동시에 이 메모리 공간을 반환합니다.

 

예를 들어 main함수에 int a라는 변수를 선언해보도록 합시다.

이 변수는 main함수 내에서는 얼마든지 자유롭게 사용할 수 있지만,

그 외에 다른 함수에서는 아무리 해당 변수에 접근을 하려고 해 보아도 접근이 불가능합니다.

이렇게 직관적으로 확인할 수 있듯이 자동변수는 자신을 선언한 함수 내에서만 사용할 수 있습니다.

이러한 영역은 함수뿐만이아니라 중괄호로도 나눌 수 있습니다.

함수 내에서 영역을 나눠보자


중괄호로 영역을 나누는 방법을 사용하면 메모리 공간을 좀 더 효율적으로 사용할 수 있는데,

어떤 의미인지 코드를 보면서 설명해보도록 하겠습니다.

#include <stdio.h>

int main() {
	int a = 10;
	int b = 20;
	int tmp;
	.
	.		//그 외의 코드
	.
	tmp = a;
	a = b;
	b = tmp;
	.
	.		//그 외의 코드
	.		
	return 0;
}

위의 코드를 매우 긴 코드에서 일부분만 가져온 것이라고 생각해봅시다.

tmp는 a와 b의 값을 변경하기 위해서 사용하는 임시 변수인데,

이러한 변수를 매우 긴 프로그램에서 단 한 번만 사용한다고 생각해봅시다.

위에서 말했듯이 자동변수는 자신이 속한 함수가 끝날 때 메모리 공간을 반환합니다.

그러면 tmp는 긴 프로그램 내에서 한 번만 사용됨에도 불구하고,

계속해서 메모리 공간을 차지하고 있는것입니다.

 

이런 변수가 tmp하나만이라면 큰 영향은 없을지도 모르지만,

언제나 그렇듯 이런 변수가 100개, 1000개라고 생각해보면

메모리 공간이 매우 비효율적으로 사용됨을 짐작하실 수 있을 겁니다.

 

이러한 문제점을 해결하고 메모리 공간을 좀 더 효율적으로 사용하기 위해서

함수 내에서 영역을 나누어서 코드를 작성할 수 있습니다.

자동 변수는 영역 내에서 선언하면 해당 영역이 끝남과 동시에 메모리 공간을 반환하기 때문입니다.

그럼 이런 방법을 코드로 한번 확인해보도록 합시다.

사진을 보시면 중괄호를 통해 영역을 나누어서 해당 영역에 tmp변수를 선언했습니다.

이후 영역이 끝나고 tmp변수에 접근하려 하니 오류가 발생하는 것을 확인하실 수 있습니다.

 

그런데 이렇게 변수가 자신의 영역에서만 존재한다면,

지금까지 다른 함수에 전달 인자로 넘겨준 작업은 어떻게 이루어지는 것일까요?

함수가 다른 함수에 번수를 전달하는 법


사실 답은 매우 간단합니다.

전달 인자로 넘겨준 변수의 값을 그대로 복사해서 해당 함수에서 사용하는 것이죠.

그렇기 때문에 넘겨받은 함수에서 매개변수의 값을 아무리 변경해도

넘겨준 함수에서의 변수값은 절대 변하지 않는 것입니다.

이 값을 변경하는 방법은 포인터 부분에서 설명했으니 생략하겠습니다.

 

다음은 정적 변수에 대해서 이야기해보도록 하겠습니다.

위에서 말했듯이 지역 함수는 함수 내에서 선언 부분이 실행되면 메모리 공간을 할당받고,

함수가 종료되면 메모리 공간을 반환합니다.

이러한 흐름을 따르지 않는 함수가 있는데, 그것이 바로 정적 변수입니다.

정적 변수란?


정적 변수는 함수 내에 선언되지만 수명을 함수와 함께 하는 것이 아닌 프로그램과 함께합니다.

즉 프로그램이 실행될 때 메모리가 할당되며, 프로그램이 종료되면 반환합니다.

 

만약 특정한 함수를 여러번 호출해야 하는 프로그램이 있다고 생각해봅시다.

그때 이 함수가 호출된 횟수를 해당 함수 내에 저장하고 싶을 때

이 정적 변수를 사용하면 매우 간단하게 처리할 수 있을 것입니다.

정적 변수를 선언하는 방법은 변수의 자료형 앞에 static을 붙여주는 것인데,

실제 코드를 통해 확인해보도록 합시다.

#include <stdio.h>

void startCnt();

int main() {
	int i = 0;
	for (i = 0; i < 10; i++) {
		startCnt();
	}
	return 0;
}

void startCnt() {
	static int cnt;		//자동적으로 0으로 초기화
	cnt++;
	printf("함수 호출횟수 : %d\n", cnt);
}

정적 변수는 프로그램이 시작될 때 메모리 공간이 할당되고, 값을 0으로 초기화합니다.

때문에 startCnt함수가 여러번 호출돼도 메모리 공간이 재할당되거나 값이 다시 초기화되지 않습니다.

또한 함수가 종료돼도 메모리 공간을 계속 유지하고 있기 때문에,

해당 변수의 포인터 값을 알고 있으면 다른 함수에서도 계속해서 사용할 수 있습니다.

프로그램 전체에서 쓸 수 있는 외부 변수


마지막으로 외부 변수라는 것이 있습니다.

이는 전역 변수라고도 이야기하는데, 그 이름처럼 함수의 바깥쪽에 위치하고 있습니다.

외부 변수의 장점은 프로그램 내의 모든 함수에서 특별한 작업 없이 접근할 수 있다는 점입니다.

또한 함수 밖에서 선언되기 때문에, 정적 변수처럼 프로그램과 수명을 같이합니다.

코드를 통해 확인해보도록 합시다.

#include <stdio.h>

void showNum();

int a, b;

int main() {
	a = 10;
	b = 20;
	showNum();
    	return 0;
}

void showNum() {
	printf("a: %d, b: %d", a, b);
}

결과를 보면 특별한 작업 없이도 a와 b의 값을 어느 함수에서든 사용할 수 있다는 걸 볼 수 있습니다.

이런 외부 변수는 정적 변수와 마찬가지로 선언하면 자동적으로 값이 0으로 초기화됩니다.

또한 주의해야 할 점이 몇 가지 있는데, 만약 외부 변수와 자동 변수의 변수명이 같을 때,

함수 내에서는 자동 변수를 우선한다는 점입니다.

 

즉 외부 변수 a와 main함수 내의 자동 변수 a가 있다고 가정했을 때,

main함수에서 변수 a에 접근하면 이는 자동변수 a를 가리킨다는 의미입니다.

또한 외부 변수는 하나의 변수를 여러 함수에서 사용하기 때문에

데이터의 안전성을 보장하기가 어렵습니다.

외부 변수를 사용하는 특정 함수가 해당 변수의 값을 변경하였을 때,

그 결과가 프로그램 내의 다른 함수에서 어떤 영향을 주는지 충분히 주의하며 사용해야 할 것입니다.

 

이상으로 변수의 영역에 관한 설명은 마치도록 하겠습니다.

다음 글에선 C언어의 응용 자료형에 대해 설명해보도록 하겠습니다.

 

반응형

'프로그래밍 언어 > C언어' 카테고리의 다른 글

C언어 18. 파일 입출력-1  (0) 2020.07.23
C언어 17. 응용자료형  (0) 2020.07.23
C언어 15. 메모리 동적 할당  (0) 2020.07.20
C언어 14. 포인터 배열, 다중 포인터  (0) 2020.07.17
C언어 13. 문자열  (0) 2020.07.16