250x250
Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

minjea.dev의 코딩블로그

[c#] 변수와 상수, 그리고 스택과 힙 본문

코딩강좌/c#

[c#] 변수와 상수, 그리고 스택과 힙

minjea.dev 2022. 4. 5. 17:59
728x90

변수란, 무언가를 담아두는 상자처럼, 사용자가 정한 값을 담아두는, 상자와도 비슷하다 볼수 있습니다. 조금 어렵게 말하자면, 변수는 변수가 선언되었을때, 할당된 값의 형식에 맞는 저장소에 메모리가 할당되며, 그 저장소에 값을 저장해두는 역할을 합니다. 우리는 변수를타입 변수명; 형식으로 만들거나, 타입 변수명 = 값; 형식으로 만들수 있습니다. 다음 예제는 int 형 변수 a와 b를 선언한 예제입니다. 

int a;
int b = 100;

변수는 타입 변수명; 으로 선언된 경우, 초기화가 되지 않았다고 합니다. 다만, 선언과 동시에 값이 할당되는 경우, 초기화가 되었다고 합니다. 초기화가 되지 않은 변수 a를 출력하려고 시도하면, 에러가 발생합니다. 그 이유는 값이 할당되지 않았기 때문입니다.

 

아까전에 설명한 것처럼, 값 형식에 맞는 저장소에 메모리를 할당받기 때문에, 형식이 다른 값을 할당하여서는 안됩니다. 아래는 string 형 변수 str에 int형 값 10을 대입하려고 시도한 올바르지 않은 예제입니다.

string str = 10;

직접 해보시면 아시겠지만, 오류가 발생합니다. 이처럼, 변수에는 타입에 맞는 값을 대입하여야 합니다.

 

값 형식

값 형식은, 변수에 대입했을때, 값 자체가 스택에 저장되며, 값 형식이 저장된 변수는 그 메모리를 가르키게 됩니다.

참조 형식

변수의 유일한 차이점은, 값을 스택에 저장하느냐, 아니면 힙에 저장하느냐에 있습니다. 앞에서 설명한것처럼 값 형식은 값 자체가 스택에 저장되지만, 참조 형식의 경우에는, 값을 담기 위해, 별도의 힙 영역의 메모리를 할당하고, 스택에는 힙 영역에 저장한 값의 주소를 가리키는 값을 저장하게 됩니다.

 

또한, 참조 형식의 경우, 아무런 값이 저장되지 않으면, null 값이 대입되며, 이는 가리킬 힙 영역에 메모리 주소가 없음을 의미합니다. (c#에서 참조 형식에 속하는 타입은, class, interface, delegate, record, dynamic, object, string 등이 있습니다. 출처 - 마이크로소프트)

 

값 형식과 참조 형식의 차이

값 형식과 참조 형식은, 자신의 값을 다른 변수에 대입했을때, 뚜렷한 차이가 나타납니다.

int i = 100;
int n = i;
n = 1000;
Console.WriteLine(i); // 100
Console.WriteLine(n); // 1000

string txt = "Hello World!";
string text = txt;
text = "Hello";
Console.WriteLine(text); // hello

n에는 i의 값을 대입하였고, text에는 txt를 대입하였는데, n과 i는 서로 다른 값이 나왔고, txt와 text는 같은 값이 나왔습니다. 그 이유는 왜 그럴까요?

 

값 형식은 스택에 직접 값을 대입하여 n과 i는 다른 메모리에 각각 값이 저장되었지만, txt와 text는 스택에 힙 주소를 가리키는 값이 저장되기 때문에, 예를 들어, txt의 힙 주소에 0x0400의 값이 저장되어있었다 치면, text에 txt의 값을 대입할때, text의 값도 0x0400가 되버린 것입니다. 따라서, 같은 힙 주소를 가리키고 있기 때문에 text를 수정하면 txt도 수정되는 것입니다.

힙과 스택

그럼 도데체 힙과 스택은 무엇일까요? 그것에 대하여 알아봅시다. 먼저 스택에 대하여 알아보겠습니다. 스택은, LIFO(Last In First Out, 후입선출) 구조로써, 가장 나중에 들어온 데이터가 가장 먼저 나가는 구조로 이루어져 있습니다. 쉽게, 배열이 수직으로 쌓여 있다고 보시면 됩니다. 따라서, 스택은 메모리 관리가 매우 쉽습니다.

{
	int a = 10;
}

위 변수 a에 담긴 정수 10은 스택에 저장되는데, 이때, 스택은 코드 블럭이 종료되는 }를 만나면, 알아서 데이터를 삭제합니다.

 

이제 힙을 알아보겠습니다. 힙은. 스택과 달리, 데이터를 스스로 제거할 수 없습니다. 다만, 닷넷에서는 이를 관리하기 위하여, 가비지 컬렉터(Garbage Collector)라는 일종의 관리도구를 통해, 힙의 메모리를 관리합니다. 가비지 컬렉터는 힙에 더 이상 사용하지 않는 데이터를 알아서 정리해 주는 기능이 있습니다.

 

스택과 달리 힙은 블록이 끝나도 데이터가 소멸되지 않는 특징이 있습니다. 그래서, 코드블럭이 끝나도 데이터를 유지할수 있습니다. 그리고 이 데이터는 가비지 컬렉터에 의하여 더이상 사용되지 않는다고 판단되면 알아서 제거됩니다.

{
	object a = {};
} // a는 블럭이 끝나도 삭제되지 않음

 

상수

변수는 값이 바뀔수 있기 때문에, 개발자가 실수로 중요한 변수의 값을 변경할 위험이 존재합니다. 이 때문에, c#은 상수를 지원합니다. 상수는 변수와 달리, 한번 값이 대입되면, 절대로 값이 변경되지 않고, 이후 값을 변경하려고 시도하면 에러가 발생합니다. 상수는 변수랑 선언이 거의 동일합니다. 다만, 앞에 const 키워드를 붙여주기만 하면 됩니다

const string developer = "Kakao";
developer = "Google"; // Error!

이처럼, 값을 변경하려고 시도하면 에러가 발생합니다. 또한, 상수는 값이 변경되면 안되기 때문에, 선언할때 반드시 초기화를 해 주어야만 합니다. 그렇지 않으면 에러가 발생합니다

const string a; // Error!
728x90

'코딩강좌 > c#' 카테고리의 다른 글

[c#] 클래스  (0) 2022.04.09
[c#] 반복문(break, continue, 그리고 goto문)  (1) 2022.04.08
[c#] 조건문  (0) 2022.04.07
[c#] 여러가지 연산자  (0) 2022.04.06
[c#] 기본 자료형  (3) 2022.04.04