以下计划:
int main()
{
const int x = 10;
int * p = (int *)&x;
*p = 12;
cout<<x<<endl;
cout<<*p<<endl;
return 0;
}
输出:
10
12
cast&amp; x对(int *)的影响是什么?为什么x的值仍为10? 我预计它会是12岁。
另一个疑问
为什么我们不能把int **说成int const **? 相反,此操作有效
void f(int const ** p);
void g(int const * const * p);
int main()
{
int ** p = /*....*/
f(p); //Error
g(p); //OK
}
请用合适的例子帮助我理解这一点 谢谢!!!
答案 0 :(得分:8)
您正在通过修改声明为const
的变量来调用未定义的行为。任何结果都是程序的合法输出,尽管有些结果比其他结果更合理。
正如我在评论中所说:
10可能是由于优化;编译器知道x
是const,因此它可以调用:
cout << 10 << endl;
而不是:
cout << x << endl;
不太清楚的是编译器是否将第二个输出优化为:
cout << 12 << endl;
您必须查看生成的汇编程序才能确定。但由于整个程序正在调用未定义的行为,因此编译器是正确的,无论它是什么。
答案 1 :(得分:2)
当编译器分配给const int
时,编译器将替换文字值。实际上你的程序看起来像:
cout<<10<<endl;
cout<<*p<<endl;
答案 2 :(得分:1)
从主要问题来看,已经回答:修改常量对象是未定义的行为。
对于第二个问题,请考虑如果允许的话,你可能会无意中破坏const正确性:
const int k = 10;
void f(int const ** p) {
*p = &k; // Valid, p promises not to change k
}
void g(int const * const * p);
int main()
{
int *p;
int ** pp = &p;
f(pp); // If allowed: p points to k!!!
p = 5; // Modifying a constant object!!!
g(pp); //OK
}
在g
的情况下,因为函数的签名承诺不会更改中间指针,编译器知道g
不会修改*pp
,这意味着它不能使*pp
(即p
)指向一个常量对象,并保证const正确性。
答案 3 :(得分:0)
int main()
{
int x = 10;
int * p = (int *)&x;
*p = 12;
cout<<x<<endl;
cout<<*p<<endl;
return 0;
}
我认为这是const标记阻止x值的变化。