负数在 C/C++ 中返回 false 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18840422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do negative numbers return false in C/C++?
提问by Jason Maldonado
When evaluating integers as booleans in C/C++, are negative numbers true or false? Are they always true/false regardless of compilers?
在 C/C++ 中将整数计算为布尔值时,负数是真还是假?无论编译器如何,它们总是真/假吗?
回答by Mark Garcia
All non-zero values will be converted to true
, and zero values to false
. With negative numbers being non-zero, they are converted to true
.
所有非零值都将转换为true
,零值将转换为false
。负数不为零时,它们将转换为true
.
Quoting from the C++11 standard (emphasis mine):
引用 C++11 标准(强调我的):
4.12 Boolean conversions [conv.bool]
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to
false
; any other value is converted totrue
.A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
4.12 布尔转换 [conv.bool]
1 算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为 bool 类型的纯右值。零值、空指针值或空成员指针值转换为
false
; 任何其他值都转换为true
. std::nullptr_t 类型的纯右值可以转换为 bool 类型的纯右值;结果值为假。
Are they always true/false regardless of compilers?
无论编译器如何,它们总是真/假吗?
You will only get the above guarantee when your compiler is standards-compliant, or at least, complies with this specific part of the standard. In practice, all compilers have this standard behavior, so there isn't much to worry about.
只有当您的编译器符合标准,或者至少符合标准的这一特定部分时,您才能获得上述保证。实际上,所有编译器都有这个标准行为,所以没有什么可担心的。
回答by Brendan Long
You can test it yourself by compiling this:
你可以通过编译这个来自己测试:
#include <stdio.h>
int main(int argc, char** argv) {
if (-1) {
printf("-1 is true\n");
} else {
printf("-1 is false\n");
}
return 0;
}
Results:
结果:
$ gcc -Wall -pedantic test.c -o test-c
$ g++ -Wall -pedantic test.c -o test-cpp
$ ./test-c
-1 is true
$ ./test-cpp
-1 is true
$ gcc -Wall -pedantic test.c -o test-c
$ g++ -Wall -pedantic test.c -o test-cpp
$ ./test-c
-1 是真的
$ ./test-cpp
-1 是真的
Of course, to answer the second part of your question, "Are they always true/false regardless of compilers?", the only way to be completely sure is to look at the spec. In general though, compilers will warn you if you do something dangerous, and you can see from the output above, that even with "pedantic" warnings, gcc
considers this code to be perfectly fine.
当然,要回答问题的第二部分,“无论编译器如何,它们是否总是真/假?”,完全确定的唯一方法是查看规范。不过一般来说,如果你做了一些危险的事情,编译器会警告你,你可以从上面的输出中看到,即使有“迂腐”的警告,也gcc
认为这段代码是完全没问题的。
回答by Keith Thompson
Short answer: Negative values, and any non-zero values in general, are treated as true when used as conditions.
简短回答:负值和一般的任何非零值在用作条件时都被视为真。
For C, there are a number of contexts in which an expression is treated as a condition. Conditions are not necessarily of type bool
or _Bool
; that type was only added to the language by the 1999 standard.
对于 C,有许多上下文将表达式视为条件。条件不一定是类型bool
或_Bool
;该类型仅由 1999 标准添加到语言中。
The most obvious of these contexts is the expression in an if
statement, but there are other examples: while
, do-while
, the second expression in a for
header, the first operand of the ?:
conditional operator, and the operand(s) of the !
, &&
, and ||
operators. (I thinkthat's an exhaustive list, but I'm not certain.)
最明显的这些上下文的是在表达if
语句,但也有其他例子:while
,do-while
,在第二个表达式for
报头,所述的第一个操作数?:
条件运算符,和操作数的(一个或多个)!
,&&
和||
运营商。(我认为这是一个详尽的清单,但我不确定。)
Here's what the C standard says about the behavior of the if
statement (the "two forms" refer to if
with and without an else
clause):
以下是 C 标准对if
语句行为的说明(“两种形式”是指if
带和不带else
子句):
In both forms, the first substatement is executed if the expression compares unequal to 0.
在这两种形式中,如果表达式比较不等于 0,则执行第一个子语句。
Which means that this:
这意味着:
if (foo) ...
is equivalent to this:
相当于:
if ((foo) != 0) ...
(adding extra parentheses to avoid any operator precedence issues). The meaning is clear if foo
is of type int
. If foo
is of some floating-point type, 0
is converted to the same type (which can cause some subtleties if the value happens to be a negative zero or a NaN). And if foo
is a pointer, 0
is treated as a null pointer constant; if (ptr)
is equivalent to if (ptr != NULL)
(assuming the definition of NULL
is visible).
(添加额外的括号以避免任何运算符优先级问题)。如果foo
是 类型,则含义很清楚int
。如果foo
是某种浮点类型,0
则转换为相同类型(如果值恰好是负零或 NaN,则可能会导致一些微妙之处)。而如果foo
是指针,0
则视为空指针常量;if (ptr)
等价于if (ptr != NULL)
(假设 的定义NULL
是可见的)。
For C++, the rules are stated a bit differently, but the effect is the same. The condition in a C++ if
statement is converted to type bool
(unlike in C, the type bool
has been built into C++ since its early history). The conversion of a value of any scalar type to bool
is defined by the C++ standard as:
对于C++,规则的表述略有不同,但效果是一样的。C++if
语句中的条件被转换为类型bool
(与 C 不同,该类型bool
自 C++ 的早期历史以来就已内置于 C++ 中)。bool
C++ 标准将任何标量类型的值转换为:
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. A prvalue of type std::nullptr_tcan be converted to a prvalue of type bool; the resulting value is false.
零值、空指针值或空成员指针值转换为false;任何其他值都将转换为 true。std::nullptr_t类型的纯右值可以转换为bool类型的纯右值;结果值为false。
So in both C and C++, any scalar (i.e., integer, floating-point, or pointer) value can be used as a condition, and the condition is false if the scalar is equal to zero, and true if it's not equal to zero. C defines this as an inequality comparison to 0
; C++ defines it as a conversion to the bool
-- but the result is the same.
所以在 C 和 C++ 中,任何标量(即整数、浮点数或指针)值都可以用作条件,如果标量等于零则条件为假,如果不等于零则为真. C 将其定义为与 的不等式比较0
;C++ 将其定义为到bool
--的转换,但结果是相同的。
This is getting a bit off the topic of the question, but I'll mention that it's important to note that a value that is treated as a true condition is not necessarily equalto true
. true
(which is 1
in C if you have #include <stdbool.h>
, and a unique value of type bool
in C++) is just one of many values that possess "truthiness" when used in a condition. Which is why you should almost never write:
这是有点过问题的话题,但我会提到,它是要注意重要的是,被视为一个真正的条件值不一定等于到true
。true
(1
如果您有#include <stdbool.h>
,则在 C 中,并且bool
在 C++ 中是类型的唯一值)只是在条件中使用时具有“真实性”的众多值之一。这就是为什么你几乎不应该写:
if (cond == true) ...
in either C or C++ (unless you really need to compare it to that one value); just write:
在 C 或 C++ 中(除非你真的需要将它与那个值进行比较);写就好了:
if (cond) ...
A C++ example:
一个 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";
}
The output is:
输出是:
n has truthiness
n != true
回答by Shafik Yaghmour
Anything that is not 0
will be converted to true
(1 in the case of C) a zero
value will be converted to false
(0 in the case of C). With respect to Cif we look at the C99 draft standardsection 6.3.1.2
Boolean typeparagraph 1says:
任何不是的0
都将转换为true
(在 C 的情况下为 1)一个zero
值将被转换为false
(在 C 的情况下为 0)。关于C,如果我们查看C99 草案标准部分6.3.1.2
布尔类型第1段说:
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.
当任何标量值转换为_Bool 时,如果值比较等于0,则结果为0;否则,结果为 1。
For completeness sake if we look at section 7.16
Boolean type and values paragraph 2says:
为了完整起见,如果我们查看7.16
布尔类型和值部分,第2段说:
The macro
bool
expands to _Bool.
with respect to C++the draft C++ standardin section 4.12
Boolean conversionsparagraph 1says(emphasis mine):
关于C++,布尔转换部分中的C++ 标准草案第1段说(强调我的):4.12
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.[...]
算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为 bool 类型的纯右值。零值、空指针值或空成员指针值转换为 false;任何其他值都将转换为 true。[...]
This should hold regardless of which compiler you use.
无论您使用哪种编译器,这都应该成立。
回答by DanielV
Good question. The answer is "depends".
好问题。答案是“取决于”。
if (-1) { // this is always true
}
On the other hand, suppose you are on a 16 bit machine:
另一方面,假设您在 16 位机器上:
if (-65536) { // this is always false
}
On the other hand,
另一方面,
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
}
}
So negative numbers are not always false, except sometimes they always are.
所以负数并不总是错误的,除非有时它们总是错误的。