• 五、程序流程控制


    5.1 程序流程控制介绍

    ​ 在程序中,程序运行的流程控制决定程序是如何执行懂得,是我们必须掌握的,主要有三大流程控制语句。

    • 顺序控制
    • 分支控制
    • 循环控制

    5.2 顺序控制

    5.2.1 介绍

    程序从上到下逐行地执行,中间没有任何判断和跳转。

    案例:

    一个案例说明,必须下面的代码中,没有判断,也没有跳转,因此程序按照默认的E流程执行,即顺序控制。

    ta8nED.png

    顺序控制流程图

    ta3Wct.png

    5.2.2 举例和注意事项

    Golang中定义变量时采用合法的前向引用。

    5.3 分支控制 (if-else)

    5.3.1 分支控制的基本介绍

    分支控制就是让程序有选择的执行,有下面三种形式。

    • 单分支
    • 双分支
    • 多分支

    5.3.2 单分支控制

    5.3.2.1 基本语法
    if  条件表达式 {
    	执行代码块
    }
    

    说明:当条件表达式为true时,就会执行{}的代码,注意{}是必须有的,就算你只写一行代码。

    5.3.2.2 案例

    ​ 编写一个程序,可以输入人的年龄,如果该同志的年龄大禹18岁,则输出"你年龄大于18岁,要对自己的行为负责!"

    taY7q0.png

    5.3.2.3 单分支的流程图

    流程图可以用图形方式来更加清晰的描述程序执行的流程。

    tatlo8.png

    5.3.2.4 细节说明

    ​ Go的if还有一个强大的地方就是条件判断语句里卖弄允许声明一个变量,这个变量的作用域只能在该条件逻辑块内,其他地方就不起作用了。

    5.3.3 双分支

    5.3.3.1 基本语法
    if  条件表达式 {
    	执行代码块1
    } 
    else{
    	执行代码块2
    }
    

    说明:当条件表达式成立,即执行代码块1,否则执行代码块2 {}也是必须有的

    5.3.3.2 案例

    ​ 编写一个程序,可以输入人的年龄,如果该同志的年龄大禹18岁,则输出"你年龄大于18岁,要对自己的行为负责!"。否则,输出"你的年龄不大这次就放过你了"

    ta0SQe.png

    5.3.3.3 单分支的流程图

    ta0EJf.png

    5.3.4 单分支和双分支练习题

    编写程序,声明2个int32型变量并赋值,判断两数之和,如果大于等于50,打印“hello wolrd”

    taDQP0.png

    编写程序,声明2个float64型变量并赋值,判断第一个大于10.0,且第二个数小于20.0,打印两数之和

    tasYNR.png

    定义两个变量int32,判断二者的和,是否能被3又能被5整除,打印提示信息

    ta6py8.png

    判断一个年份是否是闰年,闰年的条件是符合下面二者之一:1:年份能被4整除,但不能被100整除 2:能被400整除

    tagDzt.png

    5.3.5 多分支

    5.3.5.1 基本语法
    if  条件表达式1 {
    	执行代码块1
    } else if 条件表达式2 {
    	执行代码2
    }
    else{
    	执行代码块n
    }
    

    对上面基本语法的说明

    • 多分支的判断流程如下:
      • 先判断条件表达式 1 是否成立,如果为真,就执行代码块1
      • 如果条件表达式 1 为假,就去判断条件表达式2是否成立,如果条件表达式2为真,就执行代码块2
      • 以此类推
      • 如果所有的条件表达式都不成立,则执行 else的语句块。
    • else不是必须的
    • 多分支只能有一个执行入口
    5.3.5.2 多分支流程图 图解

    tdi4hD.png

    5.3.5.3 案例
    案例一

    岳小鹏参加Golang考试,他和父亲岳不群达成承诺:

    如果:

    成绩为100分时,奖励一台BMW;

    成绩为[80,99]时,奖励一台iphone7Plus;

    当成绩为[60,80]时,奖励一个ipad;

    其他时,什么奖励都没有。

    请从键盘输入岳小鹏的期末成绩,并加以判断

    taI1KA.png

    使用陷阱

    taITVx.png

    案例二

    taojYT.png

    tao6OA.png

    案例三

    taTjHI.png

    ta7d2D.png

    5.3.5 嵌套分支

    5.3.5.1 基本介绍

    在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支结构称为内层分支,外面的分支结构成为外层分支。

    5.3.5.2 基本语法
    if 条件表达式 {
    	if 条件表达式 {
    	} else {
    	}
    }
    

    说明:嵌套分支不宜过多,建议控制在3层内

    5.3.5.3 案例

    参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰,并且根据性别提示进入男子组或女子组,输入成绩和性别进行判断

    tavgg0.png

    出票系统,根据淡旺季的月份和年龄,打印票价

    4-10月份 旺季:

    ​ 成人(18-60):60

    ​ 儿童(<18):半价

    ​ 老人(>60):1/3

    淡季:

    ​ 成人(18-60):40

    ​ 儿童(<18):20

    代码

    tdC0bV.png

    5.4 switch分支结构

    5.4.1 基本介绍
    • switch语句用于基于不同条件执行不同动作,每一个动作 case 分支都是唯一的,从上到下逐一匹配,直到匹配为止
    • 匹配项后面也不需要再加break
    5.4.2 基本语法

    tdi0tU.png

    5.4.3 流程图

    tdFFH0.png

    对上图的说明和总结

    • switch的执行的流程是,先执行表达式,得到值,然后和case的表达式进行比较,如果相等,就匹配到,然后执行对应的case的语句块,然后退出switch控制
    • 如果switch的表达式的值没有和任何的case的表达式匹配成功,则执行default的语句块,执行后退出switch的控制。
    • Golang的case后的表达式可以有多个,使用 逗号 间隔
    • Golang中的case语句块不需要写break ,因为默认会有,即在默认情况下,当程序执行完case语句块后,就直接退出该switch控制结构。
    5.4.4 案例

    ​ 请编写一个程序,该程序可以接收一个字符,比如:a,b,c,d,e,f,g a表示星期一,b表示星期二 ......根据用户的输入显示相依的信息

    tdEoIP.png

    5.4.5 switch 细节讨论
    • case/switch后是一个 表达式(即:常量值、变量、一个有返回值的函数等都可以)

    tdVqFx.png

    tdZCTI.png

    • case后的各个表达式的值的数据类型,必须和 switch的表达式数据类型一致

    tdZRHA.png

    • case后面可以带多个表达式,使用逗号间隔,比如case 表达式1,表达式2...

    tdZv40.png

    • case后面的表达式如果是常量值(字面量),则要求不能重复

    tdefr4.png

    • case 后面不需要带break,程序匹配到一个case后就会执行对应的代码块,然后退出switch,如果是一个都匹配不到,则执行 default

    • default 语句不是必须的

    • switch 后也可以不带表达式,类似多个 if-else 分支来使用

    tdnycT.png

    • switch 后也可以直接声明/定义一个变量,分号结束,不推荐

    • switch 穿透-fallthrough,如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透

    tdGej1.png

    • Type Switch:Switch 语句还可以被用于type-switch 来判断interface(接口)变量中实际指向的变量类型

    tdGv5D.png

    5.4.6 switch 和 if 的比较

    总结了什么情况下使用switch,什么情况下使用 if

    • 如果判断的具体数值不多,而且符号整数,浮点数,字符,字符串这几种类型,建议使用switch语句,简洁高效
    • 其他情况,对区间判断和结果为bool类型的判断,使用if if的使用范围更广
    5.4.7 实战练习

    ​ **使用switch把小写类型的char型转为大写(键盘输入)。只转换a、b、c、d、e 其它的输出 "other" **

    tdY2kT.png

    对于学生成绩大于60分的,输出"合格"。低于60分的,输出"不合格"(注:输入的E成绩不能大于100)

    tdtJgJ.png

    根据用户指定月份,打印该月份所属的季节,3,4,5春季,6,7,8夏季,9,10,11秋季,12,1,2冬季

    tdNePO.png

    5.5 for循环控制

    5.5.1 基本介绍

    听其名而知其意,就是让你的代码可以循环的使用

    5.5.2 一个实际需求

    请大家看个案例,编写一个程序,可以打印10句"hello world"

    tdUdfO.png

    5.5.3 基本语法

    for 循环变量初始化;循环条件;循环量迭代{
    	循环操作(语句)
    }
    

    对上面的语法格式说明

    • 对 for循环来说,有四个要素

    • 循环变量初始化

    • 循环条件

    • 循环操作(语句),有人也叫循环体

    for循环执行的顺序说明

    • 执行循环变量初始化,比如:i := 1
    • 执行循环条件,比如:i <= 10
    • 如果循环条件为真,就执行循环操作,比如:fmt.Println(".....")
    • 再执行循环变量迭代,比如:i++
    • 反复执行2,3,4 步骤,直到循环条件为False,就退出for循环

    5.5.4 for循环执行流程分析

    • 画出流程图

    tda6v4.png

    • 代码执行内存分析图

    tddGIx.png

    5.5.5 注意事项和细节说明

    • 循环条件是返回一个布尔值的表达式

    • for循环的E第二种使用方式

      for 循环判断条件 {
      	//循环执行语句
      }
      

      变量初始化变量迭代写到其它位置

    • for循环的第三种使用方式

      for {
      	//循环执行语句
      }
      

      上面的写法等价于 for;;{}是一个无限循环,通常需要配合break语句使用

    • Golang提高 for-range的方式,可以方便遍历字符串和数组 (注意:for-range在遍历字符串时,是按照字符来遍历的,而不是按照字节来的,请注意这点)

      tdRYFg.png

      上面代码的细节讨论

      ​ 如果我们的字符串含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。原因是传统的对字符串的遍历是按照字节来遍历,而一个汉字在utf8编码是对应3个字节

      如何解决

      ​ 需要将 str 转成 切片

    5.5.6 练习题

    打印1~100之间所有是9的倍数的个数及总和

    tdh6k8.png

    打印下图的方式

    td4PhD.png

    5.6 while 和 do....while的实现

    ​ Golang中是没有while和do...while,如果我们需要使用类似其他的语言(java c 的 while 和 do...wile),可以通过for循环来实现其效果。

    td4rv9.png

    说明上图

    • for循环是一个无限循环
    • break 语句就睡跳出 for循环

    使用上面的while实现

    捕获.PNG

    5.7 多重循环控制(重点难点)

    5.7.1 介绍

    • 将一个循环放在另一个循环体内,就形成了嵌套循环,在外边的for称为 外层循环在里面的for循环称为 内存循环 [建议一般使用两层,最多不要超过三层]
    • 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环体,才可结束外层的当次循环,开始下一次的循环。
    • 设外层循环次数为m次,内层循环n次,则内层循环实际上需要执行m*n =mn次

    编程时两大绝招

    • 先易后难,即将一个复杂的问题分解成简单的问题
    • 先死后活

    5.7.2 案例

    统计3个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入

    捕获.PNG

    统计3个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]

    package main
    import (
    	"fmt"
    )
    func main() {
    	//统计3个班成绩情况,每个班有5名同学,求出各个班的平均分
    	//和所有班级的平均分[学生的成绩从键盘输入]
    
    	// 分析实现思路1:先实现一个班的
    	// 1、统计1个班成绩情况,每个班有5名同学,求出该班的平均分
    	// 2、学生数就是5个[先死后活]
    	// 3、声明一个sum,统计班级的总分
    
    	// 分析思路2
    	// 1、 统计3个班成绩情况,每个班有5名同学,求出各个班的平均分
    	// 2、j 表示第几个班级
    	// 3、定义一个变量存放总成绩
    
    	// 分析思路3
    	// 1、代码做活
    	// 2、定义两个变量,表示班级的个数和每个班级的人数
    	var classNum int = 3
    	var stuNum int = 5
    	var totalSum float64 = 0.0
    	for j := 1; j <= classNum; j++ {
    		sum := 0.0
    		for i := 1; i <= stuNum; i++ {
    			var score float64
    			fmt.Printf("请输入第%d班,第%d个学生的成绩: 
    ", j, i)
    			fmt.Scanln(&score)
    			// 每个班的累计总分
    			sum += score
    		}
    			fmt.Printf("第%d个班级的平均分是%v 
    ", j, sum / float64(stuNum) )
    			// 将各个班的总成绩累计到 totalSum
    			totalSum += sum
    		}
    		fmt.Printf("各个班级的总成绩%v  所有班级平均分是%v
    ", totalSum, totalSum / float64((classNum * stuNum )) )
    	}		
    

    捕获.PNG

    统计三个班及格人数,每个班5名同学

    package main
    import (
    	"fmt"
    )
    func main() {
    	//统计3个班成绩情况,每个班有5名同学,求出各个班的平均分
    	//和所有班级的平均分[学生的成绩从键盘输入
    
    	// 分析实现思路1:先实现一个班的
    	// 1、统计1个班成绩情况,每个班有5名同学,求出该班的平均分
    	// 2、学生数就是5个[先死后活]
    	// 3、声明一个sum,统计班级的总分
    
    	// 分析思路2
    	// 1、 统计3个班成绩情况,每个班有5名同学,求出各个班的平均分
    	// 2、j 表示第几个班级
    	// 3、定义一个变量存放总成绩
    
    	// 分析思路3
    	// 1、代码做活
    	// 2、定义两个变量,表示班级的个数和每个班级的人数
    
    	// 分析思路4
    	// 1、声明一个变量passcount用于保存及格人数
    
    	var classNum int = 2
    	var stuNum int = 3
    	var totalSum float64 = 0.0
    	var passCount int = 0
    	for j := 1; j <= classNum; j++ {
    		sum := 0.0
    		for i := 1; i <= stuNum; i++ {
    			var score float64
    			fmt.Printf("请输入第%d班,第%d个学生的成绩: 
    ", j, i)
    			fmt.Scanln(&score)
    			// 每个班的累计总分
    			sum += score
    			//判断分数是否及格
    			if  score >= 60 {
    				passCount++
    			}
    		}
    			fmt.Printf("第%d个班级的平均分是%v 
    ", j, sum / float64(stuNum) )
    			// 将各个班的总成绩累计到 totalSum
    			totalSum += sum
    		}
    		fmt.Printf("各个班级的总成绩%v  所有班级平均分是%v
    ", totalSum, totalSum / float64((classNum * stuNum )) )
    		fmt.Printf("及格人数为%v", passCount)
    	}		
    

    捕获.PNG

    打印金字塔经典案例

    t0YT7q.png

    t0tEge.png

    t0N9MQ.png

    t0NgSS.png

    t0aoxU.png

    打印九九乘法表

    t0082V.png

    5.8 跳转控制语句- break

    5.8.1看一个具体的需求

    随机生成1-100的一个数,直到生成了99这个数,看看你一共用了几次

    ​ 分析:编写一个 无限循环的控制,然后不停的随机生成一个数,当生成了99时,就退出无限循环 ==》break

    t0yBj0.png

    5.8.2 基本介绍

    beak语句用来终止 某个语句块的执行,用于中断当前for循环或跳出switch语句

    5.8.3 基本语法

    {
        ......
        break;
        .....
    }
    

    t02CVK.png

    5.8.4 注意事项和细节说明

    • breeak语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块

    t0WGBq.png

    对上面的代码说明

    • break 默认会跳出最近的for循环
    • break 后面可以指定标签,跳出标签对应的for循环

    5.8.5 案例

    100以内的数求和,求出当和第一次大于20的当前数

    t04ZH1.png

    实现登陆验证,有三次机会,如果用户名为"张无忌",密码"888",提示登陆成功,否则提示还有几次机会

    t0IVFx.png

    5.9 跳转控制语句- continue

    5.9.1 基本介绍

    • continue 语句用于结束本次循环,继续执行下一次循环
    • continue语句出现在多层嵌套的循环语句中时,可以通过标签指明要跳过的是哪一层循环

    5.9.2 基本语法

    {
        ...
        continue;
        ...
    }
    

    t0orKe.png

    5.9.3 案例

    t0Hga9.png

    continue实现打印1-100之内的奇数{}要求使用for循环+continue

    t0L94s.png

    从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序

    t0Xk0U.png

    5.10 跳转控制语句- goto

    5.10.1 基本介绍

    • Go语言的 goto 语句可以无条件地转移到程序中指定的行
    • goto 语句通常 与条件语句配合使用,可用来实现条件转移,跳出循环体等功能
    • 在Go程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难

    5.10.2 基本语法

    goto label
    ....
    label: statement
    

    tBP4Ds.png

    tBPq8U.png

    5.11 跳转控制语句- return

    5.11.1 介绍

    return使用在方法,表示跳出所在的函数或方法

    tBiOFP.png

  • 相关阅读:
    poj 2528 Mayor's posters (线段树+离散化)
    poj 1201 Intervals (差分约束)
    hdu 4109 Instrction Arrangement (差分约束)
    poj 1195 Mobile phones (二维 树状数组)
    poj 2983 Is the Information Reliable? (差分约束)
    树状数组 讲解
    poj 2828 Buy Tickets (线段树)
    hdu 1166 敌兵布阵 (树状数组)
    Ubuntu网络配置
    Button控制窗体变量(开关控制灯的状态)
  • 原文地址:https://www.cnblogs.com/jiaxiaozia/p/13037350.html
Copyright © 2020-2023  润新知