Media Log


1. 구조체(Structures)


C/C++에서 등장했던 구조체가 C#에서 다시 한번 등장합니다. 구조체는, 클래스와 상당히 비슷한 구조를 지니고 있습니다. 구조체는 주로 몇 가지의 항목으로 구성된 간단한 개체를 구조화하기 위해 사용됩니다. 예를 들어서, 우리가 2차원의 좌표를 나타내기 위해 Point 구조체를 만들고자 한다면 아래와 같이 나타낼 수 있습니다.

struct Point
{
    public int x, y;

    public Point(int x, int y) 
    {
        this.x = x;
        this.y = y;
    }
}

위 예제를 보면 클래스와 똑같은 구조를 지니고 있습니다. 클래스와 다를게 없는 것 같은데, 어떤 부분에서 차이가 나는 것일까요? 이를 아래의 도표에서 정리해 보았습니다. (자세한 설명은 이곳)


특징 

클래스 

구조체 

형식

참조 형식 (힙에 할당)

값 형식 (스택에 할당)

상속

가능

불가능

인터페이스 상속

가능

가능 

매개 변수가 없는 명시적 생성자

가능 

불가능 


MSDN에서는 구조체는 아래와 같은 조건을 모두 만족할 때 사용하기를 권장하고 있습니다.

1. 논리적으로 기본 자료형(integer, double, ...)과 유사한 단일 값을 나타낸다.

2. 인스턴스의 크기가 16 바이트보다 작다.

3. 불변이다.

4. 박싱(Boxing)이 빈번하게 일어나지 않는다.

간단하게 말하면, 구조체는 확장이 필요없는 간단한 데이터 구조를 정의할 때 용이하게 사용될 수 있습니다. 우리가


위의 예제를 보시면, 클래스처럼 멤버 변수를 가질수도 있고, 메소드 역시 가질 수 있습니다. 한번, 구조체를 사용하여 학생의 이름과 국어, 수학, 사회, 과학, 영어 점수를 담는 구조체를 정의해보도록 하겠습니다.

using System;

namespace Example
{
    struct Point
    {
        public int x, y;

        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Point point1;

            point1.x = 20;
            point1.y = 30;

            Console.WriteLine("point1: x = {0}, y = {1}", point1.x, point1.y);
        }
    }
}

결과:

point1: x = 20, y = 30

계속하려면 아무 키나 누르십시오 . . .


코드를 보시면, 9~30행에 Test라는 구조체가 정의되었습니다. name, korean, math, society, science라는 멤버 변수를 가지고, 생성자와, Show 메소드를 멤버로 가집니다. 여기서 주의하실 점은, 매개변수가 없는 생성자와 소멸자는 선언할 수 없으며, 상속을 지원하지도 않고, 디폴트 생성자 정의 역시 지원하지 않습니다. 또 하나는 구조체의 멤버를 초기화 할 수 없다는겁니다. 만약 구조체 내에서 초기화를 하고 싶으시다면 생성자를 구현하여 생성자 내에서 초기화를 하셔야 합니다.


그리고, 36~37행을 보시면 각각 new 연산자로 구조체의 객체를 생성하고, 반대로 39~45행을 보시면 new 연산자를 사용하지 않고 선언만으로도 인스턴스화 할 수 있습니다. 값 타입(Value Type)인 구조체는, 이처럼 바로 접근이 가능하고 서로 대입이 가능합니다. 이렇게 구조체는 C#에서 크기가 작거나, 내부가 그렇게 복잡하지 않을때. 즉, 작고 단순한 메서드를 포함하고 있는 선, 컬러같은 그래픽 요소 등을 구조체로 정의합니다.

...
        static void Main(string[] args)
        {
            Point point2 = new Point();
            Point point3 = new Point(10, 10);

            Console.WriteLine("point2: x = {0}, y = {1}", point2.x, point2.y);
            Console.WriteLine("point3: x = {0}, y = {1}", point3.x, point3.y);
        }
...
결과:
point2: x = 0, y = 0
point3: x = 10, y = 10
계속하려면 아무 키나 누르십시오 . . .


오늘은 여기에서 강좌를 마치도록 하겠습니다. 수고하셨습니다.


다음 강좌에서는 인터페이스(interface)에 대해 알아보도록 하겠습니다.


  1. 임석재 at 2012.10.10 14:55 신고 [edit/del]

    강의 너무 잘 보고 있습니다. 감사합니다.
    16편도 기대되네요 ^^

    Reply
  2. 김승현 at 2012.10.20 20:35 신고 [edit/del]

    감사합니다~

    Reply
  3. ZiNee at 2013.10.21 15:08 신고 [edit/del]

    좋은 강좌 올려주셔서 감사합니다.

    Reply
  4. 안녕하세요! at 2014.12.30 16:53 신고 [edit/del]

    안녕하세요 c#구조체를 사용하던 중 궁금한 점이 있어서 질문을 좀 드리려합니다.
    누구라도 아시는 분께서는 답변을 달아주시면 감사하겠습니다..ㅠㅠ

    class Setting
    {
    public struct Room_info
    {
    public string title;
    public int start_time;
    public int run_time;
    public int replay_counting;
    public int break_time;
    }
    }
    위와 같이 Setting클래스에 구조체를 선언했구요.

    다른 클래스의 메소드 내에서 사용할 때는
    Setting.Room_info[] Rinfo = new Setting.Room_info[10];
    Rinfo[0].title = Console.ReadLine();
    Rinfo[1].title = Console.ReadLine();
    ......
    이런식으로 구조체의 각 맴버에 값을 입력했습니다.

    그리고는 또 다른 클래스의 메소드에서
    Setting.Room_info[] Rinfo = new Setting.Room_info[10];
    Console.WriteLine(Rinfo[0].title);
    로 작성하여 출력을 해보았는데..

    아무것도 출력되지가 않더라구요.ㅠㅠ
    혹시 왜 이런 현상이 나타나는지 명쾌하게 답해주실분... 안계십니까??
    부탁드립니다 엑시노아님들!

    Reply
    • 안녕하세요! at 2014.12.30 17:11 신고 [edit/del]

      맴버에 값을 입력한 메소드 내에서는 출력이 정상적으로 되는걸 봐선...
      아마 다른 클래스에서 다시
      Setting.Room_info[] Rinfo = new Setting.Room_info[10];
      을 정의하면서 Rinfo의 이름은 같지만 전혀 다른 메모리주소에 값이 저장되는 모양입니다...
      그렇다면 구조체배열의 정의를 어떻게하면 전역으로 사용할 수 있을까요??

    • oz at 2015.08.04 15:01 신고 [edit/del]

      변수 이름이 같아도 scope 가 다르거나, 새로 new 로 할당되면 아예 다른 변수가 됩니다.

      님의 경우 scope 도 다르고, 새로 new 도 할당되었으니 안되는 이유가 2가지 모두 해당되네요 ^^

      님이 원하시는걸 하기 위해선, new 로 할당한 변수를 함수를 통해 전달하면 될 것 같군요.
      아니면 클래스의 멤버(필드)로 가지고 있다가 사용하시든가요.

  5. 윤키찡 at 2017.08.25 04:04 신고 [edit/del]

    안녕하세요. C# 공부중에 주인장님께서 작성하신 소스코드를 따라하다가 문제가 생겨서 질문드립니닷
    예제의 메인메소드에서 student2 객체는 new 로 초기화를 안 해주면 VS2017 프레임워크 4.6에선 할당되지 않은 student2 지역 변수를 사용했습니다. 라고 뜨고 컴파일도 안 되네요.
    이후로 규격이 더 엄격해진걸까요?

    Reply
    • BlogIcon EXYNOA at 2017.09.25 11:07 신고 [edit/del]

      우선 말씀해주신 VS2017에서 예제의 코드를 컴파일 해보았으나 별다른 오류가 발생하지 않습니다. 해당 에러는 할당되지 않은 객체를 통해 메소드를 호출하는 경우 발생합니다. 예제와 동일한 코드임에도 불구하고 동일한 문제가 발생한다면 아래와 같이 코드를 수정해주시기 바랍니다.

      Test student2 = default(Test);

  6. ARIGATO at 2017.10.12 11:51 신고 [edit/del]

    좋은 강좌 올려주셔서 감사합니다.

    Reply
  7. 공민제 at 2018.05.25 20:58 신고 [edit/del]

    강의 다시 안쓰시나요?/

    Reply
  8. hoi at 2018.06.04 20:50 신고 [edit/del]

    이거.. 소스가 바뀐거 아닌가요 ?

    Reply

submit

티스토리 툴바