原函數是《The C programint language 》5.11問本行排序的程序,如下:
void qsort(void *v[], int left, int right, int (*comp)(void *,void *)) { int i,last; if( left >= right) return; swap(v,left,(left+right)/2); last = left; for(i = left + 1; i <= right; ++i) if(comp(v[i],v[left]) < 0) swap(v,++last,i); swap(v,left,last); qqsort(v,left,last-1,comp); qqsort(v,last+1,right,comp); } void qsort(void *v[], int left, int right, int (*comp)(void *,void *)) { int i,last; if( left >= right) return; swap(v,left,(left+right)/2); last = left; for(i = left + 1; i <= right; ++i) if(comp(v[i],v[left]) < 0) swap(v,++last,i); swap(v,left,last); qqsort(v,left,last-1,comp); qqsort(v,last+1,right,comp); }
該函數有以下特點:
1. 參數 void *v[] ,這是把main函數傳遞的實參轉換為通用的void * * 類型的形參,那對於實參的需要自己強制轉換,比如把 char * lineptr[] 傳遞給 v,必須這樣(void ** )lineptr,
那為什麼能這樣轉化
1. 任意的類型都可以賦給相應的void類型的
2. 該void的類型也可以強制轉換為該類型
那為什麼要這樣轉換
1. 這樣轉換可以滿足函數通用性的要求,任何類型都可以轉換為相應的void類型,相對於這個程序,把char 轉換為 void,只要在comp模型中提供了comp(char *,char *)去調用,就把void 轉換為 char 類型進行運算,符合程序通用化的要求;
2. 之所以可以用void的1階以上指針,是因為各種類型的地址字節都是固定了,win32用4個字節表示指針,所以只要該函數內的void類型的運算都是對地址的運算都可以,不能對相應的void的類型進行四則和取值運算,因為它雖然指向對應變量的首地址,但是他不知道該地址指向的數據類型,所以除了地址運算其他的都不能進行,也就是說使用這種轉換函數,必須保證該函數內除了地址運算外,不能進行其他的運算。