C++ 指针转换未给出预期结果
可能重复:C++ 指针转换未给出预期结果,c++,pointers,C++,Pointers,可能重复: 以下节目: int main() { const int x = 10; int * p = (int *)&x; *p = 12; cout<<x<<endl; cout<<*p<<endl; return 0; } 将&x转换为(int*)的效果是什么?为什么x的值仍然是10? 我以为是12点 另一个疑问 为什么我们不能将int**转换为int const**? 相反,这个
以下节目:
int main()
{
const int x = 10;
int * p = (int *)&x;
*p = 12;
cout<<x<<endl;
cout<<*p<<endl;
return 0;
}
将&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
}
请用合适的例子帮助我理解这一点
谢谢 编译器将在将文本值分配给
常量int
时替换该文本值。实际上,您的程序看起来像:
cout<<10<<endl;
cout<<*p<<endl;
cout您正在通过修改声明为const
的变量来调用未定义的行为。任何结果都是程序的合法输出,尽管有些结果比其他结果更可信
正如我在评论中指出的:
这10个可能是由于优化;编译器知道x
是常量,因此可以调用:
cout << 10 << endl;
这是一个有趣的问题。
当您删除x的const前缀时,您将得到所需的结果
int main()
{
int x = 10;
int * p = (int *)&x;
*p = 12;
cout<<x<<endl;
cout<<*p<<endl;
return 0;
}
intmain()
{
int x=10;
int*p=(int*)&x;
*p=12;
cout至于主要问题,它已经得到了回答:修改常量对象是未定义的行为
对于第二个问题,考虑如果允许的话,你可以打破广告中的正确性:
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
)指向一个常量对象,常量的正确性得到保证。10可能是由于优化;编译器知道x是常量,所以它调用cout@JonathanLeffler…。但是指针p呢?它指向x的地址…我不知道在强制转换((int*)&x步骤)后到底发生了什么…指针通常应该修改x的值…请在此解释“x”的内存地址中发生了什么,int*p=(int*)&x;
步骤后发生的事情是未定义的行为。任何事情都可能发生;发生的事情都可以。不要这样做。我已删除了“C”标记,因为C++和C不是同一种语言,特别是在这个问题的上下文中。@ JONAATEN LIFFLER……请看我的问题的第二部分。编译器不会做任何类似的事情。它可能是。它是未定义的行为。@ CurryyDee,程序的一部分,它会使不稳定的行为产生明确的行为,但我不是。因为它似乎做了一些合理的事情,所以不能对该部分进行寻址。const int
是标准定义的编译时常量。同样,这是错误的。丢弃constness没有错;UB在写入结果时出现。而且const int
不是编译时常量,它可以用于构造ts需要一个(OP没有做),并且只有在满足各种其他要求时才需要。巨大的差异。
cout << 12 << endl;
int main()
{
int x = 10;
int * p = (int *)&x;
*p = 12;
cout<<x<<endl;
cout<<*p<<endl;
return 0;
}
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
}