程序流程控制
决定程序如何执行,常用三大流程控制语句
- 顺序控制
- 分支控制:if-else
- 循环控制:for 符合条件前循环控制,符合条件后循环控制(笔记十去记录)
顺序控制
-
从上到下依次执行,每个程序都遵循这个原则,按照行一条条执行,没有判断,直到程序执行完毕或者中途报错。
-
关于变量使用,必须遵循{合法的向前引用原则}, 即先声明再使用,不可以先使用,再声明
package main import "fmt" func main() { //正确 var a int = 100 a += 100 fmt.Println(a) //错误 b += 100 var b int = 200 fmt.Println(b) }
if-else if-else分支控制
- if-else: 单分支,双分支,多分支三种
- 单分支:条件判断时成立则执行代码块,不成立则跳过代码块,无任何输出。 if <条件表达式> {<代码内容>}
- 双分支:条件判断时成立则执行代码块1,不成立则执行代码块2,到达下方继续执行顺序控制。 if <条件表达式> {<代码内容1>} else {<代码内容2>}
- 多分支:条件判断时成立则执行代码块1,不成立则执行代码块2…不成立则执行代码块n,都不成立则执行else中的代码块。
if <条件表达式> {<代码内容1>} else if <条件表达式> {<代码内容2>}… else if <条件表达式> {<代码内容n>} else {<最终代码内容>}
-
关于if格式,官方建议表达式不加小括号,而且所有开发代码中也没有把表达式加上括号的,但是加小括号没有错
if a>10 { fmt.Println("a大于10") //a>10执行打印,a<=10 }
-
关于if-else格式,Golang规定只有一种写法:
if a>10 { fmt.Println("a大于10") } else { fmt.Println("a小于10") }
-
关于if- else if - else, else不是必须的,一旦一个成立,则直接跳过下方代码转到顺序控制
if a>10 { fmt.Println("a大于10") } else if a==10 { fmt.Println("a等于10") } else { fmt.Println("a小于10") }
-
使用中的坑:if 后面必须加条件表达式,可以是a==10,但不能是a=10这种赋值,编译肯定通不过
多分支示例:
中学数学学过 ax^2+bx+c=0 分别输入变量a,b,c三个参数,判断方程有几个根
b^2 - 4ac > 0:有两个不同实根
b^2 - 4ac = 0:有一个实根
b^2 - 4ac < 0:无实根
package main
import (
"fmt"
"math"
)
func main() {
/*
需求分析:
中学数学学过 ax^2+bx+c=0 分别输入变量a,b,c三个参数,判断方程有几个根
b^2 - 4ac > 0:有两个不同实根
b^2 - 4ac = 0:有一个实根
b^2 - 4ac < 0:无实根
引入x1和x2两个变量接收 b^2 - 4ac > 0:有两个不同实根情况
x1= (-b + math.Sqrt(b^2 - 4ac))/2a
x2= (-b - math.Sqrt(b^2 - 4ac))/2a
引入变量x一个变量接收 b^2 - 4ac = 0:有一个实根情况
x = -b / 2a
如果无实根则打印,没有实根
*/
var (
a float64
b float64
c float64
drt float64
)
fmt.Printf("请分别按顺序输入方程中a,b,c三个参数数值,用空格间隔开:\n")
fmt.Scanf("%f %f %f",&a,&b,&c)
drt = float64(b*b - 4 * a * c)
if drt > 0 {
x1 := (-b + math.Sqrt(drt)) / 2 * a
x2 := (-b - math.Sqrt(drt)) / 2 * a
fmt.Printf("\n该方程有两个实根,分别是\nx1=%v, x2=%v",x1,x2)
} else if drt == 0 {
x := -b / 2 * a
fmt.Printf("该方程有一个实根,分别是 x=%v",x)
} else if drt < 0 {
fmt.Printf("该方程没有实根")
}
}
嵌套分支:分支中嵌套新的分支,也就是if中嵌套if,迭代
多分支嵌套案例演示:
package main
import "fmt"
func main() {
/*
需求:圣斗士可进入竞技场的条件,
战斗力大于等于1000的为黄金圣斗士;
战斗力大于等于500小于1000的为白银圣斗士;
战斗力大于等于200小于500的为青铜圣斗士;
战斗力小于200的为战五渣,直接出局,不可进入竞技场
需求分析:
进入竞技场和进不了竞技场为两类人,需要用if-else判断;
if条件成立则
进入竞技场的又可以继续划分圣斗士等级,使用if-else if - else结构
if条件不成立则直接让战五渣out
*/
var name string
var power int
fmt.Println("请输入圣斗士姓名: ")
fmt.Scanf("%s",&name)
fmt.Printf("请输入圣斗士%s的战斗力:",name)
fmt.Scanf("%d",&power)
if power > 200 {
fmt.Printf("圣斗士%s允许进入竞技场参加角逐",name)
if power >= 1000 {
fmt.Printf("圣斗士%s经过战力评定判定为黄金圣斗士",name)
} else if power >= 500 {
fmt.Printf("\n圣斗士%s经过战力评定判定为白银圣斗士",name)
} else if power > 200 {
fmt.Printf("\n圣斗士%s经过战力评定判定为青铜圣斗士",name)
}
} else if power <= 200 && power >5 {
fmt.Printf("圣斗士%s战斗力不足,不允许进入竞技场",name)
} else {
fmt.Printf("圣斗士%s是战斗力不足5的渣,不允许进入竞技场",name)
}
}
switch分支控制
-
switch语句用于基于不同条件执行不同的动作,每一个case分支都是唯一的,由上到下逐一测试直到匹配为止。
-
★★★Golang语言匹配项后面不需要再加break!!!!
-
switch特别适合多项选择拿到相应结果的方式
-
★★★switch和case 后接的是一个表达式,可以是常量,变量,运算,有返回值的函数,都可以。
-
★★★case表达式的值要与switch表达式的值数据类型一致!
-
case后面可以有多个表达式,但是所有表达式必须与switch数据类型一致!
-
所有case中的表达式如果是常量值,不能重复,必须两两互斥!
-
default语句不是必须的,如果没有匹配switch就直接结束了。
-
switch后面也可以不加表达式,直接让下方case作为if-else if分支来用了
switch { case <分支表达式1>,<分支表达式2>: 语句块1 }
-
switch后面表达式可以是个变量赋值,switch num := xxx {…}
-
switch穿透:fallthrough,即case1匹配了,按理来讲switch块结束,可是我并不希望switch结束,那么使用了fallthrough,下面的case继续匹配,fallthrough默认只能穿透一层,如果下面case2也符合匹配条件,case1,case2都会输出
if和switch的比较
- 如果判断的具体数值不多,符合整数,浮点数,字符,字符串这几种类型,使用switch高效。
- 对区间判断和bool类型的判断,使用if更好
代码示例:
switch <表达式>(多用来传入变量,不然没有意义) {
case <分支表达式1>,<分支表达式2>:
语句块1 //没有break,默认有符合的case执行完了默认就break了,结束switch块
case <分支表达式3>,<分支表达式4>...<分支表达式n>:
语句块2
.
.
.
default:
<上面都不匹配>语句块d //类似异常执行后的finally
} //待完成之后结束switch块继续执行顺序控制
案例:
package main
import "fmt"
func main() {
/*
需求:冰封王座英雄技能表,首先输入一个英雄名称,然后查看英雄相应技能及说明
英雄名称:恶魔猎手,死亡骑士
恶魔猎手技能:法力燃烧,献祭,闪避,恶魔化身
死亡骑士技能:死亡缠绕,吃尸,邪恶光环,黑暗奴仆
*/
var heroName string
fmt.Println("请输入要查询的英雄的名字:")
fmt.Scanf("%v",&heroName)
switch heroName {
case "恶魔猎手":
var skill string
fmt.Println("请输入要查询的技能名字:")
fmt.Scanf("%v",&skill)
switch skill {
case "法力燃烧":
fmt.Printf("%s真的很牛逼啊~", skill)
case "献祭":
fmt.Printf("%s真的很牛逼啊~", skill)
case "闪避":
fmt.Printf("%s真的很牛逼啊~", skill)
case "恶魔化身":
fmt.Printf("%s真的很牛逼啊~", skill)
}
case "死亡骑士":
var skill string
fmt.Println("请输入要查询的技能名字:")
fmt.Scanf("%v",&skill)
switch skill {
case "死亡缠绕":
fmt.Printf("%s真的很牛逼啊~",skill)
case "吃尸":
fmt.Printf("%s真的很牛逼啊~",skill)
case "邪恶光环":
fmt.Printf("%s真的很牛逼啊~",skill)
case "黑暗奴仆":
fmt.Printf("%s真的很牛逼啊~",skill)
}
default:
fmt.Printf("没有查询到该英雄名称,请重新输入")
}
}