C語言中實現模板函式小結

2021-05-25 07:06:45 字數 3316 閱讀 2211

如果要寫個函式支援多種資料型別,首先想到的就是c++的模板了,但是有時候只能用c語言,比如在linux核心開發中,為了減少**量,或者是某面試官的要求…

考慮了一陣子後,就想到了qsort上.qsort的函式原型:

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

快排時,只要自己實現相應資料型別的比較函式cmpare就可以了.如果比較int型時,乙個典型的compare函式如下:

int cmp(const void *a,const void *b)

那麼,就是說可以利用void *. void *意指未指定型別,也可以理解為任意型別。其他型別的指標可以直接賦值給void *變數,但是void *變數需要強制型別轉換為其它指標型別。這個相信大家都知道。那麼下面以乙個簡單的題目為例,來**如何在c語言中實現模板函式。

方法1: 利用void *.

在看下面的源程式之前,需要了解幾點。首先,在32位平台上,任何型別的指標所佔的位元組都是4個位元組,因為32位機器虛擬記憶體一般為4g,即2的32次方,只要32位即4個位元組就可以足夠定址,sizeof(void *)=4; 其次,雖然各種不同型別的指標所佔的空間都為4個位元組,但是不同型別的指標所指的空間的位元組數卻不同(這一點尤為重要,下面的程式我在開始沒有調通就因為這點意識不強)。所以,如果你將乙個指標強制轉換為另乙個型別的指標,指標本身所佔的位元組是不變的,但是,如果對這個指標進行運算,比如 *p,p++,p-=1等一般都是不同的。 再次,函式指標應該了解下,這裡不多說。 最後,因為sandy跟我說,c++開始的時候模板的實現其實就是利用巨集替換,在編譯的時候確定型別。所以,為了方便,型別也用了預編譯指令#define。

#include "stdio.h"

#include "stdlib.h"

//typedef int t; //或者下面的也可以.

#define t int

int cmp(const void *a,const void *b)

/*//這個findmin是sandy寫的.felix021也寫了個,差不多的就不貼出來的.

void findmin(const void *arr,int arr_size,int arrmembersize,int *index,

int (*cmp)(const void *,const void *b))

p+=arrmembersize;

}(*index)=((int)(tmp-arr))/arrmembersize;}*/

int findmin(const void *arr,int arr_size,int arrmembersize,int (*cmp)(const void *,const void *)) } 

return index;} 

int main();

//int *result;

int result;//result儲存的是最小值索引.

result=findmin(arr,12,sizeof(arr[0]),cmp);

printf("%d,%d

",result,arr[result]);

system("pause");

return 0;

}

方法2:利用巨集。在編譯的時候確定型別。查閱資料的時候,很多都說這種方法比較好,方便除錯,也很直觀,雖然很囉嗦。

#include #ifndef _int_

#define _int_

#endif

int cmp(const void *a,const void *b)

#ifdef _int_

void findmin(int *arr,int arr_size,int *result,int cmp(const void *a,const void *b))

#elif _float_

void findmin(float *arr,int arr_size,float *result,int cmp(const void *a,const void *b))

#elif _double_

void findmin(double *arr,int arr_size,double *result,int cmp(const void *a,const void *b))

#endif} 

int main();

int result;

findmin(arr1,6,&result,cmp);

printf("%d

",result);

return 0;

}

方法3:在findmin中,不用強制型別轉換為char *,直接利用memcpy記憶體拷貝過去,這時,還可以在引數列表中儲存結果,而不是索引。此方法由csdn上的ltc_mouse提供。

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

void findmin(void *arr,int arr_size,int arrmembersize,void * result,

int (*fpcmp)(const void *,const void *b))

}}int cmp_int(const void *a, const void *b)

int cmp_double(const void *a, const void *b)

int main()

; double farr=;

int imin;

double fmin;

findmin( (void *)iarr, sizeof(iarr)/sizeof(iarr[0]), sizeof(iarr[0]), (void *)&imin, cmp_int );

findmin( (void *)farr, sizeof(farr)/sizeof(farr[0]), sizeof(farr[0]), (void *)&fmin, cmp_double);

printf("min of iarr is %d

", imin);

printf("min of farr is %lf

", fmin);

return 0;

}

C 語言中的模板 函式模板

模板概述 c 提供了函式模板 function template.所謂函式模板,實際上是建立乙個通用函式,其函式型別和形參型別不具體制定,用乙個虛擬的型別來代表。這個通用函式 就成為函式模板。凡是函式體相同的函式都可以用這個模板代替,不必定義多個函 數,只需在模板中定義一次即可。在呼叫函式時系統會根...

C語言中scanf 函式的小結

1.scanf 的返回值 scanf函式是有返回值的,接受乙個變數返回1。如 c scanf d d a,b 若輸入的全是整數,則c為2 若全是字元,則c為0 因為scanf在佔位符存在的情況下,只接受符合佔位符的資料。2.scanf的結束 如果不是 c,則以空格,回車,tab鍵結束,或非法字元結束...

C語言中malloc函式實現

該實現使用大容量的靜態陣列作為堆,但也可使用作業系統呼叫分配堆。定義了乙個資料型別header儲存每個儲存器塊的簿記資訊,定義了具有header型別元素的堆陣列,這樣就可以很容易地將簿記資訊儲存在儲存器塊中。型別header包含了3塊資訊 指向列表的下乙個塊的指標,當前分配空間的長度,後面的自由空間...