Media Log


1. 구조체(Structures)


C/C++에서 등장했던 구조체가 C#에서 다시한번 등장합니다. 구조체는, 클래스와 상당히 비슷한 구조를 지니고 있습니다. 하지만 무시할 수 없는 큰 차이점이 존재하는데, 클래스는 힙에 생성되는 참조 타입(Reference Type)이고, 구조체는 스택에 생성되는 값 타입(Value Type)이라는 것이죠. 구조체는 클래스보다 메모리 소모가 덜하므로 어떤 개발자들은 구조체를 더 선호하기도 합니다. 아래는 구조체의 선언 형식입니다.

struct 구조체명
{
// 멤버 변수.. 메소드..
}

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication24
{
    struct Test
    {
        public string name;
        public int korean;
        public int math;
        public int society;
        public int science;

        public Test(string name, int korean, int math, int society, int science)
        {
            this.name = name;
            this.korean = korean;
            this.math = math;
            this.society = society;
            this.science = science;
        }
        public void Show()
        {
            Console.WriteLine(name + "의 시험 점수:");
            Console.WriteLine("국어: " + korean + ", 수학: " + math + ", 사회:" + society + ", 과학: " + science);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Test student1 = new Test("김철수", 94, 96, 84, 92);
            student1.Show();

            Test student2;
            student2.name = "김영희";
            student2.korean = 100;
            student2.math = 84;
            student2.society = 96;
            student2.science = 86;
            student2.Show();
        }
    }
}

결과:

김철수의 시험 점수:

국어: 94, 수학: 96, 사회:84, 과학: 92

김영희의 시험 점수:

국어: 100, 수학: 84, 사회:96, 과학: 86

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


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


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


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


다음 강좌에서는 인터페이스(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

submit

티스토리 툴바