关键字深度剖析,集齐所有关键字可召唤神龙?【二】

  • 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语句是如何执行的?

  1. 先执行()中的表达式,得到真假结果
  2. 条件的判定
  3. 根据结果进行分支功能

如果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. 浮点数是不能==比较的
  3. 如何改造使得可以比较
  4. 要不要<=细节

###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. 关键字深度剖析,集齐所有关键字可召唤神龙?【完】

    关键字深度剖析,集齐所有关键字可召唤神龙?[完] 1. union关键字 1.1 联合体union 1.2 union和内存布局 1.3 大小端对于union的影响 2. enum 关键字 2.1 枚 ...

  2. 关键字深度剖析,集齐所有关键字可召唤神龙?【三】

    关键字深度剖析,集齐所有关键字可召唤神龙?[三] 1. return关键字 1.0 before return 1.1 熟悉的问题,函数调用开辟栈帧 1.2 返回值临时变量接收的本质 1.3 retu ...

  3. 华为集齐 AI 龙珠,“召唤神龙”为期不远

    作者 | 马超 责编 | 胡巍巍 出品 | CSDN(ID:CSDNnews) 3月26日,<人民日报>开设"新基建 新机遇"专栏,其中头条文章<新基建拓展新空间 ...

  4. 【C语言你真的学会了吗】C语言深度剖析(1)【关键字深度剖析】

    目标: 初步了解关键字分类 深刻理解变量 深刻理解定义与声明 auto关键字的理解 站在存储结构角度,理解register关键字 目录 1.关键字分类 2.第一个C程序(补充内容) 3.变量的定义和声 ...

  5. 集齐ABCI四张牌,TA“召唤”了网安新风向!

    不久之前,网友们得知了一则悲伤的消息,风靡全球的漫画以及同名动画片<樱桃小丸子>的作者因癌症去世. 得知后,各大平台的粉丝童鞋们纷纷表示"再见!美好的童年回忆",朋友圈 ...

  6. volatile关键字之全面深度剖析

    引言 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字 ...

  7. 【C语言深度剖析】— 史上最全关键字(爆肝半个月、数万字详解、考试必备)

    目录 引言: 1. 关于变量 1.1 什么是变量 1.2 变量的定义与声明 1.3 为什么要定义变量 1.4 变量定义的本质 2. 关键字 2.1 最宽宏大量的关键字 - auto 2.1.1 局部变 ...

  8. 读书笔记之《C语言深度剖析》第一章:关键字

    第一章引言 什么是定义及声明? 定义:定义是编译器创建一个对象,并且为这个对象分配一块内存并给它取上一个名字,这个名字就是我们经常所说的变量名或对象名. 声明:1.告诉编译器该变量名已经匹配了一个内存 ...

  9. 【技术综述】图像与CNN发家简史,集齐深度学习三巨头

    文章首发于微信公众号<有三AI> [技术综述]图像与CNN发家简史,集齐深度学习三巨头 没有一个经典的发现会是突然之间横空出世,它总是需要一些积淀. 提起卷积神经网络,我们总会从LeNet ...

最新文章

  1. 【C++】拷贝,赋值与构造
  2. R语言Apriori算法关联规则挖掘:使用interestMeasure函数评估挖掘到的规则(包括覆盖率(coverage)和FishersExactTest)、置信度最高的五条规则(top five
  3. 操作系统原理第一章:操作系统概述
  4. Oracle查询日期
  5. 跨数据库调用存储过程权限问题
  6. 无法恢复,欧洲云服务巨头数据中心起火
  7. iphone 随机颜色生成
  8. 随想录(插件的重要思想)
  9. [Python] ubuntu 上安装 Miniconda
  10. 系统学习NLP(二十八)--GPT
  11. oracle Fusion Applications 简介 (Oracle融合管理软件简介)
  12. IT:银行类金融科技岗笔试习题集合—四个模块包括【综合知识+EPI+英语+个性测评】持续更新,建议收藏
  13. Python-GUI界面设计(tkinter)
  14. Spring AOP编程官方文档解读之操作Advised对象
  15. Python TypeError: cat() takes no arguments
  16. 凉凉!写了个脚本,不小时锁了1W台手机。。
  17. Photoshop几何3D立体头像制作教程
  18. 数据挖掘::实验一 WEKA分类
  19. 联合国安理会默哀悼念汶川大地震遇难者(组图)
  20. 社区发现的3个评估指标:标准化互信息NMI,ARI指标,以及模块度(modularity)

热门文章

  1. python气象卫星云图解析_python下载卫星云图合成gif的方法示例
  2. 前端效果 -- 实现折叠、展开动画效果
  3. 鸽主姓名查询成绩_获奖鸽主姓名,名次及足环号码
  4. 华为云OBS究竟是什么?
  5. ElasticSearch教程-索引的介绍
  6. 不同局域网之间socket通信
  7. java爬取当当网所有分类的图书信息(ISBN,作者,出版社,价格,所属分类等)
  8. 在Qt中使用OpenGL(二)
  9. 又一家初创公司获得数千万融资进军边缘计算赛道!
  10. linux cpu数理,Linux中的 德·摩根定律