流程控制01
流程控制01
1. if语句
分支结构的作用就是将 C 语言的代码变得丰富
那么光有关系表达式和逻辑表达式还不足以实现分支结构,还需要学习一个新的语句——if 语句。
if 语句的实现有好几种形式,我们逐一给大家介绍一下。
第一种:
…… // 其它语句 if (表达式) { …… // 逻辑值为真所执行的语句、程序块 } …… // 其它语句
第一种是最简单的,if 后边小括号内填写返回逻辑值的表达式,当然你可以直接填入一个逻辑值,当你填入这个值为非 0 的时候,编译系统就会认为这个逻辑值是真;只有当你填入 0 的时候,才被认为是假的。
第二种:
…… // 其它语句 if (表达式) { …… // 表达式的逻辑值为真所执行的语句、程序块 } else { …… // 表达式的逻辑值为假所执行的语句、程序块 } …… // 其它语句
第三种:
…… // 其它语句 if (表达式1) { …… // 表达式 1 的逻辑值为真所执行的语句、程序块 } else if (表达式2) { …… // 表达式 2 的逻辑值为真所执行的语句、程序块 } else if (表达式3) { …… // 表达式 3 的逻辑值为真所执行的语句、程序块 } else if (表达式n) { …… // 表达式 n 的逻辑值为真所执行的语句、程序块 } else { …… // 上面所有表达式的逻辑值均为假所执行的语句、程序块 } …… // 其它语句
2. switch语句和分支嵌套
处理多分支结构,可以考虑使用语法更简便的 switch 语句
…… // 其它语句 switch (表达式) { case 常量表达式 1: 语句或程序块; case 常量表达式 2: 语句或程序块; …… case 常量表达式 n:语句或程序块; default: 语句或程序块; } …… // 其它语句
- 这里每个 case 后边的常量是匹配 switch 后边表达式的值
- case 后边必须跟一个常量值,而不能是一个范围
- 如果所有的 case 均没有匹配的,那么执行 default 的内容
- default 是可选的,如果没有 default,并且所有的 case 均不匹配,那么 switch 语句不执行任何动作
使用 break 语句跳出
switch 语句中的 case 和 default 事实上都是“标签”,用来标志一个位置而已。当 switch 跳到某个位置之后,就会一直往下执行,所以我们这里还需要配合一个 break 语句,让代码在适当的位置跳出 switch。
事实上 break 语句在循环中能发挥更大的作用哦!
分支结构的嵌套
如果在一个 if 语句中包含另一个 if 语句,我们就称之为 if 语句的嵌套,也叫分支结构的嵌套。
#include <stdio.h> int main() { int a, b; printf("请输入两个数:"); scanf("%d %d",&a,&b); if(a != b) { if(a > b) { printf("%d > %d\n",a,b); } else { printf("%d < %d\n",a,b); } } else { printf("%d = %d\n",a,b); } return 0; }
悬挂 else
这个问题虽然已经为人熟知,而且也并非 C 语言所独有。但即使是有多年经验的 C 程序员,也常常在此失误过!
考虑下面的代码片段:
…… if (x == 0) if (y == 0) error(); else z = x + y; ……
这段代码中编程者的本意是应该有两种主要情况,x 等于 0 以及 x 不等于 0。对于 x 等于 0 的情形,除非 y 也等于 0(此时调用 error 函数),否则程序不作任何处理;对于 x 不等于 0 的情形,程序将 x 与 y 之和赋值给 z。
然而,这段代码实际上所做的却与编程者的意图相去甚远。
原因在于 C 语言中有这样的规则,else 始终与同一对括号内最近的未匹配的 if 结合。如果我们按照上面这段程序实际上被执行的逻辑来调整代码缩进,大致是这个样子:
…… if (x == 0) if (y == 0) error(); else z = x + y; ……
也就是说,如果 x 不等于 0,程序将不会做任何处理。如果要得到原来的例子中由代码缩进体现的编程者本意的结果,应该这样写:
…… if (x == 0) { if (y == 0) { error(); } } else { z = x + y; } ……
现在,else 与第一个 if 结合,即使它离第二个 if 更近也是如此,因为此时第二个 if 已经被括号“封装”起来了。
等于号带来的问题
在 C 语言中使用等号(=)作为赋值运算,使用连续两个等号(==)作为比较运算。一般而言,赋值运算相对于比较运算出现得更频繁,因此字符较少的 = 就被赋予了更常用的含义——赋值操作。此外,在 C 语言中赋值符号被作为一种操作符对待,因而重复进行赋值操作(如 a = b = c)可以很容易地书写,并且赋值操作还可以被嵌入到更大的表达式中。
但是,这种使用上的便利性可能导致一个潜在的问题:当程序员本意是在作比较运算时,却可能无意中误写成赋值运算。
比如下例,该语句本意似乎是要检查 x 是否等于 y :
if (x = y) break;
而实际上是将 y 的值赋给了 x ,然后检查该值是否为零。
再来看看下面的例子:
if (c = ' ' || c == '\t' || c == '\n') space = space + 1;
该程序的本意是计算空白字符(空格符、制表符和换行符)的数量,但是由于程序员在比较字符 ' ' 和变量 c 时,误将比较运算符 == 写成了赋值运算符 = 。因为赋值运算符 = 的优先级要低于逻辑运算符 || ,因此实际上是将以下表达式的值赋给了 c :
' ' || c == '\t' || c == '\n'
因为空格(' ')不等于零(空格的 ASCII 码值为32),那么无论变量 c 此前为何值,上述表达式的值都是 1。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!