《语言接口与实现》 读书笔记 之 接口与实现

    技术2022-05-12  8

    /****************1.接 *******************/ 用一个例子说明接口中所使用的一些约定: #ifndef ARITH_H#define ARITH_Hextern 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);#endif 接口名字以前缀的形式出现在接口的每一个标识符中,因为在文件范围内所有标识符----变量,函数,类型定义以及枚举常量共享一个专用的名字空寂,而所有的全局结构,结构体,共用体以及枚举标签共享另一个专用的名字空间,所以为了防止名字冲突,采取这种方法。 对于x和y不同符号时,以上几种运算可能在不同编译器下出现不同的结果,所以在实现的时候需要注意。 Arith_div是用更精确的数学术语定义的,Arith_div(x,y)是不超过实数z的最大整数,其中z.y=x. 而c中的内嵌操作,如-13/5则是向0取整,故-13/5=-2。 /*************2.实现*****************/ #include "arith.h"#include <stdio.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;//检测-13/5会是如何的结果    else        return x/y;}int Arith_mod(int x, int y) {    //Arith_mod(x,y)=x-y*Arith_div(x,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);}int main(int argc,char* argv[]){    int a=(-13)/5;    int b=Arith_div(-13,5);    int c=Arith_mod(-13,5);    int d=Arith_ceiling(-13,5);    int e=Arith_floor(-13,5);    printf("a=%d/n",a);     printf("b=%d/n",b);    printf("c=%d/n",c);    printf("d=%d/n",d);    printf("e=%d/n",e);} 一个接口可能有多个实现,但其定义要符合接口的声明,然而c语言中并没有提供某种机制检查实现的一致性/***************3.堆栈***************/我们再来看一个关于抽象数据类型(ADT)的例子:Stack 先看接口: #ifndef STACK_INCLUDED#define STACK_INCLUDED#define T Stack_T/*typedef定义了Stack_T类型,该类型是一个指向有相同名字标签的结构*/typedef struct T *T;/*这里Stack_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 <stdlib.h>#include "assert.h"//该书作者自己写的头文件#include "mem.h"   //该书作者自己写的头文件#include "stack.h"#define T Stack_Tstruct T {    int count;    struct elem     {        void *x;        struct elem *link;    } *head;};//勿忘T Stack_new(void) {    T stk;    NEW(stk);//来自mem.h的方法    stk->count = 0;    stk->head = NULL;    return stk;}int Stack_empty(T stk) {    assert(stk);//来自assert.h的方法    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);//来自mem.h的方法    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);} 当一个抽象数据类型用隐式指针表示时,返回的类型也是一个指针类型,所以把Stack_T定义为一个指向结构体Stack_T的指针,所以以上表达式中,stk可以用用->符号获取结构体元素

    最新回复(0)