Union -- 公用体和内存对齐

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 *)指向一个字符的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值