C语言:动态数组实现学生信息的增删查改

一、问题引入

我们定义数组时,数组的方括号内填写的是一个常量表达式。可是,在很多情况下,数组的大小是不确定的,比如储存学生信息的数组,我们往往需要对学生的信息进行增、删、查、改,那么数组的大小就要随着对学生信息的操作而改变。这里就需要引入动态数组的概念。

二、动态数组

大多数情况下,我们无法预知数组的长度,所以,我们希望数组的长度能够随数据的增加自动增长。一种常用的数组增长策略是:当程序检测到数组已经装满时,数组长度自动增长为原来的两倍。为了实现这个功能,我们需要引入malloc 与 realloc 函数。

三、malloc 与 realloc 函数

1、void *malloc(size_t size);

malloc函数用于向内存申请size个字节大小的空间,若申请成功,则返回这段内存空间的首地址。若申请失败,则返回NULL。

2、void *realloc(void *ptr, size_t new_size);

realloc函数用于增长或缩短之前申请的内存空间。函数的第一个参数是之前申请的内存空间的首地址,第二个参数是将之前申请的内存空间增长或缩短为new_size个字节大小的内存空间,返回值是新的内存空间的首地址。

四、具体案例

为方便大家理解,我们引入一个具体案例:利用动态数组实现学生信息的增、删、查、改。

一、定义相关结构体

首先,定义学生信息结构体。

typedef struct{
    int id; // 学号
    char name[20]; // 姓名
    int gender; // 性别
    int mark; // 成绩
}student;

然后,定义一个嵌套结构。

typedef struct {
    student* pData;
    int size;
    int capacity;
}vector

pData 用于记录数组的首元素指针。 size 为数组中盛放的数据的长度。 capacity 为整个数组拥有的元素个数,即数组的容量。

二、定义vectorInit函数初始化vector结构体

为了方便测试,我们将数组初始大小设置为1,可以用一个define宏定义。

#define VECTOR_INIT_CAPACITY 1

然后,再定义一个vectorInit函数初始化vector结构体, 初始情况下,使用 malloc 函数申请一个元素类 型为 struct student 的数组,数组的元素数量为 VECTOR_INIT_CAPACITY 。保存这个数组的首元素指针 到 pData 中。此时,数组拥有的元素个数为 VECTOR_INIT_CAPACITY ,盛放的数据长度为0。

void vectorInit(vector* pVec)
{
    pVec->pData = (student*)malloc(sizeof(student)*VECTOR_INIT_CAPACITY);
    //相当于student a->pData[sizeof(student)*VECTOR_INIT_CAPACITY]
    pVec->size = 0;
    pVec->capacity = VECTOR_INIT_CAPACITY;
}

三、增

利用bool型函数增加学生信息,如果增加成功,返回true,否则返回false。

代码和注释如下。

bool vectorAppend(vector* pVec,student data)
{
    if (pVec->size >= pVec->capacity)//判断数组是否装满
    {
        //将数组增长为原来的两倍
        student* newData = (student*)realloc(pVec->pData, pVec->capacity * sizeof(student) * 2);
        if (newData == NULL)//如果增长失败,则返回false
        {
            return false;
        }
        pVec->pData = newData;
        pVec->capacity = 2 * pVec->capacity;
    }
    pVec->pData[pVec->size] = data;
    pVec->size++;
    return true;
}

四、删

从数组中删除元素的方法:从被删除元素的下标开始,将后续元素依次赋值给前驱元素。

void vectorRemove(vector* pVec, int index)
{
    for (int i = index; i < pVec->size - 1; i++)
        pVec->pData[i] = pVec->pData[i + 1];//将后续元素依次赋值给前驱元素
    pVec->size -= 1;//数组盛放元素减1
}

五、查

查找元素很简单,只要输出结构体数组中index下标所对应的元素数据即可。

student vectorGet(vector* pVec, int index)
{
    return pVec->pData[index];
}

六、改

clear 方法用于将所有数组中盛放的数据清空,并将数组的容量缩短为初始容量。再调用”增“函数重置学生信息即可。

void vectorClear(vector* pVec)
{
    if (pVec->pData != NULL)
        free(pVec->pData);//释放内存空间
    pVec->pData = (student*)malloc(sizeof(student) * VECTOR_INIT_CAPACITY);
    pVec->size = 0;
    pVec->capacity = VECTOR_INIT_CAPACITY;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值