union与大小端

  union是C语言中的一个关键字,它的用法其实与struct很相似。
  union中的所有数据成员共用一个空间,同一时间只能存储其中的一个数据成员,并且所有的数据成员有相同的起始地址。例如:

union U
{
     double d;
     int i;
     char c;
     float f;
}u;

  我们可以使用sizeof来检测一下上面例子的大小,可以发现它的大小是其中最大长度double类型的大小,是8个字节。
  


大小端堆union类型数据的影响

首先解释一下什么是大小端?

大端(Big_endian)字数据的高字节存储在低地址中,字数据的低字节存储在高地址中。
小端(Little_endian)字数据的高字节存储在高地址中,字数据的低字节存储在低地址中。

  union型数据所占的空间等于其最大的成员所占的空间,对union型成员的存取都从相对于该联合体基地址的偏移量为0开始,也就是说对于联合体的访问,不论是哪个变量都是从union的首地址开始,所以机器大小端的不同会对union型的数据产生影响。举一个例子:

void test()
{
     union
     {
          int i;
          char a[2];
     }*p, u;
     p = &u;
     p->a[0] = 0x39;
     p->a[1] = 0x38;
     printf("%x", p->i);
}

这个程序会打印出来什么数据呢?
  通过vs2013测试,发现打印出来的是0xcccc3839。我们打开内存窗口,通过调试,可以发现内存第一行中左边是低地址,右边是高地址,而打印出来的数据的高字节存储在内存的高地址中,低字节存储在内存的低地址中,由此,也可以判断,我的电脑是小端。
至于在大端的电脑下运行结果,通过推断也可以看出来是0x3938cccc


  现在有一道题:请写一个C函数,若处理器是大端的,则返回0;若是小端的,则返回1。
这道题,我们可以通过联合体来解决。首先,我们定义一个int类型的变量,看一下他在内存中如何存储?

  通过联合体所有成员起始地址一样的特点,此时,我们取其最低位的一个字节,可以发现,如果是大端,则得到的是0,如果是小端,得到的是1。
代码如下:

int CheckSystem()
{
     union check
     {
          int i;
          char c;
     }c;
     c.i = 1;
     return c.c;
}

测试发现,结果正确:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值