- ADT和黑盒
C語言可以用於設計和實現抽象數據類型(ADT,abstract data type),因爲它可以限制函數和數據定義的作用域。這個技巧也被稱爲黑盒(black box)設計。抽象數據類型的基本想法是很簡單的——模塊具有功能說明和接口說明,前者說明模塊設計所執行的任務,後者定義模塊的使用。但是,模塊的用戶並不需要知道模塊實現的任何細節,而且除了那些定義好的接口之外,用戶不能以任何方式訪問模塊。限制對模塊的訪問是通過static關鍵字的合理使用實現的,它可以限制對那些並非接口的函數和數據的訪問。例如:
//地址列表模塊的聲明
//數據特徵
//各種數據的最大長度(包括結尾的NUL字節)和地址的最大數量
#define NAME_LENGTH 30 //允許出現的最長名字
#define ADDR_LENGTH 100 //允許出現的最長地址
#define PHONE_LENGTH 11 //允許出現的最長電話號碼
#define MAX_ADDRESSES 1000 //允許出現的最多地址個數
//接口函數
//給出一個名字,查找對應的地址
char const*
lookup_address(char const* name);
//給出一個名字,查找對應的電話號碼
char const*
lookup_phone(char const* name);
//addrlist.h
//地址列表模塊 頭文件
//用於維護一個地址列表的抽象數據類型
#include "aderliti.h"
#include <stdio.h>
//每個地址的三個部分,分別保存於三個數組的對應元素中
static char name[MAX_ADDRESSES][NAME_LENGTH];
static char address[MAX_ADDRESSES][ADDR_LENGTH];
static char phone[MAX_ADDRESSES][PHONE_LENGTH];
//這個函數在數組中查找一個名字並返回查找到的位置下標
//如果這個名字在數組中並不存在,函數返回-1
static int
find_entry(char const *name_to_find)
{
int entry;
for(entry=0;entry<MAX_ADDRESSES;entry+=1)
if(strcmp(name_to_find,name[entry])==0)
return entry;
return -1;
}
//在這個例子裏,接口是函數lookup_address和lookup_phone,但是用戶不能直接訪問和模塊實現有關的數據,如數組或輔助函數find_entry,因爲這些內容被聲明爲static。
- 遞歸
C語言通過運行時堆棧支持遞歸函數的實現。遞歸函數就是直接或間接調用自身的函數。
#include <stdio.h>
void binary_to_ascii(unsigned int value)
{
unsigned int quotient;
quotient=value/10;
if (quotient != 0)
{
binary_to_ascii(quotient);
}
putchar(value%10+'0');
}
//1.將參數值除以10
//2.如果quotient的值爲非零,調用binary_to_ascii打印quotient當前值的各位數字。
//3.接着,打印步驟1中除法運算的餘數。
一旦理解了遞歸,閱讀遞歸函數最容易的方法不是糾纏於它的執行工程,而是相信遞歸函數會順利完成它的任務。如果每個步驟正確無誤,限制條件設置正確,並且每次調用之後更接近限制條件,那麼遞歸函數總是能夠正確地完成任務。