使用C語(yǔ)言實(shí)現(xiàn)vector動(dòng)態(tài)數(shù)組的實(shí)例分享
下面是做項(xiàng)目時(shí)實(shí)現(xiàn)的一個(gè)動(dòng)態(tài)數(shù)組,先后加入了好幾個(gè)之后的項(xiàng)目,下面曬下代碼。
頭文件:
# 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;
}
改進(jìn)版
上面那份代碼是在Linux下寫(xiě)的,如果是在Windows的Visul C++環(huán)境下編譯似乎會(huì)出些問(wèn)題,所以特別做了個(gè)改進(jìn)版:
下面是更新后的代碼:
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語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解分析
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之復(fù)雜鏈表的拷貝
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)進(jìn)階之棧和隊(duì)列的實(shí)現(xiàn)
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)時(shí)間復(fù)雜度及空間復(fù)雜度簡(jiǎn)要分析
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)單鏈表接口函數(shù)全面講解教程
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)創(chuàng)建及遍歷十字鏈表
- C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)線性表之順序表和鏈表原理分析
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之vector底層實(shí)現(xiàn)機(jī)制解析
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)靜態(tài)存儲(chǔ)通訊錄的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)靜態(tài)存儲(chǔ)的通訊錄,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,需要的可以參考一下2022-09-09
C語(yǔ)言實(shí)現(xiàn)輸入一顆二元查找樹(shù)并將該樹(shù)轉(zhuǎn)換為它的鏡像
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)輸入一顆二元查找樹(shù)并將該樹(shù)轉(zhuǎn)換為它的鏡像,是數(shù)據(jù)結(jié)構(gòu)中二元查找樹(shù)的一個(gè)比較經(jīng)典的算法,有不錯(cuò)的借鑒價(jià)值,需要的朋友可以參考下2014-09-09
利用Matlab制作一個(gè)賊簡(jiǎn)單的粒子圣誕樹(shù)
圣誕節(jié)快到了,本文用Matlab繪制了圣誕樹(shù)祝你們圣誕節(jié)快樂(lè),所以下面這篇文章主要給大家介紹了關(guān)于如何利用Matlab制作一個(gè)賊簡(jiǎn)單的粒子圣誕樹(shù),需要的朋友可以參考下2022-12-12
詳解C++中類(lèi)的六大默認(rèn)成員函數(shù)
這篇文章主要介紹了C++類(lèi)中的六大默認(rèn)成員函數(shù)的原理雨使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
C++?Boost?StringAlgorithms超詳細(xì)講解
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)2022-11-11

