数组定义和内存布局
数组是多个相同类型数据的组合,一个数组一旦声明/定义了,其长度是固定的, 不能动态变化。
数组可以存放多个同一类型数据。数组也是一种数据类型,在 Go 中,数组是值类型。使用数组来解决问题,程序的可维护性增加,代码更加清晰,也容易扩展。
数组中的元素可以是任何数据类型,包括值类型和引用类型,但是不能混用。
数组的定义
var 数组名 [数组大小]数据类型
var a [5]int
数组的初始化
var numArr01 [3]int = [3]int{1, 2, 3}
fmt.Println("numArr01=", numArr01)
var numArr02 = [3]int{5, 6, 7}
fmt.Println("numArr02=", numArr02)
var numArr03 = [...]int{8, 9, 10}
fmt.Println("numArr03=", numArr03)
var numArr04 = [...]int{1: 800, 0: 900, 2: 999}
fmt.Println("numArr04=", numArr04)
//类型推导
strArr05 := [...]string{1: "tom", 0: "jack", 2: "mary"}
fmt.Println("strArr05=", strArr05)
数组的赋值
a[0] = 1 a[1] = 30 ....
数组的内存布局
- 数组的地址可以通过数组名来获取 &intArr
- 数组的第一个元素的地址,就是数组的首地址
- 数组的各个元素的地址间隔是依据数组的类型决定,比如 int64 -> 8 int32->4…
4)数组的下标是从 0 开始的
数组下标必须在指定范围内使用,否则报 panic:数组越界,比如var arr [5]int 则有效下标为 0-4
var intArr [3]int //int占16个字节
//当我们定义完数组后,其实数组的各个元素有默认值 0
fmt.Println(intArr)
intArr[0] = 10
intArr[1] = 20
intArr[2] = 30
fmt.Println(intArr)
fmt.Printf("intArr的地址=%p intArr[0] 地址%p intArr[1] 地址%p intArr[2] 地址%p\n",
&intArr, &intArr[0], &intArr[1], &intArr[2])
数组的使用
使用数组的步骤
- 声明数组并开辟空间
- 给数组各个元素赋值(数组创建后,如果没有赋值,有默认值(零值))
- 使用数组
数组名[下标] : 要使用 a 数组的第三个元素 a[2]
数组的默认值
- 数值类型数组:默认值为 0
- 字符串数组: 默认值为 “”
- bool 数组: 默认值为 false
//数组创建后,如果没有赋值,有默认值(零值)
//1. 数值(整数系列, 浮点数系列) =>0
//2. 字符串 ==> ""
//3. 布尔类型 ==> false
var arr01 [3]float32
var arr02 [3]string
var arr03 [3]bool
fmt.Printf("arr01=%v arr02=%v arr03=%v\n", arr01, arr02, arr03)
数组的遍历
常规遍历
for i := 0; i < len(score); i++ {
fmt.Printf("score[%d]=%v\n", i, score[i])
}
for-range 结构遍历
var intArr2 [5]int = [...]int {1, -1, 9, 90, 12}
sum := 0
for _, val := range intArr2 {
//累计求和
sum += val
}
Go 的数组属值类型, 在默认情况下是值传递, 因此会进行值拷贝。数组间不会相互影响
如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)
长度是数组类型的一部分,在传递函数参数时 需要考虑数组的长度
var arr []int 这时 arr 就是一个 slice 切片