go语言使用-引用数据类型——数组
一、基本介绍
数组可以存放多个同一类型数据。数组也是一种数据类型,在Go中,
数组是值类型。
二、基本语法
数组的定义
var 数组名 [数组大小]数据类型
var a [5]int
赋初值 a[0] = 1 a[1] = 30 ....
三、快速入门案例
/*
一个养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,
3.4kg,2kg,50kg 。请问这六只鸡的总体重是多少?平
均体重是多少? 请你编一个程序
*/
func ArrayDemo() {
var hens [6] float64
hens[0]=3
hens[1]=5
hens[2]=1
hens[3]=3.4
hens[4]=2
hens[5]=50
var sum float64
for _, value := range hens {
sum +=value
}
aver := sum / float64(len(hens))
fmt.Printf("这六只鸡的总体重是%f 平均体重是%f \n",sum,aver)
}
四、数组内存分析
//分析go 的数组在内存中存在的形式
func main() {
var scores [3]int
scores[0] = 10
scores[1] = 20
scores[2] = 30
}
五、数组的使用
1、访问数组元素
数组名[下标] 比如:你要使用a数组的第三个元素 a[2]
2、四种初始化数组的方式
//数组的四种初始化方式
func ArrayDemo2() {
//定义形式
var array [3] int = [3] int {1,2,3}
var array1 = [3] int {1,2,3}
var array2 = [...] int {1,2,3}
//指定元素对应下标
var array3 = [3] int {1:1,2:2,0:3}
fmt.Println("array=",array)
fmt.Println("array1=",array1)
fmt.Println("array2=",array2)
fmt.Println("array3=",array3)
}
3、数组遍历
1)方式1-常规遍历:
var array [3] int = [3] int {1,2,3}
for i:= 0; i< len(array); i++{
array[i]
}
2)方式2-for-range结构遍历
这是Go语言一种独有的结构,可以用来遍历访问数组的元素。
- 基本语法
for index, value := range array01 {
...
}
- 说明
1) 第一个返回值 index 是数组的下标
2) 第二个value是在该下标位置的值
3) 他们都是仅在 for 循环内部可见的局部变量
4) 遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线_
5) index 和 value 的名称不是固定的,即程序员可以自行指定,一般命名为 index 和 value
示例:
func ArrayDemo4() {
var chars [26] byte
chars[0] = 'A'
for i := 1; i < 26; i++ {
chars[i]=chars[i-1]+1
}
for index ,value := range chars {
fmt.Printf("chars[%d]=%c \n",index,value)
}
六、数组使用细节和注意事项
1、 数组是多个相同类型数据的组合,一个数组一旦声明/定义了,其长度是固定的, 不能动态变化。
2、var arr []int 这时 arr 就是一个slice切片,切片后面专门讲解。
3、 数组中的元素可以是任何数据类型,包括值类型和引用类型,但是不能混用。
4)、数组创建后,如果没有赋值,有默认值(零值)
数值类型数组:默认值为 0
字符串数组: 默认值为 ""
bool数组: 默认值为 false
5、 使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值(默认零值) 3 使用数组
6)、数组的下标是从0开始的。
7、 数组下标必须在指定范围内使用,否则报 panic:数组越界,比如
var arr [5]int 则有效下标为 0-4
8)、Go的数组属值类型, 在默认情况下是值传递, 因此会进行值拷贝。数组间不会相互影响
9)、如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)
示例
package main
import (
"fmt"
)
func test(arr [3]int) {
arr[0] = 100
fmt.Println("test arr", arr)
}
func test2(arr *[3]int) {
(*arr)[0] = 100
fmt.Println("test arr", *arr)
}
//分析go 的数组在内存中存在的形式
func main() {
var scores [3]int //
// scores[0] = 10
// scores[1] = 20
// scores[2] = 30
// fmt.Printf("scores[0]地址=%p scores[1]地址=%p scores[2]地址=%p 数组名地址=%p\n",
// &scores[0], &scores[1], &scores[2], &scores)
test2(&scores)
fmt.Println("scores", scores)
}
10、长度是数组类型的一部分,在传递函数参数时 需要考虑数组的长度。
//默认值拷贝
func modify(arr [3]int ){
arr[0] = 100
fmt.Println("modify 的 arr ", arr)
}
func main() {
var arr = [...]int{1, 2, 3}
modify(arr)
}
七、数组复杂使用-数组反转
要求:随机生成6个数,并将其反转打印。
func ArrayDemo5() {
var arr [7] int
rand.Seed(time.Now().UnixNano())
for i := 0; i < len(arr) - 1; i++ {
radom := rand.Intn(100)
arr[i] = radom
}
fmt.Println("随机数组arr=",arr)
count := len(arr)
var arr2 [7] int
for i := count - 1; i >= 0; i-- {
fmt.Printf("反转打印数组arr[%d]=%d \n",i,arr[i])
arr2[count -i-1]=arr[i]
}
fmt.Println("新数组arr2=",arr2)
fmt.Println("原数组arr=",arr)
for i := 0; i < count / 2; i++ {
temp := arr[i]
arr[i] = arr[ count - 1 - i ]
arr[ count - 1 - i ] =temp
fmt.Println("arr=",arr)
}
}
八、二维数组
1、基本介绍
多维数组我们只介绍二维数组
2、使用方式
使用方式1: 先声明/定义,再赋值
1) 语法: var 数组名 [大小][大小]类型
2) 比如: var arr [2][3]int
, 再赋值。
3) 使用演示
var arr [4][6]int
arr[1][2] = 1
arr[2][1] = 2
arr[2][3] = 3
4) 二维数组在内存的存在形式(重点)
使用方式2: 直接初始化
1) 声明:var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
2) 赋值(有默认值,比如int 类型的就是0)
3) 使用演示
a = [3][4]int{
{0, 1, 2, 3} , /* 第一行索引为 0 */
{4, 5, 6, 7} , /* 第二行索引为 1 */
{8, 9, 10, 11} /* 第三行索引为 2 */
}
4) 说明:二维数组在声明/定义时也对应有四种写法[和一维数组类似]
var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 [大小][大小]类型 = […][大小]类型{{初值..},{初值..}}
var 数组名 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 = […][大小]类型{{初值..},{初值..}}
3、快速入门案例:
请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
package main
import (
"fmt"
)
func main() {
// 快速入门案例:
// 请用二维数组输出如下图形
// 0 0 0 0 0 0 => arr[0] =>arr[0][0] arr[0][1] ...
// 0 0 1 0 0 0 => arr[1] =>arr[1][2]=1...
// 0 2 0 3 0 0 => arr[2]
// 0 0 0 0 0 0 => arr[3]
var arr [4][6]int
fmt.Println("arr-len=", len(arr)) //4
arr[1][2] = 1
arr[2][1] = 2
arr[2][3] = 3
//遍历
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
fmt.Print(arr[i][j],"\t")
}
fmt.Println()
}
//使用for-range遍历 二维数组
for i, v := range arr { // v 是一个一维数组
for j, v2 := range v {
fmt.Printf("arr[%d][%d]=%d\t", i, j ,v2)
}
fmt.Println()
}
}
4、二维数组的遍历
1) 双层for循环完成遍历
2) for-range方式完成遍历
案例:定义二维数组,用于保存三个班,每个班五名同学成绩,
并求出每个班级平均分、以及所有班级平均分
package main
import (
"fmt"
)
// 定义二维数组,用于保存三个班,每个班五名同学成绩,
// 并求出每个班级平均分、以及所有班级平均分
func main() {
var scores [3][5]float64
for i := 0; i < len(scores); i++ {
for j := 0; j < len(scores[i]); j++ {
fmt.Printf("请输入第%d班的第%d学生的成绩\n", i + 1, j + 1)
fmt.Scanln(&scores[i][j])
}
}
//遍历二维数组求出总分
totalSum := 0.0
classNum := len(scores)
for i := 0; i < classNum; i++ {
//对每个班遍历
sum := 0.0
for j := 0; j < len(scores[0]); j++ {
sum += scores[i][j]
}
totalSum += sum // 将所有班级的分数累计
fmt.Printf("第%d班的平均分=%f\n", i+1, sum/float64(len(scores[i])))
}
fmt.Printf("所有学生的平均分=%f\n", totalSum/float64(len(scores[0]) * classNum))
}