3wee-3数组
数组
一.数组的特性
- //数组是值类型: var a=[3]int{1,2,3},b = a,新开内存,造1个全新的副本,造1个全新的副本b
- // 长度不可变
- // 内容可变
- // 可索引
- // 顺序表
- //函数retune出去的数组,也会新开内存存储
- 数组必须在编译时就确定大小,之后不能改变大小
- 元素是连续存放内存中
1.数组定义方式1
func test() {
var a0 [3]int // 定义1个数组叫a0,值是零值 ;数组[ ]里必须给出个数, 如果不赋值,就是0值, len:长度; cap:容量
fmt.Println(len(a0), cap(a0))
2.数组定义方式2
2.定义数组方式2自动推断
var a1 = [3]int{} //
fmt.Println(len(a1), cap(a1), a1) //[0 0 0]
3.定义数组方式3左边写类型 = 后面也写类型,不推断
var a2 [3]int = [3]int{}
fmt.Println(a2) //[0 0 0]
4. 定义数组方式4--- 数组的长度用常量定义
//4.数组的长度用常量定义
const count = 3 //不能用变量.因为数组长度是固定的,不能变
var a3 = [count]int{}
fmt.Println(a3)
5定义数组方式5--- 推断元素个数
var a4 = [...]int{1, 2, 3, 4, 5}
fmt.Println(len(a4), cap(a4))
6 定义数组方式6---初始化前2个元素,后面3个零值
var a5 = [5]int{1, 20}
fmt.Println(a5)
7 定义数组方式7---按照索引定义
var a6 = [5]int{1: 20, 4: 30}
fmt.Println(a6)
二.二维数组
1.数组的理解
- 上图解释:a7是一个二维数组.第一维它有2个元素,每个元素的类型是[3]int的数组,第二维有3个元素(3个元素的int)
// // 二维数组
a7 := [2][3]int{0: {100, 200, 300}}
fmt.Println(a7)
a8 := [...][4]int{10: {100, 200, 300}}
fmt.Println(a8)
三.数组遍历
1.for-len遍历数组
var a0 = [5]int{1, 3, 5, 7, 9}
for i := 0; i < len(a0); i++ { //len(a0)长度是5
// fmt.Println(i, a0[i])
fmt.Printf("数组a的地址:%p\t 索引:%d\t 元素值:%d\t 元素地址:%p +8\n", &a0, i, a0[i], &a0[i])
}
- 元素的首地址就是数组的地址
- 我的电脑是64位,int类型占8Byte,首内存地址连续
偏移
+8Byte,8Byte=64bit符合int类型的定义 - 数组元素改变不会改变数组的内存地址,数组的内存地址是定死的
- 第0个元素的地址就是数组的地址
2.for-range遍历数组
for i, v := range a0 {
fmt.Println(i, v, a0[i])
}
3.遍历数组字符串
var a0 = [3]string{"abc", "d", "xyz"}
for i := 0; i < len(a0); i++ {
fmt.Printf("数组a的地址:%p\t 索引:%d\t 元素值:%s\t 元素地址:%p 16进制F是15,没有16,进位变成10,10=16,占16bytes\n", &a0, i, a0[i], &a0[i])
}
4.遍历数组字符串.超出16byte
- Go 的字符串有个特性,不管长度是多少,大小都是固定的 16 字节.
- Go 的字符串底层并没有实际保存这些字符,而是保存了一个指针,该指针指向的内存区域负责存储具体的字符。由于指针的大小是固定的,所以不管字符串多长,大小都是相等的。
var a1 = [4]string{"abc", "d", "xyzxyzxyzxyzxyzyz", "c"}
for i := 0; i < len(a1); i++ {
fmt.Printf("数组a的地址:%p\t 索引:%d\t 元素值:%s\t 元素地址:%p 16进制F是15,没有16,进位变成10,10=16,占16bytes\n", &a1, i, a1[i], &a1[i])
}
四.数组复制
package main
import "fmt"
func showArr(arr [5]int) {
fmt.Printf("3 %v %p", arr, &arr)
}
func main() {
var a0 = [5]int{1, 3, 5, 7, 9}
fmt.Printf("1 %v %p\n", a0, &a0)
var a1 = a0 //其他语言中,a1和a0是公用1个地址,而go是,另开内存,造一个完全一样的副本,这叫值复制
fmt.Printf("2 %v %p\n", a1, &a1)
fmt.Println(a0 == a1, &a0 == &a1)
showArr(a0) //函数传参
}
- 结果
五.二维数组遍历
//二维数组遍历
arr2 := [3][4]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
for i := 0; i < len(arr2); i++ {
for j := 0; j < len(arr2[i]); j++ {
fmt.Print(arr2[i][j])
}
fmt.Println()
}
for _, v1 := range arr2 {
fmt.Println(v1)
for _, v2 := range v1 {
fmt.Println(v2)
}
}
}