我尝试使用go
来写一个动态数组,但是很可惜,我实力尚弱,尝试数次,最终以失败了,所以,决定使用c
来实现一个简单的int
类型的动态数组,名字也不想改变了,还是叫 学习golang 初探 吧。
所谓的动态数组,其实在本质上,和go slice
相似,也是申请了一块数组,当数组不够的时候,重新申请数组,然后将老数组的数据拷贝进新数组中,再把老数组给销毁掉就好了。
动态数组逻辑
有效长度和总长度
我们还是和go slice
类似,我们使用len
来获取动态数组的有效数据长度,使用cap
来获取底层数据的长度。
例如,在下列数组中,我们定义绿色为可以使用的数据块,黄色为不可使用的数据块。
那在数组中,cap
应当为10,len
有效数据长度应当为6。
如何新增有效数据
我们也可以定义一个append
函数,来扩展一个有效数据,其实就是在 (len+1) < cap
的情况下,进行len+1
即可
数组如何扩容
当len
和cap
相当时,恰恰又要进行append
,此时,我们就需要扩容了,我们可以按当前量扩充到2倍足以。
例如:
当前数组已经使用完了
若我们还想在增加一个,则就需要扩容才行
我们就先申请数组b,然后将老数据拷贝至数组b,cap
同步修改,然后再进行扩容,不就可以了么
我们先进行扩容,然后再append
代码以及逻辑实现
初始化
结构体定义
我们将结构体定义为这样
我们结构体定义为如下
在初始化时,我们需要传入初始化一个数值作为默认大小,然后实际分配内存空间,且将容量个数传给该动态数组
追加函数
接着,我们来编写追加函数,追加函数
追加函数分为2中情况
- 容量未满
- 容量已经满了
对于容量未满的情况,我们直接赋值,且使有效长度+1即可
对于容量已满的情况,我们则需要做如下操作
- 申请新动态数组,容量为老数组的2倍
- 拷贝老数组内存
- 重新插入数据
我们来看看append
函数
测试数据
我们在main
中追加一下数据,用于测试
执行c程序
我们来尝试下
我们可以看到,第一次扩容之前,起始地址为: 0x7fffed75a2b0
第一次扩容为0x7fffed75a2d0
第二次扩容为: 0x7fffed75a2f0
容量值也从3到6再到12,下一次扩容,应当为24
总结
之前之所以不用go
写,我是不知道怎么定义固定数组,若不定义固定数组,像c
这样定义指针的话,我又不知道如何进行动态内存分配,哎,还是对go
不怎么熟悉,所以最后,尝试了若干次过后,我决定用c
来写该操作,很久没有写c
了,感觉还是蛮吃力的。不过好好,而恰恰好,我们go slice
的基本逻辑应该和此类似,实现的代码,我还是放在Gitee
上了哈 pdudo/autoArray.c
加油咯,运维小学生。