关于C语言中的布尔类型
C语言相对较晚才引入布尔类型,具体时间是1999年。在此之前,C语言并不支持布尔类型,而是使用int
类型来处理所有布尔表达式。因此,所有逻辑运算符如> == !
等返回的都是值为1
或0
的int
类型。
在使用自定义的类型,例如 typedef enum { FALSE, TRUE } BOOL;
的应用程序中,这种情况很常见,它同样是一个int
大小的类型。
C++则提供了更好的、明确的布尔类型——bool
,其大小不超过1字节。然而在C中,布尔类型或表达式最坏情况下会占用4个字节。在C99标准中,为了与C++兼容,引入了某种程度上的兼容性。C语言也得到了布尔类型 _Bool
和头文件 stdbool.h
。
stdbool.h
提供了一些与 C++ 兼容的功能。该头文件定义了宏bool
(与C++关键字拼写相同),它扩展为 _Bool
,一种小整数类型,可能大小为1字节。同样地,该头文件提供了两个宏true
和false
,与C++关键字的拼写相同,但向后兼容旧的C程序。因此,在C中,true
和false
会扩展为1
和0
,其类型是int
。这些宏实际上并不像对应的C++关键字那样属于布尔类型。
同样地,为了保持向后兼容性,C语言中的逻辑运算符至今仍会返回一个int
类型,尽管现在C语言已经有了布尔类型。而在C++中,逻辑运算符会返回一个bool
类型。因此,如sizeof(a == b)
这样的表达式在C语言中将给出一个int
的大小,但在C++中将给出一个bool
的大小。
关于三目运算符?:
三目运算符?:
是一个带有一些怪癖的奇怪操作符。很多人错误地认为它与if() { } else {}
完全等价。但实际上不是。
在第1个和第2或3个操作数之间存在一个序列点。?:
运算符只保证评估第2或第3个操作数,因此它无法执行未被评估的操作数的任何副作用。像true? func1() : func2()
这样的代码不会执行func2()
。到目前为止还好。
然而,有一个特殊规则规定,第2和第3个操作数必须隐式类型提升并使用通常的算术转换进行平衡。(C语言中的隐式类型提升规则在这里解释)。这意味着第2或第3个操作数将始终至少与一个int
类型一样大。
因此,即使在C语言中,true
和false
恰好是int
类型,表达式始终会至少给出一个int
的大小。
即使您将表达式改写为
sizeof(a ? (bool)true : (bool)false)
,它仍会返回一个
int
的大小!这是由于通过通常的算术转换进行了隐式类型提升。
sizeof(true)
和sizeof(false)
也都是4:http://ide.geeksforgeeks.org/O5jvuN - tkausl_Bool
大小为1时,却没有定义true
和false
。但据我所知,标准对此没有任何规定。 - user2371524sizeof(true)
吗?也许这会使事情变得更清晰一些(特别是,它将变得明显,三元运算符是一个转移注意力的东西)。 - n. m.stdbool.h
将true
定义为#define
为1,因此这是其字面定义。 - n. m.