1. 소개
구조체는 C#에서 특별한 데이터 타입이야. 여러 값을(심지어 타입이 달라도 됨) 한 “박스”에 넣을 수 있어. 약간 작은 LEGO 조립 세트 같은 느낌이지: 부품을 모아서, 결과적으로 편하고 컴팩트한 객체를 만드는 거야.
구조체는 클래스랑 비슷하지만, 몇 가지 차이점이 있고, 클래스만큼 “무겁고” 복잡한 게 필요 없을 때, 좀 더 “간단한” 상황에서 써.
문법
struct Point
{
public int X;
public int Y;
}
Point 구조체 선언
이 예제에서는 X랑 Y 좌표를 가진 평면 위의 점을 위한 구조체를 만든 거야.
구조체는 어디에 써?
보통 구조체는 작고 단순한 객체, 정말 가볍고 “그냥 데이터”만 필요한 경우에 많이 써.
C#에서 몇몇 표준 타입들도 구조체야:
- int, double, bool, DateTime, TimeSpan, decimal, Guid
- 그리고 예를 들면 ConsoleKeyInfo나 Point (그래픽 라이브러리에서)도 구조체야
구조체와 클래스의 차이점
| 기준 | 구조체 | 클래스 |
|---|---|---|
| 키워드 | |
|
| 저장 타입 | Value Type | Reference Type |
| 저장 위치 | 스택(메모리 영역) | 힙(메모리 영역) |
| 메서드로 전달 | 값으로(복사) | 참조로 |
| 상속 | 안 됨(인터페이스만 가능) | 가능 |
| null 가능? | 안 됨(Nullable만 가능) | 가능 |
| 기본값 | 모든 필드가 자동으로 0으로 초기화됨 | 생성자 통해서만 |
2. 구조체 선언과 사용
구조체는 클래스 안이나 밖에서 선언할 수 있어:
struct Rectangle
{
public int Width;
public int Height;
}
생성 및 사용 예시:
Rectangle r;
r.Width = 10;
r.Height = 5;
Console.WriteLine($"면적: {r.Width * r.Height}");
생성자도 쓸 수 있어:
struct Point
{
public int X;
public int Y;
// 생성자
public Point(int x, int y)
{
X = x;
Y = y;
}
}
var p = new Point(3, 7);
Console.WriteLine($"점: ({p.X}, {p.Y})");
언제 구조체를 쓰는 게 좋아?
- 작은 “데이터 묶음”(예: 좌표, 색상, 범위, 날짜와 시간 등)에.
- 컴팩트함과 성능이 중요할 때(예: 배열에 수백만 개의 점).
- 객체가 하나의 값처럼 동작해야 할 때(copy-paste 하면 진짜 복사됨!).
구조체를 쓰지 않는 게 좋은 경우:
- 객체가 크거나(필드가 많음)
- 상속 구조에 들어가야 할 때
- 참조로 자주 바뀌어야 할 때
3. 구조체의 특징과 “함정”
복사
Point p1 = new Point(1, 2);
Point p2 = p1; // 복사본이 만들어짐!
p2.X = 100;
Console.WriteLine(p1.X); // 1 — 안 바뀜!
Console.WriteLine(p2.X); // 100
구조체를 복사하면 독립적인 복사본이 만들어져
자동 기본값
Point p; // X랑 Y 필드는 0이야, 명시적으로 안 넣어도!
Nullable 가능
null을 저장하려면, 타입 이름 뒤에 물음표를 붙이는 특별한 nullable 문법을 써야 해. 그러면 변수에 null을 넣을 수 있어.
Point? p = null;
if (p == null)
Console.WriteLine("점 없음");
4. 자동 프로퍼티와 메서드가 있는 구조체
구조체도 메서드, 프로퍼티, 이벤트, 심지어 static 멤버까지 가질 수 있어.
public struct Range
{
public int Start { get; set; }
public int End { get; set; }
public int Length => End - Start;
public override string ToString() => $"[{Start}..{End}]";
}
예시: 복소수용 구조체
복소수용 구조체, 메서드와 ToString() 오버라이드 예시
struct Complex
{
public double Re;
public double Im;
public Complex(double re, double im)
{
Re = re;
Im = im;
}
public double Abs() => Math.Sqrt(Re * Re + Im * Im);
public override string ToString() => $"{Re} + {Im}i";
}
var z = new Complex(1, 2);
Console.WriteLine(z); // 1 + 2i
Console.WriteLine(z.Abs()); // 2.236...
GO TO FULL VERSION