简体   繁体   English

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

[英]C Programming : Confusion between operator precedence

I am confused between precedence of operators and want to know how this statement would be evaluated. 我对运算符的优先级感到困惑,想知道如何评估该语句。

# include <stdio.h>

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

Here k is initially have value 35, when I am testing k in printf I think : 这里k最初的值为35,当我在printf测试k ,我认为:

  1. k>40 should be checked which should result in 0 k>40应检查为0
  2. k==35 should be checked and which should result in 1 k==35应该被检查,结果应该为1
  3. Lastly 50 should get assigned to k and which should output 50 最后,应将50分配给k ,并应输出50

So final output should be 1 50 0 , but output is 0 50 1 . 因此最终输出应为1 50 0 ,但输出为0 50 1

You can not rely on the output of this program since it is undefined behavior , the evaluation order is not specified in C since that allows the compiler to optimize better, from the C99 draft standard section 6.5 paragraph 3 : 您不能依赖此程序的输出,因为它是undefined behavior ,未在C中指定评估顺序,因为这使编译器可以根据C99草案标准第6.5节第3段进行更好的优化:

The grouping of operators and operands is indicated by the syntax.74) Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified. 语法表示操作符和操作数的分组。74)除非稍后指定(对于函数调用(),&&,||,?:和逗号运算符), 子表达式的求值顺序和哪种副作用都未指定。

It is also undefined because you are accessing the value of k and assigning to it in the same sequence point . 它也是未定义的,因为您正在访问k的值并在同一sequence point为其分配sequence point From draft standard section 6.5 paragraph 2 : 从标准草案第6.5条第2款:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. 在上一个序列点与下一个序列点之间,对象的存储值最多只能通过对表达式的求值来修改。 Furthermore, the prior value shall be read only to determine the value to be stored. 此外,先验值应只读以确定要存储的值。

it cites the following code examples as being undefined: 它引用了以下未定义的代码示例:

i = ++i + 1;
a[i++] = i; 

Update 更新资料

There was a comment as to whether the commas in the function call acted as a sequence point or not. 关于函数调用中的逗号是否充当序列点的评论。 If we look at section 6.5.17 Comma operator paragraph 2 says: 如果我们看6.5.17 Comma operator节, 6.5.17 Comma operator2段会说:

The left operand of a comma operator is evaluated as a void expression; 逗号运算符的左操作数被评估为void表达式; there is a sequence point after its evaluation. 评估后有一个序列点。

but paragraph 3 says: 但是第3段说:

EXAMPLE As indicated by the syntax, the comma operator (as described in this subclause) cannot appear in contexts where a comma is used to separate items in a list (such as arguments to functions or lists of initializers ). 示例如语法所示,逗号运算符(如本小节中所述) 不能出现在使用逗号分隔列表中的项(例如函数的参数或初始化器列表 )的上下文中

So in this case the comma does not introduce a sequence point. 因此,在这种情况下,逗号不会引入序列点。

The order in which function arguments are evaluated is not specified. 未指定函数参数的评估顺序。 They can be evaluated in any order. 可以按任何顺序对它们进行评估。 The compiler decides. 编译器决定。

This is undefined behaviour . 这是未定义的行为

You may get any value. 您可能会获得任何价值。 Lack of sequence points in two consecutive execution. 在两个连续执行中缺少序列点 Increase strictness level for warning and you will get warning: operation on 'k' may be undefined . 提高警告的严格性级别,您会得到warning: operation on 'k' may be undefined

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM