近期频繁使用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