网站建设样式,设计制作软件,申请备案 关网站,普达建站快车目录
概念#xff1a;
联合的声明#xff1a;
类比结构体#xff1a;
联合体的大小#xff1a;
联合的⼤⼩⾄少是最⼤成员的⼤⼩ 联合体的空间是共用的
联合体内部成员的赋值#xff1a;
当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候#xff0c;就要对⻬到最⼤对⻬…目录
概念
联合的声明
类比结构体
联合体的大小
联合的⼤⼩⾄少是最⼤成员的⼤⼩ 联合体的空间是共用的
联合体内部成员的赋值
当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候就要对⻬到最⼤对⻬数的整数倍。
利用联合体判断当前机器是⼤端还是⼩端
什么是大端小端
简单介绍一下
代码演示 概念
联合也是一种特殊的自定义类型。
这种类型定义的变量也包含一系列的成员特征是这些成员公用同一块空间(所以联合也叫共用体)。
联合的声明
union un
{int a;char c;
}u;union是联合的关键字不可更改。un 是联合的标签相当于联合的名字可以更改。{}花括号内部的是联合体的成员和结构体一样是一个不同类型数据的集合。u表示的是该联合类型创造的变量。
类比结构体 联合体类比与结构体或者说各方各面都和结构体类似但是有一点不同。如果将结构体比作一栋楼那么这栋楼内有很多层住户每一个住户都有各自的独立的空间。而相比于结构体联合体更像是一个出租屋里面有好几位租客它们很多的生活空间都是共用的。 联合体的大小
联合的⼤⼩⾄少是最⼤成员的⼤⼩
union un
{int a;char c;
}u;int main()
{int ret sizeof(u);printf(%d\n,ret);return 0;
}
从以上代码来看int 类型的a占据了四个字节而char 类型的c占据一个字节那么理论上联合体占据的总字节应该是5个字节。
但是答案是这样吗 并不是这其实原理来自于联合体的特点之一联合的⼤⼩⾄少是最⼤成员的⼤⼩。
如上文说过联合体好比一个出租屋很多的生活空间都是共用的。
所以联合体是开辟了一块大空间让内部的成员一起使用。 联合体的空间是共用的
又比如
union un
{int a;char c;
}u;int main()
{printf(%p\nu);printf(%p\n(u.a));printf(%p\n(u.c));return 0;
}
最终的答案是 这样能够证明联合体的空间是共用的。
联合体内部成员的赋值
上文讲诉了联合体的空间内部就像合租一样是共用空间的。 所以当赋予一个联合体成员数值的时候其他的联合体成员是会被该成员的数值覆盖。
例如
union un
{int a;char c;
}u;int main
{union Un u;u.a 0x11223344;u.c 0x00;return 0;
} 我们先后对成员a和成员c进行赋值。按照之前的说法给成员c赋值那么成员c所在的空间中的成员a的数值就会被c的数据覆盖或者给成员a赋值那么成员c所在空间的数据就会被a覆盖。 进行调试 这是对int 类型的成员a进行赋值后。 随后又对char类型的成员c进行了赋值。
得到的结论如以上说法一致。这种覆盖赋值的模式类似与共享单车。 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候就要对⻬到最⼤对⻬数的整数倍。
union un
{char arr[5];int i;
}u;int main()
{printf(%d\n,sizeof(union un));return 0;
}以上代码是求联合体的字节数按照之前的说法 “ 联合的⼤⼩⾄少是最⼤成员的⼤⼩。”
char arr[5]的字节大小是5而int i 的字节大小是4那么联合体大小一定是最大的成员的大小也就是char arr[5]的大小5个字节。
答案真是如此吗 错误这里涉及到了联合体成员内存对齐的原理。 char arr[5]相当于写了五个char所以最大其实是int 但是空间不够啊所以应该用对齐解决而int的默认对齐数是8 所以最大字节数是8。
又列如
union un
{short arr[7];int i;
}u;int main()
{printf(%d\n,sizeof(union un));return 0;
}short arr[7]占据的是14个字节int i占据的是4个字节而这里求除的联合体大小是16个字节是最大类型 int 的字节数的4倍。 利用联合体判断当前机器是⼤端还是⼩端
什么是大端小端
大端小端是内存存储数据的方法而内存存储数据一般是二进制数位进行存储所以这里便有了区分。
简单介绍一下
int i 1
1的十六进制数位0x 00 00 00 01 去除前缀0x十六进制数位从低到高是 01 00 00 00 这就是小端而十六进制数位从高到低 00 00 00 01 这就是大端。
而判断机器的是大端还是小端则是判断这十六进制数位的最前端的字节到底是00还是01如果是00那么是大端如果是01那么是小端。这里使用整型数字1的十六进制数位进行判断
而在此时便可以利用联合体的特点。
代码演示
int check_sys()
{union{int i;char c;}un;un.i 1;return un.c;
}通过提取出 int 类型的成员i 并进行赋值而后返回char类型的成员c进行读取因为联合体的特点这两个成员都处在一个空间且成员c是char类型并没有进行赋值所以再返回后读取的其实是int类型的成员i的数据也是int类型成员i的最前端的空间数据。
也就是可以使用以上代码读取整型数字1再该编译器中使用的是大端还是小端。