这段C语言代码的输出是否定义良好?是否存在序列点间多次更新变量?
这段C语言代码的输出是否具有良好定义?
先看你给出的代码:
#include<stdio.h> int main() { int p=10,*q; q= &p; *q=p+++*q; printf("%d",*q); return 0; }
结论是:这段代码的行为是未定义的,你的判断是正确的——它在两个连续序列点之间对变量p进行了多次修改,同时伴随无明确顺序的读取操作,导致输出结果没有良好定义。
具体分析:
- 编译器会把
p+++*q按照贪心原则解析为p++ + *q,而*q就是p(因为q指向p),所以整个表达式等价于p = p++ + p。 - 根据C标准,在一个表达式中,如果对同一个对象的两次修改操作之间没有序列点,或者修改操作与读取该对象(且读取不是为了确定修改后的值)的操作之间没有序列点,就会触发未定义行为。
- 这里赋值运算符
=的左右操作数求值没有固定顺序:右边的p++(修改p)、*q(读取p),以及左边对p的赋值(修改p),这些操作的执行顺序完全由编译器决定,不同编译器甚至同一编译器的不同优化级别都可能产生不同结果。比如:- 若先读取
*q(值为10),再执行p++(返回10,p变为11),相加得20后赋值给p,最终输出20; - 若先执行
p++(返回10,p变为11),再读取*q(值为11),相加得21后赋值给p,最终输出21; - 甚至可能出现其他不符合预期的结果,因为标准完全不约束这种场景的行为。
- 若先读取
内容的提问来源于stack exchange,提问作者SUBHAJIT PAUL
相关产品推荐
相关产品推荐

