1.1.1. 一、数组的说明:
数组是存放多个同一类型数据的数据结构。数组也是一种数据类型,在 Go 中,数组是值类型。
1、数组的定义。
var 数组名 [数组大小]数据类型
示例如下:var weights [4]float64 //声明一个可以存放4个元素的数组。
//声明一个可以存放4个元素的float64类型数组。
var weights [4]float64
weights[0] = 2.0
weights[1] = 8.0
weights[2] = 3.4
weights[3] = 50.0
totalweights := 0.0
for i := 0; i< len(weights); i++ {
totalweights += weights[i]
}
//总重量=63.4,平均重量=15.85
//float64(len(weights)): weights的长度强制转换为float64类型
fmt.Printf("总重量=%v,平均重量=%.2f",totalweights,totalweights/float64(len(weights)))
2、数组的内存说明。
var intArr [3]int //定义之后。每个元素直接赋零值
fmt.Println(intArr) //[0 0 0]
//intArr的地址=0xc0000122e0,intArr[0]的地址=0xc0000122e0,intArr[1]的地址=0xc0000122e8
fmt.Printf("intArr的地址=%p,intArr[0]的地址=%p,intArr[1]的地址=%p",
&intArr,&intArr[0],&intArr[1])
- 数组声明之后。每个元素会被赋予对应类型的零值。
var intArr [3]int //定义之后。每个元素直接赋零值
- 数组的地址
&intArr
等于 第一个元素的地址intArr[0] 。
之后每个元素的地址等于前一个元素的地址加上元素类型占的字节数。比如:int类型占8个字节。第一个元素的地址intArr[0] 等于0xc0000600c0,则第二个元素intArr[1]的地址=0xc000012
1.1.2. 二、4种初始化数组的方式:
方式1和2:var intArr1 [3]int = [3]int{10,2,76}
或者 var intArr1 = [3]int{10,2,76}
var intArr1 [3]int = [3]int{10,2,76}
fmt.Println(intArr1) // [10 2 76]
var intArr2 [3]int = [3]int{10,2} //初始化前两个,最后一个为默认值
fmt.Println(intArr2) // [10 2 0]
var intArr3 = [3]int{10,2} //类型推导
fmt.Println(intArr3) // [10 2 0]
方式3和4:变长数组。var intArr1 = [...]int{10,2}
或者 var intArr2 = [...]int{0: 10,3: 5}
(这种方式是用下标设置初始值,下标最大为3,表示有4个元素。其他元素设置为默认值。)
例子1:
var intArr1 = [...]int{10,2}
fmt.Println(intArr1) // [10 2]
//以下标设置初始值。格式:“ 下标:值 ”。下标最大为3,表示有4个元素
var intArr2 = [...]int{0: 10,3: 5}
fmt.Println(intArr2) // [10 0 0 5]
例子2:
intArr1 := [...]string{1:"tom",0:"jack"}
fmt.Println(intArr1) // [jack tom]
1.1.3. 三、for--range 遍历数组。
数组有2种遍历方式,一种是普通方式。另一种是for--range 方式。
for--range的基本语法。index 是数组下标, value 是数组值。index 、value只是变量名。可以取其他的名字。
for index, value := range intArr1 {
// fmt.Printf("下标是%v,值是%v \n",index,value)
}
也可以不接收下标如下,同理也可以用下划线不接收值。
for _, value := range intArr1 {
//fmt.Printf("值是%v \n",value)
}
例子如下:
var intArr1 = [...]string{1:"tom",0:"jack"}
for index, value := range intArr1 {
fmt.Printf("下标是%v,值是%v \n",index,value)
}
for _, value := range intArr1 {
fmt.Printf("值是%v \n",value)
}
输出如下:
下标是0,值是jack
下标是1,值是tom
值是jack
值是tom
1.1.4. 四、数组的注意事项。
1、一个数组一旦声明/定义了,其长度是固定的, 不能动态变化。如下:
var intArr [2]int
intArr[0] = 5
intArr[2] = 0 // 编译报错。数组只能存储2个元素。下标超出了存储范围
2、如果这样写:var arr []int
这时 变量arr 就是一个 slice 切片,不是数组。
3、数组创建后,如果没有赋值,有默认值(零值)。
数值类型数组:默认值为 0; 字符串数组: 默认值为 ""; bool 数组: 默认值为 false
4、Go 的数组是值类型, 调用函数时,在默认情况下是值传递, 因此会进行值拷贝。在函数内部修改数组的值,不会影响外部数组的值。
例子如下:函数内部改变值arr[0] = 50
func test(arr [3]int) {
arr[0] = 50
}
func main() {
intArr := [3]int{11,2,3}
test(intArr)
//test()函数内部改变不了外部数组的值
fmt.Println(intArr) // [11 2 3]
}
5、函数接收指针。能改变函数外部数组元素的值。
func test(arrPoint *[3]int) {
//*arrPoint 表示获得指针 arrPoint 的值。这个值是数组[3]int类型
//(*arrPoint)[0] 获得数组的第一个元素
(*arrPoint)[0] = 50
}
func main() {
intArr := [3]int{11,2,3}
// 传递intArr的地址
test(&intArr)
//使用指针,函数内部能改变数组值。
fmt.Println(intArr) // [50 2 3]
}
注意改变值的语句:(*arrPoint)[0] = 50
6、长度是数组类型的一部分,在传递函数参数时数组的长度一致。
例子:下面的函数接受[3]int类型。所以传递参数的时候也需要[3]int类型。如果是[5]int类型就会报错。也就是数组和它的长度组成一个新的类型。
func test(arr [3]int) {
arr[0] = 50
}