C语言-const和volatile深度分析
1、const只读变量
const修饰的变量是只读的。本质还是变量
const修饰的局部变量在栈上分配空间
const修饰的全局变量在全局数据区分配空间
const只在编译期有用,在运行期无用
const修饰的变量不是真的变量,它只是告诉
编译器该变量不能出现在赋值符号的左边
实例一.cpp:
#include <stdio.h> const int g_cc = ; int main()
{
const int cc = ; int* p = (int*)&cc; printf("cc = %d\n", cc); *p = ; printf("cc = %d\n", cc); p = (int*)&g_cc; printf("g_cc = %d\n", g_cc); *p = ; printf("g_cc = %d\n", g_cc); return ;
}
从上面的代码我们发现,const并不是真正意义上的常量,而只是read-only;
提示:GCC编译器如果编译上面的代码,在第21行代码会发生段错误,因为GCC编译器会把const全局数据放置在只读存储区,不能再修改。
但const仍然不能定义真正的意义上的常量。
实例二.cpp
#include <stdio.h>
const int g_array[] = {};
void modify(int* p, int v)
{
*p = v;
}
int main()
{
int const i = ;
const static int j = ;
int const array[] = {};
modify((int*)&i, ); // ok
modify((int*)&j, ); // error
modify((int*)&array[], ); // ok
modify((int*)&g_array[], ); // error
printf("i = %d\n", i);
printf("j = %d\n", j);
printf("array[0] = %d\n", array[]);
printf("g_array[0] = %d\n", g_array[]);
return ;
}
2.const修饰函数参数和返回值
-const修饰函数参数表示在函数体内不希望改变参数的值
-const修饰函数返回值表示返回值不可改变,多用于返回指针的情形
小贴士:
-C语言中的字符串字面量存储于只读存储区,
-在程序中需要使用 const char* 指针。
实例3.cpp
#include <stdio.h> const char* f(const int i)
{
i = ; return "Delphi Tang";
} int main()
{
char* pc = f(); printf("%s\n", pc); pc[] = '_'; printf("%s\n", pc); return ;
}
上面的代码 第5行和第16行将会报错,这里不再讲述。
3.volatile分析
volatile可理解为“编译器警告提示符”
volatile告诉编译器必须每次去内存中取变量值
volatile主要修饰可能被多个线程访问的变量
volatile也可以修饰可能被未知因数更改的变量
int obj = ;
int a = ;
int b = ;
a = obj;
Sleep();
b = obj;
编译器在编译的时候发现obj没有被当成左值使用,
因此会“聪明”的直接将obj替换成10,而把a和b都赋值为10。(优化)
volatile主要用于多线程编程环境和嵌入式开发领域
此时若改变obj的值,a和b又如何???
volatile int obj = 10后,a和b又如何???
有趣的问题
const volatile int i = 0;
- 变量 i 具有什么样的特性?
- 编译器如何处理这个变量?
正解: 每次用i都会到内存取i的值,i不能出现在赋值符号左边
小结:
const使得变量具有只读属性
const不能定义真正意义上的常量
const将具有全局生命期的变量存储于只读存储区
volatile强制编译器减少优化,必须每次到内存中取值
C语言-const和volatile深度分析的更多相关文章
- const与readonly深度分析(.NET)
前言 很多.NET的初学者对const和readonly的使用很模糊,本文就const和readonly做一下深度分析,包括: 1. const数据类型的优势 2. const数据类型的劣势 3. r ...
- C语言const和volatile关键字
这部分内容比较简单,我这里直接先做总结,然后通过写三个测试代码,体会其中的关键点 一.总结 1.const使得变量具有只读属性(但是不一定就是不能更改) 2.const不能定义真正意义上的常 ...
- 第9课 - const 和 volatile分析
第9课 - const和volatile分析 1. const只读变量 (1)const修饰的变量是只读的,本质上还是变量,并不是真正意义上的常量 ※※ const只是告诉编译器该变量 ...
- C语言中关键字auto、static、register、const、volatile、extern的作用
原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...
- JAVA CAS原理深度分析 volatile,偏向锁,轻量级锁
JAVA CAS原理深度分析 http://blog.csdn.net/hsuxu/article/details/9467651 偏向锁,轻量级锁 https://blog.csdn.net/zqz ...
- C语言中关键字volatile的含义【转】
本文转载自:http://m.jb51.net/article/37489.htm 本篇文章是对C语言中关键字volatile的含义进行了详细的分析介绍,需要的朋友参考下 volatile 的意思是“ ...
- 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)
写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...
- AndroidService 深度分析(2)
AndroidService 深度分析(2) 上一篇文章我们Service的生命周期进行了測试及总结. 这篇文章我们介绍下绑定执行的Service的实现. 绑定执行的Service可能是仅为本应用提供 ...
- 【转】话说C语言const用法
原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修 ...
随机推荐
- ES6常用语法(二)
arrow functions (箭头函数) 函数的快捷写法.不需要 function 关键字来创建函数,省略 return 关键字,继承当前上下文的 this 关键字 // ES5 var arr1 ...
- django 搭建一个投票类网站(四)
昨天我把投票页面终于写完,怎么说呢,觉得这本书对我的帮助也不是很大,然后去看了下django的文档,发现竟然是同一个项目...... 但还是要善始善终吧,贴一下中文版的文档https://docs.d ...
- Python 教你 4 行代码开发新闻网站通用爬虫
\ GNE(GeneralNewsExtractor)是一个通用新闻网站正文抽取模块,输入一篇新闻网页的 HTML, 输出正文内容.标题.作者.发布时间.正文中的图片地址和正文所在的标签源代码.G ...
- PHPMailer发送邮件遇坑小记
一:phpmailer发送邮件成功了 数据库发送状态也更改 但是用户就是没收到邮件. 出现原因:发送邮件太多 导致邮箱服务器被腾讯封了 发送的邮件统统进入了邮件服务器的草稿箱里. 解决方案: 重新修改 ...
- 题解 P5718 【【深基4.例2】找最小值】
题目传送门 思路 介绍一种新方法--sort排序,它的格式是这样的sort(a+1,a+n+1,cmp);,我们只需要把a数组排好序,然后输出第\(1\)个元素即可. 定义a数组与变量\(n\)并输入 ...
- Oracle 12c 如何在 PDB 中添加 SCOTT 模式(数据泵方式)
Oracle 12c 建库后,没有 scott 模式,本篇使用数据泵方式,在12c版本之前数据库中 expdp 导出 scott 模式,并连接 12c 的 pdb 进行 impdp 导入. 目录 1. ...
- pandas玩转excel-> (1)如何利用pandas创建【行,列,单元格】
import pandas as pd #------新建单元格的方法一:通过先创建字典的形式 #可以先新建一个字典d={'x':100,'y':200,'z':300} #打印字典的索引print( ...
- 【LInux01】学习Linux课程体系
知识 =>技能 需要大量的练习 相当于复盘 要有成就感 在一个领域深挖,再迁移到其他领域 1.两周以后的知识留存率: 主动学习: 动手实践:40% 讲给别人听:70% 写博客:是写教程,便 ...
- 原生JS操作class 极致版
// 获取class function getClass(el) { return el.getAttribute('class') } // 设置class function setClass(el ...
- 多模块打war包
1.在启动类的那个模块中的pom.xml中加入<packaging>war</packaging> 就这句 <groupId>com.mybatis</gr ...