今天休息,本不打算写文章,一个偶然的机会让我好好认识了一下C语言中的联合体,以前也木有深究,今天在这里好好总结一番(当然本文也是查阅了很多资料后写的):
1、 联合体union定义:
当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。在C Programming Language 一书中对于联合体是这么描述的:
1)联合体是一个结构;
2)它的所有成员相对于基地址的偏移量都为0;
3)此结构空间要大到足够容纳最"宽"的成员;
4)其对齐方式要适合其中所有的成员;
下面解释这四条描述:
由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成
员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。实例如下:
union U1
{
char s[10];
int n;
double d;
};
s占10字节,n占4字节,d占8字节,因此其至少需10字节的空间。然而其实际大小并不是10,用运算符sizeof测试其大小为16.这是因为这里存在字节对齐的问题,10
既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,
即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包含的所有基本数据类型的大小所整除。
union U2
{
char s[5];
int n;
double d;
};
s占5字节,n占4字节,d占8字节,因此其至少需8字节的空间.而char型占用一个字节,int占用四个字节,double占用8字节,其最小公倍数为8字节,所以U2也就是占用8字节就可以了。
相信大家现在对联合体也有了一个较为详细的了解了吧。。。。下面就用一些程序实例来对联合体进行测试吧。。。。
#include<iostream>
using namespace std;
union T
{
char a[2];
int i;
}b;
int main()
{
b.a[0]=12;
b.a[1]=1;
cout<<b.i<<endl;
printf("%d\n",sizeof(b));
return 0;
}
程序运行结果为:268
4
下面我们就来分析以上两个数据。数据4:char类型占用一个字节,int占用4个字节,其最小公倍数为4,而a[2]占用两个字节,综合得出union占用4字节。由于该处的a[1]和a[0]均是十进制,所以十进制转化成高、低八位的二进制为00000001 00001100,最终用十进制输出即为268.
下面再看一个例子:
#include<iostream>
using namespace std;
union T
{
char a[2];
int i;
}b;
int main()
{
b.a[0]=0x0c;
b.a[1]=0x01;
cout<<b.i<<endl;
printf("%d\n",sizeof(b));
return 0;
}
此处只是将a[1]、a[0]写成十六进制
其输出结果为:268
4
原理也一样,这里不再赘述。