C风格库文件笔记

来源:互联网 发布:文笔好的网络作家 编辑:程序博客网 时间:2024/05/19 20:38

C风格库文件笔记

今天学习《Thinking in C++》数据抽象。看到袖珍C库的程序。作为一个C++初学者,感到理解有些困难。因此整理笔记,以便理清思路,并得以更加深入地理解库文件。

源程序如下:

 

//:Clib.h//一个可以在运行过程中创建的类似数组的结构typedef struct CStashTag{    int size;       //每个空间的大小    int quantity;   //存储空间总数    int next;       //下一个空的空间    //动态分配数组字节    unsigned char* storage;}CStash;void initiallize(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); //扩充存储空间///:~ 


 

//CLib.cpp//C风格库的实现//声明结构和函数:#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){    if(s->next >= s->quantity)//是否有足够的空间?        inflate(s, increment);    //将element复制到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* fecth(CStash* s,int index){    //检查下标界线(Check index boundaries):    assert(0 <= index);    if (index >= s->next)        return 0; //To indicate the end    //为需要的元素创立一个指针    return &(s->storage[index * s->size]); }int count(CStash* s){    return s->next; //CStash中的元素}void inflate(CStash* s, int increase){    assert(increase > 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->quantity = newQuantity;} void cleanup(CStash* s) {    if(s->storage != 0) {        cout << "freeing storage" << endl;        delete []s->storage;    }}///:~


 

 

CStash结构意义:

size为整型,表示一块CStash有几个元素。

quantity为整型,表示一块CStash占几个字节。

next为整型,表示当前位于第几个元素。

storage为指向无符号字符的指针,为CStash的首地址。

 

const int increment CStash需要增加时默认的增加的元素个数(它只在add函数中出现过)。

initialize()对指定的CStash变量作初始化。其中storage0表示它为空指针,不分配初始内存。

add()函数在下一个位置插入一个元素。此处next以及size的用处得到淋漓尽致的体现。而且可以看出其设置的巧妙。next用于记录位置。存储指定成员是用到size变量。此变量在初始化时有用户指定。所以使得CStash结构可以存储各种类型的数据。该函数一开始检查CStash变量是否已满,若是,则用inflate函数进行扩充。add()函数最后返回下标号。

现在,就可以比较轻松的理解书上的解释了。原话如下:

因为编译器并不知道存放的特定变量的类型(函数返回的都是void*),所以不能只做赋值,虽然这的确是很方便的事情。我们必须一个字节一个字节地拷贝这个变量,完成这项拷贝任务最简单的方法是使用数组下标。典型的情况是,在storage中已经存放有数据字节,有next的值指明。为了从正确的字节偏移开始,next必须乘上每个元素的长度(按字节),产生startBytes,然后,参数element转换为一个unsigned char*,所以这就能一个字节接着一个字节地寻址,拷贝进可用的storage存储空间中。增加后的next指向下一个可用的存储块,fetch()能用指向这个数值存放点的“下标数”重新得到这个值。

――此段引自《Thinking in C++

 

原创粉丝点击