|  |  |  | @ -1,251 +1,250 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #ifndef ARRAY_INCLUDED | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include<assert.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include<malloc.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include<stdlib.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include<string.h> | 
			
		
	
		
			
				
					|  |  |  |  | /*带有assert的安全分配内存*/ | 
			
		
	
		
			
				
					|  |  |  |  | void *malloc_s(int _size){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert(_size > 0); | 
			
		
	
		
			
				
					|  |  |  |  |     void *malloc_ptr = malloc(_size); | 
			
		
	
		
			
				
					|  |  |  |  |     assert(malloc_ptr != NULL); | 
			
		
	
		
			
				
					|  |  |  |  |     return malloc_ptr; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*字符串变量的创建与复制*/ | 
			
		
	
		
			
				
					|  |  |  |  | char *malloc_s_strcpy(const char *const src){ | 
			
		
	
		
			
				
					|  |  |  |  |     //申请char[]时需要多分配几个位置用于存放'\0'结束符
 | 
			
		
	
		
			
				
					|  |  |  |  |     char *dst = malloc_s(strlen(src)+2); | 
			
		
	
		
			
				
					|  |  |  |  |     strcpy(dst, src); | 
			
		
	
		
			
				
					|  |  |  |  |     return dst; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*MARCO:根据类型安全分配内存*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName))) | 
			
		
	
		
			
				
					|  |  |  |  | /*链表单元*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array_{ | 
			
		
	
		
			
				
					|  |  |  |  |     void *p; /*内容数据*/ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *next; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*通过单向链表实现的动态数组,需要指定内置数据的类型*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array{ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *front, *back; /*头尾节点*/ | 
			
		
	
		
			
				
					|  |  |  |  |     int TypeSize;   /*内置类型的大小(不包含动态数据的纯大小)*/ | 
			
		
	
		
			
				
					|  |  |  |  |     int size;       /*总体大小*/ | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*链表初始化*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_create(struct Array *a, int ts) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_create" && ts > 0); | 
			
		
	
		
			
				
					|  |  |  |  |     a->TypeSize = ts; | 
			
		
	
		
			
				
					|  |  |  |  |     a->size = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     a->back = a->front = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     if(a == back) return ; | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release_(a->next, back, rel); | 
			
		
	
		
			
				
					|  |  |  |  |     rel(a->p); | 
			
		
	
		
			
				
					|  |  |  |  |     free(a->p); | 
			
		
	
		
			
				
					|  |  |  |  |     free(a); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*释放动态分配的内存,需要指定释放内部动态成员的方法*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_release(struct Array *a, void (*rel)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release_(a->front, a->back, rel); | 
			
		
	
		
			
				
					|  |  |  |  |     a->size = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     a->back = a->front = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*返回指定位置的Array_*指针
 | 
			
		
	
		
			
				
					|  |  |  |  | 配合PAT宏获取内部数据*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array_ *Array(struct Array *a, int pos){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array[pos]" && pos >= 0 && pos < a->size); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *node = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |     for(int i = 0; i < pos; i ++) node = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |     return node; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*在pos前插入*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_insert(struct Array *a, void *p, int pos) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_insert" && pos >= 0 && pos <= a->size); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *newNode, *node = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |     newNode = MALLOC_S(struct Array_); | 
			
		
	
		
			
				
					|  |  |  |  |     newNode->p = malloc_s(a->TypeSize); | 
			
		
	
		
			
				
					|  |  |  |  |     memcpy(newNode->p, p, a->TypeSize); | 
			
		
	
		
			
				
					|  |  |  |  |     if(pos == 0){ | 
			
		
	
		
			
				
					|  |  |  |  |         newNode->next = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |         a->front = newNode; | 
			
		
	
		
			
				
					|  |  |  |  |     }else{ | 
			
		
	
		
			
				
					|  |  |  |  |         for(int i = 0; i < pos-1; i ++) node = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         newNode->next = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         node->next = newNode; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     a->size += 1; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*删除pos位置的Array_节点*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_delete_pos(struct Array *a, int pos, void (*rel_)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *node = a->front, *freeNode; | 
			
		
	
		
			
				
					|  |  |  |  |     if(pos == 0){ | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |         a->front = a->front->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     }else{ | 
			
		
	
		
			
				
					|  |  |  |  |         for(int i = 0; i < pos-1; i ++) node = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         node->next = node->next->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     a->size--; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*删除node所指向的Array节点*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_delete_p(struct Array *a, struct Array_ *node, void (*rel_)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_delete_p" && node != a->back); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *freeNode; | 
			
		
	
		
			
				
					|  |  |  |  |     if(node == a->front){ | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |         a->front = a->front->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     }else{ | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         node->next = node->next->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     a->size--; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*交换内容,即p指针*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array__swap(struct Array_ *a, struct Array_ *b){ | 
			
		
	
		
			
				
					|  |  |  |  |     void *t = b->p; | 
			
		
	
		
			
				
					|  |  |  |  |     b->p = a->p; | 
			
		
	
		
			
				
					|  |  |  |  |     a->p = t; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  | 带有reverse选项的冒泡排序,默认(reverse == 0)是升序 | 
			
		
	
		
			
				
					|  |  |  |  | func(a,b)为排序所依据的比较函数 | 
			
		
	
		
			
				
					|  |  |  |  | a>b:>0 | 
			
		
	
		
			
				
					|  |  |  |  | a==b:0 | 
			
		
	
		
			
				
					|  |  |  |  | a < b:<0 | 
			
		
	
		
			
				
					|  |  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){ | 
			
		
	
		
			
				
					|  |  |  |  |     reverse = reverse ? -1 : 1; | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *sorted = a->back, *p; | 
			
		
	
		
			
				
					|  |  |  |  |     while(a->front->next != sorted){ | 
			
		
	
		
			
				
					|  |  |  |  |         for(p = a->front; p->next != sorted; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |             if(reverse*func(p->p,p->next->p) > 0) | 
			
		
	
		
			
				
					|  |  |  |  |                 Array__swap(p, p->next); | 
			
		
	
		
			
				
					|  |  |  |  |         sorted = p; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*指定类型 转换(void)Array.p中的内容*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p) | 
			
		
	
		
			
				
					|  |  |  |  | /*链表的遍历*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  | /*链表指定类型的初始化*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define DEF_ARRAY(Type, name)  | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void DoNothing(){} | 
			
		
	
		
			
				
					|  |  |  |  | /*记录每Array容器对象的信息*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct ArrayObjects{ | 
			
		
	
		
			
				
					|  |  |  |  |     void *p_obj;    /*Array对象的地址*/ | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*为每一个Array容器类实现释放管理*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct ArrayClass{ | 
			
		
	
		
			
				
					|  |  |  |  |     char *TypeName;     /*容器内置类型的名称*/ | 
			
		
	
		
			
				
					|  |  |  |  |     void (*rel_)(void *);/*释放Array对象内部单个元素数据的方式*/ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array objects;/*该内置类型所有Array对象的信息*/ | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*存储所有Array容器类*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array ArrayList; | 
			
		
	
		
			
				
					|  |  |  |  | /*以TypeName注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayClass_Reg(char *TypeName, void (*Rel__Func)(void *p)){ | 
			
		
	
		
			
				
					|  |  |  |  |     struct ArrayClass ac; | 
			
		
	
		
			
				
					|  |  |  |  |     ac.TypeName = malloc_s_strcpy(TypeName); | 
			
		
	
		
			
				
					|  |  |  |  |     ac.rel_ = Rel__Func; | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ac.objects, sizeof(struct ArrayObjects)); | 
			
		
	
		
			
				
					|  |  |  |  |     Array_insert(&ArrayList, &ac, 0); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*向给定TypName的ArrayClass注册一个新的对象,对象地址为p_obj*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayObj_Reg(char *TypeName, void *p_obj){ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *p; | 
			
		
	
		
			
				
					|  |  |  |  |     for(p = ArrayList.front; p != ArrayList.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |         if(strcmp(((struct ArrayClass*)p->p)->TypeName, TypeName) == 0) | 
			
		
	
		
			
				
					|  |  |  |  |             break; | 
			
		
	
		
			
				
					|  |  |  |  |     Array_insert((&((struct ArrayClass*)p->p)->objects), &(struct ArrayObjects){p_obj}, 0); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /*释放ArrayList中单个元素占用的资源*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayList_Rel_(void *p_class){ | 
			
		
	
		
			
				
					|  |  |  |  |     free(((struct ArrayClass *)p_class)->TypeName); | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release(&((struct ArrayClass *)p_class)->objects, DoNothing); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*初始化Array_List*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayList_Init(){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ArrayList, sizeof(struct ArrayClass)); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*释放ArrayList占用的资源*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayList_Rel(){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release(&ArrayList, ArrayList_Rel_); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*主动提前释放资源,对于局部变量,需要在其被编译器释放前主动释放占用资源,防止内存泄漏*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_Obj_PreRelease(struct Array *unrel_obj){ | 
			
		
	
		
			
				
					|  |  |  |  |     for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |         for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) | 
			
		
	
		
			
				
					|  |  |  |  |             if(unrel_obj == ((struct ArrayObjects*)q->p)->p_obj){ | 
			
		
	
		
			
				
					|  |  |  |  |                 printf("%s\n", ((struct ArrayClass *)p->p)->TypeName); | 
			
		
	
		
			
				
					|  |  |  |  |                 Array_release(unrel_obj, ((struct ArrayClass *)p->p)->rel_); | 
			
		
	
		
			
				
					|  |  |  |  |                 Array_delete_p(&((struct ArrayClass *)p->p)->objects, q, DoNothing); | 
			
		
	
		
			
				
					|  |  |  |  |                 return ; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_Obj_PreRelease:NotFound"); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*根据ArrayObj反查ArrayClass*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct ArrayClass *ArrayList_Find_Class_From_Obj(struct Array *a){ | 
			
		
	
		
			
				
					|  |  |  |  |     for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |         for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) | 
			
		
	
		
			
				
					|  |  |  |  |             if(a == ((struct ArrayObjects*)q->p)->p_obj) | 
			
		
	
		
			
				
					|  |  |  |  |                 return (struct ArrayClass *)p->p; | 
			
		
	
		
			
				
					|  |  |  |  |     assert("ArrayList_Find_Class_From_Obj:NotFound"); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*重写简化的Array_delete*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_deletepos(struct Array *a, int pos){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_delete_pos(a, pos, ArrayList_Find_Class_From_Obj(a)->rel_); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | void Array_deletep(struct Array *a, struct Array_ *node){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_delete_p(a, node, ArrayList_Find_Class_From_Obj(a)->rel_); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*MARCO:为Type注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define DECLARE_ARRAY(Type, RelFunc) ArrayClass_Reg(#Type, RelFunc); | 
			
		
	
		
			
				
					|  |  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  | MARCO:为内置类型为Type的ArrayClass创建一个新的对象,名称为ArrName | 
			
		
	
		
			
				
					|  |  |  |  | Example: | 
			
		
	
		
			
				
					|  |  |  |  | struct ARRAY(a, struct A); | 
			
		
	
		
			
				
					|  |  |  |  | ^^^^^^___________________^ | 
			
		
	
		
			
				
					|  |  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  |  | #define ARRAY(ArrName, Type)                            \ | 
			
		
	
		
			
				
					|  |  |  |  |     Array ArrName;                                      \ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ArrName, sizeof(Type));               \ | 
			
		
	
		
			
				
					|  |  |  |  |     ArrayObj_Reg(#Type, &ArrName) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #define ARRAY_BIND(ArrName, Type)                       \ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ArrName, sizeof(Type));               \ | 
			
		
	
		
			
				
					|  |  |  |  |     ArrayObj_Reg(#Type, &ArrName); | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  | Example: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct A{ | 
			
		
	
		
			
				
					|  |  |  |  |     int a; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | void rel_(void*p){} | 
			
		
	
		
			
				
					|  |  |  |  | int main(){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_Class_Init(); | 
			
		
	
		
			
				
					|  |  |  |  |     DECLARE_ARRAY(struct A, rel_) | 
			
		
	
		
			
				
					|  |  |  |  |     struct ARRAY(a, struct A); | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     Array_Obj_PreRelease(&a); | 
			
		
	
		
			
				
					|  |  |  |  |     Array_Class_Rel(); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | #ifndef ARRAY_INCLUDED | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include<assert.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include<malloc.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include<stdlib.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include<string.h> | 
			
		
	
		
			
				
					|  |  |  |  | /*带有assert的安全分配内存*/ | 
			
		
	
		
			
				
					|  |  |  |  | void *malloc_s(int _size){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert(_size > 0); | 
			
		
	
		
			
				
					|  |  |  |  |     void *malloc_ptr = malloc(_size); | 
			
		
	
		
			
				
					|  |  |  |  |     assert(malloc_ptr != NULL); | 
			
		
	
		
			
				
					|  |  |  |  |     return malloc_ptr; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*字符串变量的创建与复制*/ | 
			
		
	
		
			
				
					|  |  |  |  | char *malloc_s_strcpy(const char *const src){ | 
			
		
	
		
			
				
					|  |  |  |  |     //申请char[]时需要多分配几个位置用于存放'\0'结束符
 | 
			
		
	
		
			
				
					|  |  |  |  |     char *dst = malloc_s(strlen(src)+2); | 
			
		
	
		
			
				
					|  |  |  |  |     strcpy(dst, src); | 
			
		
	
		
			
				
					|  |  |  |  |     return dst; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*MARCO:根据类型安全分配内存*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName))) | 
			
		
	
		
			
				
					|  |  |  |  | /*链表单元*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array_{ | 
			
		
	
		
			
				
					|  |  |  |  |     void *p; /*内容数据*/ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *next; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*通过单向链表实现的动态数组,需要指定内置数据的类型*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array{ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *front, *back; /*头尾节点*/ | 
			
		
	
		
			
				
					|  |  |  |  |     int TypeSize;   /*内置类型的大小(不包含动态数据的纯大小)*/ | 
			
		
	
		
			
				
					|  |  |  |  |     int size;       /*总体大小*/ | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*链表初始化*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_create(struct Array *a, int ts) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_create" && ts > 0); | 
			
		
	
		
			
				
					|  |  |  |  |     a->TypeSize = ts; | 
			
		
	
		
			
				
					|  |  |  |  |     a->size = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     a->back = a->front = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     if(a == back) return ; | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release_(a->next, back, rel); | 
			
		
	
		
			
				
					|  |  |  |  |     rel(a->p); | 
			
		
	
		
			
				
					|  |  |  |  |     free(a->p); | 
			
		
	
		
			
				
					|  |  |  |  |     free(a); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*释放动态分配的内存,需要指定释放内部动态成员的方法*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_release(struct Array *a, void (*rel)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release_(a->front, a->back, rel); | 
			
		
	
		
			
				
					|  |  |  |  |     a->size = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     a->back = a->front = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*返回指定位置的Array_*指针
 | 
			
		
	
		
			
				
					|  |  |  |  | 配合PAT宏获取内部数据*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array_ *Array(struct Array *a, int pos){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array[pos]" && pos >= 0 && pos < a->size); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *node = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |     for(int i = 0; i < pos; i ++) node = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |     return node; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*在pos前插入*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_insert(struct Array *a, void *p, int pos) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_insert" && pos >= 0 && pos <= a->size); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *newNode, *node = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |     newNode = MALLOC_S(struct Array_); | 
			
		
	
		
			
				
					|  |  |  |  |     newNode->p = malloc_s(a->TypeSize); | 
			
		
	
		
			
				
					|  |  |  |  |     memcpy(newNode->p, p, a->TypeSize); | 
			
		
	
		
			
				
					|  |  |  |  |     if(pos == 0){ | 
			
		
	
		
			
				
					|  |  |  |  |         newNode->next = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |         a->front = newNode; | 
			
		
	
		
			
				
					|  |  |  |  |     }else{ | 
			
		
	
		
			
				
					|  |  |  |  |         for(int i = 0; i < pos-1; i ++) node = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         newNode->next = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         node->next = newNode; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     a->size += 1; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*删除pos位置的Array_节点*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_delete_pos(struct Array *a, int pos, void (*rel_)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *node = a->front, *freeNode; | 
			
		
	
		
			
				
					|  |  |  |  |     if(pos == 0){ | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |         a->front = a->front->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     }else{ | 
			
		
	
		
			
				
					|  |  |  |  |         for(int i = 0; i < pos-1; i ++) node = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         node->next = node->next->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     a->size--; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*删除node所指向的Array节点*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_delete_p(struct Array *a, struct Array_ *node, void (*rel_)(void *)){ | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_delete_p" && node != a->back); | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *freeNode; | 
			
		
	
		
			
				
					|  |  |  |  |     if(node == a->front){ | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = a->front; | 
			
		
	
		
			
				
					|  |  |  |  |         a->front = a->front->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     }else{ | 
			
		
	
		
			
				
					|  |  |  |  |         freeNode = node->next; | 
			
		
	
		
			
				
					|  |  |  |  |         node->next = node->next->next; | 
			
		
	
		
			
				
					|  |  |  |  |         rel_(freeNode->p); | 
			
		
	
		
			
				
					|  |  |  |  |         free(freeNode); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     a->size--; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*交换内容,即p指针*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array__swap(struct Array_ *a, struct Array_ *b){ | 
			
		
	
		
			
				
					|  |  |  |  |     void *t = b->p; | 
			
		
	
		
			
				
					|  |  |  |  |     b->p = a->p; | 
			
		
	
		
			
				
					|  |  |  |  |     a->p = t; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  | 带有reverse选项的冒泡排序,默认(reverse == 0)是升序 | 
			
		
	
		
			
				
					|  |  |  |  | func(a,b)为排序所依据的比较函数 | 
			
		
	
		
			
				
					|  |  |  |  | a>b:>0 | 
			
		
	
		
			
				
					|  |  |  |  | a==b:0 | 
			
		
	
		
			
				
					|  |  |  |  | a < b:<0 | 
			
		
	
		
			
				
					|  |  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){ | 
			
		
	
		
			
				
					|  |  |  |  |     reverse = reverse ? -1 : 1; | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *sorted = a->back, *p; | 
			
		
	
		
			
				
					|  |  |  |  |     while(a->front->next != sorted){ | 
			
		
	
		
			
				
					|  |  |  |  |         for(p = a->front; p->next != sorted; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |             if(reverse*func(p->p,p->next->p) > 0) | 
			
		
	
		
			
				
					|  |  |  |  |                 Array__swap(p, p->next); | 
			
		
	
		
			
				
					|  |  |  |  |         sorted = p; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*指定类型 转换(void)Array.p中的内容*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p) | 
			
		
	
		
			
				
					|  |  |  |  | /*链表的遍历*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  | /*链表指定类型的初始化*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define DEF_ARRAY(Type, name)  | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void DoNothing(){} | 
			
		
	
		
			
				
					|  |  |  |  | /*记录每Array容器对象的信息*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct ArrayObjects{ | 
			
		
	
		
			
				
					|  |  |  |  |     void *p_obj;    /*Array对象的地址*/ | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*为每一个Array容器类实现释放管理*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct ArrayClass{ | 
			
		
	
		
			
				
					|  |  |  |  |     char *TypeName;     /*容器内置类型的名称*/ | 
			
		
	
		
			
				
					|  |  |  |  |     void (*rel_)(void *);/*释放Array对象内部单个元素数据的方式*/ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array objects;/*该内置类型所有Array对象的信息*/ | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | /*存储所有Array容器类*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct Array ArrayList; | 
			
		
	
		
			
				
					|  |  |  |  | /*以TypeName注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayClass_Reg(char *TypeName, void (*Rel__Func)(void *p)){ | 
			
		
	
		
			
				
					|  |  |  |  |     struct ArrayClass ac; | 
			
		
	
		
			
				
					|  |  |  |  |     ac.TypeName = malloc_s_strcpy(TypeName); | 
			
		
	
		
			
				
					|  |  |  |  |     ac.rel_ = Rel__Func; | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ac.objects, sizeof(struct ArrayObjects)); | 
			
		
	
		
			
				
					|  |  |  |  |     Array_insert(&ArrayList, &ac, 0); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*向给定TypName的ArrayClass注册一个新的对象,对象地址为p_obj*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayObj_Reg(char *TypeName, void *p_obj){ | 
			
		
	
		
			
				
					|  |  |  |  |     struct Array_ *p; | 
			
		
	
		
			
				
					|  |  |  |  |     for(p = ArrayList.front; p != ArrayList.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |         if(strcmp(((struct ArrayClass*)p->p)->TypeName, TypeName) == 0) | 
			
		
	
		
			
				
					|  |  |  |  |             break; | 
			
		
	
		
			
				
					|  |  |  |  |     Array_insert((&((struct ArrayClass*)p->p)->objects), &(struct ArrayObjects){p_obj}, 0); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /*释放ArrayList中单个元素占用的资源*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayList_Rel_(void *p_class){ | 
			
		
	
		
			
				
					|  |  |  |  |     free(((struct ArrayClass *)p_class)->TypeName); | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release(&((struct ArrayClass *)p_class)->objects, DoNothing); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*初始化Array_List*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayList_Init(){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ArrayList, sizeof(struct ArrayClass)); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*释放ArrayList占用的资源*/ | 
			
		
	
		
			
				
					|  |  |  |  | void ArrayList_Rel(){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_release(&ArrayList, ArrayList_Rel_); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*主动提前释放资源,对于局部变量,需要在其被编译器释放前主动释放占用资源,防止内存泄漏*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_Obj_PreRelease(struct Array *unrel_obj){ | 
			
		
	
		
			
				
					|  |  |  |  |     for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |         for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) | 
			
		
	
		
			
				
					|  |  |  |  |             if(unrel_obj == ((struct ArrayObjects*)q->p)->p_obj){ | 
			
		
	
		
			
				
					|  |  |  |  |                 Array_release(unrel_obj, ((struct ArrayClass *)p->p)->rel_); | 
			
		
	
		
			
				
					|  |  |  |  |                 Array_delete_p(&((struct ArrayClass *)p->p)->objects, q, DoNothing); | 
			
		
	
		
			
				
					|  |  |  |  |                 return ; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |     assert("Array_Obj_PreRelease:NotFound"); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*根据ArrayObj反查ArrayClass*/ | 
			
		
	
		
			
				
					|  |  |  |  | struct ArrayClass *ArrayList_Find_Class_From_Obj(struct Array *a){ | 
			
		
	
		
			
				
					|  |  |  |  |     for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) | 
			
		
	
		
			
				
					|  |  |  |  |         for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) | 
			
		
	
		
			
				
					|  |  |  |  |             if(a == ((struct ArrayObjects*)q->p)->p_obj) | 
			
		
	
		
			
				
					|  |  |  |  |                 return (struct ArrayClass *)p->p; | 
			
		
	
		
			
				
					|  |  |  |  |     assert("ArrayList_Find_Class_From_Obj:NotFound"); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*重写简化的Array_delete*/ | 
			
		
	
		
			
				
					|  |  |  |  | void Array_deletepos(struct Array *a, int pos){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_delete_pos(a, pos, ArrayList_Find_Class_From_Obj(a)->rel_); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | void Array_deletep(struct Array *a, struct Array_ *node){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_delete_p(a, node, ArrayList_Find_Class_From_Obj(a)->rel_); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | /*MARCO:为Type注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ | 
			
		
	
		
			
				
					|  |  |  |  | #define DECLARE_ARRAY(Type, RelFunc) ArrayClass_Reg(#Type, RelFunc); | 
			
		
	
		
			
				
					|  |  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  | MARCO:为内置类型为Type的ArrayClass创建一个新的对象,名称为ArrName | 
			
		
	
		
			
				
					|  |  |  |  | Example: | 
			
		
	
		
			
				
					|  |  |  |  | struct ARRAY(a, struct A); | 
			
		
	
		
			
				
					|  |  |  |  | ^^^^^^___________________^ | 
			
		
	
		
			
				
					|  |  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  |  | #define ARRAY(ArrName, Type)                            \ | 
			
		
	
		
			
				
					|  |  |  |  |     Array ArrName;                                      \ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ArrName, sizeof(Type));               \ | 
			
		
	
		
			
				
					|  |  |  |  |     ArrayObj_Reg(#Type, &ArrName) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #define ARRAY_BIND(ArrName, Type)                       \ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_create(&ArrName, sizeof(Type));               \ | 
			
		
	
		
			
				
					|  |  |  |  |     ArrayObj_Reg(#Type, &ArrName); | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  | Example: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct A{ | 
			
		
	
		
			
				
					|  |  |  |  |     int a; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | void rel_(void*p){} | 
			
		
	
		
			
				
					|  |  |  |  | int main(){ | 
			
		
	
		
			
				
					|  |  |  |  |     Array_Class_Init(); | 
			
		
	
		
			
				
					|  |  |  |  |     DECLARE_ARRAY(struct A, rel_) | 
			
		
	
		
			
				
					|  |  |  |  |     struct ARRAY(a, struct A); | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     Array_Obj_PreRelease(&a); | 
			
		
	
		
			
				
					|  |  |  |  |     Array_Class_Rel(); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | #define ARRAY_INCLUDED |