C语言中printf函数内部表达式的求值

3

我知道多个表达式的求值顺序是从右到左的。 例如:

int i = 0;   
printf("%d %d %d", i, i++, i++); // Prints 2 1 0

但是,当涉及到每个表达式的计算时,我不确定它是从右到左还是从左到右。

int main()
{
    int a = 1, b = 1, d = 1;
    printf("%d", a + ++a); // Result = 4
}

考虑从左到右进行评估,前置代码应该被评估为1 + 2 = 3。

int main()
{
    int a = 1, b = 1, d = 1;
    printf("%d", ++a + a); // Result = 4
}

这应该被解释为 2 + 2 = 4。

但是在两种情况下答案都是4。

请问有人能解释一下这些表达式是如何计算的吗?


1
我知道多个表达式从右到左进行求值。例如:int i = 0; printf("%d %d %d", i, i++, i++); // 输出 2 1 0,这是错误的,是未定义的行为。 - David Ranieri
@AlterMann 这个问题包含两个问题:函数参数的求值顺序和同一表达式中同一变量的操作顺序不当。那个重复的问题只解释了后者,我会重新打开这个问题。 - Lundin
1
@Lundin 因此,您重新打开了它。实际上,重复项确实解释了顺序:https://dev59.com/L3NA5IYBdhLWcg3wdtv5#18260171,https://dev59.com/L3NA5IYBdhLWcg3wdtv5#949508 - 2501
@2501 那也可以,但是那个重复问题中的实际问题并没有涉及到任何求值顺序问题,所以可能会让提问者感到困惑。 - Lundin
有人默默地重新打开了它。太好了! - 2501
@2501 这不是一个很好的重复。理想情况下,重复应该解决问题中的两个问题。在有人找到这样的答案之前,我的答案仍然链接到那篇帖子。 - Lundin
1个回答

5
我知道多个表达式是从右到左进行评估的。但函数参数的评估顺序是未指定的行为,这意味着你无法知道顺序,它可能因系统而异,甚至在不同的函数调用之间也可能不同。你不应该编写依赖于这种评估顺序的程序。此外,在函数参数的评估之间没有序列点,所以像 printf("%d", ++a + a); 这样的代码也会导致未定义的行为,请参见Why are these constructs (using ++) undefined behavior?。请注意,运算符优先级和结合性仅保证表达式解析的顺序!这与操作数的评估顺序无关(有一些特殊的例外,例如 || && , ?: 运算符)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接