我们这里说的vector是之C++语言中的Vector.vector 是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结果和算法的模板类和函数库,vector是一个容器,他能够存放各种类型的对象,简单的说,vetor是一个能够存放任何数据类型的动态数组,可以动态改变内存大小。
方法 | 说明 |
---|---|
clear() | 移除容器中所有数据。 |
empty() | 判断容器是否为空 |
erase(pos) | 删除pos位置的数据 |
erase(beg,end) | 删除[beg,end)区间的数据 |
front() | 传回第一个数据。 |
insert(pos,elem) | 在pos位置插入一个elem拷贝 |
pop_back() | 删除最后一个数据。 |
push_back(elem) | 在尾部加入一个数据。 |
resize(num) | 重新设置该容器的大小 |
size() | 回容器中实际数据的个数。 |
begin() | 返回指向容器第一个元素的迭代器 |
end() | 返回指向容器最后一个元素的迭代器 |
在这里我看到了C++中常用的方法,那么我们现在为让老死党C语言也同样拥有这样强大的能力,那么我们遍开始构建属于自己的vector.这里我们使用前面一篇文章给出的c语言基类cssObj来创建这个Vector。(这里我只是简单给出几个常用的方法出来,如有不对的地方请指教,小弟小白一枚)。在写一个数据结构之前,我们首先需要知道这个数据结构的内存模型是怎样的。
vector的内存结构有点像栈的内存结构,先进后出.我们可以从上面的方法表中可以看到,pop_back() 方法和push_back()方法中可以看出,其最基本的内存模型是栈结构。
这里我们使用面向对象的继承特性,继承基类的所有基本操作。
详细可以参考我前面的文章C语言面向对象之基类
我们废话少说直接上代码(这里只实现的部分功能)
/*
* cssVector.h
*
* Created on: 2017年10月18日
* Author: JasonHuo
*/
#ifndef SECURITY_CSSVECTOR_H_
#define SECURITY_CSSVECTOR_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "cssObject.h"
//////////////////////////
// stl容器类方法返回值 //
//////////////////////////
#define VEC_RET_SUCCESS 1 ///返回成功
#define VEC_RET_FAILD 0 ///返回失败
/******************************************************************************
@bref STL容器类,因为我们的伟大的C语言中没有写出我们常用的动态容器,为了更好的使用内存,我在这里
参照C++版本的vector创建的 cssVector类。该容器类可以存放任何类型的个的参数。只要在初始类的时候
告诉类你需要存放的类的内存大小就可以了,可以使用sizeof()函数获取类型大小便可。尤为强大的是,
cssVector会内存自增长。不过尤为遗憾的是,我这里只实现了几个我常用到的方法,如果你想获取更强大
的功能可以继承我这个类来创建更加强大的vector。
该类是采用css宏定义类架构编写,继承与基类。创建该类后在生命周期结束时需要手动调用基类的个
Release方法
-------------------------------------------------------------------------------
@param
--------
int mSize 容器中元素的个数
int mMaxSize 该容器最大存储元素的个数
int mTypeSize 该容器存储元素的类型,内存大小
int _mUsedMemLen 该容器已经使用的内存长度
int _mMemLen 该容器拥有的内存长度
void *_mHead 该容器的元素头指针
void *_mEnd 该容器的元素尾指针
-------------------------------------------------------------------------------
@fun
--------
checkPicketLine 警戒线检测函数
vecIsFull 判断容器是否已经满
vecRresize 容器自身内存扩大两倍函数
vecPush_back 向容器的尾部添加一个元素
vecPop_back 从容器的尾部删除一个元素
vecAt 访问容器 index 位置的个元素。可读写
vecClear 将容器原本所有内存清楚,从新让容器获取只能存放一个元素的内存
vecModifyAt 修改容器 index 位置的元素内容
*******************************************************************************/
#define cssVectorFields(TYPE) \
cssObjectFields(TYPE) \
int mSize; \
int mMaxSize; \
int mTypeSize; \
int _mUsedMemLen; \
int _mMemLen; \
void *_mHead; \
void *_mEnd;\
void(*onCssObjectDelloc)(TYPE _this); \
int (*vecIsFull)(TYPE _this); \
int (*vecRresize)(TYPE _this); \
int (*vecPush_back)(TYPE _this,void *pValue); \
int (*vecPop_back)(TYPE _this); \
void* (*vecAt)(TYPE _this,int index); \
int (*vecClear)(TYPE _this); \
int (*vecModifyAt)(TYPE _this,int index,void *pValue);
cssClass(cssVector)
/**
* cssVector容器初始化函数,这里会配置cssVector的所有方法,同时分配类内存
* @param _this 容器自身指针,this
* @param typeSize 容器存放类型的内存大小,相当于 C++ vector;
* 这里typeSize = sizeof(int)
* @param elemNum 初始化可以存放元素的个数
* @return 返回容器类指针
*/
cssVector *cssVectorInit(cssVector *_this,int typeSize,int elemNum);
/**
* 创建容器类
* @param typeSize 容器存放类型的大小
* @param elemNum 容器个初始存放个数
* @return 返回容器指针
*
* @exp
* -----------------------------------------------
* C++中代码
* vector vecInt;
* ...
* vector().swap(vecInt);
* -----------------------------------------------
* css 代码
* cssVector *pVecInt =cssVectorCreat(sizeof(int),1);
* ....
* pVecInt->Release();
* -----------------------------------------------
* 然后后续使用类似
*/
cssVector *cssVectorCreat(int typeSize,int elemNum);
#ifdef __cplusplus
}
#endif
#endif /* SECURITY_CSSVECTOR_H_ */
/*
* cssVector.c
*
* Created on: 2017年10月18日
* Author: JasonHuo
*/
#include "cssVector.h"
//内存清理函数
static void cssVectorOnDelloc(cssVector * _this)
{
free(_this->_mHead);
_this->onCssObjectDelloc(_this);
}
static int vecIsFull(cssVector *_this)
{
return _this->_mUsedMemLen==_this->_mMemLen?1:0;
}
static int vecResize(cssVector *_this)
{
int ret = VEC_RET_FAILD;
//获取两倍的内存
int newMemLen = _this->_mMemLen<<1;
void *mempty =malloc(newMemLen);
if(mempty!=NULL)
{
//将原本内存中的数据拷贝到到新的内存当中
//并且释放原来的内存
memset(mempty,0,newMemLen);
memcpy(mempty,_this->_mHead,_this->_mUsedMemLen);
free(_this->_mHead);
_this->_mEnd = _this->_mHead+_this->_mUsedMemLen;
_this->_mMemLen = newMemLen;
_this->mMaxSize <<=1;
ret = VEC_RET_SUCCESS;
}
return ret;
}
static int vecPush_back(cssVector *_this,void *pValue)
{
if(_this->vecIsFull(_this)==1)
{
//如果内存已经满了,则将原来的内存扩大两倍
_this->vecRresize(_this);
}
//将新来的数据拷贝到个容器当中
memcpy(_this->_mEnd,pValue,_this->mTypeSize);
_this->_mEnd +=_this->mTypeSize;
_this->mSize++;
_this->_mUsedMemLen+=_this->mTypeSize;
return VEC_RET_SUCCESS;
}
static int vecPop_back(cssVector *_this)
{
int ret = VEC_RET_FAILD;
if(_this->mSize!=0)
{
_this->_mEnd-=_this->mTypeSize;
_this->_mUsedMemLen-=_this->mTypeSize;
_this->mSize--;
ret = VEC_RET_SUCCESS;
}
return ret;
}
static void *vecAt(cssVector *_this,int index)
{
void *atPtr = NULL;
if(index<_this->mSize && index >=0)
{
atPtr = _this->_mHead+_this->mTypeSize*index;
}
return atPtr;
}
static int vecClear(cssVector *_this)
{
_this->_mUsedMemLen = 0;
_this->_mMemLen = _this->mTypeSize;
_this->mMaxSize = 1;
_this->mSize = 0;
free(_this->_mHead);
_this->_mHead =malloc(_this->mTypeSize);
memset(_this->_mHead,0,_this->mTypeSize);
_this->_mEnd = _this->_mHead;
return VEC_RET_SUCCESS;
}
static int vecModifyAt(cssVector *_this,int index,void *pValue)
{
void *atPtr = _this->vecAt(_this,index);
memcpy(atPtr,pValue,_this->mTypeSize);
return VEC_RET_SUCCESS;
}
cssVector *cssVectorInit(cssVector *_this,int typeSize,int elemNum)
{
cssObjectInit(cssAs(cssObject*,_this));
//配置内存清除方法
_this->onCssObjectDelloc = _this->onDelloc;
_this->onDelloc = &cssVectorOnDelloc;
if(elemNum>=0)
{
//分配容器内存
void* memptr = malloc(typeSize*elemNum);
memset(memptr,0,typeSize*elemNum);
if(memptr == NULL)
return _this;
_this->mSize = 0;
_this->mMaxSize = elemNum;
_this->mTypeSize = typeSize;
_this->_mUsedMemLen = 0;
_this->_mMemLen = typeSize*elemNum;
_this->_mHead = memptr;
_this->_mEnd = memptr;
//配置回调函数
_this->vecIsFull = &vecIsFull;
_this->vecRresize = &vecResize;
_this->vecPush_back = &vecPush_back;
_this->vecPop_back = &vecPop_back;
_this->vecAt = &vecAt;
_this->vecClear = &vecClear;
_this->vecModifyAt = &vecModifyAt;
}
return _this;
}
cssVector *cssVectorCreat(int typeSize,int elemNum)
{
return cssVectorInit(cssAlloc(cssVector),typeSize,elemNum);
}