我有一个很小的代码,但我无法理解为什么输出就是这样。
这是
#include <stdio.h>
int f(int i, int j, int k);
int main(int argc, char const *argv[])
{
int a;
printf("enter a\n");
scanf("%d",&a);
f(a,a++,a++);
printf("%d \n",a );
return 0;
}
int f(int i, int j, int k)
{
printf("function arguments \n");
printf("%d %d %d\n",i,j,k );
}
输入:4
输出:6 5 4
答案 0 :(得分:4)
标记副本中接受的答案不正确。
f(a,a++,a++);
导致未定义的行为。它试图在没有插入序列点的情况下修改参数a
。此外,重要的是要注意函数参数的评估顺序是未指定。它可以是:
如果您正在使用GCC,您可以使用警告标志-wsequence-point
来警告您与序列点相关的未定义行为。
在GCC中如果您在最严格的警告级别编译程序,编译器将为您提供此诊断:
prog.c:10:18:错误:'a'上的操作可能未定义[-Werror = sequence-point]
prog.c:10:18:错误:'a'上的操作可能未定义[-Werror = sequence-point]
参考:
C99标准§6.5.2.2:
第10段:
函数指示符的评估顺序,实际参数和 实际参数中的子表达式未指定,但有一个序列点 在实际通话之前。
请注意,引用只表示在实际函数调用之前有一个序列点,并不意味着在表达子表达式参数之间存在一个序列点。
答案 1 :(得分:1)
f(a,a++,a++);
似乎是未定义的行为,因为:
如果标量对象的副作用相对于其中任何一个都没有排序 对同一个标量对象或值有不同的副作用 使用相同标量对象的值进行计算,行为是 未定义。如果有多个允许的排序 表达式的子表达式,如果这样的话,行为是不确定的 任何顺序都会出现无序的副作用。
使用未定义的行为时,C标准没有要求。