C语言进阶——const 和 volatile 分析09
const只读变量:
- const修饰的变量是只读的,本质还是一个变量
- const修饰的局部变量在栈上分配空间
- const修饰的全局变量在全局函数区分配资源空间
- const只在编译器有用,在运行期无用
注意:const修饰的变量不是真的常量,他只是告诉编译器该变量不能出现在赋值符号的左边
const全局变量的分歧:
- 在现代C语言编译器中,修改const全局变量将导致程序崩溃
- 标准C语言编译器不会将const修饰的全局变量存贮于只读存贮区中,而是存贮可修改的全局数据区,其值依然可以改变
程序实例1:
#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 = ; //error printf("g_cc = %d\n", g_cc); return ;
}
这段代码说明,const修饰的局部变量可以使用指针修改,但是const修饰全局变量不可以通过指针进行修改,第21行代码试图修改const修饰全局变量,由于我使用的codeblocks,是一款现代编译器,所以编译阶段会报错,删掉21行代码程序就可以正常运行
const的本质:
- C语言的const使得变量具有只读属性
- 现代C编译器中的const将具有全局生命周期的变量存贮于只读存贮区
- const不能顶第一真正意义上的常量
程序示例2:
#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 ;
}
第3行和第13行声明了用const修饰的具有全局生命周期的变量,所以在试图用指针来修改他们的值的时候,编译器会报错
const修饰函数参数和返回值:
- const修饰函数参数表示在函数体内不希望改变参数的值
- const修饰函数返回值表示返回值不可改变,多用于返回指针的情形
- 小贴示:C语言的字符串字面量存贮于只读存贮区中,在程序中需要使用const char* 指针
程序实例3:
#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行会出错,我们注释掉,接下来再编译,在12行会给出一个警告,我们用一个char *类型来接受了一个字面值常量,因为只是警告,所以我们可以运行一下,最后运行的时候还是出错了,因为第16行尝试修改了一个字面值常量
深藏不露的volatile:
- volatile 可以理解为 “编译器警告指示”
- volatile 告诉编译器必须每次去内存中去该变量值
- volatile 主要修饰可能被多个线程访问的变量
- volatile 也可以修饰可能被未知因数更改的变量
示例程序4:
int boj = ; //编译器在编译的时候发现obj int a=;
int b=; a= obj; //“聪明“的编译器不会到内存中去找obj对应的值,而是直接替换为10 sleep(); //在另一个线程里面可能已经改变了obj的值 b= obj; //这个时候编译器还是自作聪明的用10来代替obj,而不去内存中去找obj对应的值
这段代码只是一个小的片段,但是已经可以帮助我们理解有的时候编译器的自作聪明可能会导致某些bugconst volatile int i = 0;但是如果在定义一个变量的时候我们加上volatile属性,编译器每次就会去内存中去找到变量对应的值。
小结:
- const 使得变量具有只读属性
- const 不能定义真正意义上的常量
- const将具有全局生命周期的变量存贮于只读存贮区
- volatile 强制编译器减少优化,必须每次从内存中取值

C语言进阶——const 和 volatile 分析09的更多相关文章
- 第9课 - const 和 volatile分析
第9课 - const和volatile分析 1. const只读变量 (1)const修饰的变量是只读的,本质上还是变量,并不是真正意义上的常量 ※※ const只是告诉编译器该变量 ...
- 第9课 const和volatile分析
1. const只读变量——(注意不是真正常量,只是告诉编译器不能出现在赋值号左边!) (1)const修饰的变量是只读的,本质还是变量 (2)const修饰的局部变量在栈上分配空间 (3)const ...
- const和volatile分析
c语言中const修饰的变量是只读的,不能直接作为赋值号的左值,其本质还是变量:会占用内存空间:本质上const在编译器有用,运行时无用(还是可以通过指针改变它的值) ; int *p=&ab ...
- C语言进阶——enum, sizeof, typedef 分析11
枚举类型的使用方法: enum是C语言的 一种自定义类型 enum值是可以根据需要自定义的整型值 第一个enum的值默认为0 默认情况下的enum值是在前一个定义值的基础上加 1 enum类型的变量只 ...
- C语言进阶——struct和union分析10
struct的小秘密: C语言中的struct可以看作变量的集合 struct的问题:空结构体占用多大内存呢? 程序实例1: #include <stdio.h> struct TS { ...
- 《C语言进阶剖析》课程目录
<C语言进阶剖析>学习笔记 本文总结自狄泰软件学院唐佐林老师的<C语言 ...
- C语言-const和volatile深度分析
1.const只读变量 const修饰的变量是只读的.本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在全局数据区分配空间 const只在编译期有用,在运行期无用 con ...
- C语言中关键字auto、static、register、const、volatile、extern的作用
原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...
- 【R笔记】R语言进阶之4:数据整形(reshape)
R语言进阶之4:数据整形(reshape) 2013-05-31 10:15 xxx 网易博客 字号:T | T 从不同途径得到的数据的组织方式是多种多样的,很多数据都要经过整理才能进行有效的分析,数 ...
随机推荐
- iframe跨域上传图片
方案一:用jquery的$.post异步提交,然后把返回来的值用jquery填充到隐藏域中.可是$.post不支持跨域. jQuery.ajax()支持get方式的跨域,这其实是采用jsonp的方式来 ...
- css3 animatehue属性
-webkit-perspective(-moz,-o,perspective下同)表示透视范围大小: -webkit-transform-style很好理解了,表示变换类型,preserve-3d看 ...
- Struts2_使用token拦截器控制重复提交(很少用)
控制重复提交的方式:1.表单提交后页面重定向:2.Struts2.x token拦截器 大致流程: 例子: index.jsp <%@ page language="java" ...
- 项目01-nginx模块
项目01-nginx模块 1.nginx介绍 nginx是一款高性能web服务器和反向代理服务器,在互联网项目中使用非常频繁,尤其其出色的性能以及轻量级进程占用,已经超过了apache的httpd服务 ...
- word文档快速转换为PPT演示文稿
方法一: 访问http://t.im/pdftoppt,点击继续浏览(会跳转至:https://smallpdf.com/cn/pdf-to-ppt): 打开word文档,设置为“横向”,输出为PDF ...
- May 04th 2017 Week 18th Thursday
No matter how far you may fly, never forget where you come from. 无论你能飞多远,都别忘了你来自何方. I never forget w ...
- 【BZOJ4487】[JSOI2015] 染色问题(高维容斥)
点此看题面 大致题意: 有一个\(n*m\)的矩形,先让你用\(C\)种颜色给它染色.每个格子可染色可不染色,但要求每行每列至少有一个小方格被染色,且每种颜色至少出现一次.求方案数. 高维容斥 显然题 ...
- caffe resize用interpolation
opencv的resize默认的是使用双线性插值INTER_LINEAR,也可以是尝试其他的方式进行插值操作 if (param.random_interpolation_method()) { // ...
- halcon保存带有region的图片算子
显示带区域的图片除了可以用dev_display挨个显示外再截图,还可以通过一个算子来实现这一功能 这个算子是:dump_window_image.(其实就是截图) 这个算子的意思是把WindowHa ...
- 第36章 SDIO—SD卡读写测试—零死角玩转STM32-F429系列
第36章 SDIO—SD卡读写测试 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...