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. 24. 12:00
728x90

구조체는 사용자 정의 타입으로써, 기본 타입 외에 사용자가 직접 타입을 정의해 사용할수 있도록 c#에서 지원하는 기능입니다. 구조체는 클래스와 달리 값 형식입니다.

 

구조체는 클래스를 정의하는 문법과 매우 유사하며, class 키워드를 struct 예약어로 대체함과 동시에, 클래스와는 여러가지 차이점이 존재합니다.

  1. 인스턴스의 생성을 꼭 new를 통하지 않아도 할수 있다.
  2. 기본 생성자를 정의할수 없고, 매개변수가 존재하는 생성자를 정의하더라도, 컴파일러에 의해 자동으로 기본생성자가 포함된다.
  3. 매개변수를 받을 경우, 구조체 내에 모든 필드에 값을 할당해주어야 한다.

그러면 한번 구조체를 하나 만들어보겠습니다.

exStruct exStruct1; // new 없이 선언
exStruct exStruct2 = new exStruct(1,2,"hello","World"); // new 있게 선언
exStruct exStruct3 = new exStruct();
exStruct2.printAll();
exStruct3.printAll();

struct exStruct {
    public int i;
    public int n;
    public string str;
    public string str2;
    
    public exStruct(int i,int n,string str,string str2) {
        this.i = i;
        this.n = n;
        this.str = str;
        this.str2 = str2;
    }
    
    public void printAll() {
        Console.WriteLine("i: "+i+", n:"+n+", str:"+str+", str2:"+str2);
    }
}

이렇게 선언이 가능합니다. 그런데, exStruct3처럼 인스턴스를 new로 기본생성자를 통해 생성하는것은 모든 값을 0으로 선언하는것과 동일합니다.(문자열의 경우 빈 값을 대입했다고 생각하시면 됩니다.) 그러면 exStruct1은 exStruct3과 printAll 메서드를 호출했을때의 결과가 동일할까요? 당연히 아닙니다. exStruct1는 기본생성자나 그 외의 생성자를 사용하여 인스턴스를 생성한 것이 아니여서, 초기화가 되지 않은 상태이므로, 메서드를 호출하면 오류가 발생하지만, exStruct3는 컴파일러가 만든 기본생성자를 통해 값을 대입했으므로, 오류가 나지 않고 다음 결과가 출력됩니다.

"i: 0, n:0, str:, str2:"

 

클래스와 구조체의 차이

클래스는 참조 형식이고, 구조체는 값 형식이라는 점을 꼭 기억하시길 바랍니다. 값 형식과 참조 형식은 다른 변수에 인스턴스를 대입했을때, 차이가 발생합니다. 예를 들어, exStruct 타입의 exStruct1을 생성하고, 그 값을 새로운 exStruct 타입의 exStruct2라는 변수에 대입한다면, 어떤 일이 벌어질까요?

exStruct exStruct1 = new exStruct(1,2,"hello",", World");
exStruct exStruct2 = exStruct1;

값을 담아두었던 메모리 자체가 복사되며, 새로운 변수에 대입되게 되는데요, 이를 값까지 모두 복사된다 하여 깊은 복사라 하고, 스택의 값이 또 다른 저장공간인 힙의 주소를 가리키는 참조형 변수의 경우에는, 그 주소만이 복사되어 결국에는 같은 힙 주소를 가리키기 때문에 결과적으로는 같은 값을 가리키기 때문에 이를 얕은 복사라고 합니다.

 

얕은 복사의 경우, a의 값을 b 변수에 대입한 후, b의 값을 변경하게 되면, 원본이었던 a의 값도 변경되게 됩니다. 다만 깊은 복사의 경우에는 아예 다른 값을 가리키고 있으므로, c의 값을 변수 d에 대입해도, 결과적으로는 값을 담아둔 메모리 자체가 복사되기 때문에 d를 변경하면 d만 변경되고, c의 값은 변경되지 않습니다. 반대로 c의 값을 변경해도 c의 값만 변경되고, d의 값은 변경되지 않습니다.

 

이를 명심하고, 필요에 따라, 클래스와 구조체를 잘 선택해서 사용하시길 바라겠습니다.

 

그럼 오늘도 여기서 마치도록 하겠습니다.

728x90

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

[c#] ref 그리고 out  (2) 2022.04.25
[c#] 이벤트 (글이 완성되지 않았으니 보셔서 조회수 늘리지 마세요)  (0) 2022.04.23
[c#] 인터페이스  (0) 2022.04.22
[c#] 델리게이트  (0) 2022.04.21
[c#] 추상 클래스  (0) 2022.04.20