首先,我们来看一段代码。
union Un
{
int a;
char b;
};
int main()
{
union Un u;
printf("%d\n", sizeof(u));
return 0;
}
看到结果,一些地球人可能会感到诧异,那么,现在就来解释一下其中的原理吧!
联合在内存中的储存方式
要想明白联合的大小,就要先了解联合中变量在内存中的储存方式,于是我们可以用下面代码来探究。
union Un
{
int a;
char b;
};
int main()
{
union Un u;
printf("%d\n", sizeof(u));
printf("%p\n", &u);
printf("%p\n", &(u.a));
printf("%p\n", &(u.b));
return 0;
}
union Un
{
int a;
char b;
};
int main()
{
union Un u;
u.a = 0x11223344;
u.b = 0x00;
return 0;
}
a的地址:
修改b的地址后,a的地址:
由结果可知,联合的储存方式并不是像一般的数据储存。而是像下面这样
所以我们可以知道联合的成员是共用一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少有能力保存最大的那个成员)。
计算方法
大致了解了联合在内存中的储存方式,接下来,我们开始具体讲解联合大小的计算方法。
例子1:
union Un
{
char arr[5];//对齐数1
int i;//对齐数4
};
int main()
{
printf("%d\n", sizeof(union Un));
return 0;
}
联合中数据的储存需要对齐,数组arr为char型所以对齐数为1,同理,i为4,所以联合中最大的对齐数为4,那么最后联合的大小就必须为4的倍数。
储存位置如图
虽然有效的空间只有1到5但是,因为5不是4的倍数,所以6到8这三个字节就会被浪费掉,最后联合的大小为8。
例子2:
union Un
{
short arr[7];//对齐数2
int i;//对齐数4
};
int main()
{
printf("%d\n", sizeof(union Un));
return 0;
}
数组arr对齐数为2,变量i对齐数为4,所以联合中最大的对齐数为4,那么最后联合的大小就必须为4的倍数。
因为14不为4的倍数,所以15和16两个字节被浪费掉,最后联合的大小为16。