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\n", a, b, c)

	//iota遇到const,重置为0
	const d = iota
	fmt.Printf("d=%d\n", d)

	//在iota枚举中,同一行的值相同
	const (
		a1     = iota
		b1, c1 = iota, iota
		d1     = iota
	)
	fmt.Printf("a1=%d,b1=%d,c1=%d,d1=%d\n", a1, b1, c1, d1)

	//在iota枚举中,除第一行外,其他枚举值不用赋值
	const (
		a2 = iota
		b2
		c2
		d2
	)
	fmt.Printf("a2=%d,b2=%d,c2=%d,d2=%d\n", a2, b2, c2, d2)

	const (
		a3 = iota
		b3 = 3
		c3 = iota
		d3 = 7
	)
	fmt.Printf("a3=%d,b3=%d,c3=%d,d3=%d\n", 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\n", sum)
	//强制类型转化
	//数据类型(变量) 数据类型(表达式)
	avg := float64(sum) / float64(num)
	fmt.Printf("avg=%.2f\n", 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\n", a)

	a -= b //a = a - b
	fmt.Printf("a=%d\n", a)

	a *= b //a = a * b
	fmt.Printf("a=%d\n", a)

	a /= b //a = a / b
	fmt.Printf("a=%d\n", a)

	a %= b //a= a % b
	fmt.Printf("a=%d\n", 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\n", a < b)
	fmt.Printf("a > b:%t\n", a > b)

	fmt.Printf("a <= b:%t\n", a <= b)
	fmt.Printf("a >= b:%t\n", a >= b)

	fmt.Printf("a == b:%t\n", a == b)
	fmt.Printf("a != b:%t\n", 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\n", &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\n",&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\n",&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\n",&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\n",&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\t",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\t",i,j,i*j)
		}
		fmt.Println()
	}
}

  练习3:输出以下图形

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

func main()  {
	var num int
	fmt.Print("你想输出几行:")
	fmt.Scanf("%d\n",&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()
	}
}

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

猜你喜欢

转载自www.cnblogs.com/dacaigouzi1993/p/10957757.html