【问题标题】:Comparing with boolean variable in C与 C 中的布尔变量比较
【发布时间】:2012-12-01 10:18:45
【问题描述】:

考虑代码:

int foo(void)
{
    _Bool b = 1; // is true
    int i = 42;  // mean true in conditions

    if (i == b)
        return 1;
    else if ((_Bool)i == b)
        return 2;
    else
        return 3;
}

根据 C 标准(C99 或 C11),此函数将返回什么?

附:在带有 -std=c99 选项的 GCC 4.7.2 上,该函数返回 2。

【问题讨论】:

标签: c c99 c11


【解决方案1】:

它返回2

“通常的算术转换”应用于== 运算符的操作数。 _Bool 是无符号类型,转换等级低于intunsigned int

C99C11 标准的第 6.3.1.8 节“常用算术转换”中指定了“常用算术转换”(链接指向最近的草案)。

i == b 中,由于没有浮点操作数,因此“整数提升”应用于两个操作数,将右操作数从_Bool 提升到int 并产生值1。现在两个操作数属于同一类型,因此不需要进一步转换。所以i == b等价于42 == 1,是假的。

(_Bool)i == b 中,“整数提升”仍然应用于两个操作数,因此两者都从_Bool 转换为int。 (从int_Bool 再到int 的转换会丢失信息,将所有非零值转换为1。)现在两个操作数的类型相同,因此不需要进一步转换。所以(_Bool)i == b 等价于1 == 1,这是真的——并且函数返回2

(注意:由于我在阅读标准时有些粗心,这是关于此答案的第三次主要编辑。我想这次我做对了。)

在回答 cmets 中的一个问题时,b == 42ub_Bool 提升到 int,从而产生 intunsigned int 的比较。由于操作数的符号不同但转换等级相同,因此将有符号操作数转换为无符号类型。将1int 转换为unsigned int 很简单,生成1u。所以比较等于1u == 42u,是假的。

(请注意,C 中的 == 运算符与其他等式和关系运算符一样,会产生 int 类型的结果,其值为 01不是 _Bool 类型的结果。)

【讨论】:

  • if(b == 42u) 是 TRUE 还是 FALSE ? ...42 后缀为无符号
【解决方案2】:

为什么不直接运行呢?

实际上是返回2。 gcc 版本 4.5.4 与 -std=gnu99

【讨论】:

    【解决方案3】:

    如果两个操作数都有算术类型,通常的算术转换是 执行。

    因此,在计算表达式i == b 时,会发生算术转换。在算术转换期间,所有涉及的操作数都被转换为所有可以“适应”的最低等级类型,在本例中为int

    由于1 != 42,第一个条件不成立。

    第二个表达式首先将i 转换为_Bool,从而得到true。然后它评估true == true,这显然是true。因此该函数返回2

    【讨论】:

      猜你喜欢
      • 2021-07-16
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多