欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

union与大小端

程序员文章站 2022-04-22 12:08:21
...

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

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

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


大小端堆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
union与大小端


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

union与大小端

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

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

测试发现,结果正确:
union与大小端

相关标签: union 大小端