Golang中的数组
- 数组介绍
- 数组的定义和内存布局
- 数组的定义
- 数组的内存图
- 数组 的使用
- 访问数组元素
- 案例
- 四种初始化的方式
- for-range结构遍历
- 基本语法
- 说明
- 案例
- 数组使用注意事项和细节
- 数组应用案例
- 1.创建一个byte类型的26个元素的数组,分别放置A-Z。使用for循环访问所有元素并打印出来
- 2.请求出一个数组的最大值,并得到对应的下标
- 3.请求出一个数组的和和平均值
- 4.随机生成五个数,并将其反转打印
数组介绍
数组可以存放多个同一类型数据。数组也是一种数据类型,在Go中数组是值类型。
package main
import (
"fmt"
)
func main() {
//定义一个数组
var hens [6]float64;
//给数组的每个元素赋值,元素的每个下标是从0开始的
hens[0] = 37.0
hens[1] = 38.0
hens[2] = 36.0
hens[3] = 35.0
hens[4] = 32.0
hens[5] = 30.0
//遍历数组求出总体重
totalWeight := 0.0
for i := 0 ; i < len(hens) ; i++ {
totalWeight += hens[i]
}
//求出平均体重
avgWeight := fmt.Sprintf("%.2f", totalWeight / float64(len(hens)))
fmt.Printf("totalWeight=%v avgWeight=%v", totalWeight , avgWeight)
}
//totalWeight=208 avgWeight=34.67
总结:
- 使用数组来解决问题,程序的可维护性增加
- 而且代码更加清晰,容易扩展
数组的定义和内存布局
数组的定义
var 数组名 [数组大小] 数据类型
var a [5] int
赋初值 a[0] = 1 a[1] = 30 …
数组的内存图
package main
import (
"fmt"
)
func main() {
var intArr [3]int
//当定义完数组后,其实数组的各个元素有默认值
fmt.Println(intArr)
fmt.Printf("intArr的地址=%p intArr[0]的地址是%p intArr[1]的地址是%p intArr[2]的地址是%p",
&intArr ,&intArr[0] , &intArr[1], &intArr[2])
}
//intArr的地址=0xc000014180 intArr[0]的地址是0xc000014180 intArr[1]的地址是0xc000014188 intArr[2]的地址是0xc000014190
总结:
- 1.数组的地址可以通过数组名来获取&intArr
- 2.数组的第一个元素的地址,就是数组的首地址
- 3.数组的各个元素的地址间隔是依据数组的类型决定的
数组 的使用
访问数组元素
数组名[下标] 比如:要是用a数组的第三个元素 a[2]
案例
从终端循环输入5个成绩,保存到float64数组,并输出
package main
import (
"fmt"
)
func main() {
var score [5]float64
for i := 0 ; i < len(score); i++ {
fmt.Println("请输入第%d个元素的值\n", i+1)
fmt.Scanln(&score[i])
}
//变量数组打印
for i := 0 ; i < len(score); i++ {
fmt.Printf("score[%d]=%v\n", i , score[i])
}
}
/*
请输入第1个元素的值
45
请输入第2个元素的值
78
请输入第3个元素的值
65
请输入第4个元素的值
23
请输入第5个元素的值
64
score[0]=45
score[1]=78
score[2]=65
score[3]=23
score[4]=64
*/
四种初始化的方式
package main
import (
"fmt"
)
func main() {
var numArr01 [3]int = [3]int{1, 2, 3}
fmt.Println("numArr01=", numArr01)
var numArr02 = [3]int{1, 2, 3}
fmt.Println("numArr02=", numArr02)
//这里的[...]是规定的写法
var numArr03 = [...]int{1, 2, 3}
fmt.Println("numArr03=", numArr03)
var numArr04 = [...]int{1 : 800, 0 : 900, 2:900}
fmt.Println("numArr04=", numArr04)
}
/*
numArr01= [1 2 3]
numArr02= [1 2 3]
numArr03= [1 2 3]
numArr04= [900 800 900]
*/
for-range结构遍历
这是Go语言一种独有的结构,可以用来遍历访问数组的元素
基本语法
for index, value := range array01 {
...
}
说明
- 1.第一个返回值index是数组的下标
- 2.第二个value是该下标位置的值
- 3.他们都是仅在for循环内部可见的局部变量
- 4.遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线
- 5.index和value的名称不是固定的,即程序员可以自行指定,一般命名为index和value
案例
package main
import (
"fmt"
)
func main() {
//演示for-range遍历数组
heroes := [...]string{"kunkun", "ikun", "heizi"}
for i, v := range heroes {
fmt.Printf("i=%v v=%v\n", i, v)
}
for _, v := range heroes {
fmt.Printf("元素的值=%v\n", v)
}
}
/*
i=0 v=kunkun
i=1 v=ikun
i=2 v=heizi
元素的值=kunkun
元素的值=ikun
元素的值=heizi
*/
数组使用注意事项和细节
- 1.数组是多个相同类型数据的租户,一个数组一旦声明/定义了,其长度是固定的,不能动态变化
- 2.var arr[] int 这是arr就是一个slice切片
- 3.数组创建后,如果没有复制有默认值
- 数值类型数组:默认值为0
- 字符串数组:默认值为“ ”
- bool数组:默认值为false
- 5.使用数组的步骤1.声明数组并开辟空间内,2.给数组各个元素赋值(默认0值),3.使用数组
- 6.数组的下标是从开始的
- 7.数组下标必须在指定范围内使用,否则报panic:数组越界,比如:var arr[5]int 则有效下标为0-4
- 8.Go的数组属值类型,在默认情况下是值传递,因此会进行值拷贝。数组间不会相互影响
- 9.如果在其他函数中,去修改原来的数组,可以使用引用传递(指针方式)
- 10.长度是数组类型的一部分,在传递参数时,需要考虑数组的长度
数组应用案例
1.创建一个byte类型的26个元素的数组,分别放置A-Z。使用for循环访问所有元素并打印出来
package main
import (
"fmt"
)
func main() {
//声明一个数组 var myChars [26]byte
//使用for循环,利用字符可以进行运算的特点来赋值
//使用for循环打印即可
var myChars [26]byte
for i := 0 ; i < 26; i++ {
myChars[i] = 'A' + byte(i) //注意需要将i转化为byte
}
for i := 0; i < 26; i++ {
fmt.Printf("%c ", myChars[i])
}
}
//A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
2.请求出一个数组的最大值,并得到对应的下标
package main
import (
"fmt"
)
func main() {
//声明一个数组 var intArr[5] = [...]int {1, -1, 9, 99, 11}
//假定第一个元素就是最大值,下标就是0
//然后从第二个元素开始循环比较,如果发现有更大的,则交换
var intArr [5]int = [...]int {1, -1, 9, 99, 11}
maxVal := intArr[0]
maxValIndex := 0
for i := 1; i < len(intArr); i++ {
//然后从第二个元素开始循环比较,如果发现有更大的,则交换
if maxVal < intArr[i] {
maxVal = intArr[i]
maxValIndex = i
}
}
fmt.Printf("maxVal=%v maxValIndex=%v", maxVal, maxValIndex)
}
//maxVal=99 maxValIndex=3
3.请求出一个数组的和和平均值
package main
import (
"fmt"
)
func main() {
//声明一个数组 var intArr[5] = [...]int {1, -1, 9, 99, 11}
//求出和sum
//求出平均值
var intArr2 [5]int = [...]int {1, -1, 9, 99, 11}
sum := 0
for _, val := range intArr2{
//累积求和
sum += val
}
//如何让平均值保留到小数
fmt.Printf("sum=%v 平均值=%v", sum, float64(sum) / float64(len(intArr2)))
}
//sum=119 平均值=23
4.随机生成五个数,并将其反转打印
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
//随机生成五个数,,rand.Intn()函数
//当我们得到随机数后,就放到一个数组int数组中
//反转打印
var intArr [5]int
//为了每次生成的随机数不一样,我们需要给一个seed值
len := len(intArr)
rand.Seed(time.Now().UnixNano())
for i := 0; i < len; i++ {
intArr[i] = rand.Intn(100) //0<=n<100
}
fmt.Println("交换前=", intArr)
//反转打印,交换的次数是len/2
//倒数第一个和第一个元素交换,倒数第二个和第二个交换
temp := 0 //做一个临时变量
for i := 0; i < len / 2; i++ {
temp = intArr[len - 1 - i]
intArr[len - 1 - i] = intArr[i]
intArr[i] = temp
}
fmt.Println("交换后=", intArr)
}
//交换前= [41 20 28 53 9]
交换后= [9 53 28 20 41]