【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;
}

【ThinkingInC++】23、一个袖珍的C库,布布扣,bubuko.com

时间: 2024-12-28 08:37:04

【ThinkingInC++】23、一个袖珍的C库的相关文章

ACM选手进阶指北:一个好的代码库与latex维护代码文档

一个好的代码库是必须的,打的久的人心里自然有b数 而且对于算法模板而言,简单的文件夹分级维护就能满足所有需求了 当然,好的代码库不只是把代码堆进去那么简单, 还需要随用随取,变量名不冲突,风格一致,封装优秀等等 并且每次写题都用自己的板子,不断精进细节 非常推荐使用封装,默认参数,宏定义,有意义的变量名,统一取名习惯和常数名等等 例如主席树的模板代码,直接复制粘贴就能用,也不会和你写了一半的其他代码冲突: int rt[maxn];//@树根@ class ptree{public: #defi

如何持续集成/交付一个开源.NET函数库到Nuget.org

(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:这是一个简单的入门向导,涉及到GitHub.AppVeyor和Nuget.org. 最近在开发钉钉相关东西,遂简单包装了一个钉钉SDK并开源(https://github.com/keyroads/DingtalkSDK),这就涉及到如何进行持续集成并自动发布Nuget包的问题.之前一直都是使用TFS或者VSTS来做CI,既然是一个托管在GitHub中的开源项目,就从大家常用的持续集成平台(A

C 封装一个简单二叉树基库

引文 今天分享一个喜欢佩服的伟人,应该算人类文明极大突破者.收藏过一张纸币类型如下 那我们继续科普一段关于他的简介 '高斯有些孤傲,但令人惊奇的是,他春风得意地度过了中产阶级的一生,而  没有遭受到冷酷现实的打击:这种打击常无情地加诸于每个脱离现实环境生活的  人.或许高斯讲求实效和追求完美的性格,有助于让他抓住生活中的简单现实.  高斯22岁获博士学位,25岁当选圣彼德堡科学院外籍院士,30岁任哥廷根大学数  学教授兼天文台台长.虽说高斯不喜欢浮华荣耀,但在他成名后的五十年间,这  些东西就像

一个简单的跨库事务问题

什么是数据结构? 数据结构是相互之间存在一种或多种特定关系的数据元素的集合. 还有一些概念(数据.数据元素.数据项.数据对象.数据类型...) 传统上,我们把数据结构分为逻辑结构和物理结构. 逻辑结构:是指数据对象中数据元素之间的相互关系,也是我们今后最需要关注和讨论的问题. 物理结构:是指数据的逻辑结构在计算机中的存储形式. 逻辑结构分为以下四种: 1.集合:集合结构中的数据元素除了同属于一个集合外,之间没有任何关系. 2.线性结构:元素之间一对一. 3.树形结构:一对多. 4.图形结构:多对

Javascript的一个生产PDF的库: unicode和中文问题的解决

Javascript的一个生产PDF的库: unicode和中文问题的解决基于canvas和jspdf库, 实现用javascript的支持中文pdf生成实用工具.参考:http://javascript.ruanyifeng.com/htmlapi/canvas.html 1. 使用canvas将中文写入canvas中,再将canvas转换成图片,从而解决中文问题. <!DOCTYPE html> <html> <head> </head> <bod

一个现代化的JSON库Moshi针对Android和Java

Moshi 是一个现代化的JSON库针对Android和Java.它可以很容易地解析JSON成Java对象: String json = ...; Moshi moshi = new Moshi.Builder().build(); JsonAdapter<BlackjackHand> jsonAdapter = moshi.adapter(BlackjackHand.class); BlackjackHand blackjackHand = jsonAdapter.fromJson(json

分享一个嵌入式httpdserver开发库 - boahttpd library

http://sourceforge.net/projects/boahttpd/ 一个C接口的开发库,适用于 windows/linux/或其它嵌入式平台,支持CGI扩展,支持多线程.採用面向对象开发,一个应用里能够同一时候开多个http server,仅仅要port不同就互不影响.主要应用场景应该是嵌入式应用(所谓boa-server的概念),在须要做一个基本web的设备管理使用.在样例中就是展示,从页面信息的提交.到处理.到结果的返回,里面结合jquery/bootstrap网页技术,能够

SDS(Simple Dynamic String)一个简易动态字符串库

SDS(Simple Dynamic Strings)是一个C语言字符串库,设计中增加了从堆上分配内存的字符串,来扩充有限的libc字符处理的功能,使得: 使用更简便 二进制安全 计算更有效率 而且仍旧…兼容一般的C字符串功能 它使用另一种设计来实现,不用C结构体来表现一个字符串,而是使用一个二进制的前缀(prefix),保存在实际的指向字符串的指针之前,SDS将其返回给用户. C 1 2 3 4 5 +--------+-------------------------------+-----

分享一个远程更新目标库数据的存储过程

本文给大家分享一个远程更新目标库数据的存储过程,适用于更新列名一致,主键为Int类型,可远程链接的数据库.USE [Table]--切换到源表,就是数据最新的那个表GO/****** Object: StoredProcedure [dbo].[proc_DataUpdate] Script Date: 2018/5/4 15:08:56 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO(http://www.0831jlyy.com)--