-
2、分支语句(选择结构)
-
2.1 if语句
- 错误写法
- 18 <= 10 为假,就是 0,所以:0 < 28 为真,所以输出“青年”
- &&:并且
- 18 <= 10 为假,就是 0,所以:0 < 28 为真,所以输出“青年”
- 如果条件成立,要执行多条语句,应该使用代码块
- 意思就是如果语句很多,要用大括号 {} 括起来
- 悬空else
- 输出为空
- else 和哪个 if 对齐就和哪个匹配❌
- else 是和它最近的 if 所匹配的✅
- ⬇️
- 非要让第一个 if 和 else 对应
- 非要让第一个 if 和 else 对应
- ⬇️
- 输出为空
- if 语句规范书写
- 1. 变量的命名(有意义,规范)
- 可阅读性强
- 可阅读性强
- 2. 空格,空行,换行
- 3. 如何避免判断语句老是忘记写两个等号 ==
- 把 5 赋值给 num,万无一失
- 把 5 赋值给 num,万无一失
- 1. 变量的命名(有意义,规范)
- 练习
- 1. 判断一个数是否为奇数
- 2. 输出1-100之间的奇数
- 法1
- 法2:1 + 2 + 2 + ...,后面一直都是奇数如果一直加2
- 法1
- 1. 判断一个数是否为奇数
- 错误写法
-
2.2 switch语句
- switch语句也是一种分支语句,常常用于多分支的情况。
- 比如:
- 那我写成 if...else if ...else if 的形式太复杂,那我们就得有不一样的语法形式。
- 这就是switch 语句的用法
- 比如:
- 记住要有 break 来结束
- switch 语句必须是 整形表达式,也就是 int 类型
- case + 整形常量表达式:
- case + 字符 也是可以的,字符本质上也是一个整形,因为字符存储的是它的 ASCII 码值,也是整数。
- 必须整数
- 必须常量,不能变量
-
练习
- 1. 输入1-5,输出的是“weekday”;
- 法1
- 法2
- 如果没有 break 就会一直往下走,从而实现多个 case 匹配同一个执行语句的这样一个效果
- 法1
- 1. 输入1-5,输出的是“weekday”;
- default 子句
- 所有的 case 不能匹配的,都到 default 这边来
- 所有的 case 不能匹配的,都到 default 这边来
- ➡️m = 5, n = 3
- 1️⃣switch 语句可以嵌套;
- 2️⃣break 只会跳出自己所处的 switch 语句,不会一下跳出所有的switch 语句。
- switch语句也是一种分支语句,常常用于多分支的情况。
-
-
3、循环语句
for > while > do while-
3.1 while循环
- while 语法结构
- while循环中,当条件表达式成立时,才会执行循环体中语句,每次执行期间,都会对循环因子进行修改(否则就成为死循环),修改完成后如果while条件表达式成立,继续循环,如果不成立,循环结束
- 故:while循环条件将会比循环体多执行一次。(B)
- 故:while循环条件将会比循环体多执行一次。(B)
- 01
- 表达式为真,执行且循环返回再判断真假,一直循环直到为假才停止
- while循环中,当条件表达式成立时,才会执行循环体中语句,每次执行期间,都会对循环因子进行修改(否则就成为死循环),修改完成后如果while条件表达式成立,继续循环,如果不成立,循环结束
- ➡️在屏幕上打印1-10的数字
- while循环中的
- break是用于永久的终止循环
- continue 跳过本次循环后面的代码,直接去判断部分,进行下一次循环的判断
- break 语句
- 中途想要停止 while 循环
- 添加一个 break 语句
- i = 5 时,判断到 if 内为真,就结束,下面的 printf 打印也不会再终止了
- continue 语句
- 把后面代码直接跳过去了
- 添加一个 continue 语句
- 直接跳过 i = 5 的这次循环及 continue 后面的代码,直接去 while 判断部分判断要不要进行下一次循环
- 没有 5 ,这次的 i++ 在上面,不会被跳过
- while循环中的
- getchar 获取字符,把获取的字符的ASCII码放到ch里面去,然后再打印输出
- 💯这里的代码适当的修改是可以用来清理缓冲区的
- 如果一次 ctrl + z 没反应,就多来几下
- ❓为什么每次点回车结果就会换行显示?⬇️
- 其实 ch 后面还有一个 \n ,识别完 ch 后会立刻再识别 ch 后面的 \n,从而实现换行继续看接下来的字符
- 其实 ch 后面还有一个 \n ,识别完 ch 后会立刻再识别 ch 后面的 \n,从而实现换行继续看接下来的字符
- 1️⃣这里的 scanf 读取了password 后,下面的 getchar 把它后面的 \n 读取了
- 所以直接输出 No
- 所以直接输出 No
- 2️⃣加一个 getchar( ); //读取了\n
- scanf 把 45646 拿走,之后中间 getchar 把数字后的空格拿走了,最下面的 getchar 把后面的字母拿走
- ➡️字符串以空格为结束标志,所以到空格 scanf 就停止了,getchar 获得的是空格,所以就错了,继续直接输出 No
- 3️⃣✅ while ((ch = getchar()) != '\n')
- 如果 getchar 读取不到 \n,就一直找,直到把它用掉,也就相当于“清理缓存区”
- 让后面的 getchar 可以正常运行
- 💯这个代码的作用是:只打印数字字符,跳过其他类型的字符
- 直接打印数字字符
- 只要判断是在 ASCII 码表里面的 0 - 9 之外的,全部 continue 函数跳过,继续找数字字符
- 直接打印数字字符
- while 语法结构
-
3.2 for 循环
- 语法形式
- for循环 的执行流程图:
- while 循环的code
- for 循环的code
- 不加大括号
- 加上大括号,在每次循环后都会加一个hehe
- 不加大括号
- break:直接跳出循环
- continue:跳过其后的代码
- for语句的循环控制变量
- 1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
- 2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。
- 前闭后开
- i < 10;
- i <= 9;
- 前闭后开
- 1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
- 一些for循环的变种
- for循环的 判断部分 省略➡️判断会恒成立
- for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。
- 省略 初始化部分
- for 循环的嵌套
- 每执行一次 i 的循环,在内部把 j 循环直到结束,也就是3次 j 的循环,所以一共 3*3 = 9 次
- 当把内外两个循环的 初始化部分 去掉后
- 外层循环第一次进入内层,内存循环结束后,j 就一直是3了,
- 外层第二次循环到内层时,j = 3 ,j 不小于3,所以内层循环就进不去了,返回继续第三次外层循环
- ➡️所以相当于内层进行了一次循环,外层三次但只有第一次循环进入了内层,其余两次都没有进入,直接返回继续下一次循环
- 每执行一次 i 的循环,在内部把 j 循环直到结束,也就是3次 j 的循环,所以一共 3*3 = 9 次
- 省略 初始化部分
- for循环的 判断部分 省略➡️判断会恒成立
- 使用多余一个变量控制循环
- 谨慎使用:c99语法才支持了这种写法;C++中也支持这种写法
- 一道笔试题:请问循环要循环多少次?
- 答:0次
- k 赋值为0,条件 0 为假,不进入循环
- k == 0;➡️第一次循环出来后,i 和 k 都不为0了,所以只循环一次
- 语法形式
-
3.3 do ... while( ) 循环
- do语句的语法
- do语句的特点
- 循环至少执行一次,使用的场景有限,所以不是经常使用
- 执行流程
- do ... while循环的code
- break:
- ( i++ 在printf 下面)到 i = 5 的时候就结束循环,下面的打印也就不执行了
- ( i++ 在printf 上面)上来直接就是 i = 2,到 5 那里依旧结束循环,所以打印的是 234
- ( i++ 在printf 上面)上来直接就是 i = 2,到 5 那里依旧结束循环,所以打印的是 234
- ( i++ 在printf 下面)到 i = 5 的时候就结束循环,下面的打印也就不执行了
- continue:
- ( i++ 在printf 上面)跳过 i = 5 的那次循环
- ( i++ 在printf 下面)1234 然后死循环
- 正常循环到 5 的时候,会跳过,但同时把 printf 下面的 i++ 也跳过了,i 一直等于5,一直跳过该循环➡️死循环
- 正常循环到 5 的时候,会跳过,但同时把 printf 下面的 i++ 也跳过了,i 一直等于5,一直跳过该循环➡️死循环
- ( i++ 在printf 上面)跳过 i = 5 的那次循环
- do语句的语法
-
3.4 练习
-
1. 计算 n的阶乘。
- ret = ret * i;
- ret = ret * i;
-
2. 计算 1!+2!+3!+……+10!
- ret = 1;
- 优化:每一次把上次算出的阶乘利用起来,直接加上一次的结果
- ret = 1;
-
3. 在一个有序数组中查找具体的某个数字n。
- 无序数组
- 无序数组
-
✅二分查找 / 折半查找(数据必须是有序的)
- 查找的图解过程
- 36. 分支和循环语句_do-while循环练习(上)25:50
- 37. 分支和循环语句_do-while循环练习(中)开头
- 36. 分支和循环语句_do-while循环练习(上)25:50
- ❗注意事项
- 1️⃣ int mid = (left + right) / 2;
- mid 的求取必须在while循环里面
- 因为每次的二分查找都是根据左右下标来确定从而求出新的 mid,
- 一旦放到外面,下一次再进行二分查找的时候,就不会根据 left 和 right 来求出 mid 了,也就构不成二分查找了
- 2️⃣ while (left <= right) 中必须有:等于号 “ = ”
- 如果是while (left < right),就算当 left right 都等于 7 的时候,也判定不出来
- 如果是while (left < right),就算当 left right 都等于 7 的时候,也判定不出来
- 3️⃣担心 left + right 太大,得出的结果溢出导致二者的平均值算出来不准确(亿位数相加时)
- int mid = left + (right - left) / 2;
- int mid = left + (right - left) / 2;
- 1️⃣ int mid = (left + right) / 2;
- 时间复杂度
- log以2为底的n
- log以2为底的n
- 测试 k 的值
- int k = 7;
- int k = 17;
- int k = 7;
- 查找的图解过程
-
4. 编写代码,演示多个字符从两端移动,向中间汇聚。
- 解析
- 1️⃣strlen 是计算字符串的长度,而 sizeof 是计算操作数组的长度
- strlen 计算 \0 之前的字符的个数;sizeof 计算包括 \0 的元素的个数
- c 的下标一直都是 2;
- 对于 strlen,最右端的 c 就是 3-1;
- 对于 sizeof,最右端的 c 就是 4-2。
- 2️⃣ Sleep(1000);
- 休眠一秒 ( 1000指1000毫秒 ),可以用来减缓汇聚的速度
- Sleep 的头文件是 #include <windows.h>
- 3️⃣ system("cls");
- system是一个库函数,可以执行系统命令;
- system 的头文件是 #include <stdlib.h>
- 1️⃣strlen 是计算字符串的长度,而 sizeof 是计算操作数组的长度
- 代码演示
- 实现流程:两边的字母不断向内变化,直到实现目标语句
- code
- 实现流程:两边的字母不断向内变化,直到实现目标语句
- 解析
-
5. 编写代码实现,模拟用户登录情景,并且只能登录三次。
(只允许输入三次密码:如果密码正确,则提示登录成功;如果三次均输入错误,则退出程序。)- 1️⃣❗注:这里的 password 不需要取地址
- 这里的 password 本身就是数组,数组是可以不取地址的,数组名本来就是地址
- 2️⃣ if( strcmp (password,"abcdef") == 0 )
- 比较两个字符串是否相等,不能使用 ==,而应该使用库函数:strcmp
- 把 strcmp 里面的两个东西都传给strcmp,进行对比,如果strcmp函数的返回值是0,说明里面的两个字符串相等
- 3️⃣strcmp函数 的头文件是 #include <string.h>
- 代码演示
- code
- code
- 1️⃣❗注:这里的 password 不需要取地址
-
6. 猜数字游戏实现
- //0~99 --> 1~100
- int ret = rand() %100+ 1; //生成随机数的函数
-
-
分支语句和循环语句⬆️
于 2023-10-25 23:31:58 首次发布