重要示例:
告诉compiler不能做任何优化
比如要往某一地址送两指令:

int *ip =...; //设备地址
*ip = 1; //第一个指令
*ip = 2; //第二个指令

在普通c程序中,这段程序不过就是赋值而已,以上程序的第一个指令是完全没有必要的,compiler可能做优化而成:

int *ip = ...;
*ip = 2;

结果第一个指令丢失。而在嵌入式或单片机中,第一条是有必要的,如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意,这对嵌入式来讲非常重要

一、易变的
volatile 在词典中的主要释义就是“易变的”。
变量保存在内存中,但为了提高运行速度,有时不从内存取值,而从cpu缓存/寄存器中取值。在嵌入式/或单片机开发中,这有时是很致命的。
volatile 定义变量后:假设有读、写两条语句,依次对同一个 volatile 变量进行操作,那么后一条的读操作不会直接使用前一条的写操作对应的 volatile 变量的寄存器内容,而是重新从内存中读取该 volatile 变量的值。
上述描述的(部分)示例代码内容如下:

volatile int nNum = 0;  // 将nNum声明为volatile
int nSum = 0;
nNum = FunA();      // nNum被写入的新内容,其值会缓存在寄存器中
nSum = nNum + 1;    // 此处会从内存(而非寄存器)中读取nNum的值

二、不可优化的
在 C/C++ 编程语言中,volatile 的第二个特性是“不可优化性”。
volatile 会告诉编译器,不要对 volatile 声明的变量进行各种激进的优化(甚至将变量直接消除),从而保证程序员写在代码中的指令一定会被执行。
上述描述的(部分)示例代码内容如下:

volatile int nNum;  // 将nNum声明为volatile
nNum = 1;
printf("nNum is: %d", nNum);

在上述代码中,如果变量 nNum 没有声明为 volatile 类型,则编译器在编译过程中就会对其进行优化,直接使用常量“1”进行替换(这样优化之后,生成的汇编代码很简介,执行时效率很高)。
而当使用 volatile 进行声明后,编译器则不会对其进行优化,nNum 变量仍旧存在,编译器会将该变量从内存中取出,放入寄存器之中,然后再调用 printf() 函数进行打印。
三、顺序执行的
在 C/C++ 编程语言中,volatile 的第三个特性是“顺序执行特性”,即能够保证 volatile 变量间的顺序性不会被编译器进行乱序优化。
**C/C++ 编译器最基本优化原理:**保证一段程序的输出,在优化前后无变化。为了对本特性进行深入了解,下面以两个变量(nNum1 和 nNum2)为例(既然存在“顺序执行”,那描述对象必然大于一个),介绍 volatile 的顺序执行特性,示例代码内容如下:

int nNum1;
int nNum2;
nNum2 = nNum1 + 1;    // 语句1
nNum1 = 10;           // 语句2

在上述代码中:当 nNum1 和 nNum2 都没有使用 volatile 关键字进行修饰时,编译器会对“语句1”和“语句2”的执行顺序进行优化:即先执行“语句2”、再执行“语句1”;当 nNum2 使用 volatile 关键字进行修饰时,编译器也可能会对“语句1”和“语句2”的执行顺序进行优化:即先执行“语句2”、再执行“语句1”;当 nNum1 和 nNum2 都使用 volatile 关键字进行修饰时,编译器不会对“语句1”和“语句2”的执行顺序进行优化:即先执行“语句1”、再执行“语句2”;说明:上述论述可通过观察代码的生成的汇编代码进行验证。

嵌入式C语言volatile作用相关推荐

  1. 16道嵌入式C语言面试题(经典) 预处理器(Preprocessor)

    16道嵌入式C语言面试题(经典) 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_ ...

  2. 嵌入式C语言强化学习——(嵌入式学习路线1)

    前言 从零开始记录自己学习嵌入式,之前看稚晖君的视频,里面的费曼学习法觉得对自己很有帮助,所以准备把自己学习到的东西分享出来,便于学的更深(符合费曼学习法) 众所周知,嵌入式编一般是使用C语言(也有用 ...

  3. 【面试】嵌入式C语言题目整理

    [面试]嵌入式C语言题目整理 描述内存四区. 内存四区分为:代码区.静态区.堆区.栈区 代码区就是用来存放代码的. 静态区用来存放全局变量.静态变量.常量(字符串常量.const修饰的全局变量). 堆 ...

  4. 【嵌入式C语言】4.指针

    0.前言 本章开始主要讲解C语言内存空间的使用. 这里的内存泛指RAM资源.内存条资源.显卡资源.IIC资源等等. 本文主要整理指针的使用方法. 内存属性: 1.内存操作的大小 2.内存的变化性,可写 ...

  5. 嵌入式C语言——学习笔记

    嵌入式C语言--学习笔记 计算机程序语言的学习思路? GCC的使用及其常用选项介绍 gcc概述 C语言编译过程 C语言常见的错误 预处理的使用 宏展开下的 #.## C语言常用关键字及运算符操作 关键 ...

  6. 嵌入式C语言进行曲之要诀

    一. 良好的编程风格 1.排版:a. 代码缩进空格数为4 个.若是可能,尽量用空格来代替Tab键,因为有些编译器不支持Tab键(我自己至今未见过,但确实有这个风险),这给程序的移植带来了问题. b. ...

  7. uml+oopc嵌入式c语言开发精讲_当前火爆的嵌入式领域,为什么选择C语言作为开发语言?了解一下...

    C语言和嵌入式C编程有什么区别?其区别在于嵌入式的C语言是跑在嵌入式的开发板上的,CPU和电脑不一样,所以编译器也是不一样的,生成的可执行程序也是不一样的.选择嵌入式开发语言归结于嵌入式系统开发的特点 ...

  8. python嵌入式系统开发_Python在开发实时嵌入式系统中的作用

    原标题:Python在开发实时嵌入式系统中的作用 在过去的几年里,Python已经成为一种热门的程序语言.以著名的Monty Python喜剧小组命名,该语言是面向对象和解释.该属性导致Python在 ...

  9. 嵌入式C语言基础(一)

    嵌入式C语言基础: system函数:功能是运行windows命令 #include <stdio.h> #include <stdlib.h> int main() {//m ...

  10. c语言 怎么访问64位地址_大神用10000字总结了嵌入式C语言必学知识点……

    导读:怎么做好嵌入式?相信这个问题无论问谁你都会得到一句学好C语言!今天推荐一篇大佬写的嵌入式C语言知识点总结,非常值得一读. 从语法上来说C语言并不复杂, 但编写优质可靠的嵌入式C程序并非易事,不仅 ...

最新文章

  1. 利用nofllow与内页链接做好SEO
  2. Docker在服务器之间怎样导入导出镜像(服务器之间容器复制)
  3. GetCursorPos/WindowFromPoint/SendMessage
  4. Makefile总结
  5. IPhone 应用程序管理
  6. PyTorch-训练
  7. iOS逆向之旅(进阶篇) — 重签名APP(一)
  8. (21)FPGA面试题D触发器表示方法
  9. Django Navi 重用
  10. 浏览器配置异常_IE浏览器异常 修复/重置ie设置方法
  11. gm21模型python_GM11灰色模型
  12. 关于a标签 中特有的tilte属性 和 字符串文字换行
  13. 求求你学学医疗保险小知识吧
  14. uniapp支付打开支付宝app进行付款
  15. C/C++基础讲解(二十六)之数值计算与趣味数学篇(打鱼还是晒网与怎样存钱以获取最大利息)
  16. Kubernetes Kubelete 报错 ctr: failed to create shim task: OCI runtime create failed
  17. 动态刷新listview数据
  18. 【C++】getchar()有什么用
  19. IE ajax无局部刷新_se7en3_新浪博客
  20. Linux 和UNIX 的新手培训教程

热门文章

  1. Networkx参考手册
  2. 倒立摆小车matlab仿真,倒立摆系统的建模及Matlab仿真分析
  3. java.sql.Date.valueOf处理日期格式IllegalArgumentException异常
  4. socks5认证过程
  5. 苹果手机计算机切换用户名,苹果ID如何切换账号?苹果手机切换ID登录使用教程...
  6. 【Python】Python绘制CIE1931色度图并标点
  7. GRPC入门使用及测试用例源码
  8. SQL SERVER 2005下载(本地使用)
  9. C#中splitContainer用法
  10. SplitContainer控件扩展之收缩面板