您的位置:首页 > 编程语言 > C语言/C++

C模板实现STL容器中的vector

2015-08-29 22:12 549 查看

C模板实现STL容器中的vector

最近在工作中因为一直用C语言开发,刚好有点闲时间就准备写一个C的STL作为以后开发使用。因为实习的公司不能上外网,每天晚上再重写一下白天的代码,也确实够苦逼的。话不多说,下面就说说C语言中模板实现的几种方法吧!

1,C语言模板实现技术

1.1 宏替换来实现

C语言中宏是实现很多高级功能的有力武器,其中宏函数可以完成一些比较给力的功能。比如下面这种形式就能实现模板功能。#define test(type) ({\
type m_type;\
})其中在用C中的宏替换的时候一定要记得,宏函数内部定义变量名字的时候一定要尽量使用不常用的或者比较系统的变量命名法则,不然的话由于宏函数只是简单的宏替换,假如在引用宏函数的代码中有一个同样的变量名,则会出现严重错误。

1.2 使用宏函数中的可变参数并且和__VA_ARGS__宏一起结合来实现

宏函数中的可变参数的使用可以确保输入不同的参数类型和不同的参数个数,而__VA_ARGS__宏的使用更是绝妙,该宏可以讲输入参数转化为字符串。然后就可以利用传参进来的字符串来逐一匹配C语言中整个类型库和自定义类型库,这样也能实现不同的类型匹配。具体实现可以参考以下例子:

<span style="font-size:14px;">#define test(...) _creat(#__VA_ARGS__)
vector* _creat(const char* typename)
{
vector* m_vector;
m_vector = malloc(sizeof(vector));
if(typename !=NULL)
{
m_vector->type = get_type(typename);/*获取类型库中的类型*/
}
}</span>我们可以看出这样子比较麻烦,但是有个很好的好处,如果使用这种方法,可以写出来比较健全,可靠地C语言模板类型。其中我在研究了一个开源的C语言开源STL库--cstl库后发现是使用这种方法来实现的,但是很复杂,适合写健壮的代码。而我选择了用第一种宏替换的方法来实现vector容器。

2,vector具体实现代码

下面是具体vector实现代码其中,有些纰漏请多欢迎指正。

/*
**创建者:小巴掌
**创建时间2015/8/20
**代码功能:C实现vector容器
**约定返回0为成功,-1为失败
*/
#ifndef __VECTOR_H__
#define __VECTOR_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>

typedef struct stvector
{
unsigned int mem_len;/*申请的内存长度,单位字节*/
unsigned int user_len;/*已经使用的内存长度,单位字节*/
unsigned int ele_num;/*当前元素个数*/
unsigned int type_len;/*存放数据类型的长度,单位字节*/
void* head;/*数据头指针*/
void* end;/*数据尾指针*/
}vector;

/*
*函数功能:创建vector
*函数参数:
* vec: vec结构指针
* type:传入的存放数据的类型
* len: 初次开辟的元素个数
*/
#define creat(vec,type,len) ({\
int vec_creat_ret = -1;\
if(len >=0)\
{\
vec = (vector*)malloc(sizeof(vector));\
vec->type_len = sizeof(type);\
vec->ele_num = 0;\
vec->user_len = 0;\
vec->mem_len = (len*sizeof(type)*2);\
void* vec_creat_ptr1 = (void*)malloc(vec->mem_len);\
if(ptr == NULL){\
vec_creat_ret = -1;\
}\
vec->head = vec_creat_ptr1;\
vec->end = vec_creat_ptr1;\
vec_creat_ret = 0;\
}\
ret;
})

/*
*函数功能:测试容器是不是已经占满内存
*函数参数:
* vec: vec结构指针
*/
int isfull(vector* vec)
{
int ret = -1;
if((vec->mem_len-vec->user_len)<=(2*vec->type_len)){
ret = 0;
}
return ret;
}
/*
*函数功能:重新开辟更大的空间来存放元素
*函数参数:
* vec: vec结构指针
*/
int resize(vector* vec)
{
int ret = -1;
void* ptr = (void*)malloc(2*vec->mem_len);
if(ptr!=NULL){
memcpy(ptr,vec->head,vec->user_len);
free(vec->head);
vec->head = ptr;
vec->end = vec->head+vec->user_len;
vec->mem_len = 2*vec->mem_len;
ret = 0;
}
return ret;
}
/*
*函数功能:在容器尾部添加元素
*函数参数:
* vec: vec结构指针
* value:所要添加元素,务必要保证元素类型一致
*/
#define push_back(vec,value)({\
int vec_psbk_ret = -1;\
if(vec!=NULL){\
if(isfull(vec) ==0){\
resize(vec);\
}\
memcpy(vec->end;(void*)&value,vec->type_len);\
vec->end +=vec->type_len;\
vec->user_len +=vec->type_len;\
vec->ele_num++;\
vec_psbk_ret = 0;\
}\
vec_ps_bkret;\
})
/*
*函数功能:删除容器尾部的元素
*函数参数:
* vec: vec结构指针
* type:传入的存放数据的类型
*/
#define pop_back(vec,type)({\
int vec_ppbk_ret = -1;\
if(vec->ele_num!=0){\
vec->end -=vec->type_len;\
vec->user_len -= vec->type_len;\
vec->ele_num--;\
vec_ppbk_ret = 0;\
}\
vec_ppbk_ret;\
})
/*
*函数功能:定位位置为i的元素值
*函数参数:
* vec: vec结构指针
* type:传入的存放数据的类型
* i: 在容器中的位置,注意位置是从0开始的
*/
#define at(vec,type,(i))({\
type vec_at_ret;\
if((i)<vec->ele_num && (i)>=0){\
void* vec_at_ptr = vec->end-vec->type_len;\
vec_at_ret = *(type*)vec_at_ptr;\
}\
vec_at_ret;\
})
/*
*函数功能:在位置i处插入元素
*函数参数:
* vec: vec结构指针
* i:在容器中的位置,注意位置是从0开始的
* value: 插入的元素
*/
#define insert(vec,i,value)({\
int vec_inst_ret = -1;\
if(isfull(vec) == 0){\
resize(vec);\
}\
if((i)<=vec->ele_num && (i)>=0){\
void* vec_inst_ptr1 = vec->end+vec->type_len;\
void* vec_inst_ptr2 = vec->end;\
int vec_inst_num =vec->ele_num - (i) -1;\
void* vec_inst_ptr3 = vec->head+((i)*vec->type_len);\
while(vec_inst_num--){\
memcpy(vec_inst_ptr1,vec_inst_ptr2,vec->type_len);\
vec_inst_ptr1 -= vec->type_len;\
vec_inst_ptr2 -= vec->type_len;\
}\
memcpy(vec_inst_ptr3,(void*)&value,vec->type_len);\
vec->user_len += vec->type_len;\
vec->end += vec->type_len;\
vec->ele_num++;\
vec_inst_ret = 0;\
}\
vec_inst_ret;\
})
/*
*函数功能:在位置i处删除元素
*函数参数:
* vec: vec结构指针
* i:删除元素在容器中的位置
*/
#define erase(vec,i)({\
int vec_erase_ret = -1;\
if(vec->ele_num != 0){\
if((i)>=0 && (i)<vec->ele_num){\
void* vec_erase_ptr1 = vec->head + (vec->type_len*(i));\
void* vec_erase_ptr2 = vec_erase_ptr1 + vec->type_len;\
int vec_erase_num = vec->ele_num+(i)+1;\
while(vec_erase_num--){\
memcpy(vec_erase_ptr1,vec_erase_ptr2,vec->type_len);\
vec_erase_ptr1 +=vec->type_len;\
vec_erase_ptr2 +=vec->type_len;\
}\
vec->ele_num--;\
vec->user_len -= vec->type_len;\
vec->end -= vec->type_len;\
}\
}\
vec_erase_ret;\
})
/*
*函数功能:返回容器当前第一个元素的值
*函数参数:
* vec: vec结构指针
* type:传入的存放数据的类型
* 返回值:该类型的元素
*/
#define front(vec,type)({\
type vec_front_ret;\
if(vec->ele_num != 0){\
vec_front_ret = at(vec, type, 0);\
}\
vec_front_ret;\
})
/*
*函数功能:返回容器尾部的元素
*函数参数:
* vec: vec结构指针
* type:传入的存放数据的类型
* 返回值:该类型的元素
*/
#define back(vec,type)({\
type vec_back_ret;\
if(vec->ele_num !=0){\
vec_back_ret = at(vec,type,(vec->ele_num-1));\
}\
vec_back_ret;\
})
/*
*函数功能:返回容器内申请的最大元素个数
*函数参数:
* vec: vec结构指针
*/
int capacity(vector* vec)
{
int ret = 0;
if(vec != NULL)
ret = vec->mem_len/vec->type_len;
return ret;
}
/*
*函数功能:返回当前容器内元素个数
*函数参数:
* vec: vec结构指针
*/
int size(vector* vec)
{
int ret = 0;
if(vec !=NULL)
ret = vec->user_len / vec->type_len;
return ret;
}
/*
*函数功能:清除vector中所有元素
*函数参数:
* vec: vec结构指针
*/
int clear(vector* vec)
{
int ret = -1;
if(vec !=NULL)
{
free(vec->head);
vec->ele_num = 0;
vec->end = vec->head;
vec->user_len = 0;
}
r
8e23
eturn ret;
}
/*
*函数功能:返回迭代容器首位置
*函数参数:
* vec: vec结构指针
*/
int begin(vector* vec)
{
return 0;
}
/*
*函数功能:返回迭代器容器中尾位置
*函数参数:
* vec: vec结构指针
*/
int end(vector* vec)
{
return (vec->ele_num-1);
}
#ifdef __cplusplus
}
#endif
其中代码中对输入参数还有判断不完全的情况,欢迎对代码订正。下一次将会实现STL中栈的实现。期待与你见面。

写代码其实就好比在谈恋爱,为自己加油!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 stl