首页 > 代码库 > 【ThinkingInC++】23、一个袖珍的C库

【ThinkingInC++】23、一个袖珍的C库



/**
* 功能:一个袖珍的C库
* 时间:2014年8月17日08:05:26
* 作者:cutter_point
*/

//这个头文类似一个C的库

#ifndef CLIB_H_INCLUDED
#define CLIB_H_INCLUDED

typedef struct CStashTag
{
    int size;       //每个小空间的大小
    int quantity;   //用来表示要分配多少个字节,全部空间大小
    int next;       //已经存放了数据的字节个数
    //首先,我们不知道要分配的类型大小是什么,所以用最小的单位作为空间大小
    unsigned char* storage;
}CStash;

void initialize(CStash* s, int size);   //初始化空间大小
void cleanup(CStash* s);    //回收内存
int add(CStash* s, const void* element);    //添加元素
void* fetch(CStash* s, int index);
int count(CStash* s);
void inflate(CStash* s, int increase);


#endif // CLIB_H_INCLUDED


/**
* 功能:一个袖珍的C库,的定义实现
* 时间:2014年8月17日08:05:55
* 作者:cutter_point
*/

#include"CLib.h"
#include<iostream>
#include<cassert>

using namespace std;

const int increment=100;

void initialize(CStash* s, int sz)
{
    s->size=sz;
    s->quantity=0;
    s->storage=0;
    s->next=0;
}

int add(CStash* s, const void* element) //void未知类型
{
    if(s->next >= s->quantity)  //要求的下一块空空间比类型有的空间还要大,那么就扩充
        inflate(s, increment);
    //拷贝元素进入storage中
    //在下一个新的空间开始
    int startBytes=s->next*s->size; //知道从哪里开始是没有数据的空间
    unsigned char* e=(unsigned char*)element;
    for(int i=0 ; i < s->size ; ++i)
        s->storage[startBytes+i]=e[i];
    s->next++;

    return (s->next-1);     //位置索引
}

void* fetch(CStash* s, int index)   //
{
    assert(0<=index);   //索引位置应该不小于0

    if(index >= s->next)
        return 0;

    return &(s->storage[index*s->size]);
}

int count(CStash* s)
{
    return s->next;
}

void inflate(CStash* s, int increase)   //增加内存空间
{
    assert(increase>0); //需要增加的空间大小要大于0

    int newQuantity=s->quantity+increase;   //新的空间大小数
    int newBytes=newQuantity*s->size;       //新的字节个数,这个可以得到内存空间大小
    int oldBytes=s->quantity*s->size;
    unsigned char* b=new unsigned char[newBytes];
    for(int i=0 ; i<oldBytes ; ++i)
        b[i]=s->storage[i]; //吧原来的数据拷贝到新的内存区

    delete [] (s->storage); //回收旧的空间

    s->storage=b;   //新空间的头指针赋值给s->storage
    s->quantity=newQuantity;
}

void cleanup(CStash* s)
{
    if(s->storage != 0)
    {
        cout<<"freeing storage"<<endl;
        delete [] s->storage;
    }
}




/**
* 功能:一个袖珍的C库,的定义实现,使用
* 时间:2014年8月17日08:06:38
* 作者:cutter_point
*/

#include"CLib.h"
#include"CLib.cpp"
#include<fstream>
#include<iostream>
#include<string>
#include<cassert>

using namespace std;

int main()
{
    CStash intStash, stringStash;
    int i;
    char* cp;
    ifstream in;
    string line;
    const int bufsize=80;

    initialize(&intStash, sizeof(int));
    for(i=0 ; i<100 ; ++i)
        add(&intStash, &i);
    for(i=0 ; i<count(&intStash) ; ++i)
        cout<<"fetch(&intStash, "<<i<<")="<<*(int*)fetch(&intStash, i)<<endl;

    cout<<"---------------------------------------"<<endl;

    initialize(&stringStash, sizeof(char)*bufsize);

    in.open("CLibTest.cpp");
    assert(in);

    while(getline(in, line))
        add(&stringStash, line.c_str());    //c_str()是一个指向line字符的指针

    i=0;
    while((cp=(char*)fetch(&stringStash, i++)) != 0)
        cout<<"fetch(&intStash, "<<i<<")="<<cp<<endl;

    cleanup(&intStash);
    cleanup(&stringStash);

    return 0;
}