【问题标题】:Back-to-back assignments in C [duplicate]C中的背靠背分配[重复]
【发布时间】:2016-12-24 11:57:11
【问题描述】:

我今天遇到了这段代码:

for (i = 0; i < level; i++) {
    a[i] = b[i] = c[i] = 0;
}

for循环里面的代码是什么意思?

【问题讨论】:

  • 最右边首先分配
  • 这些被称为“分配”,而不是“定义”。
  • @aschepler 已编辑。没错。
  • 太糟糕了,这篇文章没有显示a[], b[], c[] 的声明,因为这会有所作为。
  • @chux: dup 也没有 :-(。这就是为什么我认为应该给出一个全面的答案。

标签: c


【解决方案1】:
 a[i] = b[i] = c[i] = 0;

被解析为:

 a[i] = (b[i] = (c[i] = 0));

与以下效果相同:

 a[i] = 0;
 b[i] = 0;
 c[i] = 0;

【讨论】:

  • 与底部示例不同,直接赋值中没有任何序列点。因此不是严格等价的。
  • 您提到的等价在技术上并不完全正确。 (但效果与之前相同)。对于a = b = c = 0,等价于c=0; b=c; a=b;(也接受@2501 对不完全等价的解释)
  • 它们也不等同于 volatile 除了最左边的赋值之外的所有 LHS 的合格左值。而且它们也可能没有“相同的效果”。
  • @P.P.:对于volatile lvalues,这是一件非常危险的事情,因为标准甚至不需要实现具有一致的行为。查看副本。
  • @Olaf 事实上,这甚至可能是 UB。如果a 的元素少于level,则存在越界访问。或者,如果它们被声明为:int i = 0; int *a = &amp;i; int *b = &amp;i; int *c = &amp;i; 并假设 level>0,那么还有 UB。我敢肯定,许多类似的问题都可以“发明”,而无需了解所涉及的对象是如何声明的。
【解决方案2】:

以上代码的处理如下...

首先将0 分配给c[i],然后将c[i] 的值分配给b[i],然后将b[i] 的值分配给a[i]

所以,总的来说,为了明确你的概念,从现在开始你应该记住,这样的赋值语句是从 right to left 评估的。

【讨论】:

  • 这个答案说“第一个 0 分配给 ...”和“...的值分配给 ...”。如我所见,没有序列点,因此优化编译器可能会重新排序分配,例如将0 分配给a[i],然后再分配其他的。
  • 赋值语句从右到左计算。不正确。从右到左的关联性与评估顺序无关。
猜你喜欢
  • 2021-08-08
  • 1970-01-01
  • 2021-03-21
  • 2010-11-23
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2022-06-29
  • 1970-01-01
相关资源
最近更新 更多