与0值比较的那些事

来源:互联网 发布:淘宝客怎么提现 编辑:程序博客网 时间:2024/05/17 02:27
在条件判断的时候,我们经常会碰到与0值比较的情况,但是通常有许多人使用时采用不恰当的条件判断。下面我们就详细讨论各种情况:
1. 布尔变量与零值的比较:
假设布尔变量的变量名为flag,则它和0值比较的条件判断语句如下:
if(flag) //表示flag为真
if(!flag) //表示flag为假

原因:根据布尔类型的语义,0为假,任何非0都为真,也许有人会觉得那直接用下面这种写法也行啊,
if(flag != 0) //表示flag为真
if(flag == 0) //表示flag为假
根据定义,似乎是对的,当然,在程序中也不会错,但是我们会以为这是布尔类型和整型的比较,类型
不匹配!当然,还有下面一种方法。
if(flag == TRUE)//表示flag为真
if(flag == FALSE)//表示flag为假
不错,对于许多语言,都有这两个关键字,而且FALSE被定义为0,但是只要TRUE,大多数语言都将其定义
为1,而这却没有遵循布尔类型的定义(非零表示真),这样的比较就会出现bug,比如flag=2时,就不会执行flag为真时的语句。

综上所述,布尔类型的变量和0值比较是应采用以下写法:
if(flag) //表示flag为真
if(!flag) //表示flag为假

2. 整型变量和零值的比较:
这中情况就很简单了,就是下面的写法:
if(flag != 0) //表示flag为真
if(flag == 0) //表示flag为假

3. 浮点数与零值的比较:
对于浮点数与零值的比较,就相对复杂一些。因为计算机表示浮点数都有一个精度限制。对于超出了精度限制的浮点数,计算机
会把它们的精度之外的小数部分截断。因此,本来不相等的两个浮点数在计算机中可能就变成相等的了。
float a = 2.111111112;
float a = 2.111111118;
理论上,这两个数是不相等的,但是在32为机器上是相等的(原因:在32位机器上,float保留6为小数)。
所以,对于浮点数比较,是这样规定的:如果两个同符号浮点数之差绝对值销毁或等于某一个可接受的误差(即精度),就认为
它们是相等的,否则就是不相等的。至于精度应根据具体要求而定。而不要直接用“==”或“!=”对两个浮点数进行比较
float sub = 0.0000001f;//自定义的精度
if(abs(a - b) <= sub);//表示a == b;
if(abs(a - b) > sub);//表示a != b;
而与零值的比较,当然就是下面的写法了:
if(abs(a) <= sub);//表示a == 0;
if(abs(a) > sub);//表示a != 0;

注意:在实际的编程环境中,如果直接比较浮点数和另一个数(整型或浮点数)是否相等(==)或不等(!=),可能产生错误。
至于其结果,可能依赖于具体的编译环境和平台,因为每一个编译平台都有自己默认的精度,对于浮点数直接进行==和!=比较
采用的就是这个默认的精度,而不是按照内存中两个仅有某个bit不同来判断的。
4. 指针变量与零值的比较:
指针变量的零值是“空值”(即为NULL),即不指向任何对象。
所以指针变量与零值比较的标准if语句如下:
if(p == NULL) //p为空
if(p != NULL) //p不为空
虽然NULL的值与0相同,但是两者意义不同。打开VC环境下的NULL定义:
/* Define NULL pointer value */#ifndef NULL#ifdef  __cplusplus#define NULL    0#else#define NULL    ((void *)0)#endif#endif

也就是说NULL是定义的一个宏,这样便可区分整型与0值的比较;
如果使用下面的写法:
if(p != 0) //表示flag为NULL
if(p == 0) //表示flag为NULL

当然,这样也不会错,但是我们会误以为p是整型变量。

虽然这都是一些很小的方面,但是程序中难以查找的bug往往就是出现在这些细节之处!

原创粉丝点击