c语言系统api,C语言接口与实现方法实例详解
2014
本文以实例形式详细讲述了C语言接口与实现方法,对于深入掌握C语言程序设计有一定的借鉴价值。分享给大家供大家参考。具体分析如下:
一般来说,一个模块有两部分组成:接口和实现。接口指明模块要做什么,它声明了使用该模块的代码可用的标识符、类型和例程,实现指明模块是如何完成其接口声明的目标的,一个给定的模块通常只有一个接口,但是可能会有许多种实现能够提供接口所指定的功能。每个实现可能使用不同的算法和数据结构,但是它们都必须符合接口所给出的使用说明。客户调用程序是使用某个模块的一段代码,客户调用程序导入接口,而实现导出接口。由于多个客户调用程序是共享接口和实现的,因此使用实现的目标代码避免了不必要的代码重复,同时也有助于避免错误,因为接口和实现只需一次编写和调试就可多次使用。
接口
接口只需要指明客户调用程序可能使用的标识符即可,应尽可能地隐藏一些无关的表示细节和算法,这样客户调用程序可以不必依赖于特定的实现细节。这种客户调用程序和实现之间的依赖--耦合----可能会在实现改变时引起错误,当这种依赖性埋藏在一些关于实现隐藏的或是不明确的假设中时,这些错误可能很难修复,因此一个设计良好且描述精确的接口应该尽量减少耦合。
C语言对接口和实现的分离只提供最基本的支持,但是简单的约定能给接口/实现方法论带来巨大的好处。在C中,接口在头文件声明,头文件声明了客户调用程序可以使用的宏、类型、数据结构、变量以及例程。用户使用C语言的预处理指令#include导入接口。
下面的例子说明了本篇文章的接口中所使用的一些约定、接口:
1
2
3
4
5
6extern 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,接口头文件也相应地命名为arith.h,接口的名字以前缀的形式出现在接口的每个标识符中。模块名不仅提供了合适的前缀,而且还有助于整理客户调用程序代码。
Arith接口还提供了一些标准C函数库中没有但是很有用的函数,并为出发和取模提供了良好的定义,而标准C中并没有给出这些操作的定义和只提供基于实现的定义。
实现
一个实现导出一个接口,它定义了必要的变量和函数以提供接口所规定的功能,在C语言中,一个实现是由一个或多个.c文件提供的,一个实现必须提供其导出的接口所指定的功能。实现应包含接口的.h文件,以保证它的定义和接口的声明时一致的。
Arith_min和Arith_max返回其整型参数中的最小值和最大值:
1
2
3
4
5
6int Arith_max(int x,int y) {
return x > y ? x : y;
}
int Arith_min(int x,int y) {
return x > y ? y : x;
}
Arith_div返回y除以x得到的商,Arith_mod返回相应的余数。当x与y同号的时候,Arith_div(x,y)等价于x/y,Arith_mod(x,y)等价于x%y
当x与y的符号不同的时候,C的内嵌操作的返回值就取决于具体的实现:
如果-13/5=2,-13%5=-3,如果-13/5=-3,-13%5=2
标准库函数总是向零取整,因此div(-13,2)=-2,Arith_div和Arith_mod的语义同样定义好了:它们总是趋近数轴的左侧取整,因此Arith_div(-13,5)=-3,Arith_div(x,y)是不超过实数z的最大整数,其中z满足z*y=x。
Arith_mod(x,y)被定义为x-y*Arith_div(x,y)。因此Arith_mod(-13,5)=-13-5*(-3)=2
函数Arith_ceiling和Arith_floor遵循类似的约定,Arith_ceiling(x,y)返回不小于实数商x/y的最小整数
Arith_floor(x,y)返回不超过实数商x/y的最大整数
完整实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#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);
}
抽象数据类型
抽象数据类型(abstract data type,ADT)是一个定义了数据类型以及基于该类型值提供的各种操作的接口
一个高级类型是抽象的,因为接口隐藏了它的表示细节,以免客户调用程序依赖这些细节。下面是一个抽象数据类型(ADT)的规范化例子--堆栈,它定义了该类型以及五种操作:
1
2
3
4
5
6
7
8
9
10
11#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
实现
包含相关头文件:
1
2
3
4
5#include
#include "assert.h"
#include "mem.h"
#include "stack.h"
#define T Stack_T
Stack_T的内部是一个结构,该结构有个字段指向一个栈内指针的链表以及一个这些指针的计数:
1
2
3
4
5
6
7struct T {
int count;
struct elem {
void *x;
struct elem *link;
} *head;
};
Stack_new分配并初始化一个新的T:
1
2
3
4
5
6
7T 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:
1
2
3
4int Stack_empty(T stk) {
assert(stk);
return stk->count == 0;
}
assert(stk)实现了可检查的运行期错误,它禁止空指针传给Stack中的任何函数。
Stack_push和Stack_pop从stk->head所指向的链表的头部添加或移出元素:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21void 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是另一个接口中定义的释放宏指令,它释放指针参数所指向的空间,然后将参数设为空指针
1
2
3
4
5
6
7
8
9void 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);
}
完整实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#include
#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程序设计有一定的借鉴价值。
c语言系统api,C语言接口与实现方法实例详解相关推荐
- c语言字符串正序反序连接输出,C语言中字符串实现正序与逆序实例详解
C语言中字符串实现逆序实例详解 字符串逆序和正序的实现代码: #include #include #include #include #include /*定义*/ typedef struct no ...
- ∑ n!(1! 2!)用c语言怎么编,数控车床编程教程,图文实例详解!
原标题:数控车床编程教程,图文实例详解! 第一节数控车床编程基础 一.数控车编程特点 (1) 可以采用绝对值编程(用X.Z表示).增量值编程(用U.W表示)或者二者混合编程. (2) 直径方向(X方向 ...
- c 语言 组合数,C++中求组合数的各种方法总结详解
[问题] 组合问题 问题描述:找出从自然数1.2.... .n中任取r个数的所有组合.例如n=5,r=3的所有组合为: 1,2,3 1,2,4 1,3,4 2,3,4 1,2,5 1,3,5 ...
- php微信接口怎么开发,php微信公众平台配置接口开发程序的方法实例详解
这篇文章主要为大家详细介绍了php微信公众平台配置接口开发程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 在阅读这篇文章之前你要做以下的准备: 1.注册一个订阅号(通过微信公众平台https: ...
- android系统旁边有一个锁,Android中系统自带锁WalkLock与KeyguardLock用法实例详解
本文实例讲述了Android中系统自带锁WalkLock与KeyguardLock用法.分享给大家供大家参考,具体如下: WalkLock - 顾名思义 唤醒锁 点亮屏幕用的 KeyguardLock ...
- 系统应用:Windows的故障恢复控制台应用实例详解
当Windows 2000/XP/2003出现了启动故障,而且在安全模式或其他模式下都启动无效时,很多朋友首先想到的就是重装系统.其实不必.这时我们首先应该考虑使用Windows的"故障恢复 ...
- 3.Pytorch基础模块torch的API之Indexing,Slicing,Joining,Mutating Ops实例详解
文章目录 0. torch 1. Tensors 2. Creation Ops 3. Indexing,Slicing,Joining,Mutating Ops 3.1 torch.cat() 3. ...
- solidworks api二次开发实例详解_Solidworks开发语言对比及分析
很多初学Solidworks二次开发的同学,也许都会纠结使用何种语言进行二次开发.对于Solidworks二次开发的语言,官方有VBA,VB.NET,C#以及C++,四种语言. 用户通常会有如下疑问, ...
- C 语言中获取系统时间的函数,C/C++如何获取当前系统时间的实例详解
C/C++如何获取当前系统时间的实例详解 C库中与系统时间相关的函数定义在头文件中, C++定义在头文件中. 一.time(time_t*)函数 函数定义如下: time_t time (time_t ...
最新文章
- 【动态规划】Part1
- 数据结构----单链表增删改查
- Mapped Statements collection does not contain value for TaskMapper.selectByPrimaryKey
- elasticsearch 第三篇(安装篇)
- 配置ftp服务器亲测可用
- NOIP2010排队接水
- 浙江师范大学python试卷_2014考研计算机真题试卷及答案(浙江师范大学考点)
- centos7.3下apache搭建django[未成功]
- 推荐系统之---如何理解低秩矩阵?
- BAPI_SALESDOCU_CREATEFROMDATA1--VA01
- iOS8 获取通知设置状态
- html插入循环图片,javascript – HTML5在带有for循环的画布上绘制图片?
- 你会用JSON.stringify()?
- Opencv LBP特征
- BS7799系列讲座:HTP模型图及构建(转载)
- MATLAB中fspecial()函数的用法
- 手机测试陨石软件,鉴定陨石真伪的简单测试方法
- iPhone入门学习汇总
- 微信二维码扫一扫打开手机外部浏览器打开指定HTML网页
- 国内洗地机品牌排行榜前十名有哪些?洗地机十大品牌排行榜介绍
热门文章
- 小狗电器发布新品卧吸S9 AWE演绎碾压级最强吸力
- Kubernetes资源编排系列之五: OAM篇
- MOBA电竞游戏:Zuki Moba
- 美团陷“内斗”拼多多站点关停 社区团购巨头在五环内失速
- 什么是file handle?
- Cadence Allegro 技巧实战视频之原理图符号-调整芯片引脚技巧
- 涿州不低调 再创环京价值至高点
- python拼多多1分抢手机_拼多多1分钱拼手机真相(拼多多一分钱手机套路曝光)...
- 《Python 程序设计》张莉主编 第三章节:序列 课后习题答案
- 恒必达智能蓝牙耳机——解放自我的突破