
C++ 中存在 const 常量和非 const 变量,const 常量不允许被修改。
在指针的声明中使用 const:
1. 指向 const 常量的指针:防止通过指针修改指针指向的值。
例如:const int* pNum = &nNum; // 无法通过 pNum 修改 nNum
2. const 指针:防止修改指针的值。例如:
int* const pNum = &nNum; // 无法修改 pNum
注意这样的情况:
int nNum = 10;
const int* pNum = &nNum;
我们无法通过指针 pNum 修改 nNum,但是 nNum 实际上并不是一个常量,即是在指针的声明中使用 const,const
仅仅和指针相互绑定。
在 C++ 中,指向 const 常量的指针能够指向 const 常量和非 const 变量,对于常规指针来说,只能指向非 const
变量,例如:
const int nNum = 10; // const
const int* pNum = &nNum; // valid
int* pNum2 = &nNum; // invalid
我们再看一个例子:
void Func(int* pNum){}
const int NUM = 10;
Func(&NUM); // Error: cannot convert parameter 1 from 'const
int*' to 'int*'
而这样定义 Func 就不会出问题:
void Func(const int* pNum){}
因此,我们应该尽可能的使用 const:
1. 避免了无意的修改数据而导致的错误
2. 在函数的指针形参上使用 const 使得函数能够处理 const 和非 const 实参
实际上,const 常量在编译时能够进行常量折叠(constant
folding)(在程序编译期间,在可能的情况下,符号常量的值会替换该名字的出现)。const
常量默认为内部链接性,如果我们做了如下定义:
extern const int NUM = 10;
int arrTest[NUM]; // OK,NUM 的定义与 arrTest 的定义在同一个编译单元
注意,存在于内存中的值,在编译时是无法使用的(这很明显,因为编译时程序还没有运行起来),常量折叠仅仅发生在编译时,下面的代码将无法通过编译:
extern const int NUM; // 在其他处定义
int arrTest[NUM]; // Error,无法获得 NUM 的值,不在同一个编译单元中,无法进行常量折叠
对于一些复杂的数据结构,必定引发内存的分配:
const int arrNum[] = {1, 2, 3, 4};
int arrNum2[arrNum[0]]; // Error,编译期间无法取内存中的值
Powered by Haiwit