55.7 연습문제: 장치 옵션 구조체 만들기

다음 소스 코드를 완성하여 0x1107060504030201이 출력되게 만드세요.

practice_define_struct_device_option.c

#include <stdio.h>

struct DeviceOption {
    ____________________________
        unsigned long long option;
        ...
    ____________________________                            
};

int main()
{
    struct DeviceOption opt;

    opt.boot[0] = 0x01;
    opt.boot[1] = 0x02;
    opt.boot[2] = 0x03;
    opt.boot[3] = 0x04;
    opt.interrupt[0] = 0x05;
    opt.interrupt[1] = 0x06;
    opt.bus[0] = 0x07;
    opt.bus[1] = 0x11;

    printf("0x%llx\n", opt.option);

    return 0;
}

실행 결과

0x1107060504030201

정답

union {
    unsigned long long option;
    struct {
        unsigned char boot[4];
        unsigned char interrupt[2];
        unsigned char bus[2];
    };
};

해설

opt.boot, opt.interrupt, opt.bus에 인덱스로 접근하여 값을 할당한 뒤 printf에서 opt.option을 출력했을 때 값은 그대로지만 저장한 순서는 반대로 출력됩니다(리틀 엔디언). 따라서 boot, interrupt, busoption은 공용체 멤버입니다.

optionunsigned long long인데 boot는 4번, interrupt는 2번, bus는 2번 총 8번에 걸쳐 배열의 각 요소에 값을 저장하고 있습니다. optionboot, interrupt, bus의 크기가 같아지려면 자료형은 char 또는, unsigned char가 되고 배열의 크기는 boot[4], interrupt[2], bus[2]가 되어야 합니다.

boot, interrupt, bus는 독립적인 공간을 가져야 하므로 구조체로 묶어주고, 이 구조체와 option을 공용체로 묶어주면 됩니다. 여기서 boot, interrupt, bus, option모두 opt.boot, opt.interrupt, opt.bus, opt.option처럼 구조체 변수에서 직접 접근하고 있으므로 익명 구조체입니다.