• C语言中volatile修饰变量,及其余const的区别


    volatile修饰的变量表示是随时可以发生变化的,因此当编译器用到这个值的时候会重新去调用其数值,而不是使用保存在寄存器的备份。Volatile一般来修饰寄存器变量,因为寄存器里面存数的数据会经常发生变化。Volatile只是一个修饰关键字因此可以用数据类型放在前边修饰比如:const volatile a;表示a是一个volatile类型的常量,说是常量是因为在程序运行中程序不能更改这个数值,但是它可能会意想不到的发生改变。在头文件中常来定义寄存器变量,比如:

    #define PWMC       (*(unsigned int volatile xdata *)0xfff0)

    #define PWMCH      (*(unsigned char volatile xdata *)0xfff0)

    #define PWMCL      (*(unsigned char volatile xdata *)0xfff1)

    #define PWMCKS     (*(unsigned char volatile xdata *)0xfff2)

    通过指针来定义寄存器变量。

    一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

    1) 并行设备的硬件寄存器(如:状态寄存器)

    2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

    3) 多线程应用中被几个任务共享的变量 

    这个问题是区分C程序员和嵌入式系统程序员的最基本的点。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的使用将会带来灾难。

    在这里插入图片描述

     解释:

    在我们编译程序的时候,现代编译器总会去做一些优化,优化之一就是避免每次去读内存的值,我们知道,CPU每次去读内存的时候是很耗时的操作,所以编译器为了提高执行效率,往往就会去做一些优化。

     在上面这个例子来看,没多大毛病,但是,问题的核心在于,如果我们将这个程序片段放到一个多线程的环境,或者一个嵌入式系统中与中断处理程序相关的一些程序代码的时候,那意外就产生了,在休眠100ms的这个时间段内,obj的值很可能被其他线程比改变,那么休眠完毕后赋值给b的值也就应该发生变化,但是没有给obj添加volatile关键字,编译器自动优化了,此时的obj的值并没有发生改变,b所得到的值不是一个正确的值。
    所以,为了避免这个情况,我们就可以使用volatile来修饰obj变量,告诉编译器不要“自作聪明”来对这个变量进行优化处理,取消也可以说是保护现场。
    volatile这个关键字在嵌入式或者多线程使用较多。

    另外const和volatile的区别:

    在这里插入图片描述

  • 相关阅读:
    QT学习笔记-QT程序执行Linux Shell命令实现动态添加路由
    【Unity100个实用小技巧】世界Canvas自动隐藏,包含子物体
    java基于ssm的 大学生社团管理系统 elementui 前后端分离
    中文分词:Python、Golang、Java
    PMP提分练习
    B+ 树的简单认识
    澳洲猫罐头如何?我亲自喂养过的优质猫罐头分享
    【SQL刷题】Day10----SQL高级过滤函数专项练习
    mysql数据库root密码忘记了,这里有一个简单的方法可以解决
    组会记录2023/9/28
  • 原文地址:https://blog.csdn.net/zxm8513/article/details/126242090