그림 54-1 구조체 그림을 보면 1바이트, 1바이트(패딩), 2바이트, 4바이트 순으로 정렬되어 있습니다. 그런데 51단원에서 가장 큰 자료형 크기의 배수로 정렬 한다고 배웠는데 그렇다면 1바이트, 3바이트(패딩), 2바이트, 2바이트(패딩), 4바이트 이렇게 정렬 되어야 하는 것 아닌가요? 이해가 가지 않아 질문 남깁니다!
구조체와 공용체는 다릅니다.
그림 54-1까지 보고 질문이라면 해당 단원을 끝까지 공부하고 UNIT 55에서 구조체와 공용체 활용까지 보는 게 좋을 것 같습니다.
공용체는 가장 큰 자료형의 공간을 공유합니다.
그림 54-1에서 보면 int가 가장 크고, int면 4바이트 공간이니까 패딩이 필요 없습니다. char, short에 패딩이 들어가지 않습니다. int와 공간을 다 공유하니까요.
#define _CRT_SECURE_NO_WARNINGS // strcpy 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h> // strcpy 함수가 선언된 헤더 파일
union Box { // 공용체 정의
short candy; // 2바이트
char snack; // 1바이트
// char doll[8]; // 8바이트
};
union Box2 { // 공용체 정의
short candy; // 2바이트
char snack; // 1바이트
char doll[3]; // 3바이트
};
union Pad {
char arr[sizeof (double) + 1];
double d;
};
int main()
{
union Box b1; // 공용체 변수 선언
union Pad p;
union Box2 b2;
printf("%u\n", sizeof(b1));
printf("%u\n", sizeof(b2));
printf("%u\n", sizeof(double));
printf("%u\n", sizeof(p));
return 0;
}
결과는 다음과 같습니다. 64비트 환경의 실행 결과입니다.
2 4 8 16
union Box는 short, char만 있습니다. 이 경우 가장 큰 타입은 short이므로 2바이트이고, 가장 작은 배수이므로 2바이트 크기가 됩니다.
union Box2는 char doll[3]으로 3바이트를 의도적으로 끼워 넣었습니다.
이 경우 2, 1, 3바이트 조합이므로 3바이트가 가장 크고 정렬이 맞지 않으므로 가장 가까운 정렬인 4바이트에 맞춰지니까 4가 출력됩니다. short이 가장 큰 타입이니 2바이트 단위로 맞춰집니다. char doll[9]로 출력해보면 10이 출력될 겁니다. char doll[10]으로 해보면 10이 나옵니다(딱 일치)
union Box2 { // 공용체 정의
int candy; // 4바이트
char snack; // 1바이트
char doll[9]; // 9바이트
};
int candy로 바꿔보면 doll[9]일 때 9바이트가 아니고, int 4바이트 크기로 정렬이 맞춰지니까 12가 출력됩니다.
union Pad는 64비트 환경에서 double은 8바이트이므로 d는 8바이트인데, sizeof(double) + 1 = 9바이트이므로 char arr[9]가 됩니다. 역시나 1바이트만 초과해도 정렬이 맞지 않아서 결과는 16이 됩니다. 여기서는 double이 가장 큰 타입이니 8바이트 단위로 정렬이 맞춰집니다.
char arr[17]로 바꿔보면 24가 출력됩니다.
숫자를 바꿔서 다양하게 테스트해보면 됩니다.
나머지 단원을 꾸준히 학습하세요.