Union中的所有元素共用一块内存单元,它的size大小等于所有元素中size最大的那个元素。
union维护足够的空间来放置多种数据成员中的 "一种",而不是为每一个数据成员分配空间。
在union中所有的数据成员共用一个空间,同一时间只能存储器中一个数据成员,所有的数据成员具有相同的起始地址。
来看一个例子说明一下吧:
例1:
union student
{
char sex;
int number;
double score;
};
int main()
{
union student STU;
printf("%d\n",sizeof(STU));//最大的那个数据类型,double是8个字节。
system("pause");
return 0;
}
下面看一下起始地址:
例2:
union student
{
char sex;
int number;
double score;
};
union
{
int i;
char a[2];
}*p,u;
int main()
{
p = &u;
p->a[0] = 0x39;
p->a[1] = 0x38;
printf("p->i = 0x%x\n",p->i);//0x3839,是小端模式
printf("&(p->a[0]) = 0x%x\n",&(p->a[0]));
printf("&(p->a[1]) = 0x%x\n",&(p->a[1]));
printf("&(p->i) = 0x%x\n",&(p->i));
union student STU;
STU.number = 100;
printf("%d\n",sizeof(STU));//最大的那个数据类型,double是8个字节。
printf("&STU = 0x%x\n",&STU);
printf("&STU.number = 0x%x\n",&STU.number);
printf("&STU.sex = 0x%x\n",&STU.sex);
printf("&STU.score = 0x%x\n",&STU.score);//输出了相同的地址
system("pause");
return 0;
}
看一下调试结果:
可以看出number=10,sex='d' ,字母d的ASCII就是100.
至于score的取值,这个你要学习一下专门的计算方法了,它的存储比较特殊,是按照整数,小数结合的算法计算出来的,感兴趣的可以学习一下。
输出结果:
下面这个例子有点复杂,可以参照 http://blog.csdn.net/dongyanxia1000/article/details/50555449 先看一下。
例3:
union uni{
struct{
char *p1;
int n1;
}s1;
struct{
char *p2;
int n2;
int n3;
}s2;
};
int main()
{
union uni u;
u.s1.p1=(char*)&u.s2.n3;//p1,p2都指向n3
u.s2.p2=(char*)&u.s2.n2;//p1,p2的指向发生改变,都指向n2
u.s2.n2=0x55555555;//n2,n1的值都是0x55555555
u.s2.n3=0xffffffff;//n3的值是0xffffffff
u.s1.n1=0x22222222;//n1,n2的值发生改变,此刻的值是0x22222222
printf("%d\n",(int)(int*)&u.s1.p1);
printf("%d\n",(int)(char *)&u.s1.p1);
printf("%d\n",(int)(int*)&u.s1.n1);
printf("%d\n",(int)(int*)&u.s2.p2);
printf("%d\n",(int)(int*)&u.s2.n2);
printf("%d\n",(int)(int*)&u.s2.n3);
printf("%x\n",(int)u.s2.n2);
printf("%x\n",(int)u.s2.n3);
printf("%x\n",(int)u.s1.n1);
printf("%d %d\n",sizeof(u),sizeof(&u));//12,4
printf("%d %d\n",(int*)&u.s1.n1-(int*)&u.s2.p2,(int*)&u.s2.n3-(int*)&u.s1.n1);//1,1
printf("%d %d\n",(char*)&u.s1.n1-(char*)&u.s2.p2,(char*)&u.s2.n3-(char*)&u.s1.n1);//4,4
printf("%d %d\n",(int)(int*)&u.s1.n1-(int)(int*)&u.s2.p2,(int)(int*)&u.s2.n3-(int)(int*)&u.s1.n1);//4,4
printf("%d\n",u.s1.p1);
system("pause");
}
输出结果显示:
解析:
struct s1 和struct s2共用一块内存。注意结构体内满足内存对齐,起始地址是4的倍数。具体方法请看:
http://blog.csdn.net/dongyanxia1000/article/details/50770787
struct s1的大小是8 bytes.struct s2的大小是12 bytes.
union u的大小是两个中较大的那个,所以sizeof(u)=12, 因为&u是地址,占4个字节。
通过输出的地址结果可以看出:
p1和p2的地址是相同的,n1和n2的地址是相同的,改变n1/n2的值,两者的值同时都改变了。
还有一个就是指针类型的转换,(int *)指向一个整型的指针,(char *)指向一个字符的指针。