(*(volatile unsigned int *)0x0000FFF0)

(*(volatile unsigned int *)0x0000FFF0)

在MCU的底层驱动中经常看到这样的对寄存器地址操作的C语言写法,下面来一一分析下这个

为了简化对该表达式的理解可以分两步走

对上面表达式进行简化如下:

(*(volatile unsigned int *)(x))  注意这里将上面常量用一个变量替换是便于下面分析

再简化

p=(volatile unsigned int *)(x)

(*p)

再简化我们拿掉看不懂的volatile

1)       p=( unsigned int *)(x)

2)       (*p)

现在就很清楚了,第一个表达式将变量x转换为指针,该指针我们给它取名为p,原先x本来是存数据的,现在无非是拿来存地址了,就是这样。

第二个表达式就更简单了就是取该指针里的值

现在我们变换一下,将x变量换成常量,这里先给个值吧,比如就是标题的0x0000FFF0

还是一样分两步走

1)  p=( unsigned int *)(0x0000FFF0)

2)  (*p)

第一个表达式将常量转换为指针,第二个表达式就是取该指针所存取地址的值,现在问题来了那常数是不可以存地址的,所以很明显了这里常数就是该地址值,所以就可以概括了,就是0x0000FFF0地址的值

 

还有最后一个问题要解决了,就是这个类型转换前面的volatile

这个其实就是告诉编译器对该变量不要进行优化,每次都是从该地址读取数据,这样是为了防止一些错误。

还是举个例子来说好了

Int *a,int b;

b=(*a) *(*a);

单单看第二个表达式,可以知道需要在a所指向的地址连续取两次值,而计算机中一般取的值肯定是存在某一个存储空间上的,计算机在编译这段代码时会考虑到读取效率的问题,就会将读取两次值改为一次,怎么改呢,那就是先将a所指向的地址取一次值,然后保存起来,以后用到的话,就直接用保存起来的那个值就好了。

计算机优化后的代码可能长成这样:

Int *a,int b;

c= *a;

b=c*c;

但是若是在*a前面加了volatile情况就会像我们所想那样工作,而不会被编译器优化了,其实这个主要的好处还是为了减少错误,试着想一下,当将一个地址拿来的东西存到一个地方,万一那个地方出了问题,数据丢失了就糟糕了,当然这只是万一。

 

综合分析来看,为了提高代码执行效率,就不加volatile,有利于代码优化,提升计算机执行效率,但为了防止关键数据丢失或减少不确定性,就加volatile,减少错误发生。

最后要记住volatile:中文意思为易变的

posted @   idea~  阅读(202)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示