【问题标题】:Unclear behavior of "," operator in CC中“,”运算符的行为不明确
【发布时间】:2013-07-17 10:39:02
【问题描述】:

在给定的代码中,我发现了以下序列,

data = POC_P_Status, TE_OK;

我不明白那是什么意思。

数据元素是否接收第一个或第二个元素或其他内容?

更新:

我在某处读到这种行为是这样的,

如果我会这样写:

如果(数据 = POC_P_Status,TE_OK){ ... }

如果 TE_OK 为真,则 if 子句为真。

什么意思?

【问题讨论】:

  • (data = POC_P_Status), TE_OK; 赋值的优先级高于逗号。
  • @BartFriederichs 优先级是您如何判断, 的第一个操作数是data = POC_P_Status 而不仅仅是POC_P_Status
  • @Bart 但是你通过优先规则确定它的第一个和第二个操作数是什么。
  • @DanielDaranas 确定 for 循环中的更新表达式获得豁免?
  • @Peter Try and see. cmets 中的 @all 也没有任何意义。

标签: c comma-operator


【解决方案1】:

它将POC_P_Status 存储到data 中。

i = a, b;   // stores a into i.

这相当于

(i = a), b;

因为逗号运算符的优先级低于赋值。

【讨论】:

  • 为什么在 return 语句中像:return a, b;它总是会返回 b 吗?在这种情况下,逗号运算符具有更高的优先级?
  • @dotixx,那里没有分配,所以没有优先级问题。
  • @dotixx 逗号运算符将两个表达式作为操作数。 return something 不是表达式,所以 return (a,b); 是解析它的唯一可能方法。
【解决方案2】:

相当于下面的代码:

data = POC_P_Status;
TE_OK;

换句话说,它将POC_P_Status 分配给data 并计算为TE_OK。 在您的第一种情况下,表达式是独立的,因此 TE_OK 只有在它是具有副作用的宏时才有意义。在第二种情况下,表达式实际上是if 语句的一部分,因此它总是计算为TE_OK 的值。该语句可以改写为:

data = POC_P_Status;
if (TE_OK) { ... }

来自 C11 草案 (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf):

逗号运算符的左操作数被评估为 void 表达;在其评估之后有一个序列点。然后 评估右操作数;结果有它的类型和值。如果 尝试修改逗号运算符的结果或 在下一个序列点之后访问它,行为是未定义的。

这意味着在表达式中:

a, b

a 被评估并丢弃,然后b 被评估。整个表达式的值等于b

(a, b) == b

逗号运算符常用于需要多次赋值但只允许一个表达式的地方,例如for循环:

for (int i=0, z=length; i < z; i++, z--) {
    // do things
}

在其他上下文中,例如函数调用和声明,逗号不是逗号运算符:

int func(int a, int b) {...}
              ^
              |
              Not a comma operator

int a, b;
     ^
     |
     Not a comma operator

【讨论】:

  • 虽然这一切都是真的,但它实际上并没有回答“x = y, z 做什么?”的问题
猜你喜欢
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
相关资源
最近更新 更多