본문 바로가기
C#

[C#기초] 클래스와 구조체의 차이

by Meaning_ 2021. 7. 21.
728x90
반응형

값 형식과 참조형식


 

C#에는 두가지 데이터 형식이 있는데, 값형식참조형식이라는 두가지 데이터 형식이 있다.

 

형식은 스택에 메모리가 저장되고, 참조형식은 에 메모리가 저장된다.

값 타입으로 전달되는 경우 참조 값으로 전달되는 경우
기본 데이터 타입, 구조체, 열거형  클래스, 인터페이스,델리게이트

 

 

 

구조체와 클래스


  구조체 클래스
전달되는 타입 값 타입으로 전달 참조값으로 전달
메모리 할당 유무 구조체는 메모리가 할당되기 때문에 사용자가 할당해줄 필요가 없다(값에 의한 형태)
--> 내부에서 new 연산자를 자동으로 호출하기 때문 
클래스 사용시 new 연산자로 사용자가 메모리를 할당해줘야 한다. (참조에 의한 형태)
상속여부 불가능 하다 가능하다
사용 메모리 그 자체를 이용하려 할 때 내부의 메모리가 어떠하던지 간에 기능적인 측면이 중요할 때 

 

메모리 절약을 따진다면 클래스, 속도를 따진다면 구조체를 사용하는 것이 좋다. 

 

 

아래 두 분의 블로그를 참고하여 작성했다. 

https://vaert.tistory.com/111

 

[C#] 구조체와 클래스의 차이

클래스와 구조체는 데이터 타입생성기 라는 점에서는 유사하지만,  구조체는 값타입이라는것과 클래스는 참조타입이라는 점에서 차이점이 있다.  구조체를 사용하는이유는 클래스 사용시에

vaert.tistory.com

https://funfunhanblog.tistory.com/96

 

C#) struct와 class의 차이점 구조체와 클래스

struct와 class의 차이점 1) Type차이 구조체는 값 타입(value) => 스택메모리에 생성된다. 클래스는 참조 타입(reference) => 힙 메모리에 생성된다. 힙과 스택차이점 값타입과 참조타입 관련 예제 구조체

funfunhanblog.tistory.com

 

 

예제를 통해 알아보기


학생 정보를 저장하는 class와 구조체를 작성해보았다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
namespace classAndStruct
{
    internal class Info
    {
        public string name;
        public int studentID;
        public String address;
        public Info(String name, int studentID, String address)
        {
            this.name = name;
            this.studentID = studentID;
            this.address = address;
 
        }
    }
 
    internal struct Info2
    {
        public string name;
        public int studentID;
        public string address;
    }
 
    
   
    class program
    {
        public static void changeInfo(Info a)
        {
            a.address = "세종시";
        }
        public static void changeInfo2(Info2 a)
        {
            a.address = "뉴욕시";
        }
        static void Main(string[] args)
        {
 
            Info info = new Info("김영희"2020"서울시");
            Console.WriteLine($"학번:{info.studentID},이름:{info.name},주소:{info.address}");
            changeInfo(info);
            Console.WriteLine($"학번:{info.studentID},이름:{info.name},주소:{info.address}");
 
            Info2 b; //b는 값타입
            b.address = "캘리포니아";
            b.studentID = 2021;
            b.name = "John";
            Console.WriteLine($"학번:{b.studentID},이름:{b.name},주소:{b.address}");
            changeInfo2(b);
            Console.WriteLine($"학번:{b.studentID},이름:{b.name},주소:{b.address}");
 
 
            
 
 
        }
 
    }
}
 
cs

 

changeInfo ,changeInfo2 메서드를 사용하여 주소를 바꿀 수 있게 하였다. 

 

콘솔 창을 보면 클래스를 사용한 경우 address 변수 가 바뀌지만, 구조체를 사용했을 땐 address 변수가 바뀌지 않는다.

 

클래스의 경우, Heap에 클래스의 인스턴스가 생성이 되고, 스택에 변수로 주소값 설정한다.

즉, 힙의 주소를 전달하기 때문에 값이 아닌 같은 주소가 참조되는 것이다. 또한 changeInfo 메서드 를 빠져나와도 변경된 데이터는 남아있기 때문에 Main 메서드에서 changeInfo에서 변경된 값 그대로 출력되게 된다.

(changeInfo 메서드처럼 매개변수에 클래스를 설정하면 원래 stack 변수에도 영향이간다. --> 그렇기 때문에 address 변수가 서울시에서 세종시로 바뀔 수 있던 것)

 

구조체는 changeInfo2메서드에서 "뉴욕시"로 변경해도 외부 메서드인 Main 메서드에서는 값이 변경되지 않는다.

복사된 데이터는 원본 데이터가 아니기 때문에 (구조체는 깊은 복사를 사용함)

복사된 값을 수정하면(changeInfo 메서드를 통해 수정), 스택에 복사된 값을 변경하게 되는것이다.

복사본에 입력된 값들은 메서드를 나오면서 사라지기 때문(원래 stack은 함수 호출이 완료되면 사라진다)에, Main 메서드에는 복사본의 값이 아닌 원본 데이터 값(캘리포니아)이 나오는 것이다. 

 

두분의 블로그를 참고하여 글을 썼다. 더 알아보고 싶으신 분들은 url링크를 타고 가서 보길 바란다!

 

https://sillim83.tistory.com/157

 

CS 기초강좌 6. 값 타입과 참조 타입, 스택과 힙, struct와 class

CS 기초강좌 6. 값 타입과 참조 타입, 스택과 힙, struct와 class  사용자가 코드를 통하여 객체를 생성할 때, 크게 두 가지 메모리 영역에 생성시킬 수 있다. stack과 heap 영역이다. 관련 설명을 간단히

sillim83.tistory.com

https://nowonbun.tistory.com/84

 

[C#] 17. 구조체(struct) 그리고 값 형식 참조(Value type reference)와 참조(포인터) 형식 참조(Reference type r

안녕하세요. 명월입니다. 이 글은 C#에서의 구조체(struct) 그리고 값 형식 참조(Value type reference)와 참조(포인터) 형식 참조(Reference type reference)에 대한 글입니다. 이전 글에서 제가 클래스와 인스턴

nowonbun.tistory.com

 

c#의 깊은 복사와 얕은 복사를 알고 싶다면

 

https://076923.github.io/posts/C-17/

 

C# 강좌 : 제 17강 - 구조체 | 076923

구조체(Struct)

076923.github.io

 

728x90
반응형

'C#' 카테고리의 다른 글

[C#기초] 가상함수/ 동적바인딩,정적바인딩  (0) 2021.08.14
[C# 기초] 다형성/상속  (0) 2021.07.27
[C#기초] 복사 생성자/ static  (0) 2021.07.27
[C#기초] setter/getter 함수  (0) 2021.07.19
[C#기초] 참조  (0) 2021.07.19

댓글