1. 动态数组
在实际项目中,我们经常与各式各样的数据打交道。
例如:我们处理的是学生的数据。
struct student {
int id; // 学号
char name[20]; // 姓名
int gender; // 性别
int mark; // 成绩
};
学生数据使用一个结构体表示,该结构体拥有4个成员。分别为:
- 学号
- 姓名
- 性别
- 成绩
大多数情况下,数据的数量是不确定的,可能随着时间流逝而增加或减少。
例如:一开始有5个学生,后来增加到8个,再后来增加到15个。最后,减少到3个学生。
我们可以使用数组来盛放这些学生的数据,但是,声明数组时,声明一个长度为多少的数组,是一个需要考虑的问题。
如果我们能预知学生数量最多为15个,我们可以声明一个元素数量为15的结构体数组。
struct student arrStudent[15];
但是,大多数情况下,我们是不能预知数据到底有多少的。因此,最好是能够让数组的长度根据数据的多少自动增长。一种常用的数组增长策略是:当数组已经装满时,将数组长度增长到原来的两倍。
例如,数组的初始长度为5,当数组需要继续添加数据时,数组的长度增长为原来的两倍,即10个元素。若数组再次被装满,将数组的长度再次增加为原来的两倍,即20个元素。
为了实现上述的特性,我们可以借助于malloc
与realloc
函数。
void *malloc(size_t size);
void *realloc(void *ptr, size_t new_size);
malloc
函数可以向系统申请size
字节大小的内存空间。若申请成功,则返回这段内存空间的首地址。
relloc
函数可以用于增长或缩短之前申请的内存空间。relloc
函数的第一个参数是之前申请的内存空间的首地址,它会根据第二个参数,长度new_size
增长或缩短之前申请的内存空间,并返回调整长度后的内存空间的首地址。
2. 实现动态数组
下面我们来实现这个动态数组对象,我们将这个对象命名为vector
。
struct vector {
bool (*append)(struct vector* pVec, struct student data);
struct student (*get)(struct vector* pVec, int index);
void (*clear)(struct vector *pVec);
void (*remove)(struct vector* pVec, int index);
struct student *pData;
int size;
int capacity;
};
成员
这个对象有3个成员,它们分别是:
struct student *pData
int size
int capacity
pData
用于记录数组的首元素指针。
size
为数组中盛放的数据的长度。
capacity
为整个数组拥有的元素个数,即数组的容量。
初始化
我们定义一个符号常量VECTOR_INIT_CAPACITY
用来表示初始情况下,数组拥有的元素个数。为了方便测试,我们把这个数值定的小一点,暂时将数值设定为1。
#define VECTOR_INIT_CAPACITY 1
定义一个vectorInit
函数,用于vector
对象的初始化。初始情况下,使用malloc
函数申请一个元素类型为struct student
的数组,数组的元素数量为VECTOR_INIT_CAPACITY
。保存这个数组的首元素指针到pData
中。此时,数组拥有的元素个数为VECTOR_INIT_CAPACITY
,盛放的数据长度为0。
void vectorInit(struct vector* pVec)
{
pVec->pData = (struct student*)malloc(sizeof(struct student) * VECTOR_INIT_CAPACITY);
pVec->size = 0;
pVec->capacity = VECTOR_INIT_CAPACITY;
}
方法
接下来我们再来看vector
对象的4个方法。
bool (*append)(struct vector* pVec, struct student data);
struct student (*get)(struct vector* pVec, int index);
void (*clear)(struct vector *pVec);
void (*remove)(struct vector* pVec, int index);
append
方法用于向数组中添加一个struct student
数据。如果添加成功返回true
,否则返回false
。
get
方法用于从数组中获取一个struct student
数据,index
参数为需要获取的数组元素下标。
clear
方法用于清除所有数组中盛放的数据,并将size
复位为0,capacity
复位为VECTOR_INIT_CAPACITY
。
remove
方法用于删除数组中下标为index
的元素,并将size
减1。