struct的成员各自有自己的内存空间,各自使用互不干涉,一个struct变量的总长度不小于所有成员的长度之和,由于遵循内存对齐原则总长度可能会变大。
union各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址。因而,联合体比结构体更节约内存。一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍。
一、对比struct和union占用内存大小
#include<stdio.h>
struct u1
{
char a;
int b;
short c;
}U1;
union u2
{
char a;
int b;
short c;
}U2;
int main()
{
printf("%d\n", sizeof(U1)); //12
printf("%d\n", sizeof(U2)); //4
return 0;
}
造成以上差异的原因是union的所有成员共用一块内存,一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍,char1个字节,int4个字节,short2个字节,所以该union所占内存空间大小为4个字节(测试平台是32位,下同)。
二、union成员赋值
#include<stdio.h>
union u1
{
char a;
int b;
short c;
}U1;
int main()
{
U1.a = 'a';
printf("%c%c\n", U1.b, U1.c); //aa
U1.a = 'b';
printf("%c%c\n", U1.b, U1.c); //bb
U1.a = 0x41;
printf("%c%c\n", U1.b, U1.c); //AA
U1.b = 0x4241;
printf("%c%c\n", U1.a, U1.c); //AA
printf("%p %p %p\n", &U1.a, &U1.b, &U1.c); //三个地址一致
return 0;
}
三、union大小计算
#include<stdio.h>
union u1
{
char a;
int b;
short c;
double d;
int e[5];
}U1;
int main()
{
printf("%d\n", sizeof(U1)); //24
return 0;
}
union大小计算准则:1、至少要容纳最大的成员变量 ;2、必须是所有成员变量类型大小的整数倍。
至少容纳最大e[5]为4*5字节,同时是所有成员变量类型大小的整数倍,double8字节整数倍,因此该联合体占内存24字节。
四、struct字节对齐
pragma pack (2) 指定按2字节对齐
pragma pack () 取消指定对齐,恢复缺省对齐
#include<stdio.h>
struct u4
{
int a;
char b;
short c;
}U4;
struct u5
{
char b;
int a;
short c;
}U5;
#pragma pack (2)
struct u6
{
char b;
int a;
short c;
}U6;
#pragma pack ()
int main()
{
printf("%d\n", sizeof(U4)); //8
printf("%d\n", sizeof(U5)); //12
printf("%d\n", sizeof(U6)); //8
return 0;
}