指向const常量的指针可以修改常量的值

指向const常量的指针可以修改常量的值

实例

先直接看代码:

int main(int argc, char const* argv[])c
{
	const int a = 100;
	const int* pa = &a;
	int* pa_1 = &a;
	//*pa = 3; // 编译不过,指针常量不能通过指针修改值
	
	int* b = const_cast<int*>(pa); // 把const转换掉
	*b = 3;

	cout << "a: " << a << endl; // 100
	cout << "*b: " << *pa << endl; // 3
}

输出结果:

a:100

​ *pa:3

​ 可以看到,指向a的指针的输出值变为了100,但为什么a的值还是100呢,因为const int x = 100;这种情况,编译器会认为x是一个编译期可计算出结果的常量,那么x就会像宏定义一样,用到x的地方会被编译器替换成100。如果我们将其变为运行时初始化:

int func()
 {
	 return 100;
 };

  int main(int argc, char const* argv[])
  {
	  const int a = func();
	  const int* pa = &a;

	  int* b = const_cast<int*>(pa); // 把const转换掉
	  *b = 3;

	  cout << "a: " << a << endl; // 3
	  cout << "*pa: " << *pa << endl; // 3
  }

输出结果:

​ a:3

​ *pa:3

​ 在这种情况下,a的输出值也变成了 3 。再尝试一下,通过constexpr的情况:

 constexpr int func()
 {
	 return 100;
 };

 int main(int argc, char const* argv[])
 {
	 constexpr int a = func();
	 const int* pa = &a;

	 int* b = const_cast<int*>(pa); // 把const转换掉
	 *b = 3;

	 cout << "a: " << a << endl; // 100
	 cout << "*pa: " << *pa << endl; // 3
 }

输出结果:

​ a:100

​ *pa:3

​ 可以看到,借由constexpr赋予的常量表达式获得在程序编译阶段计算出结果的能力,a的值重新变成了在编译时初始化。

解决方法

​ 对于这种情况,我们可以通过把局部const变量变成全局const变量。代码如下:

const int a = 100;
 int main(int argc, char const* argv[])
 {
	 
	 const int* pa = &a;

	 int* b = const_cast<int*>(pa); // 把const转换掉
	 *b = 3;

	 cout << "a: " << a << endl; 
	 cout << "*pa: " << *pa << endl; 
 }

​ 这段代码将不会正确运行。其原因是,全局常量的存储位置是数据段的全局/静态区,这个内存区是只读的,而局部常量存放于堆栈中,虽然不能直接修改,但可以通过指针间接修改。

posted @ 2021-03-15 15:39  浩楠honer  阅读(783)  评论(0编辑  收藏  举报