泛型程式設計讓你編寫完全一般化並可重複使用的演算法,其效率與針對某特定資料型別而設計的演算法相同。在c語言中,可以通過一些手段實現這樣的泛型程式設計。這裡介紹一種方法——通過無型別指標void*
看下面的乙個實現交換兩個元素內容的函式swap,以整型int為例:
void swap(int* i1,int* i2)
當你想交換兩個char型別時,你還得重寫乙個引數型別為char的函式,是不是能用無型別的指標來作為引數呢?看如下改動:
void swap(void *vp1,void *vp2)
這段**是錯誤的,是通不過編譯的。首先,變數是不能宣告為void無型別的。而你不知道呼叫此函式傳進的引數是什麼型別的,無法確定一種型別的聲 明。同時,不能將*用在無型別指標上,因為系統沒有此位址指向物件大小的資訊。在編譯階段,編譯器無法得知傳入此函式引數的型別的。這裡要想實現泛型的函 數,需要在呼叫的地方傳入相關要交換的物件的位址空間大小size,同時利用在標頭檔案string.h中定義的memcpy()函式來實現。改動如下:
void swap(void *vp1,void *vp2,int size)
在呼叫這個函式時,可以像如下這樣呼叫(同樣適用於其它型別的x、y):
int x = 27,y = 2;swap(&x,&y,sizeof(int));
下面看另一種功能的函式:
int lsearch(int key,int array,int size)
此函式在陣列array中查詢key元素,找到後返回它的索引,找不到返回-1.如上,也可以實現泛型的函式:
void* lsearch(void* key, void *base, int n, int elemsize)return null;
}
**第三行:將陣列的首位址強制轉換為指向char型別的指標,是利用char 型別大小為1位元組的特性,使elemaddr指向此」泛型「陣列的第i-1個元素的首位址。因為之前已經說過,此時你並不知道你傳入的是什麼型別的資料, 系統無法確定此陣列乙個元素有多長,跳向下個元素需要多少位元組,所以強制轉換為指向char的指標,再加上引數傳入的元素大小資訊和累加數i的乘積,即偏 移位址,即可得此陣列第i-1個元素的首位址。這樣使無論傳入的引數是指向什麼型別的指標,都可以得到指向正確元素的指標,實現泛型程式設計。
此函式在陣列base中查詢key元素,找到則返回它的位址資訊,找不到則返回null。
如果使用函式指標,則可以實現其行為的泛型:
void *lsearch(void *key,void *base,int n,int elemsize,int(*cmpfn)(void*,void*,int))return null;
}
再定義乙個要呼叫的函式:
int intcmp(void* elem1,void* elem2)
看如下呼叫:
int array = ;int size = 6;
int number = 3;
int *found = lsearch(&number,array,size,sizeof(int),intcmp);
if(found == null)
printf("
no\n
");else
printf("
yes\n
");
c語言也可以實現一定的泛型程式設計,但這樣是不安全的,系統對其只有有限的檢查。在程式設計時一定要多加細心。
C語言泛型程式設計 泛型氣泡排序
在實際程式設計中,常常會需要一些方法 函式 比如排序,它們具體實現基本一致,僅僅只有引數型別不同,那麼可不可以有一種通用的函式,不管是什麼型別的引數都可以通用呢?泛型程式設計 泛型即是指具有在多種資料型別上皆可操作的含義,與模板有些相似。利用泛型程式設計,我們可以寫一些通用的函式,以減少 量,實現 ...
C語言泛型程式設計 泛型氣泡排序
在實際程式設計中,常常會需要一些方法 函式 比如排序,它們具體實現基本一致,僅僅只有引數型別不同,那麼可不可以有一種通用的函式,不管是什麼型別的引數都可以通用呢?泛型程式設計 泛型即是指具有在多種資料型別上皆可操作的含義,與模板有些相似。利用泛型程式設計,我們可以寫一些通用的函式,以減少 量,實現 ...
在C語言中實現泛型程式設計
注意 返回值為void並不是沒有返回值,而是代表返回空型別,這就是你仍然可以在這些函式中使用return語句的原因。只有一些語言的建構函式和析構函式才沒有返回值,在這些函式中,不可以使用return語句,他們是有顯著的不同的,objective c是一門獨特的語言,它的類的初始化方法是乙個普通方法,...