近期頻繁使用qsort函數,可是對於cmp函數卻一直不太熟悉,現用現查。故寫一篇小筆記記錄一下。數組
函數原型:函數
void qsort(void *base,size_t NumEle,size_t SizeEle,int (cmp*)(const void *a,const void *b))
值得注意的是cmp這個函數指針,返回值類型必須是int,參數是兩個const void *
,在寫cmp函數時,能夠選擇在函數體內,再將a,b強轉爲所須要的類型,而由於void *
的特殊性,也能夠在寫函數簽名是用const T*
代替。設計
以一個int數組爲例,如今要將這個數組按照元素大小,升序排列。cmp函數與參數a,b對於qsort的影響是指針
if a>b return positive if a=b return 0 if a<b return negative
按照這個要求設計的return
就會使得按照升序排序,注意是按照這個要求去設計所須要的返回值!只要能保住a,b在你設計的規則下,產生這樣的返回值便可。code
而這三個條件恰好與a-b
等價:排序
a>b return positive ~ a-b a=b return 0 ~ a-b a<b return negative ~ a-b
於是cmp
函數能夠寫爲:字符串
int cmp(const void *a,const void *b){ return *(int*)a-*(int*)b;/*按照升序排序*/ }
那麼按照這個思想,一樣能夠寫出字符串按字典序,由於strcmp
函數的返回值,正與咱們所要求的升序設計一致。於是cmp函數能夠寫爲:原型
int cmp(const void *a,const void *b){ return (char*)a-(char*)b;/*按照升序排序*/ }
對於結構體的排序也是如此,只是要注意類型的轉化。多級排序就設計一個if/else便可,例如:it
struct pair{ int x; int y; }P[100]; /* 當x不相等時,按照x升序排序,不然就按y降序排列 */ int cmp(const void *a,const void *b){ struct pair* p_a=(struct pair*)a; struct pair* p_b=(struct pair*)b; if(p_a->x==p_b->x){ return p_a->x - p_b->x; }else{ reyurn p_b->y - p_a->y; } } qsort(P,100,sizeof(P[0]),cmp);
所以,要弄清楚cmp的意義,關鍵在於如何排序是有規定的,咱們要根據這個規定去設計cmp函數的返回值。class
按照升序排序的要求:對於任意的元素a,b(假定比較運算符有意義)
if a>b return positive if a=b return 0 if a<b return negative