数组和切片3
数组复杂使用--数组反转
要求:随机生成五个数,并将其反转打印
通过找规律反转
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
//思路
//1.随机生成五个数, rand.Intn() 函数
//2.当我们得到随机数后,就放到一个数组 int数组
//3.反转打印,交换的次数是 len / 2,倒数第一个和第一个元素交换,
//倒数第2个和第2个元素交换
var intArr [5]int
len := len(intArr)
//为了每次生成的随机数不一样,我们需要给一个seed值
rand.Seed(time.Now().UnixNano())
for i := 0; i < len; i++ {
intArr[i] = rand.Intn(100) // 0 <= n < 100
}
fmt.Println("交换前~=", intArr)
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)
}
为什么需要切片?
先看一个需求:我们需要一个数组用于保存学生的成绩,但是学生的个数是不确定的,请问怎么办?解决方案:使用切片
切片的基本介绍:
1)切片的英文是slice
2)切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制。
3)切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度len(slice) 都一样。
4)切片的长度是可以变化的,因此切片是一个可以动态变化数组。
5)切片定义的基本语法:
var 切片名 []类型
比如: var a []int
切片的快速入门:
func main() {
var intArr [5]int = [...]int {1, 22, 33, 66, 99}
//声明/定义一个切片
//1.slice 就是切片名
//2.intArr[1:3] 表示 slice 引用到intArr这个数组
//3.引用intArr数组的起始下标为1,最后的下标为3(但是不包含3)
slice := intArr[1:3]
fmt.Println("intArr=", intArr)
fmt.Println("slice 的元素是 =", slice) // 22,33
fmt.Println("slice 的元素个数 = ", len(slice)) // 2
fmt.Println("slice 的容量 = ", cap(slice)) //切片的容量是可以动态变化的。
}
切片在内存中的形式:
1)以前面的案例来分析切片在内存中的布局
2)切片底层的数据结构可以理解成是一个结构体struct
3)输出切片和切片引用的地址
切片使用的三种方式:
方式1:
第一种方式:定义一个切片,然后让切片去引用一个已经创建好的数组,比如前面的案例就是这样的。
方式2:
第二种方式:通过make来创建切片
基本语法:var 切片名 []type = make([]type, len, [cap])
参数说明:type:就是数据类型 len:大小 cap:指定切片容量,可选。如果分配了cap,要求 cap >= len
案例演示:
对上面代码的小结:
1)通过make 方式创建切片可以指定切片的大小和容量
2)如果没有给切片的各个元素赋值,那么就会使用默认值[int , float=>0, string=>"", bool=>false]
3)通过make 方式创建的切片对应的数组是由make 底层维护,对外不可见。即只能通过 slice 去访问各个元素
方式3:
第三种方式:定义一个切片,直接就指定数组,使用原理类似make 的方式。
案例演示:
func main() {
var slice []int = []int {1,3,5}
fmt.Println(slice)
}
func main() {
var strSlice []string = []string {"tom", "jack", "marry"}
fmt.Println("strSlice=", strSlice)
fmt.Println("strSlice size=", len(strSlice)) //3
fmt.Println("strSlice cap=", cap(strSlice)) //3
}
切片的使用区别分析:
方式1和方式2的区别:
方式1是直接引用数组,这个数组是事先存在的,程序员是可见的。
方式2是通过make 来创建切片,make也会创建一个数组,是由切片在底层进行维护,程序员是看不见的。
make创建切片的示意图: