union的二种用法

发布于 2019-09-17  143 次阅读


联合体(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;

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。