volatile与const综合分析
在C/C++ 编程中,volatile与const关键字一向容易让人困惑,当然,新手可能从来不用,但是 在高质量和稳健的程序中,这两个关键字 是相当重要的。
相比const,volatile关键字的发展(变化)较少,从C到C++的演变中,一直保持着 它的语义,因此,我们先从volatile来了解下,这两个关键字
一、volatile
1.volatile 的基础 认知:
volatile 的英文 释义是 容易 挥发的,
作为 关键字,可以 记忆为 它修饰的 变量 是 不稳定的,可能被其他地方的某些方式改变,因此为了 获取正确的值,编译器 不该对其做优化,比如为了 获取较快的 读取速度,将它 放入寄存器中等,而是每次都要从它所在的内存中 读取。
BS在 书中 对 volatile 的定义是:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
volatile修饰符 意在暗示 编译器,该被修饰的对象 通过该语言未指定的方式改变他的值,因此,积极的优化都应该被消除。
未指定的方式 ,比如 操作系统,硬件或者其他线程等。
遇到volatile修饰的变量,编译器对访问该变量的代码 不再进行优化,从而可以提供对特殊地质的稳定访问。
稳定的访问的方式 是 ,系统总是重新从该 变量的 内存中读取数据,即使 它 前面的 指令 刚刚 从该处 读取过数据。
2.volatile 修饰指针
我们可以使用 volatile修饰 指针,比如
volatile char * myVolatileStr;
char *volatile strVolatilePtr;
volatile 修饰 char* 和 *char 是 有较大区别的,和const修饰一样,volatile可以将其修饰的 内存区域 声明为 易挥发的,也可以将 指针变量本身声明为 易挥发的。通常,有以下注意点:
注意:(1) 可以把一个非volatile int 赋给 volatile int,但是不能把非volatile对象赋给一个volatile对象。
(2) 除了基本类型外,对用户定义类型也可以用volatile类型进行修饰。
(3) C++中一个有volatile标识符的类只能访问它接口的子集,一个由类的实现者控制的子集。用户只能用const_cast来获得对类型接口的完全访问。此外,volatile向const一样会从类传递到它的成员。
3.volatile在 多线程中
在 多线程 中,有些变量是要用volatile关键字声明的。当两个线程都要用到某一个变量且该变量的值会被改变时,应该用volatile声明,该关键字的作用是防止优化编译器把变量从内存装入CPU寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。volatile的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值,
下面,来对比学习 下 const,
二、const
1.const基础
在C++中,老手们建议 我们 尽可能的 多使用 const,但是 为啥呢?如果 面试官 问起,你就说,为了程序的稳健性,但是 这和问 锻炼身体为啥呢,保卫祖国 ,没什么 区别。
const 理论上 是 constant的简写,constant的英文释义是 不变的;恒定的;经常的。但是 很多大神将它理解成了 只读的,readonly,甚至觉得 要把这个关键词 替换成readonly。这在gun编译器中也是这么 提错的,很有意思。
和volatile一样,const也是对编译器的约束(废话),它明确的告诉 编译器,const修饰的变量 是 不变的,如果出现了 其他地方的对其修饰值的改变,应该在编译期间就报错。这样能大大提高程序的健壮性,当然,对于程序员,在编译期间就发现错误本就是极好的。
2.const修饰局部变量
这是 最基本的用法,如
const int i = ;
int const i = ;
3.const 与指针
const char* str;
char * const str;
char const* str;
const char* const str;
const char const* str;
以上,声明了 5种const 与指针的 位置 修饰 关系。
4.const与引用
5. const修饰函数参数
void function(constintVar);//传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)void function(constchar*Var);//参数指针所指内容为常量不可变void function(char*constVar);//参数指针本身为常量不可变(也无意义, 因为char* Var也是形参)
void function(constClass&Var);//引用参数在函数内不可以改变void function(const TYPE&Var);//引用参数在函数内为常量不可变
6. const 修饰函数返回值
7. const修饰类对象/对象指针/对象引用
class AAA
{
void func1();
void func2()const;
}
const AAA aObj;
aObj.func1();//×
aObj.func2();//正确 const AAA* aObj =new AAA();
aObj->func1();// ×
aObj->func2();//正确
8. const修饰成员变量
class A
{
…
constint nValue; //成员常量不能被修改
…
A(int x): nValue(x){};//只能在初始化列表中赋值
}
9. const修饰成员函数
class A
{
…
void function()const;//常成员函数, 它不改变对象的成员变量. 也不能调用类中任何非const成员函数。
}
对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。
10. const常量与define宏定义的区别
三、总结 分析
volatile与const综合分析的更多相关文章
- volatile和const
volatile可理解为“编译器警告指示字” volatile用于告诉编译器必须每次去内存中取变量值 volatile主要修饰可能被多个线程访问的变量 volatile也可以修饰可能被未知因数更改的变 ...
- volatile 和const 变量的使用
一.volatile定义: 一个定义为volatile的变量是说这变量可能会被意想不到的被改变,这样,有了volatile变量后,就提醒编译器就不会去假设这个变量的值了.精确地说就是,编译中的优化器在 ...
- 你必须知道的495个C语言问题,学习体会一
C语言作为一门古老的语言,其灵活性和容易出错都让人 又爱又恨,书籍<你必须知道的495个C语言问题>,使用问答的形式,告诉读者 C语言使用的各个方面的知识,包括一些冷知识等.以下,我要摘录 ...
- const volatile int i
问题: const volatile int i=10:这行代码有没有问题?如果没有,那 i 到底是什么属性? 回答: 没有问题,例如只读的状态寄存器.它是volatile,因为它可能被意想不到地改变 ...
- const volatile同时限定一个类型int a = 10
const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好 ...
- C++ - explicit和volatile/const的内容
第一眼见到explicit和volatile可能会一愣一愣的觉得可能是c11或者c14新加的标识符. 其实不是这样,volatile和const两个关键字在C语言的第二个版本KR C的时候就被加入了C ...
- __I、__O 、__IO volatile是什么?怎么用? .
这是ST库里面的宏定义,定义如下: #define __I volatile const /*!< defines 'read only' permissions */ #define __O ...
- C/C++中volatile关键字详解 (转)
1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...
- c语言,volatile
一.意义: 该关键字的意义就是表示定义的变量值随时都会改变,必须从变量的地址处读取值,所以只有这个变量在使用过程中可能被改变(比如中断程序),就需要用这个关键字说明. )volatile, ...
随机推荐
- Java并发(1):synchronized
虽然多线程编程极大地提高了效率,但是也会带来一定的隐患.比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据.今天我们就来一起讨论下线程安全问题,以及Java中提供 ...
- 发布mvc3 遇到的HTTP错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容
今天在发布别人提供的MVC3的程序,正常部署后浏览报错,错误内容如图: 根据IIS提供的解决办法,启用目录浏览,刷新页面发现确实不报错了,但页面是以目录显示的,如图 虽然解决了报错问题,但不是正常的效 ...
- clipboard
我们在网页上放置一个复制按钮,主要用来方便用户复制链接之类的复杂文本,以往的做法是,通过JS依靠Flash,甚至借助jQuery庞大的js库来实现文本复制到剪贴板的.今天我要给大家介绍的是一款极现代的 ...
- Java技术学习路线
转载 作者:David 链接:https://www.zhihu.com/question/25255189/answer/86898400来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...
- CodeForces - 786B Legacy (线段树+DIjkstra+思维)
题意:给N个点和Q条选项,有三种类型的选项:1.从u到v花费w修建一条路:2.从u到下标区间为[L,R]的点花费w修建一条路; 3.从下标区间为[L,R]的点到u花费w修建一条路. 然后求起点s到其余 ...
- Python3.x:pyodbc连接Sybase数据库操作(Windows系统下DNS模式)
Python3.x:pyodbc连接Sybase数据库操作(Windows系统下DNS模式) 一.安装模块pyodbc pip install pyodbc 二.配置odbc数据源 (1).windo ...
- Apache 源码包安装
系统:Centos 7.4 服务:Apache 2.4.33.apr 1.5.2.apr-util 1.5.4 依赖包: pcre.x86_64 pcre-devel.x86_64 openssl.x ...
- Java基础之冒泡排序
冒泡排序 基本介绍 冒泡排序是比较相邻的两个元素,通过不停的比较,较大的数往下沉,较小的往上冒,这也是冒泡排序名字的来源 第一趟从数组下标为0的数字开始,arr[0]大于arr[1]就交换他们的位置, ...
- ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。
阿里巴巴技术大牛黄勇的经验分享,感觉很受用. 关于IT 职场经验 1. 把技术当成工具 技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单. 我们每天在面 ...
- elasticsearch 拼音搜索
现在很多公司都开始使用es来做搜索,我们公司目前也有好几个业务部门在用,我主要做商户搜索,为业务部门提供基础支持.上周把呼叫中心的搜索重新整理了下,在新增几个字段后,全量同步发现通过拼音首字母搜索无法 ...