【问题标题】:Unusual behavior of ternary operator?三元运算符的异常行为?
【发布时间】:2012-01-20 14:54:45
【问题描述】:

我今天只是在我的 c 课上玩三元运算符。并发现了这种奇怪的行为。

#include <stdio.h>
#include <stdbool.h>
main()
{
        int x='0' ? 1 : 2;
        printf("%i",x);
}

returns 1 符合预期。但是

#include <stdio.h>
#include <stdbool.h>
main()
{
        int x='0'==true ? 1 : 2;
        printf("%i",x);
}

returns 2 而我希望它是return 1

【问题讨论】:

    标签: c ternary-operator


    【解决方案1】:

    “0”的值不是零,它是在您的系统上编码数字“0”的任何整数值。通常为 48(在编码中使用 from ASCII),然后在解释为整数时不等于 true,即 1。

    所以你的第一行代码相当于

    int x = (48 != 0) ? 1 : 2;
    

    这清楚地评估为1。第二个是

    int x = (48 == 1) ? 1 : 2;
    

    同样清楚地评估为2

    【讨论】:

    • 这就是为什么带有“条件始终为真/假”警告的良好编译器很方便的原因。如果编译器没有对此发出警告,则说明它配置不当或制作不当。
    • @Lundin:我不同意。在很多情况下,由于使用预处理器宏和/或使用if 而不是#ifdef 进行条件编译,会出现always-true 或always-false 表达式,在这种情况下,通常会出现“条件始终为X”警告虚假并掩盖在它们之间丢失的真实警告。
    【解决方案2】:

    也许你混淆了'\0''0'

    字符常量的值

    '\0'
    

    在 C 中总是0

    字符常量的值

    '0'
    

    是实现定义的,取决于字符集。对于 ASCII,它是 0x30

    另请注意,宏 true 定义为值 1 而不是 0

    【讨论】:

      【解决方案3】:

      这是因为(假设为 ASCII)'0' 代表整数 0x30,即48,而true 代表整数 1。所以他们不相等。

      在 C 中,任何非零值都被认为是真的,但 true 本身是 1,而 1 是您从任何内置布尔测试中得到的(例如,0 == 01) .

      【讨论】:

      • (+1) 这就是为什么您经常会看到成语 !!foo 而不是 foo == true 来生成一个布尔值来指示 foo 是否具有非零值。
      • '0' 不会被提升为 int;它本身具有int 类型。
      • @R.:很好,谢谢。 true 也是如此,它被定义为扩展为整数常量1。所以这里根本没有进行类型推广。我已经相应地更新了我的答案。 (再次感谢!)
      【解决方案4】:

      true 定义为 1。'0' 在 ASCII 中是 0x30,不等于 1。

      因此条件'0'==true 不成立。

      【讨论】:

        【解决方案5】:

        那是因为'0' != true。布尔值被提升为整数类型并且等于 1 而'0' 等于 48

        【讨论】:

          【解决方案6】:

          '0' 不等于true,所以'0'==true 的结果为0(假)。这被分配给 x 并传递给三元运算符,给出您看到的结果。

          如果您打算做其他事情,您应该使用方括号来阐明您想要的优先顺序,或者将您的代码分解为多个语句。

          【讨论】:

            猜你喜欢
            • 2020-05-10
            • 2011-02-09
            • 2018-09-18
            • 1970-01-01
            • 2016-01-08
            • 1970-01-01
            • 2012-08-08
            • 1970-01-01
            • 2018-11-19
            相关资源
            最近更新 更多