#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
谁能解释一下输出?
您正在做的是抛弃const
(变量a1
)的常量。这会导致未定义的行为(UB)。在实践中,这意味着任何事情都可能发生。你观察到的是“任何东西”的一种表现形式。
通常,涉及 UB 的问题的答案包括可能发生的疯狂事情的狂野例子。我将通过避免这样做来打破传统。
这是“未定义行为”的一个示例,它解释了为什么您“从一个变量”获得两个不同的输出。未定义的行为,意味着“不一定是您所期望的,但可能是您所期望的”。
由于您已经“承诺”编译器不会更改a1
,因此编译器只是将常量40
放入该cout << a1 << endl
行,而不是实际读取a1
. 这是对常数完全有效的优化。然后您跳过箍以设法“松开”该变量的常量并对其进行写入这一事实并没有真正改变您承诺不会更改该值的事实。
赋值*c1 = 'A';
写入不可写内存。希望你知道那很糟糕。我假设编写代码并要求人们解释它的原因不那么愚蠢。
也许您想要一个示例,说明实施选择如何导致您看到的结果。这是一个:编译器优化了变量的所有读取:打印*c1
它说“我不需要看*c1
,我知道里面有什么,我只是放了一个 65。我会打印那个。” 然后打印a1
它说“我不需要看a1
,我将它初始化为 40 并且不允许更改,所以我就打印它。” 然后它查看*c1
分配并说“我真的不需要分配那个值,因为我不会使用它。”
或者也许最后一部分不会发生。该变量是本地的,因此它很可能在堆栈上,在可写页面中,而没有有意义的运行时强制执行其常量。