Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
관리 메뉴

시작은 0부터

23. 구조체(Struct)와 클래스(Class) 본문

C# 학습일지

23. 구조체(Struct)와 클래스(Class)

0base 2022. 8. 3. 22:11

구조체(Struct)

: 멤버변수를 정의하는 데이터 형식. 클래스와 유사하지만 클래스와 달리 구조체를 생성하는 것으로, 클래스와 비슷한 개념인 것 같다. 클래스 개념을 이해할 때 클래스란 붕어빵을 찍어내는 붕어빵 '틀'로 이해했다.

 

Class bread
{
    int a;
    int b;
    string c;
}

 

빵이라는 클래스 틀을 만들고 그 안에 멤버변수 a, b, c 를 생성하고, 빵 클래스 틀을 활용하여 빵 클래스를 만들면 그 클래스 고유 이름을 선언하고 생성한다. 

Bread honeybutterbread = new Bread();
honeybutterbread.a = 1;
honeybutterbread.b = 2;
honeybutterbread.c = 3;

빵 클래스로부터 꿀버터빵(?)이라는 생성자를 통해 객체를 만들어냈다. 맨 위 줄이 생성자를 선언하는 부분이며, 위와 같은 선언 없이 그냥 클래스만 만들면 보이지 않아도 자동으로 같은 이름의 생성자가 생성된다. 

 

이러한 방식으로 클래스를 통해서 객체를 생성하는 방법을 배웠다. 그런데 구조체도 크게 다르지 않다.

 

Struct Bread
{
    int a;
    int b;
    int c;
}

 똑같이 객체처럼 하나의 틀을 만들어 두고 그 틀을 활용해서 동일한 멤버변수를 사용하는 객체들을 찍어낸다.

구조체는 클래스 외부에서 선언할 수 있고, 구조체를 활용하여 클래스 내부에서 객체를 만들어낼 수 있다.

그런데 클래스 안에다 바로 만들 수는 없고, 클래스 내부에 함수를 만들고 그 안에서만 만들 수 있었다.

 

namespace A
{
	struct S
    	{
            int a;
            int b;
    	}
    
	class C
    	{
    	    S test = new S();
            S.a = 1; <== X
    
            public void F()
            {
                S.a = 2;
                S.b = 1;
            }
    	}
}

위 코드에서 클래스 안 함수 밖에 있는 S.a = 1은 성립될 수 없는 코드였다. 구조체(Struct) 자체가 멤버변수이며 값을 할당하지 않고 형식만 갖추는 구조인데, 그 구조체에 값을 할당하여 멤버변수로 사용하려했기 때문에 성립될 수 없었던 것인지 다른 이유에서인지 모르겠다. 그리고 사용방법이 익숙치 않아서인지 굳이 구조체를 사용할 바에는 클래스로 만들어도 되지않나 싶은 생각이 든다. 

 

++

구조체는 값 우형이고, 클래스는 참조 유형이다.

구조체는 값이니 스택 영역에 들어가고 클래스는 참조 유형이니 힙 영역에 들어간다.

스택은 정적으로 메모리에 할당된다. 스택 영역의 변수는 선언된 함수 밖으로 나가면 사라진다.

구조체는 값이라서 함수 밖에서는 사라지기 때문에 함수 내부에서만 선언될 수 있던 것이 아닐까 추측한다.

 

힙은 동적으로 메모리에 할당되고, C#의 경우 이 힙 메모리를 가비지컬렉터(GC)가 자동으로 값을 제거한다.

프로그램 시작과 동시에 값을 깔고 시작하는 스택과 달리 힙은 프로그래머가 원하는 시점에 동적으로 메모리를 할당한다.

 

코드를 작성할 때, 가끔 클래스 내부에서 함수를 만들면서 다른 클래스의 함수의 값을 가져오려고 할 때, static (정적) 선언을 하지 않으면 정적이 아니라서 값을 가져올 수 없다라고 하는 경우가 종종 있다. 프로그램 순서상 값을 가져오려는 함수에서 먼저 값을 할당하고 그 이후에 실행되는 함수에서 앞의 함수에서 값을 가져오려고 해도 값이 가져올 수 없는 이유는, 함수의 실행순서와 관계없이 함수 내부의 값, 또는 함수 외부의 멤버변수의 값을 가져올 때 그 값이 정적이 아니라면 값이 스택 메모리에 없는 것이고, 스택메모리에 없는 상태에서 참조하려고 하니 참조할 값이 없어서 그러한 문제가 생기는 것이라 짐작해본다.