C++编程思想 第1卷 第4章 数据抽象 一个袖珍C库

库由一组函数开始
第三方C库程序员知道,通常还有比行为,动作,函数更多的东西
颜色 重量 纹理 亮度 特性由数据表示
C语言处理特性,方便放数据在一起,形成struct
如何在问题空间有多个类似的东西,可以对每件东西创建struct变量
大多数c库有一组struct和一组struct的函数

编程工具,表现像数组,但长度能在运行是确立

//: C04:CLib.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Header file for a C-like library
// An array-like entity created at runtime

typedef struct CStashTag {
  int size;      // Size of each space
  int quantity;  // Number of storage spaces
  int next;      // Next empty space
  // Dynamically allocated array of bytes:
  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);
///:~

//: C04:CLib.cpp {O}
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Implementation of example C-like library
// Declare structure and functions:
#include "CLib.h"
#include <iostream>
#include <cassert> 
using namespace std;
// Quantity of elements to add
// when increasing storage:
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) //Enough space left?
    inflate(s, increment);
  // Copy element into storage,
  // starting at next empty space:
  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); // Index number
}

void* fetch(CStash* s, int index) {
  // Check index boundaries:
  assert(0 <= index);
  if(index >= s->next)
    return 0; // To indicate the end
  // Produce pointer to desired element:
  return &(s->storage[index * s->size]);
}

int count(CStash* s) {
  return s->next;  // Elements in 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]; // Copy old to new
  delete [](s->storage); // Old storage
  s->storage = b; // Point to new memory
  s->quantity = newQuantity;
}

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

CStashTag标签名用于需要在struct内部引用自身
创建一个链表
链表每个元素包含指向下一个元素的指针
链表需要指向下一个struct变量的指针
需要一种方法,能辨别struct内部的指针
c库中,几乎总是可以在 每个struct体看到typedef
 
库可能只是编译好的obj或lib
initialize()通过设置内部变量为适当的值
完成对struct CStash的必要设置
最初,设置storage指针为零,表示不分配初始存储


add()函数在CStash的下一个可用位置插入一个元素
编译器不知道存放的特定变量的类型 
函数返回的都是void*
void* 不能只做赋值
fetch()看index是否越界,没有越界,就返回说希望的变量地址




无输出 没有main函数,可以生成 lib  dll obj

猜你喜欢

转载自blog.csdn.net/eyetired/article/details/80910791