仓库: https://github.com/THZrry/Marco-C-Utils
起因
起因是我写一个代码到处都是内存错误,心烦意乱,跑过来写点C的Vector。 但目前我见到的C的Vector都太重了,于是将这个仅包含宏的vector发出来,并准备往里面加些别的内容。
如何?
C里面定义宏函数很简单,如下:
#define func(arg) {function-body}
有一些括号和do{}while(0)
的技巧在此不细说。总之,宏是在汇编之前完成的,所以不需要类型检查,可以干出很多魔法。比如lw_oopc
就是一个,用宏在C里面模拟出了面向对象。其改进版甚至支持继承、接口等高级功能(封装和动态忘了能不能)。可以看出,宏还是很强的。
而动态内存的写法也很模板化:
// crating
type *array = (type*)malloc(length * sizeof type);
if (array == NULL){
// ERROR handler
}
扩容也一样:
// expanding
type *new_array = (type*)realloc(array, length * sizeof type);
if (new_array == NULL){
// ERROR handler
}
array = new_array;
new_array = NULL ; // clearing
没用了的指针记得归零。
用完后:
free(array);
就这样,可以提取出模板化的表达:
int num = 1;
Vector(int) array = New_vector(int); // 这里由于写不出没做判断
Vector_push_back(array, num);
宏展开后大概长这样(已去除多余括号):
int num = 1;
// Vector(type) array = New_vector(int);
int* array = (int*)malloc(sizeof int);
// Vector_push_back(array, num);
int* new_array = (int*)realloc(array, 1 * sizeof int);
array = new_array;
new_array = NULL ;
array[0] = num ;
但如果要做成vector的化需要记得长度,我选择多calloc(初值设0)一个,并拿嘴左端内存的sizeof int(4字节)存储。
写完后就是那个样子,不长,就百来行。我摘了C的部分放这里,可以自行复制(原版有条件编译在C++时直接调用STL里面的)大部分注释也去掉了:
/*
(此处的用法已去。
Lisence: WTFPL
Author : THZrry(github.com/THZrry)
*/
#ifndef _MVECTOR_
#define _MVECTOR_
// 此处C++判断已去。
#include <malloc.h>
#define _Vector_GetMacro(_1,_2,NAME,...) NAME
#define Vector(type) type*
#define New_vector(type) ((type*)calloc(1,sizeof(type))+1)
#define Vector_size(vector) (*(int*)(vector-1))
#define Vector_empty(vector) (Vector_size(vector)>0)
#define Vector_push_back(vector,x) do{ \
typeof(vector) new_vector = (typeof(vector))realloc(vector-1,(Vector_size(vector)+2)*(sizeof *vector)); \
vector = new_vector+1; \
Vector_size(vector)++; \
vector[Vector_size(vector)-1] = x; \
}while(0)
#define Vector_insert(vector,index,x) do{ \
vector = (typeof(vector))realloc(vector-1, Vector_size(vector)++*(sizeof *vector))+1; \
for (int i=Vector_size(vector); i>index; --i) \
vector[i] = vector[i-1]; \
vector[index] = x; \
}while(0)
#define Vector__erase1(vector,index) do{ \
for (int i=index+1; i<Vector_size(vector); i++) \
vector[i-1] = vector[i]; \
vector = (typeof(vector))realloc(vector-1, Vector_size(vector)--*(sizeof *vector))+1; \
}while(0)
#define Vector__erase2(vector,first,last) do{ \
int gap=last-first, i, j; \
for (i=last; i<Vector_size(vector); i++) \
vector[i-gap] = vector[i]; \
Vector_size(vector) -= gap; \
vector = (typeof(vector))realloc(vector-1, Vector_size(vector)*(sizeof *vector))+1; \
}while(0)
#define Vector_erase(vector,...) _Vector_GetMacro(__VA_ARGS__, Vector__erase2, Vector__erase1, ...)(vector, __VA_ARGS__)
#define Vector_pop_back(vector) Vector_erase(vector, Vector_size(vector)-1)
#define Vector_clear(vector) do{ \
vector = (typeof(vector))realloc(vector-1, sizeof *vector)+1; \
Vector_size(vector) = 0; \
}while(0)
#define Vector_at(vector,pos) (vector+pos)
#define Vector_begin(vector) Vector_at(vector, 0)
#define Vector_end(vector) Vector_at(vector, Vector_size(vector)-1)
#define Vector_front(vector) Vector_at(vector, 0)
#define Vector_back(vector) Vector_at(vector, Vector_size(vector)-1)
#define Vector_release(vector) (free(vector-1))
#endif
可以自己取走用,开源协议是WTFPL,随便用。
(其实我本来还要写点的,但是要开学了,最近都不会更新喽
CSDN,2024/2/20 21:25