golang学习笔记008--数组,切片和二维数组

1.数组

1.1数组介绍

  • 数组可以存放多个同意类型的数据,数组也是一种数据类型,在go中,数组是值类型
  • 定义: var 数组名[数组大小] 数据类型
  • var a [5] int
  • 赋初值 a[0]=1 a[1]=2
  • 数组的地址可以通过数组名来获取&intArr
  • 数组的第一个元素的地址,就是数组的首地址
  • 数组的各个元素的地址间隔是依据数组的类型决定,比如int64->8 int32->4
    在这里插入图片描述
    在这里插入图片描述

1.2数组的使用

● 访问数组元素:数组名[下标] 比如:你要使用a数组的第三个元素 a[2]
在这里插入图片描述
● 四种初始化数组的方法
在这里插入图片描述

1.3数组的遍历

(1) 常规遍历
(2) for-range遍历
for index,values:= range array{

}
说明:
○ 第一个返回值index是数组的下标
○ 第二个返回值value是该下表位置的值
○ 他们都是仅在for循环内部可用的局部变量
○ 遍历时,如果不想使用下表用_代替忽略
○ index,value名称不是固定的,一般为index和value

package main

import (
	"fmt"
)

func main(){
	arr := [3]int{10,20,30}
	for index,value :=range arr{
		fmt.Println(index,value)
	}
}

1.4数组使用注意事项

● 数组是多个相同类型数据的集合,一个数组一旦声明,其长度是固定的,不能动态变换
● var arr[] int 这是arr就是一个slice切片
● 数组创建后,若没有赋值,有默认值(零值)
  ○ 数值类型:0
  ○ 字符串:""bool:false
● 使用数组的步骤:
  ○ 声明数组并开辟空间
  ○ 给数组个元素赋值
  ○ 使用数组
● 数组下标从0开始

● go语言数组属于数值型,在默认情况下是值传递,因此会进行值拷贝,数组间不会相互影响
在这里插入图片描述
● 如果在其他函数中,去修改原来的数组,可以使用引用传递(指针方式)
在这里插入图片描述
● 长度是数组类型的一部分,在传递函数参数时,需要考虑数组长度
在这里插入图片描述

1.5 随机生成5个数,并反转

在这里插入图片描述

2.切片slice

2.1基本介绍

● 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制
● 切片和数组类似,遍历切片,访问切片的元素和求切片长度len(slice)都一样
● 切片的长度是可变的,因此切片是一个可以动态变换的数组
● 切片定义的基本语法: var 切片名 [] 类型 比如:var a[] int

package main

import (
	"fmt"
)

func main(){
	intArr := [5]int{1,22,33,66,99}

	slice :=intArr[1:3]//定义一个切片,slice就是切片名称
					//arr[1,3]表示slice引用intArr这个数组,引用arr数组起始下标为1至下标为3(不包含3)

	fmt.Println("intArr=:" ,intArr)//intArr=: [1 22 33 66 99]
	fmt.Println("slice 的内容" , slice)//slice 的内容 [22 33]
	fmt.Println("slice 长度为" , len(slice))//slice 长度为 2
	fmt.Println("slice 的容量为" ,cap(slice))//	slice 的容量为 4
	
}

● 内存结构:
在这里插入图片描述

● 对上图说明:
  ○ slice是一个引用类型
  ○ slice从底层来说是一个数据结构(struct结构体)
	type slice struct{
		ptr *[2]int
		len int
		cap int
	}

2.2 切片的使用

方式一:引用数组

定义一个切片,然后去引用一个已经创建好的数组,比如上面的方式

方式二:make

通过make来创建切片
基本语法:var 切片名 [] type = make([]type,len,[cap])
参数说明:type:数据类型 len:大小 cap:指定切片容量,可选,如果分配cap,则cap>=len

package main

import (
	"fmt"
)

func main(){
	var slice2 []float64 =make([]float64,5,10)
	slice2[0]=10
	slice2[3]=20
	fmt.Println("slice2 的内容" , slice2)//slice2 的内容 [10 0 0 20 0]
	fmt.Println("slice2 长度为" , len(slice2))//slice2 长度为 5
	fmt.Println("slice2 的容量为" ,cap(slice2))//slice2 的容量为 10
}

内存
在这里插入图片描述
小结:
● 通过make方式创建切片可以指定切片的大小和容量
● 如果没有给切片的个元素赋值,则为默认值
● 通过make方式创建的切片对应的数组是由make底层维护的,对外不可见,只能通过slice去访问各个元素

方式三:

定义一个切片,直接就指定具体数组,使用原理类似make方式

package main

import (
	"fmt"
)

func main(){
	var slice3 []string =[]string{"tom","jack","mary"}
	fmt.Println("slice3 的内容" , slice3)//slice3 的内容 [tom jack mary]
	fmt.Println("slice3 长度为" , len(slice3))//slice3 长度为 3
	fmt.Println("slice3 的容量为" ,cap(slice3))//slice3 的容量为 3
}

方式一和方式二的区别:

● 方式一是直接引用数组,这个数组是事先存在的,程序员可见的
● 方式二是通过make来创建切片,make也会创建一个一个数组,是由切片在底层维护,程序员不可见

2.3 切片的遍历

● for循环
● for-range
在这里插入图片描述

2.4 使用注意事项

  1. 切片初始化时 var slice =arr[startIndex:endIndex]
    ○ 说明:从arr数组下标为startInde取到endIndex的元素(不包含endIndex)
    ○ var slice =arr[0:end]可以简写 var slice=arr[:end]
    ○ var slice =arr[start:len(arr)]可以简写 var slice=arr[start:]
    ○ var slice =arr[0:len(arr)]可以简写 var slice=arr[:]

  2. 切片初始化时,仍然不能越界,但是可以动态增长

  3. cap是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素

  4. 切片定义完后,还不能使用,因为本身一个空的,需要让其引用到一个数组,或者make一个空间供切片来使用

  5. 切片可以继续切片

package main

import (
	"fmt"
)

func main(){

	var slice2 []float64 =make([]float64,5,10)
	slice2[0]=10
	slice2[3]=20

	slice4 := slice2[0:2]
	fmt.Println("slice4 的内容" , slice4)//slice4 的内容 [10 0]
	fmt.Println("slice4 长度为" , len(slice4))//slice4 长度为 2
	fmt.Println("slice4 的容量为" ,cap(slice4))//slice4 的容量为 10
}
  1. 用append内置函数,可以对切片进行动态追加
	ar slice5 []int=[]int{100,200,300}
	//追加具体元素
	slice5 = append(slice5,400,500,600)
	fmt.Println("slice5=",slice5)//slice5= [100 200 300 400 500 600]
	
	//追加切片
	slice5=append(slice5,slice5...)
	fmt.Println("slice5=",slice5)//slice5= [100 200 300 400 500 600 100 200 300 400 500 600]

○ 切片append操作的本质就是对数组扩容
○ go底层会创建一个新的数组newArr
○ 将slice原来包含的元素拷贝到新的数组newArr中
○ slice重新引用到newArr
○ 注意newArr是在底层来维护的,程序员不可见

  1. 切片的拷贝操作
    ○ 切片使用copy内置函数完成拷贝
    ○ copy(slice6,slice5)参数的数据类型都是切片
    ○ slice6,slice5的数据空间都是独立的,相互不影响
	var slice5 []int=[]int{100,200,300}
	slice5 = append(slice5,400,500,600)
	fmt.Println("slice5=",slice5)//slice5= [100 200 300 400 500 600]
	
	var slice6 =make([]int,10)
	copy(slice6,slice5)
	fmt.Println("slice6=",slice6)//slice6= [100 200 300 400 500 600 0 0 0 0]
  1. 这段代码没问题,可以运行,输出[1],空间不够不报错
    在这里插入图片描述
  2. 切片是引用类型,引用传递
    在这里插入图片描述

3.string和slice

● string底层是一个byte数组,因此string也可以进行切片处理

	str := "wang"
	slice:= str[0:2]
	fmt.Println(slice)//wa

● string和切片内存形式
在这里插入图片描述

● string是不可变的,不能通过str[0]="a"来修改字符串
● 如果需要修改,可以先将stirng转为[]byte 或[]rune修改完转换为string

	str := "wang"
	slice:= str[0:2]
	fmt.Println(slice)//wa
	arr1 := []byte(str)
	arr1[0] = 'a'
	str=string(arr1)
	fmt.Println(str)//aang

如果包含汉字,转为[]rune

	str := "wang"
	slice:= str[0:2]
	fmt.Println(slice)//wa
	arr1 := []rune(str)
	arr1[0] = '王'
	str=string(arr1)
	fmt.Println(str)//王ang

4.二维数组

4.1 入门

var arr [2][3]int
	arr[0][2]=1
	arr[1][1]=2

	for i:=0;i<2;i++{
		for j:=0;j<3;j++{
			fmt.Print(arr[i][j]," ")
		}
		fmt.Println()
	}
	//0 0 1
	//0 2 0

4.2 使用方式1:先声明,在赋值

● 语法: var 数组名 [大小][大小] 类型
● 比如 var arr[2][3]int
● 二维数组内存结构
在这里插入图片描述

4.3 使用方式2:直接初始化

● var arr [2][3]int = [2][3]int {{1,2,3},{4,5,6}}
● 写法
  ○ var 数组名 [大小][大小]类型 = [大小][大小] 类型{{值},{值}}
  ○ var 数组名 [大小][大小]类型 = [...][大小] 类型{{值},{值}}
  ○ var 数组名= [大小][大小] 类型{{值},{值}}
  ○ var 数组名 = [...][大小] 类型{{值},{值}}

4.4 二维数组遍历

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值