GO语言学习之流程控制
1.流程控制类型
是对代码执行过程,执行顺序进行控制
1》顺序控制
2》分支控制
3》循环控制
2.顺序控制
程序从上到下按照顺序执行
代码示例:
var say string
say="i love liuyifei"
fmt.Printf("张三说:%v\n",say )
say="i love dogdog"
fmt.Printf("李丽说:%v\n",say)
3.分支控制
就是让程序有选择的,有条件的去执行,有三种形式:
1》单分支
if 条件表达式{
代码块//条件表达式为true,执行该代码块
}
代码示例:
var score int =95
if score>90{
fmt.Println("爸爸带你去夏威夷玩")
}
//注意:go 中 if 后面可以直接声明变量
if agE:=19 ;agE>18{
fmt.Println("可以去网吧了。。。")
}
2》双分支
if 条件表达式{
代码块1//条件表达式为true,执行该代码块
}else{
代码块2
}
代码示例:
var score=78
if score >90{
fmt.Println("爸爸带你去夏威夷玩")
}else {
fmt.Println("爸爸带你去姥姥家玩")
}
注意:
不管什么分支,代码块外面没有{},都会报错,java等其他语言中,则不会
if score<60
fmt.Println("妈妈打你屁股")
//这种写法,会出现编译错误
score=78
if score >90{
fmt.Println("爸爸带你去夏威夷玩")
}
else {
fmt.Println("爸爸带你去姥姥家玩")
}
//这种写法,会出现编译错误,原因:else前面不能换行
score=78
if (score >90){
fmt.Println("爸爸带你去夏威夷玩")
}
//这种写法,正确,if后面条件表达式可以放在()里,但是建议不用
练习:判断一个年份是闰年还是平年
package main
import "fmt"
func main() {
var year int
//友情提示:
fmt.Println("请输入一个年份:")
//键盘接收录入数据
fmt.Scanln(&year)
if (year%4==0&&year%100!=0)||year%400==0{
fmt.Printf("%v年是闰年",year)
}else {
fmt.Printf("%v年是平年",year)
}
}
3》多分支
if 条件表达式{
代码块1//条件表达式为true,执行该代码块
}else if 条件表达式{
代码块2
}else if 条件表达式{
代码块 3
可以n个else if
}else{
}
可以有多个else if ,最后 else 不是必须的
执行流程,从上往下对每个条件进行判断,哪个条件符合执行哪个
代码示例:
package main
import "fmt"
func main() {
//根据高考成绩上大学
var score int
fmt.Scanf("请输入您的成绩%v",&score)
if(score>666&&score<=750){
fmt.Println("北大,清华,欢迎您。。。")
}else if(score>630&&score<666){
fmt.Println("十大名校,欢迎您。。。")
}else if(score<=630&&score>=600){
fmt.Println("985,欢迎您。。。")
}else if(score<600&&score>=580){
fmt.Println("211,欢迎您。。。")
}else {
fmt.Println("学校不好,再来一年吧。。。")
}
}
作业:根据条件找对象,不作演示
嵌套分支
定义:在一个分支语句中里面嵌套一层分支
语法:
if 表达式1 {
if 表达式 2{
}else{
}
else{
}
里面可以嵌套多个分支
代码示例:
package main
import "fmt"
func main() {
//阿里P8找对象
var piaoliang bool=true
var is211 bool =true
if piaoliang{
if is211{
fmt.Println("直接领走")
}else{
fmt.Println("留个微信,认识一下")
}
}else {
fmt.Println("谢谢再见")
}
}
4》switch分支
作用:
从上往下依次执行,满足条件的case,就执行,不满足就跳过
匹配项后面不需要加break
语法:
switch 表达式{
case 表达式1,表达式2,,,,:
代码块
case 表达式3,表达式4,,,,:
代码块
。。。
default:
代码块
}
语法说明:
1》switch的执行流程:先执行表达式,得到值,然后和case的表达式进行比较,如果相等,就匹配到,然后执行对应的case的语句块,然后退出switch控制
2》如果switch的表达式的值没有和任何的case的表达式匹配成功,则执行default的语句块。执行后退出switch的控制
3》golang中的case语句块不需要写break,默认会有。默认,当程序执行完case后面的代码块,直接退出switch控制(没有case穿透)
代码示例:
package main
import "fmt"
func main() {
var i int
fmt.Println("请输入0-6之间的整数")
fmt.Scanln(&i)
switch i {
case 1:
fmt.Println("今天星期一")
case 2:
fmt.Println("今天星期二")
case 3:
fmt.Println("今天星期三")
case 4:
fmt.Println("今天星期四")
case 5:
fmt.Println("今天星期五")
case 6:
fmt.Println("今天星期六")
case 0:
fmt.Println("今天星期日")
default:
fmt.Println("你不是地球人吧。。。")
}
}
注意事项:
1》case/switch 后是一个表达式(常量,变量,一个有返回值的函数都可以)
package main
import "fmt"
func test(char byte) byte {
return char+1
}
func main() {
//案例:
var key byte
fmt.Println("请输入一个字符 a,b,c,d,e,f,g")
fmt.Scanf("%c",&key)
switch test(key) {//函数
case 'a':
fmt.Println("alibaba")
case 'b':
fmt.Println("baidu")
case 'c':
fmt.Println("chinese")
case 'd':
fmt.Println("Dog")
default:
fmt.Println("都不是")
}
}
2》case后的各个表达式的值的数据类型,必须和switch的表达式数据类型一致
var a int32
var b int64
switch a {
case a:
fmt.Println("hello a")
case b:
fmt.Println("hello b")//a 和 b数据类型不一致,所以会出错
default:
fmt.Println("错了吧。。。。")
}
3》case后面可以带多个表达式,使用逗号间隔,比如:case表达式1,表达式2
var a int32
var b int32
switch a {
case a,3,8:
fmt.Println("hello a")
case b:
fmt.Println("hello b")
default:
fmt.Println("错了吧。。。。")
}
4》case后面的表达式如果是常量值(字面量),则要求不能重复
var a int32
var b int32
switch a {
case a,3,8:
fmt.Println("hello a")
case 3://报错是因为已经有3这个case项了
fmt.Println("hello b")
default:
fmt.Println("错了吧。。。。")
}
5》case后面不需要带break,程序匹配一个case后就会执行对应的代码块,然后退出switch.如果一个都匹配不到,则执行default
6》default语句不是必须的
7》switch后也可以不带表达式,类似 if-else分支来使用
var age=19
switch {
case age>=18:
fmt.Println("你可以上网吧了")
case age<18:
fmt.Println("在家好好写作业")
}
8》switch后也可以直接声明/定义一个变量,分号结束,不推荐
switch age:=22;{
case age>=18:
fmt.Println("你可以上网吧了")
case age<18:
fmt.Println("在家好好写作业")
}
9》switch穿透fallthrough,如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透
var x int=100
switch x {
case 100:
fmt.Println("100")
fallthrough//一个fallthrough只能穿透一层
case 200:
fmt.Println(200)
default:
fmt.Println("没有匹配到。。。。")
}
10》Type Switch:switch 语句还可以被用于type-switch来判断某个interface变量中实际指向的变量类型,这个后面学了interface就懂了,先看例子:
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的类型是 float64 型")
default:
fmt.Printf("未知型")
}
练习:
1.使用switch把小写类型的char型转为大写(键盘录入)。只转换a,b,c,d,e,其他的输出"other"
package main
import "fmt"
func main(){
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...")
}
}
2.对学生成绩大于60的输出,通过,低于60的输出,不通过
package main
import "fmt"
func main(){
var score float64
fmt.Println("请输入您的成绩")
fmt.Scanln(&score)
switch (score/60) {
case 1:
fmt.Println("通过")
case 0:
fmt.Println("补考")
default:
fmt.Println("你输得什么玩意")
}
}
3.根据用户指定月份,输出该月份有多少天
package main
import "fmt"
func main() {
var num int
fmt.Println("请输入一个月份")
fmt.Scanln(&num)
switch num {
case 1,3,5,7,8,10,12:
fmt.Printf("%d月有31天",num)
case 4,6,9,11:
fmt.Printf("%d月有30天",num)
case 2:
fmt.Printf("%d月有28或者29天",num)
default:
fmt.Println("你输的啥玩意。。。")
}
}
switch 和if比较:
1.如果判断的具体数值不多,而且符合整数,浮点数,字符,字符串这几种类型。建议使用switch语句
2.其他情况:对区间判断和结果为bool的类型的判断,使用if,一般使用if
4.for循环控制
1.实际需要:
对你的爱人表白99次。
传统的可能:
fmt.Println("翠花,i love you")
fmt.Println("翠花,i love you")
fmt.Println("翠花,i love you")
.....
fmt.Println("翠花,i love you")//很麻烦
for循环实现:
for i :=1;i<100;i++{
fmt.Println("翠花,i love you")
}
2.语法:
for 循环变量初始化;循环条件;循环变量迭代{
循环体语句
}
语法详解:
###对for循环来说,有四个要素,
1》循环变量初始化
2》循环·条件
3》循环体语句
4》循环变量迭代
###执行顺序
1》执行循环变量初始化,比如 i:=1
2》执行循环条件,比如 i<100
3》如果循环条件为真,就执行循环体
4》执行循环变量迭代 i++
5》反复执行2,3,4步,直到2》为false,就退出循环
3.注意事项:
1>循环条件是返回一个布尔值表达式
2>for循环第二种格式:
for 循环判断条件{
//循环体语句
}
i :=1//初始化
for i<=10{//判断
fmt.Println(i)//循环体
i++//控制变量
}
3>死循环
for{
//循环体
}
等价于 for ;;{},实际使用中需要配合break语句使用
i :=1
for{
if i<100{
fmt.Println("翠花,i love you")
}else {
break//跳出循环
}
i++
}
4>for-range语句。
可以方便遍历字符串和数组
#字符串遍历
传统方式:
var str string ="hello world"
for i:=0;i<len(str);i++{
fmt.Printf("%c \n",str[i])
}
for range方式:
var str2 string ="hello world"
for index,val :=range str2{
fmt.Printf("index=%d,val=%c \n",index,val)
}
注意:如果我们字符串中含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。原因:传统的对字符串的遍历是按照字节来遍历,而一个汉字在utf8编码对应的是3个字节。
解决方式:
需要将str 转换成[]rune切片:
//带中文的字符串遍历方式 1
var str3 string="我爱北京天安门"
str4:=[]rune(str3)//将中文字符串转成[]rune形式
for i:=0;i<len(str4);i++{
fmt.Printf("%c \n",str4[i])//使用到下标
}
但是对于采用for -range来说,直接转就行了
4.for循环练习
求1-10之间能被3整除的数以及个数
package main
import "fmt"
func main(){
var i int=1
var count=0
for{
if i>10{
break
}else{
if i%3==0{
fmt.Println(i)
count++
}
}
i++
}
fmt.Println(count,"个")
}
5.while和 do while
注意:go中没有java/c中的 while /do while
但是刚刚上面的for循环练习的例子的使用其实本质是和java中的 while 是一样的
6.多重循环控制
》一个循环中还有一个循环,就是嵌套循环,外边的成为外循环,里面的被称为内循环,一般不宜超过三层
》实质上,内循环相当于外循环的循环体
》外层循环次数为m次,内层循环为n次,则内层循环体实际上需要执行m*n次·
案例1:
打印五行六列的星星
for m:=1;m<=5;m++{
for n:=1;n<=6;n++{
if n==6{
fmt.Println("*")
}else {
fmt.Print("*")
}
}
}
案例2:
打印五行五列的等腰直角三角形的星星
for i:=1;i<=5;i++{
for j:=1;j<=i;j++{
if j==i{
fmt.Println("*")
}else {
fmt.Print("*")
}
}
}
案例3:
打印八层实心金字塔,
for i:=1;i<=8;i++{
for j:=1;j<=8-i;j++{
fmt.Print(" ")
}
for x:=1;x<=2*i-1;x++{
if x==2*i-1{
fmt.Println("*")
}else {
fmt.Print("*")
}
}
}
案例4:
打印八层空心金字塔
for i:=1;i<=8;i++{
for j:=1;j<=8-i;j++{
fmt.Print(" ")
}
for x:=1;x<=2*i-1;x++{
if x==1||x==2*i-1||i==8{
fmt.Print("*")
}else {
fmt.Print(" ")
}
}
fmt.Println(" ")
}
案例5:
打印久久乘法表
for i:=1;i<=9;i++{
for j:=1;j<=i;j++{
fmt.Printf("%v * %v =%v \t",j,i,j*i)
}
fmt.Println()
}
7.跳转控制语句break
1.看一个具体需求,引出break
公司年会抽奖,每人一次机会,假如抽到88,代表中奖
for{
var num int
fmt.Println("请猜奖")
fmt.Scanln(&num)
if num==88{
fmt.Println("恭喜你,中大奖了。。。。")
break
}
}
2.注意:
当多重循环时,可以通过lable 标签来指定退出哪一层循环
package main
import "fmt"
func main(){
la2:
for i:=1;i<5;i++{
label1:
for j:=6;j<=10;j++{
if j==7{
break label1
}
if i==3{
break la2
}
fmt.Println(i,"x",j)
}
}
}
3.练习:
1》100以内的数求和,求当和第一次大于20的当前数
sum:=0
for i:=1;i<=100;i++{
sum+=i
if sum>20{
fmt.Println("当和大于20时,当前数字是",i)
break
}
}
2》实现登录验证,有三次机会,如果用户名为:“张三丰”,密码为zsf123,提示登录成功,否则提示还有几次机会
package main
import "fmt"
func main(){
var name string
var pwd string
var loginNum int=3
for i:=1;i<=3;i++{
fmt.Println("请输入账号:")
fmt.Scanln(&name)
fmt.Println("请输入密码:")
fmt.Scanln(&pwd)
if name=="张三丰"&&pwd=="zsf123"{
fmt.Println("登录成功")
break
}else {
loginNum--
if loginNum>0 {
fmt.Printf("您还有%v次登录机会\n",loginNum)
}
}
}
if loginNum==0{
fmt.Println("机会用完,账号锁定。。。")
}
}
8.跳转控制语句continue
1.基本介绍:
continue语句用于结束本次循环,继续执行下一次循环
continue语句出现在多层嵌套的循环语句体中,可以通过标签指明要跳过的是哪一层循环,这个和前面的break标签的使用的规则一样
2.基本语法:
{
continue
}
3.示例:
package main
import "fmt"
func main() {
//打印出1--10中间3的倍数
for i:=1;i<=10;i++{
if i%3!=0{
continue
}
fmt.Println(i)
}
}
4.练习
打印出1–100之间的偶数
9.跳转控制语句goto
1.基本介绍
》go语言的goto语句可以无条件地转移到程序中指定的行
》goto语句通常与条件语句配合使用,可用来实现条件转移,跳出循环体等功能
》在Go程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难
2.goto语法:
goto label
…
label:statement
3案例
package main
import "fmt"
func main() {
var n int =88
if n>66{
goto label
}
fmt.Println("helloworld")
label:
fmt.Println("helloGolang")
}
10.跳转控制语句return
1.基本介绍:
return 使用在方法或者函数中。表示跳出所在的方法或函数,在讲解函数的时候,会详细介绍
1》如果return 是在普通函数,则表示跳出该函数,即不再执行程序中return后面的代码,也可以理解成终止函数
2》如果return是在Main函数中,则表示终止main函数,终止程序
package main
import "fmt"
func main(){
var i int =9
if i>8{
fmt.Println("到此为止吧")
return
}
fmt.Println("hello world")
}