C++与C语言 通过指针改变const变量的值
C++与C语言 通过指针改变const变量的值
在C++和C语言中,const变量通常被认为是不可修改的。然而,通过指针和强制类型转换,我们似乎能够改变这些变量的值。本文将通过具体的代码示例,探讨这种行为在C语言和C++中的不同表现及其背后的原理。
一、问题描述
当一个变量声明为const时,通常是不可以改变它的值的,程序设计过程中也不应该这么做。
const int num = 666;//我们不应该对num的值进行修改
// num = 777; 此语句是错误的
当然,如果我们写以下语句,程序编译也会出现这样的错误:
int *p = #//程序会报错:无法将"const int *"转换为"int *"
但如果我们强制转换,就会发现程序编译通过了:
int *p = (int *)#//程序编译通过
这种程序执行之后,通过指针p访问num和直接访问num的值是怎样的呢?让我们一探究竟。
二、执行结果
程序代码如下:(注意:C语言和C++的执行结果是不同的)
int main() {
const int num = 666;
int *p = (int *)num;
*p = 777;
printf("num : %d, *p : %d", num, *p);
return 0;
}
2.1 C语言的执行结果
我们补全C语言的代码,并将其放入一个.c文件中:
#include<stdio.h>
int main() {
const int num = 666;
int *p = (int *)num;
*p = 777;
printf("num : %d, *p : %d", num, *p);
return 0;
}
我们先看程序的执行结果:
结果显示,二者的值都被改变了。原因是C语言的const关键字为运行时const,编译期间只是定义,在运行时才会初始化。因此,这就是C语言中的const变量不能作为数组长度的原因。
2.2 C++的执行结果
我们将以下C++代码放入一个.cpp文件中:
#include <iostream>
using namespace std;
int main(){
const int num = 666;
int *p = (int *)#
*p = 777;
cout << "num : " << num << ", *p : " << *p << endl;
return 0;
}
执行结果如下:
我们可以看到,直接访问num的值并没有改变,而通过指针p间接访问到的值改变了,与C语言执行结果不同。因为C++的const变量为编译时const,是像#define宏定义一样使用的常量。
2.3 补充:那const变量空间的值到底改变了吗
结论:是的,const变量的值的确被改变了。而且二者访问的是同一段空间。
那在C++执行结果中,为什么直接访问和间接访问会出现两种不同的结果呢?
我们可以通过以下代码,看到两段空间的地址:
#include <iostream>
using namespace std;
int main(){
const int num = 666;
int *p = (int *)#
*p = 777;
cout << "num : " << num << ", *p : " << *p << endl;
cout << "num 's address : " << &num << endl;
cout << "(*p)'s address : " << p << endl;
return 0;
}
通过以上执行结果我们可以看到,两次的地址都是同一个值,说明他们两个是同一段空间。
二者不同的原因:为了C++程序运行的效率更高,编译器会将常量表中的值缓存在栈中。当我们直接访问num时,访问的其实是栈中的缓存值,而此时被改变的值并没有同步过来。而我们通过指针*p间接访问的是那段内存空间,因此就是被改变之后的值。