learn_C_deep_6 (布尔类型、布尔与“零值“、浮点型与“零值“、指针与“零值“的比较)
目录
语句和表达式的概念
if语句的多种语法结构
注释的便捷方法(环境vs)
if语句执行的过程
逻辑与&& 逻辑或|| 运算关系的顺序
else的匹配原则
C语言有没有布尔类型
C99标准
sizeof(bool)的值为多少?
_Bool原码
BOOL、TRUE、FALSE
sizeof(BOOL)的值为多少?
BOOL与bool的区别
“零值”的比较
1.bool变量与“零值”比较
2.float、double变量与“零值”比较 - (这里以double为例)
3.指针变量与"零值"比较
语句和表达式的概念
C语言中由一个分号;隔开的就是一条语句
printf("Hello!\n");
1+2;
C语言中,用各种操作符把变量连接起来,形成有意义的式子,就叫做表达式
1+2
if语句的多种语法结构
1.if语句
if(表达式) 语句;
2.if - else语句
if(表达式) 语句1; else 语句2;
3.if - else if - else语句
//多分支 if(表达式1) 语句1; else if(表达式2) 语句2; else 语句3;
注释的便捷方法(环境vs)
1.先按ctrl + k,再按ctrl + c
2.采用if(0)注释 -- 不推荐
同时我们还可以从上面得出一个结论:非0为真,0为假
if语句执行的过程
#include<stdio.h>
int main()
{
int flag = 1;
if (flag == 1)
printf("hello world\n");
return 0;
}
#include<stdio.h>
int isEmpty()
{
printf("某种数据结构是否为空!\n");
return 1;
}
int main()
{
if ((isEmpty()) == 1)
printf("yes\n");
return 0;
}
1.先执行()中的表达式或者函数,得到真假结果
2.条件 判定功能
3.进行 分支功能
逻辑与&& 逻辑或|| 运算关系的顺序
总结:从左到右。
else的匹配原则
我们来看看下面的代码运行结果是啥?
相信我们很多人看到这里,由于x等于0,而不等于10,所以来到else打印hello yesterday!但其结果其实是什么也不打印,这里是因为else是与离他最近的if匹配的,由于x不等于10,所以里面的if-else语句没有执行,所以也就不会打印啦。我们来验证一下,在与if(x==0)后面加一个与之匹配的else语句。
总结:以后写if_else时,建议带上{ },这样不仅不容易出粗,而且代码的可观性也比较好。
再来看一个代码
#include<stdio.h>
int main()
{
int flag = 0;
if (flag == 1);
{
printf("why you can see me?\n");
}
return 0;
}
C语言有没有布尔类型
bool 类型只有两个值:true 和 false。上面我们写的if()语句中非0为真,0为假,是因为C语言没有提供bool类型,而且我们也知道if()只有是条件表达式为真我们才执行,所以我们一般都写if(1),而不写if(true)。
当我们写if(true)或者定义bool类型的变量时,编译器也提示出来为定义的标识符,说明编译器不认识它们,证明C没有提供bool类型。
C99标准
但其实C语言时是有bool类型的,只不过我们编译器目前采用的是C89 or C90的标准,而在C99中引入了_Bool类型,它是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了bool,为了保证C/C++兼容性。引入头文件stdbool.h,程序就没有错误了。
sizeof(bool)的值为多少?
在 C 语言标准中,bool 类型是由 stdbool.h 头文件引入的。bool 通常被定义为枚举类型,其中 false 的值为 0,true 的值为 1。因此,sizeof(bool) 的值在 C 语言标准中并没有规定。 一般情况下,sizeof(bool) 的大小应该是 1 字节,因为 bool 类型只需要存储一个二进制位(0 或 1)来表示 true 或 false。但是,具体的实现方式可能会因编译器和操作系统的不同而有所不同。
_Bool原码
BOOL、TRUE、FALSE
#include<stdio.h>
#include<windows.h>
int main()
{BOOL x = TRUE;x = FALSE;
}
这里的BOOL实际上是一个重命名 - typedef int BOOL; 这里我们可以证明一下
sizeof(BOOL)的值为多少?
BOOL与bool的区别
我将BOOL转到定义后,发现开头有这么一串注释,这样他们的区别就很明显了。
由上面的图片可以得到,BOOL是微软帮我们设计的,我们只能在微软的对应的开发工具才能使用BOOL,BOOL是微软的标准(不推荐,可移植性较差),而bool是通用的。
总结:
1.优先使用C90,就是我们之前用的非0为真,0为假。
2.一定要使用bool类型,优先使用bool,不推荐BOOL(可移植性较差)。
“零值”的比较
1.bool变量与“零值”比较
#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
}写法三:
//1.先执行()中的表达式,得到真假结果(true or false,逻辑结果) - 而这里的pass本身就是逻辑结果
//2.条件 判定功能
//3.进行 分支功能
if (pass) { //推荐 - 直挂的反应出来了,flag是"bool"
//TODO
}
system("pause");
return 0;
}
结论:bool类型,直接判定,不用操作符进行和特定值比较。
2.float、double变量与“零值”比较 - (这里以double为例)
我们接下来看这个代码,后面的注释是我们预测的输出。
#include <stdio.h>
int main()
{
double x = 1.0;
double y = 0.1;
printf("%.50f\n", x - 0.9);//0.1
printf("%.50f\n", y);//0.1
if ((x - 0.9) == y) {
printf("you can see me!\n");//输出you can see me!
}
else {
printf("you can not see me!\n");
}
return 0;
}
但是当我们运行这个代码的时候,结果令我们大失所望呀。
为什么呢?
这里我们将数值3.1打印50的精度,结果出现了一大堆意外的数字。
这是因为浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。 注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会“四舍五入”或者其他策略。所以上面才会输出you can not see me!
那么两个浮点数该如何比较呢? - 应该进行范围精度比较
在 C 语言中,由于浮点数的精度问题,不能直接使用等于号(==)判断两个浮点数是否相等。通常使用以下方法来比较两个浮点数的大小关系:
1.定义一个比较精度值 EPS,例如 1e-6,代表可接受的最小误差范围;
2.判断两个数之差(绝对值)是否小于等于精度值 EPS;
了解fabs函数
在 C 语言中,fabs 函数属于 math.h 头文件,因此在使用该函数前需要先包含 math.h 头文件。该函数返回一个 double 类型的值,可以用于计算浮点数的绝对值。
当我们去改进程序后,我么发现就可以比较两个浮点数了。
两个精度定义
我们发现我们定义1e-6(也就是0.000001),可能有时候设置的误差范围比较大导致判断错误,那么我们一个具体怎么设置这个值呢,那么此时C语言就提供了两个精度:
#include //使用下面两个精度,需要包含该头文件
DBL_EPSILON //double 最小精度
FLT_EPSILON //float 最小精度
转到定义后
XXX_EPSILON是最小误差,是:XXX_EPSILON+n不等于n的最小的正数。 EPSILON这个单词翻译过来是'ε'的意思,数学上,就是极小的正数 。
请问我们这样写会有问题嘛? - 问题是:要不要相等
XXX_EPSILON是最小误差,是:XXX_EPSILON+n不等于n的最小的正数。 XXX_EPSILON+n不等于n的最小的正数: 有很多数字+n都可以不等于n,但是XXX_EPSILON是最小的,但是, XXX_EPSILON依旧是引起不等的一员。 换句话说:fabs(x) <= DBL_EPSILON(确认x是否是0的逻辑),如果=,就说明x本身,已经能够引起其他和他+和-的数据本身的变化了,这个不符合0的概念。
现在我们来回归主题:float、double变量与“零值”比较
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <windows.h>
int main()
{double x = 0.00000000000000000000001;//if (fabs(x-0.0) < DBL_EPSILON){ //写法1//if (fabs(x) < DBL_EPSILON){ //写法2if (x > -DBL_EPSILON && x < DBL_EPSILON) { //写法3printf("you can see me!\n");}else {printf("you can not see me!\n");}system("pause");return 0;
}
总结:在 C 语言中,由于浮点数在计算机中存储的方式和精度限制的原因,不能直接使用等于号来判断两个浮点数是否相等,也不能直接判断浮点数是否等于 0.0,如果我们要比较,就需要形成一个极小的精度EPS,然后将这个数与0.0的差值的绝对值进行比较,这样我们才能判断float、double变量与“零值”的比较。
3.指针变量与"零值"比较
常识补充:对NULL, '\0', 0的整体理解
1.NULL、'\0'和0是C语言中常用的三个表示“0”的值。
2.它们的类型是不同的。
1. NULL:通常被定义为一个值为0的宏,表示指针不指向任何有效的内存地址。在大多数情况下,一个指针的值为NULL表示其未被初始化或者指向了无效的内存地址,NULL是'0'被强制转换成指针类型的值。
2. '\0':是一个字符常量,表示字符数组的结束符。在C语言中,字符串是由字符数组组成的,每个字符串的结尾都必须以'\0'字符作为结束标志,告诉程序字符串的长度。
3. 0:是整数常量的一种,表示数值0。在C语言中,用0来表示逻辑假,非0的值表示逻辑真。
4.强制类型转化的理解
总结:强制类型转化没有改变内存中的数据,只是改变了它的类型。
接下来看下面的写法哪个好
#include<stdio.h>
int main()
{int* p = NULL;if (p == 0){//写法一}if (p){//写法二}if (NULL == p){//写法三}return 0;
}
写法一:尽管NULL的值和0一样,但是意义不同,写法一容易让人认为p是整形变量
写法二:让人认为p是bool变量
写法三:很容易让人认识到这是指针相关的判断
相关文章:

learn_C_deep_6 (布尔类型、布尔与“零值“、浮点型与“零值“、指针与“零值“的比较)
目录 语句和表达式的概念 if语句的多种语法结构 注释的便捷方法(环境vs) if语句执行的过程 逻辑与&& 逻辑或|| 运算关系的顺序 else的匹配原则 C语言有没有布尔类型 C99标准 sizeof(bool)的值为多少? _Bool原码 BOOL…...

JavaScript日期库之date-fn.js
用官网的话来说,date-fn.js 就是一个现代 JavaScript 日期实用程序库,date-fns 为在浏览器和 Node.js 中操作 JavaScript 日期提供了最全面、但最简单和一致的工具集。那实际用起来像它说的那么神奇呢,下面就一起来看看吧。 安装 安装的话就…...

五一假期出游攻略【诗与远方】
原文在:PUSDN 可以导入作为模板引用。 五一旅行计划 假期倒计时 [该类型的内容暂不支持下载] 本次目标:五一旅行计划【画饼版】 前言 任何一个地方,一个城市,都有可观赏的地方,如果没去过邢台的,建议五一去…...

怎样正确做web应用的压力测试?
web应用,通俗来讲就是一个网站,主要依托于浏览器实现其功能。 提到压力测试,我们想到的是服务端压力测试,其实这是片面的,完整的压力测试包含服务端压力测试和前端压力测试。 下文将从以下几部分内容展开:…...

Hibernate的持久化类
Hibernate是一个开源的ORM(对象关系映射)框架,用于将Java程序中的对象映射到数据库中的关系型数据。在Hibernate中,持久化类是用来映射Java对象和关系型数据库表的类。 编写Hibernate持久化类需要遵循以下规则: 持久…...

【c语言】enum枚举类型的定义格式 | 基本用法
创作不易,本篇文章如果帮助到了你,还请点赞支持一下♡>𖥦<)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ…...

Python数据挖掘与机器学习
近年来,Python编程语言受到越来越多科研人员的喜爱,在多个编程语言排行榜中持续夺冠。同时,伴随着深度学习的快速发展,人工智能技术在各个领域中的应用越来越广泛。机器学习是人工智能的基础,因此,掌握常用…...

Java有用的书籍2
. 1.《Effective Java》是由Joshua Bloch撰写的一本Java编程规范和最佳实践指南,第三版是最新版。它涵盖了Java编程中一些常见问题和技巧,以及如何编写更加优雅、健壮和高效的Java代码。 该书共分为15章,每一章都涵盖了Java编程中的一个关键…...

CTA进网测试《5G消息 终端测试方法》标准依据:YDT 3958-2021
GB 21288-2022 强制国标要求变化 与GB 21288-2007相比, 新国标主要有以下变化: 1. 增加职业暴露定义: 2. 增加吸收功率密度定义: 3. 增加不同频率、不同人体部位适用的暴露限值: 4. 增加产品说明书的注释:…...

[LeetCode复盘] LCCUP‘23春季赛 20230422
[LeetCode复盘] LCCUP23春季赛 20230422 一、总结二、 1. 补给马车1. 题目描述2. 思路分析3. 代码实现 三、2. 探险营地1. 题目描述2. 思路分析3. 代码实现 四、 3. 最强祝福力场1. 题目描述2. 思路分析3. 代码实现 五、 4. 传送卷轴1. 题目描述2. 思路分析3. 代码实现 六、 5…...

传统燃油车的智控App远控响应速度优化方向几点思考
一、分析当前问题及其影响因素 网络延迟:燃油车的App远控响应速度受到网络延迟的影响。网络延迟可能是由于网络拥堵或服务器响应速度慢等原因导致的。 用户设备:用户设备的性能也会影响燃油车的App远控响应速度。例如,设备的内存不足或存在故…...

回炉重造九---DNS服务器
1、DNS服务器的相关概念和技术 1.1 DNS服务器的类型 主DNS服务器从DNS服务器缓存DNS服务器(forward DNS服务器{转发器}) 1.1.1 主DNS服务器的作用 管理和维护所负责解析的域内解析库的服务器1.1.2 从DNS服务器的作用 从主服务器或从服务器“复制”解…...

UE4/5多人游戏详解(七、自定义委托,实现寻找会话和加入会话的函数,通过Steam进行两台电脑的联机)
目录 可能出现问题(在六部分的测试可能无法连接的问题【在末尾加上了,怕有人没看见在这里写一下】) 自定义委托 调整位置 创建更多的委托和回调函数给菜单: 多播和动态多播 代码: 委托变量 代码: 回…...

【数据库多表操作】sql语句基础及进阶
常用数据库: 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它是长期存储在计算机内、有组织、有结构的数据集合。数据库是信息系统的核心部分,现代软件系统中大量采用了数据库管理系统(DBM…...
DPDK和RDMA的区别
网络的发展好像在各方面都是滞后于计算和存储,时延方面也不例外,网络传输时延高,逐渐成为了数据中心高性能的瓶颈。因为传统两个节点间传输数据的网络路径上有大量的内存拷贝,导致网络传输效率低下,网络数据包的收发处…...

体验 Google Bard
环境 windows 10 64bitGoogle Bardpython 3.8 简介 本篇介绍一个开源的 Google 聊天机器人Bard 的 API 逆向工程,使用它,可以免费的使用 Bard 服务,项目地址:https://github.com/acheong08/Bard 安装及使用 通过 pip 来安装 pip &…...

MITA触摸屏维修WP4053米塔工控机控制屏维修
MITA-TEKNIK米塔触摸屏维修工控机工控屏控制器维修DISPLAY 2COM全系列型号 Mita-Teknik触摸屏维修常见故障:上电无显示,运行报故障,无法与电脑通讯,触摸无反应,触控板破裂,触摸玻璃,上电黑屏&a…...

Nacos简介 安装 配置
简介 什么是注册中心 注册中心在微服务项目中扮演着非常重要的角色,是微服务架构中的纽带,类似于通讯录,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,…...

五、MyBatis各种查询功能
MyBatis的各种查询功能 如果查询出的数据只有一条,可以通过 实体类对象接收List集合接收Map集合接收 如果查询出的数据有多条,一定不能用实体对象接收,会抛TooManyResultsException,可以通过 实体类类型的List集合接收Map类型…...

uni-app——picker组件的用法、时间、日期、地区选择器等
1、uniapp–picker组件 <template><view class"signUp"><view class"signUp_dv1"><u-form :model"form" ref"uForm" label-width"95px"><u-form-item label"日期" :required"tr…...

什么情况需要考虑 mysql 分表
最近看到公司的其中一个数据库用户表每个月都要几百万的新用户数据增加,目前单表已经是两千多万了。所以找了 DBA 讨论,发现以前学的知识,以及网上的一些资料其实说的并不是很正确,比如 mysql 单表不建议超过一千万,我…...

系统架构师02-架构设计 20分
1.架构基本概念 *质量属性效用树:是对系统质量属性进行识别和优先级排序的重要工具 。 包括: 性能:效率指标,处理任务所需时间或单位时间内的处理量。 可用性: 可靠性: 容错:出现错误后人能保…...

【python视图3】networkx图操作示例
一、说明 根据定义,图是节点(顶点)以及已识别的节点对(称为边、链接等)的集合。在 NetworkX 中,节点可以是任何可哈希对象,例如文本字符串、图像、XML 对象、另一个图形、自定义节点对象等。 如…...

网络地址转换应用
如图所示,企业使用一台AR 路由器作为出口设备,路由器配置NAT Outbound为私网用户提供访问Internet服务,同时配置NAT Server将私网WEB服务器发布到公网上,对外网用户提供服务。运营商仅为该单位分配了一个公网IP,此地址既作为AR出接口的IP地址,也作为NAT Outbound和NAT Se…...
强化学习-Double DQN、竞争网络结构和Rainbow(第4章)
来源书籍: TENSORFLOW REINFORCEMENT LEARNING QUICK START GUIDE 《TensorFlow强化学习快速入门指南-使用Python动手搭建自学习的智能体》 著者:[美]考希克巴拉克里希南(Kaushik Balakrishnan) 译者:赵卫东 出版…...

Unity 性能优化锦集
Unity作为一款主流的游戏开发引擎,不仅提供了强大的编辑器和开发工具,还可以让开发者轻松地实现高质量的3D游戏。但是,随着游戏规模的不断扩大和玩家需求的增加,游戏的性能问题也变得越来越重要。因此,在使用Unity进行…...

JS之Map的基本使用
一、Map的基本API 创建: const map new Map()插入:map.set("name", "郑建")读取:map.get("name")判断:map.has("name")删除:map.delete大小:map.size遍历&#…...

音视频八股文(6)-- ffmpeg大体介绍和内存模型
播放器框架 常用音视频术语 • 容器/文件(Conainer/File):即特定格式的多媒体文件, 比如mp4、flv、mkv等。 • 媒体流(Stream):表示时间轴上的一段连续数据,如一 段声音…...

4.25~~~~~
接着之前PE文件结构的预习 DOS 定位到NT 怎么操作的? 用的是e_lfanew,然后是相对于文件头的偏移量(也就是raw表示方法) 现在有个问题,为什么e_lfanew 这个变量不直接存储PE头 的绝对地址呢? 比如说&…...

Android 9.0 系统设置显示主菜单添加屏幕旋转菜单实现旋转屏幕功能
1.前言 在android9.0的系统rom定制化开发中,在对系统设置进行定制开发中,有产品需求要求增加旋转屏幕功能的菜单,就是在点击旋转屏幕菜单后弹窗显示旋转0度,旋转 90度,旋转180度,旋转270度针对不同分辨率的无重力感应的大屏设备的屏幕旋转功能的实现,接下来就来分析实现…...