一、數據類型:
在任何編程語言中,數據類型作為一個整體,ANSI-C包含的類型為:int、double、char……,程序員很少滿意語言本身提供的數據類型,一個簡單的辦法就是構造類似:array、struct 或union。
那麼,什麼是數據類型呢?我們可以這樣定義:一種數據類型是一些值的集合——通常char類型共有256不同的值,int有更多,double也包含更多的值,但是它通常和數學意義上的實數不同。
相應地,我們可以定義數據類型:包含一些值的集合,在值上面添加一些操作。通常,這些值都是計算機可以表示,同時對其的操作或多或少反應了可行的硬件指令。ANCI-C中的int類型在這方面表現得不是很好:在不同的機器上有不同的值,並且算術右移等操作也可能不同。
例如,通常我們定義一個線性結構的數據結構如下:
typedef node *
並且我們定義如下的操作:
node * head(node * elt, node * tail);
當我們沒有向用戶展現具體實現,稱為抽象數據類型,比如,我們可以從一個隊列中移除一個元素,同事也可以按照一定的順序向其中添加一個元素。
抽象數據類型給程序員提供了最大的靈活性,因為定義中不包含具體的實現,我們可以很自由地選擇任何簡單高效的實現。
抽象數據類型滿足好的編程原則:信息隱藏與分治策略
代表數據項的信息只展現給需要知道的人:對程序員但不對用戶。
通過抽象數據類型,我們可以方便地隔離程序的制定與實現:以自己的方式將一個大的任務拆成小的模塊
三、例子--Set
我們怎樣構建一個抽象數據類型呢?一個集合set包含如下操作:add, find, drop……,它們將提供集合一個元素並且會返回添加的元素。find操作被用作告訴我們是否某一個元素在集合內。
這樣看來,set是一個抽象數據類型,聲明我們對set的操作,從一個Set.h頭文件開始:
SET_H * * add ( * , * * find ( * , * * drop ( * , * contains ( * , * *
Set將在某種程度上展示我們在sets上的操作,add( )向set中添加一個元素,返回是否已經存在於set或是添加成功,find( )在set中尋找一個元素,返回位置或是空指針。drop( )定位一個元素並從set中移除,返回移除元素。contains( )將find( )的結果轉換為一個具體的值。
通用指針void*貫穿始終,一方面,通過它可以隱藏set的一些細節,另一方面,它允許我們虛擬的傳遞任何的類型給add( )以及其他的函數。
四、內存管理
如何獲取一個set集合?Set是一個指針,並不是通過typedef定義的類型,結果,我們不能把Set類型定義為局部變量或是全局變量。相反,我們只能通過使用指針指向sets與其中的元素,在new.h中定義如下代碼:
NEW_H * ( * delete ( *
五、Object
假如我們打算收集set中的任何感興趣的數據,需要另一種數據類型Object,在Object.h中描述如下:
OBJECT_H * Object; differ ( * a, *
通過上述頭文件,可以寫出如下的應用main.c :
View Code七、實現
下面將逐一實現本文所有頭文件中聲明的函數:
實現--Set
main.c 可以成功編譯,但是在編譯和執行程序之前,我們必須實現抽象數據類型和內存管理,如果一個對象不儲存任何信息,並且每一個對象都至少屬於一個set,那麼我們可以用一個唯一的較小的正整數值來表示對象和每一個set,而這些正整數值可以使用一個數組heap[ ]中的索引來表示。
如果一個對象是set的成員,對應的數組元素包含代表set的整數值。
Sets和對象具有相同的展示,new( )不會在意type的類型描述,它將返回heap[ ]中值為0的元素,代碼如下:
! defined MANY || MANY < 1 MANY 10 * ( * * p; (p = heap + ; p < heap + MANY; ++ (! *< heap +* p =
使用0來標記heap[ ]中的有效元素,結果,我們不能返回指向heap[0]的指針----假如是set,其成員可以獲得0索引。new()可能越界,可以使用assert()來避免。elete()必須小心null指針,一個heap[]元素通過被設置為0從而被回收:
delete ( * * item => heap && item < heap +* item =
一個set有所包含的的對象表示:每一個元素指向set,假如一個元素包含MANY,就可以添加到set,否則,說明set中已經包含。
* add ( * _set, * * = * element = > heap && < heap +* ==> heap && element < heap + (* element ==* ( *) element = -* element == - ( *
* find ( * _set, * * = * element = > heap && < heap +* ==> heap && element < heap +* * element == - heap ? ( *) element :
contains ( * _set, * find(_set, _element) !=
* drop ( * _set, * * element =* element =
differ ( * a, * a !=
完整的Set.c源代碼如下:
View Code