• Go语言学习之路第2天(常量,运算符和流程控制)


    一. 常量

    1.1 常量的定义和使用

      在讲解常量之前,我们要先简单说一下我们前面讲解的变量。我们都知道,变量是用来存储数据,并且变量里面存储的值是可以在程序运行时随时发生变化的。那么什么是常量呢?在程序运行过程中其值不能发生改变的量就是常量。

      常量在定义时,必须给初始值,不能改变常量的值,不能获取常量地址,建议常量名为大写和变量区分。

      代码如下:

    func main() {
    	//变量的定义
    	//var 变量名 数据类型 = 值
    	b := 9
    
    	//常量的定义
    	//const 常量名 数据类型 = 值
    	const a int = 10
    
    	//不能改变常量的值
    	//a = 20  //error
    	//不能获取常量的内存地址
    	//fmt.Println(&a)   //error
    
    	//常量可以参与程序计算
    	b = a * b
    	fmt.Println(a)
    	fmt.Println(b)
    }
    

     

      通过自动推导类型创建常量

    func main() {
    	//常量的自动推导类型
    	//const 常量名 = 值
    	const a = 10
    
    	fmt.Println(a)
    	fmt.Printf("%T", a)
    }
    

      问题:什么场景下会用到常量呢?

      在程序开发中,我们用常量存储一直不会发生变化的数据,例如:π,身份证号码等。像这类的数据,在整个程序中运行中都是不允许发生改变的

    1.2 字面常量

    所谓字面常量(literal),是指程序中硬编码的常量,如:

    package main
    
    import "fmt"
    
    func main() {
    	//字面常量 (硬编码常量)
    	fmt.Println("hello")
    	fmt.Println(10)
    	fmt.Println(3.14)
    	fmt.Printf(true)
    }
    

    1.3 iota枚举

      常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。

      注意:在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一。

      具体使用方式如下

    func main() {
    	//在iota枚举中,在第一个声明的常量所在的行,iota将会被置为0,每换一行值+1
    	//iota给常量赋值使用
    	const (
    		a = iota
    		b = iota
    		c = iota
    	)
    	fmt.Printf("a=%d,b=%d,c=%d
    ", a, b, c)
    
    	//iota遇到const,重置为0
    	const d = iota
    	fmt.Printf("d=%d
    ", d)
    
    	//在iota枚举中,同一行的值相同
    	const (
    		a1     = iota
    		b1, c1 = iota, iota
    		d1     = iota
    	)
    	fmt.Printf("a1=%d,b1=%d,c1=%d,d1=%d
    ", a1, b1, c1, d1)
    
    	//在iota枚举中,除第一行外,其他枚举值不用赋值
    	const (
    		a2 = iota
    		b2
    		c2
    		d2
    	)
    	fmt.Printf("a2=%d,b2=%d,c2=%d,d2=%d
    ", a2, b2, c2, d2)
    
    	const (
    		a3 = iota
    		b3 = 3
    		c3 = iota
    		d3 = 7
    	)
    	fmt.Printf("a3=%d,b3=%d,c3=%d,d3=%d
    ", a3, b3, c3, d3)
    
    }
    

       结果如下:

    a=0,b=1,c=2
    d=0
    a1=0,b1=1,c1=1,d1=2
    a2=0,b2=1,c2=2,d2=3
    a3=0,b3=3,c3=2,d3=7
    

    二.运算符

      前面已经介绍了变量,常量,那么接下来我们学习一下运算符。Go语言中常见的运算符有算术运算符,赋值运算符,关系运算符,逻辑运算符等。

    2.1 算术运算符

    运算符

    术语

    示例

    结果

    +

    10 + 5

    15

    -

    10 - 5

    5

    *

    10 * 5

    50

    /

    10 / 5

    2

    %

    取模(取余)

    10 % 3

    1

    ++

    后自增,没有前自增

    a=0; a++

    a=1

    --

    后自减,没有前自减

    a=2; a--

    a=1

     

       

      算术表达式:由算术运算符连接起来的式子.如:1+1   a-b(变量ab前面已声明并赋初值)

      示例如下: 

    func main() {
    	a := 10
    	b := 3
    	//两个整数相除,得到的结果也是整数
    	fmt.Println(a / b)
    }
    

       结果如下:

    3
    
    func main() {
    	a := 10
    	b := 3
    	fmt.Println(a % b)
    }
    

      结果如下:

    1
    
    func main() {
    	a := 3
    	b := 4
    
    	a++
    	b--
    	fmt.Printf("a=%d,b=%d", a, b)
    }
    

      结果如下:

    a=4,b=3
    

    2.2 类型转换

      在Go语言中,不同类型的变量不允许计算;如果要计算,需要强制类型转换。

      强制类型转化:数据类型(变量) 或 数据类型(表达式)

      示例如下:

    func main() {
    	var a, b, c int
    	num := 3
    	fmt.Print("请输入三个值:")
    	fmt.Scan(&a, &b, &c)
    	sum := a + b + c
    	fmt.Printf("sum=%d
    ", sum)
    	//强制类型转化
    	//数据类型(变量) 数据类型(表达式)
    	avg := float64(sum) / float64(num)
    	fmt.Printf("avg=%.2f
    ", avg)
    }

       结果如下:

    请输入三个值:1 2 3
    sum=6
    avg=2.00
    
    func main() {
    	weight := 5
    	price := 3.25
    
    	//在Go语言中,不同类型的变量不允许计算;如果要计算,需要强制类型转换
    	fmt.Println(float64(weight) * price)
    
    	//将浮点类型转换为整型会丢弃小数部分,只保留整数部分
    	fmt.Println(weight * int(price))
    }
    

       结果如下:

    16.25
    15
    

       强制类型转换,数据类型一定要相兼容

    2.3 赋值运算符

      关于赋值运算符前面我们已经使用过多次,赋值运算符   =  ,var int num = 9;num = num + 1;这里的 = 号是赋值运算符,不是数学义意上的相等。常见的赋值运算符如下,前面我们使用的 = 是普通赋值,+=,-=等我们称为“复合赋值运算符”。

    运算符

    说明

    示例

    =

    普通赋值

    c = a + b 将a + b 表达式结果赋值给c

    +=

    相加后再赋值

    c += a 等价于c = c + a

    -=

    相减后再赋值

    c -= a 等价于c = c - a

    *=

    相乘后再赋值

    c *= a 等价于c = c * a

    /=

    相除后再赋值

    c /= a 等价于c = c / a

    %=

    求余后再赋值

    c %= a 等价于c = c % a

      示例如下:

    unc main() {
    	a := 10
    	b := 20
    
    	a += b //a = a + b
    	fmt.Printf("a=%d
    ", a)
    
    	a -= b //a = a - b
    	fmt.Printf("a=%d
    ", a)
    
    	a *= b //a = a * b
    	fmt.Printf("a=%d
    ", a)
    
    	a /= b //a = a / b
    	fmt.Printf("a=%d
    ", a)
    
    	a %= b //a= a % b
    	fmt.Printf("a=%d
    ", a)
    }
    

       结果如下:

    a=30
    a=10
    a=200
    a=10
    a=10
    

     2.4 关系运算符

      关系运算符我们又称为比较运算符,听到比较这个词,大家想到的就是比较大小,例如:

      大象的重量(1500)>老鼠的重量(1)

      兔子的寿命(3)>乌龟的寿命(1000)

      我的年龄(20)==你的年龄(20)

      提问:比大比小的结果是什么?

      结果是对或者是错,在GO语言中,怎样表示对于错呢?

      关系运算的结果是布尔类型的

      bool值只有两个

      真:true

      假:false

      

      GO语言中常见的关系运算符如下:

    运算符

    术语

    示例

    结果

    ==

    相等于

    4 == 3

    false

    !=

    不等于

    4 != 3

    true

    小于

    4 < 3

    false

    大于

    4 > 3

    true

    <=

    小于等于

    4 <= 3

    false

    >=

    大于等于

    4 >= 1

    true

      由以上关系运算符链接的表达式我们称为关系表达式。

      关系运算符具体使用方式如下:

    func main() {
    	a := 10
    	b := 20
    	
    	//%t 是一个占位符,表示输出一个布尔类型值
    	fmt.Printf("a < b:%t
    ", a < b)
    	fmt.Printf("a > b:%t
    ", a > b)
    
    	fmt.Printf("a <= b:%t
    ", a <= b)
    	fmt.Printf("a >= b:%t
    ", a >= b)
    
    	fmt.Printf("a == b:%t
    ", a == b)
    	fmt.Printf("a != b:%t
    ", a != b)
    
    }
    

       结果如下:

    a < b:true
    a > b:false
    a <= b:true
    a >= b:false
    a == b:false
    a != b:true
    

     2.5 逻辑运算符

      常见的逻辑运算符如下

    运算符

    术语

    示例

    结果

    !

    !a

    如果a为假,则!a为真;

    如果a为真,则!a为假。

    &&

    a && b

    如果a和b都为真,则结果为真,否则为假。

    ||

    a || b

    如果a和b有一个为真,则结果为真,二者都为假时,结果为假。

       

      有逻辑运算符连接的表达式叫做逻辑表达式

      通过以上表格我们发现:逻辑表达式的结果同样也是bool类型

      逻辑运算符两边放的一般都是关系表达式或者bool类型的值。

      例如:

        5>3 &&true 

        3>5||false

      示例如下:

    func main() {
    	a := 10
    	b := 20
    	//逻辑非:!,布尔值取反
    	fmt.Println(!(a > b))
    
    	a1 := true
    	b1 := false
    	//逻辑与:&&,同真为真,其余为假
    	fmt.Println(a1 && b1)
    
    	atk := 10000
    	lv := 20
    	//逻辑或:||,同假为假,其余为真
    	fmt.Println(atk >= 10000 || lv > 10)
    }
    

       结果如下:

    true
    false
    true
    

       总结:

        逻辑与:&&

        表达式1&&表达式2

    表达式1

    表达式2

    表达式1&&表达式2

    True

    True

    True

    False

    True

    False

    True

    False

    False

    False

    False

    false

        

        逻辑或:||

        表达式1||表达式2

    表达式1

    表达式2

    表达式1||表达式2

    True

    True

    True

    True

    False

    True

    False

    True

    True

    False

    False

    false

      

        逻辑非:!

        !表达式

    表达式

    !表达式

    True

    False

    False

    true

    2.6 其他运算符

    运算符

    术语

    示例

    说明

    &

    取地址运算符

    &a

    变量a的地址

    *

    取值运算符

    *a

    指针变量a所指向内存的值

      示例如下

    func main() {
    	//&,取地址运算符 引用运算符
    	//*,取值运算符 解引用运算符
    	a := 10
    
    	fmt.Println(&a)
    	fmt.Printf("%p
    ", &a)
    
    	var p *int = &a
    	fmt.Println(p)
    
    	*p = 123
    	fmt.Println(*p)
    }
    

       结果如下:

    0xc00007e008
    0xc00007e008
    0xc00007e008
    123
    

     2.7运算符优先级

      1、特殊运算符
      () [] .
      2、单目运算符
      ! ++ -- & *
      3、双目运算符
        3、1 算数运算符
        * / %
        + -
        3、2 关系运算符
        > >= < <= == !=
        3、3 逻辑运算符
        &&
        ||
        3、4 赋值运算符
        = += -= *= /= %=

    三.流程控制

      前面我们写的程序都是从第一行开始执行,一直执行到末尾,一行一行的顺序执行下来,这种执行结构叫顺序执行结构。

      GO语言除了有顺序结构,还有选择结构,循环结构。

    • 顺序结构:程序按顺序执行,不发生跳转。
    • 选择结构:依据是否满足条件,有选择的执行相应功能。
    • 循环结构:依据条件是否满足,循环多次执行某段代码。

      下面先讲解选择结构:

    3.1 选择结构

      选择结构我们也称为判断结构。

      如果某些条件满足,才能做某件事情,而不满足时不允许做,这就是所谓的判断。

    3.1.1 if结构 

      在编程中实现选择判断结构就是用if。

      if结构基本语法:

        if 条件判断{

          代码语句

        },

      条件判断如果为真(true),那么就执行大括号中的语句,如果为假(false),就不执行大括号中的语句,(大家可以想一下,什么样的表达式返回的结果要么为true,要么为false),继续执行if结构后面的代码。

      具体案例如下:

    func main() {
    	var score int
    	fmt.Scan(&score)
    
    	if score > 700 {
    		fmt.Println("我要上清华")
    	}
    }
    

       结果如下:

    710
    我要上清华
    

      GO语言相比其它语言要灵活很多,下面我们看一下if的另外一种语法格式:

    func main() {
    	//if支持初始化语句和判断语句在一起;二者以分号分隔
    	if a := 10; a == 10 {
    		fmt.Println("a == 10")
    	}
    }
    

       结果如下

    a == 10
    

    3.1.2 if else结构

      想一想:在使用if的时候,它只能做到满足条件时要做的事情。那万一需要在不满足条件的时候,做某些事,该怎么办呢?

      例如:小赵的考试成绩大于90(含)分,那么爸爸奖励他100元钱,否则的话,爸爸就让小赵跪方便面。

      有同学可能会想,这道题用if结构也可以实现。如下所示:

    func main() {
    	var score float64
    	fmt.Print("请输入考试成绩:")
    	fmt.Scanf("%f",&score)
    	if score >= 90{
    		fmt.Println("奖励100元")
    	}
    	if score < 90{
    		fmt.Println("跪方便面")
    	}
    }

      虽然以上代码可以实现,但是比较麻烦,我们可以使用更简单的方式:else

      结构如下:

        if 条件判断{

          代码语句1

        }else{

           代码语句2

        }

      首先先执行if后面的条件判断,如果条件判断成立(结果为真),执行if后面的代码语句1,代码语句1执行完成后,表示整个if---else--结构结束了(else后面的代码语句2不会执行),继续执行后面的代码。如果if后面的条件判断不成立也就是结果为假,那么if后面的代码语句1不会被执行,这时会执行else后面的代码语句2,执行完后,表示整个if—else—结构执行结束了,再执行后续的代码。

      下面我们通过if---else结构完成上面的案例。

    func main() {
    	var score float64
    	fmt.Print("请输入考试成绩:")
    	fmt.Scanf("%f", &score)
    	if score >= 90 {
    		fmt.Println("奖励100元")
    	} else {
    		fmt.Println("跪方便面")
    	}
    }
    

     3.1.3 if嵌套

      我们上面的案例中,使用的是if-else的基本结构,其实if-else结构还可以进行嵌套使用。

      例如:输入公交卡当前的余额,只要超过2元,就可以上公交车;如果空座位的数量大于0,就可以坐下。

    func main()  {
    	var money float64
    	fmt.Println("请输入公交卡钱数:")
    	fmt.Scanf("%f
    ",&money)
    	if money >= 2{
    		var seat_count int
    		fmt.Println("请输入空座位数量:")
    		fmt.Scanf("%d",&seat_count)
    		if seat_count > 0 {
    			fmt.Println("请坐")
    		}else {
    			fmt.Println("不好意思,你只能站着了!!")
    		}
    	}else {
    		fmt.Println("余额不足")
    	}
    }
    

      以上案例在if中嵌套了if-else结构,同理在else也可以嵌套if-else结构,这个要根据实际情况确定。下面我们看如下题目:

      对学员的结业考试成绩评测(大家考虑用if好还是用if-else好)

        成绩>=90 :A     

        90>成绩>=80 :B       

        80>成绩>=70 :C

        70>成绩>=60 :D

        成绩<60  :E

      我们先使用if来实现上面的问题:

    func main()  {
    	var score int
    	fmt.Println("请输入考试成绩:" )
    	fmt.Scanf("%d",&score)
    	if score >= 90{
    		fmt.Println("A")
    	}
    	if score < 90 && score >= 80{
    		fmt.Println("B")
    	}
    	if score < 80 && score >= 70{
    		fmt.Println("C")
    	}
    	if score < 70 && score >= 60{
    		fmt.Println("D")
    	}else{
    		fmt.Println("E")
    	}
    }
    

      上面的代码我们最后发现都会输出“E”,为什么呢?

      解决方案如下:

    func main()  {
    	var score int
    	fmt.Println("请输入考试成绩:" )
    	fmt.Scanf("%d",&score)
    	if score >= 90{
    		fmt.Println("A")
    	}
    	if score < 90 && score >= 80{
    		fmt.Println("B")
    	}
    	if score < 80 && score >= 70{
    		fmt.Println("C")
    	}
    	if score < 70 && score >= 60{
    		fmt.Println("D")
    	}
    	if score < 60{
    		fmt.Println("E")
    	}
    }
    

      下面我们来使用 if-else 结构来解决上面的问题

      案例演示如下:

    func main()  {
    	var score int
    	fmt.Println("请输入考试成绩:")
    	fmt.Scanf("%d",&score)
    	if score >= 90{
    		fmt.Println("A")
    	}else {
    		if score >= 80{
    			fmt.Println("B")
    		}else {
    			if score >= 70{
    				fmt.Println("C")
    			}else {
    				if score >= 60{
    					fmt.Println("D")
    				}else {
    					fmt.Println("E")
    				}
    			}
    		}
    	}
    }
    

      上面的代码虽然满足了我们的需求,但是嵌套的代码非常多,可读性比较差,我们在以后的编程工作中尽量避免这种多重嵌套。

      通过这道题,我们发现在这种多条件判断应用的场景中不太适合通过 if(适合一种条件判断的情况)或者是if-else(适合两种条件判断的情况或者是判断条件不是很多的场景)进行判断。

      上面的题目更好的方法:if-else if结构

    3.1.4 if-else if结构

      基本语法如下:

        if 条件判断{

          要执行的代码段

        }else if 条件判断{

          要执行的代码段

        }else if 条件判断{

          要执行的代码段

        }else if条件判断{

          要执行的代码段

        }.else{

        }

      通过以上的语法格式我们发现,可以写很多的else if结构。

      具体的执行过程:程序首先判断第一个if所带的小括号中的判断条件,如果条件成立,也就是返回一个true,则执行该if所带的大括号中的代码,执行完成后,立即跳出if else-if结构。如果第一个if所带的判断条件不成立,也就是返回一个false,则继续向下进行判断,依次的判断每一个if所带的判断条件,如果成立,就执行该if所带的大括号中的代码,如果不成立,则继续向下判断,如果每个if所带的判断条件都不成立,就看当前这个if else-if结构中是否存在else。如果有else的话,则执行else中所带的代码,如果没有else,则整个 if-else if什么都不做。else可以省略。

      下面我们使用该结构完成上面的案例:

    func main()  {
    	var score int
    	fmt.Println("请输入考试成绩:")
    	fmt.Scanf("%d",&score)
    	if score >= 90{
    		fmt.Println("A")
    	}else if score >=80{
    		fmt.Println("B")
    	}else if score >= 70{
    		fmt.Println("C")
    	}else if score >= 60{
    		fmt.Println("D")
    	}else{
    		fmt.Println("E")
    	}
    } 

      总结:我们通过前面的案例讲解,大家应该能够总结出if结构,if-else结构和if-else if结构应用的场景.

        if结构适合:一种的判断

        if-else结构适合:两种情况的判断

        if-else if 结构适合:多种情况判断,并且判断都是对区间中的数据进行判断(例如:考试成绩)  

    3.1.5 switch结构

      下面我们开始讲解选择中的另外一个结构就是switch结构。

      在讲解switch结构之前,我们先来看如下问题:

      李四的年终工作评定,如果定为A级,则工资涨500元,如果定为B级,则工资涨200元,如果定为C级,工资不变,如果定为D级工资降200元,如果定为E级工资降500元.

      设李四的原工资为5000,请用户输入李四的评级,然后显示李四来年的工资.

     

      大家看到如上题目,肯定想到的是用if-else if结构来实现,那么具体案例实现如下:

    func main()  {
    	var salary int = 5000
    	var level string
    	fmt.Println("请输入李四的年终评定:")
    	fmt.Scanf("%s",&level)
    	if level == "A"{
    		salary += 500
    	}else if level == "B"{
    		salary += 200
    	}else if level == "C"{
    
    	}else if level == "D"{
    		salary -= 200
    	}else if level == "E"{
    		salary -= 500
    	}else {
    		fmt.Println("输入错误,程序推迟")
    	}
    	fmt.Println("李四来年的工资是:",salary)
    }

      虽然以上代码实现了我们的需求,但是我们发现了一个问题,如果输入其它字符(例如:输入字符T),我们发现最终的结果不仅输出了“输入错误,程序退出”,同时还输出了“李四来年的工资是:5000”。如果输入错误了,这句话是不应该输出的,那么应该怎样进行处理呢?

    func main()  {
    	var salary int = 5000
    	var level string
    	var status bool = true
    	fmt.Println("请输入李四的年终评定:")
    	fmt.Scanf("%s",&level)
    	if level == "A"{
    		salary += 500
    	}else if level == "B"{
    		salary += 200
    	}else if level == "C"{
    
    	}else if level == "D"{
    		salary -= 200
    	}else if level == "E"{
    		salary -= 500
    	}else {
    		status = false
    		fmt.Println("输入错误,程序推迟")
    	}
    	if status{
    		fmt.Println("李四来年的工资是:",salary)
    	}
    }

      通过上面的代码,我们实际上是定义了一个bool类型的变量,默认值为true,当输入评定级别错误时,将其改为false.最后在输出工资时,做了判断,如果条件成立表示输入了正确的评定级别,所以输出对应的工资,否则不输出工资。

      我们前面在讲解if-else if结构时讲过,该结构适合什么场合:1.多条件判断,2:区间性的数据判断。但是我们看一下该案例,是否是对区间性的数据进行判断呢?不是,而是定值判断,也就是对一个固定值的判断。

      对这种固定值的判断推荐使用switch-case结构。  

      switch-case结构语法如下:

      switch 变量或者表达式的值{

        case 值1:

          要执行的代码

        case 值2:

          要执行的代码

        case 值3:

          要执行的代码

             ………………………………..

        default:

          要执行的代码

      }

      switch-case结构的执行流程:

      程序执行到switch处,首先将变量或者表达式的值计算出来,然后拿着这个值依次跟每个case后面所带的值进行匹配,一旦匹配成功,则执行该case所带的代码,执行完成后,跳出switch-case结构。如果,跟每个case所带的值都不匹配。就看当前这个switch-case结构中是否存在default,如果有default,则执行default中的语句,如果没有default,则该switch-case结构什么都不做。

      基本案例演示如下:

    func main()  {
    	var score int = 30
    	switch score {
    	case 90:
    		fmt.Println("优秀")
    	case 80:
    		fmt.Println("良好")
    	case 70:
    		fmt.Println("一般")
    	case 60:
    		fmt.Println("及格")
    	default:
    		fmt.Println("不及格")
    	}
    }
    

      另外一种语法格式如下

    func main() {
    	var score int
    	fmt.Scan(&score)
    
    	switch score / 10 {
    	//如果多个分支执行相同代码  可以在一个case中将多个值用逗号分隔
    	case 10, 9:
    		fmt.Println("A")
    	case 8:
    		fmt.Println("B")
    	case 7:
    		fmt.Println("C")
    	case 6:
    		fmt.Println("D")
    	default:
    		fmt.Println("E")
    	}
    }
    

      注意:某个case 后面跟着的代码执行完毕后,不会再执行后面的case,而是跳出整个switch结构, 相当于每个case后面都跟着break(终止),但是如果我们想执行完成某个case后,强制执行后面的case,可以使用fallthrough。

    func main() {
    	var m int
    	fmt.Scan(&m)
    
    	day := 0
    	switch m {
    	case 1:
    		//在当前分支执行结束后在继续执行下一个分支
    		fallthrough
    	case 3:
    		fallthrough
    	case 5:
    		fallthrough
    	case 7:
    		fallthrough
    	case 8:
    		fallthrough
    	case 10:
    		fallthrough
    	case 12:
    		day = 31
    	case 2:
    		day = 28
    	}
    
    	fmt.Println(day)
    }
    

      下面我们用switch-case结构来实现开头的案例,示例如下:

    func main()  {
    	var salary int = 5000
    	var level string
    	var status bool = true
    	fmt.Println("请输入李四的年终评定:")
    	fmt.Scanf("%s",&level)
    	switch level {
    	case "A":
    		salary += 500
    	case "B":
    		salary += 200
    	case "C":
    	case "D":
    		salary -= 200
    	case "E":
    		salary -= 500
    	default:
    		status = false
    		fmt.Println("输入错误,程序退出!")
    	}
    	if status{
    		fmt.Println("李四的工资是:",salary)
    	}
    }
    

    3.1.6  if - else if 与 switch的比较

      其实通过上面的案例,我们发现switch能够实现的,我们用if-else if也可以实现,那么反过来呢,if-else if能实现的,我们使用switch能否实现呢?接下来将我们前面用if-else if实现的“考试成绩评定”这道题用switch来实现。

    func main(){
    	var score int
    	fmt.Println("请输入考试成绩:")
    	fmt.Scanf("%d",&score)
    	switch  {
    	case score >= 90:
    		fmt.Println("A")
    	case score >= 80:
    		fmt.Println("B")
    	case score >= 70:
    		fmt.Println("C")
    	case score >= 60:
    		fmt.Println("D")
    	default:
    		fmt.Println("E")
    	}
    }
    

      总结:

      相同点:都可以实现多分支结构

      不同点(根据个人习惯进行选择):

      if-else if:可以处理范围

      switch:一般用于等值比较

      下面我们通过一个练习题,将if-else和switch结构进行综合应用

      练习:请用户输年份,再输入月份,输出该月的天数。

    func main()  {
    	var year int
    	var mouth int
    	var day int
    	fmt.Println("请输入年份:")
    	fmt.Scanf("%d
    ",&year)
    	fmt.Println("请输入月份:")
    	fmt.Scanf("%d",&mouth)
    	if mouth >= 1 && mouth <= 12 {
    		switch mouth {
    		case 1,3,5,7,8,10,12:
    			day = 31
    		case 2:
    			if (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0){
    				day = 29
    			}else {
    				day = 28
    			}
    		default:
    			day = 30
    		}
    		fmt.Printf("%d年%d月共%d天",year,mouth,day)
    	}else{
    		fmt.Println("月份输入错误!!")
    	}
    }
    

      通过上面的案例,我们发现switch结构和if-else结构是可以结合来使用的,可以根据具体的问题具体分析,灵活来应用。

    3.2 循环结构

    3.2.1 循环概念

      所谓的循环就是重复的做同一件事情,我们先从生活的角度来理解一下循环。

      打印100份试卷

      李四这次考试又粗心了,爸爸让他写1000遍“下次考试一定要细心”.

      在编程中,我们也会经常遇到循环的问题,例如:

        跟媳妇承认错误,说一万遍"媳妇儿,我错了"

        fmt.Println(“媳妇儿,我错了”)

        fmt.Println(“媳妇儿,我错了”)

        fmt.Println(“媳妇儿,我错了”)

        …………………………………

    3.2.2 基本语法结构

      在GO语言中,我们有专门实现这种循环的结构就是for结构(GO语言中只有for循环结构,没有while,do-while结构),基本语法结构如下:

      for 表达式1;表达式2;表达式3{

        循环体

      }

      表达式1:定义一个循环的变量,记录循环的次数

      表达式2:一般为循环条件,循环多少次

      表达式3:一般为改变循环条件的代码,使循环条件终有一天不再成立

      循环体:重复要做的事情。

       下面我们用for循环结构输出10遍“媳妇儿,我错了”。

    func main()  {
    	var i int
    	for i = 1;i <= 10;i++{
    		fmt.Println("媳妇儿,我错了")
    	}
    }
    

      以上代码执行的顺序:,

      先执行表达式1,然后执行表达式2,判断循环条件是否成立,如果表达式2返回的结果为true,则执行循环体。当执行完循环体后,执行表达式3,然后执行表达式2(这时不会再执行表达式1)继续判断循环条件是否成立,如果成立则继续执行循环体,如果不成立,则跳出for循环。

      我们也可以将语法进行简化如下:

    func main()  {
    	//var i int
    	for i := 1;i <= 10;i++{
    		fmt.Println("媳妇儿,我错了")
    	}
    }
    

    3.2.3 练习

      (1)求1到100之间所有整数的和

    func main()  {
    	sum := 0
    	for i := 1;i <= 100;i++{
    		sum += i
    	}
    	fmt.Println(sum)
    }

      (2)求1到100之间所有偶数的和

    func main()  {
    	sum := 0
    	for i := 0;i <= 100;i+=2{
    		sum += i
    	}
    	fmt.Println(sum)
    }
    

      (3)敲7:计算1-100中 逢7 个位为7 十位为7 或7的倍数 需要敲桌子

    func main()  {
    	for i :=1;i <= 100;i++{
    		if i % 7 == 0 || i / 10 == 7 || i % 10 == 7 {
    			fmt.Println("敲桌子")
    		}else {
    			fmt.Println(i)
    		}
    	}
    }
    

      (4)找出100-999间的水仙花数(水仙花数指的就是 这个百位数字的,百位的立方+十位的立方+个位的立方==当前这个百位数字)

    func main()  {
    	var bw int  //百位
    	var sw int  //十位
    	var gw int  //个位
    	for i := 100;i <= 999;i++{
    		bw = i / 100
    		sw = i / 10 % 10
    		gw = i % 10
    		if bw*bw*bw+sw*sw*sw+gw*gw*gw == i{
    			fmt.Println(i)
    		}
    	}
    }
    

    3.2.4 跳出语句

    关于GO语句中的跳转语句,有break,continue,goto

     

      下面我们先来讲解break

      根据前面的案例,我们发现,循环必须指定循环条件,在满足循环条件的时候执行循环,如果不满足循环的条件,可以跳出整个循环。但是如果,我们没有指定循环条件,那么循环就成了死循环,所谓的死循环指的就是一直循环,跳不出来了。

      怎样构建死循环呢?语法如下:

    func main()  {
    	for {
    		fmt.Println("hello")
    	}
    }
    

      死循环(无限循环)的语法非常简单,就是什么循环条件也没有写。

    下面我们来看一下,关于死循环的应用场景

    案例:要求用户输入用户名和密码,只要不是admin、888888就一直提示用户名,密码错误,请重新输入。

      分析:该题我们怎样构建循环条件呢?

      按照我们以前的做法,很难构建循环条件,那么我们可以使用死循环来做,但是,我们要在用户输入正确的用户名和密码的时候跳出整个循环,那么我们应该怎样强制的跳出死循环呢?我们可以使用break关键字。

        break的作用就是强制结束当前循环,并开始执行循环之后的语句。

      break 语句流程图如下:

      案例演示如下:

    func main()  {
    	var username string
    	var passwd string
    	for {
    		fmt.Print("请输入用户名:")
    		fmt.Scanf("%s
    ",&username)
    		fmt.Print("请输入密码:")
    		fmt.Scanf("%s",&passwd)
    		if username == "admin" && passwd == "888888"{
    			fmt.Println("登陆成功!")
    			//强制结束当前循环
    			break
    		}else {
    			fmt.Println("用户名或密码错误,请重新输入!")
    		}
    	}
    }
    

      通过以上案例演示,我们发现当程序执行到break语句时,会跳出for循环。

      思考:现在将上面的题目的需求在改动一下,加上以下条件”用户名密码输入错误,最多输错3次,超过3次,提示输入错误信息次数太多,并且结束整个程序”,那么该程序怎样修改呢?

      案例演示如下:

    func main()  {
    	var username string
    	var passwd string
    	var count int = 0
    	for {
    		fmt.Print("请输入用户名:")
    		fmt.Scanf("%s
    ",&username)
    		fmt.Print("请输入密码:")
    		fmt.Scanf("%s",&passwd)
    		if username == "admin" && passwd == "888888"{
    			fmt.Println("登陆成功!")
    			//强制结束当前循环
    			break
    		}else {
    			count++
    			if count >= 3{
    				fmt.Println("出入错误次数太多!!")
    				break
    			}
    			fmt.Println("用户名或密码错误,请重新输入!")
    		}
    	}
    }
    

      continue语句

      前面我们已经讲解完成了break,下面我们来说一下continue语句。

      continue的作用是:立即结束本次循环,判断循环条件,如果成立,则进入下一次循环,否则退出循环。

      基本语法:

    func main()  {
    	for i := 1;i <= 5;i++{
    		if i == 2{
    			continue
    		}
    		fmt.Println("i的值为:",i)
    	}
    }
    

      执行过程:当i的值为1时,判断循环条件,满足循环条件(i<=5),进入循环体,执行if判断,发现条件不满足,不执行continue,直接打印,第一次循环结束,进入第二次循环,这时变量i的值为2, 满足循环条件,进入循环体,执行if判断,发现满足条件,执行continue,continue的作用:结束本次循环,也就是不在执行后面的代码(不管后面有多少行代码都不在执行),直接跳转到for,执行for循环的第三个表达式,让i的值进行加1操作,这时i变量的值变成3,判断一下是否满足循环条件,满足(i<=5),进入循环体,开始执行,以此类推。最终输出结果:1,3,4,5

     

      练习:用continue实现计算1到100(含)之间的除了能整除7之外所有整数的和

    func main()  {
    	sum := 0
    	for i := 1;i <= 100;i++{
    		if i % 7 == 0{
    			continue
    		}
    		sum += i
    	}
    	fmt.Println(sum)
    }
    

      最后是 goto  

      Go 语言的 goto 语句可以无条件地转移到过程中指定的行。

      goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。

      但是,在结构化程序设计中一般不主张使用goto语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

      示例如下:

    func main() {
    
    	fmt.Println("helloworld1")
    	fmt.Println("helloworld2")
    	//这里的FLAG是自定义的,不是必须为FLAG
    	goto FLAG
    	fmt.Println("helloworld3")
    	fmt.Println("helloworld4")
    FLAG:
    	fmt.Println("helloworld5")
    	fmt.Println("helloworld6")
    }

      结果如下:

    helloworld1
    helloworld2
    helloworld5
    helloworld6
    

    3.2.5 嵌套循环

      我们在前面学习选择结构时,讲解过关于选择结构的嵌套,同理循环结构也有嵌套。

      基本使用结构如下:

    func main()  {
    	for i := 1;i <= 10;i++{
    		for j := 1;j <= 10;j++{
    			
    		}
    	}
    }
    

      练习1:在屏幕上输出如下图所示的乘法口诀表

    func main()  {
    	for i := 1;i < 10;i++{
    		for j := 1;j < 10;j++{
    			fmt.Printf("%d*%d=%d	",i,j,i*j)
    		}
    		fmt.Println()
    	}
    }
    

      练习2:输出以下结构的乘法口诀表

    func main()  {
    	for i := 1;i <10;i++{
    		for j := 1;j <=i;j++{
    			fmt.Printf("%d*%d=%d	",i,j,i*j)
    		}
    		fmt.Println()
    	}
    }
    

      练习3:输出以下图形

           *
         ***
        *****
       *******
      *********
     ***********

    func main()  {
    	var num int
    	fmt.Print("你想输出几行:")
    	fmt.Scanf("%d
    ",&num)
    	for i := 1;i <= num;i++{
    		for j := 1;j <= ((2*num-1)-(2*i-1))/2;j++  {
    			fmt.Print(" ")
    		}
    		for k := 1;k <=2*i-1;k++{
    			fmt.Print("*")
    		}
    		fmt.Println()
    	}
    }
    

      注意:尽量不要多层嵌套,性能比较低。

  • 相关阅读:
    airpods2连接win10的方法步骤
    JSON学习笔记
    TCP-IP总线与CAN总线优缺点对比
    svn切换目录
    SQLite学习笔记
    python-opencv安装及入门
    python数据可视化
    python-opencv视觉巡线
    python-opencv进阶应用
    QT窗口和部件
  • 原文地址:https://www.cnblogs.com/dacaigouzi1993/p/10957757.html
Copyright © 2020-2023  润新知