qsort 的四个参数
qsort(v, 6, sizeof(int), cmp),一个不能少:数组名、元素个数、单个元素多大(qsort 靠它整块搬元素)、比较函数名(函数名本身就是函数指针,不加括号)。记得 #include <stdlib.h>。排结构体时第三个参数必须是 sizeof(Stu)(写 sizeof(v[0]) 最不容易错),写成 sizeof(int) 会按错误步长切割内存,数据被拦腰切碎。
比较函数:负 / 零 / 正
签名必须照抄 int cmp(const void *pa, const void *pb)——qsort 不知道你排的是什么,只能递万能指针,函数体第一件事强转还原:int a = *(const int *)pa;。规矩永远不变:返回负数 = a 排前面,正数 = a 排后面,0 = 相等。想降序不用改规矩,把条件反过来,在 a 更大时返回负数即可。
多关键字:先比分数,同分再比 id
排学生 (score, id):先比第一关键字,if (a->score != b->score) 分支里分数大的返回 -1 排前(降序),到此直接定胜负、根本不看 id;只有分数相同才落进第二关键字分支,id 小的返回 -1(升序)。两个分支缺一不可——漏了同分分支,两个 90 分的顺序就随缘了。最终 (90,1) (90,2) (85,1) (80,3),量级仍是 O(n log n)。