学习golang(6) 初探:用c语言实现一个动态数组

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第25天,点击查看活动详情

我尝试使用go来写一个动态数组,但是很可惜,我实力尚弱,尝试数次,最终以失败了,所以,决定使用c来实现一个简单的int类型的动态数组,名字也不想改变了,还是叫 学习golang 初探 吧。

所谓的动态数组,其实在本质上,和go slice相似,也是申请了一块数组,当数组不够的时候,重新申请数组,然后将老数组的数据拷贝进新数组中,再把老数组给销毁掉就好了。

动态数组逻辑

有效长度和总长度

我们还是和go slice类似,我们使用len来获取动态数组的有效数据长度,使用cap来获取底层数据的长度。

例如,在下列数组中,我们定义绿色为可以使用的数据块,黄色为不可使用的数据块。

那在数组中,cap应当为10,len有效数据长度应当为6。

如何新增有效数据

我们也可以定义一个append函数,来扩展一个有效数据,其实就是在 (len+1) < cap 的情况下,进行len+1 即可

数组如何扩容

lencap相当时,恰恰又要进行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

加油咯,运维小学生。

posted @ 2022-04-25 15:04  pdudos  阅读(0)  评论(0编辑  收藏  举报  来源