【Go笔记】第 5 章 程序流程控制

9/21/2022 韩顺平尚硅谷golang笔记

# 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)
}
1
2
3
4
5
6
7
8
9
10
11
12

# 5.3 分支控制

# 5.3.1分支控制的基本介绍

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

  1. 单分支
  2. 双分支
  3. 多分支

# 5.3.2单分支控制

基本语法:

	if 条件表达式{
		执行代码
	}
1
2
3

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

🏷 应用案例 请大家看个案例[ifDemo.go]: 编写一个程序,可以输入人的年龄, 如果该同志的年龄大于 18 岁,则输出 "你年龄大 于 18,要对自己的行为负责!" 需求---[分析]---->代码 代码:

func main() {  
   //请大家看个案例【ifDemo.go】  
   //编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,则输出“你的年龄大于18,要对自己的行为负责”  
   //分析:  
   //1. 年龄 ==> var age int   
   //2. 从控制台接收一个输入 fmt.Scanln(&age)  
	 //3. if 判断  
  
   var age int  
   fmt.Println("请输入年龄:")  
   fmt.Scanln(&age)  
  
   if age > 18 {  
      fmt.Println("你的年龄大于18,要对自己的行为负责")  
   }  
  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

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

🏷 单分支的细节说明

//golang 支持在if中,直接定义一个变量,比如下面:
if age := 20;age > 18 {
	 fmt.Println("您的年龄大于18,要对自己的行为负责")
}
1
2
3
4

5.3.3双分支控制 🏷 基本语法

if 条件表达式 {
	执行代码块1
}else{
	执行代码块2
}
1
2
3
4
5

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

🏷 应用案例 请大家看个案例[IfDemo2.go]: 编写一个程序,可以输入人的年龄, 如果该同志的年龄大于 18 岁,则输出 “你年龄大于 18,要对自己的行为负责!”。则 否则 ,输出”你的年龄不大这次放过你了.”

func main() {  
   //请大家看个案例【ifDemo.go】  
   //编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,则输出“你的年龄大于18,要对自己的行为负责”  
   //分析:  
   //1. 年龄 ==> var age int   
   //2. 从控制台接收一个输入 fmt.Scanln(&age)   
   //3. if 判断  
  
   var age int  
   fmt.Println("请输入年龄:")  
   fmt.Scanln(&age)  
  
   if age > 18 {  
      fmt.Println("你的年龄大于18,要对自己的行为负责")  
   }  else {
	    fmt.Println("年龄不大,这次放过你")  
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

🏷 双分支的流程图的分析

对双分支的总结

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

# 5.3.4单分支和双分支的案例

  1. 对下列代码,若有输出,支出输出结果
var x int = 4
var y int = 1
if(x>2){
	if(y>2){
	  fmt.Println(x+y)
	}
  fmt.Println("atguigu")
}else{
 fmt.Println("x is ",x)
}
//输出结果是atguigu
1
2
3
4
5
6
7
8
9
10
11
  1. 对下列代码,若有输出,支出输出结果
var x int =4
if x>2 
fmt.Println("ok")
else
fmt.PrintIn("hello")
//编译错误,原因没有{}

1
2
3
4
5
6
7
  1. 对下列代码,若有输出,支出输出结果
var x int =4
if x>2{
	fmt.Println("ok")
}
else{
	fmt.Println("hello")
}
//编程错误,原因是else不能换行
1
2
3
4
5
6
7
8
  1. 对下列代码,若有输出,支出输出结果
var x int=4
if(x>2)(
	fmt.Println("ok~")
}else{
	fmt.PrintIn("hello")
}
//正确,输出ok
//虽然正确,但是我们要求大家f(x>2)要求写成ifx>2{
1
2
3
4
5
6
7
8
  1. 编写程序,声明 2 个 int32 型变量并赋值。判断两数之和,如果大于等于 50,打印“hello world!

package main  
  
import (  
   "fmt"  
)  
  
func main() {  
   //编写程序,声明2个int32型变量并赋值。判断两数之和,如果大于等于50,打印he11owor1dI”  
   //分析  
   //1.变量  
   //2.单分支  
  
   var n1 int32 = 10  
   var n2 int32 = 50  
   if n1+n2 >= 50 {  
      fmt.Println("hello,world")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  1. 编写程序,声明 2 个 float64 型变量并赋值。判断第一个数大于 10.0,且第 2 个数小于 20.0,打印两数之和。

package main  
  
import (  
   "fmt"  
)  
  
  
func main() {  
   //编写程序,声明2个f1oat64型变量并赋值。判断第一个数大于10.0,  
   //且第2个数小于20.0,打印两数之和  
   var n3 float64 = 11.0  
   var n4 float64 = 17.0  
   if n3 > 10.0 && n4 < 20.0 {  
      fmt.Println("和=", (n3 + n4))  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. 【选作】定义两个变量 int32,判断二者的和,是否能被 3 又能被 5 整除,打印提示信息

package main  
  
import (  
   "fmt"  
)  
  
//8)判断一个年份是否是闰年,闰年的条件是符合下面二者之一  
//(1)年份能被4整除,但不能被100整除:(2)能被400整除  
func main() {  
   var num1 int32 = 10  
   var num2 int32 = 5  
   if (num1+num2)%3 == 0 && (num1+num2)%5 == 0 {  
      fmt.Println("能被3又能被5整除")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. 判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被 4 整除,但不能被 100整除;(2)能被 400 整除

package main  
  
import (  
   "fmt"  
)  
  
//8)判断一个年份是否是闰年,闰年的条件是符合下面二者之一  
//(1)年份能被4整除,但不能被100整除:(2)能被400整除  
func main() {  
   var year int = 2019  
   if (year%4 == 0 && year%100 != 0) || year%400 == 0 {  
      fmt.Println(year, "是闰年")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 5.3.5多分支控制

🏷 基本语法

if 条件表达式1 {
	执行代码块1
}else if条件表达式2{
	执行代码块2
}
...
else {
	执行代码块n
}
1
2
3
4
5
6
7
8
9

对上面基本语法的说明

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

🏷 看一个多分支的流程图(更加清晰)

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


package main  
  
import (  
   "fmt"  
)  
  
func main() {  
   //1其它时,什么奖励也没有。  
   //请从键盘输入岳小鹏的期末成绩,并加以判断  
   //1分析思路  
   //11.score 分数变量int  
   //12.选择多分支流程控制  
   //3.成绩从键盘输入fmt.scanln  
   var score int  
   fmt.Println("请输入成绩:")  
   fmt.Scanln(&score)  
  
   //多分支判断  
   if score == 100 {  
      fmt.Println("奖励一辆BMw")  
   } else if score == 80 && score <= 99 {  
      fmt.Println("奖励一台iphone7plus")  
   } else if score > 60 && score < 80 {  
      fmt.Println("奖励一个iPad")  
   } else {  
      fmt.Println("什么都不奖励")  
   }  
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

对初学者而言,有一个使用陷阱.


package main  
  
import (  
   "fmt"  
)  
  
func main() {  
   //使用陷阱.  
   //只会输出ok1.  
   var n int = 10  
   if n > 9 {  
      fmt.Println("ok1") //输出ok1  
   } else if n > 6 {  
      fmt.Println("ok2")  
   } else if n > 3 {  
      fmt.Println("ok3")  
   } else {  
      fmt.Println("ok4")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

🏷 多分支的课堂练习

案例 2:

package main  
  
import (  
   "fmt"  
)  
  
func main() {  
   var b bool = true  
   if b == false {  
      //如果写成b=false;能编译通过吗?如果能,结果是?  
      fmt.Println("a")  
   } else if b {  
      fmt.Println("b")  
   } else if !b {  
      fmt.Println("c") //c  
   } else {  
      fmt.Println("d")  
   }  
}

//输出结果是b
//如果写成b=lse;能编译通过吗?如果能,结果是?【编程错误,if的条件表达式不能是赋值语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

案例 3: 求ax2+bx+c=0方程的根。a,b,c分别为函数的参数,如果:b2-4ac>0,则有两个解; b2-4ac=0,则有一个解;b2-4ac<0,则无解; 提示1:x1=(b+sqrt(b2-4ac)/2a X2=(-b-sqrt(b2-4ac))/2a 提示2:math.Sqrt(num;可以求平方根需要引入math包 测试数据:3,100,6

代码:


package main  
  
import (  
   "fmt"  
   "math")  
  
func main() {  
   //分析思路  
   //1,a,b,c是三个f1oat64  
   //2.使用到给出的数学公式  
   //3.使用到多分支  
   //14.  
   //使用math.squr方法=》手册  
   //走代码  
   var a float64 = 2.0  
   var b float64 = 4.0  
   var c float64 = 2.0  
  
   m := b*b - 4*a*c  
   //多分支判断  
   if m > 0 {  
      x1 := (-b + math.Sqrt(m)) / 2 * a  
      x2 := (-b - math.Sqrt(m)) / 2 * a  
      fmt.Printf("x1=%v x2=%v", x1, x2)  
   } else if m == 0 {  
      x1 := (-b + math.Sqrt(m)) / 2 * a  
      fmt.Printf("x1=%v", x1)  
   } else {  
      fmt.Println("无解..")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

🏷 案例演示4 大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条180cm以上:富:财富1千万以上;帅:是。条件从控制台输入。 1)如果这三个条件同时满足,则:“我一定要嫁给他!” 2) 如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。” 3) 如果三个条件都不满足,则:“不嫁!”

var height int32 | var money float32 | var handsome bool

代码:


package main  
  
import "fmt"  
  
func main() {  
   //分析思路  
   //1,应该设计三个变量var height int32|var money float32|var handsome bool  
   //2.而且需要从终端输入fmt.Scanln  
   //3.使用多分支if-e1seif--e1se  
   var height int32  
   var money float32  
   var handsome bool  
  
   fmt.Println("请输入身高(厘米)")  
   fmt.Scanln(&height)  
   fmt.Println("请输入财富(千万)")  
   fmt.Scanln(&money)  
   fmt.Println("请输入是否帅(true/false)")  
   fmt.Scanln(&handsome)  
  
   if height > 180 && money > 1.0 && handsome {  
      fmt.Println("我一定要嫁给他!I!")  
   } else if height > 180 || money > 1.0 || handsome {  
      fmt.Println("嫁吧,比上不足,比下有余")  
   } else {  
      fmt.Println("不嫁..")  
   }  
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

5.3.6嵌套分支 🏷 基本介绍 在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分 支外面的分支结构称为外层分支。 🏷 基本语法

if 条件表达式 {
	if 条件表达式 {

	}else{
	
	}
}else{

}
1
2
3
4
5
6
7
8
9

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

🏷 应用案例 1 参加百米运动会,如果用时 8 秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。【可以让学员先练习下】, 输入成绩和性别。

代码:


package main  
  
import "fmt"  
  
func main() {  
   //分析思路  
   //1.定义一个变量,来接收跑步使用秒数.f1oat64  
   //2.定义一个变量,来接收性别string  
   //3.因为判断是嵌套的判断,因此我们会使用嵌套分支  
   var second float64  
   fmt.Println("请输入秒数")  
   fmt.Scanln(&second)  
  
   if second <= 8 {  
      //进入决赛  
      var gender string  
      fmt.Println("请输入性别")  
      fmt.Scanln(&gender)  
  
      if gender == "男" {  
         fmt.Println("进入决赛的男子组")  
      } else {  
         fmt.Println("进入决赛的女子组")  
      }  
   } else {  
      fmt.Println("out...")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

🏷 应用案例 2 出票系统:根据淡旺季的月份和年龄,打印票价 [考虑学生先做] 4_10 旺季: 成人(18-60):60 儿童(<18):半价 老人(>60):1/3 淡季: 成人:40 其他:20

代码:


package main  
  
import "fmt"  
  
func main() {  
   //分析思路  
   //1.month age的两个变量byte  
   //2.使用嵌套分支  
  
   var month byte  
   var age byte  
   var price float64 = 60.0  
   fmt.Println("请输入游玩月份")  
   fmt.Scanln(&month)  
   fmt.Println("请输入游客的年龄")  
   fmt.Scanln(&age)  
  
   if month >= 4 && month <= 10 {  
      if age > 60 {  
         fmt.Printf("%v月票价w年龄%v", month, price/3, age)  
      } else if age > 18 {  
         fmt.Printf("%v月票价%v年龄%v", month, price, age)  
      } else {  
         fmt.Printf("%v月票价v年龄%v", month, price/2, age)  
      }  
  
   } else {  
      //淡季  
      if age >= 18 && age < 60 {  
         fmt.Println("淡季成人票价4o")  
      } else {  
         fmt.Println("淡季成人票价4o")  
      }  
   }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 5.4 switch 分支控制

# 5.4.1基本的介绍

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

# 5.4.2基本语法

switch 表达式 {
	case 表达式1,表达式2,...:
		语句块1
	case 表达式3,表达式4,...:
		语句块2	
	//这里可以有很多case语句

	default:
		语句块
}
1
2
3
4
5
6
7
8
9
10

# 5.4.3switch 的流程图

对上图的说明和总结

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

# 5.4.4switch 快速入门案例

🏷 案例: 请编写一个程序,该程序可以接收一个字符,比如: a,b,c,d,e,f,g a表示星期一,b表示星期二 … 根据用户的输入显示相依的信息.要求使用 switch 语句完成

🏷 代码


package main  
  
import "fmt"  
  
func main() {  
   //分析思路  
   //1.定义一个变量接收字符  
   //2.使用switch完成  
   var key byte  
   fmt.Println("请输入一个字符a,b,c,d,e,f,g")  
   fmt.Scanf("%c", &key)  
  
   switch key {  
   case 'a':  
      fmt.Println("周一,猴子穿新衣")  
   case 'b':  
      fmt.Println("周二,猴子当小二")  
   case 'c':  
      fmt.Println("周三,猴子爬雪山")  
   //...  
   default:  
      fmt.Println("输入有误..")  
   }  
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 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 分支来使用。【案例演示】

package main  
  
import "fmt"  
  
func main() {  
   //switch后也可以不带表达式,类似if--else分支来使用。【案例演示】  
   var age int = 10  
   switch {  
   case age == 10:  
      fmt.Println("age =10")  
   case age == 20:  
      fmt.Println("age ==20")  
   default:  
      fmt.Println("没有匹配到")  
   }  
  
   //case中也可以对范围进行判断  
   var score int = 90  
   switch {  
   case score > 90:  
      fmt.Println("成绩优秀.")  
   case score >= 70 && score <= 90:  
      fmt.Println("成绩优良.:.")  
   case score >= 60 && score < 70:  
      fmt.Println("成续及格.:.")  
   default:  
      fmt.Println("不及格")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  1. switch 后也可以直接声明/定义一个变量,分号结束, 不推荐。 【案例演示】
package main  
  
import "fmt"  
  
func main() {  
   //switch的穿透fallthrough  
   var num int = 10  
   switch num {  
   case 10:  
      fmt.Println("ok1")  
      fallthrough //默认只能穿透一层  
   case 20:  
      fmt.Println("ok2")  
      fallthrough  
   case 30:  
      fmt.Println("ok3")  
   default:  
      fmt.Println("没有匹配到..")  
   }  
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. Type Switch:switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际指向的变量类型 【还没有学 interface, 先体验一把】

package main  
  
import "fmt"  
  
func main() {  
   var x interface{}  
   var y = 10.0  
   x = y  
   switch i := x.(type) {  
   case nil:  
      fmt.Printf("x的类型~:%T", i)  
   case int:  
      fmt.Printf("x是int型")  
   case float64:  
      fmt.Printf("x是f1oat64型")  
   case func(int) float64:  
      fmt.Printf("x是func(int)型")  
   case bool, string:  
      fmt.Printf("x是bool或string型")  
   default:  
      fmt.Printf("未知型")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 5.4.6switch 的课堂练习

  1. 使用 switch 把小写类型的 char 型转为大写(键盘输入)。只转换 a, b, c, d, e. 其它的输出“other”。

package main  
  
import "fmt"  
  
func main() {  
   //1)使用switch把小写类型的char型转为大写(键盘输入)。只转换a,b,c,d,e,其它的输出“other”。  
   var char byte  
   fmt.Println("请输入一个字符.")  
   fmt.Scanf("%c", &char)  
  
   switch char {  
   case 'a':  
      fmt.Println("A")  
   case 'b':  
      fmt.Println("B")  
   case 'c':  
      fmt.Println("C")  
   case 'd':  
      fmt.Println("D")  
   case 'e':  
      fmt.Println("E")  
   default:  
      fmt.Println("other")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  1. 对学生成绩大于 60 分的,输出“合格”。低于 60 分的,输出“不合格”。(注:输入的成绩不能大于 100)

package main  
  
import "fmt"  
  
func main() {  
   //2)对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。  
   //(注:输入的成绩不能大于180)  
   var score float64  
   fmt.Println("请输入成绩")  
   fmt.Scanln(&score)  
   switch int(score / 60) {  
   case 1:  
      fmt.Println("及格")  
   case 0:  
      fmt.Println("不及格")  
   default:  
      fmt.Println("输入有误..")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1. 根据用户指定月份,打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季

package main  
  
import "fmt"  
  
func main() {  
   //13)根据用户指定月份,  
   //打印该月份所属的季节。3,4,5春季6,7,8夏季9,18,11秋季12,1,2冬季  
   var month byte  
   fmt.Println("请输入月份")  
   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("输入有误.")  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 5.4.7switch 和 if 的比较

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

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

# 5.5 for 循环控制

# 5.5.1基本介绍

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

# 5.5.2 一个实际的需求

🏷 请大家看个案例 [forTest.go]: 编写一个程序, 可以打印 10 句 "你好,尚硅谷!"。请大家想想怎么做?

🏷 使用传统的方式实现

func main(){
//输出10句"你好,尚硅谷
//fmt.Println("你好,尚硅谷")
//fmt.PrintIn("你好,尚硅谷")
//fmt.Println("你好,尚硅谷")
//fmt.Println("你好,尚硅谷")
//fmt.Println("你好,尚硅谷")
//fmt.PrintIn("你好,尚硅谷")
//fmt.Printin("你好,尚硅谷")
//fmt.Println("你好,尚硅谷")
1
2
3
4
5
6
7
8
9
10

🏷 for 循环的快速入门


package main  
  
import "fmt"  
  
func main() {  
   //golang中,有循环控制语句来处理循环的执行某段代码的方法->for循环  
   //for循环快速入门  
   for i := 1; i <= 18; i++ {  
      fmt.Println("你好,尚硅谷", i)  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12

# 5.5.3 for 循环的基本语法

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

🏷 对上面的语法格式说明

  1. 对 for 循环来说,有四个要素:
  2. 循环变量初始化
  3. 循环条件
  4. 循环操作(语句) ,有人也叫循环体。
  5. 循环变量迭代

🏷 for 循环执行的顺序说明:

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

# 5.5.4 for 循环执行流程分析

🏷 for 循环的流程图

🏷 对照代码分析 for 循环的执行过程

# 5.5.5 for 循环的使用注意事项和细节讨论

  1. 循环条件是返回一个 布尔值的表达式
  2. for 循环的第二种使用方式

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

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

🏷 案例演示:


package main  
  
import "fmt"  
  
func main() {  
   //for循环的第二种写法  
   j := 1        //循环变量初始化  
   for j <= 18 { //循环条件  
      fmt.Println("你好,尚硅谷", j)  
      j++ //循环变量迭代  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. for 循环的第三种使用方式 for { //循环执行语句 }

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


package main  
  
import "fmt"  
  
func main() {  
   //for循环的第三种写法,这种写法通常会配合break使用  
   k := 1  
   for { //这里也等价for;;{  
      if k <= 10 {  
         fmt.Println("ok", k)  
      } else {  
         break //break就是跳出这个for循环  
         k++  
      }  
  
   }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. Golang 提供 for-range 的方式,可以方便遍历字符串和数组(注: 数组的遍历,我们放到讲数组 的时候再讲解) , 案例说明如何遍历字符串。 🏷 字符串遍历方式 1-传统方式
package main  
  
import "fmt"  
  
func main() {  
   //字符串遍历方式1-传统方式  
   var str string = "hello,world!"  
   for i := 0; i < len(str); i++ {  
      fmt.Printf("%c\n", str[i]) //使用到下标..  
   }  
}
1
2
3
4
5
6
7
8
9
10
11

🏷 字符串遍历方式 2-for - range


package main  
  
import "fmt"  
  
func main() {  
   fmt.Println()  
   //字符串遍历方式2-for-range  
   str := "abc~ok"  
   for index, val := range str {  
      fmt.Printf("index=%d,val=%c \n", index, val)  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13

🏷 上面代码的细节讨论 如果我们的字符串含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。原因是传统的 对字符串的遍历是按照 字节来遍历,而一个汉字在 utf8 编码是对应 3 个字节。 如何解决 需要要将 str 转成 []rune 切片.=> 体验一把

//字符串遍历方式1-传统方式
var str string="hello,world!:北京"
str2 := []rune(str) //就是把str转成[]rune
for i:=0;i<len(str2);i++{
	fmt.Printf("%c\n",str2[i])//使用到下标..
}
1
2
3
4
5
6

对应 for-range 遍历方式而言,是按照字符方式遍历。因此如果有字符串有中文,也是 ok


package main  
  
import "fmt"  
  
func main() {  
   fmt.Println()  
   //字符串遍历方式2-for-range  
   str := "abc~ok上海别"  
   for index, val := range str {  
      fmt.Printf("index=%d,val=%c \n", index, val)  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.5.6 for 循环的课堂练习

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

package main  
  
import "fmt"  
  
func main() {  
   //打印1~1©0之间所有是9的倍数的整数的个数及总和  
   //1分析思路  
   //1.使用for循环对max进行遍历  
   //2.当一个数%9=0就是9的倍数  
   //3.我们需要声明两个变量count和sum来保存个数和总和  
   var max uint64 = 100  
   var count uint64 = 0  
   var sum uint64 = 0  
   var i uint64 = 1  
   for ; i <= max; i++ {  
      if i%9 == 0 {  
         count++  
         sum += i  
         fmt.Printf("count=%v sum=%v\n", count, sum)  
      }  
   }}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 5.6 while 和 do..while 的实现

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

# 5.6.1while 循环的实现

循环变量初始化
for{
	if 循环条件表达式{
	 break //跳出for循环.
	}
	循环操作(语句)
	循环变量迭代
}
1
2
3
4
5
6
7
8

🏷 说明上图

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

🏷 使用上面的 while 实现完成输出 10 句”hello,wrold”

func main(){
	//使用whi1e方式输出1g句"he11o,world"
	//循环变量初始化
	var i int =1
	for {
		if i > 10 {//循环条件
			break //跳出for循环,结束for循环
		}
			fmt.Println("hello,world",i)
		i++ //循环变量的迭代
	}
	fmt.Println("i=",i)
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.6.2 do..while 的实现

循环变量初始化
for{
	循环操作(语句)
	循环变量迭代
	if 循环条件表达式 {
			break //跳出for循环.
	}
}
1
2
3
4
5
6
7
8

🏷 对上图的说明

  1. 上面的循环是先执行,在判断,因此至少执行一次。
  2. 当循环条件成立后,就会执行 break, break 就是跳出 for 循环,结束循环.

🏷 案例演示 使用上面的 do...while 实现完成输出 10 句”hello,ok”

//使用的do,,,whi1e实现完成输出1g句he11o,ok“
var j int = 1
for {
	fmt.Println("hello,ok",j)
	j++ //循环变量的迭代
	if j > 10{
		break //break就是跳出for循环
	}
}
1
2
3
4
5
6
7
8
9

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

# 5.7.1基本介绍

  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() {  
   //1)统计3个班成绩情况,每个班有5名同学,  
   //求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]  
   
   //分析实现思路  
   //1.统计1个班成绩情况,每个班有5名同学,求出该班的平均分【学生的成绩从键盘输入】=》先易后  
   //2.学生数就是5个[先死后活]  
   //3.声明一个sum统计班级的总分  
   
   //分析实现思路2  
   //1.统计3个班成绩情况,每个班有5名同学,求出每个班的平均分【学生的成绩从键盘输入】  
   //2.j表示第几个班级  
   //3.定义一个变量存放总成绩  
   
   //分析实现思路3  
   //1.我们可以把代码做活  
   //2.定义两个变量,表示班级的个数和班级的人数  
   //走代码实现  
   var classNum int = 2  
   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个学生的成绩\n", j, i)  
         fmt.Scanln(&score)  
         //累计总分  
         sum += score  
      }  
      fmt.Printf("第%d个班级的平均分是%vn", j, sum/float64(stuNum))  
      //将各个班的总成绩累计到tota1Sum  
      totalSum += sum  
   }  
   fmt.Printf("各个班级的总成绩%v所有班级平均分是%v\n", totalSum, totalSum/float64(stuNum))  
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  1. 统计三个班及格人数,每个班有 5 名同学对上面的代码进行了一点修改.

package main  
  
import (  
   "fmt"  
)  
  
func main() {  
   //统计三个班及格人数,每个班有5名同学  
   //1分析思路  
   //1.声明以变量passCount用于保存及格人数  
   //走代码实现  
   var classNum int = 2  
   var stuNum int = 5  
   //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个学生的成绩\n", j, i)  
         fmt.Scanln(&score)  
         //1累计总分  
         sum += score  
         //判断分数是否及格  
         if score > 60 {  
            passCount++  
         }  
      }      fmt.Println("sum", sum)  
   }  
  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 5.8 跳转控制语句-break

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

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

package main  
  
import (  
   "fmt"  
   "math/rand"   "time")  
  
func main() {  
   //在go中,需要生成一个随机额种子,否则返回的值总是固定的  
   //time.Now().Unix():返回一个从197g1-1g:e:g到现在的一个秒数  
   rand.Seed(time.Now().Unix())  
   fmt.Println("n", rand.Intn(100)+1)  
}
1
2
3
4
5
6
7
8
9
10
11
12

# 5.8.2break 的快速入门案例


package main  
  
import (  
   "fmt"  
   "math/rand"   "time")  
  
func main() {  
   //我们为了生成一个随机数,还需要个rand设置一个种子.  
   //time.Now().Unix():返回一个从1970:o1:01的8时g分9秒到现在的秒数  
   //rand.seed(time.Now().Unix())  
   //如何随机的生成1-1©0整数  
   //n :rand.Intn(100)+1 /[0 100)  
   //fmt.Println(n)   //随机生成1-100的一个数,直到生成了99这个数,看看你一共用了几次  
   //分析思路:  
   //编写一个无限循环的控制,然后不停的随机生成数,当生成了99时,就退出这个无限循环==》break  
   var count int = 0  
   for {  
      rand.Seed(time.Now().UnixNano())  
      n := rand.Intn(100) + 1  
      fmt.Println("n=", n)  
      count++  
      if n == 99 {  
         break //表示跳出for循环  
      }  
   }   fmt.Println("生成99, 一共使用了", count)  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 5.8.3 基本介绍:

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

# 5.8.4 基本语法:

{
	……
	break
	……
}
1
2
3
4
5

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

# 5.8.6break 的注意事项和使用细节

  1. break 语句出现在多层嵌套的语句块中时,可以 通过标签指明要终止的是哪一层语句块
  2. 看一个案例

package main  
  
import "fmt"  
  
func main() {  
   //这里演示一下指定标签的形式来使用break  
lable2:  
   for i := 0; i < 4; i++ {  
      //1ab1e1:/∥设置一个标签  
      for j := 0; j < 10; j++ {  
         if j == 2 {  
            //break//break默认会跳出最近的for循环  
            //break lablel  
            break lable2 //j=0 j=1  
         }  
         fmt.Println("j=", j)  
      }  
   }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  1. 对上面案例的说明 (1) break 默认会跳出最近的 for 循环 (2) break 后面可以指定标签,跳出标签对应的 for 循环

# 5.8.7课堂练习

# 5.9 跳转控制语句-continue

# 5.9.1基本介绍:

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

# 5.9.2基本语法:

{
 ……
continue
……
}

# 5.9.3continue 流程图

# 5.9.4案例分析 continue 的使用

5.9.5continu 的课堂练习 🏷 练习 1

🏷 continue 实现 打印 1——100 之内的奇数[要求使用 for 循环+continue] 代码:


package main  
  
import "fmt"  
  
func main() {  
   //continue.实现打印1一loo之内的奇数[要求使用for循环+continue]  
   for i := 1; i <= 100; i++ {  
      if i%2 == 0 {  
         continue  
      }  
      fmt.Println("奇数是", i)  
   }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

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


package main  
  
import (  
   "fmt"  
)  
  
func main() {  
   //从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为阳时结束程序  
   var positiveCount int //正数的个数  
   var negativecount int //负数个数  
   var num int  
   for {  
      fmt.Println("请输入一个整数")  
      fmt.Scanln(&num)  
      if num == 0 {  
         break //终止for循环  
      }  
      if num > 0 {  
         positiveCount++  
         continue //结束本次循环,进入下次循环  
      }  
      negativecount++  
   }  
   fmt.Printf("正数个数是%v,负数的个数是%vn", positiveCount, negativecount)  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

🏷 课后练习题(同学们课后自己完成): 某人有 100,000 元,每经过一次路口,需要交费,规则如下: 当现金>50000 时,每次交 5% 当现金<=50000 时,每次交 1000 编程计算该人可以经过多少次路口,使用 for break 方式完成

# 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 = 30  
   //演示goto的使用  
   fmt.Println("okl")  
   if n > 20 {  
      goto labell  
   }  
  
   fmt.Println("ok2")  
   fmt.Println("ok3")  
   fmt.Println("ok4")  
labell:  
   fmt.Println("ok5")  
   fmt.Println("ok6")  
   fmt.Println("ok7")  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 5.11 跳转控制语句-return

# 5.11.1 介绍:

return 使用在方法或者函数中,表示跳出所在的方法或函数,在 讲解函数的时候,会详细的介绍

func main() {  
   for i := 1; i <= 10; i++ {  
      if i == 3 {  
         return  
      }  
      fmt.Println("哇哇", i)  
   }  
   fmt.Println("Hello World!")  
}
1
2
3
4
5
6
7
8
9

说明

  1. 如果 return 是在普通的函数,则表示跳出该函数,即不再执行函数中 return 后面代码,也可以理解成终止函数。
  2. 如果 return 是在 main 函数,表示终止 main 函数,也就是说终止程序。