C编程:运算符优先级之间的混淆

时间:2013-08-14 12:26:11

标签: c operators operator-precedence

我对运算符的优先级感到困惑,并想知道如何评估此语句。

# include <stdio.h>

int main()
{
  int k=35;  
  printf("%d %d %d",k==35,k=50,k>40);  
  return 0;  
}

此处k最初的值为35,当我在k中测试printf时,我认为:

    应该检查
  1. k>40哪个应该导致0
  2. 应该检查
  3. k==35,哪个应该导致1
  4. 最后应将50分配给k,并输出50
  5. 因此最终输出应为1 50 0,但输出为0 50 1

3 个答案:

答案 0 :(得分:6)

您不能依赖此程序的输出,因为它是undefined behavior,评估顺序未在C中指定,因为它允许编译器更好地优化,来自C99草案标准部分{ {1}}段6.5

  

运算符和操作数的分组由语法表示.74)除非另有说明   稍后(对于函数调用(),&amp;&amp;,||,?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。

它也是未定义的,因为您正在访问3的值并在同一sequence point中分配给它。来自草案标准部分k6.5

  

在上一个和下一个序列点之间,对象应具有其存储值   通过表达式的评估最多修改一次。 此外,先前的价值   应只读以确定要存储的值。

它引用以下代码示例为未定义:

2

更新

关于函数调用中的逗号是否作为序列点进行了评论。如果我们查看i = ++i + 1; a[i++] = i; 6.5.17 Comma operator段说:

  

逗号运算符的左操作数被计算为void表达式; 有一个   评估后的序列点。

但第2段说:

  

示例如语法所示,逗号运算符(如本子条款中所述)不能出现在使用逗号分隔列表中的项目的上下文中(例如函数的参数或初始化程序列表)。

因此,在这种情况下,逗号不会引入序列点。

答案 1 :(得分:0)

未指定评估函数参数的顺序。它们可以按任何顺序进行评估。编译器决定。

答案 2 :(得分:0)

这是undefined behaviour

您可能获得任何价值。两次连续执行中缺少sequence points。提高警告的严格程度,您将获得warning: operation on ‘k’ may be undefined