【问题标题】:How the assignment statement in an if statement serves as a condition?if 语句中的赋值语句如何作为条件?
【发布时间】:2016-09-07 01:38:03
【问题描述】:
if ((vnd = (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend))) {...}

你能告诉我为什么它是一个赋值而不是括号中的布尔表达式吗?在什么情况下这个赋值可以被认为是“真”或“假”?

【问题讨论】:

  • 任何半途而废的现代编译器都会出于充分的理由发出警告
  • @Olaf 即使使用了((..))?
  • @SouravGhosh:嗯,我真的没有注意到他们。好的,我改为“应该”。使用 gcc 验证:它甚至建议使用括号来避免警告(并且它们有效)。哎呀,这应该需要一个明确的比较来抑制警告,没有什么不那么明显的了。感谢您通知我。
  • 标记的重复项不是重复项,因为链接的问题回答了关于使用的问题,而这个问题询问了行为。我重新打开这个。 :)

标签: c if-statement boolean assignment-operator


【解决方案1】:

引用 C11,第 §6.5.16 章,赋值运算符强调我的

赋值运算符将值存储在左操作数指定的对象中。 安 赋值表达式具有赋值后左操作数的值,111) 但不是 一个左值。

因此,首先会发生赋值,然后,已赋值的值将用作if 中的条件语句。

所以,如果是

if (p = 0 )

将评估为 FALSE 并且

if (p = 5)

将是 TRUE。

【讨论】:

  • 谢谢,这正是我需要的,我会接受的。
【解决方案2】:

“等于”的逻辑运算符是==

当您说vnd = (struct... 时,您将= 之后的所有内容分配给变量vnd。如果你想要一个真假,你需要使用==

【讨论】:

    【解决方案3】:

    C 将任何非零值视为true,将任何 0 视为假。

    此分配的值等于它分配给vnd 的值,在本例中为struct diam_vnd_t *。 if 语句检查赋值后vnd 是否为NULL

    这相当于:

    vnd = (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend);
    if (vnd) {...}
    

    【讨论】:

    • C 很好地具有布尔类型。在条件中,任何表达式都将转换为布尔结果(不过是int 类型)。
    • bool 类型只是一个unsigned int。从根本上说,该语言将“零”和“非零”处理为布尔值,而不是 true/false 原子。
    • 不,_Bool 是一个独特的无符号整数类型,其值为 01 boolstdbool.h 中的一个宏,它映射到 _Bool不是 unsigned int。注意:这是标准 C,而不是一些自制软件 typedef!关于“真”/“假”解释:试试_Bool b = 4;printf("%d", (bool)5);。请注意,布尔逻辑没有定义如何表示“真”/“假”。他们通常是0/1,因为这简化了数学运算。参见维基百科。
    • 最好直接阅读 C 标准(特别是 6.2.5p2 和 p6,例如)而不是第二/第三来源。 Maybne 您会发现自过去 17 年以来的其他一些新功能。您可能还会发现NULL 是一个带有空指针常量 的宏,而不是特定值。指针变量只能是空指针。并且不需要具有全零的二进制表示。不过,这样的空指针必须评估为“假”。
    【解决方案4】:

    赋值总是用一个等号完成。 =

    int i;
    i = 0; //assignment
    

    这会将 0 分配给一个名为 i 的整数。

    你的 if 语句也会发生同样的事情。是否在 if 语句中无关紧要。

    (vnd = (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend))
    

    要做一个布尔表达式,你需要使用==

    (vnd == (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend))
    

    这将根据两个项目的比较返回真或假

    【讨论】:

    • int i = 0; 不是分配。
    • @Olaf int i; //declaration, i = 0; //assignment
    • 这些是不同的东西!
    • @Olaf 是的,我知道,我只是想确认您指的是什么。我想我应该把两者分开。
    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2020-11-06
    • 2018-09-20
    • 2020-08-07
    • 2015-07-15
    相关资源
    最近更新 更多