使用qsort排序学生结构体数组报错:进程终止状态码-1073741819
排查qsort排序结构体数组的崩溃问题
你的代码出现进程终止(状态码-1073741819通常是内存访问错误),主要是qsort参数使用错误、排序逻辑设计不当和输出格式错误导致的,下面一步步拆解问题并修正:
核心错误点分析
- qsort的第一个参数传错了:你传的是
st->grupa,这是结构体数组第一个元素的grupa成员值(int类型),但qsort要求传入待排序数组的首地址,应该传st(结构体数组的首地址)。 - 元素个数计算完全错误:
sizeof(S)/sizeof(st->grupa)是计算结构体中grupa成员占的字节比例,不是数组元素个数。你已经通过scanf获取了元素个数n,直接用n就行。 - 不需要调用两次qsort:你的需求是先按组升序,组内按学分降序,这可以在同一个比较函数里完成,两次qsort会打乱之前的排序结果,逻辑完全错误。
- printf输出错误:你用了
&st[i].grupa和&st[i].nr_credite,这是取地址,输出的是内存地址而不是变量值,应该直接写st[i].grupa和st[i].nr_credite。 - 多余的头文件:
#include<conio.h>是DOS时代的头文件,现代编译器大多不支持,而且你没用到里面的函数,可以删掉。
修正后的完整代码
#include<stdio.h> #include<stdlib.h> typedef struct Student { char nume[20]; int grupa, nr_credite; } S; // 统一的比较函数:先按grupa升序,同组按nr_credite降序 int cmpStudent(const void *a, const void *b) { const S *ia = (const S *)a; const S *ib = (const S *)b; // 先比较组号 if (ia->grupa != ib->grupa) { return ia->grupa - ib->grupa; // 升序:小的在前 } else { // 组号相同,按学分降序:大的在前 return ib->nr_credite - ia->nr_credite; } } void ex(); int main() { ex(); return 0; } void ex() { int n, i; S st[100]; scanf("%d", &n); for(i = 0; i < n; i++) { scanf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite); } // qsort正确参数:数组首地址、元素个数、单个元素大小、比较函数 qsort(st, n, sizeof(S), cmpStudent); // 正确输出变量值,不要取地址 for(i = 0; i < n; i++) { printf("%s %d %d\n", st[i].nume, st[i].grupa, st[i].nr_credite); } }
关键修正说明
- 统一比较函数:在
cmpStudent里先判断组号是否不同,不同就按组号升序返回;相同的话,按学分降序返回,一次排序就完成需求。 - qsort参数修正:
- 第一个参数:
st(结构体数组的首地址) - 第二个参数:
n(实际输入的学生数量) - 第三个参数:
sizeof(S)(单个结构体的字节大小) - 第四个参数:
cmpStudent(自定义比较函数)
- 第一个参数:
- 输出修正:去掉
&,直接输出变量值,还加了\n让每行输出更清晰。 - 清理冗余头文件:删掉了没用的
conio.h,避免编译警告。
这样修改后,代码就能正常运行,实现你需要的排序逻辑了。
内容的提问来源于stack exchange,提问作者fancy b
相关产品推荐
相关产品推荐

