我对运算符的优先级感到困惑,并想知道如何评估此语句。
# include <stdio.h>
int main()
{
int k=35;
printf("%d %d %d",k==35,k=50,k>40);
return 0;
}
此处k
最初的值为35,当我在k
中测试printf
时,我认为:
k>40
哪个应该导致0 k==35
,哪个应该导致1 k
,并输出50 因此最终输出应为1 50 0
,但输出为0 50 1
。
答案 0 :(得分:6)
您不能依赖此程序的输出,因为它是undefined behavior
,评估顺序未在C中指定,因为它允许编译器更好地优化,来自C99
草案标准部分{ {1}}段6.5
:
运算符和操作数的分组由语法表示.74)除非另有说明 稍后(对于函数调用(),&amp;&amp;,||,?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。强>
它也是未定义的,因为您正在访问3
的值并在同一sequence point
中分配给它。来自草案标准部分k
段6.5
:
在上一个和下一个序列点之间,对象应具有其存储值 通过表达式的评估最多修改一次。 此外,先前的价值 应只读以确定要存储的值。
它引用以下代码示例为未定义:
2
更新
关于函数调用中的逗号是否作为序列点进行了评论。如果我们查看i = ++i + 1;
a[i++] = i;
段6.5.17 Comma operator
段说:
逗号运算符的左操作数被计算为void表达式; 有一个 评估后的序列点。
但第2
段说:
示例如语法所示,逗号运算符(如本子条款中所述)不能出现在使用逗号分隔列表中的项目的上下文中(例如函数的参数或初始化程序列表强>)。
因此,在这种情况下,逗号不会引入序列点。
答案 1 :(得分:0)
未指定评估函数参数的顺序。它们可以按任何顺序进行评估。编译器决定。
答案 2 :(得分:0)
您可能获得任何价值。两次连续执行中缺少sequence points。提高警告的严格程度,您将获得warning: operation on ‘k’ may be undefined
。