#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
任何人都可以解释输出吗?
答案 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
赋值并说“我真的不需要分配该值,因为我不打算使用它。”
或者也许最后一部分不会发生。该变量是本地的,因此它可能位于堆栈中,在可写页面中,而没有有意义的运行时强制执行其常量。