几大类型与零值的较量

零值的的作用体现,你真的知道了吗?

下面的代码来自《C深度剖析》一书中,提取码:CSDN

一、bool与0比较

bool的简单介绍

学了这么久C语言,你在一些学校的C教材上面看到过bool类型定义的变量吗?这主要是因为书一般要落后与行业的,bool类型主要是在c99标准新加的,像以前的c89,c90标准是没有的。
C99引入了_Bool类型(不过在头文件stdbool.h中,被宏定义成bool而已,为了保证c/c++的兼容)

bool

下面是bool的定义,我们可以看到 _Bool是被宏定义成了bool,而0.1也被定义成false,true
注意:这里的 bool false true 都是小写哟,为什么是小写,请继续往下看

在这里插入图片描述

因为bool类型的两个值:true,false都是有数字0.1重定义的,所以只需要1bit就够了,而计算机的基本单位是字节,所以bool变量的大小就是1字节了

//测试代码1 
#include <stdio.h> 
#include <stdbool.h> //没有这个头文件会报错,使用新特性一定要加上 
int main() 
{ 
	bool ret = false; 
	ret = true; 
	printf("%d\n", sizeof(ret)); // vs2013 和 Linux中都是1 
return 0; 
}

BOOL

上面我们刚刚演示了bool类型,那这里的BOOL又是什么呢?小写bool是C99标准中添加的;而大写BOOL则是我们VS编译器自造的一个类型(只有在VS底下才能用,和之前博主写的scanf_s与scanf区别一样),所以博主推荐大家使用C语言标准里面的,这样的代码的移植性好

在这里插入图片描述

上面我们也能看到BOOL是int的别名而已,所以BOOL的变量大小必定也是 4字节且只有VS可用

//在vs中,看看下面的代码 

//测试代码2 
#include <stdio.h>
int main() 
{ 
	//在vs中,光标选中BOOL,单击右键,可以看到转到定义,就能看到BOOL是什么 
	BOOL ret = FALSE; 
	ret = TRUE; 
	printf("%d\n", sizeof(ret)); 
	return 0; 
}

bool与0

由于C90不支持bool,而C99支持bool,下面两个对照着来看:
推荐:bool直接判定,不用操作符进行和特定值比较。

#include <stdio.h> 
#include <stdbool.h> 
int main() 
{ 
	int pass = 0; //0表示假,C90,我们习惯用int表示bool 
	//bool pass = false; //C99 
	if (pass == 0)
	{ 
		//理论上可行,但此时的pass是应该被当做bool看待的,==用来进行整数比较,不推荐 
		//TODO 
	}
	if (pass == false)
	{ 
		//不推荐,尽管在C99中也可行 
		//TODO 
	}
	if (pass)
	{ 
		//推荐 
		//TODO 
	}

	if (!pass)
	{
		//推荐 
		//TODO 
	}
	//理论上可行,但此时的pass是应该被当做bool看待的,==用来进行整数比较,不推荐 
	//另外,非0为真,但是非0有多个,这里也不一定是完全正确的 
	if (pass != 1)
	{ 
		//TODO 
	}
	if (pass != true)
	{ 
		//不推荐,尽管在C99中也可行 
		//TODO 
	}
	
	return 0;
}

小总结

  1. 优先使用c90,就是我们之前以及后面一直用的方式
  2. 万一非得使用bool,推荐c99标准,不推荐MS自定义。

二、float与0比较

float的内存存储方式

float的讲解需要了解float变量在内存的存储布局
可以看一下博主的另外一篇博客了解一下:深度剖析数据的存储

float的精度损失

浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。
注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会“四舍五入”或者其他 策略

在这里插入图片描述
在这里插入图片描述

浮点数存储有精度损失的话,那么我们用float类型的变量进行 == 比较的时候,就不会相等了。

在这里插入图片描述

float类型的数据比较

精度的定义:

  1. 自己宏定义一个很小的数字
  2. 使用系统定义好的
    1. #include<float.h> //使用下面两个精度,需要包含该头文件
    2. DBL_EPSILON //double 最小精度
    3. FLT_EPSILON //float 最小精度
if((x-y) > -精度 && (x-y) < 精度)
{ 
	//TODO 
}

//伪代码-简洁版 
if(fabs(x-y) < 精度)
{ 
	//fabs是浮点数求绝对值 
	//TODO 
}

在这里插入图片描述

float与0的比较

了解了上面的内容,看下面的就很容易理解了

#include <stdio.h> 
#include <math.h> 
#include <float.h> 
int main() 
{ 
	double x = 0.00000000000000000000001; 
	//if (fabs(x-0.0) < DBL_EPSILON){ //写法1 
	//if (fabs(x) < DBL_EPSILON){ //写法2 
	if(x > -DBL_EPSILON && x < DBL_EPSILON)
	{ 
		//书中写法 
		printf("you can see me!\n"); 
	}
	else
	{
		printf("oops\n"); 
	}
	return 0; 
}

小总结

  • float不能直接用操作符进行比较大小,需要判断两个数的差的fabs是否小于定义的最小值
  • 与最小值的比较的时候不能带 = 等于号
    • fabs(x) <= DBL_EPSILON(确认x是否是0的逻辑),如果=,就说明x本身,已经能够引起其他和他±的数 据本身的变化了,这个不符合0的概念。

三、指针与0比较

三种零值:

  1. 0
  2. ‘\0’
  3. NULL
int main()
{
	int* ptr = NULL;  // 只是为了给我们看的时候,一下子就知道 ptr是个指针变量而已
	if(0 == ptr)
	{
	}
	
	if(p) // 容易误认 p 为 bool类型变量
	{
	}
	// 推荐:看到这样的代码就知道ptr是一个指针 
	if(NULL != ptr)
	{	
	}
}

总结

  1. bool类型在C里面一般还不怎么用,C里面表示真假一般使用 0 与 非0
  2. 浮点数比较要采用特殊的方法,不能直接比较
  3. 指针变量判断为空,用NULL判断,最好不要用 0

欢迎大家有问题私信博主,我也希望你们看完后也能有所收获,也可以给个一键三连哟

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值