const使用小结

来源:互联网 发布:nginx中配置pathinfo 编辑:程序博客网 时间:2024/06/03 20:23

const VS enum和#define

在C++中,常量有3种表达方式:cosnt, enum和#define,这3种方式有什么不同呢?
1. #define在编译预处理时进行数据替换,没有存储空间;
   enum是编译时常量,没有存储空间;
   const将会分配数据存储空间(取决于编译器是否进行constant propagation)。
2. #define在debug调试时看不到变量名;
   enum在调试时可以看见变量名,但不能获取没有地址;
   const在调试时可以看见变量名和地址(所以只有const能获取变量地址、传地址)。
3. enum和const是类型安全的,而#define不是;
   只有enum和#define可以被用于 switch。


一些概念

1. const的作用域是整个文件,默认为内部连接。为了使const成为外部连接以便让另外一个文件可以对它引用,必须明确把它定义成extern。extern const强制进行了空间分配,extern意味着使用外部链接,因此必须分配存储空间。
2. const是运行期常量,加上static const后变为编译器常量。


常量折叠

先看例子:

#include <iostream>using namespace std;int main(){    const int a = 2*5;     int *b = (int*)&a;    *b = 20;    cout << "&a = " << &a << ',' << "b = " << b <<endl    << "a = " << a << ',' << "*b = " << *b <<endl;    return 0;}
输出结果为:

&a = 0x7fffc239893c,b = 0x7fffc239893ca = 10,*b = 20
这时会发现&a和b的值(地址)一样,而a和*b的值不一样,就是说在相同的地址下的内存空间有不同的值。  
为什么呢?  
因为在编译期间进行了优化,即常量折叠(const folding),程序在编译过程中经过两种过程:1.const folding; 2.copy propagation。
const folding:上例中const int a = 2*5;  计算表达式的值时,编译器将2 * 5算成10,这个过程被称为const folding;
copy propagation:编译器在遇到a这个标识符时,自动将a替换成10,而不是去相应地址中取值,这个过程就是copy propagation.
上例就是这两个过程的结果,以后代码中遇到a的地方,编译器就自动将a替换成10.    
常量折叠概念:常量折叠是在编译时间简单化常量表达的一个过程。简单来说就是将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。  


编译时常量转运行时

编译时常量在编译后变量值已经确定,程序运行时常量值保持不变,例如:const int RUN_TIME = 1;
而运行时常量在程序运行时每次值都不一样。
例如:

int read_at_runtime(){   int val;   std::cin >> val;   return val; }const int RUN_TIME = read_at_runtime();

以下下几种情况不能使用编译时常量转运行时:
1. 数组边界; 2.switch case表达式; 3.位域长; 4.枚举初始化; 5.模板的非类型参数赋值。


0 0
原创粉丝点击