[Vector] 纯C语言用宏实现简单STL Vector

文章目录


仓库: 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

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值