">"、"<"、"!"、"&&"、"||"和"=="的“真正”结果是否已定义?

19

比如在C语言中写7>1,我能否期望结果将是确切的1,还是一些非零值?这个规则适用于所有布尔运算符吗?


3
很可能是重复的,但我找不到 :-( - mbq
3
@TRD:错误的。C语言表达式7>1的结果是类型为int且值为1的变量。 - Keith Thompson
4个回答

35
在C99的§6.5.8关系运算符中,第6项(<><=>=)规定如下:
每个运算符<(小于),>(大于),<=(小于或等于)和>=(大于或等于)应返回1,如果指定的关系为true则返回0,如果为false。结果类型为int
至于相等运算符,在§6.5.9中稍微有所不同(==!=):
与关系运算符类似,==(等于)和!=(不等于)运算符的优先级较低。每个运算符返回1,如果指定的关系为true,则返回0,如果为false,则返回0。结果类型为int。对于任何一对操作数,恰好一个关系是true。
逻辑AND和逻辑OR在§6.5.13(&&)稍微有所不同
如果两个操作数都不为0,则&&运算符应返回1;否则,它将返回0。结果类型为int
...和§6.5.14(||
如果两个操作数中的任何一个不为0,则||运算符应返回1;否则,它将返回0。结果类型为int
一元算术运算符!的语义在§6.5.3.3/4中:
逻辑否定运算符!的结果为0,如果其操作数的值与0不相等,则为1。结果类型为int。表达式!E等效于(0==E)。
结果类型在整个过程中均为int,可能的值为01。(除非我错过了一些内容。)

6
方便的是,stdbool.h 将 true 和 false 分别定义为 1 和 0(C99 7.16)。 - Lundin
很好,尤其是因为在其他语言中&&和||的行为不同(返回最后一个被评估的值)。如果没有使用标准操作符,可以通过使用!!或者转换到< stdbool.h > bool来完成夹紧。 - Tobu

15

C语言在布尔运算符中遵循波斯特法则(Postel's Law):对自己所做的事情保守,对来自他人的事情宽容。在布尔表达式中,任何非零值都被视为真,但它总会产生0或1。例如2 != 3始终为1


6
从ISO C99标准第6.5.8节中可以得知:
6 每个运算符 < (小于)、> (大于)、<= (小于等于) 和 >= (大于等于) 都应返回1,如果指定的关系为真,则返回0。结果类型为int。
从第6.5.9节中可以得知:
3 == (等于) 和 != (不等于) 运算符类似于关系运算符,除了它们具有较低的优先级。每个运算符都会返回1,如果指定的关系为真,则返回0。结果类型为int。对于任何一对操作数,只有一个关系是真的。
逻辑合取 (&&) 和逻辑析取 (||) 运算符也是如此。
PS:顺便提一下,这就是位运算符 (&|) 通常可以用作非短路版本逻辑运算符的原因。

4

所有在C语言中产生逻辑真/假值的运算符都会返回一个类型为int的结果,其中0表示假,1表示真。

但并非所有产生逻辑真/假值的表达式都是这样的。例如,在<ctype.h>中声明的is*()字符分类函数(如isdigit()isupper()等)如果条件为假,则返回0,但如果条件为真,则可能返回任何非零值。

只要您直接将结果用作条件:

if (isdigit(c)) ...
if (!isdigit(c)) ...
if (isdigit(c) || islower(c)) ...

不要试图将其与其他东西进行比较:

if (isdigit(c) == 1) ...    /* WRONG */
if (isdigit(c) == true) ... /* ALSO WRONG */

这不应该引起任何问题。

(你可以安全地将结果与0false进行比较,但没有充分的理由这样做;这就是!运算符的作用。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接