当前课程知识点:基于Linux的C++ > 第二讲 程序控制结构 > 2.4 分支结构 > LinuxCPP0204
有两种典型的分支
一个叫做if分支结构
一种叫做switch分支
我们先从If分支结构开始讲起
If分支结构有三种结构
一个标准结构
如果只有一个单路分支
那就if小括号对里面写条件表达式
后面跟着一个语句序列
如果语句序列就一条语句
那么这个花括号对可以省略
任何时候那个小括号对是不能省略的
如果是一个双路分支
那你就写if条件表达式
然后语句序列1 else语句序列2
你就按照这个格式来写
同样 这个语句序列1也好
语句序列2也好 它只有单条语句
那么花括号对都是可以省略的
语句3呢
你可以把这个if-else不断的拼接
你可以写if条件表达式1、语句序列1、
else if条件表达式2、语句序列2
不断往下拼接 最后是else
语句序列n是可以的
这是多路分支典型结构
真实计算的时候
它要首先计算这个条件表达式
或者条件表达式1的值
如果为真 它就做对应的语句序列
如果为假去找else
如果没有else 就跳过
如果else那个语句后面继续是if
那么它就继续做条件表达式2
如果为真 就去做后面那条语句序列
如果为假 继续去找else
它就按照这样的方式进行计算
我们看几个例子
就会很清楚它的程序流程结构
我们看看第一个例子
我们让同学们写一个程序
接受用户输入的一个整数
如果这个整数是一个奇数
我们将它乘3加1
如果是个偶数呢我们就直接输出
听上去蛮简单的
前面我们就不讲了
这个代码和刚才一模一样
我们定义两个量 int a、result
输出完程序功能之后
输出一个提示信息让用户输入一个整数
我们得到这个整数
用cin >> a得到这个整数
然后把这个结果设成a
怎么算它是奇数呢
除以2 余数为1
我们就写if (a % 2 == 1 )
相等判断应该是“==”
一定不能写一个“=”
这只写一个“=”
那是把1赋值给a % 2 不可以
所以一定是if (a % 2 == 1 )
然后result赋值为a * 3 + 1
然后cout输出结果
这是一个很典型的单路if分支
那如果是一个双路If分支的话
那我们就看这个代码
如果是奇数就乘3加1
如果是偶数就除以2
那就两路分支了 前面代码一样的
接下来就是得到这个数a了
不用result赋值为a 这条语句不需要了
直接就算if (a % 2 == 1 )
我就result = a * 3 + 1
else result = a / 2
接下来就是最后一个
if-else if-else
我们已知道2006年12月1号星期五
编制这个程序来打印日历
用户输入12月1号到31号某个数字
然后按照这个格式打印
打印在哪呢
1号星期五 就打印星期五下面
然后如果是2号呢
我们打在Saturday下面
现在你肯定也知道
如果是3号 甚至如果是10号
那肯定是打印在Sunday的下面
因为在打印日期时候
要决定这个日期打印的位置和格式
要控制它的制表
所以我们需要使用一个iomanip
这个头文件必须包含
manip是manipulate
就是操纵的意思
指定输入输出格式用的
然后就枚举Sunday、Monday、Tuesday
一直到Saturday
然后我们完成标准的主程序
这个程序比较复杂
是我们到目前为止写的
最复杂的一个程序
首先我们定义一个整型量date
其次我们要决定date为1
就是2006年12月1号
对应weekday星期信息是Friday
这是一个常数不变
2006年12月1号就是星期五
然后我要定义一个量
小weekday
它对应weekday是星期几
然后输出提示信息
获取一个日期(1到31)
计算2006年12月那一天
它的日期是星期几
cin传一个date进来
后面代码是if
if(day < 1 || day > 31)
花括号对cout << “Data Error!\n”; return 1
这个是做数据进行有效性检查的
我们后面还会详细讨论这部分东西
这是非常必要的
2006年12月某一天的日期
就1到31之间这些数
你不可能随便给我来一个数据250
12月哪有一个250号
没有 没有的话就不能写 不能算
它和我们的现实世界不符合
这样的程序是没有意义的
所以我们的程序必须要处理这个问题
数据有效性检查对于重要的数据
是必不可省的一个动作
所以我们一定要做错误检测
接下来代码我们就要算 星期几
我们前面讲枚举文字的时候还特别谈到过
枚举文字在计算机内部
实际上是当做一个整数(无符号整数)来保存的
第一个文字是0
Sunday就是0
Monday就是1
给我一个日期 比如3
那到底是星期几呢
那我们就要算 1号是星期五
3号就相当于是星期五后面加上2
这个1号的日期
它对应那个枚举文字是什么
是Friday 它转换成整数
用小括号int
表示把这个枚举文字的量转换成整数
参与我们运算
Friday星期五
转换出来结果是5
date如果是3号
出来的结果余数就为0
余数为0重新转化WEEKDAY
那结果就是Sunday
为什么要这么做呢
就是因为它是循环的
这方面只涉及到一个问题
枚举文字转换成整数 参与运算
然后再重新转换枚举文字
注意看我们这里有一个格式
Sunday、Monday、Tuesday
每个都占两列嘛
然后中间空位又占两列
所以在输出的时候
要决定每一个数据对应的位置在哪里
我们用什么呢
用一个操纵算子setw
也就是设置它输出时候的输出宽度
setw括号里带一个整数
表示你设置它的宽度是多少字符
最后我们cout输出endl
换行结束整个程序
接下来第二种分支结构
我们称之为switch
switch后面跟着一个表达式
花括号对switch分支结构里面
跟着一堆的条件
每个条件都使用case
后面跟着一个常数表达式
后面一个冒号
“case常数表达式1: 语句序列1;
case常数表达式2: 语句序列2;”
然后“default:”
这是一个默认语句序列
它怎么去做呢
标准预算逻辑是这样
先计算这个表达式的值
然后根据这个表达式值
和常数表达式匹配
看它和哪一个常数表达式值是吻合的
如果是等的 就去做那个分支
如果全都不匹配
就会去做default分支
这就是switch的标准流程
如果没有一个default分支
如果没有任何一个常数表达式
和这个表达式值匹配
那么啥也不做
case的语句序列不一定是一条语句
可以很多条语句
也不需要花括号对括起来
switch表达式有一个很重要的地方
就是这个表达式的值
必须是一个整数 或者一个字符型
或者是枚举型
总之它能够和整数形成一一对应
只有这种架构才OK
非整数不行
看流程图的话就看得很清楚
从一个入口进来 然后就算表达式
跟常数表达式1、常数表达式2等等
这些东西比较匹配
看跟哪个等
哪个等就去做哪条语句
如果都不匹配就做缺省序列
这是标准执行流程
是我们期望的程序流程
实际上在switch这个语句结构里面
压根就不是这么做的
你要想这么做 必须要使用break
看我刚才这个例子 我打印这个日历
我刚才是用if-else if-else
现在我们把它换成switch
算出来weekday是星期几
我找case SUN、case MON、case TUE
一个一个去匹配
如果匹配到SUN 我就输出它
Setw(2) 设置它的长宽为两个字符宽度
然后输出这个date
输出这个date以后 我们break
如果是Monday一样
一直到最后default
如果你觉得这个空语句没有意义
你就把default这一行删掉也OK
为什么要break
这是非常重要的一个地方
break语句将终止switch语句的执行
分支结构本身是可以嵌套
if分支、switch分支都可以嵌套
我们看一个例子就知道了
考虑一个企业工资晋级计划
基本的原则就是
如果员工服务年限没有达到五年
那么如果年龄不小于28岁
那我就给你涨一级工资
如果服务年限达到5年
我们就涨两级工资
那些服务年限短的
年龄也小的就不涨了
公司一般没这么干的
要增长工资的话
年限短的那就要涨一级
剩下涨两级、三级
不涨 有点说不过去
我们就是举一个例子
age表示员工年龄
service_years表示服务年限
然后salary_level表示员工的工资级别
然后我们怎么来给他涨工资
我们看我们写的代码
“if ( service_years < 5 )
if ( age>= 28 )
salary_level += 1
else salary_level += 2;”
对吗 不对 这里面有两个if 一个else
我们讲过了 单独出现if是可以的
如果有一个else
一定要有一个if配对
两个Ifif一个else没有问题
问题就在于这个else
到底和哪一个if进行配对
我们要做一个明确的限定
你如果不限定
C/C++就会按照一个自己的规则
对它进行限定
它的限定条件就是
else就和离它最近的同层次的那个if配对
什么叫离的最近 也就是距离最短
我们从这个源代码级别
从后往前倒过来看
看哪一个if最先出现
那么这就是距离离的最短的
同层次呢
我们就看它们是不是在同一个级别
这个else和第二个if是同层次的
所以就按照这个方式进行配对
那么如果按照这个方式配对的话
这个代码就不对了
如果服务年限小于5年
那么如果年龄大于等于28
就涨一级工资
否则服务年限小于5年
且年龄小于28涨两级工资
那服务年限大于等于5年呢 不涨
跟我们刚才要求一样吗
肯定不对 天壤之别
怎么改 我要把这个else
保证和第一个if配对
而不是第二个if配对
怎么办
把第二个else层次给降低一层
用一个复合语句块
用花括号对把这个if括起来
就表示这个if是花括号对里面的代码
这个代码层次就降了一级
而这个else呢
将会跳过前面这个花括号对
直接和第一个if配对
这就对了
-1.1 提纲
-1.2 程序设计的基本概念
-1.3 简单C/C++程序介绍
-1.4 程序设计的基本流程
-1.5 基本语法元素
-1.6 程序设计风格
-1.7 编程实践
-第一讲 C/C++基本语法元素--编程实践提交入口
-2.1 提纲
-2.2 结构化程序设计基础
-2.3 布尔数据
-2.4 分支结构
-2.5 break语句
-2.6 循环结构
-2.7 编程实践
-第二讲 程序控制结构--编程实践提交入口
-3.1 提纲
-3.2 函数声明、调用与定义
-3.3 函数调用栈框架
-3.4 编程实践
-第三讲 函数--编程实践提交入口
-4.1 提纲
-4.2 算法概念与特征
-4.3 算法描述
-4.4 算法设计与实现
-4.5 递归算法(一)
-4.6 递归算法(二)
-4.7 容错与计算复杂度
-4.8 编程实践
-第四讲 算法--编程实践提交入口
-5.1 提纲
-5.2 库与接口
-5.3 随机数库(一)
-5.4 随机数库(二)
-5.5 作用域与生存期
-5.6 典型软件开发流程(一)
-5.7 典型软件开发流程(二)
-5.8 编程实践
-第五讲 程序组织与开发方法--编程实践提交入口
-6.1 提纲
-6.2 字符
-6.3 数组(一)
-6.4 数组(二)
-6.5 结构体
-6.6 编程实践
-第六讲 复合数据类型--编程实践提交入口
-7.1 提纲
-7.2 指针基本概念
-7.3 指针与函数
-7.4 指针与复合数据类型(一)
-7.5 指针与复合数据类型(二)
-7.6 字符串
-7.7 动态存储管理(一)
-7.8 动态存储管理(二)
-7.9 引用
-7.10 编程实践
-第七讲 指针与引用--编程实践提交入口
-8.1 提纲
-8.2 数据抽象(一)
-8.3 数据抽象(二)
-8.4 链表(一)
-8.5 链表(二)
-8.6 链表(三)
-8.7 链表(四)
-8.8 函数指针(一)
-8.9 函数指针(二)
-8.10 抽象链表(一)
-8.11 抽象链表(二)
-8.12 编程实践
-第八讲 链表与程序抽象--编程实践提交入口
-9.1 提纲
-9.2 程序抽象与面向对象
-9.3 类类型
-9.4 对象(一)
-9.5 对象(二)
-9.6 类与对象的成员(一)
-9.7 类与对象的成员(二)
-9.8 类与对象的成员(三)
-9.9 继承(一)
-9.10 继承(二)
-9.11 继承(三)
-9.12 多态(一)
-9.13 多态(二)
-9.14 编程实践
-第九讲 类与对象--编程实践提交入口
-10.1 提纲
-10.2 四则运算符重载(一)
-10.3 四则运算符重载(二)
-10.4 关系与下标操作符重载
-10.5 赋值操作符重载(一)
-10.6 赋值操作符重载(二)
-10.7 赋值操作符重载(三)
-10.8 赋值操作符重载(四)
-10.9 赋值操作符重载(五)
-10.10 流操作符重载(一)
-10.11 流操作符重载(二)
-10.12 流操作符重载(三)
-10.13 操作符重载总结
-10.14 编程实践
-第十讲 操作符重载--编程实践提交入口
-11.1 提纲
-11.2 泛型编程概览
-11.3 异常处理机制(一)
-11.4 异常处理机制(二)
-11.5 运行期型式信息(一)
-11.6 运行期型式信息(二)
-11.7 模板与型式参数化
-11.8 题外话:术语翻译
-11.9 泛型编程实践(一)
-11.10 泛型编程实践(二)
-11.11 泛型编程实践(三)
-11.12 泛型编程实践(四)
-11.13 泛型编程实践(五)
-11.14 泛型编程实践(六)
-11.15 泛型编程实践(七)
-11.16 泛型编程实践(八)
-11.17 泛型编程实践(九)
-11.18 泛型编程实践(十)
-11.19 编程实践
-第十一讲 泛型编程--编程实践提交入口
-12.1 提纲
-12.2 程序执行环境(一)
-12.3 程序执行环境(二)
-12.4 程序执行环境(三)
-12.5 程序执行环境(四)
-12.6 输入输出(一)
-12.7 输入输出(二)
-12.8 文件系统
-12.9 设备
-12.10 库(一)
-12.11 库(二)
-12.12 makefile文件(一)
-12.13 makefile文件(二)
-12.14 makefile文件(三)
-12.15 编程实践
-第十二讲 Linux系统编程基础--编程实践提交入口
-13.01 提纲
-13.02 进程基本概念
-13.03 信号
-13.04 进程管理(一)
-13.05 进程管理(二)
-13.06 进程管理(三)
-13.07 进程间通信(一)
-13.08 进程间通信(二)
-13.09 进程间通信(三)
-13.10 进程间通信(四)
-13.11 进程池
-13.12 编程实践
-第十三讲 进程编程--编程实践提交入口
-14.1 提纲
-14.2 线程基本概念
-14.3 线程管理(一)
-14.4 线程管理(二)
-14.5 线程管理(三)
-14.6 线程管理(四)
-14.7 线程同步机制(一)
-14.8 线程同步机制(二)
-14.9 C++11线程库(一)
-14.10 C++11线程库(二)
-14.11 C++11线程库(三)
-14.12 C++11线程库(四)
-14.13 C++11线程库(五)
-14.14 编程实践
-第十四讲 线程编程--编程实践提交入口
-15.1 提纲
-15.2 Internet网络协议
-15.3 套接字(一)
-15.4 套接字(二)
-15.5 编程实践
-第十五讲 网络编程--编程实践提交入口