600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > C语言实现 动态数组 处理任意类型数据

C语言实现 动态数组 处理任意类型数据

时间:2020-09-24 15:57:11

相关推荐

C语言实现 动态数组 处理任意类型数据

引言:动态数组在C/C++、Java、Python等语言中应用广泛,高级语言一般通过调用类或接口等可以快捷使用,C语言实现动态数组需要手动构造,以下为实现过程。

1结构体构造动态数组

typedef struct Array{void **p; //维护在堆区创建的指针(后续函数入参为传址调用,节省内存,对void*操作,因此构造void **p)size_t capacity; //动态数组容量size_t size;//动态数组实际大小} Array;

2动态数组初始化

Array *initArray(size_t capacity) {Array *array = (Array *)malloc(sizeof(Array));//在堆区申请array的内存array->capacity = capacity;//将动态数组容量初始化为函数入参array->size = 0;//将动态数组实际大小初始化为0array->p = (void **)malloc(sizeof(void *) * capacity); //在堆区申请二级指针p的内存return array;}

3动态数组在索引index处插入数据data

/*** @brief 向动态数组插入一个数据* @param array 动态数组* @param index 插入索引* @param data 插入数据,data为传址* @return int 插入成功返回1,失败返回0*/#define RATIO 2 //扩容倍数int insertArrayByIndex(Array *array, int index, void *data) {if (array == NULL || data == NULL)//空指针判断return 0;if (index < 0 || index >= array->size) //插入索引不在[0,size)内时,选择尾插index = array->size;if (array->capacity == array->size) // array数组已满,需要申请更大空间,并将源数据copy到新空间{size_t newCapacity = array->capacity * RATIO; //动态数组新容量void **newP = (void **)malloc(sizeof(void *) * newCapacity);//重新申请堆内存memcpy(newP, array->p, sizeof(void *) * array->capacity);//源数据copy至新的堆内存中free(array->p);//释放旧空间array->p = newP;//更新新指向array->capacity = newCapacity; //更新新容量}for (int i = array->size - 1; i >= index; i--) //新数据插入在index,先后移index及其以后数据array->p[i + 1] = array->p[i]; // p[i]相当于*(p+i),p原为二级指针,解引用操作了void *;使得一级地址后移array->p[index] = data; array->size++; //更新大小return 1;}

4 动态数组移除数据,可分为通过索引index移除或通过数据data移除,

4.1通过索引index移除

int removeArrayByIndex(Array *array, int index) //从动态数组移除一个数据{if (array == NULL || index < 0 || index >= array->size)//空指针或非法索引会导致移除失败return 0;for (int i = index + 1; i < array->size; i++)array->p[i - 1] = array->p[i];//移除index对应的data后,需将index后的数据前移free(array->p[array->size-1]);array->p[array->size - 1] = NULL;//原末位数据置空array->size--;//原实际数组大小减1return 1;}

4.2通过数据data移除,为方便理解,以下代码构造了动态数组存储的数据类型

typedef struct Student // 以动态数组存储的数据类型为Student*为例分析{char name[10];int age;} Student;int compare(void *s1, void *s2) //根据结构体Student设计比较规则,返回1表示相等{Student *stu1 = (Student *)s1;//指针类型转换Student *stu2 = (Student *)s2;if (strcmp(stu1->name, stu2->name) == 0 && stu1->age == stu2->age)return 1;return 0;}int removeArrayByData(Array *array, void *data, int (*compare)(void *s1, void *s2)) //移除data函数,仅考虑不重复情况下{if (array == NULL || data == NULL)//空指针return 0;for (int i = 0; i < array->size; i++){if (compare(array->p[i], data))//利用函数回调找出与data相同时的索引index{for (int index = i; index < array->size - 1; index++)//思路与通过索引删除数据一致array->p[index] = array->p[index + 1];free(array->p[array->size - 1]);array->p[array->size - 1] = NULL;array->size--;return 1;//删除成功返回1}}return 0;//删除失败返回0}

5动态数组遍历

void listArray(Array *array, void (*printfdArray)(void *)) //利用函数回调遍历{if (array == NULL || printfdArray == NULL)return;for (int i = 0; i < array->size; i++)printfdArray(array->p[i]);puts("\n");}void printfStudent(void *data) //为Student*类型数据写遍历函数{Student *s = (Student *)data;printf("%s->%d\t", s->name, s->age);}

6动态数组销毁

void destoryArray(Array *array)//释放占用的内存即可{if (array != NULL){free(array);array = NULL;}if (array->p != NULL){free(array->p);array->p = NULL;}}

7动态数组简单演示

#include <stdio.h>#include <stdlib.h>#include <string.h>#define RATIO 2 //动态数组扩展系数#define SHOW_CAPACITY_SIZE_AND_LIST \printf("容量->%d\t大小->%d\t\n", array->capacity, array->size); \listArray(array, printfStudent);int main(){Array *array = initArray(5);Student s1 = {"jakes1", 16};Student s2 = {"jakes2", 17};Student s3 = {"jakes3", 18};Student s4 = {"jakes4", 19};Student s5 = {"jakes5", 20};Student s6 = {"jakes6", 21};insertArray(array, 0, &s1);SHOW_CAPACITY_SIZE_AND_LISTinsertArray(array, 0, &s2);SHOW_CAPACITY_SIZE_AND_LISTinsertArray(array, 1, &s3);SHOW_CAPACITY_SIZE_AND_LISTinsertArray(array, 0, &s4);SHOW_CAPACITY_SIZE_AND_LISTinsertArray(array, 1, &s5);SHOW_CAPACITY_SIZE_AND_LISTinsertArray(array, 2, &s6);SHOW_CAPACITY_SIZE_AND_LISTremoveArrayByIndex(array, 2);SHOW_CAPACITY_SIZE_AND_LISTprintf("-----%d\n", removeArrayByData(array, &s3, compare));SHOW_CAPACITY_SIZE_AND_LISTreturn 0;}

运行结果如下

--如有错误,欢迎大家指出交流,共同学习--

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。