文档章节

const;volatile

pp__qq
 pp__qq
发布于 2015/02/24 21:47
字数 853
阅读 14
收藏 0
点赞 0
评论 0

注:

  • 由于从没有使用过 volatile 这个关键词,所以以下内容中,关于 volatile 的说明可能不是正确的.

const;volatile

  • 在编译期看来,const,volatile 是变量的属性,如下:

const volatile int i = 33;
// 编译期会将 i 当作一个变量,其中"int"表明了该变量的类型,"33"则指定了变量的初始值;
// 而 "const","volatile" 则认为是变量 i 的属性,其中
// const 表明变量 i 的值不可以被修改
// volatile 告诉编译期每一次读取 i 的值时都从内存中读取,而不是从缓存中(如寄存器).

volatile

  • 用来修饰一个变量,告诉编译期

    • 每一次对该变量的读取都是从内存中,而不是从缓存中(如:寄存器).
    • 每一次修改变量的值时,都将新值写入到内存中,而并不是只写到缓存中.
int i = 10;
int a = i;
sleep(3);
int b = i;

// 则编译期翻译的汇编代码可能是:
mov eax,i  ;
mov a,eax  ; 将 i 赋值给 a.
call sleep ; 在此之前可能需要插入参数.
mov b,eax  ; 将 i 赋值给 b.此时直接从寄存器中读取数据,减少了内存访问次数.

// 当使用了 volatile 关键词后,即:volatile int i = 33;编译期翻译的代码可能如下:
mov eax,i  ;
mov a,eax  ; 
call sleep ; 
mov eax,i  ; 始终从内存中访问 i 的值.
mov b,eax  ;

// 第 2 个程序,演示修改变量的值后,将新值写入到内存的必要性.
int i = 0;
void thread_func(){
    lock(); // 获取 i 的保护锁.
    i = i+1;
    unlock();
}
// 则此时编译器编译结果可能是:
call lock();
mov eax,i;
inc eax
// mov i,eax;//编译器为了提高效率而可能不会立即将新值写入到内存中,所以可能没有该指令.
call unlock();
// 这样若 2 个线程都同时执行 thread_func(),在线程 1 获取锁,并修改 i 的值,然后释放锁;此时线程2看到的 i 将仍然是 0.

const,volatile 与指针

  • int const *iptr = &i;int *const iptrc = &i;这两个语句的区别,首先要知道 iptr,iptrc 也是一个变量,其类型为 int* 类型,表明该变量的值是一个地址,指向着一个 int 类型的变量.

    • int const *iptr; const 的作用范围是 *iptr,即此处 const 并不是表明 iptr 的值不可以修改,而是 iptr 指向的 int 类型变量(即 i 的值)不可以修改.

    • int * const iptrc; const 的作用范围是 iptrc,表明变量 iptrc 的值不可以修改,但是 iptrc 指向的 int 类型变量是可以修改的,如下:

int i = 33;
int const *iptr = &i;
int * const iptrc = &i;
++(*iptr); // 错误,increment of read-only location ‘* iptr’
++iptr;    // 正确;
++(*iptrc);// 正确
++iptrc;   // 错误,increment of read-only variable ‘iptrc’

  • volatile,const 的修饰范围为从 const,volatile 所在的位置到变量名处.如下:

int const ci = 33; // const 作用范围是 ci;表明变量 ci 的值是不可以修改的.
int const *ciptr = &ci; // const 的作用范围是"*ciptr",表明 ciptr 指向的 int 类型变量的值是不可以修改的.
int const * const ciptrc = &ci; 
// 第 1 个 const 的修饰范围是 *ciptrc,表明 ciptrc 指向的 int 类型变量的值是不可以修改的.
// 第 2 个 const 的修饰范围是 ciptrc,表明变量 ciptrc 的值是不可以修改的.
int const ** ciptrptr = &ciptr;
// const 的修饰范围是 **ciptrptr,
int const * const *ciptrcptr = &ciptrc;



© 著作权归作者所有

共有 人打赏支持
pp__qq
粉丝 17
博文 51
码字总数 97223
作品 0
合肥
程序员
C语言 —— const和volatile同时修饰某对象的意义

const和volatile同时修饰某对象的意义: volatile const int i; (1)本程序段中不能对 i 做修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心; (2)另一个程序段则...

follitude ⋅ 2016/05/13 ⋅ 0

C++ 惯用法: const 常量和字面量

原文:C++ 惯用法: const 常量和字面量 作者:Breaker C++ 中 const 关键字、常量和字面量的惯用法 关键字:const, enum, constcast, constiterator, mutable, 左值, 字面量 本质和非本质上的...

晨曦之光 ⋅ 2012/05/23 ⋅ 0

const、volatile、mutable的用法

const、volatile、mutable的用法 const修饰普通变量和指针 const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写法在本质上是一样的。它的含义是:const修饰的类型...

小熊猫大暴走 ⋅ 2012/04/24 ⋅ 0

对 volatile 的对象取值和赋值 (几何画板开发笔记 二)

问题提出: 在研究和借鉴 emacs lisp 实现程序时, 有部分值被定义为 volatile 的, 则对其取值和赋值都有些不同, 在 C++ 中. 例子: struct Lisp_Object { int i; }; // 这是 lisp 基本对象结构...

刘军兴 ⋅ 2014/05/03 ⋅ 0

转:C++中const、volatile、mutable的用法

const修饰普通变量和指针 const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写法在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。对...

nothingfinal ⋅ 04/03 ⋅ 0

C++中const、volatile、mutable的用法

const关键字 const修饰普通变量和指针 const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写法在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value...

Jerikc ⋅ 2014/05/23 ⋅ 0

C/C++中volatile关键字详解

1. 为什么用volatile?   C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 “The C++ Programming Language” 对 volatile 修...

fx677588 ⋅ 2017/08/13 ⋅ 0

C Primer Plus 第12章 12.7 ANSI C的类型限定词

您已经知道一个变量是以它的类型与存储类表征的。C90增加了两个属性:不变性和易变性。这些属性是通过关键字const和volatile声明的,这样就创建了受限类型(qualified type)。C99标准添加了第...

idreamo ⋅ 2016/12/28 ⋅ 0

mutable和volatile的区别

1.mutable 在C++中,mutable是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被...

风雅轩 ⋅ 2017/10/24 ⋅ 0

C语言中auto,register,static,const,volatile的区别

1)auto   这个关键字用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有...

BeyondChallenge ⋅ 2015/08/21 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

行政区划代码转为字典形式

原数据为: http://www.mca.gov.cn/article/sj/xzqh/2018/201804-12/201804-06041553.html 手动替换了一下格式,并使用下面的代码处理. # 输入格式s = """110000:北京市110101:东城区1101...

漫步海边小路 ⋅ 11分钟前 ⋅ 0

android apk 签名

创建key,需要用到keytool.exe (位于C:\Program Files\Java\jdk1.6.0_10\bin目录下),使用产生的key对apk签名用到的是jarsigner.exe (位于C:\Program Files\Java\jdk1.6.0_10\bin目录下),把...

国仔饼 ⋅ 19分钟前 ⋅ 0

springcloud+jps+mybatis多数据库配置

多数据库配置 配置我们目录结构设置: config ---datasource ----jpa ----mybatis ----redis Datasource中是数据的相关配置 Jap中是springDatajpa的相关配置 Mybatis中是mybatis的相关配置 ...

大-智-若-愚 ⋅ 27分钟前 ⋅ 0

Spring mvc HandlerMapping 实现机制

概述 当DispatcherServlet接受到客户端的请求后,SpringMVC 通过 HandlerMapping 找到请求的Controller。 HandlerMapping 在这里起到路由的作用,负责找到请求的Controller。 Spring MVC 默认...

轨迹_ ⋅ 30分钟前 ⋅ 0

JavaScript零基础入门——(十)JavaScript的DOM基础

JavaScript零基础入门——(十)JavaScript的DOM基础 欢迎大家回到我们的JavaScript零基础入门,上一节课,我们了解了JavaScript中的函数,这一节课,我们来了解一下JavaScript的DOM。 第一节...

JandenMa ⋅ 今天 ⋅ 0

Weex起步

本教程假设你已经在你的本地环境安装了node 其实weex起步教程在 https://github.com/lilugirl/incubator-weex 项目说明文件中都已经有了,但为了有些同学看到英文秒变文盲,所以这里我重新写...

lilugirl ⋅ 今天 ⋅ 0

Jenkins实践1 之安装

1 下载 http://mirrors.jenkins.io/war/latest/jenkins.war 2 启动 java -jar jenkins.war 前提:安装jdk并配置环境变量 启动结果节选: ************************************************......

晨猫 ⋅ 今天 ⋅ 0

组合数学 1-2000 中,能被6或10整除的数的个数

1--2000 中,能被6或10整除的数的个数 利用集合的性质 能被6整除的个数 2000/6 = 333 能被10整除的个数 2000/10 = 200 能被6和10整除的个数 2000/30 = 66 能被6或10整除的个数 333+200-66 =...

阿豪boy ⋅ 今天 ⋅ 0

一篇文章学懂Shell脚本

Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合。 Shell可以直接使用在win/Unix/Linux上面,并且可以调用...

Jake_xun ⋅ 今天 ⋅ 0

大数据工程师需要精通算法吗,要达到一个什么程度呢?

机器学习是人工智能的一个重要分支,而机器学习下最重要的就是算法,本文讲述归纳了入门级的几个机器学习算法,加大数据学习群:716581014一起加入AI技术大本营。 1、监督学习算法 这个算法由...

董黎明 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部