55.3 익명 구조체와 익명 공용체 활용하기

이번에는 익명 구조체와 익명 공용체를 활용하는 방법을 알아보겠습니다. 다음은 3차원 벡터 좌표를 구조체와 공용체로 나타낸 예제입니다.

anonymous_struct_union.c

#include <stdio.h>

struct Vector3 { // 3차원 벡터 좌표
    union {          // 익명 공용체
        struct {         // 익명 구조체
            float x;         // x 좌표
            float y;         // y 좌표
            float z;         // z 좌표
        };
        float v[3];      // 좌표를 배열로 저장
    };
};

int main()
{
    struct Vector3 pos;

    for (int i = 0; i < 3; i++)    // 3번 반복
    {
        pos.v[i] = 1.0f;           // v는 배열이므로 인덱스로 접근 할 수 있음
    }
 
    printf("%f %f %f\n", pos.x, pos.y, pos.z);    // 1.000000 1.000000 1.000000: x, y, z로 접근

    return 0;
}

실행 결과

1.000000 1.000000 1.000000

x, y, z 좌표를 저장하는 Vector3 구조체를 정의했습니다. 먼저 맨 안쪽 x, y, zfloat로 선언되어 있으며 익명 구조체입니다(x, y, z는 각각의 값을 독립적인 공간에 저장하기 위해 구조체로 정의합니다. 또한, pos.x처럼 멤버에 바로 접근하기 위해 익명 구조체로 정의합니다). 그리고 익명 공용체가 x, y, z익명 구조체와 배열 v를 감싸고 있습니다(pos.v처럼 멤버에 바로 접근하기 위해 익명 공용체로 정의합니다).

struct Vector3 { // 3차원 벡터 좌표
    union {          // 익명 공용체
        struct {         // 익명 구조체
            float x;         // x 좌표
            float y;         // y 좌표
            float z;         // z 좌표
        };
        float v[3];      // 좌표를 배열로 저장
    };
};

float x, y, z는 변수 3개이고 float v[3]은 배열의 요소가 3개입니다. 자료형도 같고 개수도 같으므로 결국 같은 공간을 차지합니다. 따라서 공용체로 묶어주면 x, y, zv[3]은 같은 공간을 공유하게 됩니다.

그림 55‑3 익명 구조체와 익명 공용체

다음과 같이 v는 배열이므로 인덱스로 접근하여 값을 할당할 수 있습니다. 여기서는 3번 반복하면서 v[0], v[1], v[2]에 1.0을 할당했습니다.

for (int i = 0; i < 3; i++)    // 3번 반복
{
    pos.v[i] = 1.0f;           // v는 배열이므로 인덱스로 접근 할 수 있음
}

공용체에 값을 넣었으므로 값은 같은 공간에 있습니다. 따라서 x, y, z 멤버로도 접근할 수도 있습니다.

printf("%f %f %f\n", pos.x, pos.y, pos.z);    // 1.000000 1.000000 1.000000: x, y, z로 접근

이처럼 익명 구조체와 익명 공용체를 사용하면 같은 값이지만 이름과 형태를 달리하여 접근할 수 있습니다.

지금까지 구조체와 공용체를 활용하는 방법을 배웠는데 구조체나 공용체가 여러 번 나오면서 문법이 좀 복잡했습니다. 일단은 구조체와 공용체가 이렇게 활용된다 정도로만 알아두고, 멤버가 변수이면 점, 포인터이면 화살표로 하위 멤버에 접근한다는 점만 기억하면 됩니다.