联合体与大小端存储

union{
    int val;
    char str[2];
}obj;

int main()
{
    obj.str[0] = 10;
    obj.str[1] = 1;
    cout<<obj.val;
    return 0;
}

使用小端方式存储,上述代码的输出结果为:266.
这里写图片描述
可以看到,obj.val中存储的是010a,对应的二进制位0000 0001 0000 1010,转换为十进制,(256+8+2)即为266.
为什么呢?这就要涉及两个内容:联合体和大小端存储。

联合体

联合体就是存储空间共享的一种机制,可以用不同的方式去访问它。也可以理解为同一个存储空间具有不同的类型,但同一时间仅仅能存放当中的一种。

联合体全部成员的首地址都是一样的(共享同一块内存空间)。

联合体所占的内存的长度,一般等于其最大成员的内存长度。

联合体成员的对齐方式要适合全部的成员。
union Demo
{
int a;// 4个字节
char b;// 2个字节
long long c;// 8个字节
char d[11];// 11个字节
};
sizeof(Demo) = 16.
上面联合体变量demo的大小之所以不是11个字节而是16个字节,是由于这里存在字节对齐问题:
11既不能被2整除,也不能被4,、8整除,因此补充字节到16,因此就符合全部成员自身内存对齐了。
这里能够看出联合体所占空间的大小,不仅取决于最大成员的内存大小。并且跟全部成员的数据类型有关系。其大小必须满足两个必须条件:
1、大小足够容纳其最宽的成员。
2、大小能被全部成员类型的大小所整除。

大、小端存储

小端:将数据的低位存放在低地址处,将数据的高位存放在高地址处。
大端:将数据的低位存放在高地址处,将数据的高位存放在低地址处。

一般操作系统都是小端,而通讯协议是大端的。

测试系统是大端还是小端

使用联合体即可测试

//判断系统是大端还是小端:通过联合体,因为联合体的所有成员的首地址相同,都从低地址开始存放
int fun1()
{
    union test
    {
        int i;
        char c;
    };

    test t;
    t.i = 1;

    //如果是大端,则t.c为0x00,则t.c!=1,返回0 是小端,则t.c为0x01,则t.c==1,返回1
    return (t.c==1);
}

版权声明:本文为qq_24336773原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。