[C语言]解析bool, float

一、BOOL

1、C语言bool详解

  • bool是C语言中的一个关键字,用于声明布尔类型的变量。布尔类型只有两个可能的值:truefalse
  • 在C99标准之前,C语言并没有内置的布尔类型,人们通常使用int类型,并用0表示false,非0(通常是1)表示trueC99标准引入了bool类型,以及头文件<stdbool.h>,它定义了booltruefalse

2、bool的用法和定义 

        要使用bool类型,首先需要包含头文件<stdbool.h>然后,你可以像声明其他类型的变量一样声明bool类型的变量:

#include <stdbool.h>

bool isHappy = true;  
bool isSad = false;

3、bool的基本作用

   bool类型的主要作用是提供一种更直观、更易于理解的方式来表示逻辑值。在编写条件语句时,使用bool类型的变量可以使代码更加清晰和易于理解。

4、bool与其他类型的转换

        在需要时,bool类型的值可以隐式地转换为int类型,其中false转换为0true转换为1。但是,将int类型转换为bool类型时,0会被转换为false,任何非0的值都会被转换为true

5、使用bool的注意事项

  1. 不要将bool类型的变量与整数类型混淆,尽管它们之间可以转换。
  2. 在编写条件语句时,直接使用bool类型的变量作为条件,而不要与truefalse进行比较,例如if (isHappy)而不是if (isHappy == true)
  3. 在一些旧的C编译器或环境中,可能不支持bool类型。在这种情况下,你可以使用int类型并遵循相同的逻辑约定。

6、拓展:bool类型与其“零值”比较

        在布尔逻辑的语义中,零值被视为“假”(FALSE),而任何非零值都被视为“真”(TRUE)。值得注意的是,TRUE的具体数值并没有统一的标准,它依赖于具体的编程语言或环境。例如,在Visual C++中,TRUE被定义为1,而在Visual Basic中,TRUE则被定义为-1。

        重要的是要理解,bool类型变量的本质是一个布尔表达式,用于表示与“零值”(即FALSE)的比较结果。因此,在if语句中直接使用bool类型的变量作为条件表达式,无需显式地与其“零值”进行比较。正确的if语句用法如下:

bool b;  
// 假设b已被赋予某个值  
if (b) {  
    // 如果b为真(非零),则执行此处代码  
    ...  
}  
  
// 使用逻辑非操作符"!"来检查b是否为假(零值)  
if (!b) {  
    // 如果b为假(零值),则执行此处代码  
    ...  
}

二、FLOAT

1、float的定义和用途

        float关键字用于声明一个单精度浮点变量,它能够存储带有小数的数值,且数值范围相对较广。在C语言中,float类型通常占用4个字节(32位)的内存空间,其中1位用于符号位,8位用于指数位,而剩下的23位则用于尾数位。

2、float的基本使用

        在C语言中,使用float关键字定义变量时,需要在变量名后加上“f”或“F”后缀,以明确表示这是一个float类型的常量。例如:

float a = 3.14f;
//如果不加“f”或“F”后缀,编译器可能会将其视为double类型的常量,进而可能引发类型不匹配的警告或错误。

3、float的精度问题

        float精度问题的根本原因在于计算机内部使用二进制来表示浮点数,而很多十进制小数无法完全用二进制精确表示。此外,float类型在存储时遵循IEEE 754标准,该标准将32位分为符号位(1位)、指数位(8位)和尾数位(23位),这种表示方式也限制了float的精度。

      具体来说,尾数位用于表示浮点数的小数部分,但由于只有23位,因此只能精确表示一定范围内的数字。对于超出这个范围的数字,计算机将进行舍入操作,以找到最接近的可表示数字,从而导致精度损失。

4、精度问题的举例

1、0.1无法精确表示

        在十进制中,0.1是一个简单的数字,但在二进制中,它无法精确表示。当我们尝试将0.1存储为float类型时,计算机会将其转换为最接近的二进制分数,从而导致精度损失。例如:

float a = 0.1f;  
// 输出可能不是0.1,而是类似0.100000024的近似值

2、浮点数相加产生精度损失:

        当我们将两个浮点数相加时,如果它们的小数部分无法精确表示,那么相加的结果也可能出现精度损失。例如:

float b = 0.2f;  
float c = a + b; // a为上面例子中定义的0.1f  
// c可能不是0.3,而是类似0.300000012的近似值

3、浮点数相加产生精度损失:

        在进行循环或条件判断时,如果涉及到浮点数的比较,可能会因为精度问题而导致逻辑错误。例如,在判断两个浮点数是否相等时,由于精度损失,直接使用==运算符往往不是最佳选择。

5、拓展:float类型与“零值”比较

  float​类型对应的“零值”并不是0.0​,这是由于浮点类型会丢失精度。此外,float​类型不能用==​或者!=​进行比较,只能使用<=​和>=​构建一个排除其“零值”的区间进行比较。

        如仅分析理论,在c语言的float.h​或c++的cfloat​文件中,提供了一个FLT_EPSILON​常量。该常量为1.192092896e-07F​,表示1与大于的第一个(或最小)单精度浮点数之差,即理论最小正单精度浮点数。根据该常量,我们可以写出以下语句:


#include<float.h> 
// c++ 为 #include<cfloat> 
...
float a = 某浮点数;
...
// 为"零值"
if((a >= -FLT_EPSILON) && (a <= FLT_EPSILON)){
  ...
}
// ---- and ----
// 不为“零值”
if((a <= -FLT_EPSILON) || (a >= FLT_EPSILON)){
  ...
}

        此外,double类型也有同样的极限常量,为DBL_EPSILON​,同样可从float.h​或cfloat​文件引入,在此不做赘述。

       实际过程中,需要具体情况具体分析,还要考虑读数的测量误差等问题,而非简单用数学极限去排除“零值”。比如一个表示测量水桶水位的浮点读数,假设当水桶水空的时候,再往里面加水,此时我们如果用FLT_EPSILON​去比较就不太合理了。

6、拓展:指针变量与其“零值”比较

指针变量的零值是“空”(记为NULL​),在C语言和C++中,NULL​的定义并不相同。

//在C语言中,习惯将NULL定义为void*指针值0:
#define NULL (void*)0 


//在C++中,NULL却被明确定义为整常数0:
// wchar.h中定义NULL的源码  
#ifndef NULL
#ifdef __cplusplus
#ifndef _WIN64
#define NULL 0
#else
#define NULL 0LL
#endif  /* W64 */
#else
#define NULL ((void *)0)
#endif
#endif


        在C++11以下的版本中,指针变量与其“零值”的比较,实质上就是指针变量与NULL​的比较,而在C++11以上的版本中,由于nullptr的引入,统一了C语言和C++的差异,如下:

//----------------C++ 11 以下--------------------
char* c;
if(c == NULL){
  ...
}
// ---- and ----
if(c != NULL){
  ...
}

//----------------C++ 11 以上--------------------
char* c;
if(c == nullptr){
  ...
}
// ---- and ----
if(c != nullptr){
  ...
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值