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;
}
测试发现,结果正确:
上一篇: Mac OS X 安装Maven
下一篇: 大小端模式详解及其测定