关键字深度剖析,集齐所有关键字可召唤神龙?【二】
关键字深度剖析,集齐所有关键字可召唤神龙?【二】
- 1. if、else 组合
- 1.1 if 和 else
- 1.1.1 结论1
- 1.1.2 结论2
- 1.1.3 结论3
- 1.2 bool 变量与"零值"进行比较
- 1.2.1 bool变量的大小
- 1.2.2 查看bool源码
- 1.2.3 推荐写法
- 1.2.4 float 变量与"零值"进行比较
- 1.2.4.1 对于`NULL, '\0', 0`的整体理解。
- 1.2.4.2 理解强制类型转换
- 1.2.5 if-else书写风格
- 1.2.5.1 if- else匹配
- 1.2.6.2 if 语句后面的分号
- 2. switch、case 组合
- 2.1 不要拿青龙偃月刀去削苹果
- 2.2 switch--case配合
- 2.2.1 case的作用是什么? break在switch中的作用是什么?default的顺序?
- 2.2.2 case的值有什么要求吗
- 2.3 case 语句中有什么要求吗
- 2.4 case语句的排列顺序
- 2.5 使用case 语句的其他注意事项
- 3. do、while、for 关键字
- 3.1 三种循环的死循环写法
- 3.2 输入输出流
- 3.2.1 为什么scanf和printf叫做格式化输入和输出
- 3.3 break和continue
- 3.4 循环语句的注意点
- 4. goto 关键字
- 5. void 关键字
- 5.1 为什么void不能定义变量
- 5.2 void使用情况
- 5.2.1 void修饰函数返回值的作用
- 5.2.2 void 作为函数参数的作用
- 5.3 void 指针
- 5.3.1 void 指针定义变量
- 5.3.2 void* 变量++?
- 5.3.3 void*指针可以直接解引用吗
今天继续上一次的关键字,学习《C语言深度剖析》,由于深度剖析,简单的东西就不赘述,继续集齐剩下的龙珠吧!
1. if、else 组合
1.1 if 和 else
1.1.1 结论1
认识一种不标准的写法,要认识但是不要模仿,这样的后果是,如果一旦有人改了表达式中的0,就会改变代码
int main()
{if (0) { //不推荐int flag = 2;if (1 == flag) {printf("hello bit\n");}else if (2 == flag) {if (1) {printf("....................\n");}printf("hello C深剖\n");}else {printf("hello world\n");}}return 0;
}
1.1.2 结论2
在C中0为假,非0为真
1.1.3 结论3
if语句是如何执行的?
- 先执行()中的表达式,得到真假结果
- 条件的判定
- 根据结果进行分支功能
如果if的()中是函数,就是先执行表达式
int IsEmpty()
{printf("某种数据是否为空!\n");return 1;
}
int main()
{if (IsEmpty()) {printf("yes\n");}return 0;
}
1.2 bool 变量与"零值"进行比较
C语言中只有0和1,没有bool变量吗?
并不是,首先我们要知道要有bool变量就得导入<stdbool.h>
,这是C99中引入的
但是当前使用C语言还是用的不涉及很多
1.2.1 bool变量的大小
int main()
{bool ret = false;ret = true;printf("%d\n", sizeof(ret)); //vs2013 和 Linux中都是1return 0;
}
别急,还有一套BOOL类型,这套BOOL是微软定义的,也就是说用VS2019特殊才给的
int main()
{BOOL ret = FALSE;ret = TRUE;printf("%d\n", sizeof(ret)); //输出结果是4,因为在源代码中,是这么定义的:typedef int BOOL;return 0;
}
这里肯定是不推荐BOOL,因为好的习惯是:一定要保证代码的跨平台性,微软定义的专属类型,其他平台不支持。
1.2.2 查看bool源码
源码用到了很多宏定义
//查看源码
/* stdbool.h standard header */
//stdbool.h
#ifndef _STDBOOL
#define _STDBOOL
#define __bool_true_false_are_defined 1
#ifndef __cplusplus
#define bool _Bool //c99中是一个关键字哦,后续可以使用bool
#define false 0 //假
#define true 1 //真
#endif /* __cplusplus */
#endif /* _STDBOOL */
/*
* Copyright (c) 1992-2010 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.30:0009 */
1.2.3 推荐写法
int main()
{//int pass = 0; //0表示假,C90,我们习惯用int表示boolbool pass = false; //C99if (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}return 0;
}
1.2.4 float 变量与"零值"进行比较
浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。
注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会“四舍五入”或者其他
精度损失的栗子
double d = 3.6;printf("%.50f\n", 3.6);
double x = 1.0;double y = 0.1;printf("%.50f\n", x - 0.9); //0.1printf("%.50f\n", y);
应该是一样的个却打印出来不同的结果
那么既然精度会产生问题所以不能用来作为判断
double x = 1.0;double y = 0.1;if ((x - 0.9) == y){printf("you can see me!\n");}else {printf("oops!\n");}
所以说浮点数在比较的时候绝对不能使用双等号进行比较
那么怎么才能使用呢?如果一定要用的话这样就可以了
#include<math.h>
#define EPS 0.00000000000001
double x = 1.0;
double y = 0.1;if (fabs((x - 0.9) - y) < EPS) {printf("you can see me!\n");}else {printf("oops!\n");}
或者是这样
#include <float.h>
#include<math.h>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");}
什么是 DBL_EPSILON?
我们查找 DBL_EPSILON发现它是最小精度定义XX X_EPSILON是最小误差,是:XXX_EPSILON+n不等于n的最小的正数。
EPSILON这个单词翻译过来是’ε’的意思,数学上,就是极小的正数//两个精度定义 #define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */ #define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
终于我们能够回到float与0值的比较,或者是double和0值比较
if (fabs(a) < DBL_EPSILON){//不建议写=//a == 0.0}
也就是说如果类型doucle 的a的值是小于 DBL_EPSILON的,那么说明a相当于就是0.0,就是0值
小结:
- 浮点数存储的时候,是有精度损失的
- 浮点数是不能==比较的
- 如何改造使得可以比较
- 要不要<=细节
###1.2.5 指针变量与“零值”进行比较
1.2.4.1 对于NULL, '\0', 0
的整体理解。
int* p = NULL;printf("%d\n", 0);printf("%d\n", '\0');printf("%d\n", NULL);
NULL其实就是0的强转
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif
1.2.4.2 理解强制类型转换
强制类型转换是不会改变数据本身的存储的,只是改变了数据读取的类型方式,而真实的转化会改变内存中的数据
1.2.5 if-else书写风格
1.2.5.1 if- else匹配
C 语言有这样的规定:else 始终与同一括号内最近的未匹配的if 语句结合
int main()
{int x = 0;int y = 1;if (10 == x)if (11 == y)printf("hello bit\n");elseprintf("hello world!\n");return 0;
}
没有任何输出
int main()
{int x = 0;int y = 1;if (10 == x){if (11 == y){printf("hello bit\n");}}else{printf("hello world!\n");}system("pause");return 0;
}
这样才对
1.2.6.2 if 语句后面的分号
关于if-else 语句还有一个容易出错的地方就是与空语句的连用。
if(NULL != p) ;
fun();
这里的fun()函数并不是在NULL != p 的时候被调用,而是任何时候都会被调用。问题就出
在if 语句后面的分号上。在C 语言中,分号预示着一条语句的结尾,但是并不是每条C 语
言语句都需要分号作为结束标志。if 语句的后面并不需要分号,但如果你不小心写了个分号,
编译器并不会提示出错。因为编译器会把这个分号解析成一条空语句。也就是上面的代码实
际等效于:
if(NULL != p){;}fun();
2. switch、case 组合
2.1 不要拿青龙偃月刀去削苹果
书中说的很有意思
那你既然有了菜刀为什么还需要水果刀呢?你总不能扛着云长的青龙偃月刀(又名冷艳
锯)去削苹果吧。如果你真能做到,关二爷也会佩服你的。关键字深度剖析,集齐所有关键字可召唤神龙?【二】相关推荐
- 关键字深度剖析,集齐所有关键字可召唤神龙?【完】
关键字深度剖析,集齐所有关键字可召唤神龙?[完] 1. union关键字 1.1 联合体union 1.2 union和内存布局 1.3 大小端对于union的影响 2. enum 关键字 2.1 枚 ...
- 关键字深度剖析,集齐所有关键字可召唤神龙?【三】
关键字深度剖析,集齐所有关键字可召唤神龙?[三] 1. return关键字 1.0 before return 1.1 熟悉的问题,函数调用开辟栈帧 1.2 返回值临时变量接收的本质 1.3 retu ...
- 华为集齐 AI 龙珠,“召唤神龙”为期不远
作者 | 马超 责编 | 胡巍巍 出品 | CSDN(ID:CSDNnews) 3月26日,<人民日报>开设"新基建 新机遇"专栏,其中头条文章<新基建拓展新空间 ...
- 【C语言你真的学会了吗】C语言深度剖析(1)【关键字深度剖析】
目标: 初步了解关键字分类 深刻理解变量 深刻理解定义与声明 auto关键字的理解 站在存储结构角度,理解register关键字 目录 1.关键字分类 2.第一个C程序(补充内容) 3.变量的定义和声 ...
- 集齐ABCI四张牌,TA“召唤”了网安新风向!
不久之前,网友们得知了一则悲伤的消息,风靡全球的漫画以及同名动画片<樱桃小丸子>的作者因癌症去世. 得知后,各大平台的粉丝童鞋们纷纷表示"再见!美好的童年回忆",朋友圈 ...
- volatile关键字之全面深度剖析
引言 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字 ...
- 【C语言深度剖析】— 史上最全关键字(爆肝半个月、数万字详解、考试必备)
目录 引言: 1. 关于变量 1.1 什么是变量 1.2 变量的定义与声明 1.3 为什么要定义变量 1.4 变量定义的本质 2. 关键字 2.1 最宽宏大量的关键字 - auto 2.1.1 局部变 ...
- 读书笔记之《C语言深度剖析》第一章:关键字
第一章引言 什么是定义及声明? 定义:定义是编译器创建一个对象,并且为这个对象分配一块内存并给它取上一个名字,这个名字就是我们经常所说的变量名或对象名. 声明:1.告诉编译器该变量名已经匹配了一个内存 ...
- 【技术综述】图像与CNN发家简史,集齐深度学习三巨头
文章首发于微信公众号<有三AI> [技术综述]图像与CNN发家简史,集齐深度学习三巨头 没有一个经典的发现会是突然之间横空出世,它总是需要一些积淀. 提起卷积神经网络,我们总会从LeNet ...
最新文章
- 【C++】拷贝,赋值与构造
- R语言Apriori算法关联规则挖掘:使用interestMeasure函数评估挖掘到的规则(包括覆盖率(coverage)和FishersExactTest)、置信度最高的五条规则(top five
- 操作系统原理第一章:操作系统概述
- Oracle查询日期
- 跨数据库调用存储过程权限问题
- 无法恢复,欧洲云服务巨头数据中心起火
- iphone 随机颜色生成
- 随想录(插件的重要思想)
- [Python] ubuntu 上安装 Miniconda
- 系统学习NLP(二十八)--GPT
- oracle Fusion Applications 简介 (Oracle融合管理软件简介)
- IT:银行类金融科技岗笔试习题集合—四个模块包括【综合知识+EPI+英语+个性测评】持续更新,建议收藏
- Python-GUI界面设计(tkinter)
- Spring AOP编程官方文档解读之操作Advised对象
- Python TypeError: cat() takes no arguments
- 凉凉!写了个脚本,不小时锁了1W台手机。。
- Photoshop几何3D立体头像制作教程
- 数据挖掘::实验一 WEKA分类
- 联合国安理会默哀悼念汶川大地震遇难者(组图)
- 社区发现的3个评估指标:标准化互信息NMI,ARI指标,以及模块度(modularity)
热门文章
- python气象卫星云图解析_python下载卫星云图合成gif的方法示例
- 前端效果 -- 实现折叠、展开动画效果
- 鸽主姓名查询成绩_获奖鸽主姓名,名次及足环号码
- 华为云OBS究竟是什么?
- ElasticSearch教程-索引的介绍
- 不同局域网之间socket通信
- java爬取当当网所有分类的图书信息(ISBN,作者,出版社,价格,所属分类等)
- 在Qt中使用OpenGL(二)
- 又一家初创公司获得数千万融资进军边缘计算赛道!
- linux cpu数理,Linux中的 德·摩根定律