🚀 Go进阶:流程控制(if/for/switch)与数组切片
大家好!上一篇我们掌握了Go语言的基础语法,包括变量、数据类型以及函数的相关知识,为编程之旅打下了坚实基础。今天,我们将向着更复杂、灵活的程序编写迈进,深入探索Go语言中的流程控制语句以及数组和切片的运用。
一、流程控制:程序的“方向盘”
流程控制语句赋予我们依据条件决定程序执行路径,或重复执行某段代码的能力。Go语言提供了 if
、for
和 switch
等常用流程控制语句。
1. if
语句:条件判断
if
语句依据条件决定是否执行特定代码块,基本格式如下:
if condition {
// 如果条件为真,执行这里的代码
}
示例:判断数字正负性
package main
import "fmt"
func main() {
num := 10
if num > 0 {
fmt.Println(num, "是正数")
}
}
添加 else
分支,用于条件为假时执行:
package main
import "fmt"
func main() {
num := -5
if num > 0 {
fmt.Println(num, "是正数")
} else {
fmt.Println(num, "不是正数")
}
}
if
语句支持 else if
,用于多条件判断:
package main
import "fmt"
func main() {
score := 75
if score >= 90 {
fmt.Println("优秀")
} else if score >= 70 {
fmt.Println("良好")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
}
2. for
语句:循环执行
for
语句是Go语言唯一的循环语句,可用于多种循环类型。
基本格式:
for initialization; condition; post {
// 循环体
}
示例:打印1到10的数字
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
}
省略初始化和后置语句:
package main
import "fmt"
func main() {
i := 1
for i <= 10 {
fmt.Println(i)
i++
}
}
无限循环:
package main
import "fmt"
func main() {
for {
fmt.Println("无限循环中...")
}
}
通常在无限循环中,会使用 break
语句跳出循环。
3. switch
语句:多分支选择
switch
语句依据不同条件执行不同代码块,较多个 if - else if
语句更简洁易读。
基本格式:
switch variable {
case value1:
// 当variable等于value1时执行
case value2:
// 当variable等于value2时执行
default:
// 当variable不等于任何case的值时执行
}
示例:根据数字输出星期几
package main
import "fmt"
func main() {
day := 3
switch day {
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 7:
fmt.Println("星期日")
default:
fmt.Println("无效的数字")
}
}
switch
还支持不指定变量,直接在 case
中使用条件表达式:
package main
import "fmt"
func main() {
num := 15
switch {
case num < 10:
fmt.Println("小于10")
case num >= 10 && num < 20:
fmt.Println("10到19之间")
default:
fmt.Println("大于等于20")
}
}
二、数组和切片:数据的“集合容器”
1. 数组:固定长度的序列
数组是具有固定长度且类型相同元素的序列,定义数组基本格式如下:
var arrayName [length]dataType
示例:定义含5个整数的数组
package main
import "fmt"
func main() {
var numbers [5]int //如果定义好了直接打印 numbers 的话是 [0 0 0 0 0]
numbers[0] = 1
numbers[1] = 2
numbers[2] = 3
numbers[3] = 4
numbers[4] = 5
fmt.Println(numbers) //[1 2 3 4 5]
}
也可在定义时初始化数组:
package main
import "fmt"
func main() {
numbers := [5]int{1, 2, 3, 4, 5}
fmt.Println(numbers)
}
访问数组元素:
package main
import "fmt"
func main() {
numbers := [5]int{1, 2, 3, 4, 5}
fmt.Println(numbers[2]) // 输出第3个元素 3
}
2. 切片:动态长度的序列
切片是基于数组的动态数据结构,长度可在运行时动态变化,定义切片基本格式如下:
var sliceName []dataType
创建切片常用方式:
package main
import "fmt"
func main() {
// 基于数组创建切片
numbers := [5]int{1, 2, 3, 4, 5}
//包前不包后
slice1 := numbers[1:3] // 从数组的第2个元素到第3个元素(不包含第4个元素)
fmt.Println(slice1) //[2 3]
// 使用make函数创建切片
slice2 := make([]int, 3) // 创建一个长度为3的切片
slice2[0] = 10
slice2[1] = 20
slice2[2] = 30
fmt.Println(slice2) //[10 20 30]
}
切片常用操作:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3}
// 添加元素
slice = append(slice, 4)
fmt.Println(slice)
// 切片拼接
slice2 := []int{5, 6}
slice = append(slice, slice2...)
fmt.Println(slice)
}
三、小结
今日我们学习了Go语言的流程控制语句(if
、for
、switch
)和数据集合(数组和切片),这些知识是构建复杂程序的基石。
- 流程控制:
if
语句用于条件判断,引导程序执行方向。for
语句是Go语言的循环支柱,支持多种循环方式。switch
语句提供简洁的多分支选择结构。
- 数组和切片:
- 数组是固定长度的同类型元素序列。
- 切片基于数组,长度动态可变,使用更灵活。
四、实战:学生成绩统计
通过实现一个学生成绩统计程序,巩固所学知识。该程序计算学生成绩的平均分、最高分和最低分,并统计高于平均分的学生人数。
package main
import "fmt"
func main() {
// 声明变量存储学生人数
var studentCount int
fmt.Print("请输入学生人数: ")
// 读取用户输入并检查错误
if _, err := fmt.Scan(&studentCount); err != nil {
fmt.Println("输入错误,请输入有效的整数")
return // 发生错误时终止程序
}
// 创建一个切片存储学生成绩,预分配容量以提高性能
// make([]int, 0, studentCount) 表示初始长度为0,容量为studentCount
scores := make([]int, 0, studentCount)
// 初始化总分、最高分和最低分
total := 0
maxScore := -1 // 初始化为不可能的低分,确保任何有效分数都能更新它
minScore := 101 // 初始化为不可能的高分,确保任何有效分数都能更新它
// 循环读取每个学生的成绩
for i := 0; i < studentCount; i++ {
var score int
fmt.Printf("请输入第%d个学生的成绩: ", i+1)
// 读取成绩并检查输入是否有效
if _, err := fmt.Scan(&score); err != nil {
fmt.Println("输入错误,请输入有效的整数")
return
}
// 将成绩添加到切片中
scores = append(scores, score)
// 累加总分
total += score
// 更新最高分:如果当前成绩大于最高分,则替换
if score > maxScore {
maxScore = score
}
// 更新最低分:如果当前成绩小于最低分,则替换
if score < minScore {
minScore = score
}
}
// 处理边界情况:如果没有学生数据
if len(scores) == 0 {
fmt.Println("没有学生数据")
return
}
// 计算平均分(转换为浮点数以保留小数部分)
average := float64(total) / float64(len(scores))
// 统计高于平均分的学生人数
aboveAverageCount := 0
// 使用 range 遍历切片,_ 表示忽略索引(不需要索引)
// score 直接获取切片中的每个元素值
for _, score := range scores {
if score > int(average) { // 注意:这里将平均分转换为整数进行比较
aboveAverageCount++
}
}
// 输出统计结果,使用更美观的格式
fmt.Printf("\n统计结果:\n")
fmt.Printf("学生人数: %d\n", len(scores))
fmt.Printf("平均分: %.2f\n", average) // %.2f 表示保留两位小数
fmt.Printf("最高分: %d\n", maxScore)
fmt.Printf("最低分: %d\n", minScore)
fmt.Printf("高于平均分的学生人数: %d\n", aboveAverageCount)
}
运行结果:
请输入学生人数: 3
请输入第1个学生的成绩: 90
请输入第2个学生的成绩: 95
请输入第3个学生的成绩: 100
统计结果:
学生人数: 3
平均分: 95.00
最高分: 100
最低分: 90
高于平均分的学生人数: 1
通过此实战案例,希望大家能更好理解和运用今日所学。持续练习,在Go语言学习之路上稳步前行!
专栏预告:下一篇我们将学习Go语言的强大特性,深入了解结构体、接口以及 Go 语言独特的面向对象编程方式,带你领略Go语言在构建复杂数据结构和实现面向对象编程范式方面的魅力,学会这些将大幅提升你对大型程序的设计与开发能力,敬请期待!😊