if 条件中的链式赋值

Posted

技术标签:

【中文标题】if 条件中的链式赋值【英文标题】:Chaining assignment in an if condition 【发布时间】:2021-05-05 01:08:27 【问题描述】:

您好,只是想知道如果您在 if 条件中使用链式分配,最左边的变量是否会用于检查 if 条件

就像 a=b=c 一样,它的 a 最终被检查,而不是 b 或 c

#include <stdio.h>

 int main()
 
  int a, b, c =0;
 
  // does this reduce to a == 100 and the variables b or c are not checked if they are == to 100 but simply assigned the value of 100 ? 
  if( (a = b = c = 100) == 100)
     printf( "a is 100 \n");

   
 return 0;

【问题讨论】:

没关系,可能编译器不会在汇编程序中使用变量。 【参考方案1】:

表达式实际上并未检查abc

赋值表达式,与任何表达式一样,都有一个值。在这种情况下,它是存储的值。但是,将值实际存储在对象中是一个副作用,因此无法保证在计算比较运算符时已经发生。

所以条件其实更像:

if (100 == 100)

对于abc 的分配以相对于比较而言无序的方式发生。

C standard 的第 6.5.16p3 节对赋值运算符进行了详细说明:

赋值运算符将值存储在左操作数指定的对象中。赋值表达式在赋值后具有左操作数的值,但不是左值。赋值表达式的类型是左操作数在左值转换后的类型。更新左操作数的存储值的副作用是在左操作数和右操作数的值计算之后排序的。操作数的计算是无序的。

【讨论】:

谢谢,所以我想如果有不可预测的情况,不应该使用链式分配 @AfzelAdam 它本身并不是不可预测的。您不能做的是在没有中间序列点的情况下在同一个表达式中读取和写入变量。在您的代码中,您只是在编写,所以没有问题。 @AfzelAdam thx,所以我想如果存在不可预测的情况,不应该使用链式赋值不,你不要使用这样的链式表达式,因为它们很难阅读,难以调试,因此更有可能出现错误。坦率地说,任何告诉您通过将越来越多的逻辑塞进一行来减少程序中的行数的人都不值得听。代码的重要之处在于保持其可读性,以便您可以轻松查看发生了什么,然后在需要修复其中的错误时对其进行调试。而且您必须修复其中的错误。 澄清一下,你不是说它是UB,对吧? @HolyBlackCat 正确,OP 的代码显示 UB。【参考方案2】:

条件始终为真。您的代码相当于:

a = 100;
b = 100;
c = 100;
printf( "a is 100 \n");

【讨论】:

代码最好被认为是c = 100; b = c; a = b; if (a == 100)…,因为每个赋值都会计算转换为左侧操作数类型后的结果,而不是右侧运算符的原始值。例如,对于 float a; int b;a = b = 3.5; 会将 a 设置为 3,而不是 3.5。 但是实际测试的是什么,看它是否为 100,比如它是变量 a @AfzelAdam a 的最终值正在测试中,在您的情况下始终为 100

以上是关于if 条件中的链式赋值的主要内容,如果未能解决你的问题,请参考以下文章

《Python基础教程》

条件“if”修饰符中的 Ruby 变量赋值

c语言中if语句条件为赋值语句

C语言中的条件赋值语句和if——else语句执行效率比较,哪一个效率高些,坐等高手解惑

if-if 和 if-elif 是不是定义为链式条件?

if条件的种类