在C / C ++中将整数评估为布尔值时,负数是真还是假?无论编译器如何,它们总是真/假吗?
答案 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是真的
当然,要回答问题的第二部分,“无论编译器是什么,它们总是真/假吗?”,唯一可以完全确定的方法是查看规范。一般来说,编译器会警告你,如果你做了一些危险的事情,你可以从上面的输出中看到,即使使用“迂腐”warnings,gcc
也认为这段代码完全正常。
答案 2 :(得分:4)
简答:是的,负值和一般的任何非零值在用作条件时都被视为真。
对于C,有许多上下文将表达式视为条件。条件不一定是bool
或_Bool
类型;该类型仅在1999年标准中添加到该语言中。
这些上下文中最明显的是if
语句中的表达式,但还有其他示例:while
,do-while
,for
标题中的第二个表达式,?:
条件运算符的第一个操作数,以及!
,&&
和||
运算符的操作数。 (我认为这是一个详尽的清单,但我不确定。)
以下是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
}
}
所以负数并不总是假的,除非有时它们总是如此。