指向常数的指针

时间:2013-06-06 10:27:07

标签: c++ pointers const

#include <iostream>
using namespace std;

int main(void)
{
   const int a1 = 40;
   const int* b1 = &a1;
   int * c1 = (int *)(b1);
   *c1 = 'A';
cout<<*c1<<endl;
cout<<a1<<endl;
   return 0;
}

O / P:

65
40

任何人都可以解释输出吗?

3 个答案:

答案 0 :(得分:6)

你正在做的是抛弃const(变量a1)的常量。这会导致未定义的行为(UB)。实际上,这意味着任何事情都可能发生。你观察到的是“任何事物”的一种表现形式。

通常,涉及UB的问题的答案包括可能发生的疯狂事件的疯狂例子。我将通过避免这种做法打破传统。

答案 1 :(得分:2)

这是“未定义行为”的一个示例,它解释了为什么从“一个变量”获得两个不同的输出。未定义的行为,意味着“不一定是您所期望的,但可能是您所期望的”。

由于您已“承诺”编译器您不会更改a1,因此编译器只需将常量40放入cout << a1 << endl行,而不是实际读取a1中的值。这是一个对常量完全有效的优化。然后,你跳过箍来设法“松散”该变量的常量并写入它并不会真正改变你承诺不改变该值的事实。

答案 2 :(得分:1)

赋值*c1 = 'A';写入不可写内存。希望你知道这很糟糕。我会假设编写代码并要求人们解释它的原因不那么愚蠢。

也许您想要一个示例,说明实现选择如何导致您看到的结果。这是一个:编译器优化掉变量的所有读取:打印*c1它说“我不需要看*c1,我知道它里面有什么,我只是把65放在那里我打印那个。“然后打印a1它说“我不需要查看a1,我将其初始化为40并且不允许更改,所以我只打印它。”然后它查看*c1赋值并说“我真的不需要分配该值,因为我不打算使用它。”

或者也许最后一部分不会发生。该变量是本地的,因此它可能位于堆栈中,在可写页面中,而没有有意义的运行时强制执行其常量。