接口实现
重点内容在本书中的第二章中,介绍了接口的封装例子。
1. 接口定义
C语言中可将接口封装好,让后以.h文件作文扩展,简单例子:
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.h中声明。
以上6个函数都是对两个数的操作,求最大值,求最小值,除法,向上去整,向下取整。个人觉得对于定义接口的话,主要是找对最佳的函数参数,返回值,这一步比较简单。
2. 具体实现
这几个函数的实现比较简单,不过,作为一个接口封装的例子,比较好地诠释了一个过程。
int Arith_max(int x, int y)
{
int max = 0;
if(x >= y)
max = x;
else
max = y;
return 0;
}
int Arith_min(int x, int y)
{
int min = 0;
if(x >= y)
min = y;
else
min = x;
return 0;
}
对于除法来说,其中会涉及到内建的操作符;也可通过除法来做取余操作,不过,通过负数除正数,单纯地以内建除法来做,结果会向零舍入,比如:-13/5 = -2 结果如果以Int来算话。书中原话介绍。
The built-in operators are thus useful only for positive operands. The standard library functions div and ldiv take two integers or long integers and return the quotient and remainder in the quot and rem fields of a structure. Their semantics are well defined: they always truncatetoward zero, so div(-13, 5).quot is always equal to −2.
int Arith_div(int x,int y)
{
if((-13/5)&&
((x<0)!=(y<0))&&
(x%y != 0))
return x/y - 1;
else
return x/y;
}
/*上面的条件(-13/5)得到判断内建除法 结果会得到-2,可以试试,但是用windows计算器计算-13/5会得到-3,这就是经过处理了。*/
int Arith_mod(int x, int y) {
return x - y*Arith_div(x, y);
}
3. 抽象类型
在这个小节中,用C语言的抽象方式,来对一个栈进行定义与实现。根据自己的理解,对书中的代码有些许改动,更好地理解。
stack.h
#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 "stack.h"
#define T Stack_T
struct T {
int count;
struct elem {
void *x;
struct elem *link;
} *head;
};
T Stack_new(void) {
T stk;
stk = malloc(sizeof(stk));
stk->count = 0;
stk->head = NULL;
return stk;
}
void Stack_push(T stk, void *x) {
struct elem *t;
assert(stk);
t = malloc(sizeof(struct elem));
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);
}
int Stack_empty(const struct T *stk) {
assert(stk);
return stk->count == 0;
}
main.c
#include"stack.h"
int main()
{
Stack_T s;
s = Stack_new();
char x[] = "123";
Stack_push(s,x);
printf("%s\n", (char*)Stack_pop(s));
Stack_push(s, x);
if (Stack_empty(s) != 0)
Stack_free(s);
return 0;
}