Go核心开发学习笔记(九)—— 顺序控制,分支控制

程序流程控制
决定程序如何执行,常用三大流程控制语句

  1. 顺序控制
  2. 分支控制:if-else
  3. 循环控制:for 符合条件前循环控制,符合条件后循环控制(笔记十去记录)

顺序控制

  1. 从上到下依次执行,每个程序都遵循这个原则,按照行一条条执行,没有判断,直到程序执行完毕或者中途报错。

  2. 关于变量使用,必须遵循{合法的向前引用原则}, 即先声明再使用,不可以先使用,再声明

     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分支控制

  1. if-else: 单分支,双分支,多分支三种
  • 单分支:条件判断时成立则执行代码块,不成立则跳过代码块,无任何输出。 if <条件表达式> {<代码内容>}
  • 双分支:条件判断时成立则执行代码块1,不成立则执行代码块2,到达下方继续执行顺序控制。 if <条件表达式> {<代码内容1>} else {<代码内容2>}
  • 多分支:条件判断时成立则执行代码块1,不成立则执行代码块2…不成立则执行代码块n,都不成立则执行else中的代码块。
    if <条件表达式> {<代码内容1>} else if <条件表达式> {<代码内容2>}… else if <条件表达式> {<代码内容n>} else {<最终代码内容>}
  1. 关于if格式,官方建议表达式不加小括号,而且所有开发代码中也没有把表达式加上括号的,但是加小括号没有错

     if a>10 {
     	fmt.Println("a大于10")      //a>10执行打印,a<=10
     }         
    
  2. 关于if-else格式,Golang规定只有一种写法:

     if a>10 {
     	fmt.Println("a大于10")
     } else {
     	fmt.Println("a小于10")
     }
    
  3. 关于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")
     }
    
  4. 使用中的坑: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分支控制

  1. switch语句用于基于不同条件执行不同的动作,每一个case分支都是唯一的,由上到下逐一测试直到匹配为止。

  2. ★★★Golang语言匹配项后面不需要再加break!!!!

  3. switch特别适合多项选择拿到相应结果的方式

  4. ★★★switch和case 后接的是一个表达式,可以是常量,变量,运算,有返回值的函数,都可以。

  5. ★★★case表达式的值要与switch表达式的值数据类型一致!

  6. case后面可以有多个表达式,但是所有表达式必须与switch数据类型一致!

  7. 所有case中的表达式如果是常量值,不能重复,必须两两互斥!

  8. default语句不是必须的,如果没有匹配switch就直接结束了。

  9. switch后面也可以不加表达式,直接让下方case作为if-else if分支来用了

     switch {
     case <分支表达式1>,<分支表达式2>: 
     语句块1
     }
    
  10. switch后面表达式可以是个变量赋值,switch num := xxx {…}

  11. switch穿透:fallthrough,即case1匹配了,按理来讲switch块结束,可是我并不希望switch结束,那么使用了fallthrough,下面的case继续匹配,fallthrough默认只能穿透一层,如果下面case2也符合匹配条件,case1,case2都会输出

if和switch的比较

  1. 如果判断的具体数值不多,符合整数,浮点数,字符,字符串这几种类型,使用switch高效。
  2. 对区间判断和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("没有查询到该英雄名称,请重新输入")
	}
}
发布了50 篇原创文章 · 获赞 18 · 访问量 4020

猜你喜欢

转载自blog.csdn.net/weixin_41047549/article/details/89609030