1. const只读变量——(注意不是真正常量,只是告诉编译器不能出现在赋值号左边!)

(1)const修饰的变量是只读的,本质还是变量

(2)const修饰的局部变量上分配空间

(3)const修饰的全局变量全局数据区分配空间(vc、gcc会将其放入常量区,bcc放入全局数据区)

(4)const只在编译期有用,在运行期无用

【编程实验】const变量的本质

#include <stdio.h>

const int g_cc = ;//bcc下放入全局数据区,可修改。
//vc、gcc将其放入常量区,不可修改 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 = ; //bcc编译器下没问题,vc\gcc下会出错。 printf("g_cc = %d\n", g_cc); return ;
}

2. const的本质——不能定义真正意义上的常量

(1)C语言中的const使得变量具有只读属性

(2)现代C编译器(如Vc、gcc)中的const将具有全局生命周期(如全局变量,static属性的变量)存储于只读存储区,修改该变量时将导致程序崩溃。

【注意】标准C语言编译器(如bcc)不会被const修饰的全局变量存储于只读存储区,而是存储于可修改的全局数据区,其值依然可以改变。

【编程实验】const本质的分析

#include <stdio.h>

const int g_array[] = {};

void modify(int* p, int v)
{
*p = v;
} int main()
{
int const i = ; //相当于const int i=0;
const static int j = ;
int const array[] = {}; //相当于const int array[5]={0}; 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. const修饰函数参数和返回值

(1)const修饰函数参数表示在函数体内不希望改变参数的值

(2)const修饰函数返回值表示返回值不可改变,多用于返回指针的情形。

【小贴士】C语言中的字符串字面量存储于只读存储区中,在程序中需要使用const char*指针

#include <stdio.h>

int main(){

    const char* s= "I like programming!"; //存储于只读存读区

}

【实例分析】const修饰函数参数与返回值

#include <stdio.h>

const char* f(const int i)
{
i = ;//错误,i不能作为左值 return "I like programming!";
} int main()
{
char* pc = f(); //警告,f的返回值为const char* printf("%s\n", pc); pc[] = '_'; //错误,试图修改只读存储区中的数据 printf("%s\n", pc); return ;
}

4. 深藏不露的volatile

(1)volatile可理解为“编译器警告指示字”

(2)volatile告诉编译器必须每次去内存中取变量值

(3)volatile主要修饰可能被多个线程访问的变量

(4)volatile也可以修饰可能被未知因数更改的变量

5. 有趣的问题——const volatile int i=0;

(1)变量i具有什么样的特性:i为int型变量,每次都必须到内存取值,且i是只读变量。

(2)编译器如何处理这个变量:i不能作为左值

6. 小结

(1)const使得变量具有只读属性

(2)const不能定义真正意义上的常量

(3)const将具有全局生命期(含static属性的)的变量存储于只读存储区中

(4)volatile强制编译器减少优化,必须每次到内存中去取值

第9课 const和volatile分析的更多相关文章

  1. 第9课 - const 和 volatile分析

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

  2. const和volatile分析

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

  3. C语言进阶——const 和 volatile 分析09

    const只读变量: const修饰的变量是只读的,本质还是一个变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在全局函数区分配资源空间 const只在编译器有用,在运行期无用 ...

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

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

  5. C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast(dynamic_cast还支持交叉转换,const_cast将一个类的const、volatile以及__unaligned属性去掉)

    在C++中,存在类型转换,通常意味着存在缺陷(并非绝对).所以,对于类型转换,有如下几个原则:(1)尽量避免类型转换,包括隐式的类型转换(2)如果需要类型转换,尽量使用显式的类型转换,在编译期间转换( ...

  6. C++ const、volatile、mutable的用法 (转)

      const.volatile.mutable的用法 鸣谢作者: http://blog.csdn.net/wuliming_sc/article/details/3717017 const修饰普通 ...

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

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

  8. const、volatile、mutable的用法

    http://blog.csdn.net/wuliming_sc/article/details/3717017 const.volatile.mutable的用法 const修饰普通变量和指针 co ...

  9. C++ 中 const、volatile、mutable的用法

    @2019-01-14 [小记] C++中const.volatile.mutable的用法

随机推荐

  1. 获取exe所在目录路径,速度

    // test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> #include &l ...

  2. 【计算机视觉】如何使用opencv自带工具训练人脸检测分类器

    前言 使用opencv自带的分类器效果并不是很好,由此想要训练自己的分类器,正好opencv有自带的工具进行训练.本文就对此进行展开. 步骤 1.查找工具文件: 2.准备样本数据: 3.训练分类器: ...

  3. CSS的使用

    1.行内样式/内联样式 特点:在具体的HTML标签中引入CSS代码 语法:所有的HTML标签都具有一个style属性,属性值就可以使用CSS样式规则 <标签 style="CSS样式规 ...

  4. HPU :字符串的统计

    字符串的统计 时间限制: 2 Sec 内存限制: 128 MB提交: 15 解决: 1 题目描述 给定n个字符串,我想知道第i个字符串已经出现多少次? 输入 第一行输入一个整数t,代表t(t < ...

  5. 记录几个ubuntu环境下的php相关的路径

    php路径 /usr/bin/php phpize5 /usr/bin/phpize5 php5-fpm /usr/sbin/php5-fpm php所有的配置文件 /etc/php5/fpm 重启p ...

  6. CUDA H624解码性能测试

    测试环境: Cpu:       Inter(R)Core(TM)i7-4790 CPU @3.6GHZ GPU:         NVIDIA GeForce GTX960* 1 操作系统:   W ...

  7. Java 发展历史

    Java自1995诞生,至今已经20多年的历史. Java的名字的来源:Java是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名.Java语言中的许多库类名称,多与咖啡有关,如JavaBeans(咖啡豆 ...

  8. oracle之 redo过高诊断

    一.诊断过度redo 要找到生成大量重做的会话,您可以使用以下任何一种方法.这两种方法都检查生成的撤销量.当一个事务生成撤销,它将自动生成重做. 当需要检查生成大量的程序时,使用第一个查询.当这些程序 ...

  9. ORA-10997:another startup/shutdown operation of this instance in progress解决方法

    SQL> startup ORA-10997: another startup/shutdown operation of this instance inprogress ORA-09967: ...

  10. centos7 MFS drbd keepalived

    环境: centos7.3 + moosefs 3.0.97 + drbd84-utils-8.9.8-1 + keepalived-1.2.13-9 工作原理: 架构图: 节点信息: 节点名     ...