[英]Do negative numbers return false in C/C++?
在C / C ++中将整数评估为布尔值时,负数是真还是假? 无论编译器如何,它们总是真/假吗?
所有非零值都将转换为true
,零值将转换为false
。 如果负数不为零,则将它们转换为true
。
引用C ++ 11标准(强调我的):
4.12布尔转换[conv.bool]
1算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue。 零值,空指针值或空成员指针值转换为
false
; 任何其他值都转换为true
。 类型为std :: nullptr_t的prvalue可以转换为bool类型的prvalue; 结果值为false。
无论编译器如何,它们总是真/假吗?
只有当您的编译器符合标准,或者至少符合标准的这一特定部分时,您才能获得上述保证。 实际上,所有编译器都有这种标准行为,因此没有太多担心。
您可以通过编译来自行测试:
#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是真的
当然,要回答问题的第二部分,“无论编译器是什么,它们总是真/假吗?”,唯一可以完全确定的方法是查看规范。 一般来说,编译器会警告你,如果你做了危险的事情,你可以从上面的输出中看到,即使有“迂腐”的警告 , gcc
认为这个代码完全没问题。
简答:当用作条件时,负值和一般的任何非零值都被视为真。
对于C,有许多上下文将表达式视为条件。 条件不一定是bool
或_Bool
类型; 该类型仅在1999年标准中添加到该语言中。
这些上下文中最明显的是if
语句中的表达式,但还有其他示例: while
, do-while
, for
头中的第二个表达式, ?:
条件运算符的第一个操作数,以及操作数的!
, &&
和||
运营商。 (我认为这是一份详尽的清单,但我不确定。)
下面介绍一下C标准说,有关的行为if
声明(以下简称“两种形式”是指if
有和没有else
条款):
在两种形式中,如果表达式比较不等于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可以转换为bool类型的prvalue; 结果值为false 。
因此在C和C ++中,任何标量(即整数,浮点或指针)值都可以用作条件,如果标量等于零,则条件为假,如果不等于零,则为true 。 C将此定义为与0
的不等式比较; C ++将其定义为bool
的转换 - 但结果是相同的。
这有点偏离问题的主题,但我会提到重要的是要注意,被视为真实条件的值不一定等于 true
。 true
(如果你有#include <stdbool.h>
,则在C中为1
,在C ++中为bool
类型的唯一值)只是在条件中使用时具有“真实性”的众多值中的一个。 这就是为什么你几乎不应该写:
if (cond == true) ...
在C或C ++中(除非你真的需要将它与那个值进行比较); 写吧:
if (cond) ...
一个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";
}
输出是:
n has truthiness
n != true
任何非0
都将转换为true
( 在C的情况下为1 ), zero
值将转换为false
( 在C的情况下为0 )。 关于C,如果我们看一下C99标准草案第6.3.1.2
节布尔类型第1段说:
当任何标量值转换为_Bool时,如果值比较等于0,则结果为0; 否则,结果为1。
为了完整起见,如果我们看一下7.16
节的布尔类型和值,第2段说:
The macro
bool
expands to _Bool.
关于C ++ ,第4.12
节中的C ++标准草案 布尔转换第1段说( 强调我的 ):
算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue。 零值,空指针值或空成员指针值转换为false; 任何其他值都转换为true。 [...]
无论您使用哪种编译器,这都应该成立。
好问题。 答案是“依赖”。
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
}
}
所以负数并不总是错误的,除非有时它们总是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.