8. 구조체(struct), 공용체(union), 열거형(enum)

8.2 구조체(struct)

  • 구조체는 임의의 타입의 원소들이 모인 것이다.

8.2.1 struct 구조

  • struct 객체는 선언된 순서대로 멤버들을 보관한다. -> 멤버들은 선언 순서에 따라 메모리에 할당 된다.

  • 객체의 멤버들이 선형적으로 연결되어 배치된다.

  • 하지만, struct 객체의 크기가 반드시 그 멤버들의 크기의 합과 같지는 않다.

    • 대부분의 컴퓨터 아키텍처에서 데이터가 메모리에 올바르게 저장 및 접근하기 위해서, 정렬된 메모리 엑세스가 필요하다.

    • 대부분의 시스템에서는 4바이트 정렬이 필요하므로, 4의 배수 주소에서 데이터를 읽고 쓸 때 최상의 성능을 유지한다.

    • 이를 위해서 구조체 멤버 변수 사이에 패딩을 사용한다.

  • 크기가 큰 멤버변수 순서대로 선언 시, 패딩 사용을 최소화 할 수 있다.

  • 일반적으로는 멤버들을 가독성 위주로 정렬하고, 최적화의 필요성이 확실한 경우에만 크기 순으로 정렬하는 편이 바람직하다!

  • 아래 코드를 살펴보자

    • 아래 코드와 같이 구조체에서 멤버변수를 사용하는 순서에 따라서, 사용하는 메모리의 크기가 달라진다.

// sizeof(Readout) = 12
struct Readout {
    char hour;
    int value;
    char seq;
}
// sizeof(Readout) = 8
struct Readout {
    int value;
    char hour;
    char seq;
}

8.2.3 구조체와 클래스

  • 기본적으로 구조체는 클래스에서 사용하는 모든 기능을 사용 가능하다. -> 다른 점이라고 한다면, 기본 접근제어자가 public 이라는 점이 다르다)

8.2.5 타입 동등 관계

  • 서로 다른 구조체에서 똑같은 멤버를 갖고 있어도, 이름이 다른 두 struct 는 서로 다른 타입이다. -> 동등 관계를 멤버 변수로 판단하지 않는다.

  • 모든 구조체는 하나의 프로그램 내에서 고유의 정의를 가져야한다.

8.3 공용체(union)

  • 공용체는 모든 멤버가 동일한 주소에 할당되는 구조체이다! -> 동일한 메모리 사용!

  • 그러므로 공용체는 멤버 중 가장 큰 멤버 만큼의 크기만 사용한다.

  • 아래 코드를 살펴보자

  • 공용체에는 다음과 같은 엄청난 단점이 존재한다.

    • 타입안정성 부족 : 컴파일러가 타입을 체크하지 않기 때문에, 프로그래머가 타입을 직접 체크해야 한다.

    • 정의되지 않은 동작 : 여러 멤버가 동일한 메모리를 공유하기 때문에 하나의 멤버를 수정하면 다른 멤버에도 영향을 줍니다. 이로 인해 의도하지 않은 데이터 손상이 발생할 수 있으며, 데이터의 무결성이 위험에 노출될 수 있습니다.

    • 디버깅의 어려움 : 여러 타입이 하나의 메모리에 저장되므로 디버깅이 어려워진다.

8.4 열거형 (enum)

  • 열거형은 사용자가 지정한 정수 값 집합을 보관하는 타입이다.

  • 열거형에는 다음과 같이 두 종류가 있다.

    • enum 클래스 : enum 클래스는 값이 다른 타입으로 암시적 변환이 되지 않아 타입 안정성을 가진다.

    • enum : enum 값이 정수로 암시적 변환되므로 타입이 불안정하다..

8.4.1 enum 클래스

  • enum 클래스는 유효 범위를 가지면, 타입 안정성을 가진다.

  • 열거형 타입 표시에 사용되는 기초 타입의 default 설정은 int 이다.

  • 다음의 코드를 살펴보자

    • 기초 타입을 명시적으로 설정할 수 있다.

    • 열거형 멤버 변수는 정수 타입, 상수 표현에 의해 초기화 될 수 있다.

8.4.2 일반 enum

  • 일반 enum은 enum 클래스가 도입되기 이전에 사용되었던 것으로,

  • 일반 enum 은 정수형 타입의 값으로 암시적으로 변환된다.

Last updated