C语言接口的使用方法

客户调用程序是使用某个模块的一段代码,客户调用程序导入接口,而实现导出接口。由于多个客户调用程序是共享接口和实现的,因此使用实现的目标代码避免了不必要的代码重复,同时也有助于避免错误,因为接口和实现只需一次编写和调试就可多次使用。以下是小编为大家搜索整理的C语言接口的使用方法,希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业生考试网!

一个模块有两部分组成:接口和实现。接口指明模块要做什么,它声明了使用该模块的代码可用的标识符、类型和例程,实现指明模块是如何完成其接口声明的目标的,一个给定的模块通常只有一个接口,但是可能会有许多种实现能够提供接口所指定的功能。每个实现可能使用不同的算法和数据结构,但是它们都必须符合接口所给出的使用说明。客户调用程序是使用某个模块的一段代码,客户调用程序导入接口,而实现导出接口。由于多个客户调用程序是共享接口和实现的,因此使用实现的目标代码避免了不必要的代码重复,同时也有助于避免错误,因为接口和实现只需一次编写和调试就可多次使用。

接口只需要指明客户调用程序可能使用的标识符即可,应尽可能地隐藏一些无关的表示细节和算法,这样客户调用程序可以不必依赖于特定的实现细节。这种客户调用程序和实现之间的依赖--耦合----可能会在实现改变时引起错误,当这种依赖性埋藏在一些关于实现隐藏的或是不明确的假设中时,这些错误可能很难修复,因此一个设计良好且描述精确的接口应该尽量减少耦合。

C语言对接口和实现的分离只提供最基本的支持,但是简单的约定能给接口/实现方法论带来巨大的好处。在C中,接口在头文件声明,头文件声明了客户调用程序可以使用的宏、类型、数据结构、变量以及例程。用户使用C语言的预处理指令#include导入接口。

下面的例子说明了本篇文章的接口中所使用的一些约定、接口:

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

该接口的名字为Arith,接口头文件也相应地命名为arith.h,接口的名字以前缀的形式出现在接口的每个标识符中。模块名不仅提供了合适的前缀,而且还有助于整理客户调用程序代码。

Arith接口还提供了一些标准C函数库中没有但是很有用的函数,并为出发和取模提供了良好的定义,而标准C中并没有给出这些操作的定义和只提供基于实现的定义。

实现

一个实现导出一个接口,它定义了必要的变量和函数以提供接口所规定的功能,在C语言中,一个实现是由一个或多个.c文件提供的,一个实现必须提供其导出的接口所指定的功能。实现应包含接口的.h文件,以保证它的定义和接口的声明时一致的.。

Arith_min和Arith_max返回其整型参数中的最小值和最大值:

int 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的内嵌操作的返回值就取决于具体的实现:

eg.如果-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的最大整数

完整实现代码如下:

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

}

arith.c

抽象数据类型

抽象数据类型(abstract data type,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

stack.h

实现

包含相关头文件:

#include

#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

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

}

stack.c

【C语言接口的使用方法】相关文章:

c语言 接口调用,C语言接口的使用方法相关推荐

  1. c语言实现爬虫功能,用C/C 扩展Python语言_python 调用c语言 python实现简单爬虫功能_python实现简单爬虫...

    用C/C 扩展Python语言 Python是一门功能强大的脚本语言,它的强大不仅表现在功能上,还表现在其扩展性上.她提供大量的API以方便程序员利用C/C++对Python进行扩展.因为执行速度慢几 ...

  2. 淘宝,tmall,1688,抖音,拼多多等平台商品详情接口(网络爬虫数据接口调用示例)接口对接教程

    淘宝,tmall,1688,抖音,拼多多等平台商品详情接口(网络爬虫数据接口调用示例)接口对接教程如下: 1.公共参数 名称 类型 必须 描述(接口代码教程wx19970108018) key Str ...

  3. 高德地图api接口文档_在 R 语言里面调用高德地图接口:地理编码与路径规划

    你知道从广州南站去珠江新城怎么走么?今天就让我们一起使用 R 语言调用高德地图的地理编码(地址转经纬度)接口和路径规划接口来回答这个问题. 准备工作 注册高德地图,创建应用添加 Key(注意申请 Ke ...

  4. 易语言c调用,易语言调用C++编写的DLL

    511遇见网站最近在录制一套易语言编写DLL及调用和Hook,今天记录一下使用VS2015编写一个C++的Dll,易语言来调用. 步骤: 1.启动VS2015 2.创建工程 3.Visual C++ ...

  5. python怎么调用c语言_Python调用C语言程序方法解析

    Python调用C语言程序方法解析 首先我们需要将编写好的c程序文件编译为动态库文件(后缀名为.so) 使用下面的命令: gcc 原文件名.c -shared -o 新文件名.so 然后在python ...

  6. java 调用c语言_Java 调用C语言JNI库(Hello World实例)

    要在java中调用c语言的库,一直觉得很不可思议,但是Java提供了JNI这个东西,这也就变得可能了. 作为一个码农,我们还是从最简单的 Hello World开始吧. 首先说一下我们想要做的事情. ...

  7. C语言中调用数组元素的三种方法:下标法、数组名法、指针法

    /*调用数组元素的三种方法:下标法.数组名法.指针法*/ #include<stdio.h> int main() {int a[] = { 1,2,3,4,5 }, i, * p;pri ...

  8. JAVA语言怎么调用短信接口

    * 接口类型:触发短信接口,支持发送验证码短信.订单通知短信等.  * 账户注册:请通过该地址开通账户 http://user.ihuyi.com/?exClaO   * 注意事项: *(1)调试期间 ...

  9. c语言xml库调用方法,c语言如何调用xml的接口函数?

    富国沪深 1.Libxml2 是一个xml c语言版的解析器,本来是为Gnome项目开发的工具,是一个基于MIT License的免费开源软件.它除了支持c语言版以外,还支持c++.PHP.Pasca ...

最新文章

  1. 解决android引用library project错误
  2. 游戏人工智能开发之6种决策方法
  3. LBO验证与LBO_full验证的区别
  4. Leetcode 82. Remove Duplicates from Sorted List II
  5. BZOJ4300 绝世好题
  6. SpringBoot MySql Druid配置主从数据源(多个数据源)
  7. 2015年蓝桥杯省赛A组c++第4题
  8. shiro-cas------整合springboot客户端
  9. C++11 现代C++风格的新元素--简介
  10. 七个非常好用的黑科技APP,免费/小众/超实用,一次性全给你
  11. Android 汽车电子功能安全模块化设计思路
  12. php机器人聊天对话框,PHP实现QQ聊天机器人
  13. 怎么用计算机圣诞节快乐,【计算机·图文】圣诞节快乐—圣诞节故事
  14. 银河麒麟高级服务器v10 sp1 搭建局域网yum源(同步阿里yum源centos7.9)
  15. 永恒之黑(CVE-2020-0796 微软SMBv3协议远程代码执行漏洞)
  16. 跨境电商的三个增长点:产品曝光 品类轮转 入自建站
  17. 中国56个民族拼音表
  18. 难上加难?女性在技术领域可以这样做……
  19. 入门级短信推送,你还不会吗?
  20. Notepad++ 设置tab为N个空格

热门文章

  1. mysql数据库异地恢复_数据库的异地备份恢复及恢复
  2. 《互联网DSP广告揭秘——精准投放与高效转化之道》一一1.9 程序化交易广告的前世今生 ...
  3. Wireshark -IO图表获得各个信息的对比
  4. 「java工程师」常见面试题及其答案(持续更新)
  5. 苹果无法安装计算机,“windows 无法更新计算机的启动配置。安装无法继续”这样解决...
  6. 无线水标数值如何上传服务器,一种精准上传数据的智能水表及用水量记录上传方法...
  7. textmate 主题_更漂亮的TextMate
  8. 【科研入门】Latex论文写作辅助工具及期刊查询网站
  9. 「 LaTex 」写论文,Springer杂志插入ORCID
  10. 青春与阳光——李宇春日记