考虑代码
bool f() { return 42; }
if (f() == 1)
printf("hello");
C(C99 + with stdbool.h)和C ++标准是否保证"你好"会打印吗?确实
bool a = x;
总是等同于
bool a = x ? 1 : 0;
答案 0 :(得分:2)
是。你错过了一步。 “0”为false,其他每个int都为true,但f()始终返回true(“1”)。它不返回42,铸造发生在“返回42;”。
答案 1 :(得分:2)
在C macro bool中(我们谈到stdbool.h
中定义的宏)扩展为只有两个值0和1的_Bool
。
在C ++中,表达式f() == 1
中f()的值根据整数提升隐式转换为int 1。
所以在我看来这段代码
bool f() { return 42; }
if (f() == 1)
printf("hello");
是安全的。
答案 2 :(得分:2)
在C ++中,bool
是内置类型。从任何类型到bool
的转化始终会产生false
(0)或true
(1)。
在1999 ISO C标准之前,C没有内置的布尔类型。程序员定义他们自己的布尔类型是(并且仍然是)常见的,例如:
typedef int BOOL;
#define FALSE 0
#define TRUE 1
或
typedef enum { false, true } bool;
任何此类型的大小至少为1个字节,并且可以存储0
或1
以外的值,因此与0
或1
的相等比较可能不安全
C99添加了一个内置类型_Bool
,其转换语义类似于C ++中bool
的转换语义;如果您有bool
,也可以将其称为#include <stdbool.h>
。
在C或C ++中,行为未定义的代码可能会在bool
对象中存储0或1以外的值。例如,这个:
bool b;
*(char*)&b = 2;
将(可能)将值2
存储在b
中,但C ++编译器可能假设其值为0
或{{1} };像1
或b == 0
这样的比较可能会成功或失败。
我的建议:
b == true
对象中存储奇怪值的代码。bool
平等或不平等的值与bool
,0
,1
或false
进行比较。在你的例子中:
true
假设这是C ++或带有bool f() { return 42; }
的C,此函数将返回<stdbool.h>
或等同于true
,因为1
转换为42
收益率bool
。
1
由于您尚未构建任何奇怪的if (f() == 1)
printf("hello");
值,因此表现良好且会打印bool
。
但明确地进行比较毫无意义。 "hello"
已经是f()
类型,因此它已经可用作条件。你可以(也可能应该)写下:
bool
撰写if (f())
printf("hello");
并不比撰写f() == 1
更有帮助。
在一个真实的程序中,大概你会给你的函数一个有意义的名字,清楚地表明它的值代表一个条件:
(f() == 1) == 1)
答案 3 :(得分:0)
我所知道的唯一真正的技巧,对于C99之前的环境很有用,是双重否定
int a = 42;
if ( (!!a) != 0 ) printf("Hello\n");
这将打印Hello
,因为!!
操作的结果是值为非零时为true
的布尔值,否则为false
。但是这要花费你2个否定来获得你想要的布尔值,在现代标准中这是多余的,因为没有!!
你将获得相同的结果,而且这是语言授予的结果。