共用体定义与使用
// 共用体类型定义
union s
{
int a;
char b;
};
union s p1; // 共用体变量的定义
p1.a = 23; // 共用体元素的使用
共用体与结构体异同点
共用体union和结构体struct在类型定义、变量定义、使用方法上很相似。
共用体和结构体不同:
1、结构体类似于一个包裹,结构体中的成员彼此是独立存在的,分布在内存的不同单元中,他们只是被打包成一个整体叫做结构体。
共用体中的各个成员其实是一体的,彼此不独立,他们使用同一内存单元。可以理解为:有时候是这个元素,有时候是那个元素。
2、每个成员占用的内存空间是相同的,只是解析方式不同。
3、union的sizeof测到的大小,实际上是union中各个元素里面占用内存最大的那个元素的大小。
4、union中的元素不存在内存对齐的问题,因为union中实际只有1个内存空间,都是从同一地址开始的
共用体的主要用途
1、共用体用在对同一个内存单元进行多种不同规则解析的这种情况。
2、C语言中其实是可以没有共用体的,用指针和强制类型转换可以替代共用体完成同样的功能,但是共用体的方式更简单好理解。
共用体应用
大小端模式
出现大小端的背景: 在计算机通信发展起来之后,串口等串行通信中,一次只能发送1个字节。
这时候就会出现一个问题: 发送数据时是要从高位开始发送还是低位开始发送?
规则就是发送和接收方必须按照同样的字节顺序来通信,否则会出现错误。
现在大小端模式更多指的是计算机系统的大小端。
大端模式(big endian): 高字节对应内存高地址
小端模式(little endian): 高字节对应内存低地址
大端模式和小端模式本身是没有对错的,理论上按照大端或则小端都是可以的。但是要求必须存储时和读取时按照相同的大小端进行,否则会出错。
有些芯片用大端模式(如:C51单片机),有些CPU用小端模式(如:ARM、INTEL)
当不确定当前的环境是大端模式还是小端模式时,就要用代码先去验证。要如何验证?
1、共用体union
union myunion
{
int a;
char b;
};
// 测试
union myunion s;
s.a =1;
s.b = ?;
2、指针方式
int a =1;
char b = (*(char *)(&a));
分析一些看似可以用来测试大小端模式,实际上是不能测试的方法
1、位与运算
位与运算是编译器提供的运算,这个运算时高于内存层次的或者说&运算在二进制层次具有可移植性。&运算一定是高字节&高字节,低字节&低字节,和二进制存储无关。
2、移位
和上面的原因一样。因为C语言对运算符的级别是高于二进制层次的。
3、强制类型转换
和上面的原因一样。因为C语言对运算符的级别是高于二进制层次的。