以比较变量作为参数的 printf 的解释
Explaination for printf with comparing variables as arguments
main(){
int a = 5;
int b = 6;
printf("%d %d %d",a==b,a=b,a<b);
}
我测试的输出
1 6 1
在上面的程序中,我期望输出为 0 6 0 。在某些编译器中,它给出此输出(例如 Xcode),但在某些其他编译器中,它给出的输出为 1 6 1 。我找不到解释。序列点也是如此
考虑下面的程序
main(){
int a = 5;
int b = 6;
printf("%d %d %d",a<b,a>b,a=b);
printf("%d %d",a<=b,a!=b);
}
我测试的输出
0 0 6 1 0
下面这个程序给出了我期望的正确输出,即 0 0 6 1 0
但是为什么上面的程序在大多数编译器中没有给出 060 的输出
=
是赋值运算符,改变左操作数的值。
FWIW,比较运算符是==
在此声明中
printf("%d %d %d",a==b,a=b,a<b);
您正在更改 a
(a = b
) 的值并尝试读取该值(其他两种情况)以执行其他操作,锻炼之间有一个序列点。此外,标准未定义(或未指定)函数参数的评估顺序。
引用 C11
标准,章节 §6.5,(强调我的)
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.
所以,上面的语句产生undefined behaviour.
注:main()
推荐签名为int main(void)
.
in above program i am expecting output as 0 6 0
您期待从左到右(英文阅读方向)的参数评估。但是评估的顺序可能是从左到右、从右到左或其他顺序。程序不应依赖于函数参数的求值顺序。
printf("%d %d %d",a==b,a=b,a<b);
// 1. Evaluate the following in no specific order
// (a==b), (a=b) and side effects, (a<b)
// (Warning: Depending on the order, result may be different)
// 2. Pass "%d %d %d" as first argument, the result of
// (a==b) as second argument, result of of (a=b) as
// third argument and result of (a<b) as fourth
// argument of printf
在 C
中,参数评估的顺序未指定。所以它可以按任何顺序评估参数。当您在其中一个参数中更改变量 a
的值(使用赋值运算符 =
)时,请使用以下内容以获得更一致的结果。
printf("%d ",a==b); // Evaluate (a==b) and pass as second argument of printf
printf("%d ",a=b); // Evaluate (a=b) and side effects and pass as second argument of printf
printf("%d" ,a<b); // Evaluate (a==b) and pass as second argument of printf
如果没有这个,您的程序将调用未定义的行为,因为您正在更新和读取序列点之前的 a
的值。但在后一种情况下,没有歧义,因此程序显示出明确定义的行为。
p.s。不要混淆 function parameter list and the comma operator
中使用的逗号
C 标准说:
C11: 6.5 (p2):
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined [...]
这意味着您的程序调用了未定义的行为。在语句中
printf("%d %d %d",a==b,a=b,a<b);
和
printf("%d %d %d",a<b,a>b,a=b);
a
的副作用未排序,因为标准说:
main(){
int a = 5;
int b = 6;
printf("%d %d %d",a==b,a=b,a<b);
}
我测试的输出
1 6 1
在上面的程序中,我期望输出为 0 6 0 。在某些编译器中,它给出此输出(例如 Xcode),但在某些其他编译器中,它给出的输出为 1 6 1 。我找不到解释。序列点也是如此
考虑下面的程序
main(){
int a = 5;
int b = 6;
printf("%d %d %d",a<b,a>b,a=b);
printf("%d %d",a<=b,a!=b);
}
我测试的输出
0 0 6 1 0
下面这个程序给出了我期望的正确输出,即 0 0 6 1 0 但是为什么上面的程序在大多数编译器中没有给出 060 的输出
=
是赋值运算符,改变左操作数的值。
FWIW,比较运算符是==
在此声明中
printf("%d %d %d",a==b,a=b,a<b);
您正在更改 a
(a = b
) 的值并尝试读取该值(其他两种情况)以执行其他操作,锻炼之间有一个序列点。此外,标准未定义(或未指定)函数参数的评估顺序。
引用 C11
标准,章节 §6.5,(强调我的)
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.
所以,上面的语句产生undefined behaviour.
注:main()
推荐签名为int main(void)
.
in above program i am expecting output as 0 6 0
您期待从左到右(英文阅读方向)的参数评估。但是评估的顺序可能是从左到右、从右到左或其他顺序。程序不应依赖于函数参数的求值顺序。
printf("%d %d %d",a==b,a=b,a<b);
// 1. Evaluate the following in no specific order
// (a==b), (a=b) and side effects, (a<b)
// (Warning: Depending on the order, result may be different)
// 2. Pass "%d %d %d" as first argument, the result of
// (a==b) as second argument, result of of (a=b) as
// third argument and result of (a<b) as fourth
// argument of printf
在 C
中,参数评估的顺序未指定。所以它可以按任何顺序评估参数。当您在其中一个参数中更改变量 a
的值(使用赋值运算符 =
)时,请使用以下内容以获得更一致的结果。
printf("%d ",a==b); // Evaluate (a==b) and pass as second argument of printf
printf("%d ",a=b); // Evaluate (a=b) and side effects and pass as second argument of printf
printf("%d" ,a<b); // Evaluate (a==b) and pass as second argument of printf
如果没有这个,您的程序将调用未定义的行为,因为您正在更新和读取序列点之前的 a
的值。但在后一种情况下,没有歧义,因此程序显示出明确定义的行为。
p.s。不要混淆 function parameter list and the comma operator
中使用的逗号C 标准说:
C11: 6.5 (p2):
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined [...]
这意味着您的程序调用了未定义的行为。在语句中
printf("%d %d %d",a==b,a=b,a<b);
和
printf("%d %d %d",a<b,a>b,a=b);
a
的副作用未排序,因为标准说: