C++ 指向常数的指针

C++ 指向常数的指针,c++,pointers,constants,C++,Pointers,Constants,有人能解释输出吗?这是一个“未定义行为”的例子,它解释了为什么“从一个变量”得到两个不同的输出。未定义的行为,意味着“不一定是你所期望的,但可能是你所期望的” 既然您已经向编译器“承诺”您不会更改a1,那么编译器只需将常量40放入cout,您所做的就是丢弃常量const(变量a1)的常量。这会导致未定义的行为(UB)。实际上,这意味着任何事情都可能发生。你所观察到的是“任何东西”的一种表现 通常涉及UB的问题的答案包括可能发生的疯狂事情的疯狂例子。我将打破传统,不再那样做。作业*c1='A'写入

有人能解释输出吗?

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


既然您已经向编译器“承诺”您不会更改
a1
,那么编译器只需将常量
40
放入
cout,您所做的就是丢弃常量
const
(变量
a1
)的常量。这会导致未定义的行为(UB)。实际上,这意味着任何事情都可能发生。你所观察到的是“任何东西”的一种表现


通常涉及UB的问题的答案包括可能发生的疯狂事情的疯狂例子。我将打破传统,不再那样做。

作业
*c1='A'写入不可写入内存。希望你知道这很糟糕。我会假设有一个不那么愚蠢的理由来编写代码并要求人们解释它

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


或者最后一部分没有发生。变量是局部变量,因此它可能在堆栈上,在一个可写页面中,没有对其常量进行有意义的运行时强制。

这是未定义的行为。您正在抛弃一些真正是
常量的常量。akash:正如Raymond Chen所说,“不要这样编写代码。”“。写这样的废话或关心它做什么或如何做都没有很好的理由。这是一种未定义的行为,它取决于编译器给你一个错误或任何答案。标准对它的定义是不明确的,“传统”是愚蠢的。即使是一致性程序也可以做任何事情,因为不能保证任何实现或实现的实例是一致的。标准所说的是,如果一致性程序由一致性实现执行,将会发生什么。。。“未定义的行为”只是标准中未定义的行为。但无论是否按照标准定义,实现都是现实世界中的确定性组件,并且在适当的知识水平下具有可预测的行为。如果他使用了
const_cast
,它仍然是未定义的行为吗?@JimBalter:事实上,不,系统在几年前就不再是确定性的了。锁定不当的多线程程序可能会运行到热依赖的竞争条件下(!)。温度会影响结果,随着现代CPU的运行接近量子力学的极限,这种行为是不可预测的。当然,定义良好的程序没有这种竞争条件。@0x499602D2:是的,拼写不重要,强制转换本身就是UB。@MSalters:啊,好的。你说QM把我甩了!
#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;
}
65
40