第6讲-C语言关键字(6)

本文介绍了C语言中浮点数与0比较的细节,通过代码示例展示了如何使用fabs和DBL_EPSILON判断极小浮点数是否等于0。同时,讨论了类型转化,包括'0'、NULL的区别以及强制类型转化的原理。还涉及了if-else语句的就近原则和如何避免scanf引起的报错。最后,简要提及了switch-case语句的基本使用。
摘要由CSDN通过智能技术生成

接着上节课的最后,上节课的最后我们讲了浮点型数据和0的比较,接下来,我们写一串代码来实现这个步骤

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<float.h>
int main()
{
	double a = 0.00000001;
	if (fabs(a) < DBL_EPSILON)
	{
		printf("you can see it   a=0  \n");
	}
	else
	{
		printf("obbs\n");
	}
	return 0;
}

其中,头文件#include<math.h>对应的是fabs,fabs是求浮点型数据的绝对值,头文件#include<float.h>对应的是DBL_EPSILON,DBL_EPSILON的意思是系统对应的double类型的精度,我们进行编译

 这里没有执行if语句的原因是:double类型的a不够小,我们进行调整一下

#include<stdio.h>
#include<math.h>
#include<float.h>
int main()
{
	double a = 0.000000000000000000000000001;
	if (fabs(a) < DBL_EPSILON)
	{
		printf("you can see it   a=0  \n");
	}
	else
	{
		printf("obbs\n");
	}
	return 0;
}

我们进行编译,

接下来,我们来分析一个案例

#include<stdio.h>
#include<math.h>
#include<float.h>
int main()
{
	double x = 0.000000000000000000000000001;
	if (x > -DBL_EPSILON&&x < DBL_EPSILON)
	{
		printf("you can see it   a=0  \n");
	}
	else
	{
		printf("obbs\n");
	}
	return 0;
}

这串代码和上一串代码不同的就是判断条件,这里我们要思考的问题是:判断条件x > -DBL_EPSILON&&x < DBL_EPSILON中的大于和小于能改成大于等于或小于等于吗?

答:不能,解释如下

首先,我们看系统给的精度DBL_EPSILON的定义

 总结就是:DBL_EPSILON是最小的值,最小的能让1.0和它的和的结果大于1.0的值

所以假如我们的x等于了这个最小的值,0的定义是任何数加0的结果是它本身,而这个最小的值和1.0相加的结果大于1.0的值,所以这个最小的值就不是0,所以x就不是0,所以条件错误。

总结:不建议写等号

0和‘\0’和NULL的区别

答:首先,数值上相等

int main()
{
	printf("%d\n", 0);
	printf("%d\n", '\0');
	printf("%d\n", NULL);
	return 0;
}

编译结果

int a = 0;
	char*p = NULL;

=号是操作符,操作符两端的类型必须相等,比如int a;double b;a+b,+是操作符,操作符两端的类型不同,所以产生隐式转化

这里也是相同,p是指针,所以初始化就不要把等号右端换成0,假设我们换成0,我们进行运行

int main()
{
	
	int a = 0;
	char*p = 0;
}

 可以发现,代码并没有报错:不同的编译器下编译的结果不同

NULL是什么?

我们转到他的定义看看

我们可以发现,NULL的意思就是把0强制类型转化为指针所对应的结果,这里引出了强制类型转化

\0’是什么?

答:假如我们不带\

int main()
{
	printf("%d\n", 0);
	printf("%d\n", '0');
	printf("%d\n", NULL);
	return 0;
}

我们进行编译

 我们可以发现。‘0’对应的结果是48,为什么呢?

答:这里的0是字符0,因为字符0对应的ascii码值为48,所以打印的结果是48

强制类型转化

要理解强制类型转化,首先要理解真正的转化

真正的转化:“123456”--->整型123456,因为第一个是字符串,字符串加上\0一共七个字符,占七个字节,而整型123456无论如何都占4个字节,所以这两个在内存中的存储形式一定不同,所以真正的转化是改变数据在内存中的布局,从而实现改变

“虚假” 的转化:虚假的转化,也就是强制类型转化,例如我们写一串二进位制序列11111111 11111111 11111111 11111111,我们声明他的类型是signed int,我们会把他当成-1,假设我们将其强制类型转化为unsigned int,我们就会把他当成一个很大的数字。总结:强制类型转化并不会改变数据在内存中的存储形式,改变的是数据的类型

许多人可能有疑问:假如我们把一个double类型的数据赋给整型,是不是会改变内存中的数据

答:例如int x=(int)3.14,3.14是double类型的数据,占8个字节,把8个字节的浮点型的数据强制类型转化为四个字节的整型,发生了截断问题,但和我们本身double类型的数据3.14是没有关系的

if——else就近原则

int main()
{
	int x = 1;
	int y = 0;
	if (10 == x)
	    if (11 == x)
		printf("hello 比特");
	else
		printf("hello world");
		return 0;
}

通常的思路:变量x不等于10,所以不进入循环,执行else语句,打印hello world ,我们进行运行

我们可以发现,无结果,原因是什么?

答:因为if else执行的是就近原则,所以else对应的是第二个if,因为第一个if不满足条件,所以不进入下一个if-else语句,所以无结果 

如何避免这种错误产生呢?

我们要严格加上花括号,例如

int main()
{
	int x = 1;
	int y = 0;
	if (10 == x)
	{
		if (11 == x)
		{
			printf("hello 比特");
		}
	}
	else
	{
		printf("hello world");
	}
		return 0;
}

这时候,我们进行运行

成功打印出hello world 

如何规避scanf所引起的报错

int main()
{
	int a = 0;
	scanf("%d", &a);
	if (3 == a)
	{
		printf("3");
	}
	else
	{
		printf(".");
	}
	return 0;
}

我们进行运行

 我们要如何规避呢?下面是一种方法

答:

#pragma warning(disable:4996)

我们加上这一行代码,这里的意思是屏蔽或者忽略来自c4996的报错

第二种方法

#define _CRT_SECURE_NO_WARNINGS 1

加上这样一串代码,这是个宏定义,要写在头文件的前面。

switch case语句

首先,switch case语句和if语句都有相同的特点:判断,分支

但也有不同点:if语句能够判断的种类和条件是更丰富的,而switch语句只能判断整型

switch case语句中,case相当于判断部分,break相当于分支部分

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值