我们知道任何不相等的数字0都被视为trueC,所以我们可以写:
int a = 16;
while (a--)
printf("%d\n", a); // prints numbers from 15 to 0
Run Code Online (Sandbox Code Playgroud)
但是,我想知道是否将真/假定义为C中的1/ 0,所以我尝试了下面的代码:
printf("True = %d, False = %d\n", (0 == 0), (0 != 0)); // prints: True = 1, False = 0
Run Code Online (Sandbox Code Playgroud)
请问C标准明确指示的真正的真值和假的1和0分别?
hac*_*cks 93
C标准是否明确指出了真值
true和falseas0和1?
C标准定义true和false作为宏分别stdbool.h扩展到1和0.
C11-§7.18:
其余三个宏适用于
#if预处理指令.他们是Run Code Online (Sandbox Code Playgroud)true它扩展为整数常量
1,Run Code Online (Sandbox Code Playgroud)false扩展为整数常数
0[...]
关于运营商==和!=
C11-§6.5.9/ 3:
的
==(等于)和!=(不等于)运算符类似于除了它们的优先级低的关系运算符.108)1如果指定的关系为真且每个运算符0为假,则每个运算符都会产生.结果有类型int.对于任何一对操作数,其中一个关系是正确的.
ken*_*ytm 50
它没有在C11中明确指出.所有语言级别的操作都将返回1作为真值(并接受任何非零,包括NaN为真).
_Bool,那么true必须是1,因为标准只要求它保持0和1.(§6.2.5/ 2).<stdbool.h>宏中true扩展到1(§7.18/ 3)==,!=,<,>,<=和>=返回0或1(§6.5.8/ 6,§6.5.9/ 3).!,&&并||返回0或1(§6.5.3.3/ 5,§6.5.13/ 3,§6.5.14/ 3)defined 扩展为0或1(§6.10.1/ 1)但是所有标准库函数,例如islower只是说"非零"(例如§7.4.1/ 1,§7.17.5.1/ 3,§7.30.2.1/ 1,§7.30.2.2.1/ 4).
§6.2.5/ 2:声明为type的对象
_Bool足以存储值0和1.§6.5.5.3/ 5:
!如果操作数的值不等于0,则逻辑否定运算符的结果为0;如果其操作数的值等于0,则为1.§6.5.8/ 6:如果指定的关系为真,则每个运算符
<(小于),>(大于),<=(小于或等于)和>=(大于或等于)将产生1,如果指定的关系为0则为0是假的.107)......§6.5.9/ 3:(
==等于)和!=(不等于)运算符类似于关系运算符,除了它们的优先级较低.108)如果指定的关系为真,则每个运算符产生1,如果是,则每个运算符产生0假....§6.5.13/ 3:
&&如果两个操作数的比较不等于0,则运算符应得1; ...§6.5.14/ 3:
||如果操作数的任何一个比较不等于0,则运算符应产生1; ...§6.10.1/ 1:......它可能包含形式的一元运算符表达式
defined identifier- 或 -defined ( identifier )- 如果......,则评估为1§7.4.1(字符分类函数)/ 1:当且仅当...时,本子句中的函数返回非零(真)
§7.18/ 3:其余三个宏适用于
#if预处理指令.它们是 -true- 扩展为整数常数1,...§7.17.5.1/ 3:
atomic_is_lock_free当且仅当对象的操作是无锁的时,泛型函数返回非零(true)....§7.30.2.1(宽字符分类函数)/ 1:当且仅当...时,本子句中的函数返回非零(真)
§7.30.2.2.1/ 4:
iswctype当且仅当...时,函数返回非零(true)
pax*_*blo 21
在C中处理布尔值(我的意思是真/假值而不是特定的C bool/_Bool类型)时,需要注意两个标准区域.
第一个与表达式的结果有关,可以在C11 6.5 Expressions(例如关系运算符和相等运算符)的各个部分中找到.最重要的是,每当表达式生成布尔值时,它......
...如果指定的关系为真,则产生1,如果为假,则产生0.结果是int类型.
所以,是的,任何布尔生成表达式的结果都是一个表示true,或者0表示false.这与stdbool.h标准宏所在的位置匹配,true并false以相同的方式定义.
但请记住,遵循"你所发送的保守,你接受的自由"的鲁棒性原则,布尔语境中整数的解释稍微放松一些.
再次,从各个部分6.5,你会看到如下语言:
该
||操作人员应得到1如果任一操作数的比较不等于0; 否则,它产生0.结果类型为int.
从那(和其他部分),很明显零被认为是假,任何其他值都是真的.
另外,指定用于布尔生成和解释的值的语言也会出现在C99和C89中,所以它们已经存在了相当长的一段时间.甚至K&R(ANSI-C第二版和第一版)都指定了以下文本段:
如果为true,则关系表达式
i > j和由&&和连接的逻辑表达式||定义为具有值,1如果为true,0则为false.在测试部分
if,while,for,等,"真"只是意味着"非零".该
&&运营商...如果两个操作数比较不等于零,否则为0返回1.该
||运营商...返回1,如果任一操作数比较不等于零,否则为0.
宏stdbool.h也会出现在C99中,但不会出现在C89或K&R中,因为该头文件在该点不存在.
你混合了很多不同的东西:控制语句,运算符和布尔类型.每个人都有自己的规则.
控制语句的作用类似于if语句C11 6.4.8.1:
在两种形式中,如果表达式比较不等于0,则执行第一个子语句.
while,for等有相同的规则.这与"真实"或"虚假"无关.
对于假设产生布尔结果的运算符,它们实际上产生的int值为1或0.例如,相等运算符,C11 6.5.9:
如果指定的关系为真,则每个运算符产生1,如果为假,则产生0
以上所有是因为C在1999年之前没有布尔类型,即使它确实得到了一个,上述规则也没有改变.因此,与语句和运算符产生布尔类型(如C++和Java)的大多数其他编程语言不同,它们只产生一个int零值或零值.例如,sizeof(1==1)将在C中给出4,但在C++中给出1.
C中的实际布尔类型是命名的_Bool,需要现代编译器.头stdbool.h定义的宏bool,true并false展开后_Bool,1并0分别(用于C++兼容性).
然而,将控制语句和运算符视为实际需要/产生布尔类型是一种很好的编程习惯.像MISRA-C这样的某些编码标准推荐这种做法.那是:
if(ptr == NULL)而不是if(ptr).
if((data & mask) != 0)而不是if(data & mask).
这种风格的目的是借助静态分析工具提高类型安全性,从而减少错误.可以说,这种风格只有在你使用静态分析仪时才有意义.例如,在某些情况下,它会导致更具可读性,自我记录的代码
if(c == '\0')
Run Code Online (Sandbox Code Playgroud)
好,意图很清楚,代码是自我记录的.
与
if(c)
Run Code Online (Sandbox Code Playgroud)
坏.可能意味着什么,我们必须去寻找c理解代码的类型.它是整数,指针还是字符?
| 归档时间: |
|
| 查看次数: |
18105 次 |
| 最近记录: |