最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言接口與實(shí)現(xiàn)方法實(shí)例詳解

 更新時間:2014年09月10日 10:14:07   投稿:shichen2014  
這篇文章主要介紹了C語言接口與實(shí)現(xiàn)方法,包括接口的概念、實(shí)現(xiàn)方法及抽象數(shù)據(jù)類型等,并配合實(shí)例予以說明,需要的朋友可以參考下

本文以實(shí)例形式詳細(xì)講述了C語言接口與實(shí)現(xiàn)方法,對于深入掌握C語言程序設(shè)計(jì)有一定的借鑒價值。分享給大家供大家參考。具體分析如下:

一般來說,一個模塊有兩部分組成:接口和實(shí)現(xiàn)。接口指明模塊要做什么,它聲明了使用該模塊的代碼可用的標(biāo)識符、類型和例程,實(shí)現(xiàn)指明模塊是如何完成其接口聲明的目標(biāo)的,一個給定的模塊通常只有一個接口,但是可能會有許多種實(shí)現(xiàn)能夠提供接口所指定的功能。每個實(shí)現(xiàn)可能使用不同的算法和數(shù)據(jù)結(jié)構(gòu),但是它們都必須符合接口所給出的使用說明。客戶調(diào)用程序是使用某個模塊的一段代碼,客戶調(diào)用程序?qū)虢涌冢鴮?shí)現(xiàn)導(dǎo)出接口。由于多個客戶調(diào)用程序是共享接口和實(shí)現(xiàn)的,因此使用實(shí)現(xiàn)的目標(biāo)代碼避免了不必要的代碼重復(fù),同時也有助于避免錯誤,因?yàn)榻涌诤蛯?shí)現(xiàn)只需一次編寫和調(diào)試就可多次使用。

接口

接口只需要指明客戶調(diào)用程序可能使用的標(biāo)識符即可,應(yīng)盡可能地隱藏一些無關(guān)的表示細(xì)節(jié)和算法,這樣客戶調(diào)用程序可以不必依賴于特定的實(shí)現(xiàn)細(xì)節(jié)。這種客戶調(diào)用程序和實(shí)現(xiàn)之間的依賴--耦合----可能會在實(shí)現(xiàn)改變時引起錯誤,當(dāng)這種依賴性埋藏在一些關(guān)于實(shí)現(xiàn)隱藏的或是不明確的假設(shè)中時,這些錯誤可能很難修復(fù),因此一個設(shè)計(jì)良好且描述精確的接口應(yīng)該盡量減少耦合。

C語言對接口和實(shí)現(xiàn)的分離只提供最基本的支持,但是簡單的約定能給接口/實(shí)現(xiàn)方法論帶來巨大的好處。在C中,接口在頭文件聲明,頭文件聲明了客戶調(diào)用程序可以使用的宏、類型、數(shù)據(jù)結(jié)構(gòu)、變量以及例程。用戶使用C語言的預(yù)處理指令#include導(dǎo)入接口。

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

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,接口頭文件也相應(yīng)地命名為arith.h,接口的名字以前綴的形式出現(xiàn)在接口的每個標(biāo)識符中。模塊名不僅提供了合適的前綴,而且還有助于整理客戶調(diào)用程序代碼。

Arith接口還提供了一些標(biāo)準(zhǔn)C函數(shù)庫中沒有但是很有用的函數(shù),并為出發(fā)和取模提供了良好的定義,而標(biāo)準(zhǔn)C中并沒有給出這些操作的定義和只提供基于實(shí)現(xiàn)的定義。

實(shí)現(xiàn)

一個實(shí)現(xiàn)導(dǎo)出一個接口,它定義了必要的變量和函數(shù)以提供接口所規(guī)定的功能,在C語言中,一個實(shí)現(xiàn)是由一個或多個.c文件提供的,一個實(shí)現(xiàn)必須提供其導(dǎo)出的接口所指定的功能。實(shí)現(xiàn)應(yīng)包含接口的.h文件,以保證它的定義和接口的聲明時一致的。

Arith_min和Arith_max返回其整型參數(shù)中的最小值和最大值:

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返回相應(yīng)的余數(shù)。當(dāng)x與y同號的時候,Arith_div(x,y)等價于x/y,Arith_mod(x,y)等價于x%y

當(dāng)x與y的符號不同的時候,C的內(nèi)嵌操作的返回值就取決于具體的實(shí)現(xiàn):

如果-13/5=2,-13%5=-3,如果-13/5=-3,-13%5=2

標(biāo)準(zhǔn)庫函數(shù)總是向零取整,因此div(-13,2)=-2,Arith_div和Arith_mod的語義同樣定義好了:它們總是趨近數(shù)軸的左側(cè)取整,因此Arith_div(-13,5)=-3,Arith_div(x,y)是不超過實(shí)數(shù)z的最大整數(shù),其中z滿足z*y=x。

Arith_mod(x,y)被定義為x-y*Arith_div(x,y)。因此Arith_mod(-13,5)=-13-5*(-3)=2

函數(shù)Arith_ceiling和Arith_floor遵循類似的約定,Arith_ceiling(x,y)返回不小于實(shí)數(shù)商x/y的最小整數(shù)

Arith_floor(x,y)返回不超過實(shí)數(shù)商x/y的最大整數(shù)

完整實(shí)現(xiàn)代碼如下:

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

抽象數(shù)據(jù)類型

抽象數(shù)據(jù)類型(abstract data type,ADT)是一個定義了數(shù)據(jù)類型以及基于該類型值提供的各種操作的接口

一個高級類型是抽象的,因?yàn)榻涌陔[藏了它的表示細(xì)節(jié),以免客戶調(diào)用程序依賴這些細(xì)節(jié)。下面是一個抽象數(shù)據(jù)類型(ADT)的規(guī)范化例子--堆棧,它定義了該類型以及五種操作:

#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

實(shí)現(xiàn)

包含相關(guān)頭文件:

#include <stddef.h>
#include "assert.h"
#include "mem.h"
#include "stack.h"
#define T Stack_T

Stack_T的內(nèi)部是一個結(jié)構(gòu),該結(jié)構(gòu)有個字段指向一個棧內(nèi)指針的鏈表以及一個這些指針的計(jì)數(shù):

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)將分配該結(jié)構(gòu)的一個實(shí)例,并將其指針賦給p,因此Stack_new中使用它就可以分配一個新的Stack_T

當(dāng)count=0時,Stack_empty返回1,否則返回0:

int Stack_empty(T stk) {
  assert(stk);
  return stk->count == 0;
}

assert(stk)實(shí)現(xiàn)了可檢查的運(yùn)行期錯誤,它禁止空指針傳給Stack中的任何函數(shù)。

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是另一個接口中定義的釋放宏指令,它釋放指針參數(shù)所指向的空間,然后將參數(shù)設(shè)為空指針

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

完整實(shí)現(xiàn)代碼如下:

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

相信本文所述對大家的C程序設(shè)計(jì)有一定的借鑒價值。

相關(guān)文章

  • C++利用GPAC實(shí)現(xiàn)生成MP4文件的示例代碼

    C++利用GPAC實(shí)現(xiàn)生成MP4文件的示例代碼

    GPAC主要針對學(xué)生和內(nèi)容創(chuàng)作者,代表了一個跨平臺的多媒體框架,開發(fā)人員可以使用它在?LGPL?許可下制作開源媒體。本文就來用GPAC實(shí)現(xiàn)生成MP4文件,感興趣的可以了解一下
    2023-02-02
  • C語言中const與指針使用方法總結(jié)

    C語言中const與指針使用方法總結(jié)

    這篇文章主要介紹了C語言中const與指針使用方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-10-10
  • Qt Designer的簡單使用方法

    Qt Designer的簡單使用方法

    用 C++ 代碼編寫圖形界面的問題就是不直觀,因此 Qt 項(xiàng)目開發(fā)了專門的可視化圖形界面編輯器,本文就詳細(xì)的介紹一下
    2021-08-08
  • C語言實(shí)現(xiàn)小學(xué)生隨機(jī)出題測試計(jì)分

    C語言實(shí)現(xiàn)小學(xué)生隨機(jī)出題測試計(jì)分

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)小學(xué)生隨機(jī)出題測試計(jì)分,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • C++實(shí)現(xiàn)Huffman的編解碼

    C++實(shí)現(xiàn)Huffman的編解碼

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)Huffman的編解碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C++11?中的override詳解

    C++11?中的override詳解

    這篇文章主要介紹了C++11?中的override詳解,本文以重寫虛函數(shù)時,容易犯的四個錯誤為例,結(jié)合示例代碼給大家詳細(xì)介紹,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 詳解C++ string常用截取字符串方法

    詳解C++ string常用截取字符串方法

    這篇文章主要介紹了C++ string常用截取字符串方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • C++異常處理入門(try和catch)

    C++異常處理入門(try和catch)

    C++ 提供了異常機(jī)制,讓我們能夠捕獲運(yùn)行時錯誤,本文就詳細(xì)的介紹了C++異常處理入門,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++使用正則表達(dá)式的詳細(xì)教程

    C++使用正則表達(dá)式的詳細(xì)教程

    正則表達(dá)式是一個非常強(qiáng)大的工具,主要用于字符串匹配,下面這篇文章主要給大家介紹了關(guān)于C++使用正則表達(dá)式的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • 簡單談?wù)凜++ 頭文件系列之(algorithm)

    簡單談?wù)凜++ 頭文件系列之(algorithm)

    <algorithm>是c++特有的STL模板的算法頭文件 包含了一些特定的算法函數(shù) 包括sort(),stable_sort(),partical_sort(),nth_element()等常用的算法函數(shù)
    2017-02-02

最新評論

五大连池市| 浠水县| 德州市| 灵宝市| 且末县| 墨玉县| 普洱| 长岛县| 大城县| 淮安市| 黎城县| 武安市| 淮安市| 新干县| 普兰县| 鄂托克前旗| 呼玛县| 息烽县| 宁国市| 修武县| 涿鹿县| 犍为县| 且末县| 华池县| 武乡县| 延庆县| 太仆寺旗| 西华县| 德阳市| 永仁县| 西青区| 黄龙县| 盐边县| 清新县| 南陵县| 英超| 肃北| 淄博市| 满城县| 青海省| 五台县|