#include <stdio.h>
void main()
{
int x=5,y=6;
printf("%d%d%d",x++,(y=x++),(x=y++));
}
任何人都可以解释为什么这会返回766?
答案 0 :(得分:9)
首先,如果这个格式的问题是在初学者C编程课程中提出的,那么课程/老师就是一个糟糕的课程。
这里的主要问题是'x'和'y'在序列点之前被修改了几次,这是未定义的行为(C99 / C116.5§2)。这是一个严重的错误,因为任何事情都可能发生。在删除++ mess之前,没有人知道这段代码是做什么的。 Read this then read it again
此外,函数参数的评估顺序是未指定的行为。 (C99 / C116.5.2.2§10)。也就是说,编译器可以从左到右或从右到左评估它们,并且我们不能知道适用的顺序。编译器不需要记录这个!但如果你很幸运,可以记录下来。在尝试回答问题之前,您必须阅读编译器文档以了解适用的评估顺序。否则你必须给出两个答案。
此外,如果这是托管系统的代码,例如Windows PC,则只允许main返回'int',否则此代码将无法在C编译器上编译。
答案 1 :(得分:3)
你通过在序列点之间多次修改x
来调用未定义的行为,所以你很幸运/不幸的是它打印了任何东西......
答案 2 :(得分:2)
是的,未定义解析此类函数的参数的顺序是什么。
处理可变数量的args函数(如printf)的最简单方法是从最后开始,因为你知道开头的位置!
正如'R'所指出的那样 - 如果评价不明确,那么它的定义是不明确的。
例如x++ = x++
答案 3 :(得分:0)
这个工作堆栈概念作为提及操作LIFO第一个右操作数进入堆栈,即x = y ++(这是后增量opratore然后第一个y值,在y之后将x增加为x = 6)然后secound (此处x = 6且y = 7但是y指定x的值为6,然后x将增加1)和第三(此处x = 7,此声明后x将增加1),值为766。 / p>
答案 4 :(得分:-1)
首先评估最后一个表达式(x=y++)
。这将返回6,因为x被赋值为y,最初为6,然后将y递增为1.现在y为7,x为6. x在此处打印。
要评估的下一个表达式是(y=x++)
。与上面相同,首先指定y = x并将x增加到1.因此,值为y为6,x为7. y在此处打印。
现在x++
。它打印7并将x递增到1。
答案 5 :(得分:-2)
执行strts frm从右到左。所以,x = y ++,x值变为6,之后y值变为7,然后是y = x ++,其中y的restoe值为6.之后在x ++语句中x值为7由于前面的陈述(y = x ++)。答案也是如此766
答案 6 :(得分:-3)
printf("%d%d%d",x++,(y=x++),(x=y++));
想要添加为什么它从右端评估为前面提到的答案。 printf的所有参数都被推送到堆栈然后开始评估。由于堆栈是LIFO,评估从结束开始。