#include<stdio.h>
int main()
{
const int sum=100;
int *p=(int *)∑
*p=101;
printf("%d, %d",*p,sum);
return 0;
}
/ *
输出
101,101
* /
p指向一个常数整数变量,那么为什么/ p如何设法改变和的值?
答案 0 :(得分:6)
这是未定义的行为 - 这是代码中的错误。代码“似乎有效”这一事实毫无意义。允许编译器使程序崩溃,或者允许程序执行无意义的操作(例如更改应该是const的某些内容的值)。或者完全做其他事情。对行为进行“推理”毫无意义,因为对行为没有要求。
请注意,如果代码编译为C ++,您将收到错误,因为C ++不会隐式抛弃const
。希望,即使编译为C,您也会收到警告。
答案 1 :(得分:2)
p
包含变量sum
的内存地址。语法*p
表示sum
的实际值。
当你说
时*p=101
你说的是:转到地址p
(这是存储变量sum
的地址)并在那里更改值。所以你实际上正在改变sum
。
答案 2 :(得分:2)
你可以看到const
作为编译时标志告诉编译器“我不应该修改这个变量,告诉我是否这样做。”它不会对是否实际修改变量强制执行任何操作。
由于 通过非const指针修改该变量,编译器确实会告诉你:
main.c: In function 'main':
main.c:6:16: warning: initialization discards qualifiers from pointer target type
你打破了自己的承诺,编译器警告你,但会让你愉快地继续前进。
答案 3 :(得分:1)
行为未定义,这意味着它可能会在不同的编译器实现,体系结构,编译器/优化器/链接器选项上产生不同的结果。
为了分析,这里是:
(免责声明:我不知道编译器。这只是对编译器如何选择处理这种情况的逻辑猜测,从一个简单的汇编语言调试器的角度来看。)
sum
的每个实例都改成一个文字{{1 }}。
100
将变为{{1其中printf
和int main() { printf("%s, %s", (b1? "100" : "101"), (b2? "100" : "101")); return 0; }
取决于编译器的情绪。