printf中的多个赋值语句c

ss_*_*s_t 1 c compiler-construction printf

任何人都可以帮助我理解下面的代码输出:

int main()
{
    int a=35;
    printf("%d %d %d %d %d",a--,a,a=20,a++,a=39);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量:20 19 19 39 19

赞赏如何在printf函数中的c中处理(编译)赋值.

Sha*_*baz 7

这是未指定的行为.函数参数的评估顺序未在C标准中指定,因此可以按任何顺序发生.

人们已经在您可以阅读的评论中给了您一些链接.但总之,有一些叫做"序列点"的东西.这些确保了在执行之前需要执行的所有内容,然后程序可以继续执行.在两个序列点之间,指令可以以任何顺序执行.

从C11标准:

3.4.4:

  1. 未指明的行为
    使用未指定的值,或者本国际标准提供两种或更多种可能性的其他行为,并且在任何情况下都不会对其进行任何进一步的要求

  2. 示例未指定行为的示例是计算函数参数的顺序.

6.5.2.2.10说

在评估函数指示符和实际参数之后但在实际调用之前有一个序列点.调用函数(包括其他函数调用)中的每个评估(在执行被调用函数的主体之前或之后没有特别排序)对于被调用函数的执行是不确定地排序的.

换句话说,在函数参数的求值之间没有序列点,因此可以按照编译器的顺序来评估它们.

要完成答案,这也是未定义的行为,因为您尝试a在两个序列点之间多次更改值.

6.5.2:

如果相对于对同一标量对象的不同副作用或使用相同标量对象的值进行值计算,对标量对象的副作用未被排序,则行为未定义.如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的.84)

84)他的段落呈现未定义的语句表达式,例如
i = ++i + 1;
a[i++] = i;
允许时
i = i + 1;
a[i] = i;