第9课 - const 和 volatile分析
第9课 - const和volatile分析
1. const只读变量
(1)const修饰的变量是只读的,本质上还是变量,并不是真正意义上的常量 ※※ const只是告诉编译器该变量不能出现在赋值符号的左边
(2)const修饰的局部变量在栈上分配空间;const修饰的全局变量在全局数据区分配空间
(3)const只在编译期间有用(检查const修饰的变量有没有出现在赋值符号左边,如果有就会编译报错),在运行期间无用
#include <stdio.h> int main()
{
const int cc = ; int *p = (int*)&cc; // cc = 10; // compile error: assignment of read-only variable ‘cc’ printf("cc = %d\n", cc); // cc = 1 *p = ; printf("cc = %d\n", cc); // cc = 10 return ;
}
2. const全局变量的分歧
(1)在标准C语言编译器中,const修饰的全局变量仍然存储于全局数据区,并没有改变存储方式,通过指针可以隐式的修改全局变量的值。
(2)在现代C语言编译器中,将const 修饰的全局变量分配在只读存储区,改变了存储方式,通过指针隐式修改会导致程序段错误。
#include <stdio.h> const int g_ci = ; int main()
{
int *p = (int *)&g_ci; // g_ci = 10; // compile error: assignment of read-only variable ‘g_ci’ printf("g_ci = %d\n", g_ci); *p = ; // 通过指针隐式修改 printf("g_ci = %d\n", g_ci); return ;
}
使用gcc编译执行(现代C编译器) ==> 段错误

使用bcc32编译执行(标准C编译器) ==> 修改成功

3. const的本质
(1)C 语言中的const 使得变量具有只读属性
(2)现代C编译器中的const将具有全局生命周期的变量(全局变量 + static修饰的局部变量)存储于只读存储区

【static修饰局部变量】
#include <stdio.h> int main()
{
const static int si = ; // const修饰static修饰的局部变量 int *p = (int *)&si; *p = ; // 使用gcc、VS2010编译执行会产生段错误
// 使用bcc32编译执行,可以修改si的值为1 printf("si = %d\n", si); return ;
}
【const的本质分析】
#include <stdio.h>
const int g_array[] = {};
void modify(int* p, int v)
{
*p = v;
}
int main()
{
int const i = ; // const放在int前后都可以
const static int j = ;
int const array[] = {};
modify((int*)&i, ); // ok
modify((int*)&j, ); // error,j存储在只读存储区
modify((int*)&array[], ); // ok
modify((int*)&g_array[], ); // error,g_array[5]数组存储在只读存储区
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 ;
}
4. const修饰函数参数和返回值
(1)const 修饰函数参数表示在函数体内不希望改变参数的值
(2)const 修饰函数返回值表示返回值不可改变,多用于返回指针的情形
TIP:C 语言的字符串字面量存储于只读存储区中,在程序中需要使用 const char* 指针

【const修饰函数参数与返回值】
#include <stdio.h> const char* f(const int i)
{
// i = 5; // error, i不能作为左值 return "swj striving! 2019-12-23 22:23:57";
} int main()
{
char* pc = f(); // 编译会报warning,函数f的返回值为const char* printf("%s\n", pc); pc[] = '_'; // error,试图修改只读存储区中的字符串 printf("%s\n", pc); return ;
}
5. 深藏不露的volatile
(1)volatile 可理解为 "编译器警告指示字"
(2)volatile 告诉编译器必须每次去内存中取变量值
(3)volatile 主要修饰可能被多个线程访问的变量
(4)volatile 也可以修饰可能被未知因数更改的变量

6. 有趣的问题
const volatile int i = 0;
ⅰ:变量 i 具有什么样的特性? i为int型变量,每次都必须到内存取值,且i是只读变量
ⅱ:编译器如何处理这个变量? i不能作为左值
第9课 - const 和 volatile分析的更多相关文章
- 第9课 const和volatile分析
1. const只读变量——(注意不是真正常量,只是告诉编译器不能出现在赋值号左边!) (1)const修饰的变量是只读的,本质还是变量 (2)const修饰的局部变量在栈上分配空间 (3)const ...
- const和volatile分析
c语言中const修饰的变量是只读的,不能直接作为赋值号的左值,其本质还是变量:会占用内存空间:本质上const在编译器有用,运行时无用(还是可以通过指针改变它的值) ; int *p=&ab ...
- C语言进阶——const 和 volatile 分析09
const只读变量: const修饰的变量是只读的,本质还是一个变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在全局函数区分配资源空间 const只在编译器有用,在运行期无用 ...
- C语言-const和volatile深度分析
1.const只读变量 const修饰的变量是只读的.本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在全局数据区分配空间 const只在编译期有用,在运行期无用 con ...
- C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast(dynamic_cast还支持交叉转换,const_cast将一个类的const、volatile以及__unaligned属性去掉)
在C++中,存在类型转换,通常意味着存在缺陷(并非绝对).所以,对于类型转换,有如下几个原则:(1)尽量避免类型转换,包括隐式的类型转换(2)如果需要类型转换,尽量使用显式的类型转换,在编译期间转换( ...
- C++ const、volatile、mutable的用法 (转)
const.volatile.mutable的用法 鸣谢作者: http://blog.csdn.net/wuliming_sc/article/details/3717017 const修饰普通 ...
- C语言中关键字auto、static、register、const、volatile、extern的作用
原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...
- const、volatile、mutable的用法
http://blog.csdn.net/wuliming_sc/article/details/3717017 const.volatile.mutable的用法 const修饰普通变量和指针 co ...
- C++ 中 const、volatile、mutable的用法
@2019-01-14 [小记] C++中const.volatile.mutable的用法
随机推荐
- 微信access token过期
两台服务器使用同一个微信账号(同一个app id) 时,当其中一台服务器向微信请求access token时,会造成另一台服务器的access token过期
- SpringBoot+MyBatis整合报错Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
项目启动的时候报这个错误,这个问题我百度了一天,果然不出意外的还是没能解决,其中有一篇文章相对来说还是有点用的:https://blog.csdn.net/qq8693/article/details ...
- MYSQL语法(一)
数据表准备: CREATE TABLE student3 ( id int, name varchar(20), age int, sex varchar(5), address varchar(10 ...
- springMVC入门(三)------springMVC的处理器映射器和处理器适配器配置
简介 springMVC的处理器映射器和处理器适配器存在多种配置,因此在此专门做一个总结 常见处理器映射器.适配器的配置 springmvc多个映射器多个处理器可以并存 所有的映射器都实现了Handl ...
- vmware 虚拟机共享 windows 目录
1.vmware 配置: 2.虚拟机进行配置: 虚拟机安装vmware-tools 3.虚拟机中挂载sr0(cdrom): [root@bogon ~]# mount /dev/sr0 /mnt/ m ...
- SpringBoot项目 使用Jenkins进行自动化部署 (gitLab管理项目)_
1.部署服务器创建好对应文件夹和启动脚本 创建文件夹 mkdir /wdcloud/app/rps/rps-module-category 创建启动脚本 cd /wdcloud/app/rps/rps ...
- Java算法——递归思想
描述递归(recursion):程序调用自身的编程技巧. 递归满足2个条件:1)有反复执行的过程(调用自身)2)有跳出反复执行过程的条件(递归出口) 递归与栈的关系下面演示的是求n的阶乘 int Fa ...
- CSS动画实例:3D立方体
CSS3支持3D转换,与3D转换有关的属性有: transform:向元素应用 2D或3D 转换. transform-origin:改变被转换元素的位置. transform-style:规定被嵌套 ...
- 从零搭建Spring Boot脚手架(7):整合OSS作为文件服务器
1. 前言 文件服务器是一个应用必要的组件之一.最早我搞过FTP,然后又用过FastDFS,接私活的时候我用MongoDB也凑合凑合.现如今时代不同了,开始流行起了OSS. Gitee: https: ...
- myblogplus 第二期 慕舲原创 如何删除官方在你博客内设置的所有广告
问题描述: 文章下方广告渐多了起来,这也无可厚非,原来只有小小一幅的,毕竟博客园团队很卖力,博客园首页不是在更新吗,博问也在推广(虽然解答者不多,提问者很多) 不过无疑很影响美观,那些可以让他设置,不 ...
