C语言数据类型与“0值”的比较

简介: 目录1.bool变量与“0值”进行比较 1.1 bool类型介绍 1.2 bool和0比较2.浮点数与“0值”进行比较 2.1 浮点数之间的比较 2.2 浮点数和0比较3.指针变量和“0值”的比较 3.1 引言 3.2 指针和0比较

1.bool变量与“0值”进行比较

                 1.1  bool类型介绍

问题:C语言有没有bool类型?


一:c89或c90没有_bool类型//c99引入了_Bool类型


二:(细谈)c99之前,主要是c90是没有的,目前大部分书,都是认为没有的。因为书,一般都要落后于行业。 但是c99引入了_Bool类型(你没有看错,_Bool就是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了 bool,为了保证C/C++兼容性)。


C语言中我们都清楚0表示假,非0表示真


可bool类型用的是true和false来表示真假


测试代码一:(此代码用VS2013进行编译的,所以有#include <windows.h>和system("pause");)

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

//查看源码:

#define bool _Bool //c99中是一个关键字哦,后续可以使用bool
#define false 0 //假
#define true 1 //真

PS:理论上,表示真假,需要一个bit就够了,不过这个问题,还是要取决于编译器的理解。vs2013中认为是1个字节。


but!!

//测试代码2:

#include <stdio.h>
#include <windows.h>
int main()
{
//在vs中,光标选中BOOL,单击右键,可以看到转到定义,就能看到BOOL是什么
BOOL ret = FALSE;
ret = TRUE;
printf("%d\n", sizeof(ret)); //输出结果是4,因为在源代码中,是这么定义的:typedef int BOOL;
system("pause");
return 0;
}

我们发现,竟然也能编过。。。什么鬼??


这都是Microsoft自己搞的一套BOOL值。在vs中转到BOOL对应的头文件,翻到最上面,就能看到微软的版权信息。 好了,该听谁的??


微软?强烈不推荐,大写的BOOL是微软的标准,跨平台性太差,可移植性较差,测试代码1在VS2013和Linux都可以编过,可代码2只能在VS2013中通过,Linux不行


所以,后面万一要用bool,强烈推荐C99标准的,摒弃微软


                 1.2  bool和0比较

通过代码解释:

#include <stdio.h>
#include <stdbool.h>
#include <windows.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
}
//理论上可行,但此时的pass是应该被当做bool看待的,==用来进行整数比较,不推荐
//另外,非0为真,但是非0有多个,这里也不一定是完全正确的
if (pass != 1)
{
  //TODO
}
if (pass != true)
{ 
  //不推荐,尽管在C99中也可行
  //TODO
}
if (!pass)
{
  //推荐
  //TODO
}
system("pause");
return 0;
}

2.浮点数与“0值”进行比较

                  2.1  浮点数之间的比较

精度损失:


浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。


注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会“四舍五入”或者其他策略


例如:

#include<stdio.h>
int main()
{
  double d = 3.6;
  printf("%.50f\n", 3.6);
  return 0;
}

image.png比较过程:(先看代码)

#include<stdio.h>
int main()
{
  double x = 1.0;
  double y = 0.1;
  printf("%.50f\n", x - 0.9);
  printf("%.50f\n", y);
  if ((x - 0.9) == 0.1)
  {
    printf("you can see me!\n");
  }
  else
  {
    printf("oops!\n");   // oops!
  }
  return 0;
}

image.png//浮点数在进行比较的时候绝对不能直接用==来进行比较!!!!

//浮点数本身有精度损失,进而导致各种结果可能有细微的差别。

解决方法:!!

法一:

伪代码:

if((x-y) > -精度 && (x-y) < 精度)
{
    //TODO
}

正式代码:这里采用自定义EPSION来定义精度范围

#include<stdio.h>
#define EPSION 0.00000000001
int main()
{
  double x = 1.0;
  double y = 0.1;
  if (((x - 0.9) - y) > -EPSION && ((x - 0.9) - y) < EPSION)
  {
    printf("you can see me!\n");
  }
  else
    printf("oops!\n");
  return 0;
}

法二:使用绝对值的方法解决这个问题

伪代码版本:

if(fabs(x-y) < 精度)
{
    //fabs是浮点数求绝对值
    //TODO
}

正式代码:

#include<stdio.h>
#include<math.h>
#include<float.h>
int main()
{
  double x = 1.0;
  double y = 0.1;
    if (fabs((x - 0.9) - y) < DBL_EPSILON)
  {
      printf("you can see me!\n");
    }
  else
      printf("oops!\n");
  return 0;
}

  2.2  浮点数和0比较

既然知道了浮点数之间的比较,那么将其中一个浮点数转换为0,就相当于是浮点数和0的比较


// 比较a和b,则需要按照下列进行比较


// fabs(a - b) < DBL_EPSILON)


// 比较a和0,可以将上述代码中的b转换为0,如下:


// fabs(a) < DBL_EPSILON)


// 说明只要满足上述代码要求,就可以说明a和0是相等的

#include<stdio.h>
#include<math.h>
#include<float.h>
int main()
{
  double x = 0.00000000000000000000000000001;
  //法一:
  /*if (fabs(x) < DBL_EPSILON)
  {
    printf("you can see me! x==0.0\n");
  }
  else
  {
    printf("oops!\n");
  }*/
  //法二:
  if ((x > -DBL_EPSILON) && (x < DBL_EPSILON))
  {
    printf("you can see me! x==0.0\n");
  }
  else
  {
    printf("oops!\n");
  }
  return 0;
}

/*问题:要不要带等号?

//不带: if ((x > -DBL_EPSILON) && (x < DBL_EPSILON))

// 带: if ((x >= -DBL_EPSILON) && (x <= DBL_EPSILON))

XXX_EPSILON是最小误差,但是:XXX_EPSILON+n不等于n的最小的正数。

 不能带=

 若fabs(x) == DBL_EPSILON

 则double y + x != y;

 且double y + DBL_EPSILON != y;

 但是y + 0.0 == y;这才是正解

 如果带了等号,就说明x本身,已经能够引起其他和他+-的数据的本身的变化了,这个不符合0的概念

 所以以后不要写等号*/

3.指针变量和“0值”的比较

                  3.1  引言

看代码:

#include<stdio.h>
int main()
{
  //类型是不同的
  printf("%d\n", 0);      //0 
  printf("%d\n", '\0');   //0
  printf("%d\n", NULL);   //0
  int a = 0;
  char* p = NULL;
  //这里NULL的值是0是因为发生了强制类型转换
  //  如何理解强制类型转换?
  //  需要编写算法,或使用相关库函数
  //  "123456"  -> int: 123456  
  //  "123456" 7 字节 int 类型 4 字节 //真实转换
  return 0;
}

//    ******真实的转换会改变内存当中的数据 ******

//    ******强制类型转化不改变内存中的数据,只改变对应的类型***

                  3.2  指针和0比较

#include<stdio.h>
int main()
{
  int* p = NULL;
  //if (p == NULL) 不推荐
  //if (NULL == p) 推荐
  return 0;
}
相关文章
|
1月前
|
存储 安全 C语言
C语言中的数据类型
C语言中的数据类型
|
1月前
|
存储 C语言
C语言数据类型、变量和运算符以及printf相关问题
C语言数据类型、变量和运算符以及printf相关问题
|
9天前
|
存储 C语言 索引
C 语言数据类型详解
C语言中的数据类型主要包括基本数据类型、构造数据类型和用户定义数据类型。基本类型如整型(`int`)、字符型(`char`)、浮点型(`float`)、双精度浮点型(`double`)和无符号整型(`unsigned int`)。构造类型包括数组(`Array`)、结构体(`Struct`)、共用体(`Union`)和枚举(`Enum`)。用户定义类型则通过`typedef`为已有类型定义新名称,并可通过结构体和共用体自定义复合数据结构。此外,还有指针类型用于存储变量地址,以及`signed`、`unsigned`、`short`、`long`等类型修饰符。
42 11
|
8天前
|
存储 C语言
【C语言基础考研向】02 数据类型-常量-变量
本文介绍了编程中的基本概念,包括数据类型分类、常量与变量的定义及使用。首先概述了四大类数据类型:基本类型(整型、浮点、字符型)、构造类型(数组、结构体)、指针类型和空类型。接着阐述了常量与变量的区别及命名规则,并详细说明了整型、浮点型和字符型数据的特点与应用。最后总结了常见的易错点,如字符串与字符常量的区别及浮点数的默认输出格式。
|
10天前
|
存储 编译器 程序员
c语言基本数据类型详解
在 C 语言中,基本数据类型用于存储不同类型的数据,并在内存中分配不同大小的空间,如 `char`(1 字节)、`int`(4 字节)、`short`(2 字节)、`long`(4 或 8 字节)、`float`(4 字节)和 `double`(8 字节)。此外,还有 `void` 和用 `int` 类型替代的 `bool` 类型。这些数据类型的存储空间大小可能因编译器和平台的不同而有所变化,但通常遵循上述规则。选择合适的数据类型可以充分利用内存空间并确保数据准确性。C 语言还支持用户自定义数据类型,如结构体和枚举类型,用于描述复杂的数据结构。
|
11天前
|
C语言
C语言程序设计核心详解 第二章:数据与数据类型 4种常量详解 常见表达式详解
本文详细介绍了C语言中的数据与数据类型,包括常量、变量、表达式和函数等内容。常量分为整型、实型、字符型和字符串常量,其中整型常量有十进制、八进制和十六进制三种形式;实型常量包括小数和指数形式;字符型常量涵盖常规字符、转义字符及八进制、十六进制形式;字符串常量由双引号括起。变量遵循先定义后使用的规则,并需遵守命名规范。函数分为标准函数和自定义函数,如`sqrt()`和`abs()`。表达式涉及算术、赋值、自增自减和逗号运算符等,需注意运算符的优先级和结合性。文章还介绍了强制类型转换及隐式转换的概念。
|
1月前
|
C语言
C语言------数据类型与输入输出
这篇文章是C语言的数据类型与输入输出实训教程,通过示例代码演示了整型、实型、字符型数据的定义、使用和输出,以及如何使用printf()和scanf()函数进行格式化输出和输入。
C语言------数据类型与输入输出
|
1月前
|
存储 编译器 C语言
【C语言篇】C语言数据类型和变量
我们使⽤强制类型转换都是万不得已的时候使用,如果不需要强制类型转化就能实现代码,这样⾃然更好的.
|
1月前
|
C语言
C语言数据类型和变量
C语言数据类型和变量
31 5
|
3月前
|
存储 C语言
二:《初学C语言》— 数据类型和变量
本篇文章详细介绍了C语言的数据类型和变量,数据类型是C语言中最基础的内容,也是必须要清楚的知识点
45 8
二:《初学C语言》—  数据类型和变量