那些类型与0的关系

183 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

那些类型与0的关系

前言

本文主要介绍一下布尔类型和0的关系、指针类型和0的关系以及浮点类型与0的关系;

一、布尔类型与0的关系?

在此之前,请大家猜一下在C语言中是否存在bool类型? … 答案是:

image.png

没有的!!!😁😁😁But, 在C90和C89中是没有布尔类型的,目前大多数书都是认为没有的,因为书本一般都是落后于行业的;而在最新的C99标准中引入了_Bool的类型,是的你没有看错,_Bool就是一个类型,只不过呢,为了和C++兼容呢,_Bool被用宏重新定义在了<stdbool.h>文件里面了;就像这样:

image.png

既然bool是一个类型,我们就应该关心一下它的大小;
于是我们请来了sizeof来帮我们计算一下一个bool类型在内存中的空间大小;

image.png

大小是一个字节,理论上呢?表示真假,一个字节也就够了,但是不同的编译器会有所差异,但是呢,VS2019默认是一个字节; 前文做了这么多铺垫,接下来我们对于bool类型与0的关系一定有了稍微的认识; 在C90之前呢,没有bool类型,于是我们就用0表示假,非0表示真; 在C99标准中呢,由于具有了bool类型, 我们就用false表示0也就是假; true表示1也就是真;

总结

1、在可以不使用bool类型的条件下,我们优先使用C90标准下的0表示假,非0表示真; 2、如果非要使用bool类型,推荐使用C99标准下的bool类型,不建议使用编译器自带的bool类型,因为这是编译器平台字节写的,在其它平台下就无法识别了,可移植性较差;

二、指针类型和0的关系

在实际表示空指针中,我们有以下两种写法:

image.png

首先这两种写法,语法上是没有问题的,编译器也没有报错,编译器上能跑过去;但是呢这样的代码风格不好,因为对于’=’ , ‘-’ , ‘*’ , '/'等操作符来说,他两边的操作数应该是一样类型的;就比如这样:

image.png

我们都知道,表达式num1+num2;在相加的时候,num1会发生隐式转换,会先转换成double型,最后在进行运算,所以最后表达式计算结果也是double类型的; 同理,这里的int p1=0;也是如此,=左边式int**的类型,而=右边确实int型(0是int型)这看似是多么的不符常理,于是呢我们在C语言中呢

image.png

采用宏定义的方式和(强制类型转换的方式,把它转换成为指针类型(但是呢我们并没有给定死,我们用的是void*,因为开发者是不知道你会把0赋给那个类型的指针的);
这就是指针类型与0的关系,和为什么会有NULL的出现;

强制类型转换

这里既然讲到了强制类型转换,那我们就来简单的介绍一下强制类型转换的概念:所谓强制类型呢?就是不改变它在内存中的二进制方式,而是把解读它的方式给改变了,举个简单的栗子:

image.png

给你这么一个二进制序列,如果现在我用signed int的方式去解释它呢? 他被解释出来就是-1;但是现在我觉得用signed int的方式去解释它不好,于是呢,我把原来的解释方式给它强制换掉,我用unsigned int的方式去解释它,最终得到的接过就是一个超大的数,最终解释的结果就是4294967295

image.png

总结: 强制类型转换的本质就是,不改变二进制数在内存中的序列,只改变我们解释它的方式

三、浮点数类型与0的关系

为了方便起见,本文统一采用double类型的浮点类型来为大家做演示,当然也可以用float;😀😀😀 首先a我们来看一串代码a:

int main()
{
	double num1 = 1.1;
	double num2 = 1.0;
	if (num1 - num2 == 0.1)
		printf("相等\n");
	else
		printf("不相等\n");
	return 0;
}

大家可以思考一下,你们认为相等还是不相等? … 经过我们的运行显示:

image.png

答案是不相等;为什么?时不时很诧异?难道1.1-1.0不等于0.1吗?难道我数学学错了?答案其实并不是这样,我们的想法是对的,是计算机的问题; 为了更方便的向大家解释,我们来看看num1-num2的结果的后50位和0.1的后50位:

image.png

我们发现好像不一样唉,前面十几位还正常,越到后面就越不正常了; 这是为什呢?这主要与十进制小数转二进制小数有关 方法是:小数部分乘2,取整数部分,直至小数点后为0 但是有的小数乘2以后,小数部分一直无法得到0,如0.333333。这种只需要到一定的精确度就行了。这就会造成我们的精度丢失;也是造成num1-num2与0.1不相等的“罪魁祸首”; 于是呢对于两个浮点数的比较,我们不能像整型那样简单的认为用==就可以了,我们应该用num1-num2的值与0.1的差值的绝对值与一个精度比较,只要他们之间的误差在这个精度的范围之内,我们都可以认为num1-num2与0.1近似相等; 这个精度呢?我们可以自己定义,比如:

#include<math.h>
#define EPS 0.0000000000001
int main()
{
	double num1 = 1.1;
	double num2 = 1.0;
	if (fabs((num1 - num2) - 0.1) < EPS)
		printf("近似相等\n");
	else
		printf("不相等\n");

	return 0;
}

当然我们也可以利用编译器给我们提供的精度:

#include<math.h>
#include<float.h>
int main()
{
	double num1 = 1.1;
	double num2 = 1.0;
	if (fabs((num1 - num2) - 0.1) <DBL_EPSILON)
		printf("近似相等\n");
	else
		printf("不相等\n");

	return 0;
}

编译器对于最小精度的解释

image.png

总结:

对于浮点数之间的比较,绝对不能用来完成,而应该二者之差的绝对值和最小精度进行比较,如果符合最小精度,则关系可以判定为相等;否则,反之; 于是呢?对于和0.0这个特殊的浮点数作比较我们直接这样写就好了:

image.png

总结

好了,文章到此就结束了,如果你觉得写的还不错的话,记得给博主一个一键三联哦;其中有不足的地方,欢迎大家指正!!!😁😁😁