package main
import "fmt"
/*...Golang 中的数组...*/
/* Go 语言中的数组是指一系列相同类型数据的集合。数组中的元素必须要相同数据类型。数组中包含的每个数据被称为数组元素。
1. 数组的长度是类型的一部分,也就是说[5]int 和 [10]int 是两个不同的类型。
Go 语言中数组的基本语法:
数组支持索引取值和赋值操作。
var a [3]int // 定义一个长度为3元素类型为int的数组a
var b [6]int // 定义一个长度为6元素类型为int的数组b
b[0] = 50
b[1] = 60
b[2] = 70
2. 数组定义
var 数组变量名 [元素数量]T
比如:var a [5]int, 数组的长度必须是常量,并且长度是数组类型的一部分。一旦定义,长度不能变。
[5]int 和 [4]int是不同的类型。
var a [3]int
var b [4]int
a = b // 不可以这样做,因为此时a和b是不同的类型。
数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是lenth-1,访问越界,则触发访问越界,会panic
3. 数组的初始化,分为三种
方法1:初始化数组时,可以使用初始化列表来设置数组元素的值。
方法2:根据初始值的个数自行推断数组的长度
方法3:使用指定索引值的方式来初始化数组
4. 数组的遍历,遍历数组有两种方法,方法1:for循环遍历,方法2:for range 遍历
5. 数组是值类型,相当于Python中的深度拷贝。赋值和传参会复制整个数组。变量a和变量b是两个独立的内存地址,互不影响。
a := 3
b := a
a += 1
fmt.Println("a=",a, "b=",b) // 结果是: a= 4 b= 3
注意:
1. 数组支持 == 和 != 操作符,因为内存总是被初始化过的。
2. [n]*T 表示n个数量的指针数组,*[n]T 表示这是一个数组类型的指针。
6. 多维数组
Go 语言中支持多维数组,我们通常情况下不要超过三维,这里以二维数组为例。
6.1 二维数组的定义:var 数组变量名称 [元素数量][元素数量]Type
例如下面的数组可以解析为:定义一个三行两列的string类型数组a。
a := [3][2]string{
{"北京","上海"},
{"广州","深圳"},
{"成都","重庆"},
}
6.2 二维数组的遍历,通过for range 循环每一个数组元素的值。
将上面的数组a进行循环遍历并打印结果:
for _,v1 := range a {
for _,v2 := range v1 {
fmt.Printf("%s \t", v2)
}
fmt.Println()
}
这个数组aaa循环遍历后的结果如下:
北京 上海
广州 深圳
成都 重庆
6.3 多维数组只有第一层可以使用...来让编译器推导数组的长度。例如:
支持的写法是:a := [...][2]string{{"北京","北京"},{"上海","上海"},{"深圳","深圳"}}
7. 数组练习题
7.1 请求出一个数组的和以及平均值。for-range
var intArr2 [5]int = [...]int{1,-1,9,90,12}
sum := 0
for _,val := range intArr2 {
// 累计求和
sum += val
}
// 如何让平均值保留到小数
fmt.Printf("sum=%v 平均值=%v \n", sum, float64(sum) / float64(len(intArr2)))
*/
func modifyArray(x [3]int) {
x[0] = 1000
fmt.Println(x) // [100 20 30]
a := 3
b := a
a += 1
fmt.Println("a=", a, "b=", b)
}
func modifyArray2(x [3][2]int) {
x[2][0] = 999
fmt.Println(x)
}
func main() {
// 1. 数组的基本语法
var a [3]int // 定义一个长度为3元素类型为int的数组a
var b [6]int // 定义一个长度为6元素类型为int的数组b
b[0] = 50
b[1] = 60
b[2] = 70
fmt.Println(a) // [0 0 0]
fmt.Println(b) // [50 60 70 0 0 0]
// 2. 数组的初始化,分为三种
// 方法1:初始化数组时,可以使用初始化列表来设置数组元素的值。
var testArray [3]int // 数组会初始化为int类型的零值
var numArray = [3]int{1, 2} // 使用指定的初始值完成初始化
var cityArray = [3]string{"北京", "上海", "广州"} // 使用指定的初始值完成初始化
fmt.Println(testArray) // [0 0 0]
fmt.Println(numArray) // [1 2 0]
fmt.Println(cityArray) // [北京 上海 广州]
// 方法2:根据初始值的个数自行推断数组的长度
var testArray2 [3]int
var numArray2 = [...]int{1, 2}
var cityArray2 = [...]string{"北京", "上海", "深圳"}
fmt.Println(testArray2) // [0 0 0]
fmt.Println(numArray2) // [1 2 0]
fmt.Printf("type of numArray:%T \n", numArray2) // type of numArray:[2]int
fmt.Println(cityArray2) // [北京 上海 深圳]
fmt.Printf("type of cityArray:%T \n", cityArray2) // type of cityArray:[3]string
// 方法3:使用指定索引值的方式来初始化数组
a2 := [...]int{1: 1, 3: 5, 6: 10}
fmt.Println(a2) // [0 1 0 5 0 0 10]
fmt.Printf("type of a2 is : %T \n", a2) // type of a2 is : [7]int
// 2.1 数组的遍历
// 遍历数组有两种方法,方法1:for循环遍历,方法2:for range 遍历
var a3 = [...]string{"北京", "上海", "深圳"}
// 方法1:for循环遍历
for i := 0; i < len(a3); i++ {
fmt.Println("循环遍历打印结果:", a3[i])
}
// 方法2: for range 遍历
for k, v := range a3 {
fmt.Println("循环遍历打印结果:", k, v)
}
// 3. 数组是值类型,值类型属于深度拷贝
// 数组是值类型,赋值和传参会复制整个数组。因此改变副本的值,不会改变本身的值。类似于Python中的深拷贝。
aa := [3]int{10, 20, 30}
modifyArray(aa) // 把aa传过去后,赋值给新的变量x,变量x和变量aa属于深度拷贝。这里面x的值是[1000 20 30]
// 深度拷贝,在内存中开启两个内存地址保存变量aa和x的值,任何变量的参数修改,他们已经互不影响。
fmt.Println(aa) // [10 20 30]
bb := [3][2]int{
{1, 1},
{1, 1},
{1, 1},
}
modifyArray2(bb) // 这里面的x的值是 [[1 1] [1 1] [999 1]]
fmt.Println(bb) // [[1 1] [1 1] [1 1]]
// 需求:定义一个三行两列string类型的二位数组,并打印出每一个数组的元素。
aaa := [3][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
for _, v1 := range aaa {
for _, v2 := range v1 {
fmt.Printf("%s \t", v2)
}
fmt.Println()
}
/* 这个数组aaa循环遍历后的结果如下:
北京 上海
广州 深圳
成都 重庆
*/
// 4. 数组练习题
// 4.1 请求出一个数组的和以及平均值。for-range
var intArr2 [5]int = [...]int{1, -1, 9, 90, 12}
sum := 0
for _, val := range intArr2 {
// 累计求和
sum += val
}
// 如何让平均值保留到小数,使用%f来接收,然后 %.2f 就表示小数保留两位
fmt.Printf("sum=%v 平均值=%v \n", sum, float64(sum)/float64(len(intArr2))) // sum=111 平均值=22.2
/* 4.2 请求出一个数组的最大值,并得到对应的下标。
4.2.1 声明一个数组 var intArrs = [...]int{1, -1, 12, 65, 11}
4.2.2 假定第一个元素就是最大值,下标就是0
4.2.3 然后从第二个元素开始循环比较,如果发现有更大,则进行交换
*/
var intArrs = [...]int{1, -1, 12, 65, 11}
maxValue := intArrs[0]
maxIndex := 0
for i := 0; i < len(intArrs); i++ {
if maxValue < intArrs[i] {
maxValue = intArrs[i]
maxIndex = i
}
}
fmt.Println("最大值是:", maxValue, "最大值的索引值是:", maxIndex) // 最大值是: 65 最大值的索引值是: 3
// 4.3 从数组[1,3,5,7,8]中找出和为8的两个元素的下标并打印
arr := [...]int{1, 3, 5, 7, 8}
for i := 0; i < len(arr); i++ {
for j := i + 1; j < len(arr); j++ {
if arr[i]+arr[j] == 8 {
fmt.Printf("(%v,%v) \n", arr[i], arr[j])
}
}
}
/* 上面打印的结果是:
(1,7)
(3,5)
*/
/* 上面代码的全部执行结果如下所示:
PS C:\Users\Zhaoshan.lu\go\DaDi> go run .\09.go
[0 0 0]
[50 60 70 0 0 0]
[0 0 0]
[1 2 0]
[北京 上海 广州]
[0 0 0]
[1 2]
type of numArray:[2]int
[北京 上海 深圳]
type of cityArray:[3]string
[0 1 0 5 0 0 10]
type of a2 is : [7]int
循环遍历打印结果: 北京
[10 20 30]
[[1 1] [1 1] [999 1]]
[[1 1] [1 1] [1 1]]
北京 上海
广州 深圳
成都 重庆
sum=111 平均值=22.2
最大值是: 65 最大值的索引值是: 3
(1,7)
(3,5)
PS C:\Users\Zhaoshan.lu\go\DaDi>
*/
}