Go中的数组
文章目录
- Go中的数组
- 一、简介
- 二、创建数组并赋值
- 三、冒泡排序
- 四、数组做函数参数是值拷贝
- 五、传递数组的地址给函数
- 六、数组的切片
- 6.1 指定长度切片
- 6.2 append为切片添加元素
- 6.3 make函数创建切片
- 6.4 传递数组的切片给函数
- 七、Copy函数的使用
- 八、切片做函数参数
一、简介
- 数组是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数组的长度。
- 数组是具有相同 唯一类型 的一组已编号且长度固定的数据项序列(这是一种同构的数据结构);这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。数组长度必须是一个常量表达式,并且必须是一个非负整数。数组长度也是数组类型的一部分,所以[5]int和[10]int是属于不同类型的
数组⻓度必须是常量,且是类型的组成部分。 [2]int 和 [3]int 是不同类型
二、创建数组并赋值
package main
import (
"fmt"
)
func main() {
var lst [5]int
lst2 := [2]int{}
fmt.Printf("lst = %v,lst2 = %v\n", lst, lst2)
//给数组循环赋值
for i := 0; i < len(lst); i++ {
lst[i] = i + 1
}
fmt.Printf("lst = %v\n", lst)
//数组的初始化三种方式
a := [3]int{1, 2}
b := [...]int{1, 2, 3}
c := [5]int{2: 100, 4: 200}
fmt.Println(a, b, c)
}
//lst = [0 0 0 0 0],lst2 = [0 0]
//lst = [1 2 3 4 5]
//[1 2 0] [1 2 3] [0 0 100 0 200]
三、冒泡排序
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
var a [10]int
n := len(a)
for i := 0; i < n; i++ {
a[i] = rand.Intn(100)
}
fmt.Println(a)
fmt.Println("开始冒泡排序")
for i := 0; i < n-1; i++ {
for j := i+1; j < n; j++ {
if a[i] > a[j] {
a[i], a[j] = a[j], a[i]
}
}
}
fmt.Println(a)
}
//[0 15 40 87 31 0 55 91 90 75]
//开始冒泡排序
//[0 0 15 31 40 55 75 87 90 91]
四、数组做函数参数是值拷贝
- 当传递一个数组时,原数组会拷贝到函数的形参数组,有性能损耗
- 数组传递是值传递,不是地址传递,要想修改数组,只能传递数组的地址
代码如下:
package main
import (
"fmt"
"math/rand"
"time"
)
func BubbleSort(a [10]int, n int) {
for i := 0; i < n-1; i++ {
for j := 0; j < n-i-1; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}
fmt.Println("冒泡排序:",a)
}
func main() {
var a [10]int
n := len(a)
rand.Seed(time.Now().Unix())
for i := 0; i < n; i++ {
a[i] = rand.Intn(100)
}
fmt.Println("排序前",a)
BubbleSort(a, n)
fmt.Println("排序后",a)
}
//排序前 [54 49 33 77 99 80 53 14 77 16]
//冒泡排序: [14 16 33 49 53 54 77 77 80 99]
//排序后 [54 49 33 77 99 80 53 14 77 16]
五、传递数组的地址给函数
- 当传递数组的地址时,不会发生数组的拷贝,没有性能损耗
package main
import (
"fmt"
"math/rand"
"time"
)
func BubbleSort_v2(n int, p *[10]int) {
for i := 0; i < n-1; i++ {
for j := 0; j < n-i-1; j++ {
if (*p)[j] > (*p)[j+1] {
(*p)[j], (*p)[j+1] = (*p)[j+1], (*p)[j]
}
}
}
fmt.Println("冒泡排序:",*p)
}
func main() {
var a [10]int
var n = len(a)
rand.Seed(time.Now().Unix())
for i := 0; i < n; i++ {
a[i] = rand.Intn(100)
}
fmt.Println("排序前",a)
BubbleSort_v2(n, &a)
fmt.Println("排序后",a)
}
//排序前 [24 15 23 39 67 43 74 62 80 54]
//冒泡排序: [15 23 24 39 43 54 62 67 74 80]
//排序后 [15 23 24 39 43 54 62 67 74 80]
六、数组的切片
6.1 指定长度切片
package main
import (
"fmt"
)
func main() {
a := [5]int{0, 1, 2, 3, 4}
b := a[1:3:5]
fmt.Println(b)
fmt.Println("切片后的长度是len(a)", len(b)) // 3 -1
fmt.Println("切片后的容量是len(a)", cap(b)) // 5- 1
}
// [1 2]
// 切片后的长度是len(a) 2
// 切片后的容量是len(a) 4
6.2 append为切片添加元素
append函数可以自动扩容,在原切片的末尾添加元素
package main
import "fmt"
func main() {
// a指定容量是一个数组
a := [5]int{0, 1, 2, 3, 4}
fmt.Println("数组:", a)
// s未指定容量是一个切片
s := []int{}
fmt.Printf("append之前: len(s) = %v,cap(s) = %v\n", len(s), cap(s))
s = append(s, 10)
fmt.Printf("append之后: len(s) = %v,cap(s) = %v\n", len(s), cap(s))
}
// 数组: [0 1 2 3 4]
// append之前: len(s) = 0,cap(s) = 0
// append之后: len(s) = 1,cap(s) = 1
6.3 make函数创建切片
package main
import "fmt"
func main() {
// 借助make函数,格式make([]切片类型,长度,容量)
s := make([]int, 5, 10)
s = append(s, 10, 20, 30)
fmt.Println("s = ", s)
fmt.Println("切片后的容量是len(a)", cap(s))
fmt.Println("切片后的长度是len(a)", len(s))
}
// s = [0 0 0 0 0 10 20 30]
// 切片后的容量是len(a) 10
// 切片后的长度是len(a) 8
6.4 传递数组的切片给函数
传递数组的切片给函数,实际上时传递的地址,因为切片直接操作底层数组
package main
import (
"fmt"
"math/rand"
"time"
)
// 冒泡排序后
func BubbleSort_v3(a []int, n int) {
for i := 0; i < n-1; i++ {
for j := 0; j < n-i-1; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}
fmt.Println("冒泡排序:",a)
}
func main() {
rand.Seed(time.Now().Unix())
s := []int{}
for i:=0;i<10;i++{
s = append(s,rand.Intn(100))
}
fmt.Println("排序前",s)
BubbleSort_v3(s,len(s))
fmt.Println("传递切片排序后",s)
}
//排序前 [81 37 85 82 90 3 3 96 37 93]
//冒泡排序: [3 3 37 37 81 82 85 90 93 96]
//传递切片排序后 [3 3 37 37 81 82 85 90 93 96]
七、Copy函数的使用
- copy只能复制两个切片, copy(目标切片,源切片)
- 会把源切片的元素,替换目的切片相同索引的元素
package main
import "fmt"
func main() {
source := []int{1, 2}
target := []int{7, 7, 7, 7, 7}
copy(target, source)
fmt.Println("target = ", target, "source = ", source)
fmt.Println("把source copy到 target结果为:", target)
}
// target = [1 2 7 7 7] source = [1 2]
// 把source copy到 target结果为: [1 2 7 7 7]
八、切片做函数参数
- 当切片作为函数参数时,是传递的变量,不是拷贝到一个新数组
package main
import "fmt"
func BubbleSort(s []int) {
n := len(s)
for i := 0; i < n-1; i++ {
for j := 0; j < n-i-1; j++ {
if s[j] > s[j+1] {
s[j], s[j+1] = s[j+1], s[j]
}
}
}
}
func main() {
s := []int{4, 34, 56, 7, 1}
fmt.Println("排序前:", s)
BubbleSort(s)
fmt.Println("排序前:", s)
}
// 排序前: [4 34 56 7 1]
// 排序前: [1 4 7 34 56]