龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

C语言接口与实现方法实例详解(2)

时间:2014-09-11 11:21来源:网络整理 作者:网络 点击:
分享到:
一个高级类型是抽象的,因为接口隐藏了它的表示细节,以免客户调用程序依赖这些细节。下面是一个抽象数据类型(ADT)的规范化例子--堆栈,它定义了

一个高级类型是抽象的,因为接口隐藏了它的表示细节,以免客户调用程序依赖这些细节。下面是一个抽象数据类型(ADT)的规范化例子--堆栈,它定义了该类型以及五种操作:

#ifndef STACK_INCLUDED
#define STACK_INCLUDED
#define T Stack_T
typedef struct T *T;
extern T   Stack_new (void);
extern int  Stack_empty(T stk);
extern void Stack_push (T stk, void *x);
extern void *Stack_pop (T stk);
extern void Stack_free (T *stk);
#undef T
#endif

实现

包含相关头文件:

#include <stddef.h>
#include "assert.h"
#include "mem.h"
#include "stack.h"
#define T Stack_T

Stack_T的内部是一个结构,该结构有个字段指向一个栈内指针的链表以及一个这些指针的计数:

struct T {
  int count;
  struct elem {
    void *x;
    struct elem *link;
  } *head;
};

Stack_new分配并初始化一个新的T:

T Stack_new(void) {
  T stk;
  NEW(stk);
  stk->count = 0;
  stk->head = NULL;
  return stk;
}

其中NEW是一个另一个接口中的一个分配宏指令。NEW(p)将分配该结构的一个实例,并将其指针赋给p,因此Stack_new中使用它就可以分配一个新的Stack_T

当count=0时,Stack_empty返回1,否则返回0:

int Stack_empty(T stk) {
  assert(stk);
  return stk->count == 0;
}

assert(stk)实现了可检查的运行期错误,它禁止空指针传给Stack中的任何函数。

Stack_push和Stack_pop从stk->head所指向的链表的头部添加或移出元素:

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

FREE是另一个接口中定义的释放宏指令,它释放指针参数所指向的空间,然后将参数设为空指针

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

完整实现代码如下:

#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);
}

相信本文所述对大家的C程序设计有一定的借鉴价值。

精彩图集

赞助商链接