与C中的布尔变量进行比较

时间:2012-12-01 10:18:46

标签: c c99 c11

考虑代码:

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),此功能将返回什么?

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

3 个答案:

答案 0 :(得分:2)

返回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

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

在回答评论中的问题时,b == 42ub_Bool提升为int,从而产生intunsigned int比较。由于操作数具有不同的符号但具有相同的转换等级,因此带符号的操作数将转换为无符号类型。将1int转换为unsigned int是微不足道的,产生1u。因此,比较等同于1u == 42u,这是假的。

(请注意,与其他相等和关系运算符一样,C中的==运算符会生成类型为int的结果,其值为01,< em> not 类型_Bool的结果。)

答案 1 :(得分:0)

  

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

因此,在评估表达式i == b时,将发生算术转换。在算术转换期间,所有涉及的操作数都将转换为所有可以“适合”的最低排序类型,在本例中为int

1 != 42以来,第一个条件不成立。

第二个表达式首先将i投射到_Bool,结果为true。然后它评估true == true,显然是true。因此该函数返回2

答案 2 :(得分:0)

为什么不运行它?

实际上是返回2。带有-std=gnu99

的gcc版本4.5.4