NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# 7. Struct 형식

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 오늘은 구조체에 대해서 알아보도록 하겠습니다. 이전에 알아본 enum처럼, struct도 User-define type입니다. 구조체는 여러가지 형식들을 사용하기 쉽게 모아둔 틀과 같습니다. 보통, 클래스를 설계하면 해당 클래스에 속성으로써 정보를 저장하게됩니다. 그러나, 어떤 특정 시나리오에서는 이러한 정보들을 구조체로 관리하는게 더 효율적¹이기도 합니다. 예를 들어, Point, Size, Color, Rectangle등이 있습니다. 현재 C#에서는 2D기반 데이타만을 제공하고 있습니다. 3D데이타를 담으려면 구조체가 정답일 수 있습니다.

    ¹ Heap에 할당되는 Class보다 Stack에 할당되는 Struct가 메모리도 적게 사용하고 속도도 빠릅니다.

    12qMukM.jpg

     

     

    구조체는 몇가지 제약 사항이 있습니다. 매개변수가 없는 생성자는 선언할 수 없습니다. WCF와 Linq to SQL에서도 시나리오에 따라 매개변수가 없는 생성자 모델을 사용할 수 없습니다. 이 부분이 매우 중요한데, 특정 기능을 사용하기 위해 몇가지를 포기해야 한다는 건 결코 쉬운 문제가 아니기 때문이죠. 나중에 WCF를 할 때 좀 더 자세히 알아보구요. 아무튼간에 구조체를 생성할 때 유의해야 합니다. 하지만, 생성자를 만들지 않아도 문제가 되지는 않습니다. 두번째는 구조체의 맴버에서는 초기화 할 수 없다는 것입니다. 그렇기 때문에 맴버만큼 변수를 받는 생성자를 만들거나, 선언 후 초기화를 해줘야 합니다. 아래 예제를 통해 하나씩 알아보도록 하겠습니다. 이전에 배운 enum도 포함하구요^^;

     

    구조체는 클래스와는 다르게 new로 인스턴스화 하지 않아도 사용할 수 있습니다.

    Program.cs

    using System;
     
    namespace ConsoleApplication1
    {
        class Program
        {
            public enum Sex { Male, Female }
            public struct People {     
                                      public string Name; 
                                      public int Age; 
                                      public Sex Sex; 
                                      public People(string name, int age, Sex sex) 
                                      { 
                                          Name = name; 
                                          Age = age; 
                                          Sex = sex; 
                                      } 
                                 }
            static void Main(string[] args)
            {
                People people;
                people.Name = "아이언맨";
                people.Age = 52;
                people.Sex = Sex.Male;
                Console.WriteLine(people.Name);
                Console.WriteLine(people.Age);
                Console.WriteLine(people.Sex);
                Console.ReadLine();
            }
        }
    }

     

     

    아래는 결과입니다.

    SWPSurS.png

     

     

    이제 위 코드에서 하이라이트되어 있는 28라인을 삭제하고 실행해 보세요. 에러가 발생합니다. 이렇게 new인스턴스를 생성하지 않으면 모든 인스턴스 맴버에 대해서 초기화를 해야 하는 제약이 생깁니다. 그렇다면, new로 인스턴스화 한 후 테스트를 해보도록 합니다.

     

    코드를 아래와 같이 수정한 후 실행해보세요.

    using System;
     
    namespace ConsoleApplication1
    {
        class Program
        {
            public enum Sex
            {
                Male, Female
            }
     
            public struct People
            {
                public string Name; public int Age; public Sex Sex; public People(string name, int age, Sex sex)
                {
                    Name = name;
                    Age = age;
                    Sex = sex;
                }
            }
     
            static void Main(string[] args)
            {
                People people = new People();
                people.Name = "아이언맨";
                people.Age = 52;
                people.Sex = Sex.Male;
                Console.WriteLine(people.Name);
                Console.WriteLine(people.Age);
                Console.WriteLine(people.Sex);
                Console.ReadLine();
            }
        }
    }

     

     

    25라인처럼 변경하고 실행해보세요. 결과가 같습니다.

    XmRy85J.png

     

     

    이제 28번째 라인을 아래처럼 주석 처리한 후 실행해 봅니다.

    //people.Sex = Sex.Male;

     

    결과는 아래와 같이 나옵니다. 만약, 인스턴스화 하지 않았다면 이곳에서 에러를 발생시키게 됩니다.

    XmRy85J.png

     

     

    인스턴스는 내부 인스턴스 맴버에 대해 적절하게 할당하게 됩니다. 하지만, 자동으로 무언가가 처리된다는 것은 나중에 오류를 찾기 힘들수도 있다는 의미입니다. 따라서, 할당하지 않았다면 에러를 발생시키는게 더 도움이 될수도 있습니다. 기본적으로 구조체와 클래스는 다릅니다. 구조체는 값형식이며, 클래스는 참조형식이기 때문입니다. 따라서 구조체는 구조체에서 상속할 수 없으며, 클래스의 베이스가 될 수도 없습니다. 참조가 필요없는 작은 클래스라면 구조체를 사용하는게 더 효율적입니다. 아직 참조형식에 대해서는 알아보지 않았으므로 이정도 차이점만 알고 계시면 될거 같습니다.

    COjf322.jpg

     

     

    아래 그림은 X, Y, Z의 값을 가지는 구조체들의 집합을 나타내고 있습니다. 이렇게 많은 데이타를 처리할 때는 클래스보다 구조체가 메모리도 조금 사용하고 속도면에서도 이점이 있습니다. 일정하지 않은 맵의 데이타를 매틀랩의 인터폴레이션으로 채워주고 OpenGL을 이용하면 쉽게 Surface를 그려볼 수 있습니다.

    rERESJ4.png

     

     

    다음 시간에...

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.