6 数组

6.1 数组的定义

数组在定义时就需要声明其元素数量和类型:

1
2
// T 即元素类型
var 数组变量名 [元素数量] T

如:var a [5]int.

数组的长度必须是常量,并且长度是数组类型的一部分,一旦定义,长度不能变。所以,[5]int[10]int 是不同的类型。

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
var a [3]bool
var b [6]bool

// a的类型是-[3]bool,b 的类型是-[6]bool
fmt.Printf("a的类型是-%T,b 的类型是-%T", a, b)
}

数组可以通过下表进行访问,下标从 0 开始,最后一个元素下标为:len-1

6.2 数组的初始化

6.2.1 方式1——通过初始化列表设置值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import "fmt"

func main() {
// 未初始化时,元素取类型默认值(零值):bool 零值为 false; 整型和浮点型的零值为 0;字符串的零值为:""
var arr1 [3]int
var arr2 = [3]int{1, 2, 3}
var strArr = [3]string{"北京", "上海", "广州"}

// [0 0 0]
fmt.Println(arr1)
// [1 2 3]
fmt.Println(arr2)
// [北京 上海 广州]
fmt.Println(strArr)
}

6.2.2 初始化方式2——...

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
// ... 表示让系统根据初始值自己去数元素数量
arr1 := [...]int{1, 2, 3, 4, 5, 6, 7, 8}
fmt.Println(arr1)
}

6.2.3 初始化方式3——使用零值补足元素

1
2
3
4
5
6
7
8
9
10
package main

import "fmt"

func main() {
// 初始时元素真实数量小于声明数量时,使用元素类型对应的默认值补足
var arr1 = [5]int{1, 2, 3}
// [1 2 3 0 0]
fmt.Println(arr1)
}

6.2.4 初始化方式4——指定索引对应的值

1
2
3
4
5
6
7
8
9
10
package main

import "fmt"

func main() {
// 初始时元素真实数量小于声明数量时,可以指定某个索引对应的值,未指定的部分使用默认值补足
var arr1 = [5]int{0: 1, 4: 2}
// [1 0 0 0 2]
fmt.Println(arr1)
}

6.3 数组的遍历

可以使用 forfor-range 两种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"
)

func main() {

arr1 := [...]int{1, 2, 3, 4, 5, 6, 7}

for i := 0; i < len(arr1); i++ {
// 获取数组指定索引位置对应的元素并打印
fmt.Println(arr1[i])
}

for index, intValue := range arr1 {
fmt.Printf("索引 %d 对应的值为 %d \n", index, intValue)
}
}

6.4 多维数组

6.4.1 多维数组的声明和初始化

var arr [3][2]int 表示声明一个二维数组,该二维数组有三个元素,每个元素都是一个有两个 int 元素的数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
var arr [3][2]int
arr = [3][2]int{
// 二维数组中,每个一维数组后面都必须跟一个逗号,否则报错。
[2]int{1, 2},
// 可以省略以为数组类型的声明,直接写值
{3, 4},
{5, 6},
}
// [[1 2] [3 4] [5 6]]
fmt.Println(arr)
}

在声明多维数组时,只有最外层可以使用 ....如:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func main() {
arr := [...][2]int{
{1, 2},
{3, 4},
{5, 6},
}
// [[1 2] [3 4] [5 6]]
fmt.Println(arr)
}

6.4.2 多维数组的遍历

嵌套 for 循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main() {
var arr [3][2]int
arr = [3][2]int{
{1, 2},
{3, 4},
{5, 6},
}

for _, v1 := range arr {
for _, v2 := range v1 {
fmt.Printf("%d \t", v2)
}
fmt.Println()
}
}

输出结果如下:

1
2
3
1 	2 	
3 4
5 6

6.4.3 数组是值类型(值传递)

数组是值类型(值传递),赋值和传参会复制整个数组。因此改变副本的值并不会改变其本身。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {
a := [...]int{1, 2, 3}
modifyArr1(a)
// [1 2 3]
fmt.Println(a)

b := [...][2]int{
{1, 2}, {3, 4}, {5, 6},
}
modifyArr2(b)
// [[1 2] [3 4] [5 6]]
fmt.Println(b)
}

func modifyArr1(x [3]int) {
x[0] = 100
}

func modifyArr2(y [3][2]int) {
y[2][0] = 100
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

func main() {
a := [...]int{1, 2, 3}
b := a

b[0] = 100
// [1 2 3]
fmt.Println(a)
// [100 2 3]
fmt.Println(b)
}

6.5 数组比较

  • 数组支持 ==!= 操作符,因为内存总是被初始化过的

  • [n]*T 表示元素为指针的数组;*[n]T 表示数组的指针

6.6 练习题

6.6.1 求数组中所有元素的和

[1,3,5,7,8] 中元素的和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

func main() {
a := [...]int{1, 3, 5, 7, 8}

sum := 0

for _, v := range a {
sum += v
}
fmt.Println(sum)
}

6.6.2 找出数组中和为指定值的两个元素的下标

[1,3,5,7,8] 中找出和为8的两个元素的下标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
a := [...]int{1, 3, 5, 7, 8}

for outIndex, v1 := range a {
for i := outIndex + 1; i < len(a); i++ {
v2 := a[i]
if v1+v2 == 8 {
fmt.Printf("索引值为 %d,%d \n", outIndex, i)
}
}
}
}