1樓:go陌小潔
各種用 c 語言實現的模板可能在使用形式上有所不同。現以一個求和函式 sum 為例,用 c++ template 可寫如下:
template r sum(const t *array, int n)
如果不是內建型別,該模板隱式地需要 有r r::operator+=(t)運算子可用。
1. 使用函式指標作為 functor 替換者
typedef struct tagaddclass
addclass;
void sum(addclass* self, const char* array, int n)
使用時:
void addint(char* r1, const char* r2)
addclass addclass = ;
int array[100];
read(array);
2. 用巨集作為functor的替換者
#define gensumfun(sumfunname, add, rettype, elemtype)
rettype sumfunname (const elemtype *array, int n) \
使用時:
#define addint(x, y) ((x) += (y))
gensumfun(sumint, addint, long, int) …..
int array[100];
read(array);
long sum = sumint(array, 100); …..
3. 所有可替換引數均為巨集
至少需要一個額外的檔案(實現檔案)為 impsum.c
/* impsum.c */
rettype funname(const elemtype *array, int n)
使用時:
#undef rettype
#undef funname
#undef elemtype
#undef add
#define addint(x, y) ((x) += (y))
#define rettype long
#define funname sumint
#define elemtype int
#define add addint
#include impsum.c …..
int array[100];
read(array);
long sum = sumint(array, 100);
4. 總結:
第一種方法,易於跟蹤除錯,但是效率低下,適用於對可變函式(函式指標)的效率要求不高,但程式出錯的可能性較大(複雜),模板函式(sum)本身很複雜,模板引數也比較複雜(add)的場合。
第二種方法,效率高,但很難跟蹤除錯,在模板函式和模板引數本身都很複雜的時候更是如此。
第三種方法,是我最近幾天才想出的,我認為是最好的,在模板引數(add)比較複雜時可以用函式(第二種也可以如此),簡單時可以用巨集,並且,易於除錯。在模板函式本身很複雜,而模板引數比較簡單時更為優越。但是,可能有點繁瑣。
2樓:椴
如果要寫個函式支援多種資料型別,首先想到的就是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函式如下:
那麼,就是說可以利用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
//這個findmin是sandy寫的.felix021也寫了個,差不多的就不貼出來的.
void findmin(const void *arr,int arr_size,int arrmembersize,int *index,
int (*cmp)(const void *,const void *b))
}return index;
}int result;
//result儲存的是最小值索引.
result=findmin(arr,12,
3樓:天蠍神經俠侶
#include
#include
typedef int elemtype;
elemtype add(const void *a,const void *b)
void main()
以add()函式上函式實現了int型別和char型別的共同藉口。
利用void型別來實現c函式過載,在某種意義上可以減少**量。
4樓:匿名使用者
那是c++自帶的模板庫,c的很少,而且**長難記且功能少,基本可以忽略。
要是用c的話,函式基本要自己寫的
在C語言中size是什麼函式
sizeof是c語言的一種單目操作符,就像c語言的其他操作符 等。它並不是函式。sizeof操作符以位元組形式給出了其運算元的儲存大小。運算元可以是一個表示式或括在括號內的型別名,如double,int等。如sizeof double 的值應該是8,即double型資料在記憶體中佔8個位元組。運算子...
c語言中函式指標用法,C語言中函式指標用法
函式在記憶體中有一個物理位置,而這個位置是可以賦給一個指標的。一零點函式的地址就是該函式的入口點。因此,函式指標可被用來呼叫一個函式。函式的地址是用不帶任何括號或引數的函式名來得到的。這很類似於陣列地址的得到方法,即,在只有陣列名而無下標是就得到陣列地址。怎樣說明一個函式指標變數呢 為了說明一個變數...
c語言voidmain在很多c語言中main前沒有為什
天河流紋石 c99規範要求main函式返回值必須是 int。但有些編譯器允許非標準的寫法,而且有一大批程式設計師不這樣寫。在應用角度來看,問題不大。但在原始碼規範上看,建議最好寫上。這就好比生活中,人們的口語總是有語病的。比如 你走先。這麼說,別人能聽懂 但要規範的話,還是要遵循語法。說成 你先走。...