一、文章来由

const具体解释之二

二、const 取代 #define

const最初动机就是取代 #define。

const 优于 #define:

(1) #define没有类型检查,const在编译期(而不是预编译期)做类型检查。

(2)const方便调试和定位bug。

所以应该全然用const取代#define

三、头文件里的const

(1)要使用const取代#define。相同须要把const定义放进头文件(或其它格式文件,include就可以)。

这样通过包括头文件。可把const定义单独放在一个地方并把它分配给一个编程单元。

(2)C++中的const默觉得内部连接(internal linkage),也就是说 const 仅在被定义过的文件里才可见,而在连接时不能被其它

url=Lo9O57v2QfNPo448tsFG0ohDjltQti7bZzkVdj5AZfTf0UmOpLWtCxRIS8IHzjonYh1CBOZ1M4XyNtjylIkzU_">编译单元看到。

可是在c中只在还有一个文件里定义(不用extern修饰),还有一个文件也是合法的。c中const是必需分配内存的,而c++实际上一開始是不会分配内存的,不过存在字符表中。

//another.c
const int a = 5; //other.c
#include <stdio.h> int main()
{
extern const int a;
printf("%d\n",a); return 0;
}

(3)定义一个const时。必须赋一个值给它,除非用extern做说明:extern const int bufsize;

四、常量折叠(constant folding)

通常C++编译器并不为const创建存储空间,相反它把这个定义保存在它的符号表里,但extern强制进行了存储空间分配。取const地址也会**,这也解释了const具体解释(一)中可以改动const空间。可是cout原值相当于还是去符号表中找。

由于extern意味着使用外部连接(定义时使用extern),因此必须分配存储空间,这也就是说有几个不同的编译单元应当可以引用它,所以必须有存储空间。

通常情况下,当extern不是定义的一部分时,不会分配存储空间。假设使用const,那么编译时会进行常量折叠。

那同文件extern呢

extern const int a;
int main()
{
//freopen("input.txt","r",stdin); cout<<a<<endl; return 0;
} const int a = 66;

由于extern不是定义的一部分,所以个人觉得这也不会分配空间。

五、为什么const要内部连接

当然想绝对不为不论什么const分配存储是不可能的,尤其是复杂的结构。所以const的定义必须默认内部连接,即连接仅在特定的编译单元内;否则。由于众多的const在多个cpp文件分配内存,引起连接错误。

连接程序在多个对象文件看到统一的定义就会“抱怨”。

然而,由于const默认内部连接,所以连接程序不会跨过编译单元连接那些定义,因此不会有冲突。


參考资料

[1] c++编程思想

[2] http://blog.csdn.net/bestrivenfan/article/details/50951809

C++高级进阶 第四季:const具体解释(二) 常量折叠的更多相关文章

  1. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  2. 高级进阶DB2(第2版)——内部结构、高级管理与问题诊断

    <高级进阶DB2(第2版)——内部结构.高级管理与问题诊断> 基本信息 作者: 牛新庄    出版社:清华大学出版社 ISBN:9787302323839 上架时间:2013-7-3 出版 ...

  3. MEF高级进阶

    MEF高级进阶   好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四 ...

  4. .Net高级进阶,在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码?

    本文将通过场景例子演示,来通俗易懂的讲解在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码. 通过一系列优化最终达到两个效果,1.通过代码块来控制事务(分布式事务),2.通过委托优化Tran ...

  5. [总]Android高级进阶之路

    个人Android高级进阶之路,目前按照这个目录执行,执行完毕再做扩展!!!!! 一.View的绘制 1)setContentView()的源码分析 2)SnackBar的源码分析 3)利用decor ...

  6. 高级进阶DB2(第2版)

    <高级进阶DB2(第2版)> 基本信息 作者: 牛新庄 出版社:清华大学出版社 ISBN:9787302323839 上架时间:2013-7-3 出版日期:2013 年7月 开本:16开 ...

  7. Django笔记 —— 模板高级进阶

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  8. 6.MySQL优化---高级进阶之表的设计及优化

    转自互联网整理. 优化之路高级进阶——表的设计及优化 优化①:创建规范化表,消除数据冗余 数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规 ...

  9. openssl之EVP系列之5---EVP_Encrypt系列函数具体解释(二)

    openssl之EVP系列之5---EVP_Encrypt系列函数详细解释(二)    ---依据openssl doc/crypto/EVP_EncryptInit.pod和doc/ssleay.t ...

随机推荐

  1. [BZOJ2667][cqoi2012]模拟工厂 贪心

    2667: [cqoi2012]模拟工厂 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 367  Solved: 184[Submit][Status] ...

  2. 洛谷——P1795 无穷的序列_NOI导刊2010提高(05)

    P1795 无穷的序列_NOI导刊2010提高(05) 题目描述 有一个无穷序列如下: 110100100010000100000… 请你找出这个无穷序列中指定位置上的数字 输入输出格式 输入格式: ...

  3. SPOJ PT07J - Query on a tree III(划分树)

    PT07J - Query on a tree III #tree You are given a node-labeled rooted tree with n nodes. Define the ...

  4. bzoj4543[POI2014]Hotel

    题目链接 bzoj4543 [POI2014]Hotel 题解 这不是裸地点分嘛 ,我真傻,真的 n^2 这不是是sb题,~滑稽 ~ 枚举点转换为无根树,暴力子树中点的深度 计数转移 令a b c d ...

  5. bzoj 2660: [Beijing wc2012]最多的方案

                       Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 617  Solved: 361[Submit][Status][ ...

  6. 【分块】bzoj1901 Zju2112 Dynamic Rankings

    区间k大,分块大法好,每个区间内存储一个有序表. 二分答案,统计在区间内小于二分到的答案的值的个数,在每个整块内二分.零散的暴力即可. 还是说∵有二分操作,∴每个块的大小定为sqrt(n*log2(n ...

  7. 使用gettext提取c#中的多语言占位符(nopCommerce示例篇)

    i18n国际化通常的作法是使用gettext,即在源码中使用特殊的关键字来标识这个字符串将可能被翻译,如 @if (Model.IsCustomerForumModerator) { <li c ...

  8. Jquery的Split二次分割

    <script type="text/javascript">var str="Q1#k1:Q2#k2"var str2=str.split(':' ...

  9. 64位下安装Scrapy 报错 "could not find openssl.exe" 的解决方法。

    其实就是安装对应的64位 pyOpenSSL 就行了, 下载地址如下: https://tahoe-lafs.org/source/tahoe-lafs/deps/tahoe-lafs-dep-egg ...

  10. linux如何启动/停止/重启MySQL

    如何启动/停止/重启MySQL 一.启动方式 1.使用 service 启动:service mysqld start2.使用 mysqld 脚本启动:/etc/inint.d/mysqld star ...