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

分类: 编程 |
而联合体(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
*)然后对其地址进行赋值操作
作者声明:转载请声明出处。