详解volatile关键字

volatile字面意思:易变的。在计算机里,是防止优化的意思,然而是怎么防止优化的呢?待我一一道来哦。微笑微笑

先看这样一个例子:

<span style="font-size:18px;">#include<iostream>
using namespace std;
int main()
{int num = 10;int *p = &num;*p = 20;cout<<num<<endl;getchar();return 0;
}</span>
结果是什么呢?


由于p取得是num的地址,即p指向num,然后*p即取出p指向的内容,将它修改为20,所以结果输出num也被修改为20.

我们再看一个例子:

<span style="font-size:18px;">#include<iostream>
using namespace std;
int main()
{const int num = 10;int *p = (int*)#*p = 20;cout<<num<<endl;getchar();return 0;
}</span>
这里只是在int前加了const,将num设定为常量(在c语言中加const修饰变量叫常变量,c++中const修饰变量叫常量),所以无法修改num的值,结果如下:


这里我详细说明一下它是怎么执行的?调出内存看一下吧:


这是num所在的位置。赋值为10.


此时p就指向num。

内存里边p指向的内容确实改变了。但是我们看一下输出的结果:(如果在linux下演示的话,将代码编到test.c下,用命令gcc test.c -02 使优化级别最高进行测试)


为什么输出的结果却是10呢?p所指向的内容确实是num,但是在这里*p改变了,num却不受影响。。这个原因就在于const关键字。const将num这个变量修饰为常量,所以无法修改它,为了使常量不受破坏,就把它放在了寄存器中。以方便使用。又因为寄存器是不编址的,所以取地址根本不受影响。说起寄存器,看一下下面这幅图:(画的不错,网上抠下来的哈)


显而易见,最上边的是寄存器,是速度最快的,最下边是内存,是速度最慢的。那么问题来了,既然寄存器这么快,为什么不把变量都放在寄存器里呢。首先,学过计算机组成原理的同学都知道,寄存器造价高,空间小,可经不起那样的伤害。所以我们尽可能的把它们放在内存中,内存的空间大小可比寄存器的大多了。

为了解决上面的问题,我们引来了另一个关键字:volatile

volatile是这样使用的。

#include<iostream>
using namespace std;
int main()
{volatile const int num = 10;int *p = (int*)#*p = 20;cout<<num<<endl;getchar();return 0;
}
这样,volatile会防止编译器的优化,保证内存的可见性。也就是不将num放入寄存器,而是放在内存中,这样就可以找到它的地址,进而修改它了。

结果是:



以上就是volatile的简单介绍,希望能对大家的认识有所帮助哦,欢迎来访~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 有符号字符型输出 面试题

1.第一题 int main() {int a 128;printf("%u\n", a);system("pause"); } 输出结果 128 #include <stdio.h> #include <stdlib.h>int main() {char a 128;printf("%u\n", a);system("pause"); } 输出结果 42949671…

正则表达式提取括号里面的值

转自 https://blog.csdn.net/jiahaowanhao/article/details/80795148

有趣的链表相关题型

链表&#xff1a;也是线性表的一种。形象的来说&#xff1a; 就像火车的一个个车厢一样&#xff0c;一个个的链起来的。它有一个特点&#xff1a;它的头没有前驱&#xff0c;尾没有后继。 为什么会引入链表这个概念呢&#xff1f;之前我们知道的顺序表&#xff0c;是用数组的形…

简陋版C语言仿真通讯录

文件cotact.c #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include "contact.h" /*初始化*/ void InitContact(pContact pc) {pc->count 0;memset(pc->data, 0, sizeof(pc->data)); }/*增加数据*/ void AddCon…

pip3 便捷安装包

将虚拟环境下 的包列举出来 并保存到文件夹 pip3 freeze > requirments.txt 一次性安装文件里面所列举的所有的包 pip3 install -r requirments.txt

有趣的约瑟夫环问题

大家有没有听过约瑟夫环这个问题呢&#xff1f;我们先来看看它是一个什么样的问题~ 约瑟夫环&#xff08;Josephus&#xff09;问题是由古罗马的史学家约瑟夫&#xff08;Flavius Josephus&#xff09;提出的。该问题的说法不一&#xff0c;传说他参加并记录了公元66—70年犹太…

C语言模拟实现标准库函数之qsort() 2

C语言模拟实现标准库函数之qsort() <1> https://blog.csdn.net/csdn_kou/article/details/80158194 排序数字 int int_cmp(const void *elem1, const void *elem2) { return *(int *)elem1 - *(int *)elem2; }int main() { int arr[] { 9,8,7,6,5,4,3,2,1 }; int siz…

node.js windows下安装与配置

转自 https://www.cnblogs.com/liuqiyun/p/8133904.html

一系列链表题

1、链表的倒序输出&#xff1a;(输出4&#xff0c;3&#xff0c;2&#xff0c;1)在这里&#xff0c;可以使用递归的方式&#xff1a; <span style"font-size:18px;">void Reverse(pNode pHead) {if(pHead){Reverse(pHead->next);cout<<pHead->data…

简陋版C语言仿真通讯录之动态内存开辟版本

简陋版C语言仿真通讯录 https://blog.csdn.net/csdn_kou/article/details/80287640 简陋版C语言仿真通讯录之动态内存开辟版本 给Contact结构体增加一个容量&#xff0c;来表示什么时候增容 #define MAX_NAME 20 typedef struct PeoInfo {char name[MAX_NAME];int age;char …

node.js 代码修改 自动识别重启工具

npm install supervisor -g supervisor xx.js 代替 node xx.js 能实现自动重启服务&#xff0c;识别代码更新

C语言转移表之加减乘除无限进化版

主干程序初级版本进阶版本版本进化 主干程序 输入程序解析程序 /*解析字符串 有空格把空格分开 比如输入&#xff1a;add 1 2 解析后&#xff1a;add12*/ void do_parse(char *buf) {int state 0;int i 0;int argc 0;char *argv[8] {0};for (i 0; buf[i]; i){if (state …

node.js 笔记1 模块方面

url 模块 parse 解析url 可以用来获取查询参数 xx.js exports.xx xx 另一个文件引用 require(’./xx.js); 获取的句柄 相当于 xx.js 中的 exports xx.js module.exports xx 这样被人引用 相当于就是直接拿到了 xx 当require xx 的时候&#xff0c; 如果xx不在当前文件夹 &…

c++之指针引用

指针&#xff1a;指向一块内存地址的标识。 引用&#xff1a;给已经定义的变量起的别名。 格式&#xff1a; 类型 &引用变量名 已定义的变量名&#xff08;引用变量名和已定义的变量名可以看成是同一个实体&#xff0c;一个改变&#xff0c;另一个也随之改变&#xff0…

C语言之scanf中的格式

scanf函数原型控制格式1.%[^\n]%*c例子1例子2 1.%[]例子1例子2 scanf函数原型 int scanf( const char *format, ... ); 见可变参数求和 https://blog.csdn.net/csdn_kou/article/details/79996606 控制格式 %c 一个单一的字符 %d 一个十进制整数 %i 一个整数 %e, %f, %…

node.js 将文件目录读取 通过匿名函数自执行 将异步改为同步

var fs require(fs);var filesarray []; fs.readdir(html, function(error, files){if(error){console.log(error.stack);console.log(--------);console.log(文件夹读取失败);return false;}// 匿名函数自执行&#xff0c; 将异步改为同步(function getFile(i){console.log(…

蛇形数组打印(两种形式)

#蛇形数组打印 ##第一种形式 形式1 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9 请按任意键继续. . .形式2 513 14 15 16 112 23 24 17 211 22 25 18 310 21 20 19…

node.js 获取异步方法里面的数据 =》 两种方式

第一种&#xff1a; 通过回调函数实现&#xff1a; var fs require(fs); function getmime(callback){ fs.readFile(./t1.js, function(err, data){// 现在理解&#xff0c;异步方法里还有别的引用 就不会提前释放callback(data);}); }getmime(function(data){console.log(…

python入门--基本语法

标准数据类型&#xff1a;Number(数字)&#xff0c;String(字符串)&#xff0c;List(列表)&#xff0c;Tuple(元组)&#xff0c;Sets(集合)&#xff0c;Dictionary(字典)Number只支持int(表示长整型)&#xff0c;float&#xff0c;bool&#xff0c;complex&#xff08;复数&…

Linux网站大杂烩《自己查阅》

从网络上拷贝别人归纳的列表。 Linux优秀网站列表 国内 http://www.chinaunix.net/ 国内最火爆的unix/linux论坛 http://www.linuxforum.net/ linux爱好者交流的场所&#xff0c;侧重编程开发 http://www.linuxaid.com.cn/ 面向初学者者提供资料 http://www.ibm.com/de…