继续
This commit is contained in:
@@ -196,4 +196,359 @@ func demonstrateArrayOperations() {
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
}// de
|
||||
monstrateMultiDimensionalArrays 演示多维数组
|
||||
func demonstrateMultiDimensionalArrays() {
|
||||
fmt.Println("4. 多维数组:")
|
||||
|
||||
// 二维数组
|
||||
fmt.Printf(" 二维数组:\n")
|
||||
|
||||
// 声明和初始化二维数组
|
||||
var matrix [3][4]int
|
||||
fmt.Printf(" 声明 3x4 矩阵: %v\n", matrix)
|
||||
|
||||
// 初始化二维数组
|
||||
matrix2 := [2][3]int{
|
||||
{1, 2, 3},
|
||||
{4, 5, 6},
|
||||
}
|
||||
fmt.Printf(" 初始化 2x3 矩阵:\n")
|
||||
for i, row := range matrix2 {
|
||||
fmt.Printf(" 行 %d: %v\n", i, row)
|
||||
}
|
||||
|
||||
// 访问和修改二维数组元素
|
||||
fmt.Printf(" 访问元素 matrix2[1][2]: %d\n", matrix2[1][2])
|
||||
matrix2[0][1] = 99
|
||||
fmt.Printf(" 修改后 matrix2[0][1]: %d\n", matrix2[0][1])
|
||||
|
||||
// 遍历二维数组
|
||||
fmt.Printf(" 遍历二维数组:\n")
|
||||
for i := 0; i < len(matrix2); i++ {
|
||||
for j := 0; j < len(matrix2[i]); j++ {
|
||||
fmt.Printf(" matrix2[%d][%d] = %d\n", i, j, matrix2[i][j])
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 range 遍历二维数组
|
||||
fmt.Printf(" 使用 range 遍历:\n")
|
||||
for i, row := range matrix2 {
|
||||
for j, value := range row {
|
||||
fmt.Printf(" [%d][%d] = %d\n", i, j, value)
|
||||
}
|
||||
}
|
||||
|
||||
// 三维数组
|
||||
fmt.Printf(" 三维数组:\n")
|
||||
cube := [2][2][2]int{
|
||||
{
|
||||
{1, 2},
|
||||
{3, 4},
|
||||
},
|
||||
{
|
||||
{5, 6},
|
||||
{7, 8},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf(" 3D 数组:\n")
|
||||
for i, plane := range cube {
|
||||
fmt.Printf(" 平面 %d:\n", i)
|
||||
for j, row := range plane {
|
||||
fmt.Printf(" 行 %d: %v\n", j, row)
|
||||
}
|
||||
}
|
||||
|
||||
// 实际应用:游戏棋盘
|
||||
fmt.Printf(" 实际应用 - 井字棋棋盘:\n")
|
||||
board := [3][3]string{
|
||||
{"X", "O", "X"},
|
||||
{"O", "X", "O"},
|
||||
{"X", "O", "X"},
|
||||
}
|
||||
|
||||
fmt.Printf(" 井字棋棋盘:\n")
|
||||
for i, row := range board {
|
||||
fmt.Printf(" ")
|
||||
for j, cell := range row {
|
||||
fmt.Printf("%s", cell)
|
||||
if j < len(row)-1 {
|
||||
fmt.Printf(" | ")
|
||||
}
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
if i < len(board)-1 {
|
||||
fmt.Printf(" ---------\n")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// demonstrateArrayProperties 演示数组的特性
|
||||
func demonstrateArrayProperties() {
|
||||
fmt.Println("5. 数组的特性:")
|
||||
|
||||
// 数组是值类型
|
||||
fmt.Printf(" 数组是值类型:\n")
|
||||
arr1 := [3]int{1, 2, 3}
|
||||
arr2 := arr1 // 拷贝整个数组
|
||||
|
||||
fmt.Printf(" 原数组 arr1: %v\n", arr1)
|
||||
fmt.Printf(" 拷贝数组 arr2: %v\n", arr2)
|
||||
|
||||
// 修改拷贝不影响原数组
|
||||
arr2[0] = 99
|
||||
fmt.Printf(" 修改 arr2[0] 后:\n")
|
||||
fmt.Printf(" arr1: %v (未改变)\n", arr1)
|
||||
fmt.Printf(" arr2: %v (已改变)\n", arr2)
|
||||
|
||||
// 数组比较
|
||||
fmt.Printf(" 数组比较:\n")
|
||||
a := [3]int{1, 2, 3}
|
||||
b := [3]int{1, 2, 3}
|
||||
c := [3]int{1, 2, 4}
|
||||
|
||||
fmt.Printf(" a == b: %t\n", a == b)
|
||||
fmt.Printf(" a == c: %t\n", a == c)
|
||||
fmt.Printf(" a != c: %t\n", a != c)
|
||||
|
||||
// 注意:不同长度的数组是不同类型,不能比较
|
||||
// var d [4]int
|
||||
// fmt.Println(a == d) // 编译错误
|
||||
|
||||
// 数组作为函数参数
|
||||
fmt.Printf(" 数组作为函数参数:\n")
|
||||
original := [3]int{10, 20, 30}
|
||||
fmt.Printf(" 调用前: %v\n", original)
|
||||
|
||||
modifyArrayByValue(original)
|
||||
fmt.Printf(" 值传递后: %v (未改变)\n", original)
|
||||
|
||||
modifyArrayByPointer(&original)
|
||||
fmt.Printf(" 指针传递后: %v (已改变)\n", original)
|
||||
|
||||
// 数组的零值
|
||||
fmt.Printf(" 数组的零值:\n")
|
||||
var zeroIntArray [3]int
|
||||
var zeroStringArray [2]string
|
||||
var zeroBoolArray [2]bool
|
||||
|
||||
fmt.Printf(" int 数组零值: %v\n", zeroIntArray)
|
||||
fmt.Printf(" string 数组零值: %v\n", zeroStringArray)
|
||||
fmt.Printf(" bool 数组零值: %v\n", zeroBoolArray)
|
||||
|
||||
// 数组长度是编译时常量
|
||||
fmt.Printf(" 数组长度是编译时常量:\n")
|
||||
const size = 5
|
||||
constArray := [size]int{1, 2, 3, 4, 5}
|
||||
fmt.Printf(" 使用常量定义数组: %v\n", constArray)
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// demonstratePracticalApplications 演示数组的实际应用
|
||||
func demonstratePracticalApplications() {
|
||||
fmt.Println("6. 数组的实际应用:")
|
||||
|
||||
// 应用1: 统计和分析
|
||||
fmt.Printf(" 应用1 - 成绩统计:\n")
|
||||
scores := [10]int{85, 92, 78, 96, 88, 73, 91, 87, 94, 82}
|
||||
|
||||
// 计算总分和平均分
|
||||
total := 0
|
||||
for _, score := range scores {
|
||||
total += score
|
||||
}
|
||||
average := float64(total) / float64(len(scores))
|
||||
|
||||
// 找最高分和最低分
|
||||
max, min := scores[0], scores[0]
|
||||
for _, score := range scores {
|
||||
if score > max {
|
||||
max = score
|
||||
}
|
||||
if score < min {
|
||||
min = score
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf(" 成绩: %v\n", scores)
|
||||
fmt.Printf(" 总分: %d\n", total)
|
||||
fmt.Printf(" 平均分: %.2f\n", average)
|
||||
fmt.Printf(" 最高分: %d\n", max)
|
||||
fmt.Printf(" 最低分: %d\n", min)
|
||||
|
||||
// 应用2: 频率统计
|
||||
fmt.Printf(" 应用2 - 字符频率统计:\n")
|
||||
text := "hello world"
|
||||
var frequency [26]int // 26个字母的频率
|
||||
|
||||
for _, char := range text {
|
||||
if char >= 'a' && char <= 'z' {
|
||||
frequency[char-'a']++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf(" 文本: \"%s\"\n", text)
|
||||
fmt.Printf(" 字母频率:\n")
|
||||
for i, count := range frequency {
|
||||
if count > 0 {
|
||||
fmt.Printf(" %c: %d\n", 'a'+i, count)
|
||||
}
|
||||
}
|
||||
|
||||
// 应用3: 查找表
|
||||
fmt.Printf(" 应用3 - 月份天数查找表:\n")
|
||||
daysInMonth := [12]int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||
months := [12]string{
|
||||
"一月", "二月", "三月", "四月", "五月", "六月",
|
||||
"七月", "八月", "九月", "十月", "十一月", "十二月",
|
||||
}
|
||||
|
||||
for i := 0; i < len(months); i++ {
|
||||
fmt.Printf(" %s: %d天\n", months[i], daysInMonth[i])
|
||||
}
|
||||
|
||||
// 应用4: 缓冲区
|
||||
fmt.Printf(" 应用4 - 固定大小缓冲区:\n")
|
||||
buffer := [8]byte{}
|
||||
data := []byte("Hello")
|
||||
|
||||
// 将数据复制到缓冲区
|
||||
copy(buffer[:], data)
|
||||
fmt.Printf(" 缓冲区: %v\n", buffer)
|
||||
fmt.Printf(" 缓冲区内容: %s\n", string(buffer[:len(data)]))
|
||||
|
||||
// 应用5: 矩阵运算
|
||||
fmt.Printf(" 应用5 - 矩阵加法:\n")
|
||||
matrixA := [2][2]int{{1, 2}, {3, 4}}
|
||||
matrixB := [2][2]int{{5, 6}, {7, 8}}
|
||||
var result [2][2]int
|
||||
|
||||
// 矩阵加法
|
||||
for i := 0; i < 2; i++ {
|
||||
for j := 0; j < 2; j++ {
|
||||
result[i][j] = matrixA[i][j] + matrixB[i][j]
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf(" 矩阵A: %v\n", matrixA)
|
||||
fmt.Printf(" 矩阵B: %v\n", matrixB)
|
||||
fmt.Printf(" A + B: %v\n", result)
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// demonstrateArrayVsSlice 演示数组 vs 切片
|
||||
func demonstrateArrayVsSlice() {
|
||||
fmt.Println("7. 数组 vs 切片:")
|
||||
|
||||
fmt.Printf(" 数组特点:\n")
|
||||
fmt.Printf(" - 固定长度,长度是类型的一部分\n")
|
||||
fmt.Printf(" - 值类型,赋值和传参会拷贝\n")
|
||||
fmt.Printf(" - 内存效率高,栈上分配\n")
|
||||
fmt.Printf(" - 编译时确定大小\n")
|
||||
fmt.Printf(" - 可以直接比较\n")
|
||||
|
||||
fmt.Printf(" 切片特点:\n")
|
||||
fmt.Printf(" - 动态长度,可以增长和缩减\n")
|
||||
fmt.Printf(" - 引用类型,赋值和传参传递引用\n")
|
||||
fmt.Printf(" - 更灵活,但有额外开销\n")
|
||||
fmt.Printf(" - 运行时动态分配\n")
|
||||
fmt.Printf(" - 不能直接比较\n")
|
||||
|
||||
// 性能比较示例
|
||||
fmt.Printf(" 使用场景建议:\n")
|
||||
fmt.Printf(" 数组适用于:\n")
|
||||
fmt.Printf(" - 固定大小的数据集合\n")
|
||||
fmt.Printf(" - 性能敏感的场景\n")
|
||||
fmt.Printf(" - 需要值语义的场景\n")
|
||||
fmt.Printf(" - 小规模数据\n")
|
||||
|
||||
fmt.Printf(" 切片适用于:\n")
|
||||
fmt.Printf(" - 动态大小的数据集合\n")
|
||||
fmt.Printf(" - 需要灵活操作的场景\n")
|
||||
fmt.Printf(" - 大规模数据处理\n")
|
||||
fmt.Printf(" - 函数参数传递\n")
|
||||
|
||||
// 转换示例
|
||||
fmt.Printf(" 数组和切片的转换:\n")
|
||||
arr := [5]int{1, 2, 3, 4, 5}
|
||||
slice := arr[:] // 数组转切片
|
||||
|
||||
fmt.Printf(" 原数组: %v\n", arr)
|
||||
fmt.Printf(" 转换的切片: %v\n", slice)
|
||||
|
||||
// 修改切片会影响原数组
|
||||
slice[0] = 99
|
||||
fmt.Printf(" 修改切片后:\n")
|
||||
fmt.Printf(" 数组: %v\n", arr)
|
||||
fmt.Printf(" 切片: %v\n", slice)
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// ========== 辅助函数 ==========
|
||||
|
||||
// 值传递数组(会拷贝整个数组)
|
||||
func modifyArrayByValue(arr [3]int) {
|
||||
arr[0] = 999
|
||||
fmt.Printf(" 函数内修改: %v\n", arr)
|
||||
}
|
||||
|
||||
// 指针传递数组(传递数组地址)
|
||||
func modifyArrayByPointer(arr *[3]int) {
|
||||
arr[0] = 888
|
||||
fmt.Printf(" 函数内修改: %v\n", *arr)
|
||||
}
|
||||
|
||||
/*
|
||||
运行这个程序:
|
||||
go run 01-arrays.go
|
||||
|
||||
学习要点:
|
||||
1. 数组是固定长度的元素序列,长度是类型的一部分
|
||||
2. 数组是值类型,赋值和传参会拷贝整个数组
|
||||
3. 数组的零值是所有元素都为零值的数组
|
||||
4. 数组可以直接比较(相同类型和长度)
|
||||
5. 多维数组本质上是数组的数组
|
||||
|
||||
数组的特性:
|
||||
1. 固定长度:编译时确定,不能改变
|
||||
2. 类型安全:所有元素必须是相同类型
|
||||
3. 连续内存:元素在内存中连续存储
|
||||
4. 索引访问:O(1) 时间复杂度
|
||||
5. 值语义:赋值和传参会拷贝
|
||||
|
||||
声明和初始化方式:
|
||||
1. var arr [n]Type
|
||||
2. arr := [n]Type{values...}
|
||||
3. arr := [...]Type{values...} // 自动推断长度
|
||||
4. arr := [n]Type{index: value} // 指定索引
|
||||
|
||||
数组 vs 切片:
|
||||
1. 数组:固定长度,值类型,性能高
|
||||
2. 切片:动态长度,引用类型,更灵活
|
||||
|
||||
使用建议:
|
||||
1. 小规模、固定大小的数据使用数组
|
||||
2. 需要动态调整大小时使用切片
|
||||
3. 性能敏感的场景考虑数组
|
||||
4. 函数参数通常使用切片而不是数组
|
||||
|
||||
常见应用场景:
|
||||
1. 固定大小的缓冲区
|
||||
2. 查找表和映射表
|
||||
3. 矩阵和多维数据
|
||||
4. 统计和频率分析
|
||||
5. 游戏棋盘等固定结构
|
||||
|
||||
注意事项:
|
||||
1. 数组长度是类型的一部分
|
||||
2. 不同长度的数组是不同类型
|
||||
3. 数组传参会拷贝,大数组考虑传指针
|
||||
4. 数组索引越界会 panic
|
||||
5. 多维数组的内存布局是行优先的
|
||||
*/
|
Reference in New Issue
Block a user