C语言接口与实现[+]

该博客详细介绍了C语言中接口与实现的紧密关系,通过Arith接口、抽象数据类型Stack、原子、异常处理、内存管理等关键概念的实例解析,深入探讨了C语言编程中的核心要素。从原子接口到高级数据结构如链表、表格和集合,展示了C语言在构建高效程序中的应用。
摘要由CSDN通过智能技术生成

第1章 简介

1. literate程序

2. 宏指令与条件编译指令

第2章 接口与实现

1. 接口与实现的关系

2. Arith接口及实现:

arith.h:

复制代码
/*  $Id: H:/drh/idioms/book/RCS/inter.doc,v 1.11 1997/02/21 19:42:15 drh Exp $  */
extern  int Arith_max( int x,  int y);
extern  int Arith_min( int x,  int y);
extern  int Arith_div( int x,  int y);
extern  int Arith_mod( int x,  int y);
extern  int Arith_ceiling( int x,  int y);
extern  int Arith_floor  ( int x,  int y);
复制代码

arith.c

 

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/inter.doc,v 1.11 1997/02/21 19:42:15 drh Exp $ ";
#include  " arith.h "
int Arith_max( int x,  int y) {
     return x > y ? x : y;
}
int Arith_min( int x,  int y) {
     return x > y ? y : x;
}
int Arith_div( int x,  int y) {
     if (- 13/ 5 == - 2
    &&    (x <  0) != (y <  0) && x%y !=  0)
         return x/y -  1;
     else
         return x/y;
}
int Arith_mod( int x,  int y) {
     if (- 13/ 5 == - 2
    &&    (x <  0) != (y <  0) && x%y !=  0)
         return x%y + y;
     else
         return x%y;
}
int Arith_floor( int x,  int y) {
     return Arith_div(x, y);
}
int Arith_ceiling( int x,  int y) {
     return Arith_div(x, y) + (x%y !=  0);
}
复制代码

 

3. 抽象数据类型Stack

4. 客户调用程序的责任

stack.h

View Code

stack.c 

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/inter.doc,v 1.11 1997/02/21 19:42:15 drh Exp $ ";
#include <stddef.h>
#include  " assert.h "
#include  " mem.h "
#include  " stack.h "
#define T Stack_T
struct T {
     int count;
     struct elem {
         void *x;
         struct elem *link;
    } *head;
};
T Stack_new( void) {
    T stk;
    NEW(stk);
    stk->count =  0;
    stk->head = NULL;
     return stk;
}
int Stack_empty(T stk) {
    assert(stk);
     return stk->count ==  0;
}
void Stack_push(T stk,  void *x) {
     struct elem *t;
    assert(stk);
    NEW(t);
    t->x = x;
    t->link = stk->head;
    stk->head = t;
    stk->count++;
}
void *Stack_pop(T stk) {
     void *x;
     struct elem *t;
    assert(stk);
    assert(stk->count >  0);
    t = stk->head;
    stk->head = t->link;
    stk->count--;
    x = t->x;
    FREE(t);
     return x;
}
void Stack_free(T *stk) {
     struct elem *t, *u;
    assert(stk && *stk);
     for (t = (*stk)->head; t; t = u) {
        u = t->link;
        FREE(t);
    }
    FREE(*stk);
}
复制代码

第3章 原子

1. 接口

atom.h: 

View Code

atom.c:

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/atom.doc,v 1.10 1997/02/21 19:42:46 drh Exp $ ";
#include  " atom.h "
#include < string.h>
#include  " assert.h "
#include <limits.h>
#include  " mem.h "
#define NELEMS(x) ((sizeof (x))/(sizeof ((x)[0])))
static  struct atom {
     struct atom *link;
     int len;
     char *str;
} *buckets[ 2048];
static unsigned  long scatter[] = {
2078917053143302914102710082719532103027552536312002600785,
14053902304524801110999515674338323502018585307438263339,
8135289291703199216618906479573714703766270699275680090,
151032044015835839261723401032196544332910981836821636505764,
980071615101159796164327927313154612751575840381069844923,
471560540890174431213147837149866136820422277461968401469,
13537785051300134328201364948030624642417339666781884751139,
7445097634000119591440466707136341624297372666359253759,
163909633233656345516428376851215013716154523136593537720,
7040358321134594751160513568113473151063025723791762719719,
269676381774132919185173716314828242191253106391746481261,
1303742040147908914489913194111699078721785335569485614972,
90717536438236168488562693120015842317457779271859353594,
2594121821237390611484334011902249868304920680202956538,
3483039401008956512133755128919534396212087879701640123668,
156867569347846435226677294012729292081961288571392083579,
8719268211117546963187117272417710587621399711871509024645,
1091900861047146551189138632999481701812473049751489680608,
70668696415067171575795875727551203661261483377884508252,
9580769041609787317189346476414814454514157432912102252735,
178826821483693533643323343920550411542109864544247038362,
2996410858343077171364585325233301614578828311504556512,
1532354806567072918404219416127625748815618899361651524391,
61845444812109325210107579001198042020876213618124757630,
208255027218342905221734544947182853138919824350681002804590,
1783300476162321963418397399266905026715307771401802120822,
316088629183041822548894489116806739541853748387946827723,
1037746818123861954515139006411441966234367393385928306929,
94600697798584783410494001811956764878364062061925613800,
208152250821189564791612420674166858380718000042201447372094,
52390475014358210489231080802161610281504871315306401572,
20182818511820959944213681979835974309413541502501843084537,
130657081724441342093422043467298781016863796551301613820,
1601294739484902984139978006503211273294184214176384212,
281341425228223074147857043189376209918968068821947861263,
119365054627322798412361986632116758626489389012593586330,
2756765513601872152670626262650127017199303101621212876,
2108097238202650112718656262978948340245520052901404522304,
489641965816381188942528818894220250902765436125855,
36532641579036907926434892951318345853664753113672163,
313561074173029807728690014715497597371699573055776289160,
214334606819752496061136476375262925046927786591856406685,
18841379235339224917354241651602280572
};
const  char *Atom_string( const  char *str) {
    assert(str);
     return Atom_new(str, strlen(str));
}
const  char *Atom_int( long n) {
     char str[ 43];
     char *s = str +  sizeof str;
    unsigned  long m;
     if (n == LONG_MIN)
        m = LONG_MAX +  1UL;
     else  if (n <  0)
        m = -n;
     else
        m = n;
     do
        *--s = m% 10 +  ' 0 ';
     while ((m /=  10) >  0);
     if (n <  0)
        *--s =  ' - ';
     return Atom_new(s, (str +  sizeof str) - s);
}
const  char *Atom_new( const  char *str,  int len) {
    unsigned  long h;
     int i;
     struct atom *p;
    assert(str);
    assert(len >=  0);
     for (h =  0, i =  0; i < len; i++)
        h = (h<< 1) + scatter[(unsigned  char)str[i]];
    h &= NELEMS(buckets)- 1;
     for (p = buckets[h]; p; p = p->link)
         if (len == p->len) {
             for (i =  0; i < len && p->str[i] == str[i]; )
                i++;
             if (i == len)
                 return p->str;
        }
    p = ALLOC( sizeof (*p) + len +  1);
    p->len = len;
    p->str = ( char *)(p +  1);
     if (len >  0)
        memcpy(p->str, str, len);
    p->str[len] =  ' \0 ';
    p->link = buckets[h];
    buckets[h] = p;
     return p->str;
}
int Atom_length( const  char *str) {
     struct atom *p;
     int i;
    assert(str);
     for (i =  0; i < NELEMS(buckets); i++)
         for (p = buckets[i]; p; p = p->link)
             if (p->str == str)
                 return p->len;
    assert( 0);
     return  0;
}
复制代码

第4章 异常与断言

except.h 

复制代码
/*  $Id: H:/drh/idioms/book/RCS/except.doc,v 1.10 1997/02/21 19:43:55 drh Exp $  */
#ifndef EXCEPT_INCLUDED
#define EXCEPT_INCLUDED
#include <setjmp.h>
#define T Except_T
typedef  struct T {
     char *reason;
} T;
typedef  struct Except_Frame Except_Frame;
struct Except_Frame {
    Except_Frame *prev;
    jmp_buf env;
     const  char *file;
     int line;
     const T *exception;
};
enum { Except_entered= 0, Except_raised,
       Except_handled,   Except_finalized };
#ifdef WIN32
__declspec(thread)
#endif
extern Except_Frame *Except_stack;
extern  const Except_T Assert_Failed;
void Except_raise( const T *e,  const  char *file, int line);
#define RAISE(e) Except_raise(&(e), __FILE__, __LINE__)
#define RERAISE Except_raise(Except_frame.exception, \
    Except_frame.file, Except_frame.line)
#define RETURN switch (Except_stack = Except_stack->prev,0) default: return
#define TRY do { \
     volatile  int Except_flag; \
    Except_Frame Except_frame; \
    Except_frame.prev = Except_stack; \
    Except_stack = &Except_frame;  \
    Except_flag = setjmp(Except_frame.env); \
     if (Except_flag == Except_entered) {
#define EXCEPT(e) \
         if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
    }  else  if (Except_frame.exception == &(e)) { \
        Except_flag = Except_handled;
#define ELSE \
         if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
    }  else { \
        Except_flag = Except_handled;
#define FINALLY \
         if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
    } { \
         if (Except_flag == Except_entered) \
            Except_flag = Except_finalized;
#define END_TRY \
         if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
        }  if (Except_flag == Except_raised) RERAISE; \
while ( 0)
#undef T
#endif
复制代码

except.c 

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/except.doc,v 1.10 1997/02/21 19:43:55 drh Exp $ ";
#include <stdlib.h>
#include <stdio.h>
#include  " assert.h "
#include  " except.h "
#define T Except_T
#ifdef WIN32
__declspec(thread)
#endif
Except_Frame *Except_stack = NULL;
void Except_raise( const T *e,  const  char *file,
     int line) {
    Except_Frame *p = Except_stack;
    assert(e);
     if (p == NULL) {
        fprintf(stderr,  " Uncaught exception ");
         if (e->reason)
            fprintf(stderr,  "  %s ", e->reason);
         else
            fprintf(stderr,  "  at 0x%p ", e);
         if (file && line >  0)
            fprintf(stderr,  "  raised at %s:%d\n ", file, line);
        fprintf(stderr,  " aborting...\n ");
        fflush(stderr);
        abort();
    }
    p->exception = e;
    p->file = file;
    p->line = line;
    Except_stack = Except_stack->prev;
    longjmp(p->env, Except_raised);
}
复制代码

assert.h

复制代码
/*  $Id: H:/drh/idioms/book/RCS/except.doc,v 1.10 1997/02/21 19:43:55 drh Exp $  */
#undef assert
#ifdef NDEBUG
#define assert(e) ((void)0)
#else
#include  " except.h "
extern  void assert( int e);
#define assert(e) ((void)((e)||(RAISE(Assert_Failed),0)))
#endif
复制代码

assert.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/except.doc,v 1.10 1997/02/21 19:43:55 drh Exp $ ";
#include  " assert.h "
const Except_T Assert_Failed = {  " Assertion failed " };
void (assert)( int e) {
    assert(e);
}
复制代码

 

第5章 内存管理

MEM分配接口

mem.h

复制代码
/*  $Id: H:/drh/idioms/book/RCS/mem.doc,v 1.12 1997/10/27 23:08:05 drh Exp $  */
#ifndef MEM_INCLUDED
#define MEM_INCLUDED
#include  " except.h "
extern  const Except_T Mem_Failed;
extern  void *Mem_alloc ( long nbytes,
     const  char *file,  int line);
extern  void *Mem_calloc( long count,  long nbytes,
     const  char *file,  int line);
extern  void Mem_free( void *ptr,
     const  char *file,  int line);
extern  void *Mem_resize( void *ptr,  long nbytes,
     const  char *file,  int line);
#define ALLOC(nbytes) \
    Mem_alloc((nbytes), __FILE__, __LINE__)
#define CALLOC(count, nbytes) \
    Mem_calloc((count), (nbytes), __FILE__, __LINE__)
#define  NEW(p) ((p) = ALLOC((long)sizeof *(p)))
#define NEW0(p) ((p) = CALLOC(1, (long)sizeof *(p)))
#define FREE(ptr) ((void)(Mem_free((ptr), \
    __FILE__, __LINE__), (ptr) =  0))
#define RESIZE(ptr, nbytes)     ((ptr) = Mem_resize((ptr), \
    (nbytes), __FILE__, __LINE__))
#endif
复制代码

 

 

mem.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/mem.doc,v 1.12 1997/10/27 23:08:05 drh Exp $ ";
#include <stdlib.h>
#include <stddef.h>
#include  " assert.h "
#include  " except.h "
#include  " mem.h "
const Except_T Mem_Failed = {  " Allocation Failed " };
void *Mem_alloc( long nbytes,  const  char *file,  int line){
     void *ptr;
    assert(nbytes >  0);
    ptr = malloc(nbytes);
     if (ptr == NULL)
        {
             if (file == NULL)
                RAISE(Mem_Failed);
             else
                Except_raise(&Mem_Failed, file, line);
        }
     return ptr;
}
void *Mem_calloc( long count,  long nbytes,
     const  char *file,  int line) {
     void *ptr;
    assert(count >  0);
    assert(nbytes >  0);
    ptr = calloc(count, nbytes);
     if (ptr == NULL)
        {
             if (file == NULL)
                RAISE(Mem_Failed);
             else
                Except_raise(&Mem_Failed, file, line);
        }
     return ptr;
}
void Mem_free( void *ptr,  const  char *file,  int line) {
     if (ptr)
        free(ptr);
}
void *Mem_resize( void *ptr,  long nbytes,
     const  char *file,  int line) {
    assert(ptr);
    assert(nbytes >  0);
    ptr = realloc(ptr, nbytes);
     if (ptr == NULL)
        {
             if (file == NULL)
                RAISE(Mem_Failed);
             else
                Except_raise(&Mem_Failed, file, line);
        }
     return ptr;
}
复制代码

 

第6章 进一步内存管理

arena.h

View Code

 

arena.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/arena.doc,v 1.10 1997/02/21 19:45:19 drh Exp $ ";
#include <stdlib.h>
#include < string.h>
#include  " assert.h "
#include  " except.h "
#include  " arena.h "
#define T Arena_T
const Except_T Arena_NewFailed =
    {  " Arena Creation Failed " };
const Except_T Arena_Failed    =
    {  " Arena Allocation Failed " };
#define THRESHOLD 10
struct T {
    T prev;
     char *avail;
     char *limit;
};
union align {
#ifdef MAXALIGN
     char pad[MAXALIGN];
#else
     int i;
     long l;
     long *lp;
     void *p;
     void (*fp)( void);
     float f;
     double d;
     long  double ld;
#endif
};
union header {
     struct T b;
    union align a;
};
static T freechunks;
static  int nfree;
T Arena_new( void) {
    T arena = malloc( sizeof (*arena));
     if (arena == NULL)
        RAISE(Arena_NewFailed);
    arena->prev = NULL;
    arena->limit = arena->avail = NULL;
     return arena;
}
void Arena_dispose(T *ap) {
    assert(ap && *ap);
    Arena_free(*ap);
    free(*ap);
    *ap = NULL;
}
void *Arena_alloc(T arena,  long nbytes,
     const  char *file,  int line) {
    assert(arena);
    assert(nbytes >  0);
    nbytes = ((nbytes +  sizeof (union align) -  1)/
        ( sizeof (union align)))*( sizeof (union align));
     while (nbytes > arena->limit - arena->avail) {
        T ptr;
         char *limit;
         if ((ptr = freechunks) != NULL) {
            freechunks = freechunks->prev;
            nfree--;
            limit = ptr->limit;
        }  else {
             long m =  sizeof (union header) + nbytes +  10* 1024;
            ptr = malloc(m);
             if (ptr == NULL)
                {
                     if (file == NULL)
                        RAISE(Arena_Failed);
                     else
                        Except_raise(&Arena_Failed, file, line);
                }
            limit = ( char *)ptr + m;
        }
        *ptr = *arena;
        arena->avail = ( char *)((union header *)ptr +  1);
        arena->limit = limit;
        arena->prev  = ptr;
    }
    arena->avail += nbytes;
     return arena->avail - nbytes;
}
void *Arena_calloc(T arena,  long count,  long nbytes,
     const  char *file,  int line) {
     void *ptr;
    assert(count >  0);
    ptr = Arena_alloc(arena, count*nbytes, file, line);
    memset(ptr,  ' \0 ', count*nbytes);
     return ptr;
}
void Arena_free(T arena) {
    assert(arena);
     while (arena->prev) {
         struct T tmp = *arena->prev;
         if (nfree < THRESHOLD) {
            arena->prev->prev = freechunks;
            freechunks = arena->prev;
            nfree++;
            freechunks->limit = arena->limit;
        }  else
            free(arena->prev);
        *arena = tmp;
    }
    assert(arena->limit == NULL);
    assert(arena->avail == NULL);
}
复制代码

 

第7章 链表

 

list.h

复制代码
/*  $Id: H:/drh/idioms/book/RCS/list.doc,v 1.11 1997/02/21 19:46:01 drh Exp $  */
#ifndef LIST_INCLUDED
#define LIST_INCLUDED
#define T List_T
typedef  struct T *T;
struct T {
    T rest;
     void *first;
};
extern T      List_append (T list, T tail);
extern T      List_copy   (T list);
extern T      List_list   ( void *x, ...);
extern T      List_pop    (T list,  void **x);
extern T      List_push   (T list,  void *x);
extern T      List_reverse(T list);
extern  int    List_length (T list);
extern  void   List_free   (T *list);
extern  void   List_map    (T list,
     void apply( void **x,  void *cl),  void *cl);
extern  void **List_toArray(T list,  void *end);
#undef T
#endif
复制代码

 

list.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/list.doc,v 1.11 1997/02/21 19:46:01 drh Exp $ ";
#include <stdarg.h>
#include <stddef.h>
#include  " assert.h "
#include  " mem.h "
#include  " list.h "
#define T List_T
T List_push(T list,  void *x) {
    T p;
    NEW(p);
    p->first = x;
    p->rest  = list;
     return p;
}
T List_list( void *x, ...) {
    va_list ap;
    T list, *p = &list;
    va_start(ap, x);
     for ( ; x; x = va_arg(ap,  void *)) {
        NEW(*p);
        (*p)->first = x;
        p = &(*p)->rest;
    }
    *p = NULL;
    va_end(ap);
     return list;
}
T List_append(T list, T tail) {
    T *p = &list;
     while (*p)
        p = &(*p)->rest;
    *p = tail;
     return list;
}
T List_copy(T list) {
    T head, *p = &head;
     for ( ; list; list = list->rest) {
        NEW(*p);
        (*p)->first = list->first;
        p = &(*p)->rest;
    }
    *p = NULL;
     return head;
}
T List_pop(T list,  void **x) {
     if (list) {
        T head = list->rest;
         if (x)
            *x = list->first;
        FREE(list);
         return head;
    }  else
         return list;
}
T List_reverse(T list) {
    T head = NULL, next;
     for ( ; list; list = next) {
        next = list->rest;
        list->rest = head;
        head = list;
    }
     return head;
}
int List_length(T list) {
     int n;
     for (n =  0; list; list = list->rest)
        n++;
     return n;
}
void List_free(T *list) {
    T next;
    assert(list);
     for ( ; *list; *list = next) {
        next = (*list)->rest;
        FREE(*list);
    }
}
void List_map(T list,
     void apply( void **x,  void *cl),  void *cl) {
    assert(apply);
     for ( ; list; list = list->rest)
        apply(&list->first, cl);
}
void **List_toArray(T list,  void *end) {
     int i, n = List_length(list);
     void **array = ALLOC((n +  1)* sizeof (*array));
     for (i =  0; i < n; i++) {
        array[i] = list->first;
        list = list->rest;
    }
    array[i] = end;
     return array;
}
复制代码

 

第8章 表格

table.h

复制代码
/*  $Id: H:/drh/idioms/book/RCS/table.doc,v 1.13 1997/10/27 23:10:11 drh Exp $  */
#ifndef TABLE_INCLUDED
#define TABLE_INCLUDED
#define T Table_T
typedef  struct T *T;
extern T    Table_new ( int hint,
     int cmp( const  void *x,  const  void *y),
    unsigned hash( const  void *key));
extern  void Table_free(T *table);
extern  int   Table_length(T table);
extern  void *Table_put   (T table,  const  void *key,
     void *value);
extern  void *Table_get   (T table,  const  void *key);
extern  void *Table_remove(T table,  const  void *key);
extern  void   Table_map    (T table,
     void apply( const  void *key,  void **value,  void *cl),
     void *cl);
extern  void **Table_toArray(T table,  void *end);
#undef T
#endif
复制代码

 

 

table.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/table.doc,v 1.13 1997/10/27 23:10:11 drh Exp $ ";
#include <limits.h>
#include <stddef.h>
#include  " mem.h "
#include  " assert.h "
#include  " table.h "
#define T Table_T
struct T {
     int size;
     int (*cmp)( const  void *x,  const  void *y);
    unsigned (*hash)( const  void *key);
     int length;
    unsigned timestamp;
     struct binding {
         struct binding *link;
         const  void *key;
         void *value;
    } **buckets;
};
static  int cmpatom( const  void *x,  const  void *y) {
     return x != y;
}
static unsigned hashatom( const  void *key) {
     return (unsigned  long)key>> 2;
}
T Table_new( int hint,
     int cmp( const  void *x,  const  void *y),
    unsigned hash( const  void *key)) {
    T table;
     int i;
     static  int primes[] = {  509509102120534093,
         8191163813277165521, INT_MAX };
    assert(hint >=  0);
     for (i =  1; primes[i] < hint; i++)
        ;
    table = ALLOC( sizeof (*table) +
        primes[i- 1]* sizeof (table->buckets[ 0]));
    table->size = primes[i- 1];
    table->cmp  = cmp  ?  cmp : cmpatom;
    table->hash = hash ? hash : hashatom;
    table->buckets = ( struct binding **)(table +  1);
     for (i =  0; i < table->size; i++)
        table->buckets[i] = NULL;
    table->length =  0;
    table->timestamp =  0;
     return table;
}
void *Table_get(T table,  const  void *key) {
     int i;
     struct binding *p;
    assert(table);
    assert(key);
    i = (*table->hash)(key)%table->size;
     for (p = table->buckets[i]; p; p = p->link)
         if ((*table->cmp)(key, p->key) ==  0)
             break;
     return p ? p->value : NULL;
}
void *Table_put(T table,  const  void *key,  void *value) {
     int i;
     struct binding *p;
     void *prev;
    assert(table);
    assert(key);
    i = (*table->hash)(key)%table->size;
     for (p = table->buckets[i]; p; p = p->link)
         if ((*table->cmp)(key, p->key) ==  0)
             break;
     if (p == NULL) {
        NEW(p);
        p->key = key;
        p->link = table->buckets[i];
        table->buckets[i] = p;
        table->length++;
        prev = NULL;
    }  else
        prev = p->value;
    p->value = value;
    table->timestamp++;
     return prev;
}
int Table_length(T table) {
    assert(table);
     return table->length;
}
void Table_map(T table,
     void apply( const  void *key,  void **value,  void *cl),
     void *cl) {
     int i;
    unsigned stamp;
     struct binding *p;
    assert(table);
    assert(apply);
    stamp = table->timestamp;
     for (i =  0; i < table->size; i++)
         for (p = table->buckets[i]; p; p = p->link) {
            apply(p->key, &p->value, cl);
            assert(table->timestamp == stamp);
        }
}
void *Table_remove(T table,  const  void *key) {
     int i;
     struct binding **pp;
    assert(table);
    assert(key);
    table->timestamp++;
    i = (*table->hash)(key)%table->size;
     for (pp = &table->buckets[i]; *pp; pp = &(*pp)->link)
         if ((*table->cmp)(key, (*pp)->key) ==  0) {
             struct binding *p = *pp;
             void *value = p->value;
            *pp = p->link;
            FREE(p);
            table->length--;
             return value;
        }
     return NULL;
}
void **Table_toArray(T table,  void *end) {
     int i, j =  0;
     void **array;
     struct binding *p;
    assert(table);
    array = ALLOC(( 2*table->length +  1)* sizeof (*array));
     for (i =  0; i < table->size; i++)
         for (p = table->buckets[i]; p; p = p->link) {
            array[j++] = ( void *)p->key;
            array[j++] = p->value;
        }
    array[j] = end;
     return array;
}
void Table_free(T *table) {
    assert(table && *table);
     if ((*table)->length >  0) {
         int i;
         struct binding *p, *q;
         for (i =  0; i < (*table)->size; i++)
             for (p = (*table)->buckets[i]; p; p = q) {
                q = p->link;
                FREE(p);
            }
    }
    FREE(*table);
}
复制代码

 

 

wf程序来统计单词的频率

getword.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/table.doc,v 1.13 1997/10/27 23:10:11 drh Exp $ ";
#include <ctype.h>
#include < string.h>
#include <stdio.h>
#include  " assert.h "
#include  " getword.h "
int getword(FILE *fp,  char *buf,  int size,
     int first( int c),  int rest( int c)) {
     int i =  0, c;
    assert(fp && buf && size >  1 && first && rest);
    c = getc(fp);
     for ( ; c != EOF; c = getc(fp))
         if (first(c)) {
            {
                 if (i < size -  1)
                    buf[i++] = c;
            }
            c = getc(fp);
             break;
        }
     for ( ; c != EOF && rest(c); c = getc(fp))
        {
             if (i < size -  1)
                buf[i++] = c;
        }
     if (i < size)
        buf[i] =  ' \0 ';
     else
        buf[size- 1] =  ' \0 ';
     if (c != EOF)
        ungetc(c, fp);
     return i >  0;
}
复制代码

 

wf.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/table.doc,v 1.13 1997/10/27 23:10:11 drh Exp $ ";
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include  " atom.h "
#include  " table.h "
#include  " mem.h "
#include  " getword.h "
#include < string.h>
void wf( char *, FILE *);
int first( int c);
int rest ( int c);
int compare( const  void *x,  const  void *y);
void vfree( const  void *,  void **,  void *);
int main( int argc,  char *argv[]) {
     int i;
     for (i =  1; i < argc; i++) {
        FILE *fp = fopen(argv[i],  " r ");
         if (fp == NULL) {
            fprintf(stderr,  " %s: can't open '%s' (%s)\n ",
                argv[ 0], argv[i], strerror(errno));
             return EXIT_FAILURE;
        }  else {
            wf(argv[i], fp);
            fclose(fp);
        }
    }
     if (argc ==  1) wf(NULL, stdin);
     return EXIT_SUCCESS;
}
void wf( char *name, FILE *fp) {
    Table_T table = Table_new( 0, NULL, NULL);
     char buf[ 128];
     while (getword(fp, buf,  sizeof buf, first, rest)) {
         const  char *word;
         int i, *count;
         for (i =  0; buf[i] !=  ' \0 '; i++)
            buf[i] = tolower(buf[i]);
        word = Atom_string(buf);
        count = Table_get(table, word);
         if (count)
            (*count)++;
         else {
            NEW(count);
            *count =  1;
            Table_put(table, word, count);
        }
    }
     if (name)
        printf( " %s:\n ", name);
    {  int i;
       void **array = Table_toArray(table, NULL);
      qsort(array, Table_length(table),  2* sizeof (*array),
          compare);
       for (i =  0; array[i]; i +=  2)
          printf( " %d\t%s\n ", *( int *)array[i+ 1],
              ( char *)array[i]);
      FREE(array); }
    Table_map(table, vfree, NULL);
    Table_free(&table);
}
int first( int c) {
     return isalpha(c);
}
int rest( int c) {
     return isalpha(c) || c ==  ' _ ';
}
int compare( const  void *x,  const  void *y) {
     return strcmp(*( char **)x, *( char **)y);
}
void vfree( const  void *key,  void **count,  void *cl) {
    FREE(*count);
}
复制代码

 

第9章 集合

集合的实现

set.h

复制代码
/*  $Id: H:/drh/idioms/book/RCS/set.doc,v 1.11 1996/06/26 23:02:01 drh Exp $  */
#ifndef SET_INCLUDED
#define SET_INCLUDED
#define T Set_T
typedef  struct T *T;
extern T    Set_new ( int hint,
     int cmp( const  void *x,  const  void *y),
    unsigned hash( const  void *x));
extern  void Set_free(T * set);
extern  int   Set_length(T  set);
extern  int   Set_member(T  setconst  void *member);
extern  void  Set_put   (T  setconst  void *member);
extern  void *Set_remove(T  setconst  void *member);
extern  void   Set_map    (T  set,
     void apply( const  void *member,  void *cl),  void *cl);
extern  void **Set_toArray(T  setvoid *end);
extern T Set_union(T s, T t);
extern T Set_inter(T s, T t);
extern T Set_minus(T s, T t);
extern T Set_diff (T s, T t);
#undef T
#endif
复制代码

 

 

set.c

复制代码
static  char rcsid[] =  " $Id: H:/drh/idioms/book/RCS/set.doc,v 1.11 1996/06/26 23:02:01 drh Exp $ ";
#include <limits.h>
#include <stddef.h>
#include  "
对于c语言接口网上的资料是少之又少,所以下面这些文字全是我一个字一个字打印上来的希望大家 能对的起我的付出: 现在的程序员都面临大量的关于应用程序接口(Application Programming Interface,API) 的信息,大多数人都会使用API和程序库,并在其所写的每一个应用程序中实现它们,但是很少人 会创建或发布新的能广泛应用的API,事实上,程序员似乎倾向与循环使用他们自己的东西,而不 愿意查找,能满足他们要求的程序库,这或许是因为写特定应用程序代码要比查找设计好的API容易。 这里我所提到的是一种基于接口与其实现的设计方法,并且通过对24个接口及其实现的描述详细地演示了这种方法,这些接口涉及到计算机领域的很多知识,其中包括数据结构,算法,字符串处理 和并发程序,这些实现并不是简单的玩具----它们是为了在你们所设计的软件代码中使用而设计的。(当然了我会通过阅读量来看是否继续发下去,人要少了我就没有必要浪费时间了) c编程语言对基于接口设计方法的支持是极少的。 而面向对象的语言,如c++,Modula-3,则鼓励将接口实现分离,基于接口的设计独立与任何特定 的语言,但是它要求程序员对像c一样的语言有更多的驾驭能力和更高的警惕性,因为这类语言很容易破坏带有隐含实现信息的接口,反之亦然。 然而一但掌握了基于接口的设计方法,就能够在服务于众多应用程序的通用接口基础上建立应用程序,从而加速开发,在一些c++环境中的基础类库就体现了这种效果。 增加对现有软件的重用---接口实现库,能够减少初始开发成本,同时还能减少维护成本,因为应用程序的更多部分都建立在经过良好测试的通用接口实现上,这里我提到的接口是针对数据结构的,但它并不是数据结构,我重点将放在算法引擎----包装数据结构以供应用程序使用----而不在数据结构算法本身,接口的示例和实现都以literate程序的方式给出,换句话说就是源代码及其解释是按照最适合理解代码的顺序交织出现的。 下面我将我想要给大家讲的内容分一下类: 基础 1,接口实现 2,异常与断言 3,内寸管理 4,进一步内寸管理 数据结构 5,链表 6,表格 7,集合 8,动态数组 9,序列 10,环 11,位向量 字符串 12,原子 13,格式化 14,低级字符串 15,高级字符串 算法 16,扩展精度算法 17,任意精度算法 18,多精度算法 线程 19,线程 建议: 看到这里的朋友我相信对c语言都有了很长时间的学习 如果你还没有搞懂c语言的全部内容,我强烈建议你先别看这里
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值