在C / C ++中,负数是否返回false?

时间:2013-09-17 02:36:54

标签: c++ c boolean

在C / C ++中将整数评估为布尔值时,负数是真还是假?无论编译器如何,它们总是真/假吗?

5 个答案:

答案 0 :(得分:57)

所有非零值都将转换为true,零值将转换为false。如果负数不为零,则会将其转换为true

引用C ++ 11标准(强调我的):

  

4.12布尔转换[conv.bool]

     

1算术,无范围枚举,指针或指针的prvalue   成员类型可以转换为bool类型的prvalue。 零   转换value,null指针值或null成员指针值   到false;任何其他值都会转换为true类型的prvalue   std :: nullptr_t可以转换为bool类型的prvalue;该   结果值是假的。


  

无论编译器如何,它们总是真/假吗?

当您的编译器符合标准,或者至少符合标准的这一特定部分时,您将只能获得上述保证。实际上,所有编译器都有这种标准行为,所以没有太多担心。

答案 1 :(得分:6)

您可以通过编译来自行测试:

#include <stdio.h>

int main(int argc, char** argv) {
    if (-1) {
        printf("-1 is true\n");
    } else {
        printf("-1 is false\n");
    }
    return 0;
}

结果:

  

$ gcc -Wall -pedantic test.c -o test-c
  $ g ++ -Wall -pedantic test.c -o test-cpp
  $ ./test-c
  -1是真的   $ ./test-cpp
  -1是真的

当然,要回答问题的第二部分,“无论编译器是什么,它们总是真/假吗?”,唯一可以完全确定的方法是查看规范。一般来说,编译器会警告你,如果你做了一些危险的事情,你可以从上面的输出中看到,即使使用“迂腐”warningsgcc也认为这段代码完全正常。

答案 2 :(得分:4)

简答:是的,负值和一般的任何非零值在用作条件时都被视为真。

对于C,有许多上下文将表达式视为条件。条件不一定是bool_Bool类型;该类型仅在1999年标准中添加到该语言中。

这些上下文中最明显的是if语句中的表达式,但还有其他示例:whiledo-whilefor标题中的第二个表达式,?:条件运算符的第一个操作数,以及!&&||运算符的操作数。 (我认为这是一个详尽的清单,但我不确定。)

以下是C标准关于if语句行为的说法(“两种形式”是指带有和不带if子句的else):

  

在两种形式中,如果表达式将une等于0,则执行第一个子语句。

这意味着:

if (foo) ...

相当于:

if ((foo) != 0) ...

(添加额外的括号以避免任何运算符优先级问题)。如果foo属于int类型,则含义很明确。如果foo具有某种浮点类型,则0将转换为相同的类型(如果该值恰好为负零或NaN,则可能会导致一些细微之处)。如果foo是指针,则0被视为空指针常量; if (ptr)相当于if (ptr != NULL)(假设NULL的定义可见)。

对于C ++,规则略有不同,但效果是一样的。 C ++ if语句中的条件转换为类型bool(与C不同,类型bool自早期历史以来就已内置于C ++中)。任何标量类型的值到bool的转换都由C ++标准定义为:

  

零值,空指针值或空成员指针值   转换为 false ;任何其他值都转换为true。一个    std :: nullptr_t 类型的prvalue可以转换为prvalue   输入 bool ;结果值为 false

因此在C和C ++中,任何标量(即整数,浮点或指针)值都可以用作条件,如果标量等于零,则条件为假,如果不是,则为真等于零。 C将此定义为与0的不等式比较; C ++将其定义为bool的转换 - 但结果是相同的。

这有点偏离问题的主题,但我会提到重要的是要注意,被视为真实条件的值不一定等于到{{1 }}。 true(如果您有true,那么在C中为1,在C ++中为#include <stdbool.h>类型的唯一值)只是拥有“真实性”的众多值之一在一个条件下使用。这就是你几乎不应该写的原因:

bool

在C或C ++中(除非你真的需要将它与那个值进行比较);只写:

if (cond == true) ...

C ++示例:

if (cond) ...

输出结果为:

#include <iostream>
int main() {
    int n = 2;
    if (n)         std::cout << "n has truthiness\n";
    else           std::cout << "n does not have truthiness\n";
    if (n == true) std::cout << "n == true\n";
    else           std::cout << "n != true\n";
}

答案 3 :(得分:2)

任何非0的内容都将转换为true(在的情况下 1),zero值将转换为{{1} (C 的情况下 0)。关于 C ,如果我们查看C99 draft standard部分false 布尔类型 1 说:

  

当任何标量值转换为_Bool时,如果值比较相等,则结果为0   到0;否则,结果是1。

为了完整起见,如果我们查看部分6.3.1.2 布尔类型和值 2 说:

7.16

关于 C ++ The macro bool expands to _Bool. 部分中的draft C++ standard布尔转换 1 表示(强调我的):

  

算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue。 零值,空指针值或空成员指针值转换为false;任何其他值都转换为true。 [...]

无论您使用哪种编译器,这都应该成立。

答案 4 :(得分:-2)

好问题。答案是“依赖”。

if (-1) { // this is always true
}

另一方面,假设您使用的是16位计算机:

if (-65536) { // this is always false
}

另一方面,

int a = whatever doesn't matter;
if (a < 0) { // this might or might not be true
    if (a) { // this will always be true if we get here
    }
}

所以负数并不总是假的,除非有时它们总是如此。