• 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的区别:

    在这里插入图片描述

  • 相关阅读:
    limma差异分析谁和谁比很重要吗
    Linux Vi编辑器基础操作指南
    鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统
    多线程案例(单例、阻塞队列、生消模型、定时器)
    实用网站大全
    HLS直播协议详解
    JTextArea 显示行号
    SpingBoot之替换容器为Undertow
    【DL】关于tensor(张量)的介绍和理解
    SpringBoot实现支付宝沙箱
  • 原文地址:https://blog.csdn.net/zxm8513/article/details/126242090