在C语言中,还有一个并不经常使用但却非常有用的关键字volatile。那么使用volatile关键字究竟能干什么呢?接下来我将就此问题进行讨论。

  一个使用volatile关键字定义变量,其实就是告诉编译系统这变量可能会被意想不到地改变。那么编译时,编译器就不会自作主张的去假设这个变量的值,而进行代码的优化了。确切的说就是,编译器在编译代码时,优化器每次遇到这个变量,都会到内存中重新读取,而不会使用保存在寄存器里的备份来对代码进行优化。

  我们已经了解了volatile关键字的基本作用。那么,在什么情况下使用volatile关键字呢?一般说来,在如下的几种情况通常会使用volatile关键字:

  • 在中断服务程序中修改的,供其它程序检测的变量,通常需要定义为volatile;
  • 在多任务环境下,各任务间共享的标志,通常也需要定义为volatile;
  • 存储器映射的硬件寄存器通常也需要定义为volatile,因为每次对它的读写都可能有不同意义;

1)使用中断改变对象值的情况

  我们在中断服务程序中操作了某个对象,比如谁改变了一个变量的值。而在其它程序中我们希望通过这个变量值得改变去进行一些操作。在这个时候,我们使用或者不使用volatile关键字,可能得到截然不同的结果。

  如果我们将变量定义为:static int var=0; ,然后再中断服务成勋中将其修改为:var=1,但是在另一函数中使用它但不会修改它,那么编译器会认为它没有变化,从而直接使用寄存器中的副本。

  如果我们将变量定义为:volatile int var=0;,那么结果就完全不同了,每次在函数中使用var变量时,都会重新读取,而不会使用寄存器中的副本。

(2)多任务共享标志的情况

  多任务共享时,其实也是一样的,在一个任务中修改了一个对象后,在另一个对象中应用它,但编译器并没发现在该任务中对它有修改。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。从而并不能响应在另一任务下的变化。

  在这种情况下,一般我们都需要使用volatile关键字来定义任务间共享的标识。

3)硬件寄存器内存映射的情况

  内存映射的情况是非常多的,比如我们将外设的寄存器映射到内存的某一段区域;再比如我们同过DMA方式将数据直接写到内存中的某一段区域。

由于我们外部的数据都是直接进入了内存区域,而程序知识引用它的值。编译器优化时可能就直接采用寄存器中的副本了。佷显然这不是我们需要的结果,这时将这段内存对应的变量声明为volatile,则可以保证我们的需求。

  综上所述,我们说明了volatile关键字的常规用法。当然,我们也可以发现volatile关键字是会降低编译器优化力度的,但它却可以保证程序的正确性,所以在适合的地方使用volatile关键字是必要的。不过能不能用的好,还要看编程者的基本功。

欢迎关注:

C语言学习及应用笔记之四:C语言volatile关键字及其使用的更多相关文章

  1. C语言学习及应用笔记之一:C运算符优先级及使用问题

    C语言中的运算符绝对是C语言学习和使用的一个难点,因为在2011版的标准中,C语言的运算符的数量超过40个,甚至比关键字的数量还要多.这些运算符有单目运算符.双目运算符以及三目运算符,又涉及到左结合和 ...

  2. GO语言学习(十六)Go 语言结构体

    Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型. 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合. 结构体表示一项记录,比如保存图 ...

  3. C语言学习书籍推荐《C程序设计语言(第2版•新版)》下载

    克尼汉 (作者), 等 (作者, 译者), 徐宝文 (译者) 下载地址:点我 <C程序设计语言(第2版•新版)>是由C语言的设计者Brian W.Kernighan和Dennis M.Ri ...

  4. C语言学习及应用笔记之七:C语言中的回调函数及使用方式

    我们在使用C语言实现相对复杂的软件开发时,经常会碰到使用回调函数的问题.但是回调函数的理解和使用却不是一件简单的事,在本篇我们根据我们个人的理解和应用经验对回调函数做简要的分析. 1.什么是回调函数 ...

  5. C语言学习及应用笔记之五:C语言typedef关键字及其使用

    在C语言中有一个typedef关键字,其用来定义用户自定义类型.当然,并不是真的创造了一种数据类型,而是给已有的或者符合型的以及复杂的数据类型取一个我们自己更容易理解的别名.总之,可以使用typede ...

  6. C语言学习及应用笔记之三:C语言const关键字及其使用

    在C语言程序中,const关键字也是经常会用到的一个关键字,那么使用const关键字的目的是什么呢?事实上,在程序中使用const关键字的主要目的就是为了向使用者传递设计者的一些意图. 事实上,无论我 ...

  7. C语言学习及应用笔记之二:C语言static关键字及其使用

    C语言有很多关键字,大多关键字使用起来是很明确的,但有一些关键字却要相对复杂一些.我们这里要说明的static关键字就是如此,它的功能很强大,相应的使用也就更复杂. 一般来说static关键字的常见用 ...

  8. C语言学习及应用笔记之六:C语言extern关键字及其使用

    在C语言中,修饰符extern用在变量或者函数的声明前,用来以标识变量或者函数的定义在别的文件中,提示编译器遇到此变量或者函数时,在其它文件中寻找其定义.extern关键字的用法有几种,我们下面对其进 ...

  9. 从零开始学习SSH框架笔记之四 几个关键配置文件备忘(模板)

    不多说,直接上代码.关于注释我尽量写详细点. 1.web.xml <?xml version="1.0" encoding="UTF-8"?> &l ...

随机推荐

  1. Shell命令-文件及目录操作之file、md5sum

    文件及目录操作 - file.md5sum 1. file:显示文件的类型 file命令的功能说明 用于辨识文件类型.通过 file 指令,我们得以辨识该文件的类型. file命令的语法格式 file ...

  2. [SimplePlayer] 3. 视频帧同步

    Frame Rate 帧率代表的是每一秒所播放的视频图像数目.通常,视频都会有固定的帧率,具体点地说是每一帧的时间间隔都是一样的,这种情况简称为CFR(Constant Frame Rate);另外一 ...

  3. 数据分析之Matplotlib和机器学习基础

    一.Matplotlib基础知识 Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形. 通过 Matplotlib,开发者可以仅需 ...

  4. 用UE4蓝图制作FPS_零基础学虚幻4第二季

    课时1:案例演示 05:12 课时2:工程准备 07:35 (把一个项目从一个工程移动到另一个工程) 1.新建一个空白工程,不包含初学者内容 2.选择我们要复制的工程,按右键,如下图: 复制到新工程的 ...

  5. [BZOJ 4819] [SDOI 2017] 新生舞会

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有 \(n\) 个男生和 \(n\) 个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴. C ...

  6. HTML- 标签语法

    HTML 标签语言 概念  超文本标记语言, 是一种用于创建网页的标记语言 ps: 不是编程语言 利用标签来描述网页 扩展名:.html .htm 语法规范 标签不区分大小写, 推荐小写 双标签必须写 ...

  7. n98-magerun2.phar

    installl: 1,cd /usr/local/bin && curl -O https://files.magerun.net/n98-magerun2.phar 2,chmod ...

  8. 基于Matlab实现多次最佳一致的函数逼近(类似求渐进函数)

    %%%做系统识别很重要,方法上完全符合系统识别最基础的理论 function [sun]=main(n) fplot(,],'r'); x=ones(n+,); :n+ x(j+)=cos(pi*(n ...

  9. golang 代码笔记

    锁 互斥锁,g0获取锁,到释放锁之间,g1去获取锁失败,阻塞,g0释放锁之后g1获取锁成功,gn阻塞. package main import ( "fmt" "sync ...

  10. 忘掉Ghost!利用Win10自带功能,玩转系统备份&恢复 -- 系统重置

    之前几篇介绍的如何备份.恢复系统,在遇到问题的时候可以轻松应对. 如果系统出现问题,还可以正常启动,但是之前没有备份过系统,那该怎么办? 碰到这种问题,可以使用Win10系统的“系统重置”功能: 按照 ...