《C语言接口与实现:创建可重用软件的技术》一2.2 实现

简介:

本节书摘来自异步社区《C语言接口与实现:创建可重用软件的技术》一书中的第2章,第2.2节,作者 傅道坤,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.2 实现

实现会导出接口。它定义了必要的变量和函数,以提供接口规定的功能。实现具体解释了接口的语义,并给出其表示细节和算法,但在理想情况下,客户程序从来都不需要看到这些细节。不同的客户程序可以共享实现的目标码,通常是从(动态)库加载实现的目标码。

一个接口可以有多个实现。只要实现遵循接口的规定,完全可以在不影响客户程序的情况下改变实现。例如,不同的实现可能会提供更好的性能。设计完善的接口会避免对特定机器的依赖,但也可能强制实现依赖于机器,因此对用到接口的每种机器,可能都需要一个不同的实现(也可能是实现的一部分)来支持。

在C语言中,一个实现通过一个或多个.c文件来提供。实现必须提供其导出的接口规定的功能。实现会包含接口的.h文件,以确保其定义与接口的声明一致。但除此之外,C语言中没有其他语言机制来检查实现与接口是否符合。

如同本书中的接口,本书描述的实现也具有一种风格化的格式,如arith.c所示:

〈arith.c〉≡ 
 #include "arith.h" 
 〈arith.c  functions 14〉 

〈arith.c functions  14〉≡ 
 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.c functions 14〉,更复杂的实现可能包含名为〈data〉、〈types〉、〈macros〉、〈prototypes〉等的代码块。在不会造成混淆时,代码块中的文件名(如arith.c)将略去。

在Arith_div的参数符号不同时,它必须处理除法的两种可能行为。如果除法向零舍入,而y不能整除x,那么Arith_div(x,y)的结果为x/y - 1,否则,返回x/y即可:

〈arith.c _functions _14_〉+≡ 
int Arith_div(int x, int y) { 
  if (〈division truncates toward 0 14〉
  && 〈x and y have different signs 14〉 && x%y != 0) 
    return x/y - 1; 
  else 
    return x/y; 
}

前一节的例子,即将-13除以5,可以测试除法所采用的舍入方式。首先判断x和y是否小于0,然后比较两个判断结果是否相等,即可检查符号问题:

〈division truncates toward 0 14〉≡ 
 -13/5 == -2 

〈x and y have different signs  14〉≡ 
 (x < 0) != (y < 0)

Arith_mod可以按其定义实现:

int Arith_mod(int x, int y) { 
  return x - y*Arith_div(x, y); 
}

如果Arith_mod也像Arith_div那样进行判断,那么也可以使用%运算符实现。在相应的条件为真时,

Arith_mod(x,y) = x - y*Arith_div(x, y)
        = x - y*(x/y - 1)
        = x - y*(x/y) + y

加下划线的子表达式是标准C对x%y的定义,因此Arith_mod可定义为:

〈arith.c functions 14〉+≡ 
 int Arith_mod(int x, int y) { 
   if (〈division truncates toward 0 14〉
   && 〈x and y have different signs 14〉 && x%y != 0) 
     return x%y + y; 
   else 
     return x%y; 
}

Arith_floor刚好等于Arith_div,而Arith_ceiling等于Arith_div加1,除非y能整除x:

〈arith.c functions 14〉+≡
 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); 
}
相关文章
|
4天前
|
存储 自然语言处理 编译器
振南技术干货集:振南当年入门C语言和单片机的那些事儿(3)
振南技术干货集:振南当年入门C语言和单片机的那些事儿(3)
|
4天前
|
存储 移动开发 Shell
振南技术干货集:C语言的一些“骚操作”及其深层理解(2)
振南技术干货集:C语言的一些“骚操作”及其深层理解(2)
|
4月前
|
前端开发 算法 JavaScript
【新手解答3】深入探索 C 语言:头文件提供必要的接口、源文件保持实现细节的私有性 + 进一步学习的方向 + 如何快速编写程序并最终能制作小游戏
【新手解答3】深入探索 C 语言:头文件提供必要的接口、源文件保持实现细节的私有性 + 进一步学习的方向 + 如何快速编写程序并最终能制作小游戏
61 0
|
4月前
|
存储 C语言
探索顺序表:数据结构中的秩序之美(c语言实现常见功能接口)
探索顺序表:数据结构中的秩序之美(c语言实现常见功能接口)
38 0
|
5月前
|
安全 Linux 程序员
「技术干货」一文搞懂C语言内存模型与栈
「技术干货」一文搞懂C语言内存模型与栈
|
7月前
|
测试技术 API C语言
C语言实现一个简易版的打字软件
C语言实现一个简易版的打字软件
79 0
|
7月前
|
存储 安全 Java
使您的软件运行起来: 防止缓冲区溢出(C语言精华帖)
使您的软件运行起来: 防止缓冲区溢出(C语言精华帖)
38 1
|
C语言
造轮子之-C语言实现ArrayList
造轮子之-C语言实现ArrayList
|
10月前
|
程序员 C语言 C++
编程最重要的技术—调试(以C语言代码为例)
编程最重要的技术—调试(以C语言代码为例)
|
C语言
C语言实现学生成绩管理系统
本文提供一例C语言实现的命令行学生信息管理系统,供初学者参考。
291 0