C语言深度解剖 笔记4
1最易变的关键字 volatile 类型修饰符
用volatile修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其他线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。比如:volatile关键字告诉编译器某变量是随时可能发生变化的,每次使用它的时候必须从内存中取出它的值,因而编译器生成的汇编代码会重新从它的地址中读取数据。
这样如果i是一个寄存器变量或者表示一个端口数据或者是多个线程的共享数据,就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
但是注意通过下面的内容,会对const和volatile有更深的理解:
#include<iostream>
using namespace std;
int main()
{
const int i=0;
int *p=const_cast<int*>(&i);
*p=2;
cout<<"i="<<i<<"\n*p="<<*p<<endl;
cout<<"&i="<<&i<<"\np="<<p<<endl;
return 0;
}
dec++和vc++运行结果都是
i=0 *p=2 且&i和p的值相等.
造成这样的原因:
1 上面的代码是强制类型转换,绕过编译器静态类型检查,从而获取变量的地址,因而在程序中只要有合法地址(非操作系统的保护内存)就可以修改地址中的数据,语言中const以及其他只是在语法上限制,无法从根本上限制。
2
但为什么在输出i的值时,仍然是0呢?
上面的代码如果修改为:
const int i=0;
int *p=(int*)&i;
*p=100;
这样i的内容也被修改了。
从而,我们想到如果使用C++中的另一个关键字:volatile,它就是用来解决这个问题。
因为从寄存器访问变量比从内存要快,所以如果一个变量在某次使用过后没有被显式修改,那么编译器将尽量从寄存器读入它的值。加volatile可以强制要求编译器每次用到这个变量时都从内存中提取它的值。所以这样就会得到正确结果:
#include<iostream>
using namespace std;
int main()
{
volatile const int i=0;
int *p=const_cast<int*>(&i);
*p=2;
cout << "i=" << i << "\n*p=" << *p << endl;
cout<<"&i="<<&i<<"\np="<<p<<endl;
return 0;
}
完全是因为前面加了const的缘故, 所以如果没有volatile, 编译器在碰到const变量的时候,用立即数代替。
volatile跟const是冲突的, 如果在const中使用volatile, 那么volatile是没作用的。
volatile的真正作用是, 在任何使用变量i的时候, 都去取地址,读地址的值,而如果不加volatile的话, 并且有优化的话,那么在连续的对i操作的情况下, 往往是放到寄存器中操作。
只要是cosnt定义的变量, 并且这个变量是用立即数初始化的, 那么, 在使用这个变量的时候, 编译器一定是用立即数代替。
在笔记中综合了各种论坛等网上的内容,甚至使用的例子有的都是网上论坛中的例子,在此只是为了自己查看的时候方便和分享我在学习中的收获,无侵犯原著的意思,请见谅。
C语言深度解剖 笔记4相关推荐
- C语言深度解剖读书笔记(1.关键字的秘密)
开始本节学习笔记之前,先说几句题外话.其实对于C语言深度解剖这本书来说,看完了有一段时间了,一直没有时间来写这篇博客.正巧还刚刚看完了国嵌唐老师的C语言视频,觉得两者是异曲同工,所以就把两者一起记录下 ...
- C语言深度解剖读书笔记
开始本节学习笔记之前,先说几句题外话.其实对于C语言深度解剖这本书来说,看完了有一段时间了,一直没有时间来写这篇博客.正巧还刚刚看完了国嵌唐老师的C语言视频,觉得两者是异曲同工,所以就把两者一起记录下 ...
- 《C语言深度解剖》中的.c/.h 程序模板及函数注释风格
编程规范和变量命令规范对于代码的可阅读性.可维护性有着很大的影响.编程规范有很多,大公司也会制定自己公司的编程规范,如<华为技术有限公司c语言编程规范>等.对于个人编程来说没必要将自己编写 ...
- c语言深度解剖 pdf,c语言深度解剖(解密).pdf.pdf
c语言深度解剖(解密).pdf.pdf 还剩 130页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: * Str ...
- C语言深度解剖:关键字
第一个C语言程序 内存 定义与声明 变量是什么 为什么要定义变量 定义变量的本质 定义声明 关键字 - auto 局部与全局变量 作用域 vs 生命周期 auto 关键字 - register 寄存器 ...
- C语言深度剖析笔记1
关键字的秘密 数据类型 什么是数据类型? 数据类型可以理解为固定内存大小的别名; 数据类型是创建变量的模子(花形的,圆形的,星形的等等); char 1byte short 2byte int 4by ...
- C语言 | C语言深度解剖 ——章节2 符号
C语言 | C语言深度解剖 --章节2 符号 C语言基本符号表 注释符号 // /* 几个似非而是的注释问题 y=x/*p 出色注释的基本要求 连接符和转义符 \ 单引号.双引号 花括号 运算符 10 ...
- C语言深度剖析笔记2
接上半部分 C语言深度剖析笔记1 https://blog.csdn.net/halazi100/article/details/125844487 C语言深度剖析笔记1 指针 变量回顾 既然程序中的 ...
- C语言深度解剖 PDF 分享
链接:https://pan.baidu.com/s/1U-8L7ZY5_sLpk4p0J302Mg 提取码:d8nu 相关推荐 [Objective-c程序设计] 中文编程·学习 ...
最新文章
- ASP.NET 2.0 ajax中gridView的刷新问题!
- DVWA提示Unable to connect to the database.
- 批处理-DHCP绑定IP地址
- vc6工程转成vs2008的一个问题【WINVER not defined】
- pycharm中如何正确配置pyqt5
- C#中的CultureInfo类
- ArrayList的remove方法(重写equals方法) 与LinkedList的常用操作
- Linux高频命令汇总,Linux高频命令
- WriteableBitmap process summary
- 求求你,别再叫我 X 工了!!!
- html宠物医院制作与实现,基于JSP的宠物医院系统设计与实现-毕业设计.doc
- psv无线怎么连接电脑连接电脑连接服务器,psv如何连接电脑复制视频,音乐,图片等资料教程...
- python输入某年某月某日歌词_python求输入某年某月某日,判断这一天是这一年的第几天...
- golang幽灵蛛(pholcus)(一)
- 微信分享网页时自定义标题、描述和图片
- Android开发需要学什么,技术实现
- Qt编写可视化大屏电子看板系统13-基础版
- WIFI 国家码和信道划分
- 网络基础之网络布线、数制转换和子网划分
- 自己动手写CPU(5)——移动指令说明
热门文章
- 神经系统的区分图解高中,神经系统的区分和组成
- bulk插入 es_ElasticSearch的Bulk操作 ES bulk详解
- easyexcel 遇到的问题 org.terracotta.statistics.StatisticsManager.tags([Ljava/lang/String;)Ljava/util/Set;
- 我的世界java版怎么加整合包_我的世界怎么制作整合包
- hiho第三周 KMP
- 感觉人生很艰难,怎么办?
- Android CameraServer:Disconnect
- etl mysql报错_etl工具
- 题目描述 假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待
- 哈工大计算金融本科新专业 | 全国首发