循环结构
应用场景
我们在写程序的时候,一定会遇到需要重复执行某条或某些指令的场景。例如用程序控制机器人踢足球,如果机器人持球而且还没有进入射门范围,那么我们就要一直发出让机器人向球门方向移动的指令。在这个场景中,让机器人向球门方向移动就是一个需要重复的动作,当然这里还会用到上一课讲的分支结构来判断机器人是否持球以及是否进入射门范围。再举一个简单的例子,如果要实现每隔1秒中在屏幕上打印一次“hello, world”并持续打印一个小时,我们肯定不能够直接把fmt.Printf('hello, world')
这句代码写3600遍,这里同样需要循环结构。
循环结构就是程序中控制某条或某些指令重复执行的结构。在golang中构造循环结构只有1种做法,for
循环。
for循环
基本的 for 循环由三部分组成,它们用分号隔开:
- 初始化语句:在第一次迭代前执行
- 条件表达式:在每次迭代前求值
- 后置语句:在每次迭代的结尾执行
例如下面代码中计算1~100求和的结果( ∑ n = 1 100 n \displaystyle \sum \limits_{n=1}^{100}n n=1∑100n)。
/*
用for循环实现1~100求和
Version: 1.0
Author: 长柳
*/
sum = 0
for i:=1;i<101;i++{
sum+=i
}
fmt.Printf(sum)
上面代码中的,i
仅在for循环内生效,i:=0
为初始化语句,仅在第一次迭代前执行,i<101
为条件表达式,在每次迭代前求值,i++
为后置语句,在每次迭代的结尾执行。初始化语句,条件表达式,后置语句都不是必要的,可以进行省略,可以看看下面的代码
//用for实现累加到1000
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
// 无限循环(可用作简单定时任务)
for {
time.Sleep(3 * time.Second)
fmt.Println("do something")
}
Go当中也有range
的关键字可供使用,一般用于迭代数组、切片、字符串、map 或通道(channel)等集合类型的元素(后面会逐个说明)。range 结构通常与 for 循环配合使用,示例如下
// 示例:遍历字符串并打印字符及其索引
str := "Hello, 世界"
for i, ch := range str {
fmt.Printf("Index: %d, Character: %c\n", i, ch)
}
练习
练习1:输入一个正整数判断是不是素数。
提示:素数指的是只能被1和自身整除的大于1的整数。
参考答案:
/*
素数判断
Version: 1.0
Author: 长柳
*/
func isPrime(n int) bool {
if n <= 1 {
return false
}
for i := 2; i*i <= n; i++ {
if n%i == 0 {
return false
}
}
return true
}
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入一个整数:")
inputStr, _ := reader.ReadString('\n')
num, _ := strconv.Atoi(strings.TrimSpace(inputStr))
if isPrime(num) {
fmt.Printf("%d 是素数。\n", num)
} else {
fmt.Printf("%d 不是素数。\n", num)
}
}
练习2:实现一个平方根函数:用牛顿法实现平方根函数。
提示:计算机通常使用循环来计算 x 的平方根。从某个猜测的值 z 开始,我们可以根据 z² 与 x 的近似度来调整 z,产生一个更好的猜测:z -= (z*z - x) / (2*z)
参考答案:
/*
计算平方根,精度到0.01
*/
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
z:= float64(1)
s:= 0.001 //选择的精度
//math.Abs()为取绝对值,返回float64类型
for math.Abs(z*z-x)>s{
z -= (z*z - x) / (2*z)
}
return z
}
func main() {
fmt.Println(Sqrt(2))
}
练习3:打印如下所示的三角形图案。
*
**
***
****
*****
*
**
***
****
*****
*
***
*****
*******
*********
参考答案:
/*
打印三角形图案
*/
package main
import (
"fmt"
)
func main(){
row := 5
for i:=0;i<row;i++{
for j:=0;j<i+1;j++{
fmt.Printf("*")
}
fmt.Println()
}
for i:=0;i<row;i++{
for j:=0;j<row;j++{
if j < row - i - 1{
fmt.Printf(" ")
}else{
fmt.Printf("*")
}
}
fmt.Println()
}
for i:=0;i<row;i++{
for j:=0;j<(row - i - 1);j++{
fmt.Printf(" ")
}
for k:=0;k<(2 * i + 1);k++{
fmt.Printf("*")
}
fmt.Println()
}
}