欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

go语言使用-引用数据类型——数组

程序员文章站 2022-05-27 08:30:25
...

一、基本介绍

数组可以存放多个同一类型数据。数组也是一种数据类型,在Go中,
数组是值类型。

二、基本语法

数组的定义
    var  数组名 [数组大小]数据类型 
    var a [5]int  
    赋初值 a[0] = 1 a[1] = 30 ....  

三、快速入门案例

/*
一个养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,
3.4kg,2kg,50kg 。请问这六只鸡的总体重是多少?平
均体重是多少? 请你编一个程序
*/
func ArrayDemo()  {
    var hens [6] float64
    hens[0]=3
    hens[1]=5
    hens[2]=1
    hens[3]=3.4
    hens[4]=2
    hens[5]=50
    var sum float64
    for _, value := range hens {
        sum +=value
    }

    aver := sum / float64(len(hens))

    fmt.Printf("这六只鸡的总体重是%f 平均体重是%f \n",sum,aver)
}

四、数组内存分析

//分析go 的数组在内存中存在的形式
func main() {
    var scores [3]int 
     scores[0] = 10
    scores[1] = 20
    scores[2] = 30  
}

go语言使用-引用数据类型——数组

五、数组的使用

1、访问数组元素
数组名[下标] 比如:你要使用a数组的第三个元素 a[2]
2、四种初始化数组的方式

//数组的四种初始化方式
func ArrayDemo2()  {

    //定义形式
    var array [3] int = [3] int {1,2,3} 
    var array1  = [3] int {1,2,3}
    var array2  = [...] int {1,2,3}
    //指定元素对应下标
    var array3 = [3] int {1:1,2:2,0:3}
    fmt.Println("array=",array)
    fmt.Println("array1=",array1)
    fmt.Println("array2=",array2)
    fmt.Println("array3=",array3)
}

3、数组遍历
1)方式1-常规遍历:

var array [3] int = [3] int {1,2,3} 
for i:= 0; i< len(array); i++{
    array[i]
}

2)方式2-for-range结构遍历

这是Go语言一种独有的结构,可以用来遍历访问数组的元素。

  • 基本语法
for index, value := range array01 { 
... 
}
  • 说明

1) 第一个返回值 index 是数组的下标
2) 第二个value是在该下标位置的值
3) 他们都是仅在 for 循环内部可见的局部变量
4) 遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线_
5) index 和 value 的名称不是固定的,即程序员可以自行指定,一般命名为 index 和 value

示例:

func ArrayDemo4()  {
    var chars [26] byte

    chars[0] = 'A'

    for i := 1; i < 26; i++ {
        chars[i]=chars[i-1]+1       
    }
    for index ,value := range chars {
        fmt.Printf("chars[%d]=%c \n",index,value)
    }

六、数组使用细节和注意事项

1、 数组是多个相同类型数据的组合,一个数组一旦声明/定义了,其长度是固定的, 不能动态变化。
2、var arr []int 这时 arr 就是一个slice切片,切片后面专门讲解。
3、 数组中的元素可以是任何数据类型,包括值类型和引用类型,但是不能混用。
4)、数组创建后,如果没有赋值,有默认值(零值)

数值类型数组:默认值为 0
字符串数组:   默认值为 ""    
bool数组:  默认值为 false

5、 使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值(默认零值) 3 使用数组
6)、数组的下标是从0开始的。
7、 数组下标必须在指定范围内使用,否则报 panic:数组越界,比如
var arr [5]int 则有效下标为 0-4
8)、Go的数组属值类型, 在默认情况下是值传递, 因此会进行值拷贝。数组间不会相互影响
9)、如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)
示例

package main
import (
    "fmt"

)

func test(arr [3]int) {
    arr[0] = 100

    fmt.Println("test arr", arr)
}

func test2(arr *[3]int) {
     (*arr)[0] = 100

     fmt.Println("test arr", *arr)
}

//分析go 的数组在内存中存在的形式
func main() {
    var scores [3]int // 
    // scores[0] = 10
    // scores[1] = 20
    // scores[2] = 30
    // fmt.Printf("scores[0]地址=%p scores[1]地址=%p scores[2]地址=%p 数组名地址=%p\n", 
    //  &scores[0], &scores[1], &scores[2], &scores)
    test2(&scores)
    fmt.Println("scores", scores)
}

go语言使用-引用数据类型——数组

10、长度是数组类型的一部分,在传递函数参数时 需要考虑数组的长度。

//默认值拷贝
func modify(arr [3]int ){
arr[0] = 100
fmt.Println("modify 的 arr ", arr)
}

func main() {
var arr = [...]int{1, 2, 3}
modify(arr) 
}

七、数组复杂使用-数组反转

要求:随机生成6个数,并将其反转打印。

func ArrayDemo5()  {
    var arr [7] int
    rand.Seed(time.Now().UnixNano())

    for i := 0; i < len(arr) - 1; i++ {
        radom := rand.Intn(100)
        arr[i] = radom
    }
    fmt.Println("随机数组arr=",arr)

    count := len(arr) 
    var arr2 [7] int
    for i := count - 1; i >= 0; i-- {

        fmt.Printf("反转打印数组arr[%d]=%d \n",i,arr[i])
        arr2[count -i-1]=arr[i]
    }
    fmt.Println("新数组arr2=",arr2)
    fmt.Println("原数组arr=",arr)
    for i := 0; i < count / 2; i++ {
        temp := arr[i]
        arr[i] = arr[ count - 1 - i ]
        arr[ count - 1 - i ] =temp
        fmt.Println("arr=",arr)
    }

}

八、二维数组

1、基本介绍
多维数组我们只介绍二维数组
2、使用方式
使用方式1: 先声明/定义,再赋值
1) 语法: var 数组名 [大小][大小]类型
2) 比如: var arr [2][3]int , 再赋值。
3) 使用演示

    var arr [4][6]int
    arr[1][2] = 1
    arr[2][1] = 2
    arr[2][3] = 3

4) 二维数组在内存的存在形式(重点)

go语言使用-引用数据类型——数组
使用方式2: 直接初始化
1) 声明:var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
2) 赋值(有默认值,比如int 类型的就是0)
3) 使用演示

a = [3][4]int{  
 {0, 1, 2, 3} ,   /*  第一行索引为 0 */
 {4, 5, 6, 7} ,   /*  第二行索引为 1 */
 {8, 9, 10, 11}   /*  第三行索引为 2 */
}

4) 说明:二维数组在声明/定义时也对应有四种写法[和一维数组类似]
var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 [大小][大小]类型 = […][大小]类型{{初值..},{初值..}}
var 数组名 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 = […][大小]类型{{初值..},{初值..}}

3、快速入门案例:
请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0

package main
import (
    "fmt"
)

func main() {

//  快速入门案例:
// 请用二维数组输出如下图形
// 0 0 0 0 0 0  => arr[0]  =>arr[0][0] arr[0][1]  ...
// 0 0 1 0 0 0  => arr[1]  =>arr[1][2]=1...
// 0 2 0 3 0 0  => arr[2]
// 0 0 0 0 0 0  => arr[3]

    var arr [4][6]int
    fmt.Println("arr-len=", len(arr)) //4
    arr[1][2] = 1
    arr[2][1] = 2
    arr[2][3] = 3
    //遍历
    for i := 0; i < len(arr); i++ {
        for j := 0; j < len(arr[i]); j++ {
            fmt.Print(arr[i][j],"\t")
        }
        fmt.Println()
    }

    //使用for-range遍历 二维数组
    for i, v := range arr { // v 是一个一维数组
        for j, v2 := range v {
            fmt.Printf("arr[%d][%d]=%d\t", i, j ,v2)
        }
        fmt.Println()
    }
}

4、二维数组的遍历
1) 双层for循环完成遍历
2) for-range方式完成遍历

案例:定义二维数组,用于保存三个班,每个班五名同学成绩,
并求出每个班级平均分、以及所有班级平均分

package main
import (
    "fmt"
)

// 定义二维数组,用于保存三个班,每个班五名同学成绩,
// 并求出每个班级平均分、以及所有班级平均分
func main() {

    var scores [3][5]float64
    for i := 0; i < len(scores); i++ {
        for j := 0; j < len(scores[i]); j++ {
            fmt.Printf("请输入第%d班的第%d学生的成绩\n", i + 1, j + 1)
            fmt.Scanln(&scores[i][j])
        }
    }

    //遍历二维数组求出总分
    totalSum := 0.0
    classNum :=  len(scores)
    for i := 0; i < classNum; i++ {

        //对每个班遍历
        sum := 0.0
        for j := 0; j < len(scores[0]); j++ {
            sum += scores[i][j]
        }
        totalSum += sum // 将所有班级的分数累计
        fmt.Printf("第%d班的平均分=%f\n", i+1, sum/float64(len(scores[i])))
    }

    fmt.Printf("所有学生的平均分=%f\n", totalSum/float64(len(scores[0]) * classNum))

}