Volatile与Register的区别

a.volatile

volatile是易变的,不稳定的意思,volatile是关键字,是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其他线程等,遇到这个关键字声明的变量,编译器对访问该变量的代码不在进行优化,从而可以提供对特殊地址的稳定访问。那么什么是编译器优化呢?

 

为了提高运行效率,攻城师们费尽心机地把代码优化,优化程序运行时存取速度。一般,分为硬件优化和软件优化。硬件优化,流水线工作,详细可以参考《计算机组成原理》。软件优化,一部分是程序猿们做的代码优化(前提你得有优化的思路和能力),还有一部分就是我们的编译器优化了。

 

现代的编译器经过那么多年的发展,已经比较成熟,它会把多余的变量忽略掉,让代码的运行效率更高。默认情况下,编译器都会对代码进行优化,会把一些变量在寄存器里存取,而不是在内存里存取,如此一来,CPU在自己家里拿东西当然比从内存那里拿东西要快得多。举个小栗子:

int i = 5;

int a = i;

……

int b = i;

 

编译器发现两次从i读数据的代码之间,并没有对i进行过操作,它会自动把上次读的数据放在b中,而不是重新从i里面读取。

 

而volatile关键字告诉编译器该变量是随时可能发生变化的,每次使用它的时候必须从内存中取出它的值,因而编译器生成的汇编代码会从原内存地址中读取数据使用,而不是从寄存器或者缓存中读取,从而保证了对特殊地址的稳定访问。

 

简言之,状态要经常变化的,为了防止我们编译优化而导致的存取的数据不同步的问题,这时我们就需要用到volatile。那具体到什么场景下需要用到volatile关键字呢?

 

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

 

2、一个中断服务子程序中会访问到的非自动变量();

 

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

 

上面提到了非自动变量,这里进一步对几种变量做一番解释:

 

自动变量:是在函数内部定义和使用的变量,它是局部变量。

 

非自动变量:有两种,一种是全局变量,一种是静态变量。

 

全局变量:在函数外面定义的变量,只能定义一次,不能有重复的定义,不然就会发生错误,而其他的文件要想使用这个变量,需要extern来声明这个变量(也可省略,因为默认就是extern),这个声明叫做引用声明。

 

若不想被其他文件访问,则用static关键字声明为静态变量。静态变量与自动变量的本质区别是,静态变量并不像自动变量那样使用堆栈机制来使用内存。

 

而是为静态变量分配固定的内存,在程序运行的整个过程中,它都会被保持,而不会被销毁。这就是说静态变量的持续性是程序运行的整个周期。这有利于我们共享一些数据。

 

如果静态变量在函数内部定义,则它的作用域就是在这个函数内部,仅在这个函数内部使用它才有效,但是它不同于自动变量,自动变量离开函数后就会被销毁,而静态变量不会被销毁。他在函数的整个运行周期内都会存在。

 

b. register

这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它累死也可能不能全部把这些变量放入寄存器吧。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C语言中,auto、static、extern、register、const和volatile是用来定义变量和函数的存储类别和属性的关键字。\[2\] auto是默认的存储类别,用于定义自动变量,它的生命周期与所在的代码块相同。static用于定义静态变量,它的生命周期在程序运行期间都存在,但作用域仅限于所在的代码块。extern用于声明外部变量或函数,它表示该变量或函数是在其他文件中定义的。register用于定义寄存器变量,它的值存储在寄存器中,以提高访问速度。const用于定义常量,一旦被赋值后就不能再修改。volatile用于定义易变的变量,每次都会从内存中获取值,而不是从缓存中获取值,适用于对硬件寄存器的访问、多线程中访问全局变量和中断中访问非自动类型的变量。\[3\] 关键字const和volatile的使用可以提高程序的可读性和可靠性,因此在编写程序时,我们应该根据需要合理地使用这些关键字。 #### 引用[.reference_title] - *1* *2* [C中的auto、static、register、extern、const和volitate](https://blog.csdn.net/m0_70888041/article/details/128286925)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [c语言中的六个存储类型:auto register static extern const volatile](https://blog.csdn.net/a2998658795/article/details/125958396)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值