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的更多相关文章

  1. 第9课 - const 和 volatile分析

    第9课 - const和volatile分析 1. const只读变量 (1)const修饰的变量是只读的,本质上还是变量,并不是真正意义上的常量         ※※ const只是告诉编译器该变量 ...

  2. 第9课 const和volatile分析

    1. const只读变量——(注意不是真正常量,只是告诉编译器不能出现在赋值号左边!) (1)const修饰的变量是只读的,本质还是变量 (2)const修饰的局部变量在栈上分配空间 (3)const ...

  3. const和volatile分析

    c语言中const修饰的变量是只读的,不能直接作为赋值号的左值,其本质还是变量:会占用内存空间:本质上const在编译器有用,运行时无用(还是可以通过指针改变它的值) ; int *p=&ab ...

  4. C语言进阶——enum, sizeof, typedef 分析11

    枚举类型的使用方法: enum是C语言的 一种自定义类型 enum值是可以根据需要自定义的整型值 第一个enum的值默认为0 默认情况下的enum值是在前一个定义值的基础上加 1 enum类型的变量只 ...

  5. C语言进阶——struct和union分析10

    struct的小秘密: C语言中的struct可以看作变量的集合 struct的问题:空结构体占用多大内存呢? 程序实例1: #include <stdio.h> struct TS { ...

  6. 《C语言进阶剖析》课程目录

    <C语言进阶剖析>学习笔记                                                         本文总结自狄泰软件学院唐佐林老师的<C语言 ...

  7. C语言-const和volatile深度分析

    1.const只读变量 const修饰的变量是只读的.本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在全局数据区分配空间 const只在编译期有用,在运行期无用 con ...

  8. C语言中关键字auto、static、register、const、volatile、extern的作用

    原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...

  9. 【R笔记】R语言进阶之4:数据整形(reshape)

    R语言进阶之4:数据整形(reshape) 2013-05-31 10:15 xxx 网易博客 字号:T | T 从不同途径得到的数据的组织方式是多种多样的,很多数据都要经过整理才能进行有效的分析,数 ...

随机推荐

  1. 《Head First 设计模式》总结

    复合模式——模式的模式 MVC(模型-视图-控制器):是由数个设计模式结合起来的模式. 戴着模式的有色眼镜看MVC: 模型利用观察者模式让控制器和视图可以随最新的状态改变而更新. 模型对视图和控制器一 ...

  2. Design Pattern ->Abstract Factory

    Layering & Contract Philosophy With additional indirection Abstract Factory //The example code i ...

  3. 从刷票了解如何获得客户端IP

    我的个人博客,源地址:http://www.woniubi.cn/get_client_ip/ 前两个星期帮一个朋友的亲戚的孩子刷票,谁让咱们是程序员呢.这当中也遇到过重装系统,除灰尘,淘宝购物,盗Q ...

  4. eclipse:maven工程下显示不出文件,但系统存在,可能是这个原因

  5. php的yii框架开发总结6

    MVC中的Controller部分,所有的controller类都是继承自Controller基类,基类里面包含actionAdmin-管理员,actionIndex-一般默认显示,actionVie ...

  6. 洛谷 P3905 道路重建

    题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...

  7. 初学React:组件的样式

    React中组件的样式有三种: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  8. IOS http协议 总结

    HTTP协议1.面试题常见:聊一下HTTP协议(协议的完整的通信过程) ============================================================ 一.一 ...

  9. HDU 3639 Hawk-and-Chicken(强连通分量+缩点)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013480600/article/details/32140501 HDU 3639 Hawk-a ...

  10. 【CCPC-Wannafly Winter Camp Day4 (Div1) J】跑跑跑路(爬山)

    点此看题面 大致题意: 共两轮,每轮每人有一个标签,标签相同的人必须到同一个点集合.求所有人总路程的最小值. 爬山算法 这道题貌似有三种做法:模拟退火.高斯消元以及爬山算法. 相比之下,自然是爬山算法 ...