對於c++等進階語言來說,語言本身提供了泛型模板,可以由編譯器產生各種版本的完成相同功能的函數。
而對於c來說,我們怎麼來完成這一切呢,我們可以充分利用指標來實現樣本1 交換兩個元素void swap(void* vp1, void* vp2, int size){ char* cpTemp = new char[size]; memcpy(cpTemp, vp1, size); memcpy(vp1, vp2, size); memcpy(vp2, cpTemp, size); delete []cpTemp;}調用: int i=10; int j= 20; swap(&i, &j, sizeof(int));顯然這樣是不夠安全的, 因為系統不會在乎傳給vp1和vp2的指標是否是同一類型的指標,任何指標都可以很容易的轉換成void型。那麼就有可能出現資料被截斷(傳的是短類型的大小)或訪問到未知記憶體的後果(傳的是長類型的大小)這些可以通過分別傳入兩個類型的大小實現,然後將大的類型截斷和小類型交換。這隻能保證沒有記憶體錯誤,不能保證轉換結果。因為你傳入的是void指標,對於你的資料類型函數一無所知,也就不能實現在函數裡的類型轉換樣本2 找到數組array中的特定索引值key 傳回它第一次出現的地址int lsearch(void* pkey, void* array, int n, int elemsize, int(*pcmp)(void*, void*)){ for(int i=0; i<n; i++) { char* pcurElem = (char*)array+i*elemsize; if(pcmp(pcurElem, pkey) == 0) return i; } return -1;}//為什麼要用自訂的pcmp比較函數而不用memcpy呢。原因很簡單,對於資料類型char*來說,memcpy比較的是兩個char*裡面裝的地址,而使用者實際想比較的是它們指向的字串。下面將提到這一點cmp的樣本對於整型:int cmp(void* vp1, void* vp2){ int* ip1 = (int*)vp1; int* ip2 = (int*)vp2; return *ip1- *ip2;}
對於字串型:(即在一個字串數組中尋找一個字串)int cmp(void* vp1, void* vp2){ char* sp1 = *(char**)vp1; char* sp2= *(char**)vp2; return strcmp(sp1, sp2);}//考慮這裡為什麼用*(char**)vp1而不直接用char*vp1? 因為這裡的vp2就是傳入的pkey 是目標元素地址,而這裡的目標元素是char* 因此需要對vp1,vp2轉為本來的類型char** 再取得目標元素。 如果直接用char* vp1 並沒有真正得到char*類型的目標元素。得到的是目標元素的地址,即將目標元素的地址強行看作了目標元素。在通俗一點,*(char**)實現了一次解引用,指標有一跳。而char*
只是一種原地強行解釋,沒有指標跳數對於字串型的測試:void main(){ char* s[5] = {"my", "name", "is", "Daijun", "Wu"}; char* aim = "Daijun" lsearch(&aim, s, 5, sizeof(char*), cmp);}熟悉這些操作可能並不能很快用於實際 但是可以對記憶體操作有更深一步的瞭解。