不同类型的变量与零究竟是如何比较

我们大多数见到的都是整型与 0 比较

很少见到 bool 类型与 0 比较

float 类型与 0 比较

指针类型与 0 比较

那么本期 阿紫 带领大家一起学习一下


 目录

1、什么是表达式、什么是语句

 1.1什么是表达式

 1.2什么是语句  

2.判断语句 是如何执行的

1.1  if 

1.2 单分支

1.3多分支

1.4嵌套 

3.bool 变量与”零值”进行比较

3.1 C语言中有没有bool类型? 

3.2 bool类型的变量占几个字节?

3.3 bool值与0比较如何比较?

4.float 变量与”零值”进行比较  

4.1两个浮点数是否可以进行相等比较 

4.2那么两个浮点数该如何比较呢? 

4.3 float 变量与 0 比较

5.指针变量与“零值”进行比较

5.1表示0的方法 

5.2指针变量与零比较

6.else 到底与哪个 if 配对呢? 


1、什么是表达式、什么是语句

 1.1什么是表达式

  • C语言中,用各种操作符变量连起来,形成有意义的式子,就叫做表达式 。例如:a = b + c

 1.2什么是语句  

  • 在表达式后面加上一个分号,就形成了一个语句 。例如:a = b + c;
  • 当然也不仅仅只有表达式后面加了分号的语句,还有类似与输入 输出 函数调用 等等语句例如:scanf(“%d”,&a);  printf(“%d”,a); add(a,b);
  • 只有一个分号  ;  的叫做 空语句
  • C语言中,用一对大括号 {} 括起来的多条语句称为复合语句复合语句在语法上被认为是一条语句

注:大家只用记住语句是由分号结尾即可,除了复合语句 


2.判断语句 是如何执行的

1.1  if

图片[1] - 不同类型的变量与零究竟是如何比较 - MaxSSL

 首先执行表达式,表达式的值为执行 if 里面的语句,为不执行

 1.2 单分支

图片[2] - 不同类型的变量与零究竟是如何比较 - MaxSSL

 首先执行表达式,表达式的值为执行 if 里面的语句1,为执行else 里面的 语句2

 1.3多分支

 图片[3] - 不同类型的变量与零究竟是如何比较 - MaxSSL

首先判断表达式1,表达式1的值为执行 if 里面的语句1,为则判断else if 里面的表达式2表达式2的值为则执行else if 里面语句2,为则执行 else 里面的语句3

1.4嵌套 

 图片[4] - 不同类型的变量与零究竟是如何比较 - MaxSSL

首先判断表达式1,表达式1的值为执行 if 里面的语句1 然后判断里面的表达式x ,表达式x执行语句x,表达式x假执行语句y 。表达式1则判断else if 里面的表达式2表达式2的值为则执行else if 里面语句2表达式2则执行 else 里面的语句3

 结论:

  1.  if 语句执行,先执行完成表达式的值,得到逻辑结果,在进行判定
  2. C中0表示假,非0表示真 

3.bool 变量与”零值”进行比较

3.1 C语言中有没有bool类型? 

思考:C语言中有没有bool类型? 

答案:c99 之前没有 bool 类型,主要是 c90 没有。但 c99 引入了_Bool 类型(_Bool 是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了 bool,为了保证C/C++兼容性)。

图片[5] - 不同类型的变量与零究竟是如何比较 - MaxSSL

bool 是一个真假类型:true 为真,false 为假 

3.2 bool类型的变量占几个字节?

图片[6] - 不同类型的变量与零究竟是如何比较 - MaxSSL

上面测试中,我们可以看出 bool 类型的变量占一个字节 。

图片[7] - 不同类型的变量与零究竟是如何比较 - MaxSSL

小伙伴看到这可能就疑惑了,为什么大写的 BOOL 、TRUE 也可以运行,而且它的大小还是四个字节呢?那我们转到它的定义看看 

图片[8] - 不同类型的变量与零究竟是如何比较 - MaxSSL

现在我们就知道为什么大写 BOOL 类型的变量占四个字节了,因为在源代码中,是这么定义的:typedef  int   BOOL;

注:这都是 Microsoft 自己搞的一套BOOL值。在vs中转到BOOL对应的头文件,翻到最上面,就能看到微软的版权信息。使用 BOOL 需要添加 #include 头文件。

我们一般写代码不仅仅是需要在自己使用的平台可以使用,还需要在其他平台可以使用,所以这就涉及到了跨平台,而 Microsoft 定义的专属类型,其他平台不支持,所以也就不支持使用

总结:

  1. 优先使用c90,就是我们之前以及后面一直用的方式(虽然c90并不支持 bool 类型,但它可以用整型表示真和假 ,0 为假 、非 0 为真)
  2. 万一非得使用bool,推荐c99标准,不推荐MS自定义。  

 3.3 bool值与0比较如何比较?

#include#includeint main(){bool a = true;if (1 == a){printf("1\n");}if (true == a){printf("2\n");}if (a)//推荐{printf("3\n");}return 0;}

为什么推荐第3个 if 的写法呢?

答: a 本身就是是一个 bool 类型的值,本来就代表的真或假。

结论:bool类型,直接判定,不用操作符进行和特定值比较


4.float 变量与”零值”进行比较  

我们知道浮点数在内存中存储,可能会有精度损失(注:这里的损失,不是一味的减少了,还有可能增多,浮点数本身存储的时候,在计算不尽的时候,会“四舍五入”或者其他 策略

图片[9] - 不同类型的变量与零究竟是如何比较 - MaxSSL

4.1两个浮点数是否可以进行相等比较 

从下面的图片代码中可以看出 x=1.0y=0.1,那么进行 if 表达式判断时 x – 0.9 应该等于 0.1 ,0.1 y 相等应当打印 1,但却打印了 0 ,这是为什么了?

图片[10] - 不同类型的变量与零究竟是如何比较 - MaxSSL

那我们接下来,来看看打印 x-0.9  0.1 打印的究竟是什么?  

原来内存中 x – 0.9 并不等于 0.1,而是精度损失了,而 y 也不是0.1,也精度损失了,所以上面代码的才没有打印 1

图片[11] - 不同类型的变量与零究竟是如何比较 - MaxSSL

结论:因为精度损失问题,两个浮点数,绝对不能使用==进行相等比较 

4.2那么两个浮点数该如何比较呢? 

应该进行范围精度比较 

图片[12] - 不同类型的变量与零究竟是如何比较 - MaxSSL

注:fabs是浮点数求绝对值 

如何设置精度? 

  1. 自己用宏定义设置 
  2. 使用系统精度 

1.自己用宏定义设置精度 

图片[13] - 不同类型的变量与零究竟是如何比较 - MaxSSL

2.使用系统精度  

图片[14] - 不同类型的变量与零究竟是如何比较 - MaxSSL

4.3 float 变量与 0 比较

#include#include#includeint main(){float x = 0.000000000000001f;//当数值足够小时,会被判断为0//if (fabs(x) < DBL_EPSILON)if (fabs(x-0) < DBL_EPSILON){printf("1\n");}else{printf("0\n");}return 0;}

5.指针变量与“零值”进行比较

5.1表示0的方法 

 我们之前学习过 数字0、转义字符 \0、空 NULL,它们也都可以表示0

图片[15] - 不同类型的变量与零究竟是如何比较 - MaxSSL

 我们可以转到NULL定义,可以看到其实NULL就是0

图片[16] - 不同类型的变量与零究竟是如何比较 - MaxSSL

 5.2指针变量与零比较

图片[17] - 不同类型的变量与零究竟是如何比较 - MaxSSL


6.else 到底与哪个 if 配对呢? 

1.这个代码总是让人感觉它与第一个 if 匹配,其实它跟第二个 if 匹配,因为 else 采取的是就近原则,所以这个代码什么也都不打印

#includeint main(){int x = 0;int y = 1;if (10 == x)if (11 == y)printf("hi\n");elseprintf("hello\n");return 0;}

2.这个才是正确的代码风格,一看就知道 else 与哪个 if 匹配

#includeint main(){int x = 0;int y = 1;if (10 == x){if (11 == y){printf("hi\n");}}else{printf("hello\n");}return 0;}

为什么 不写成 x==10,而写成10 == x?

答:因为这样写可以避免把==写成=,如果不小心写成=,我们知道赋值号的左边必须是变量,所以这属于语法错误,编译器会提示,那要是不小心写成了 x = 10,这就属于运行错误系统不会提示。 

由此可知良好的编程风格对编程者是多么重要,养成良好的编程习惯,从你我做起 

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享