章节

3.4 练习

本篇通过若干分级练习巩固数组、切片与 map,并能独立完成基础数据存储、查询与整理。

练习

学完本章你应该掌握

  • 能根据场景区分数组、切片、map,并写出对应的定义、初始化和基础操作代码。
  • 能完成数组和切片的索引、截取、追加、排序,并正确使用 lencapappend
  • 能正确初始化 map,完成增删改查,并使用 value, ok := m[key] 判断键是否存在。
  • 能识别并修正常见错误,例如数组长度不匹配、切片直接越界赋值、append 后漏接收返回值、向 nil map 写入数据。
  • 能把本章知识迁移到基础数据整理场景,例如成绩统计、名称排序、字符数统计和有序输出。

简单

第 1 题:声明并修改一个数组

第 1 题 简单

编写一个 Go 程序,完成下面要求:

  • 声明一个 scores 数组,类型为 [4]int
  • 初始值分别是 88769560
  • 把第二个元素改成 80
  • 依次输出第一个元素、第二个元素和整个数组
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import "fmt"

func main() {
	scores := [4]int{88, 76, 95, 60}
	scores[1] = 80

	fmt.Println(scores[0])
	fmt.Println(scores[1])
	fmt.Println(scores)
}

输出结果:

1
2
3
88
80
[88 80 95 60]

第 2 题:补全自动推导长度的数组

第 2 题 简单

补全下面代码中的两个空白,让程序输出:

1
2
4
map
1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
	langs := ________{"Go", "数组", "切片", "map"}
	fmt.Println(len(langs))
	fmt.Println(langs[________])
}
查看参考答案

补全后的代码如下:

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
	langs := [...]string{"Go", "数组", "切片", "map"}
	fmt.Println(len(langs))
	fmt.Println(langs[len(langs)-1])
}

说明:

  • ... 可以让 Go 自动推导数组长度。
  • len(langs)-1 是最后一个元素的索引。

第 3 题:创建并追加一个切片

第 3 题 简单

编写一个程序,完成下面要求:

  • 使用 make([]string, 0, 3) 创建切片 topics
  • 依次追加 "Go""切片""练习"
  • 输出切片内容
  • 再输出它的长度和容量

示例输出可以类似这样:

1
2
[Go 切片 练习]
3 3
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {
	topics := make([]string, 0, 3)

	topics = append(topics, "Go")
	topics = append(topics, "切片")
	topics = append(topics, "练习")

	fmt.Println(topics)
	fmt.Println(len(topics), cap(topics))
}

第 4 题:写出 makeappend 的结果

第 4 题 简单

阅读下面代码,写出它的输出结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import "fmt"

func main() {
	nums := make([]int, 2, 5)
	nums[0], nums[1] = 10, 20
	nums = append(nums, 30)

	fmt.Println(nums)
	fmt.Println(len(nums), cap(nums))
}
查看参考答案
1
2
[10 20 30]
3 5

说明:make([]int, 2, 5) 创建的是长度为 2、容量为 5 的切片;追加一个元素后,长度变成 3,容量仍然是 5

第 5 题:修正 nil map 的写入错误

第 5 题 简单

下面程序有问题,请改正后让它正常运行,并保持原有输出逻辑不变:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import "fmt"

func main() {
	var levels map[string]int

	levels["初级"] = 1
	value, ok := levels["中级"]

	fmt.Println(value, ok)
}
查看参考答案

修正后的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import "fmt"

func main() {
	levels := make(map[string]int)

	levels["初级"] = 1
	value, ok := levels["中级"]

	fmt.Println(value, ok)
}

输出结果:

1
0 false

说明:map 在写入前必须先初始化;读取不存在的键时,会返回零值和 false

一般

第 6 题:用数组统计三门成绩

第 6 题 一般

编写一个程序,完成下面要求:

  • 提示用户按“成绩1 成绩2 成绩3”的格式输入 3 个整数,例如 80 90 85
  • 使用数组 [3]int 保存这 3 个成绩
  • 使用 for range 计算总分
  • 输出总分和平均分,平均分保留 1 位小数

示例输出可以类似这样:

1
2
total=255
avg=85.0
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

func main() {
	var scores [3]int

	fmt.Print("请输入 3 个成绩:")
	fmt.Scan(&scores[0], &scores[1], &scores[2])

	total := 0
	for _, score := range scores {
		total += score
	}

	avg := float64(total) / float64(len(scores))

	fmt.Printf("total=%d\n", total)
	fmt.Printf("avg=%.1f\n", avg)
}

说明:这道题把数组、输入、遍历和类型转换组合到了一起,是很典型的基础整合题。

第 7 题:对整数切片分别做升序和降序排序

第 7 题 一般

编写一个程序,完成下面要求:

  • 创建切片 nums := []int{34, 12, 56, 23}
  • 先输出原始切片
  • 再把它按升序排序后输出
  • 最后把它按降序排序后输出
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import (
	"fmt"
	"sort"
)

func main() {
	nums := []int{34, 12, 56, 23}

	fmt.Println("原始:", nums)

	sort.Ints(nums)
	fmt.Println("升序:", nums)

	sort.Sort(sort.Reverse(sort.IntSlice(nums)))
	fmt.Println("降序:", nums)
}

一种可能的输出结果:

1
2
3
原始: [34 12 56 23]
升序: [12 23 34 56]
降序: [56 34 23 12]

说明:sort.Ints 用来做升序排序;sort.Reverse 可以把排序结果反过来,得到降序。

第 8 题:建立并查询一张年龄表

第 8 题 一般

编写一个程序,完成下面要求:

  • 创建一个 map[string]int
  • 写入三条数据:"阿斌":18"小李":20"小王":19
  • 删除 "小李"
  • 分别读取 "阿斌""小李" 的年龄
  • 两次读取都要使用 value, ok := m[key]
  • 最后输出两次读取的结果

示例输出可以类似这样:

1
2
18 true
0 false
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main() {
	ages := make(map[string]int)

	ages["阿斌"] = 18
	ages["小李"] = 20
	ages["小王"] = 19

	delete(ages, "小李")

	age1, ok1 := ages["阿斌"]
	age2, ok2 := ages["小李"]

	fmt.Println(age1, ok1)
	fmt.Println(age2, ok2)
}

说明:这道题把 map 的初始化、写入、删除和 ok 判断放到了一起,是 map 最常见的一组操作。

进阶

下面两题会把数组、切片、map 放到更接近真实数据整理的场景里,重点考察多个知识点的配合使用。

第 9 题:统计字符串的字节数和字符数

第 9 题 进阶

编写一个程序,完成下面要求:

  • 读取一个不含空格的字符串,例如 Go语言123
  • 输出它的字节数
  • 再输出它的字符数

示例输出可以类似这样:

1
2
bytes=11
chars=7
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

import "fmt"

func main() {
	var text string

	fmt.Print("请输入字符串:")
	fmt.Scanln(&text)

	fmt.Printf("bytes=%d\n", len(text))
	fmt.Printf("chars=%d\n", len([]rune(text)))
}

说明:

  • len(text) 统计的是字节数。
  • len([]rune(text)) 统计的是字符个数,处理中英文混合内容时更常用。

第 10 题:按固定顺序输出成绩并统计平均分

第 10 题 进阶

已知有一份成绩表:

1
2
3
4
5
scores := map[string]int{
	"阿斌": 92,
	"小李": 85,
	"小王": 88,
}

现在要求你按下面这个顺序输出成绩:

1
names := []string{"小李", "小王", "阿斌"}

请编写程序,完成下面要求:

  • names 的顺序输出每个人的成绩
  • 在输出过程中累计总分
  • 最后输出总分和平均分,平均分保留 1 位小数

示例输出可以类似这样:

1
2
3
4
5
小李: 85
小王: 88
阿斌: 92
total=265
avg=88.3
查看参考答案
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {
	scores := map[string]int{
		"阿斌": 92,
		"小李": 85,
		"小王": 88,
	}

	names := []string{"小李", "小王", "阿斌"}

	total := 0
	for _, name := range names {
		score := scores[name]
		fmt.Printf("%s: %d\n", name, score)
		total += score
	}

	avg := float64(total) / float64(len(names))

	fmt.Printf("total=%d\n", total)
	fmt.Printf("avg=%.1f\n", avg)
}

说明:map 的遍历顺序不固定,所以如果你需要稳定顺序,常见做法是先准备一个切片,再按切片顺序去 map 里取值。

本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字