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

Jas*_*ado 48 c c++ boolean

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

Mar*_*cia 61

所有非零值都将转换为true,而零值将转换为false.负数不为零,它们将转换为true.

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

4.12布尔转换[conv.bool]

1算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue.将零值,空指针值或空成员指针值转换为false; 任何其他值都转换为true.类型为std :: nullptr_t的prvalue可以转换为bool类型的prvalue; 结果值为false.


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

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


Rei*_*ica 7

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

#include <stdio.h>

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

结果:

$ gcc -Wall -pedantic test.c -o test-c
$ g ++ -Wall -pedantic test.c -o test-cpp
$ ./test-c
-1为true
$ ./test-cpp
-1为true

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

  • 挑剔但是在一个甚至几个编译器上运行的示例并不能证明这是有效的,或者应该在所有这些编译器中工作,即它不依赖于实现. (4认同)
  • @ShafikYaghmour是的。我更新了答案以提供更多详细信息,并添加了-Wall -pedantic`,以表明gcc对此没有任何问题。我在规格说明之后创建了这个答案,主要是为了证明问题的第一部分易于测试。 (2认同)

Kei*_*son 6

简短的答案:负值,以及通常所有非零值,在用作条件时都被视为true。

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

最明显的这些上下文的是在表达if语句,但也有其他例子:whiledo-while,在第二个表达式for报头,所述的第一个操作数?:条件运算符,和操作数的(一个或多个)!&&||运营商。(我认为这是一个详尽的清单,但我不确定。)

这是C标准关于if语句行为的说明(“两种形式”是指if带有或不带有else子句的情况):

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

这意味着:

if (foo) ...
Run Code Online (Sandbox Code Playgroud)

等效于此:

if ((foo) != 0) ...
Run Code Online (Sandbox Code Playgroud)

(添加额外的括号以避免出现任何运算符优先级问题)。如果foo是type,则含义很清楚int。If foo是某种浮点类型,0将转换为相同类型(如果该值恰好是负零或NaN,则可能会引起一些微妙)。如果foo是指针,则将其0视为空指针常量;if (ptr)等价于if (ptr != NULL)(假设的定义NULL是可见的)。

对于C ++,规则的表述有些不同,但是效果是相同的。C ++ if语句中的条件将转换为类型bool(与C语言不同,该类型bool自C ++诞生以来就已内置于C ++中)。boolC ++标准将任何标量类型的值转换为:

零值,空指针值或空成员指针值将转换为false;其他任何值都将转换为true。类型的prvalue 的std :: nullptr_t可以被转换成类型的prvalue 布尔 ; 结果值是false

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

这是有点过问题的话题,但我会提到,它是要注意重要的是,被视为一个真正的条件值不一定等于truetrue1在C中,如果您有#include <stdbool.h>,则在C中,类型的唯一值bool在C ++中)只是在条件中使用时具有“真实性”的许多值之一。这就是为什么您几乎不应该写:

if (cond == true) ...
Run Code Online (Sandbox Code Playgroud)

在C或C ++中(除非您确实需要将其与该值进行比较);写就好了:

if (cond) ...
Run Code Online (Sandbox Code Playgroud)

一个C ++示例:

#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";
}
Run Code Online (Sandbox Code Playgroud)

输出为:

n has truthiness
n != true
Run Code Online (Sandbox Code Playgroud)