新浪博客

联合体union的使用方法以及Volatile注意

2017-11-18 18:08阅读:
union,中文名“联合体、共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。


区别:结构体(struct)中所有变量是“共存”的。
而联合体(union)中是各变量是“互斥”,完全就是共用一个内存首地址,并且各种变量名都可以同时使用,操作也是共同生效,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度,联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。
1.定义联合体:
typedef union _ADDR
{
unsigned int data16;
unsigned int data_16;
struct {
unsigned char data8L;
unsigned char data8H;
}data8;
}ADDR;
2.定义联合体变量:这样ADDR就是个union _ADDR类型的变量类型,可以直接去声明变量。
ADDR senddata;
3.初始化变量:
senddata.data16=0xffee;
4.输出:
printf('%X,%p',senddata.data8.data8H,&senddata.data8.data8H);
printf('%X,%p',senddata.data8.data8L,&senddata.data8.data8L);

printf('%X,%p',senddata.data_16,&senddata.data_16);


我们将联合体中的数据,以16进制打印,并打印出其首地址。
联合体union的使用方法以及Volatile注意
我们为联合体中数据长度最长的data16赋值为0xFFEE;
可以看到data8L与data16的首地址相同,并且取出其低8位。
data8H与data16的高8位相同。可以明显看到结构体与联合体的不同。


上述代码可以描述成这样一种关系:
联合体union的使用方法以及Volatile注意
data16与data8H与data8L共用一段内存。
妙用:
由此我们可以定义一个16位的数据类型。
unsigned int sampleCount;
将其强制转化为联合体
(((ADDR *)(&sampleCount))->data8).data8H=0xff;
(((ADDR *)(&sampleCount))->data8).data8L=0xee;
我们就可以对其高位及低位单独操作。


ps: ->与. 的区别???
答:->是指针访问方式,指针访问时要确保指针有效 假如 struct A *p2 =NULL; p2->a,这样程序就挂了。->前面放的是指针,而.前面跟的是结构体变量。


Volatile


volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。


联合体union的使用方法以及Volatile注意
首先这段代码理解: 0x40018004是寄存器地址,但是只是一个数值,所以需要将其转换成为一个地址(unsigned int *)然后对其地址进行赋值操作 *(unsigned int *0x40018004,但是可能在赋值操作之前这个地址中内容已经被改变,如果再使用ram中的值就会出现错误,为避免不可预知的bug,加上Volatile便会在每次使用时候都会重新读取寄存器的值。


作者声明:转载请声明出处。










我的更多文章

下载客户端阅读体验更佳

APP专享