C语言面向对象之STL库--Vector

Vector 容器的由来

我们这里说的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()返回指向容器最后一个元素的迭代器

Vector的内存结构

在这里我看到了C++中常用的方法,那么我们现在为让老死党C语言也同样拥有这样强大的能力,那么我们遍开始构建属于自己的vector.这里我们使用前面一篇文章给出的c语言基类cssObj来创建这个Vector。(这里我只是简单给出几个常用的方法出来,如有不对的地方请指教,小弟小白一枚)。在写一个数据结构之前,我们首先需要知道这个数据结构的内存模型是怎样的。
vector的内存结构有点像栈的内存结构,先进后出.我们可以从上面的方法表中可以看到,pop_back() 方法和push_back()方法中可以看出,其最基本的内存模型是栈结构。

这里写图片描述

C语言面向对象之Vector

这里我们使用面向对象的继承特性,继承基类的所有基本操作。
详细可以参考我前面的文章C语言面向对象之基类
我们废话少说直接上代码(这里只实现的部分功能)

头文件cssVector.h

/*
 * 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<int>;
 *                   这里typeSize = sizeof(int)
 * @param  elemNum  初始化可以存放元素的个数
 * @return          返回容器类指针
 */
cssVector *cssVectorInit(cssVector *_this,int typeSize,int elemNum);

/**
 * 创建容器类
 * @param  typeSize 容器存放类型的大小
 * @param  elemNum  容器个初始存放个数
 * @return          返回容器指针
 *
 * @exp
 * -----------------------------------------------
 * C++中代码
 * vector<int> vecInt;
 *            ...
 * vector<int>().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

/*
 * 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);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值