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

    在这里插入图片描述

  • 相关阅读:
    Android 布局优化,看过来 ~
    Selenium WebDriver 中用于查找网页元素的两个方法
    RCD负载箱的安全性能和认证标准有哪些?
    软考知识点---10数据库基础
    了解常用测试模型 -- V模型、W模型
    推荐100首好听英文歌
    线上展厅干货 广州商迪
    如何设置负载均衡EasySLB后端服务器网关
    【从问题中去学习k8s】k8s中的常见面试题(夯实理论基础)(三十一)
    C++ map和set
  • 原文地址:https://blog.csdn.net/zxm8513/article/details/126242090