- 1. C++中的const是一个真正的常量,而在C语言中的const是一个“伪常量”,原因如下:
先来说一下为什么C语言中的const是一个“伪常量”:代码如下:
void main()
{
//好像 a 是一个常量
const int a = 10;
//a = 11;
int *p = NULL;
p = (int *)&a;
*p = 20; //间接赋值
printf("a:%d \n", a);
printf("*p:%d \n", *p);
system("pause");
}
上面代码在C语言中的运行结果如下
通过运行结果我们可以看到,通过指针我们是可以修改C语言中的常量的值,因为C语言中定义的常量是要给相应的常量分配内存的,所以说我们是可以通过指针来修改内存中的值的,故C语言中的const定义的常量是一个“伪常量”。
那么同样的程序我们使用C++来运行一下看看:
void main()
{
//好像 a 是一个常量
const int a = 10;
//a = 11;
int *p = NULL;
p = (int *)&a;
*p = 20; //间接赋值
printf("a:%d \n", a);
printf("*p:%d \n", *p);
system("pause");
}
运行结果如下:
我们看到定义的常量的a的值依然是10,而*p却还是20,这是为什么呢?
原因是:C++中在使用const定义常量的时候,不会再给相应的常量分配内存,而是将定义的常量存放在符号表中,当我们使用取地址运算符取常量地址的时候,会额外的给常量分配一个内存,所以说我们使用指针修改只是额外分配内存中的值,而依然没有修改常量的值,当我们我们打印常量a的时候,会从相应的符号表中对应的将a的值拿出来打印,具体的示意图如下:
通过上面得出结论:
C语言中的const变量:
C语言中const变量是只读变量,有自己的存储空间
C++中的const常量:
可能分配存储空间,也可能不分配存储空间
那么C++中的const常量什么时候分配内存:1.当const常量为全局,并且需要在其它文件中使用。2.当使用&操作符取const常量的地址
- 2. C++程序中const的基础应用:
const int a;
int const b; //一样
const int *c; //const修饰的是指针所指向的内存空间,不能被修改
int * const d; //const修饰的是指针,表明指针中的地址不能被修改
const int * const e ;//const既修饰指针又修饰指针指向的内存空间,都不能被修改
- 3. C++给const的分配时机:在编译器编译期间分配内存
//3 const分配内存的时机 编译器编译器期间
void main()
{
//好像 a 是一个常量
int a;
const int b = 10;
int c;
printf("&a:%d, &b:%d, &c:%d \n", &a, &b, &c);
system("pause");
执行结果如下:
我们可以看到结果是a,b,c的地址是连续 ,并且b的地址是在a与c之间的地址,所以说当const的分配内存是在编译器执行阶段进行的,因为当编译器进行编译扫描时,扫描到printf中的对常量b进行取地址的时候,就会给b进行分配地址,当然因为定义的常量b分配地址是在定义变量a和变量b之间,由于编译器给变量分配地址是在全部扫面完之后,按照定义的顺序统一对变量进行地址的分配,对变量进行连续的压栈进行地址的分配,所以分配内存的时候地址是在他们之间的地址,如果不是在编译器编译时分配的内存,由于编译器编译的时候已经给变量a和c分配了内存,而在运行的时候再给b分配内存,b的地址是不可能在a和c地址之间的,因为编译器分配变量的地址是进行连续的压栈的。
- 4. C++中const与#define的相同之处:
//4const 和 #define的相同之处
//#define, 在编译预处理阶段 处理
//const常量是由编译器处理的,提供类型检查和作用域检查
#define d 20
void main()
{
//int a = 10;
//int b = 20;
//int array[a+b]; //linux内核里面是成立的;原因 编译linux内核的gcc编译器支持.
//c和c++编译器 不支持这种语法现象
const int c = 10;
//const int d = 20;
int array2[c+d];
system("pause");
}
C++中const和define的区别:
//5 const定义的变量,由编译器处理的,提供类型检查和作用域检查
void fun1()
{
#define a 10
const int b = 20;
//#undef a
//# undef
}
void fun2()
{
printf("a = %d\n", a);
printf("b = %d\n", b);
}
int main()
{
fun1();
fun2();
return 0;
}
C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5
C++中的const常量与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换
//在func1定义a,在func2中能使用吗?只要没有释放宏定义,在func2中是可以使用的
//在func1中定义的b,在func2中能使用吗?局部常量,终究是局部的,在func2中是不能使用的。