Golang学习(五):数组与切片

1. 数组

1.1 数组定义和内存布局

  1. 定义
var 数组名 [数组大小]数据类型
var a [5]int
  1. 内存布局
    ① &intArr可以获取地址
    ② 第一个元素地址就是数组的首地址
    ③ 地址间隔由数组类型决定(前一个元素地址,每个元素占用的字节数)
    在这里插入图片描述

1.2 数组的访问和初始化

  1. 访问
    java一样,下标志访问
  2. 四种初始化方式
	//1.
	var numArr01 [3]int = [3]int{1, 2, 3}
	//2.
	var numArr02 = [3]int{5, 6, 7}
	//3.这里的 [...] 是规定的写法
	var numArr03 = [...]int{8, 9, 10}
	//4.注明下标
	var numArr04 = [...]int{1: 800, 0: 900, 2:999}
	//类型推导
	strArr05 := [...]string{1: "tom", 0: "jack", 2:"mary"}
package main
import (
	"fmt"
)

func main() {

	var intArr [3]int //int占8个字节
	//当我们定义完数组后,其实数组的各个元素有默认值 0
	fmt.Println(intArr)
	intArr[0] = 10
	intArr[1] = 20
	intArr[2] = 30
	fmt.Println(intArr)
	fmt.Printf("intArr的地址=%p intArr[0] 地址%p intArr[1] 地址%p intArr[2] 地址%p\n", 
		&intArr, &intArr[0], &intArr[1], &intArr[2])


	//从终端循环输入5个成绩,保存到float64数组,并输出.
	// var score [5]float64

	// for i := 0; i < len(score); i++ {
	// 	fmt.Printf("请输入第%d个元素的值\n", i+1)
	// 	fmt.Scanln(&score[i])
	// }
	
	// //变量数组打印
	// for i := 0; i < len(score); i++ {
	// 	fmt.Printf("score[%d]=%v\n", i, score[i])
	// }

	//四种初始化数组的方式
	var numArr01 [3]int = [3]int{1, 2, 3}
	fmt.Println("numArr01=", numArr01)

	var numArr02 = [3]int{5, 6, 7}
	fmt.Println("numArr02=", numArr02)
	//这里的 [...] 是规定的写法
	var numArr03 = [...]int{8, 9, 10}
	fmt.Println("numArr03=", numArr03)

	var numArr04 = [...]int{1: 800, 0: 900, 2:999}
	fmt.Println("numArr04=", numArr04)

	//类型推导
	strArr05 := [...]string{1: "tom", 0: "jack", 2:"mary"}
	fmt.Println("strArr05=", strArr05)
}

1.3 数组遍历

第一种:常规for int 遍历
第二种:for-range
在这里插入图片描述

package main
import (
	"fmt"
)

func main() {

	//演示for-range遍历数组
	 heroes  := [...]string{"宋江", "吴用", "卢俊义"}
	//使用常规的方式遍历,我不写了..

	for i, v := range heroes {
		fmt.Printf("i=%v v=%v\n", i , v)
		fmt.Printf("heroes[%d]=%v\n", i, heroes[i])
	}

	for _, v := range heroes {
		fmt.Printf("元素的值=%v\n", v)
	}
}

1.4 数组注意事项

  1. Go数组默认值传递,进行拷贝数组间不影响,如果相在其他函数中更改原来数组使用引用传递
    在这里插入图片描述
    在这里插入图片描述
  2. 传递数组时要考虑长度
    在这里插入图片描述

2. 切片

2.1 切片的内存布局

在这里插入图片描述

package main
import (
	"fmt"
)

func main() {

	//演示切片的基本使用
	var intArr [5]int = [...]int{1, 22, 33, 66, 99}
	//声明/定义一个切片
	//slice := intArr[1:3]
	//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)) // 切片的容量是可以动态变化  

	fmt.Printf("intArr[1]的地址=%p\n", &intArr[1])
	fmt.Printf("slice[0]的地址=%p slice[0==%v\n", &slice[0], slice[0])
	slice[1] = 34
	fmt.Println()
	fmt.Println()
	fmt.Println("intArr=", intArr)
	fmt.Println("slice 的元素是 =", slice) //  22, 33

}

2.2 切片的使用

  1. 定义一个切片,引用一个已经创建好的数组,比如前面这个案例
  2. make创建切片
    基本语法:var 切片名 []type = make([]type, len, [cap])
  3. 定义一个切片直接指定具体数组
package main
import (
	"fmt"
)

func main() {

	//演示切片的使用 make
	var slice []float64 = make([]float64, 5, 10)
	slice[1] = 10
	slice[3] = 20
	//对于切片,必须make使用.
	fmt.Println(slice)
	fmt.Println("slice的size=", len(slice))
	fmt.Println("slice的cap=", cap(slice))


	//方式3
	fmt.Println()
	//第3种方式:定义一个切片,直接就指定具体数组,使用原理类似make的方式
	var strSlice []string = []string{"tom", "jack", "mary"}
	fmt.Println("strSlice=", strSlice)
	fmt.Println("strSlice size=", len(strSlice)) //3
	fmt.Println("strSlice cap=", cap(strSlice)) // ?

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 切片的遍历

  1. 常规gor
  2. for-range

2.4 使用注意

  1. 切片可以继续切片
  2. append可以对切片进行动态追加
    在这里插入图片描述
  3. copy函数可以实现拷贝
  4. 在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package main
import (
	"fmt"
)

func main() {

	//使用常规的for循环遍历切片
	var arr [5]int = [...]int{10, 20, 30, 40, 50}
	//slice := arr[1:4] // 20, 30, 40
	slice := arr[1:4]
	for i := 0; i < len(slice); i++ {
		fmt.Printf("slice[%v]=%v ", i, slice[i])
	}

	fmt.Println()
	//使用for--range 方式遍历切片
	for i, v := range slice {
		fmt.Printf("i=%v v=%v \n", i, v)
	}

	slice2 := slice[1:2] //  slice [ 20, 30, 40]    [30]
	slice2[0] = 100  // 因为arr , slice 和slice2 指向的数据空间是同一个,因此slice2[0]=100,其它的都变化

	fmt.Println("slice2=", slice2)
	fmt.Println("slice=", slice)
	fmt.Println("arr=", arr)

	fmt.Println()

	//用append内置函数,可以对切片进行动态追加
	var slice3 []int = []int{100, 200, 300}
	//通过append直接给slice3追加具体的元素
	slice3 = append(slice3, 400, 500, 600)
	fmt.Println("slice3", slice3) //100, 200, 300,400, 500, 600

	//通过append将切片slice3追加给slice3
	slice3 = append(slice3, slice3...) // 100, 200, 300,400, 500, 600 100, 200, 300,400, 500, 600
	fmt.Println("slice3", slice3)


	//切片的拷贝操作
	//切片使用copy内置函数完成拷贝,举例说明
	fmt.Println()
	var slice4 []int = []int{1, 2, 3, 4, 5}
	var slice5 = make([]int, 10)
	copy(slice5, slice4)
	fmt.Println("slice4=", slice4)// 1, 2, 3, 4, 5
	fmt.Println("slice5=", slice5) // 1, 2, 3, 4, 5, 0 , 0 ,0,0,0
}

2.5 String 和 slice

  1. String 底层 Byte 数组,可以切片
    在这里插入图片描述

  2. String 和切片在内存的形式
    在这里插入图片描述

  3. String 不可变,不能通过 str[0]=‘z’ 方式修改字符串
    在这里插入图片描述

  4. 要修改字符串,先把string——[]byte,或者[]rune——修改——重写成string
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平什么阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值