转自
[url]http://blog.sina.com.cn/s/blog_662c785901013sq8.html[/url]
以前对C语言中的union一知半解,今天专门查阅相关资料总结一下:
1、 联合体union定义:
在C Programming Language 一书中对于联合体是这么描述的:
[color=red]1)联合体是一个结构;
2)它的所有成员相对于基地址的偏移量都为0;
3)此结构空间要大到足够容纳最"宽"的成员;
4)其对齐方式要适合其中所有的成员;[/color]
当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。(注意对此段对话的理解)
s占10字节,n占4字节,d占8字节,因此其至少需10字节的空间。然而其实际大小并不是10,[color=red]用运算符sizeof测试其大小为16[/color].这是因为这里存在字节对齐的问题,10既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包含的所有基本数据类型的大小所整除。
s占5字节,n占4字节,d占8字节,因此其至少需8字节的空间.而char型占用一个字节,int占用四个字节,double占用8字节,其最小公倍数为8字节,[color=red]所以U2也就是占用8字节就可[/color]以了。
下面结合实例予以说明:
下面是我整理的程序,在VS20O8下面编译通过:
这个例子在VC6.0中调试输出为0,5,6。该例程百度随处可见,非常典型,下面给出说明:
union类型是共享内存的,以size最大的结构作为自己的大小,这样的话,myun这个结构就包含u这个结构体,而大小也等于u这个结构体的大小,在内存中的排列为声明的顺序x,y,z从低到高,然后赋值的时候,在内存中,就是x的位置放置4,y的位置放置5,z的位置放置6。现在对k赋值,对k的赋值因为是union,要共享内存,所以从union的首地址开始放置,首地址开始的位置其实是x的位置,这样原来内存中x的位置就被k所赋的值代替了,就变为0了,这个时候要进行打印,就直接看内存里就行了,x的位置也就是k的位置是0,而y,z的位置的值没有改变,所以应该是0,5,6
[url]http://blog.sina.com.cn/s/blog_662c785901013sq8.html[/url]
以前对C语言中的union一知半解,今天专门查阅相关资料总结一下:
1、 联合体union定义:
在C Programming Language 一书中对于联合体是这么描述的:
[color=red]1)联合体是一个结构;
2)它的所有成员相对于基地址的偏移量都为0;
3)此结构空间要大到足够容纳最"宽"的成员;
4)其对齐方式要适合其中所有的成员;[/color]
当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。(注意对此段对话的理解)
union U1
{
char s[10];
int n;
double d;
};
s占10字节,n占4字节,d占8字节,因此其至少需10字节的空间。然而其实际大小并不是10,[color=red]用运算符sizeof测试其大小为16[/color].这是因为这里存在字节对齐的问题,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字节,[color=red]所以U2也就是占用8字节就可[/color]以了。
下面结合实例予以说明:
下面是我整理的程序,在VS20O8下面编译通过:
#include
union myun
{
struct
{
int x;
int y;
int z;
}u;
int k;
}a;
int main()
{
a.u.x =4;
a.u.y =5;
a.u.z =6;
a.k = 0;
printf("%d %d %d\n",a.u.x,a.u.y,a.u.z);
return 0;
}
这个例子在VC6.0中调试输出为0,5,6。该例程百度随处可见,非常典型,下面给出说明:
union类型是共享内存的,以size最大的结构作为自己的大小,这样的话,myun这个结构就包含u这个结构体,而大小也等于u这个结构体的大小,在内存中的排列为声明的顺序x,y,z从低到高,然后赋值的时候,在内存中,就是x的位置放置4,y的位置放置5,z的位置放置6。现在对k赋值,对k的赋值因为是union,要共享内存,所以从union的首地址开始放置,首地址开始的位置其实是x的位置,这样原来内存中x的位置就被k所赋的值代替了,就变为0了,这个时候要进行打印,就直接看内存里就行了,x的位置也就是k的位置是0,而y,z的位置的值没有改变,所以应该是0,5,6