程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C語言接口與實現實例

C語言接口與實現實例

編輯:關於C
一個模塊有兩部分組成:接口和實現。接口指明模塊要做什麼,它聲明了使用該模塊的代碼可用的標識符、類型和例程,實現指明模塊是如何完成其接口聲明的目標的,一個給定的模塊通常只有一個接口,但是可能會有許多種實現能夠提供接口所指定的功能。每個實現可能使用不同的算法和數據結構,但是它們都必須符合接口所給出的使用說明。客戶調用程序是使用某個模塊的一段代碼,客戶調用程序導入接口,而實現導出接口。由於多個客戶調用程序是共享接口和實現的,因此使用實現的目標代碼避免了不必要的代碼重復,同時也有助於避免錯誤,因為接口和實現只需一次編寫和調試就可多次使用。   本文地址:http://www.cnblogs.com/archimedes/p/c-interfaces-implementations.html,轉載請注明源地址。   接口   接口只需要指明客戶調用程序可能使用的標識符即可,應盡可能地隱藏一些無關的表示細節和算法,這樣客戶調用程序可以不必依賴於特定的實現細節。這種客戶調用程序和實現之間的依賴--耦合----可能會在實現改變時引起錯誤,當這種依賴性埋藏在一些關於實現隱藏的或是不明確的假設中時,這些錯誤可能很難修復,因此一個設計良好且描述精確的接口應該盡量減少耦合。     C語言對接口和實現的分離只提供最基本的支持,但是簡單的約定能給接口/實現方法論帶來巨大的好處。在C中,接口在頭文件聲明,頭文件聲明了客戶調用程序可以使用的宏、類型、數據結構、變量以及例程。用戶使用C語言的預處理指令#include導入接口。   下面的例子說明了本篇文章的接口中所使用的一些約定、接口:    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的最大整數   完整實現代碼如下:    arith.c 抽象數據類型 抽象數據類型(abstract data type,ADT)是一個定義了數據類型以及基於該類型值提供的各種操作的接口   一個高級類型是抽象的,因為接口隱藏了它的表示細節,以免客戶調用程序依賴這些細節。下面是一個抽象數據類型(ADT)的規范化例子--堆棧,它定義了該類型以及五種操作:    stack.h 實現 包含相關頭文件:   #include <stddef.h> #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 <stddef.h> #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); }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved