联合体(union)共用一个内存首地址,并且各种变量名都可以同时使用,操作也是共同生效。
第一种
下边示范了一种用途,代表四个含义的四个变量,但是可以用一个int来操作,直接int赋值,无论内存访问(指针大小的整数倍,访问才有效率),还是时间复杂度(一次和四次的区别,而且这四次有三次都是不整齐的地址),都会低一些。
#include<stdio.h>
union var{
char c[4];
int i;
};
int main(){
union var data;
data.c[0] = 0x04;//因为是char类型,数字不要太大,算算ascii的范围~
data.c[1] = 0x03;//写成16进制为了方便直接打印内存中的值对比
data.c[2] = 0x02;
data.c[3] = 0x11;
//数组中下标低的,地址也低,按地址从低到高,内存内容依次为:04,03,02,11。总共四字节!
//而把四个字节作为一个整体(不分类型,直接打印十六进制),应该从内存高地址到低地址看,0x11020304,低位04放在低地址上。
printf("%x\n",data.i);
}
假设结果:
11020304
则证明这个32位linux是小端(little-endian)
第二种
下面的程序是米科的流量计中数据处理的例程,C语言版本的。
void V77_Instant(void)
{
signed long ddd,eee;
float temp;
WriteMenu(0,0,0,8,0);
WriteMenu(4,0,0,9,0);
union ieee754_to_float
{
unsigned char IEE[4];
float FLOA;
};
union ieee754_to_float Change;
Change.IEE[3] = RS485_Recievebuf[3]; /////////////////////////////瞬时流量
Change.IEE[2] = RS485_Recievebuf[4];
Change.IEE[1] = RS485_Recievebuf[5];
Change.IEE[0] = RS485_Recievebuf[6];
temp = Change.FLOA;
ddd = (signed long)(temp*100000);
disp_511_Number(2,0,ddd,10,5);//显示瞬时流量
switch(RS485_Recievebuf[36]) //显示瞬时流量单位
{
case 0x00:WriteMenu(2,96,0,13,0);break;
case 0x01:WriteMenu(2,96,0,14,0);break;
case 0x02:WriteMenu(2,96,0,15,0);break;
case 0x03:WriteMenu(2,96,0,16,0);break;
case 0x04:WriteMenu(2,96,0,17,0);break;
case 0x05:WriteMenu(2,96,0,18,0);break;
case 0x06:WriteMenu(2,96,0,19,0);break;
case 0x07:WriteMenu(2,96,0,20,0);break;
case 0x08:WriteMenu(2,96,0,21,0);break;
default:break;
}
Change.IEE[3] = RS485_Recievebuf[7]; ////////////////////////////瞬时流速
Change.IEE[2] = RS485_Recievebuf[8];
Change.IEE[1] = RS485_Recievebuf[9];
Change.IEE[0] = RS485_Recievebuf[10];
temp = Change.FLOA;
eee = (signed long)(temp*100000);
disp_511_Number(6,0,eee,10,5);//显示瞬时流速
WriteMenu(6,96,0,22,0); //显示瞬时流速单位
}
这里有段union的使用。建立一个union进行类型转换。
通过485串口读出来的buff转换为float
union ieee754_to_float
{
unsigned char IEE[4];
float FLOA;
};
union ieee754_to_float Change;
Change.IEE[3] = RS485_Recievebuf[3]; /////////////////////////////瞬时流量
Change.IEE[2] = RS485_Recievebuf[4];
Change.IEE[1] = RS485_Recievebuf[5];
Change.IEE[0] = RS485_Recievebuf[6];
temp = Change.FLOA;

Comments | NOTHING