使用C语言实现vector动态数组的实例分享
更新时间:2020年4月25日 17:35 点击:1232
下面是做项目时实现的一个动态数组,先后加入了好几个之后的项目,下面晒下代码。
头文件:
# ifndef __CVECTOR_H__ # define __CVECTOR_H__ # define MIN_LEN 256 # define CVEFAILED -1 # define CVESUCCESS 0 # define CVEPUSHBACK 1 # define CVEPOPBACK 2 # define CVEINSERT 3 # define CVERM 4 # define EXPANED_VAL 1 # define REDUSED_VAL 2 typedef void *citerator; typedef struct _cvector *cvector; # ifdef _cplusplus # define EXTERN_ extern "C" # else # define EXTERN_ extern # endif EXTERN_ cvector cvector_create (const size_t size ); EXTERN_ void cvector_destroy (const cvector cv ); EXTERN_ size_t cvector_length (const cvector cv ); EXTERN_ int cvector_pushback (const cvector cv, void *memb ); EXTERN_ int cvector_popback (const cvector cv, void *memb ); EXTERN_ size_t cvector_iter_at (const cvector cv, citerator iter ); EXTERN_ int cvector_iter_val (const cvector cv, citerator iter, void *memb); EXTERN_ citerator cvector_begin (const cvector cv ); EXTERN_ citerator cvector_end (const cvector cv ); EXTERN_ citerator cvector_next (const cvector cv, citerator iter ); EXTERN_ int cvector_val_at (const cvector cv, size_t index, void *memb ); EXTERN_ int cvector_insert (const cvector cv, citerator iter, void *memb); EXTERN_ int cvector_insert_at(const cvector cv, size_t index, void *memb ); EXTERN_ int cvector_rm (const cvector cv, citerator iter ); EXTERN_ int cvector_rm_at (const cvector cv, size_t index ); /* for test */ EXTERN_ void cv_info (const cvector cv ); EXTERN_ void cv_print (const cvector cv ); #endif /* EOF file cvector.h */
C文件:
# include <stdio.h> # include <stdlib.h> # include <string.h> # include <unistd.h> # define MIN_LEN 256 # define CVEFAILED -1 # define CVESUCCESS 0 # define CVEPUSHBACK 1 # define CVEPOPBACK 2 # define CVEINSERT 3 # define CVERM 4 # define EXPANED_VAL 1 # define REDUSED_VAL 2 typedef void *citerator; typedef struct _cvector { void *cv_pdata; size_t cv_len, cv_tot_len, cv_size; } *cvector; # define CWARNING_ITER(cv, iter, file, func, line) \ do {\ if ((cvector_begin(cv) > iter) || (cvector_end(cv) <= iter)) {\ fprintf(stderr, "var(" #iter ") warng out of range, "\ "at file:%s func:%s line:%d!!/n", file, func, line);\ return CVEFAILED;\ }\ } while (0) # ifdef _cplusplus # define EXTERN_ extern "C" # else # define EXTERN_ extern # endif EXTERN_ cvector cvector_create (const size_t size ); EXTERN_ void cvector_destroy (const cvector cv ); EXTERN_ size_t cvector_length (const cvector cv ); EXTERN_ int cvector_pushback (const cvector cv, void *memb ); EXTERN_ int cvector_popback (const cvector cv, void *memb ); EXTERN_ size_t cvector_iter_at (const cvector cv, citerator iter ); EXTERN_ int cvector_iter_val (const cvector cv, citerator iter, void *memb); EXTERN_ citerator cvector_begin (const cvector cv ); EXTERN_ citerator cvector_end (const cvector cv ); EXTERN_ citerator cvector_next (const cvector cv, citerator iter ); EXTERN_ int cvector_val_at (const cvector cv, size_t index, void *memb ); EXTERN_ int cvector_insert (const cvector cv, citerator iter, void *memb); EXTERN_ int cvector_insert_at(const cvector cv, size_t index, void *memb ); EXTERN_ int cvector_rm (const cvector cv, citerator iter ); EXTERN_ int cvector_rm_at (const cvector cv, size_t index ); /* for test */ EXTERN_ void cv_info (const cvector cv ); EXTERN_ void cv_print (const cvector cv ); cvector cvector_create(const size_t size) { cvector cv = (cvector)malloc(sizeof (struct _cvector)); if (!cv) return NULL; cv->cv_pdata = malloc(MIN_LEN * size); if (!cv->cv_pdata) { free(cv); return NULL; } cv->cv_size = size; cv->cv_tot_len = MIN_LEN; cv->cv_len = 0; return cv; } void cvector_destroy(const cvector cv) { free(cv->cv_pdata); free(cv); return; } size_t cvector_length(const cvector cv) { return cv->cv_len; } int cvector_pushback(const cvector cv, void *memb) { if (cv->cv_len >= cv->cv_tot_len) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_pdata = pd_sav; cv->cv_tot_len >>= EXPANED_VAL; return CVEPUSHBACK; } } memcpy(cv->cv_pdata + cv->cv_len * cv->cv_size, memb, cv->cv_size); cv->cv_len++; return CVESUCCESS; } int cvector_popback(const cvector cv, void *memb) { if (cv->cv_len <= 0) return CVEPOPBACK; cv->cv_len--; memcpy(memb, cv->cv_pdata + cv->cv_len * cv->cv_size, cv->cv_size); if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL)) && (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len >>= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = pd_sav; return CVEPOPBACK; } } return CVESUCCESS; } size_t cvector_iter_at(const cvector cv, citerator iter) { CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); return (iter - cv->cv_pdata) / cv->cv_size; } int cvector_iter_val(const cvector cv, citerator iter, void *memb) { CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); memcpy(memb, iter, cv->cv_size); return 0; } citerator cvector_begin(const cvector cv) { return cv->cv_pdata; } citerator cvector_end(const cvector cv) { return cv->cv_pdata + (cv->cv_size * cv->cv_len); } static inline void cvmemove_foreward(const cvector cv, void *from, void *to) { size_t size = cv->cv_size; void *p; for (p = to; p >= from; p -= size) memcpy(p + size, p, size); return; } static inline void cvmemove_backward(const cvector cv, void *from, void *to) { memcpy(from, from + cv->cv_size, to - from); return; } int cvector_insert(const cvector cv, citerator iter, void *memb) { CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); if (cv->cv_len >= cv->cv_tot_len) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_pdata = pd_sav; cv->cv_tot_len >>= EXPANED_VAL; return CVEINSERT; } } cvmemove_foreward(cv, iter, cv->cv_pdata + cv->cv_len * cv->cv_size); memcpy(iter, memb, cv->cv_size); cv->cv_len++; return CVESUCCESS; } int cvector_insert_at(const cvector cv, size_t index, void *memb) { citerator iter; if (index >= cv->cv_tot_len) { cv->cv_len = index + 1; while (cv->cv_len >= cv->cv_tot_len) cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); iter = cv->cv_pdata + cv->cv_size * index; memcpy(iter, memb, cv->cv_size); } else { iter = cv->cv_pdata + cv->cv_size * index; cvector_insert(cv, iter, memb); } return 0; } citerator cvector_next(const cvector cv, citerator iter) { return iter + cv->cv_size; } int cvector_val(const cvector cv, citerator iter, void *memb) { memcpy(memb, iter, cv->cv_size); return 0; } int cvector_val_at(const cvector cv, size_t index, void *memb) { memcpy(memb, cv->cv_pdata + index * cv->cv_size, cv->cv_size); return 0; } int cvector_rm(const cvector cv, citerator iter) { citerator from; citerator end; CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); from = iter; end = cvector_end(cv); memcpy(from, from + cv->cv_size, end - from); cv->cv_len--; if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL)) && (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len >>= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = pd_sav; return CVERM; } } return CVESUCCESS; } int cvector_rm_at(const cvector cv, size_t index) { citerator iter; iter = cv->cv_pdata + cv->cv_size * index; CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); return cvector_rm(cv, iter); } void cv_info(const cvector cv) { printf("/n/ntot :%s : %d/n", __func__, cv->cv_tot_len); printf("len :%s : %d/n", __func__, cv->cv_len); printf("size:%s : %d/n/n", __func__, cv->cv_size); return; } void cv_print(const cvector cv) { int num; citerator iter; if (cvector_length(cv) == 0) fprintf(stderr, "file:%s func:%s line:%d error, null length cvector!!/n", __FILE__, __func__, __LINE__); for (iter = cvector_begin(cv); iter != cvector_end(cv); iter = cvector_next(cv, iter)) { cvector_iter_val(cv, iter, &num); printf("var:%d at:%d/n", num, cvector_iter_at(cv, iter)); } return; }
改进版
上面那份代码是在Linux下写的,如果是在Windows的Visul C++环境下编译似乎会出些问题,所以特别做了个改进版:
下面是更新后的代码:
cvector.h
# ifndef __CVECTOR_H__ # define __CVECTOR_H__ # include <stdio.h> # include <stdlib.h> # include <string.h> # define MIN_LEN 256 # define CVEFAILED -1 # define CVESUCCESS 0 # define CVEPUSHBACK 1 # define CVEPOPBACK 2 # define CVEINSERT 3 # define CVERM 4 # define EXPANED_VAL 1 # define REDUSED_VAL 2 typedef void *citerator; typedef struct _cvector *cvector; # ifdef __cplusplus extern "C" { # endif cvector cvector_create (const size_t size ); void cvector_destroy (const cvector cv ); size_t cvector_length (const cvector cv ); int cvector_pushback (const cvector cv, void *memb ); int cvector_popback (const cvector cv, void *memb ); size_t cvector_iter_at (const cvector cv, citerator iter ); int cvector_iter_val (const cvector cv, citerator iter, void *memb); citerator cvector_begin (const cvector cv ); citerator cvector_end (const cvector cv ); citerator cvector_next (const cvector cv, citerator iter ); int cvector_val_at (const cvector cv, size_t index, void *memb ); int cvector_insert (const cvector cv, citerator iter, void *memb); int cvector_insert_at(const cvector cv, size_t index, void *memb ); int cvector_rm (const cvector cv, citerator iter ); int cvector_rm_at (const cvector cv, size_t index ); /* for test */ void cv_info (const cvector cv ); void cv_print (const cvector cv ); # ifdef __cplusplus } # endif #endif /* EOF file cvector.h */
cvector.c
#include "cvector.h" #ifndef __gnu_linux__ #define __func__ "unknown" #define inline __forceinline #endif # define CWARNING_ITER(cv, iter, file, func, line) \ do {\ if ((cvector_begin(cv) > iter) || (cvector_end(cv) <= iter)) {\ fprintf(stderr, "var(" #iter ") warng out of range, "\ "at file:%s func:%s line:%d!!\n", file, func, line);\ return CVEFAILED;\ }\ } while (0) struct _cvector { void *cv_pdata; size_t cv_len, cv_tot_len, cv_size; }; cvector cvector_create(const size_t size) { cvector cv = (cvector)malloc(sizeof (struct _cvector)); if (!cv) return NULL; cv->cv_pdata = malloc(MIN_LEN * size); if (!cv->cv_pdata) { free(cv); return NULL; } cv->cv_size = size; cv->cv_tot_len = MIN_LEN; cv->cv_len = 0; return cv; } void cvector_destroy(const cvector cv) { free(cv->cv_pdata); free(cv); return; } size_t cvector_length(const cvector cv) { return cv->cv_len; } int cvector_pushback(const cvector cv, void *memb) { if (cv->cv_len >= cv->cv_tot_len) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_pdata = pd_sav; cv->cv_tot_len >>= EXPANED_VAL; return CVEPUSHBACK; } } memcpy((char *)cv->cv_pdata + cv->cv_len * cv->cv_size, memb, cv->cv_size); cv->cv_len++; return CVESUCCESS; } int cvector_popback(const cvector cv, void *memb) { if (cv->cv_len <= 0) return CVEPOPBACK; cv->cv_len--; memcpy(memb, (char *)cv->cv_pdata + cv->cv_len * cv->cv_size, cv->cv_size); if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL)) && (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len >>= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = pd_sav; return CVEPOPBACK; } } return CVESUCCESS; } size_t cvector_iter_at(const cvector cv, citerator iter) { CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); return ((char *)iter - (char *)cv->cv_pdata) / cv->cv_size; } int cvector_iter_val(const cvector cv, citerator iter, void *memb) { CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); memcpy(memb, iter, cv->cv_size); return 0; } citerator cvector_begin(const cvector cv) { return cv->cv_pdata; } citerator cvector_end(const cvector cv) { return (char *)cv->cv_pdata + (cv->cv_size * cv->cv_len); } static inline void cvmemove_foreward(const cvector cv, void *from, void *to) { size_t size = cv->cv_size; char *p; for (p = (char *)to; p >= (char *)from; p -= size) memcpy(p + size, p, size); return; } static inline void cvmemove_backward(const cvector cv, void *from, void *to) { memcpy(from, (char *)from + cv->cv_size, (char *)to - (char *)from); return; } int cvector_insert(const cvector cv, citerator iter, void *memb) { CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); if (cv->cv_len >= cv->cv_tot_len) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_pdata = pd_sav; cv->cv_tot_len >>= EXPANED_VAL; return CVEINSERT; } } cvmemove_foreward(cv, iter, (char *)cv->cv_pdata + cv->cv_len * cv->cv_size); memcpy(iter, memb, cv->cv_size); cv->cv_len++; return CVESUCCESS; } int cvector_insert_at(const cvector cv, size_t index, void *memb) { citerator iter; if (index >= cv->cv_tot_len) { cv->cv_len = index + 1; while (cv->cv_len >= cv->cv_tot_len) cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); iter = (char *)cv->cv_pdata + cv->cv_size * index; memcpy(iter, memb, cv->cv_size); } else { iter = (char *)cv->cv_pdata + cv->cv_size * index; cvector_insert(cv, iter, memb); } return 0; } citerator cvector_next(const cvector cv, citerator iter) { return (char *)iter + cv->cv_size; } int cvector_val(const cvector cv, citerator iter, void *memb) { memcpy(memb, iter, cv->cv_size); return 0; } int cvector_val_at(const cvector cv, size_t index, void *memb) { memcpy(memb, (char *)cv->cv_pdata + index * cv->cv_size, cv->cv_size); return 0; } int cvector_rm(const cvector cv, citerator iter) { citerator from; citerator end; CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); from = iter; end = cvector_end(cv); memcpy(from, (char *)from + cv->cv_size, (char *)end - (char *)from); cv->cv_len--; if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL)) && (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))) { void *pd_sav = cv->cv_pdata; cv->cv_tot_len >>= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size); if (!cv->cv_pdata) { cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = pd_sav; return CVERM; } } return CVESUCCESS; } int cvector_rm_at(const cvector cv, size_t index) { citerator iter; iter = (char *)cv->cv_pdata + cv->cv_size * index; CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__); return cvector_rm(cv, iter); } void cv_info(const cvector cv) { printf("\n\ntot :%s : %d\n", __func__, cv->cv_tot_len); printf("len :%s : %d\n", __func__, cv->cv_len); printf("size:%s : %d\n\n", __func__, cv->cv_size); return; } void cv_print(const cvector cv) { int num; citerator iter; if (cvector_length(cv) == 0) fprintf(stderr, "file:%s func:%s line:%d error, null length cvector!!\n", __FILE__, __func__, __LINE__); for (iter = cvector_begin(cv); iter != cvector_end(cv); iter = cvector_next(cv, iter)) { cvector_iter_val(cv, iter, &num); printf("var:%d at:%d\n", num, cvector_iter_at(cv, iter)); } return; }
main.cpp
#include "cvector.h" int main() { int i = 1; cvector cv = cvector_create(sizeof(int)); cvector_pushback(cv, &i); cvector_pushback(cv, &i); cvector_pushback(cv, &i); cvector_pushback(cv, &i); cv_print(cv); cvector_destroy(cv); return 0; }
上一篇: C++制作俄罗斯方块
下一篇: 在C语言中调用C++做的动态链接库
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C#中动态数组用法,实例分析了C#中ArrayList实现动态数组的技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25