C#

[C#]구조체(Struct)

DevStory 2022. 5. 15.

구조체(struct)

구조체는 struct 키워드를 사용하여 값 형식(Value Types)을 정의하고 클래스는 class 키워드를 사용하여 참조 형식(Reference Types)을 정의합니다.

값 형식(Value Types)
값이 스택(Stack) 영역에 할당됩니다.

참조 형식(Referenct Types)
값이 힙(Heap) 영역에 할당됩니다.
스택(Stack) 영역은 값이 할당된 힙의 메모리 주소를 참조합니다.

구조체 정의

struct 키워드를 사용하여 구조체를 정의합니다.

struct Person
{
  public string name;
  public int age;
}

Person 구조체 내부에는 name과 age라는 필드가 존재합니다. 구조체에는 변수뿐만 아니라 메서드, 인덱서도 존재할 수 있습니다.


구조체 변수

클래스의 인스턴스를 생성하듯이 구조체도 변수를 생성해야 합니다. 다음 예제는 구조체 변수를 생성하고 구조체 멤버를 접근합니다.

struct Person
{
  public string name;
  public int age;
  
  public void displayField()
  {
    Console.WriteLine("name: " + name + " / age: " + age);
  }
}

class Program
{
  static void Main(string[] args)
  {
    // 구조체 변수 선언
    Person person;

    // 구조체 변수 필드에 값 할당
    person.name = "둘리";
    person.age = 999;

    // 구조체 변수 필드 호출
    Console.WriteLine("Person.name: " + person.name);
    Console.WriteLine("Person.age: " + person.age);
    person.displayField();
}

실행 결과

Person.name: 둘리
Person.age: 999
name: 둘리 / age: 999

 

구조체도 new 키워드를 사용하여 인스턴스화 가능합니다. new 키워드를 사용하는 경우 매개변수가 없는 생성자를 호출하고 모든 멤버를 기본 값(Default Value)으로 초기화합니다.

struct Person
{
  public string name;
  public int age;

  public void displayField()
  {
    Console.WriteLine("name: " + name + " / age: " + age);
  }
}
class Program
{
  static void Main(string[] args)
  {
    Person person = new Person();
    person.displayField();
  }
}

실행 결과

name:  / age: 0

name은 string타입이므로 ""으로 초기화되고 age는 int타입이므로 0으로 초기화됩니다.


구조체 생성자

클래스처럼 생성자를 만들 수 있습니다.

struct Person
{
  public string name;
  public int age;

  public Person(string name, int age)
  {
    this.name = name;
    this.age = age;
  }

  public void displayField()
  {
    Console.WriteLine("name: " + name + " / age: " + age);
  }
}
class Program
{
  static void Main(string[] args)
  {
    Person person = new Person("마이콜", 20);
    person.displayField();
  }
}

실행 결과

name: 마이콜 / age: 20

 

구조체 생성자의 단점은 모든 필드에 값을 할당해야 한다는 것입니다.

struct Person
{
  public string name;
  public int age;

  public Person(string name)
  {
    this.name = name;
  }
}

위 예제는 생성자에서 age 필드에 값이 할당되지 않았으므로 컴파일 에러가 발생합니다.

 

컴파일 에러를 해결하기 위해서는 다음 예제처럼 모든 생성자에서 모든 필드의 값을 할당해야 합니다.

struct Person
{
  public string name;
  public int age;
  public string address;

  public Person(string name)
  {
    this.name = name;
    this.age = 0;
    this.address = "";
  }

  public Person(string name, int age)
  {
    this.name = name;
    this.age = age;
    this.address = "";
  }
  
  public Person(string name, int age, string address)
  {
    this.name = name;
    this.age = age;
    this.address = address;
  }
}

 추가적으로 C# 9.0 이하 버전에서는 매개변수가 없는 생성자를 만들 수 없습니다.

반응형

구조체 프로퍼티

구조체에서 프로퍼티를 사용할 수 있습니다. 다음 예제는 구조체 필드를 private로 선언 후 필드를 프로퍼티로 접근합니다.

struct Person
{
  private string name;
  private int age;

  public string Name
  {
    get { return name; }
    set { name = value;}
  }

  public int Age
  {
    get { return age; }
    set { age = value; }
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person = new Person();
    person.Name = "고길동";
    person.Age = 50;

    Console.WriteLine("Name: " + person.Name + " / Age: " + person.Age);
  }
}

실행 결과

Name: 고길동 / Age: 50

클래스와 차이점

구조체는 클래스와 유사하게 보이지만, 몇 가지 차이점이 존재합니다. 다음 예제는 클래스와 구조체의 주요 차이점인 값 형식과 참조 형식에 대해 설명합니다.

 

먼저, 클래스입니다.

class Person
{
  public string name;
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person();
    person1.name = "둘리";

    // person1을 person2에 할당합니다.
    Person person2 = person1;
    person2.name = "마이콜";
    
    // person1.name의 값도 변경되었습니다.
    Console.WriteLine("person1.name: " + person1.name);
    Console.WriteLine("person2.name: " + person2.name);
  }
}

실행 결과

person1.name: 마이콜
person2.name: 마이콜

위 예제에서 person1을 person2에 할당했습니다. 클래스는 참조 형식이므로 person2와 person1은 동일한 객체를 참조합니다. 따라서 person2의 값이 변경되면 person1의 값도 변경됩니다.

 

클래스와 반대로 구조체는 값이 변경되지 않습니다.

struct Person
{
  public string name;
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person();
    person1.name = "둘리";

    Person person2 = person1;
    person2.name = "마이콜";

    Console.WriteLine("person1.name: " + person1.name);
    Console.WriteLine("person2.name: " + person2.name);
  }
}

실행 결과

person1.name: 둘리
person2.name: 마이콜

구조체는 값 형식이므로 person2의 값을 변경해도 person1에 영향을 미치지 않습니다.


정리

  • 구조체는 값 형식, 클래스는 참조 형식입니다.
  • 구조체 생성자 내부에서 모든 필드의 값을 할당해야 합니다.
  • 구조체는 상속이 불가능합니다.
반응형

댓글