• 五、程序流程控制


    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

  • 相关阅读:
    深入剖析ASP.NET的编译原理之二:预编译(Precompilation)
    六个建议防止SQL注入式攻击
    微软IIS的ISAPI筛选器权限法则
    IIS属性没有ASP.NET选项
    让我们的服务器更安全Win03 防木马权限设置,IIS服务器安全配置
    IIS自动停止,iis自动关闭。应用程序池假死、自动重启以及iis权限等解决办法
    深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)
    c#操作xml
    C# 容易出现insert into语句的语法错误的原因
    兼容ie/火狐的全能日历代码含农历
  • 原文地址:https://www.cnblogs.com/jiaxiaozia/p/13037350.html
Copyright © 2020-2023  润新知