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

Har*_*esh 0 c operators operator-precedence

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

# include <stdio.h>

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

这里k最初的价值是35,当我在测试kprintf我认为:

  1. k>40 应该检查哪个应该导致0
  2. k==35 应该检查,哪个应该导致1
  3. 最后应该分配50 k,哪个应该输出50

所以最终输出应该是1 50 0,但输出是0 50 1.

Sha*_*our 6

你不能依赖这个程序的输出,因为它是undefined behavior,C中没有指定评估顺序,因为它允许编译器更好地优化,从C99草案标准部分6.5段落3:

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

它也是未定义的,因为您正在访问它的值k并在其中分配它sequence point.从草案标准部分6.5段落2:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,先前的值应该只读以确定要存储的值.

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

i = ++i + 1;
a[i++] = i; 
Run Code Online (Sandbox Code Playgroud)

更新

关于函数调用中的逗号是否作为序列点进行了评论.如果我们看段节6.5.17 Comma operator2说:

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

但段落3说:

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

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