当前位置:首页 > 技术文章 > 正文内容

Go语言二维数组_二维数组怎么用gets输入

zonemu1个月前 (09-06)技术文章17

Go语言二维数组完全指南

二维数组是包含数组的数组,在Go语言中有着广泛的应用场景。下面我会从基础到高级,详细讲解Go中二维数组的各种用法。


一、二维数组的基本概念

1. 什么是二维数组?

二维数组就是"数组的数组",可以想象成表格或矩阵:

[
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

2. 声明与初始化

// 方法1:直接初始化
var matrix1 [3][3]int = [3][3]int{
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
}

// 方法2:先声明后赋值
var matrix2 [2][2]string
matrix2[0][0] = "a"
matrix2[0][1] = "b"
matrix2[1][0] = "c"
matrix2[1][1] = "d"

// 方法3:自动推断长度
matrix3 := [...][2]int{
    {1, 2},
    {3, 4},
}

二、二维数组的实际应用案例

案例1:矩阵运算

func main() {
    // 定义两个2x2矩阵
    a := [2][2]int{{1, 2}, {3, 4}}
    b := [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] = a[i][j] + b[i][j]
        }
    }
    fmt.Println(result) // [[6 8] [10 12]]
}

案例2:井字棋游戏

func printBoard(board [3][3]string) {
    for i := 0; i < 3; i++ {
        fmt.Println(board[i])
    }
}

func main() {
    // 初始化3x3游戏棋盘
    board := [3][3]string{
        {" ", " ", " "},
        {" ", " ", " "},
        {" ", " ", " "},
    }
    
    // 玩家X下棋
    board[1][1] = "X"
    printBoard(board)
    /* 输出:
    [   ]
    [  X ]
    [   ]
    */
}

三、二维数组的高级用法

1. 动态二维数组(使用切片)

固定大小的数组不够灵活,实际开发中更多使用切片实现二维数组:

func main() {
    // 创建3x3的动态二维切片
    matrix := make([][]int, 3)
    for i := range matrix {
        matrix[i] = make([]int, 3)
    }
    
    // 赋值
    matrix[0][0] = 1
    matrix[1][1] = 5
    matrix[2][2] = 9
    
    fmt.Println(matrix) // [[1 0 0] [0 5 0] [0 0 9]]
}

2. 不规则二维数组

Go中的二维切片可以是"不规则"的(每行长度不同):

func main() {
    // 创建不规则二维切片
    irregular := [][]int{
        {1},
        {2, 3},
        {4, 5, 6},
    }
    
    fmt.Println(irregular) // [[1] [2 3] [4 5 6]]
}

3. 遍历二维数组

func main() {
    matrix := [][]int{
        {1, 2, 3},
        {4, 5, 6},
    }
    
    // 方法1:使用索引
    for i := 0; i < len(matrix); i++ {
        for j := 0; j < len(matrix[i]); j++ {
            fmt.Printf("%d ", matrix[i][j])
        }
        fmt.Println()
    }
    
    // 方法2:range遍历
    for _, row := range matrix {
        for _, val := range row {
            fmt.Printf("%d ", val)
        }
        fmt.Println()
    }
}

四、二维数组与函数

1. 作为函数参数

func sumMatrix(m [3][3]int) int {
    sum := 0
    for _, row := range m {
        for _, val := range row {
            sum += val
        }
    }
    return sum
}

func main() {
    matrix := [3][3]int{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    }
    fmt.Println(sumMatrix(matrix)) // 45
}

2. 返回二维数组

func createIdentityMatrix(size int) [][]int {
    matrix := make([][]int, size)
    for i := range matrix {
        matrix[i] = make([]int, size)
        matrix[i][i] = 1
    }
    return matrix
}

func main() {
    idMatrix := createIdentityMatrix(3)
    fmt.Println(idMatrix) // [[1 0 0] [0 1 0] [0 0 1]]
}

五、二维数组的注意事项

  1. 内存布局
  2. Go中的二维数组在内存中是连续存储的
  3. 访问顺序影响性能(行优先访问更快)
  4. 性能优化
  5. // 不好的访问方式(列优先) for j := 0; j < cols; j++ { for i := 0; i < rows; i++ { fmt.Println(matrix[i][j]) } } // 好的访问方式(行优先) for i := 0; i < rows; i++ { for j := 0; j < cols; j++ { fmt.Println(matrix[i][j]) } }
  6. 与切片的区别
  7. 数组是值类型,赋值会拷贝整个数组
  8. 切片是引用类型,赋值只拷贝指针

六、综合练习:图像处理

// 定义图像类型(二维数组表示像素)
type Image [][]Pixel

type Pixel struct {
    R, G, B uint8
}

// 转换为灰度图
func (img Image) ToGrayscale() {
    for i := range img {
        for j := range img[i] {
            gray := uint8(0.299*float64(img[i][j].R) + 
                         0.587*float64(img[i][j].G) + 
                         0.114*float64(img[i][j].B))
            img[i][j] = Pixel{gray, gray, gray}
        }
    }
}

func main() {
    // 创建一个2x2的彩色图像
    img := Image{
        {{255, 0, 0}, {0, 255, 0}},
        {{0, 0, 255}, {255, 255, 255}},
    }
    
    img.ToGrayscale()
    fmt.Println(img)
}

七、总结

  1. 固定大小二维数组:[m][n]T 形式,适合已知维度的场景
  2. 动态二维切片:[][]T 更灵活,是实际开发中最常用的
  3. 核心操作: 初始化(注意切片需要双重make) 遍历(推荐range方式) 作为函数参数传递
  4. 应用场景: 数学计算(矩阵运算) 游戏开发(棋盘、地图) 图像处理(像素矩阵)

通过不断练习,你会熟练掌握二维数组的各种用法!

相关文章

垃圾收费管理系统(垃圾收运管理系统)

今天来了解《#垃圾收费管理系统》,它包括如下功能:收费单位表格界面,类别表格界面,类别设置信息窗口,单位信息表格界面,单位信息信息窗口,缴费登记信息窗口,缴费登记表格界面,缴费登记的缴费单.1,到期提...

git的几种分支模式(git分支的概念)

编写代码,是软件开发交付过程的起点,发布上线,是开发工作完成的终点。代码分支模式贯穿了开发、集成和发布的整个过程,是工程师们最亲切的小伙伴。那如何根据自身的业务特点和团队规模来选择适合的分支模式呢?本...

程序员项目经理如何调动组员积极性

#这个方法应该很适合程序员都说程序员是比较傲娇,有点小自负(有的是相当,那不叫自负,那是实力的体现好吗),略微呆萌,自尊心偏小强的一类族群。是吗?中招了吗?作为管理好几个组员,要完成一个大项目的项目经...

02.Web大前端时代之:HTML5+CSS3入门系列~H5结构元素

Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html1.结构元素 可以理解为语义话标记,比如:以前这么写<...

一键看懂Html5,就这么简单(查看html的app推荐)

HTML5是WEB开发世界的一次重大的改变,事实上不管你是否喜欢,它都是代表着未来趋势。曾几何时,当HTML5出现在web端开发领域的时候,并没有引起太多人的注意,究其原因,一方面是它还没有被广泛的支...

全屋定制板材怎么选不出错?6 种板材深度对比,3 套方案闭眼选

装修选板材头疼吧?刚装完的柜子变形发霉,说好的环保结果甲醛超标,这种翻车现场见太多了。厨房卫生间千万别用密度板,这玩意儿遇水就膨胀,半年准完蛋。颗粒板性价比确实高,但小厂出的真心不敢用。环保等级至少得...