一、const
它限定一个变量不允许被改变,产生静态作用。特别注意,const 与指针:
const int *p1 = &str; // p1 可变,* p1 不可变
int const *p2 = &str; // p2 可变,* p2 不可变,与上面语句等价
int* const p3 = &str; // p3 不可变,* p3 可变
二、extern
(1)函数前加 extern,仅仅是暗示这个函数可能在别的源文件中定义了,因为函数本身不加修饰的话就是 extern。
(2)变量前加 extern,对变量做出声明,表明这个变量在别的文件中定义了,如果要使用该变量,就去其它文件中找。
三、volatile
volatile 本意是 “易变的”,用来修饰变量并指明变量可能是易变的,因此必须要求从它所在的内存读取数据。
一般说来,volatile 用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加 volatile
2、修饰多线程共享的全局变量和 IO 内存要加 volatile
3、存储器映射的硬件寄存器通常也要加 volatile 说明,因为每次对它的读写都可能由不同意义
但我们要注意,“易变” 是由于外在因素引起的,如:多线程,中断等,并不是因为用 volatile 修饰的变量就一定会变化
,假如没有外因,即使用 volatile 定义,它也不会变化。
编译器的优化是因为访问内核中寄存器要比访问内存单元快的多,所以编译器一般都会减少存取内存的次数。
我们在 STM32 代码中常常看到有这些语句:
__O:输出口,限定编译器不能进行优化,不然你连续两次输出相同值,编译器认为没改变,就忽略了后面那一次输出,假如外部在两次输出中间修改了值,那就影响输出。