C语言 谁能解释一下我们必须应用的逻辑来解决这个代码[重复]

vmdwslir  于 2023-03-28  发布在  其他
关注(0)|答案(1)|浏览(122)

此问题在此处已有答案

Why are these constructs using pre and post-increment undefined behavior?(14个答案)
(9个答案)
2天前关闭。
截至2天前,社区正在审核是否重新讨论此问题。

#include <stdio.h>

int main ()
{
    int a = 1;
    printf("%d\t%d\t%d\n", ++a, ++a, a++);
    printf("%d\t%d\n", a++, ++a);         
    printf("%d\n", a);                    
    
}

以下是我进行空运行检查时遵循的要点:
1.结合性是从右到左(〈------)
1.每当我使用相同类型的增量操作符时(比如在第一个printf行中使用++a),最近的值都会被更新(比如在第一个printf行中更新整数4)
根据我的逻辑,注解的是我期望的输出。
但实际输出是:四四一五六六
我是否应用了错误的逻辑??有人能解释一下吗?

#include <stdio.h>
int main()
{
    int a = 1;
    printf("%d\t%d\t%d\n", ++a, ++a, a++); // 4    4    1
    printf("%d\t%d\n", a++, ++a);          // 5   5
    printf("%d\n", a);                     // 6
    
}
x6yk4ghg

x6yk4ghg1#

在调用函数之前,函数参数的求值顺序是未指定的行为。你假设每个参数之间有一个sequence point,但C标准没有指定(C99,§6.5.2.2-10):
函数指示符、实际参数和实际参数中的子表达式的求值顺序未指定,但在实际调用之前有一个序列点。
在C17,§6.5.2.2-10中,措辞不同,但就该问题而言,结果相同:
在函数指示符和实际参数的求值之后,但在实际调用之前,有一个序列点。调用函数(包括其他函数调用)中的每个求值,如果没有在被调用函数体的执行之前或之后进行特定的排序,则相对于被调用函数的执行进行不确定的排序。
这意味着编译器可以自由地以任何顺序计算函数参数,因此在不同的系统,不同的编译器或启用不同选项的同一编译器上,您可能会看到与计算函数参数的不同顺序对应的不同结果。
注意,参数的求值顺序是unspecified behavior, not undefined behavior
然而,有多个(子)表达式修改同一个变量而不被序列点分隔是 undefined behavior。C17,§6.5-2:
如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量对象的值进行的值计算未排序,则行为未定义。如果表达式的子表达式有多个允许的排序,则如果任何排序中出现此类未排序的副作用,则行为未定义。
因此,前两个printf-语句有更多的a++出现 * 未定义的行为 *,因此C标准不保证程序的任何结果。

相关问题