Go第 5 章:程序流程控制

第五章程序流程控制

5.1程序流程控制介绍

在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控 制语句。
1)顺序控制
2)分支控制
3)循环控制


5.2 顺序控制

程序从上到下逐行地执行,中间没有任何判断和跳转。
一个案例说明,必须下面的代码中,没有判断,也没有跳转。因此程序按照默认的流程执行,即顺
序控制。
请添加图片描述

5.2.1顺序控制的一个流程图

请添加图片描述

5.2.2顺序控制举例和注意事项

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

func main() {
	var num1 int = 10 //声明了 num1 
	var num2 int = num1 + 20 //使用 num1 
	fmt.Println(num2)
}

错误形式:

func main() {
	var num2 int = num1 + 20 //使用 num1 
	var num1 int = 10 //声明 num1 (×) 
	fmt.Println(num2)
}

5.3 分支控制

5.3.1分支控制的基本介绍
分支控制就是让程序有选择执行。有下面三种形式

  1. 单分支
  2. 双分支
  3. 多分支
5.3.2单分支控制

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

5.3.3双分支控制

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
对双分支的总结

  1. 从上图看 条件表达式就是 age >18
  2. 执行代码块 1 => fmt.Println(“你的年龄大于 18”) …
  3. 执行代码块 2 ===> fmt.Println(“你的年龄不大…”) .
  4. 强调一下 双分支只会执行其中的一个分支。
5.3.5多分支控制

请添加图片描述
对上面基本语法的说明

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

看一个多分支的流程图(更加清晰)
请添加图片描述
案例

岳小鹏参加 Golang 考试,他和父亲岳不群达成承诺:
如果:
成绩为 100 分时,奖励一辆 BMW;
成绩为(80,99]时,奖励一台 iphone7plus;
当成绩为[60,80]时,奖励一个 iPad;
其它时,什么奖励也没有。
请从键盘输入岳小鹏的期末成绩,并加以判断
代码如下:

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

5.3.6嵌套分支

请添加图片描述
请添加图片描述
请添加图片描述


5.4 switch 分支控制

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

请添加图片描述
请添加图片描述
对上图的说明和总结

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

请添加图片描述

5.4.5switch 的使用的注意事项和细节
  1. case/switch 后是一个表达式( 即:常量值变量一个有返回值的函数等都可以)
    请添加图片描述
  2. case 后的各个表达式的值的数据类型,必须和 switch 的表达式数据类型一致
    请添加图片描述
  3. case 后面可以带多个表达式,使用逗号间隔。比如 case 表达式 1, 表达式 2 …
    请添加图片描述
  4. case 后面的表达式如果是常量值(字面量),则要求不能重复
    请添加图片描述
  5. case 后面不需要带 break , 程序匹配到一个 case 后就会执行对应的代码块,然后退出 switch,如 果一个都匹配不到,则执行 default
  6. default 语句不是必须的.
  7. switch 后也可以不带表达式,类似 if --else 分支来使用。【案例演示】
    请添加图片描述
  8. switch 后也可以直接声明/定义一个变量,分号结束,不推荐。 【案例演示】
    请添加图片描述
  9. switch 穿透-fallthrough ,如果在 case 语句块后增加 fallthrough ,则会继续执行下一个 case,也 叫 switch 穿透
    请添加图片描述
  10. Type Switch:switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际指向的 变量类型 【还没有学 interface, 先体验一把】
    请添加图片描述
5.4.6switch 的课堂练习
  1. 使用 switch 把小写类型的 char 型转为大写(键盘输入)。只转换 a, b, c, d, e. 其它的输出
    “other”。
    请添加图片描述
  2. 对学生成绩大于 60 分的,输出“合格”。低于 60 分的,输出“不合格”。(注:输入的成绩不 能大于 100)
    请添加图片描述
  3. 根据用户指定月份,打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬 季
    请添加图片描述
package main

import "fmt"

func main() {
	var num int = 10
	switch num {
	case 10:
		var month byte
		fmt.Println("imput month")
		fmt.Scanln(&month)

		switch month {
		case 3,4,5:
			fmt.Println("spring")
		case 6,7,8:
			fmt.Println("summer")
		case 9,10,11:
			fmt.Println("autumn")
		case 12,1,2:
			fmt.Println("winter")
		default:
			fmt.Println("error")
		}
		fallthrough
	case 20:
		fmt.Println("ok2")
		fallthrough
	case 30:
		fmt.Println("ok3")
	default:
		fmt.Println("no")

	}

}

5.4.7switch 和 if 的比较

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

  1. 如果判断的具体数值不多,而且符合整数、浮点数、字符、字符串这几种类型。建议使用 swtich
    语句,简洁高效。
  2. 其他情况:对区间判断和结果为 bool 类型的判断,使用 if,if 的使用范围更广。

5.5 for 循环控制 5.5.1基本介绍

听其名而知其意。就是让我们的一段代码循环的执行。

5.5.2一个实际的需求

 请大家看个案例 [forTest.go]:
编写一个程序, 可以打印 10 句
“你好,尚硅谷!”。请大家想想怎么做?
 使用传统的方式实现
请添加图片描述
请添加图片描述

5.5.3for 循环的基本语法

请添加图片描述
3) 如果循环条件为真,就执行循环操作 :比如 fmt.Println(“…”)
4) 执行循环变量迭代 , 比如 i++
5) 反复执行 2, 3, 4 步骤,直到 循环条件为 False ,就退出 for 循环。
请添加图片描述
对照代码分析 for 循环的执行过程
请添加图片描述

5.5.5for 循环的使用注意事项和细节讨论
  1. 循环条件是返回一个布尔值的表达式
  2. for 循环的第二种使用方式
    for 循环判断条件 {
    //循环执行语句 } 将变量初始化和变量迭代写到其它位置

请添加图片描述
3) for 循环的第三种使用方式
for {
//循环执行语句 } 上面的写法等价 for ; ; {} 是一个无限循环, 通常需要配合 break语句使用
请添加图片描述
4) Golang 提供 for-range 的方式,可以方便遍历字符串和数组(注: 数组的遍历,我们放到讲数组 的时候再讲解) ,案例说明如何遍历字符串。
请添加图片描述
字符串遍历方式 2-for - range
请添加图片描述
上面代码的细节讨论
如果我们的字符串含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。原因是传统的 对字符串的遍历是按照字节来遍历,而一个汉字在 utf8 编码是对应 3 个字节。
请添加图片描述
请添加图片描述

5.5.6for 循环的课堂练习
  1. 打印 1~100 之间所有是 9 的倍数的整数的个数及总和

请添加图片描述

  1. 完成下面的表达式输出 ,6 是可变的
package main

import "fmt"

func main () {
	var j int = 6
	for i := 0 ; i < j ; i ++ {
		fmt.Printf("%v + % v = %v \n", i, j-i , j)
	}
}

5.6 while 和 do…while 的实现

Go 语言没有 while 和 do…while 语法,这一点需要同学们注意一下,如果我们需要使用类似其它语 言(比如 java / c 的 while 和 do…while ),可以通过 for 循环来实现其使用效果。

5.6.1while 循环的实现

请添加图片描述
说明上图

  1. for 循环是一个无限循环
  2. break 语句就是跳出 for 循环

 使用上面的 while 实现完成输出 10 句”hello,wrold”请添加图片描述

5.6.2do…while 的实现

对上图的说明

  1. 上面的循环是先执行,在判断,因此至少执行一次。
  2. 当循环条件成立后,就会执行 break, break 就是跳出 for 循环,结束循环.  案例演示
    使用上面的 do…while实现完成输出 10 句”hello,ok”
    请添加图片描述

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

  1. 将一个循环放在另一个循环体内,就形成了嵌套循环。在外边的 for 称为外层循环在里面的 for 循环称为内层循环。
    【建议一般使用两层,最多不要超过 3 层】
  2. 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为 false 时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。
  3. 外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次
5.7.2应用案例
  1. 统计 3 个班成绩情况,每个班有 5 名同学,求出各个班的平均分和所有班级的平均分[学生的成
    绩从键盘输入]
    编程时两大绝招
    (1) 先易后难, 即将一个复杂的问题分解成简单的问题。 (2) 先死后活
    代码:
package main

import (
	"fmt"
)

func main() {

	var score float32 = 0.0
	var count1 int = 5
	//var count2 int = 0
	var sum float32 = 0.0
	var totalsum float32 = 0.0
	for i := 1; i <= 3; i++ {
		for j := 1; j <= 5; j++ {
			fmt.Printf("请输入%v班学生%v的成绩:\n", i, j)
			fmt.Scanln(&score)
			sum += score
		}
		fmt.Printf("%v班的平均分为:%v \n", i, sum/float32(count1))
		totalsum += sum
		sum = 0.0
	}
	fmt.Printf("各个班总成绩为:%v,所有班的平均分为L:%v \n", totalsum, totalsum/float32(count1))
}

  1. 统计三个班及格人数,每个班有 5 名同学
    对上面的代码进行了一点修改.
package main

import (
	"fmt"
)

func main() {
	//var j int = 6
	//for i := 0 ; i < j ; i ++ {
	//	fmt.Printf("%v + % v = %v \n", i, j-i , j)
	//}
	var score float32 = 0.0
	var count1 int = 5
	//var count2 int = 0
	var sum float32 = 0.0
	var totalsum float32 = 0.0
	var passCount int = 0
	for i := 1; i <= 3; i++ {
		for j := 1; j <= 5; j++ {
			fmt.Printf("请输入%v班学生%v的成绩:\n", i, j)
			fmt.Scanln(&score)
			sum += score

			if score > 60 {
				passCount++
			}
		}
		fmt.Printf("%v班的平均分为:%v,及格人数为:%v \n", i, sum/float32(count1), passCount)
		totalsum += sum
		sum = 0.0
		passCount = 0
	}
	fmt.Printf("各个班总成绩为:%v,所有班的平均分为L:%v \n", totalsum, totalsum/float32(count1))
}

  1. 打印金字塔经典案例
    使用 for 循环完成下面的案例请编写一个程序,可以接收一个整数,表示层数,打印出金字
     分析编程思路
    请添加图片描述请添加图片描述

请添加图片描述
4) 打印出九九乘法表
请添加图片描述
请添加图片描述

5.8 跳转控制语句-break

5.8.1看一个具体需求,引出 break

随机生成 1-100 的一个数,直到生成了 99 这个数,看看你一共用了几次? 分析:编写一个无限循环的控制,然后不停的随机生成数,当生成了 99 时,就退出这个无限循环
==》break 提示使用
这里我们给大家说一下,如下随机生成 1-100 整数.

5.8.2break 的快速入门案例

请添加图片描述

5.8.3基本介绍:

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

5.8.4基本语法:

{ ……
break ……
}

5.8.5以 for 循环使用 break 为例,画出示意图

请添加图片描述

5.8.6break 的注意事项和使用细节
  1. break 语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
  2. 看一个案例
    请添加图片描述
  3. 对上面案例的说明
    (1) break 默认会跳出最近的 for 循环
    (2) break 后面可以指定标签,跳出标签对应的 for 循环
5.8.7课堂练习
  1. 100 以内的数求和,求出 当和 第一次大于 20 的当前数
    请添加图片描述
  2. 实现登录验证,有三次机会,如果用户名为”张无忌” ,密码”888”提示登录成功,否则提示 还有几次机会.
    请添加图片描述

5.9 跳转控制语句-continue

5.9.1基本介绍:

continue 语句用于结束本次循环,继续执行下一次循环。 continue 语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环 ,
这个和前面的 break 标签的使用的规则一样.

5.9.2基本语法:

{ ……
continue ……
}

5.9.3continue 流程图

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

课后练习题(同学们课后自己完成):

某人有 100,000 元,每经过一次路口,需要交费,规则如下:
当现金>50000 时,每次交 5%
当现金<=50000时,每次交 1000
编程计算该人可以经过多少次路口,使用 for break 方式完成

func main() {
   var moneny int = 100000
   count := 0
   for {
   	if moneny > 50000 {
   		moneny = moneny - int(float64(moneny)*0.05)
   		fmt.Println("1", moneny)
   	}
   	if moneny < 50000 {
   		moneny = moneny - 1000
   		fmt.Println("2", moneny)
   	}
   	if moneny < 1000 {
   		break
   	}
   	count++
   }
   fmt.Println(count)
}

5.10 跳转控制语句-goto

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

goto label
… .
label: statement

5.10.3 goto 的流程图

请添加图片描述

5.10.4 快速入门案例
package main

import "fmt"

func main(){
	var n int
	fmt.Println("请输入数字n:")
	fmt.Scanln(&n)
	fmt.Println("ok1")
	if n>20{
		goto label1
	}
	fmt.Println("ok1")
	fmt.Println("ok1")
	fmt.Println("ok1")
	label1:
	fmt.Println("ok1")
	fmt.Println("ok1")
	fmt.Println("ok1")

}

5.11 跳转控制语句-return

5.11.1 介绍:

return 使用在方法或者函数中,表示跳出所在的方法或函数,在讲解函数的时候,会详细的介绍。
请添加图片描述
说明

  1. 如果 return 是在普通的函数,则表示跳出该函数,即不再执行函数中 return 后面代码,也可以 理解成终止函数。
  2. 如果 return 是在 main 函数,表示终止 main 函数,也就是说终止程序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值