5.1认识常量
1.字面常量只能引用不能修改,所以一般都是保存在程序符号表里,而不是一般的数据区中.除了字符
串,你无法读取一个字面常量的地址.
char *p="abcde";
*(p+2)='k';//error,不能修改常量字符串的内存单元
2.存在两种符号常量
#define定义的:#define是预编译指令,他定义的宏常量进入编译阶段已经被替换为字面常量了,实质
上是字面常量.
const定义的:在C语言中,const定义的常量实际是不能修改的变量,因此会分配空间;C++中,const定
义的常量要具体情况具体对待,基本数据类型的常量,编译器会把它放到符号表里,不分配存储空间,
而ADT/UDT的const对象则要分配空间(大对象).
对于基本数据类型的const常量,编译器会在内存创建它的一个拷贝,通过地址访问到的就是这个拷贝
而非原始的符号常量.而大数据对象往往无法防止通过指针修改数据,所以const的限定是"防君子不
防小人".
const int i=10;
int *pi=(int*)&i; //取常量的"地址",注意这里的强制转换,目的是去常量化
*pi = 5;//这里改变的实际上是一个临时变量的值
printf("i=%d, *pi=%d\n", i, pi);//i的值没有变!
class A
{
public:
A():i(10){};
int i;
};
const A ca;
A *pa=(A*)&ca;//注意这里的强制转换,目的是去常量化
pa->i = 5;
cout
3.标准C中,const符号常量默认是外连接的(分配存储),也就是不能在两个编译单元定义同名的符号
常量(重复定义错误);
标准C++中,const符号常量默认是内连接的,当每个编译单元编译时会为他们分配存储空间,而在连接
时进行常量合并.
5.4类中的常量
非static的const数据成员:不能在类体中初始化,只能通过构造函数的初始化列表
static const数据成员:可以在类体中初始化,但所有类对象共享该成员
枚举常量:不会占用对象的存储空间,编译时被全部求值,例如
class A
{
...
enum
{
size1=100,
size2=200
};
int array1[size1];//ok,size1会被直接求值
}
5.5如何定义常量
多个编译单元或模块共用时,const变量该在哪里定义呢?
充分理解上面3.中所讲的道理,这个问题就好理解了
C程序:const默认是外连接的,就像全局变量一样,如果要在头文件中定义,必须使用static关键字,这
样,每个源文件引用时,在各自的编译单元会形成该常量的一份独立定义;或者在某个源文件中定义并
初始化,其他文件通过extern声明来访问他.
C++程序:const符号常量定义默认是内连接的,这样在头文件中定义就不需要static限定.
阅读(2507) | 评论(0) | 转发(0) |