6.4 指针和多维数组
本书前面介绍的指针都是针对一维数组的,除此之外,指针还可以指向多维数组。在具体使用方法上,指向多维数组的指针要更加复杂。在本节的内容中,将详细讲解指针和多维数组的知识。
6.4.1 指向二维数组的指针变量
在Go语言中,指向二维数组的指针变量是一种常见的数据类型,它可以方便地操作二维数组,提高程序的效率和可读性。请看下面的实例代码,演示了声明、初始化和引用指向二维数组的指针变量的过程。
实例6-7:声明、初始化和引用指向二维数组的指针变量(源码路径:Go-codes\6\erwei.go)
实例文件erwei.go的具体实现代码如下所示。
package main
import "fmt"
func main() {
// 声明一个3x3的二维数组
arr := [3][3]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
// 声明一个指向二维数组的指针变量
var p *[3][3]int
p = &arr
// 使用指针访问和修改二维数组的元素
(*p)[0][0] = 100
(*p)[1][1] = 200
// 遍历并打印二维数组的所有元素
for i := 0; i < len(*p); i++ {
for j := 0; j < len((*p)[i]); j++ {
fmt.Print((*p)[i][j], " ")
}
fmt.Println()
}
}
对上述代码的具体说明如下:
- 首先声明了一个3x3的二维数组arr,并将其初始化为包含数字1到9的矩阵。
- 然后,声明了一个指向二维数组的指针变量p,并将其初始化为&arr。这意味着变量p现在指向数组arr的第一个元素,即第一行。
- 使用解引用运算符“*”来访问和修改二维数组中的元素。例如,(*p)[0][0]表示数组的第一个元素,而(*p)[1][1]表示数组的第二行第二个元素。
- 最后,使用两个循环遍历整个二维数组,并将每个元素的值打印到控制台上。需要注意的是,在引用指向二维数组的指针变量时,我们需要使用圆括号来确保正确的优先级。
执行后会输出:
100 2 3
4 200 6
7 8 9
6.4.2 二维数组指针作为函数的参数
在Go语言中,二维数组指针可以作为函数的参数传递。这样可以避免在函数内部复制整个二维数组,提高程序的性能和效率。请看下面的实例,演示了将二维数组指针作为函数的参数的用法。
实例6-8:个税计算器(源码路径:Go-codes\6\er.go)
实例文件er.go的具体实现代码如下所示。
package main
import "fmt"
func printArray(arr *[3][3]int) {
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
fmt.Print(arr[i][j], " ")
}
fmt.Println()
}
}
func main() {
arr := [3][3]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
printArray(&arr)
}
在上述代码中,定义了一个名为printArray()的函数,并将指向[3][3]整数数组的指针变量作为参数传递给该函数。在函数printArray()内部,我们使用两个循环来遍历二维数组中的所有元素,并打印它们的值。需要注意的是,在引用二维数组指针时,我们需要使用圆括号来确保正确的优先级。在函数main()中,我们创建了一个3x3的二维数组arr,并将其传递给printArray函数,由于&arr是一个指向数组的指针,因此我们需要使用“&”符号来获取其地址。需要注意的是,当将二维数组传递给函数时,可以使用指向[3][3]整数数组类型的指针变量作为参数。这避免了在函数内部复制整个数组,提高了程序的性能和效率。
执行后会输出:
1 2 3
4 5 6
7 8 9
6.4.3 三维数组和指针
在Go语言中,指针和三维数组的结合使用也是非常常见的。特别是在处理大型数据集时,使用指针和三维数组可以帮助我们提高代码的性能和可读性。请看下面的实例,演示了使用指针和三维数组的过程。
实例6-9:趣味魔方游戏(源码路径:Go-codes\6\mo.go)
假设有一个趣味的游戏,游戏中有一个 3x3x3 的立方体,每个位置上可以放置一个数字,游戏的目标是使得每个水平面、垂直面和对角线上的数字之和都相等。现在我们使用 Go 语言来实现这个游戏。实例文件mo.go的具体实现代码如下所示。
const (
ROWS = 3
COLS = 3
DEPTHS = 3
)
func main() {
// 初始化立方体数组
cube := make([][][]int, ROWS)
for i := range cube {
cube[i] = make([][]int, COLS)
for j := range cube[i] {
cube[i][j] = make([]int, DEPTHS)
}
}
// 填充立方体数组
for i := 0; i < ROWS; i++ {
for j := 0; j < COLS; j++ {
for k := 0; k < DEPTHS; k++ {
cube[i][j][k] = i + j + k
}
}
}
// 打印立方体数组
for i := 0; i < ROWS; i++ {
for j := 0; j < COLS; j++ {
for k := 0; k < DEPTHS; k++ {
fmt.Printf("%d ", cube[i][j][k])
}
fmt.Println()
}
fmt.Println()
}
}
在上述代码中,首先使用函数make()创建一个指针数组 cube,表示一个 3x3x3 的三维数组。然后,我们使用三重循环填充 cube 数组,使得每个位置上的数字等于该位置的三个下标之和。最后,我们打印 cube 数组,以便查看结果。执行后会输出:
0 1 2
1 2 3
2 3 4
1 2 3
2 3 4
3 4 5
2 3 4
3 4 5
4 5 6
上述代码中的数组初始化和填充过程可以根据实际需求进行修改,例如,可以从用户输入中读取数组元素,或者使用随机数生成器生成元素。此外,这个示例代码只是一个简单的实现,如果需要进一步完善游戏逻辑,可能需要使用更复杂的算法来计算每个面上的数字之和,并进行相应的调整。