C风格库文件笔记

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++

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值