在很多的人的普遍印象中,用const修饰符修饰的变量表示该变量是常量,是只读的,无法修改的。其实对于这样的回答,是不准确的。
在C语言中的const
在C语言中,用const修饰的变量,其本质上还是个变量,只是它不允许作为左值存在,也就是不法对该变量进行直接赋值修改该变量,但是这不意味着该变量的值就无法修改。下面我们看一下这段代码:
#include
int main()
{
const int a = 10;
int b = 10;
int* p = (int*)&a;
*p = 100;
b = a;
printf("a=%d b=%d *p=%d\n",a,b,*p);
return 0;
}
使用vs2019的平台来进行编译从这个结果中我们也可以看出,const修饰的变量的值在C语言中并非是无法修改的,我们可以通过指针来修改该变量的值。
在C++中的const 为了兼容C语言,C++也保留了const的很多属性。
但是在C++中,const这个修饰符和在C语言中有点不同
#include
int main()
{
#ifdef __Cplusplus
printf("C++");
#endif
const int a = 10;
int b = 10;
int* p = (int*)&a;
*p = 100;
b = a;
printf("a=%d b=%d *p=%d\n",a,b,*p);
return 0;
}
使用vs2019的平台来进行编译
相同的代码,用C语言和C++编译器编译运行后得到的结果却不相同。
其实在C++中 ,在编译的时候,当碰到用const修饰的变量时,编译器是直接将变量的值和变量的符号对应起来一起存到符号表中,例如const int a = 5;在符号表中就会将a和5对应起来,在编译的过程中。
当碰到printf(“a = %d\n”,a); 时,为用 5 直接将 a 替换掉。在C++中,编译器不会为a分配存储空间,在C语言中就会为a分配存储空间,所以在C编译器中,就可以通过指针来改变用const修饰的变量。
我们再看一下下面的代码:
#include
int main()
{
const int a = 5;
int* p = (int*)&a;
printf("a = %d\n",a);
*p = 10;
printf("a = %d\n",a);
printf("*p = %d\n",*p);
printf("&a = %p\n",&a);
printf("p = %p\n",p);
return 0;
}
我们只是在代码中打印了指着p和a的地址,用C语言和C++的编译器编译执行之后,打印出来的地址p和a都是相同的。可能会有疑惑 在C++中不是说不会为a分配地址吗?怎么执行后地址p和a都是相同的?
在C语言中,C编译器会为const修饰的变量分配空间,所以能打印地址和修改值大家都理解,那么在C++中呢?
在C++中,编译器不会为const变量分配空间,只会将其对应起来存到符号表中,用到变量名的时候,直接将值替换。但是在碰到int* p = (int*)&a; 这条语句的时候,在碰到 &a 时,这个时候会为 a 分配存储空间,这个时候 p 和 a 的地址相同,但是通过指针来修改a的值在C++中还是无法成功的,因为在碰到 printf(“a = %d\n”,a); 时,编译器还是会直接用 5 将 a 替换,而不会去分配的存储空间的取值。
其实在C++中,const修饰的变量,在编译的时候如果前面有extern和取地址符 & 时,会为变量分配存储空间是为了兼容C语言,但是在C++中,用const修饰的变量就真的无法修改它的值,可以说是常亮。但是在C语言中,const修饰的变量本质上还是变量而不是常量。这在C语言中其实也是矛盾的,因为我们想要用const定义一个常量,但又可以通过指针来改变该常量的值。而C++为了兼容C语言,所以保留了这个特性,但是却无法修改它的值,这就是const在C语言和C++中的区别。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)