天天看點

C語言實作泛型程式設計

泛型程式設計讓你編寫完全一般化并可重複使用的算法,其效率與針對某特定資料類型而設計的算法相同。在c語言中,可以通過一些手段實作這樣的泛型程式設計。這裡介紹一種方法——通過無類型指針void*

看下面的一個實作交換兩個元素内容的函數swap,以整型int為例:

當你想交換兩個char類型時,你還得重寫一個參數類型為char的函數,是不是能用無類型的指針來作為參數呢?看如下改動:

這段代碼是錯誤的,是通不過編譯的。首先,變量是不能聲明為void無類型的。而你不知道調用此函數傳進的參數是什麼類型的,無法确定一種類型的聲

明。同時,不能将*用在無類型指針上,因為系統沒有此位址指向對象大小的資訊。在編譯階段,編譯器無法得知傳入此函數參數的類型的。這裡要想實作泛型的函

數,需要在調用的地方傳入相關要交換的對象的位址空間大小size,同時利用在頭檔案string.h中定義的memcpy()函數來實作。改動如下:

在調用這個函數時,可以像如下這樣調用(同樣适用于其它類型的x、y):

下面看另一種功能的函數:

此函數在數組array中查找key元素,找到後傳回它的索引,找不到傳回-1.如上,也可以實作泛型的函數:

代碼第三行:将數組的首位址強制轉換為指向char類型的指針,是利用char

類型大小為1位元組的特性,使elemaddr指向此”泛型“數組的第i-1個元素的首位址。因為之前已經說過,此時你并不知道你傳入的是什麼類型的資料,

系統無法确定此數組一個元素有多長,跳向下個元素需要多少位元組,是以強制轉換為指向char的指針,再加上參數傳入的元素大小資訊和累加數i的乘積,即偏

移位址,即可得此數組第i-1個元素的首位址。這樣使無論傳入的參數是指向什麼類型的指針,都可以得到指向正确元素的指針,實作泛型程式設計。

函數memcmp()原型:int memcmp(void *dest,const void *src,int n),比較兩段長度為n首位址分别為dest、src的位址空間中的内容。

此函數在數組base中查找key元素,找到則傳回它的位址資訊,找不到則傳回null。

如果使用函數指針,則可以實作其行為的泛型:

再定義一個要調用的函數:

看如下調用:

c語言也可以實作一定的泛型程式設計,但這樣是不安全的,系統對其隻有有限的檢查。在程式設計時一定要多加細心。

繼續閱讀