加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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

(2017-11-18 18:08:35)
分类: 编程
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\n",senddata.data8.data8H,&senddata.data8.data8H);

printf("%X,%p\n",senddata.data8.data8L,&senddata.data8.data8L);

 

printf("%X,%p\n",senddata.data_16,&senddata.data_16);


我们将联合体中的数据,以16进制打印,并打印出其首地址。

http://s2/bmiddle/006eMpwqzy7fUf8gAgx31&690

我们为联合体中数据长度最长的data16赋值为0xFFEE;

可以看到data8L与data16的首地址相同,并且取出其低8位。

data8H与data16的高8位相同。可以明显看到结构体与联合体的不同。


上述代码可以描述成这样一种关系:

http://s3/small/006eMpwqzy7fUfLzXfs22&690
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的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。


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


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








0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有