C语言中的const
const修饰的变量是只读的,本质还是变量
const修饰的局部变量在栈上分配空间
const修饰的全局变量在只读存储区分配空间
const只在编译期有用,在运行期无用
注意:const修饰的变量不是真的常量,它只是告诉编译器该变量不能出现在赋值符号的左边。
总结:
C语言中的const使得变量具有只读属性
const将具有全局生命周期的变量存储于只读存储区
const不能定义真正意义上的常量!
C语言中只有通过enum定义的标识符才是真正意义上的常量。
编程实验
C/C++中的const
假设为test.c
1 #include <stdio.h>
2
3 int main()
4
5 {
6
7 const int c = 0;
8
9 int *p = (int*)&c;
10
11 printf("Begin...
");
12
13 *p = 5;
14
15 printf("c = %d
",c);
16
17 printf("End ...
");
18
19 return 0;
20
21 }
1)利用C编译器,即执行
gcc test.c
./a.out
得到C的值为5;
2)利用C++编译器,即执行
g++ test.c
./a.out
得到C的值是0,
说明第13行*p = 5 不起作用了。
同一个程序用C语言编译器和用C++编译器编译得到的运行结果不同。
下面再来修改程序,观察程序的运行结果:
1 #include <stdio.h> 2 3 int main() 4 5 { 6 7 const int c = 0; 8 9 int *p = (int*)&c; 10 11 printf("Begin... "); 12 13 *p = 5; 14 15 printf("c = %d ",c); 16 printf("*p = %d ",*p);
17 printf("End ...
");
return 0;
}
利用C编译器,得到
c = 5;
*p = 5;
利用C++编译器,得到
c = 0;
*p = 5;
为什么会这样呢?
说明了const关键字在从C语言到C++语言的进化中得到了很大的改变。那么变化究竟在哪里呢?
C++在C的基础上对const进行了进化处理
——当碰见const声明时在符号表中放入常量
——编译过程中若发现使用常量则直接以符号表中的值替换
——编译过程中若发现下述情况则给对应的常量分配存储空间(C++天生兼容C语言,也会有给常量分配空间的情况)
对const常量使用了extern
对const常量使用了&操作符
注意:
C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。(就是为了兼容C语言,兼容的意义就在于以前用C编译器编译过得程序,也能用C++编译器编译过,但运行的结果可能不同)
C语言中的const变量
——C语言中const变量是只读变量,会分配存储空间
C++中的const常量(从C语言中的只读变量变为一个常量了,但为了兼容C语言,可能为常量分配空间)
——可能分配存储空间
当const常量为全局,并且需要在其他文件中使用
当使用&操作符对const常量取地址
C++中的const常量类似于宏定义
——const int c = 5; 约等于 #define c 5
C++中的const常量在与宏定义不同
——const常量是由编译器处理
——编译器对const常量进行类型检查和作用域检查
——宏定义由预处理器处理,单纯的文本替换
const与宏的代码分析
1 #include <stdio.h>
2
3 void f()
4 {
5 #define a 3
6 const int b = 4;
7 }
8
9 void g()
10 {
11 printf("a = %d
", a);
12 //printf("b = %d
", b);
13 }
14
15 int main()
16 {
17 const int A = 1;
18 const int B = 2;
19 int array[A + B] = {0};
20 int i = 0;
21
22 for(i=0; i<(A + B); i++)
23 {
24 printf("array[%d] = %d
", i, array[i]);
25 }
26
27 f();
28 g();
29
30 return 0;
31 }
1)用C语言编译器进行编译,会发现出错。出错的地方在于:
int array[A + B] = {0};
虽然A与B是由const修饰的,根据上面所学的知识,A和B都是只读变量。数组的长度用两个变量相加,相加的结果到运行的时候才知道,
编译器就不乐意了,因此肯定会出错。
2)用C++编译器进行编译,就通过了。
此时A和B就是真正意义上的常量了。因此A+B也是常量
注意一个地方:
在g()函数中直接访问f()函数所定义的宏变量,结果没有出错,为什么?
因为宏是被预处理所处理的,直接进行文本替换,编译器压根不知道宏是什么,根本不知道宏的存在。其实,编译器看到的是这样的代码:
printf("a = %d
",3);
说明宏是没有作用域的概念的。
在g()函数中调用
printf("b = %d ", b);是不对的。
小结:
与C语言不同,C++中的const不是只读变量
C++中的const是一个真正意义上的常量
C++编译器可能会为const常量分配空间
C++完全兼容C语言中const常量的语法特性