繁体   English   中英

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

[英]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语句中的表达式,但还有其他示例: whiledo-whilefor头中的第二个表达式, ?:条件运算符的第一个操作数,以及操作数的! &&|| 运营商。 (我认为这是一份详尽的清单,但我不确定。)

下面介绍一下C标准说,有关的行为if声明(以下简称“两种形式”是指if有和没有else条款):

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

这意味着:

if (foo) ...

相当于:

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

(添加额外的括号以避免任何运算符优先级问题)。 如果fooint类型,则含义很清楚。 如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM