volatile的关键字的一些思考

来源:互联网 发布:天启抢购软件靠谱吗 编辑:程序博客网 时间:2024/05/18 03:37

       最近在深入了解C关键字,觉得volatile这个关键字很难把握,volatile修饰的变量表示这个变量是易被修改的,因此在读这个变量时编译器不要对其进行优化,而是每次到内存中去读取其值,这样能保证读到的值是准确的。

        那么一个变量会被那些突发情况修改,而导致下次读取这个值时已经改变。

        1、中断服务子程序。

         2、任务切换。

        因此我们看到的文章经常会出现一个例子如下

        char a,b;

        void main()

{

a = 2;

b = a;

}

void ISR()

{

a = 3;

}

如果a不描述为volatile变量则b读到的值可能不是实时跟新后的a值,因为编译器会将

b = a;

优化成:

MOV addr(b),#02

这样将会与我们的本意不符,因此a最好描述成volatile变量。

那么接着往下走,一个指针变量可以修饰成volatile变量吗?

答案肯定是可以的,但是指针变量就稍微复杂一点,因为指针变量涉及两个部分,一是指针变量本身,还有一个是指针指向的值。因此有下面三种情况出现。

        1、char * volatile reg;  //指针变量本身是volatile,指针指向的值不volatile

2、volatile char *reg;  //指针变量本身不是volatile,指针指向的值volatile

3、volatile char *volatile reg; //指针变量本身是volatile,指针指向的值也volatile

在这里你是不是想起了const,对volatile的位置也很关键。

我们知道const修饰的变量表示是这个变量不能被修改,而volatile修饰的变量表示这个变量是易被改写的,那么一个变量能不能即被描述成const又被描述成volatile呢?很多文章说是可以的但举得例子是什么:如只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。但状态寄存器并不是我们定义的变量,要知道一个变量被定义成const就表示他是不会变了,至于读取这个值是从寄存器备份中读取还是从地址里读取都是一样的,那么有没有一种特殊情况是需要这样描述的呢,这里推荐一个博客给大家看看。

http://blog.csdn.net/hxg130435477/article/details/6883101

这就涉及到关键字的作用范围。

例子:

//main.c

const volatile charjkkl;
void main()
{
char p1,p2;
p1 = jkkl;
p2 = jkkl;
while(1);
}
/
/ISR.c

extern volatile char jkkl;
void ISR()
{
jkkl = 3;
}
   

jkkl在main函数中是不可变的,在ISR中却是可变的,这样编译就不会出错,因此在读取jkkl的文件中因该要描述成volatile型。

volatile使用时应该小心谨慎,以免导致错误。




0 0
原创粉丝点击