联合:
(1)联合的语法和用法与结构非常相似
(2)联合与结构的主要区别在于,联合的所有成员从一个地址开始,即共享一块内存区域
(3)联合变量的字节数就是其最大成员的字节数
(4)利用联合可以将同一份数据解释为不同的类型
union x {
char a;
short b;
int c;
double d;
}
因为共享,数据肯定覆盖
//联合体演示
#include <stdio.h>
int main(void) {
union {
unsigned int un;
unsigned char uc[4];
}mb;//直接定义联合体变量mb,分配4字节
mb.un = 0x12345678;//向4字节内存写入数据0x12345678
for(int i = 0; i < sizeof(mb.uc)/sizeof(mb.uc[0]); i++)
printf("%#x ", mb.uc[i]);
printf("\n");
mb.uc[2] = 0x43; //0x34->0x43
printf("%#x\n", mb.un);
return 0;
}
到12行,输出的结果是 0x78 0x45 0x34 0x12,即数据的地位放到内存的低地址,数据的高位放到内存的高地址
而后思考一个问题,数据的地位放到内存的低地址,数据的高位放到内存的高地址,那可不可以不这么放呢?
引入一个概念:
CPU的两种模式:大端模式和小端模式
大端模式:数据的低位放到内存的高地址,数据的高位放到内存的低地址。
例:int a =0x12345678;
0-----1-----2-----3-----4------>地址依次增大
0x12 0x34 0x56 0x78
比如基站用的power pc处理器就是大端模式的CPU
小端模式:数据的低位放到内存的低地址,数据的高位放到内存的高地址、
例:int a =0x12345678;
0------1------2-------3------4------>
0x78 0x56 0x34 0x12
比如 PC机电脑和手机的处理器都是小端模式
(只有汇编语言可以去切换大小端模式)
试题:编程求大小端,可以采用联合体或者指针
//联合体演示
#include <stdio.h>
int main(void) {
union {
unsigned int un;
unsigned char uc[4];
}mb;//直接定义联合体变量mb,分配4字节
mb.un = 0x12345678;//向4字节内存写入数据0x12345678
for(int i = 0; i < sizeof(mb.uc)/sizeof(mb.uc[0]); i++)
printf("%#x ", mb.uc[i]);
printf("\n");
mb.uc[2] = 0x43; //0x34->0x43
printf("%#x\n", mb.un);
//采用联合体求大小端
mb.un = 1;
if(mb.uc[0])
printf("小端.\n");
else
printf("大端.\n");
//采用指针
short a = 1;
if(*(char *)&a) //先对a取地址,然后强转为char型指针,然后解引用取第一字节值
printf("小端.\n");
else
printf("大端.\n");
return 0;
}
联合体的实际应用:
手机端给某设备发送一条48字节的数据包
设备端需要接收。
方法一:
unsignef char buf[48];
解析48字节数据包:
buf[0]+buf[1]+buf[2]+buf[3]组成头;
buf[4~44]:原始数据;
buf[4]:尾
方法二:利用联合体
union{
unsigned char buf[48]
struct msg{
unsigned int head;
unsigned char data[40];
unsigned int tail;
};
}
因为联合体共享内存空间,所以head指向前四个字节,data指向原始数据,tail指向结尾。