prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 9.2

Q#defineTRUE定义为 1 是否危险,因为在 C 语言中任何非零值都被认为是“真”?如果内置的逻辑运算符或关系运算符“返回”的值不是 1 怎么办?


A在 C 语言中,任何非零值都被认为是真,但这只适用于“输入时”,也就是说,在期望布尔值的地方。当布尔值由内置运算符(如==, !=,而<=)生成时,它保证是 1 或 0。因此,测试

	if((a == b) == TRUE)
将按预期工作(只要TRUE为 1),但这显然是愚蠢的。事实上,显式测试TRUEFALSE通常是不合适的。特别是,与内置运算符不同,一些库函数(尤其是isupper, isalpha等)在成功时返回一个非零值,该值*不*一定为 1,因此将其返回值与单个值(如TRUE)进行比较是相当冒险的,并且很可能不起作用。

(此外,如果你认为

if((a == b) == TRUE)
if(a == b)
是一个改进,为什么不就此止步呢?为什么不使用
if(((a == b) == TRUE) == TRUE)
甚至
if((((a == b) == TRUE) == TRUE) == TRUE)
刘易斯·卡罗尔的文章《乌龟对阿喀琉斯说》。)

鉴于

	if(a == b)
是一个完全合法的条件,那么
	#include <ctype.h>

	...

	if(isupper(c))
		{ ... }
也是如此,因为isupper已知返回零/非零分别代表假/真。同样,在像
	int is_vegetable;		/* really a bool */

	...

	if(is_vegetable)
		{ ... }
	extern int fileexists(char *);	/* returns true/false */

	...

	if(fileexists(outfile))
		{ ... }
这样的代码中,不应有任何顾虑,只要is_vegetablefileexists()是“概念上的布尔类型”。像
	if(is_vegetable == TRUE)
or
	if(fileexists(outfile) == YES)
这样的替代方案并没有真正的改进。(可以将它们视为“更安全”或“更好的风格”,但也可以将它们视为冒险或糟糕的风格。它们读起来肯定不那么流畅。参见问题17.10。)

一个好的经验法则是,仅将TRUEFALSE(或类似)用于赋值给布尔变量或函数参数,或作为布尔函数的返回值,但切勿用于比较。

另请参阅问题5.3

参考:K&R1 第 2.6 节第 39 页,第 2.7 节第 41 页
K&R2 第 2.6 节第 42 页,第 2.7 节第 44 页,第 A7.4.7 节第 204 页,第 A7.9 节第 206 页
ISO 第 6.3.3.3 节,第 6.3.8 节,第 6.3.9 节,第 6.3.13 节,第 6.3.14 节,第 6.3.15 节,第 6.6.4.1 节,第 6.6.5 节
H&S 第 7.5.4 节第 196-7 页,第 7.6.4 节第 207-8 页,第 7.6.5 节第 208-9 页,第 7.7 节第 217-8 页,第 7.8 节第 218-9 页,第 8.5 节第 238-9 页,第 8.6 节第 241-4 页
刘易斯·卡罗尔,《乌龟对阿喀琉斯说》


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管