说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
QQ 群 号:513683159 【相互学习】
内容来源:
《系统程序员成长计划》
- 一、概念
- 1、数组的相关描述?
- 2、静态数组
- 3、动态数组
- 二、通用动态数组
- 1、文件结构
- 2、动态数组结构体
- 3、动态数组 创建与销毁函数
- 4、动态数组 空间扩展与缩小函数
- 5、动态数组 插入函数(指定插,头插,尾插)
- 6、动态数组删除指定位置元素
- 7、动态数组 获取指定下标数据函数
- 8、动态数组 设置指定下标数据函数
- 9、动态数组 获取数组数组长度
- 10、动态数组 遍历访问函数(调用者可用于对遍历数据进行一定操作)
- 11、动态数组 查找函数(调用者可用于获取对应数据内容)
- 三、动态数组源码及函数功能测试
- darray.c
- darray.h
- typedef.h
- main.c
- Makefile
- 测试结果:
1️⃣什么是数组?
相同类型元素的集合,分配在一块连续的内存空间。
2️⃣数组的分类:(根据数组对象长度在哪个阶段确定)
① 静态数组:
由系统在内存中栈区分配的空间,编译时确定数组长度,运行期间不可改,运行后系统自动释放。
② 动态数组:
由malloc()在内存中堆区分配的空间,运行时确定数组长度,运行期间可更改,需人工手动释放。
1️⃣定义与注意点
| 一维数组 | 二维数组 | |
|---|---|---|
| 定义 | dataType arrayName[arraySize] = {initialize}; | dataType arrayName[arraySize] [arraySize] = {initialize}; |
| 描述 | dataType :数据类型,如:int 、float等. arrayName:数组名,与变量名命名规则相同。 arraySize:数组大小(下标),必须为常量,从0开始。 initialize:初始化数值,(数组元素不可超过数组长度) 1.全部赋值(可不指定数组程度,会自动计算)2.部分赋值 | |
| 注意 | ①一维大小可省,二维不可省 ②按行顺序存储(行之间可用大括号区分) | |
| ①数组作为参数时,传递的是数组的起始地址 ②数组下标是从0开始 | ||
2️⃣示例
#include3、动态数组int global_a[] = {0,1,2,3}; int main(int argc,char **argv) { static int static_a[] = {0,1,2,3}; int local_a[6] = {0,1,2,3,4,5}; //全部赋值 int local_b[] = {0,1,2,3}; //全部赋值,省略数组长度 int local_c[6] = {0,1,2,3}; //部分赋值 //int local_d[3] = {0,1,2,3}; //赋值越界, excess elements in array initializer int local_da[2][2]={0,1,2,3}; //全部赋值 int local_db[2][2]={{0,1},{2,3}}; //全部赋值 int local_dc[][2]={0,1,2,3}; //全部赋值,省略一维数组长度 int local_dd[][2]= {0,1}; //部分赋值 return 0; }
1️⃣简述
①定义指针对象,用于指向内存空间。
②malloc函数,在内存堆区开辟空间。
2️⃣示例
(实例一)
①源程序:array.c
#include#include #include #define MIN_PRE_ALLOCATE_NR 1 #ifndef debug_printf #define debug_printf printf #endif int main(int argc,char **argv) { int arrayLen = 3; //动态数组初始化长度 int *darray = NULL; //指向动态数组指针 int local_a[10] = {0,1,2,3,4,5,6,7,8,9}; //一维数组,全部赋值 int i = 0; darray = (int *)malloc(sizeof(int)*arrayLen); if(!darray) { debug_printf("malloc error!n"); exit(1); } debug_printf("%ld %ld %ldn",sizeof(local_a),sizeof(local_a[0]),sizeof(int)); debug_printf("%dn",arrayLen); while (sizeof(local_a)/sizeof(local_a[0]) > arrayLen) { //扩大1.5倍,不直接*1.5而采用这边这样方式是因为这样计算速度更快,后面加上一个常数确保若arrayLen 为0存在的错误 arrayLen = arrayLen + (arrayLen >> 1) + MIN_PRE_ALLOCATE_NR; darray = (int *)realloc((void *)darray,sizeof(int)*arrayLen); memset(darray,0,sizeof(int)*arrayLen); debug_printf("%dn",arrayLen); } memcpy(darray,&local_a,sizeof(int)*sizeof(local_a)/sizeof(local_a[0])); for(i = 0;i < sizeof(local_a)/sizeof(local_a[0]);i++) { debug_printf("%d ",darray[i]); //数组写法, // debug_printf("%d ",(darray + 0)[i]); //数组写法,(darray + n),表示darray偏移第n个字符的起始地址 // debug_printf("%d ",*(darray+i)); //指针写法, // debug_printf("%d ",*darray+i); //指针写法, } debug_printf("n"); free(darray); return 0; }
②编译运行及结果:
xsndz@Linux:~/Desktop$ gcc array.c -o array xsndz@Linux:~/Desktop$ ./array 40 4 4 3 5 8 13 0 1 2 3 4 5 6 7 8 9
(实例二)
①源程序:array2.c
#include#include int main(){ int arrLen; // 数组长度 int *array; // 数组指针 int i; // 数组下标 printf("输入数组长度:"); scanf("%d", &arrLen); // 动态分配内存空间,如果失败就退出程序 array = (int*)malloc( arrLen*sizeof(int) ); if(!array) { printf("创建数组失败!n"); exit(1); } // 向内存中写入数据 for(i=0; i array[i] = i+1; } // 循环输出数组元素 for(i=0; i printf("%d ", array[i]); } printf("n"); free(array); return 0; }
xsndz@Linux:~/Desktop$ gcc array2.c -o array xsndz@Linux:~/Desktop$ ./array 输入数组长度:20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20二、通用动态数组 1、文件结构
. ├── darray.c //动态数组源文件 ├── darray.h //动态数组头文件 ├── main.c //主循环函数 ├── Makefile └── typedef.h //通用数据类型头文件2、动态数组结构体
####### darray.h #######
struct _DArray;
typedef struct _DArray DArray;
####### darray.c #######
struct _DArray
{
void** data; //数据
size_t size; //实际使用数组大小
size_t alloc_size; //已分配数组大小
void* data_destroy_ctx; //销毁函数中上下文变量
DataDestroyFunc data_destroy; //销毁函数指针,为指向销毁函数
};
按照封装思想,隐藏数据结构,由于该数据结构内外都要使用,故定义放在源文件中,声明放在头文件中。
详细可查看:读书笔记 ——《系统程序员成长计划》篇2:封装
因为是通用动态数组,故选择存放的变量数据类型为void*指针,可是这边为什么是void**指针呢?
因为此处只是作为指针,用于指向具体动态数组空间,但由于数据对象就是void*指针,所以void**指针
####### darray.c #######
DArray* darray_create(DataDestroyFunc data_destroy, void* ctx)
{
DArray* thiz = malloc(sizeof(DArray));
if(thiz != NULL)
{
thiz->data = NULL;
thiz->size = 0;
thiz->alloc_size = 0;
thiz->data_destroy = data_destroy;
thiz->data_destroy_ctx = ctx;
}
return thiz;
}
static void darray_destroy_data(DArray* thiz, void* data)
{
if(thiz->data_destroy != NULL)
{
thiz->data_destroy(thiz->data_destroy_ctx, data);
}
return;
}
void darray_destroy(DArray* thiz)
{
size_t i = 0;
if(thiz != NULL)
{
for(i = 0; i < thiz->size; i++)
{
darray_destroy_data(thiz, thiz->data[i]);
}
SAFE_FREE(thiz->data);
SAFE_FREE(thiz);
}
return;
}
只要有对象的创建就要有对象的销毁!!!
动态数组创建函数:用于开辟一块空间,作为动态数组对象,存放动态数组相关信息。
注意:
仅创建该动态数据对象,具体的动态数组数据空间用指针指向,根据需求对空间进行分配。
创建函数形参用于传入销毁函数指针和销毁函数的参数。(这样面对不同数据类型的数据,可由调用者灵活的进行销毁)
动态数组销毁函数:用于清空动态数组空间数据内容并释放动态数组空间和释放动态数组对象。
注意:
销毁动态数组元素的数据单独用一个静态函数表示。(仅在该文件中起作用,不对外开放接口,同样也是封装的思想)
释放空间时,注意要释放两块存储空间,一个是动态数组对象空间,一个是动态数组数据空间
####### darray.c #######
#define MIN_PRE_ALLOCATE_NR 10
static Ret darray_expand(DArray* thiz, size_t need)
{
return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
if((thiz->size + need) > thiz->alloc_size)
{
size_t alloc_size = thiz->alloc_size + (thiz->alloc_size>>1) + MIN_PRE_ALLOCATE_NR;
void** data = (void**)realloc(thiz->data, sizeof(void*) * alloc_size);
if(data != NULL)
{
thiz->data = data;
thiz->alloc_size = alloc_size;
}
}
return ((thiz->size + need) <= thiz->alloc_size) ? RET_OK : RET_FAIL;
}
static Ret darray_shrink(DArray* thiz)
{
return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
if((thiz->size < (thiz->alloc_size >> 1)) && (thiz->alloc_size > MIN_PRE_ALLOCATE_NR))
{
size_t alloc_size = thiz->size + (thiz->size >> 1);
void** data = (void**)realloc(thiz->data, sizeof(void*) * alloc_size);
if(data != NULL)
{
thiz->data = data;
thiz->alloc_size = alloc_size;
}
}
return RET_OK;
}
动态数组空间扩展函数:若当前已使用大小+所需大小 > 已分配大小,则需扩展动态数组空间大小(扩大为已分配用的1.5倍)。
第一次扩展空间的大小有一个最小空间值,此处为10.
动态数组空间缩小函数:若当前已使用大小<已分配大小的二分之一且要已分配要大于最小空间,则需缩小动态数组空间大小(缩小为已使用的1.5倍)
####### darray.c #######
Ret darray_insert(DArray* thiz, size_t index, void* data)
{
Ret ret = RET_OOM;
size_t cursor = index;
return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
cursor = cursor < thiz->size ? cursor : thiz->size; //若插入位置大于动态数组现有大小则插在现有大小后面
if(darray_expand(thiz, 1) == RET_OK)
{
size_t i = 0;
for(i = thiz->size; i > cursor; i--)
{
thiz->data[i] = thiz->data[i-1];
}
thiz->data[cursor] = data;
thiz->size++;
ret = RET_OK;
}
return ret;
}
Ret darray_prepend(DArray* thiz, void* data)
{
return darray_insert(thiz, 0, data);
}
Ret darray_append(DArray* thiz, void* data)
{
return darray_insert(thiz, -1, data);//-1表示一个非常大的正数
}
注意此处传入的数据是void *类型的数据。因为此处构建的是通用的动态数组,所以数据存储的是万能指针(void *)。
插入模式分为三种:指定位置插,头插(0= 头部),尾插(-1=最大正数)。
####### darray.c #######
Ret darray_delete(DArray* thiz, size_t index)
{
return_val_if_fail(thiz != NULL && thiz->size > index, RET_INVALID_PARAMS);
size_t i = 0;
Ret ret = RET_OK;
darray_destroy_data(thiz, thiz->data[index]);
for(i = index; (i+1) < thiz->size; i++)
{
thiz->data[i] = thiz->data[i+1];
}
thiz->size--; //当前数量-1
darray_shrink(thiz); //检查是否需要缩小内存空间
return RET_OK;
}
7、动态数组 获取指定下标数据函数
####### darray.c #######
Ret darray_get_by_index(DArray* thiz, size_t index, void** data)
{
return_val_if_fail(thiz != NULL && data != NULL && index < thiz->size,
RET_INVALID_PARAMS);
*data = thiz->data[index];
return RET_OK;
}
使用方法:
定义变量,在函数的第三个参数传入该变量地址(由于该动态数组是通用的数据存的是指针,故记得强制类型转换为void**).
此处传入的变量的地址(void **)&data,函数中*data表示指向该变量的数值从而将动态数组的数据赋值给变量(此处给的是void *类型数据,即:thiz->data[index]是void *类型,*data也是void *类型)
####### darray.c #######
Ret darray_set_by_index(DArray* thiz, size_t index, void* data)
{
return_val_if_fail(thiz != NULL && index < thiz->size,
RET_INVALID_PARAMS);
thiz->data[index] = data;
return RET_OK;
}
注意:这边传入的数据同样应该是void*的指针类型,若传入的是其他类型应该强制类型转换为指针类型。
9、动态数组 获取数组数组长度####### darray.c #######
size_t darray_length(DArray* thiz)
{
size_t length = 0;
return_val_if_fail(thiz != NULL, 0);
return thiz->size;
}
用于获取数组对象中size成员.
10、动态数组 遍历访问函数(调用者可用于对遍历数据进行一定操作)####### darray.c #######
Ret darray_foreach(DArray* thiz, DataVisitFunc visit, void* ctx)
{
return_val_if_fail(thiz != NULL && visit != NULL, RET_INVALID_PARAMS);
size_t i = 0;
Ret ret = RET_OK;
for(i = 0; i < thiz->size; i++)
{
ret = visit(ctx, thiz->data[i]);
}
return ret;
}
遍历动态数组数据,以调用者想要的形式进行访问动态数组的数据(使用函数指针决定具体访问类型)
11、动态数组 查找函数(调用者可用于获取对应数据内容)####### darray.c #######
int darray_find(DArray* thiz, DataCompareFunc cmp, void* ctx)
{
size_t i = 0;
return_val_if_fail(thiz != NULL && cmp != NULL, -1);
for(i = 0; i < thiz->size; i++)
{
if(cmp(ctx, thiz->data[i]) == 0)
{
break;
}
}
return i;
}
调用者可根据需要对数据进行比较(使用函数指针)返回指定数据的动态数组下标。
三、动态数组源码及函数功能测试 darray.c#includedarray.h#include "darray.h" #define MIN_PRE_ALLOCATE_NR 10 struct _DArray { void** data; //数据 size_t size; //实际使用数组大小 size_t alloc_size; //已分配数组大小 void* data_destroy_ctx; //销毁函数中上下文变量 DataDestroyFunc data_destroy; //销毁函数指针,为指向销毁函数 }; static void darray_destroy_data(DArray* thiz, void* data) { if(thiz->data_destroy != NULL) { thiz->data_destroy(thiz->data_destroy_ctx, data); } return; } DArray* darray_create(DataDestroyFunc data_destroy, void* ctx) { DArray* thiz = malloc(sizeof(DArray)); if(thiz != NULL) { thiz->data = NULL; thiz->size = 0; thiz->alloc_size = 0; thiz->data_destroy = data_destroy; thiz->data_destroy_ctx = ctx; } return thiz; } static Ret darray_expand(DArray* thiz, size_t need) { return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS); if((thiz->size + need) > thiz->alloc_size) { size_t alloc_size = thiz->alloc_size + (thiz->alloc_size>>1) + MIN_PRE_ALLOCATE_NR; void** data = (void**)realloc(thiz->data, sizeof(void*) * alloc_size); if(data != NULL) { thiz->data = data; thiz->alloc_size = alloc_size; } } return ((thiz->size + need) <= thiz->alloc_size) ? RET_OK : RET_FAIL; } static Ret darray_shrink(DArray* thiz) { return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS); if((thiz->size < (thiz->alloc_size >> 1)) && (thiz->alloc_size > MIN_PRE_ALLOCATE_NR)) { size_t alloc_size = thiz->size + (thiz->size >> 1); void** data = (void**)realloc(thiz->data, sizeof(void*) * alloc_size); if(data != NULL) { thiz->data = data; thiz->alloc_size = alloc_size; } } return RET_OK; } Ret darray_insert(DArray* thiz, size_t index, void* data) { Ret ret = RET_OOM; size_t cursor = index; return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS); cursor = cursor < thiz->size ? cursor : thiz->size; if(darray_expand(thiz, 1) == RET_OK) { size_t i = 0; for(i = thiz->size; i > cursor; i--) { thiz->data[i] = thiz->data[i-1]; } thiz->data[cursor] = data; thiz->size++; ret = RET_OK; } return ret; } Ret darray_prepend(DArray* thiz, void* data) { return darray_insert(thiz, 0, data); } Ret darray_append(DArray* thiz, void* data) { return darray_insert(thiz, -1, data); } Ret darray_delete(DArray* thiz, size_t index) { return_val_if_fail(thiz != NULL && thiz->size > index, RET_INVALID_PARAMS); size_t i = 0; Ret ret = RET_OK; darray_destroy_data(thiz, thiz->data[index]); for(i = index; (i+1) < thiz->size; i++) { thiz->data[i] = thiz->data[i+1]; } thiz->size--; //当前数量-1 darray_shrink(thiz); //检查是否需要缩小内存空间 return RET_OK; } Ret darray_get_by_index(DArray* thiz, size_t index, void** data) { return_val_if_fail(thiz != NULL && data != NULL && index < thiz->size, RET_INVALID_PARAMS); *data = thiz->data[index]; return RET_OK; } Ret darray_set_by_index(DArray* thiz, size_t index, void* data) { return_val_if_fail(thiz != NULL && index < thiz->size, RET_INVALID_PARAMS); thiz->data[index] = data; return RET_OK; } size_t darray_length(DArray* thiz) { size_t length = 0; return_val_if_fail(thiz != NULL, 0); return thiz->size; } Ret darray_foreach(DArray* thiz, DataVisitFunc visit, void* ctx) { return_val_if_fail(thiz != NULL && visit != NULL, RET_INVALID_PARAMS); size_t i = 0; Ret ret = RET_OK; for(i = 0; i < thiz->size; i++) { ret = visit(ctx, thiz->data[i]); } return ret; } int darray_find(DArray* thiz, DataCompareFunc cmp, void* ctx) { size_t i = 0; return_val_if_fail(thiz != NULL && cmp != NULL, -1); for(i = 0; i < thiz->size; i++) { if(cmp(ctx, thiz->data[i]) == 0) { break; } } return i; } void darray_destroy(DArray* thiz) { size_t i = 0; if(thiz != NULL) { for(i = 0; i < thiz->size; i++) { darray_destroy_data(thiz, thiz->data[i]); } SAFE_FREE(thiz->data); SAFE_FREE(thiz); } return; }
#includetypedef.h#include "typedef.h" #ifndef DARRAY_H #define DARRAY_H DECLS_BEGIN struct _DArray; typedef struct _DArray DArray; DArray* darray_create(DataDestroyFunc data_destroy, void* ctx); //创建函数 Ret darray_insert(DArray* thiz, size_t index, void* data); //插入函数 Ret darray_prepend(DArray* thiz, void* data); //插入函数(头插法) Ret darray_append(DArray* thiz, void* data); //插入函数(尾插法) Ret darray_delete(DArray* thiz, size_t index); //删除函数 Ret darray_get_by_index(DArray* thiz, size_t index, void** data); //获取指定下标数据函数 Ret darray_set_by_index(DArray* thiz, size_t index, void* data); //设置指定下标数据函数 size_t darray_length(DArray* thiz); //获取数组长度函数 int darray_find(DArray* thiz, DataCompareFunc cmp, void* ctx); //查找函数 Ret darray_foreach(DArray* thiz, DataVisitFunc visit, void* ctx); //遍历函数 void darray_destroy(DArray* thiz); //销毁函数 DECLS_END #endif
#includemain.c#include #include #ifndef TYPEDEF_H #define TYPEDEF_H typedef enum _Ret { RET_OK, //成功 RET_OOM, //内存溢出 RET_STOP, //暂停 RET_INVALID_PARAMS, //无效参数 RET_FAIL //失败 }Ret; typedef void (*DataDestroyFunc)(void* ctx, void* data); typedef int (*DataCompareFunc)(void* ctx, void* data); typedef Ret (*DataVisitFunc)(void* ctx, void* data); #ifdef __cplusplus #define DECLS_BEGIN extern "C" { #define DECLS_END } #else #define DECLS_BEGIN #define DECLS_END #endif #define return_if_fail(p) if(!(p)) {printf("%s:%d Warning: "#p" failed.n", __func__, __LINE__); return;} #define return_val_if_fail(p, ret) if(!(p)) {printf("%s:%d Warning: "#p" failed.n", __func__, __LINE__); return (ret);} #define SAFE_FREE(p) if(p != NULL) {free(p); p = NULL;} typedef Ret (*SortFunc)(void** array, size_t nr, DataCompareFunc cmp); #endif
#includeMakefile#include #include "darray.h" static int int_cmp(void* ctx, void* data) { return (int)data - (int)ctx; } static Ret print_int(void* ctx, void* data) { printf("%d ", (int)data); return RET_OK; } static Ret check_and_dec_int(void* ctx, void* data) { int* expected =(int*)ctx; assert(*expected == (int)data); (*expected)--; return RET_OK; } #ifdef DARRAY_TEST static void test_int_darray(void) { int i = 0; int n = 10; int data = 00; DArray* darray = darray_create(NULL, NULL); for(i = 0; i < n; i++) { assert(darray_append(darray, (void*)i) == RET_OK); //插入(尾插法) assert(darray_length(darray) == (i + 1)); //获取长度,判断长度正不正常 assert(darray_get_by_index(darray, i, (void**)&data) == RET_OK); //获取数据 assert(data == i); assert(darray_set_by_index(darray, i, (void*)(2*i)) == RET_OK); //设置数据 数据x2 assert(darray_get_by_index(darray, i, (void**)&data) == RET_OK); //获取数据 assert(data == 2*i); assert(darray_set_by_index(darray, i, (void*)i) == RET_OK); //设置数据 设置回去 assert(darray_find(darray, int_cmp, (void*)i) == i); //比较动态数组中存不存在i } for(i = 0; i < n; i++) { assert(darray_get_by_index(darray, 0, (void**)&data) == RET_OK); //获取数据 assert(data == (i)); assert(darray_length(darray) == (n-i)); //获取长度,判断长度正不正常 assert(darray_delete(darray, 0) == RET_OK); //删除动态数组第一个数据 assert(darray_length(darray) == (n-i-1)); //获取长度,判断长度正不正常 if((i + 1) < n) { assert(darray_get_by_index(darray, 0, (void**)&data) == RET_OK);//获取数据 assert((int)data == (i+1)); } } assert(darray_length(darray) == 0); //获取长度,判断长度正不正常,前面有没有删除干净 for(i = 0; i < n; i++) { assert(darray_prepend(darray, (void*)i) == RET_OK); //插入(头插法) assert(darray_length(darray) == (i + 1)); //获取长度,判断长度正不正常 assert(darray_get_by_index(darray, 0, (void**)&data) == RET_OK); //获取数据 assert(data == i); assert(darray_set_by_index(darray, 0, (void*)(2*i)) == RET_OK); //设置数据 数据x2 assert(darray_get_by_index(darray, 0, (void**)&data) == RET_OK); //获取数据 assert(data == 2*i); assert(darray_set_by_index(darray, 0, (void*)i) == RET_OK); //设置数据 设置回去 } i = n - 1; assert(darray_foreach(darray, check_and_dec_int, &i) == RET_OK); darray_destroy(darray); return; } static void test_invalid_params(void) { printf("===========Warning is normal begin==============n"); assert(darray_length(NULL) == 0); assert(darray_prepend(NULL, 0) == RET_INVALID_PARAMS); assert(darray_append(NULL, 0) == RET_INVALID_PARAMS); assert(darray_delete(NULL, 0) == RET_INVALID_PARAMS); assert(darray_insert(NULL, 0, 0) == RET_INVALID_PARAMS); assert(darray_set_by_index(NULL, 0, 0) == RET_INVALID_PARAMS); assert(darray_get_by_index(NULL, 0, NULL) == RET_INVALID_PARAMS); assert(darray_find(NULL, NULL, NULL) < 0); assert(darray_foreach(NULL, NULL, NULL) == RET_INVALID_PARAMS); printf("===========Warning is normal end==============n"); return; } static void single_thread_test(void) { test_int_darray(); test_invalid_params(); return; } #endif int main(int argc, char* argv[]) { int i = 0; int n = 10; int data = 0; #ifdef DARRAY_TEST single_thread_test(); #endif DArray* darray = darray_create(NULL, NULL); //尾插法对动态数组赋值,构建动态数组 for(i = 0; i < n; i++) { darray_append(darray, (void*)i); //插入(尾插法) } darray_foreach(darray,print_int,NULL); //输出动态数组内容 printf("n"); darray_get_by_index(darray, 3, (void**)&data); //获取下标3的数据,存入data遍历 printf("%dn",data); //将获取到的数据进行输出查看 darray_set_by_index(darray, 3, (void*)(6)); //将下标3的数据变为6 darray_foreach(darray,print_int,NULL); //输出动态数组内容 printf("n"); printf("%dn",darray_find(darray, int_cmp, (void*)6)); //查找数据6的下标 printf("%dn",darray_length(darray)); //输出动态数组长度 darray_destroy(darray); return 0; }
CFILES=darray.c main.c all: gcc -m32 -g -DDARRAY_TEST $(CFILES) -o darray_test clean: rm -f *test测试结果:
===========Warning is normal begin============== darray_length:280 Warning: thiz != NULL failed. darray_insert:142 Warning: thiz != NULL failed. darray_insert:142 Warning: thiz != NULL failed. darray_delete:203 Warning: thiz != NULL && thiz->size > index failed. darray_insert:142 Warning: thiz != NULL failed. darray_set_by_index:262 Warning: thiz != NULL && index < thiz->size failed. darray_get_by_index:243 Warning: thiz != NULL && data != NULL && index < thiz->size failed. darray_find:324 Warning: thiz != NULL && cmp != NULL failed. darray_foreach:296 Warning: thiz != NULL && visit != NULL failed. ===========Warning is normal end============== hello0 1 2 3 4 5 6 7 8 9 3 0 1 2 6 4 5 6 7 8 9 3 10



