c语言数组切片,Go 其二 数组与切片

艺多不压身,学习一下最近蛮火的Go语言,整理一下笔记。相关Code和笔记也放到了Git上,传送门。

数组的声明

var a [3] int //声明并初始化为默认零值

a[0] = 1

b := [3]int{1,2,3} //声明同时初始化

c := [2][2]int{{1,2},{3,4}} //多维数组初始化

Go语言中定义的变量一定要使用,否则会报错,但如果只是想使用foreach的写法,可以使用 _ 来占位.

//foreach的写法, idx即为数组的索引的值

for idx, e:= range arr2 {

t.Log(idx, e)

}

//Go语言中定义的变量一定要使用,所以下面的写法会报错 idx declared but not used

// for idx, e:= range arr2 {

// t.Log(e)

// }

//如果只是想使用foreach的写法,可以使用 _ 来占位

for _, e:= range arr2 {

t.Log(e)

}

数组截取

a[开始索引(包含), 结束索引(不包含)]

a := [...] int {1,2,3,4,5}

a[1:2] // 2

a[1:3] // 2,3

a[1:len(1)] // 2, 3, 4, 5

a[1:] //2, 3, 4, 5 //从索引1开始一直到末尾

a[:3] //1,2,3 //从索引0开始,一直到索引为3的位置,不包含索引为3的值

---------------------------------------------------------------

切片

切片在别的语言中不一定有,比如c#

使用起来像是可变长数组

切片内部结构

实际上是一个结构体,包含三个元素

1.指针,指向一片连续的存储空间(一个数组)ptr

2.切片内的元素个数 len

3.指针指向的这个数组的长度,容量 cap

//与声明数组很类似,区别是没有指定长度!例如

var s0 []int

利用len()方法来获得切片内元素个数

利用cap()方法来获得切片空间大小

利用append(s0, 1)来填充切片

使用make方法来声明长度和容量不同的切片 例如

//这里s2长度为3,但容量为5

s2 := make([]int, 3, 5)

其中len个元素会被初始化为默认值0,未初始化元素不可访问

切片本质上是共享的存储结构,注意这里的共享指的是由同一个切片“派生”出的其他切片或数组,例如

year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}

q2 := year[3:6]

summer := year[5:8]

year,q2,summer是共享存储空间的

而反之,如

a := []int{1,2,3,4}

b := []int{1,2,3,4}

虽然初始的值相同,但其实是不共享存储空间的

---------------------------------------------------------------

数组 VS 切片

1. 容量是否可以伸缩,数组不可以,切片可以

2. 是否可以进行比较,数组可以与数组比较,切片与切片之间不可以比较

附录:

数组相关Code:

package array_test

import "testing"

func TestArrayInit(t *testing.T){

var arr [3]int

t.Log(arr[1],arr[2])

arr1 := [4]int{1,2,3,4}

//不指定长度且初始化时可以用[...]

arr2 := [...]int{1,2,3,4,5}

arr1[1] = 9

t.Log(arr1[1], arr1[3])

t.Log(arr2[2])

}

func TestArrayTraval(t *testing.T){

arr2 := [...]int{1,2,3,4,5}

for i:= 0; i < len(arr2); i++{

t.Log(arr2[i])

}

//foreach的写法, idx即为数组的索引的值

for idx, e:= range arr2 {

t.Log(idx, e)

}

//Go语言中定义的变量一定要使用,所以下面的写法会报错 idx declared but not used

// for idx, e:= range arr2 {

// t.Log(e)

// }

//如果只是想使用foreach的写法,可以使用 _ 来占位

for _, e:= range arr2 {

t.Log(e)

}

}

func TestArraySection(t *testing.T){

arr3 := [...] int{1,2,3,4,5}

arr3_sec := arr3[:3]

t.Log(arr3_sec)

arr3_sec2 := arr3[3:]

t.Log(arr3_sec2)

}

切片相关code:

package slice_test

import "testing"

func TestSliceInit(t *testing.T){

//与声明数组很类似,区别是没有指定长度!

var s0 []int

t.Log(len(s0), cap(s0))

s0 = append(s0, 1)

t.Log(len(s0), cap(s0))

//初始化

s1 := []int{1,2,3,4}

t.Log(len(s1), cap(s1))

//这里s2长度为3,但容量为5

s2 := make([]int, 3, 5)

t.Log(len(s2), cap(s2))

//这里会报错,因为后两个元素会越界

//t.Log(s2[0],s2[1],s2[2],s2[3],s2[4])

t.Log(s2[0],s2[1],s2[2])

s2 = append(s2, 1)

t.Log(s2[0],s2[1],s2[2],s2[3])

}

func TestSliceGrowing(t *testing.T){

s:=[]int{}

for i:=0; i<10; i++{

s = append(s, i)

t.Log(len(s), cap(s))

}

//输出结果

/*

TestSliceGrowing: slice_test.go:30: 1 1

TestSliceGrowing: slice_test.go:30: 2 2

TestSliceGrowing: slice_test.go:30: 3 4

TestSliceGrowing: slice_test.go:30: 4 4

TestSliceGrowing: slice_test.go:30: 5 8

TestSliceGrowing: slice_test.go:30: 6 8

TestSliceGrowing: slice_test.go:30: 7 8

TestSliceGrowing: slice_test.go:30: 8 8

TestSliceGrowing: slice_test.go:30: 9 16

TestSliceGrowing: slice_test.go:30: 10 16

*/

//每次不够放的适合,都会将上次的扩展为之前的两倍,因此要使用类似于s2 = append(s2, 1) 因为是新的空间给s2,并将原来的数据拷贝过去。

}

func TestSliceShareMemory(t *testing.T) {

year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}

q2 := year[3:6]

t.Log(q2, len(q2), cap(q2))

//输出结果为

//TestSliceShareMemory: slice_test.go:53: [Apr May Jun] 3 9,容量是直接到末尾的,所以是9.

summer := year[5:8]

t.Log(summer, len(summer), cap(summer))

summer[0] = "Unkonw"

t.Log(summer, len(summer), cap(summer))

t.Log(q2, len(q2), cap(q2))

//输出结果为

/*

TestSliceShareMemory: slice_test.go:60: [Unkonw Jul Aug] 3 7

TestSliceShareMemory: slice_test.go:61: [Apr May Unkonw] 3 9

*/

//由于是共享的存储空间,因此summer的改动同时影响到了q2的值.

}

func TestSliceComparing(t *testing.T){

a := []int{1,2,3,4}

b := []int{1,2,3,4}

//会报错,nvalid operation: a == b (slice can only be compared to nil)

// if(a == b){

// t.Log("Can Compare")

// }

t.Log(a[2])

t.Log(b[2])

b[2] = 9

t.Log(a[2])

t.Log(b[2])

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值