1、C语言中的const:

  • const修饰的变量是只读的,本质还是变量
  • const修饰的局部变量在栈上分配空间
  • const修饰的全局变量在只读存储区分配空间
  • const只在编译期有用,在运行期无效
  • const不能定义真正意义上的常量

const修饰的变量不是真的常量,它只是告诉编译器该变量不能出现在赋值符号的左边。const 局部变量是在栈上分配空间,可以通过指针改变这个空间里面的值。过了编译期,const变量的常量特性,只读特性就没有了,只读特性只在编译期有效,运行期根本无效。const修饰的全局变量在只读存储区分配空间,因此如果用指针去修改了const修饰的全局变量,程序就会崩溃,因为修改了程序只读存储区中内容,大部分程序都会发生崩溃。

2、C++中的const:

C++在C的基础上对const进行了进化处理,具体表现在:

  • const声明时,在符号表中放入常量

  • 编译过程中发现常量直接以符号表中的值替换(常量折叠)

  • 编译过程中也可能为对应的常量分配存储空间:

    • const用在全局或者使用了static关键字说明,存放在只读数据区

      extern const int i = 10;
      static const int i = 10; // 或者修饰全局变量
      const int a =10;
      int main()
      {}
    • 局部变量中对const常量使用了&操作符,在栈区分配空间

注意:C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值

符号表是编译过程中产生的一种数据结构

#include <iostream>
#include <string>
using namespace std; const int i = 10; // 如果通过指针去改变i,就会出现段错误:尝试修改只读数据区数据
int main()
{
const int a = 5;
int *p = (int *)&a; // &a, 给a标识符分配空间了,并用p指向了该空间,可以通过*p访问这个地址,但是不能通过a来访问
*p = 10; // 不能通过指针去改变a的值
cout << a << endl;
cout << *p << endl; return 0;
}

3、与宏定义对比

C++ 中的const常量类似于宏定义

const int c = 5;
// 类似于
#define c 5

但是cosnt与宏定义的区别在于:

  • const常量是有编译器处理
  • 编译器对cosnt常量进行类型检查和作用域检查
  • 宏定义由预处理器处理,只是进行单纯的文本替换
#include <stdio.h>

void f()
{
#define a 3
const int b = 4;
} void g()
{
printf("a = %d\n", a);
// 在g函数中访问f函数中的宏定义,完全没有问题
// 在预处理的时候就进行了宏替换,对编译器来说,就是printf("a = %d\n", 3);
// 宏是没有作用域的概念 // const 定义的常量,被编译器处理,是有作用域的,不能访问b
printf("b = %d\n", b);
} int main()
{
const int A = 1;
const int B = 2;
int array[A + B] = {0};
// 如果是C语言,const修饰得到的只是具有只读特性的变量,数组的大小是由两个变量的大小决定的,两个变量相加的结果需要在运行的时候才能直到,因此编译器编译的时候不知道这个数组长度,直接报错
// C++编译,const是定义的真正意义上的常量,直接从符号表中取值,编译的时候就知道A和B的值,可以得到数组的长度,不会报错
int i = 0; for(i=0; i<(A + B); i++)
{
printf("array[%d] = %d\n", i, array[i]);
} f();
g(); return 0;
}

4、小结

与C语言不同,C++中的const不是只读变量

C++中的const是一个真正意义上的常量

C++编译器可能会为const常量分配空间

C++完全兼容C语言中const常量的语法特性

三、C++ const分析的更多相关文章

  1. mysql优化(三)–explain分析sql语句执行效率

    mysql优化(三)–explain分析sql语句执行效率 mushu 发布于 11个月前 (06-04) 分类:Mysql 阅读(651) 评论(0) Explain命令在解决数据库性能上是第一推荐 ...

  2. 对于这个函数const int func(const int& a) const声明中,三个const分别是什么意思?

    第一个const 函数的返回值类型是const. 这个const修饰没什么意义,你可以想象一下: 既然是函数的 返回值,而且是值传递的形式,是否const有什么意义.如果指针(引用)传递,怎表示返回值 ...

  3. [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const

    程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...

  4. OO前三次作业分析

    一,第一次作业分析 度量分析: 第一次的oo作业按照常理来说是不应该有这么多的圈复杂度,但是由于第一次写的时候,完全不了解java的相关知识,按照c语言的方式来写,完全的根据指导书的逻辑,先写好了正确 ...

  5. 实验三:跟踪分析Linux内核的启动过程

    实验三:跟踪分析Linux内核的启动过程 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.16 ...

  6. LwIP协议栈开发嵌入式网络的三种方法分析

    LwIP协议栈开发嵌入式网络的三种方法分析   摘要  轻量级的TCP/IP协议栈LwIP,提供了三种应用程序设计方法,且很容易被移植到多任务的操作系统中.本文结合μC/OS-II这一实时操作系统,以 ...

  7. 开始 python programming第三版案例分析

    最近研究python,打算将python programming第三版案例分析下 但是全书1600多页 比较费时 而且 介绍太多 感觉没有必要! python programming 堪称经典之作 第 ...

  8. Linux I2C设备驱动编写(三)-实例分析AM3359

    TI-AM3359 I2C适配器实例分析 I2C Spec简述 特性: 兼容飞利浦I2C 2.1版本规格 支持标准模式(100K bits/s)和快速模式(400K bits/s) 多路接收.发送模式 ...

  9. 【转】Linux I2C设备驱动编写(三)-实例分析AM3359

    原文网址:http://www.cnblogs.com/biglucky/p/4059586.html TI-AM3359 I2C适配器实例分析 I2C Spec简述 特性: 兼容飞利浦I2C 2.1 ...

随机推荐

  1. python list生成表达式

    列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式.运用列表生成式,可以写出非常简洁的代码. >>> list(ra ...

  2. bzoj 3796: Mushroom追妹纸【二分+后缀数组+st表】

    把三个串加上ASCII大于z的分隔符连起来,然后求SA 显然每个相同子串都是一个后缀的前缀,所以枚举s1的每个后缀的最长和s2相同的前缀串(直接在排序后的数组里挨个找,最近的两个分别属于s1和s2的后 ...

  3. ionic4+angular7+cordova上传图片

    安装插件 安装插件Image Picker $ ionic cordova plugin add cordova-plugin-telerik-imagepicker $ npm install @i ...

  4. K8S学习心得 == kube-controller-manager 报错configmaps "extension-apiserver-authentication" is forbidden: User "kubernetes" cannot get resource "configmaps" in API group ""

    当我按照教材设置证书,配置好kube-controller的相关条件后,启动kube-controller-manage组件,却意外报错. 一.基本信息如下: 1. kube-controller-m ...

  5. php连接mysql并读取数据

    <?php $server_name="localhost:3306"; //数据库服务器名称 $username="root"; // 连接数据库用户名 ...

  6. 洛谷 P3810 【模板】三维偏序(陌上花开) (cdq分治模板)

    在solve(L,R)中,需要先分治solve两个子区间,再计算左边区间修改对右边区间询问的贡献. 注意,计算额外的贡献时,两子区间各自内部的顺序变得不再重要(不管怎么样左边区间的都发生在右边之前), ...

  7. Spark MLlib编程API入门系列之特征选择之R模型公式(RFormula)

    不多说,直接上干货! 特征选择里,常见的有:VectorSlicer(向量选择) RFormula(R模型公式) ChiSqSelector(卡方特征选择). RFormula用于将数据中的字段通过R ...

  8. SASS @mixin 遇到的坑

    @mixin borderTop($size:1px,$type:solid,$color:red){ border-top:$size $type $color; } .border_top{ @i ...

  9. 利用贝塞尔曲线绘制(UIBezierPath)自定义iOS动态速度表,可以自定义刻度,刻度值,进度条样式

    GitHub的Demo下载地址 使用UIBezierPath画图步骤: 创建一个UIBezierPath对象 调用-moveToPoint:设置初始线段的起点 添加线或者曲线去定义一个或者多个子路径 ...

  10. elasticsearch 2.4.0安装说明

    首先从官网下载安装包,是个压缩文件,然后解压 在es目录下找到es的配置文件 修改集群(cluster)名称 PS:一般情况下一台机只部署一个es程序,也就是一个集群,默认集群名是ewater_mai ...