C语言如何实现整数从大到小排序?学生学分排序代码输出异常求解
问题诊断
- 排序逻辑存在根本性错误:原代码没有对比两个学生的学分大小,而是和临时变量
tempCred对比,交换操作没有备份s[i]的原始学分值,直接导致低值数据丢失,这就是你输入2、6、8后输出没有2的核心原因。 - 交换操作不完整:仅交换了学分字段,没有同步交换学生姓名字段,会导致排序后姓名和学分不匹配。
- 内层循环范围不合理:无意义遍历全部元素,排序效率低。
- 输入代码存在笔误:
scanf_s("%s", &s[i].name, 21)中name是数组名本身就是首地址,不需要加取地址符&。
修复后完整代码
#include <stdlib.h> #include <stdio.h> #include <string.h> struct Student { char name[21]; int credits; } s[99]; int main() { int students; int tempCred = 0; char tempName[21]; printf("How many students?: "); scanf_s("%d", &students); for (int i = 0; i < students; i++) { printf("\nStudent Name?: "); // 去掉多余的取地址符 scanf_s("%s", s[i].name, 21); printf("\nCredits Taken?: "); scanf_s("%d", &s[i].credits); } // 标准降序冒泡排序逻辑 for (int i = 0; i < students - 1; i++) { // 已排序的末尾元素不需要再比较,减少循环次数 for (int j = 0; j < students - 1 - i; j++) { // 前一个学分小于后一个则交换,实现从大到小排序 if (s[j].credits < s[j+1].credits) { // 交换学分 tempCred = s[j].credits; s[j].credits = s[j+1].credits; s[j+1].credits = tempCred; // 同步交换姓名,保证数据对应 strcpy_s(tempName, 21, s[j].name); strcpy_s(s[j].name, 21, s[j+1].name); strcpy_s(s[j+1].name, 21, tempName); } } } // 输出排序后的完整结果 printf("\n排序结果:\n"); for (int i = 0; i < students; i++) { printf("姓名:%s,学分:%d\n", s[i].name, s[i].credits); } return 0; }
核心修改说明
- 替换为标准的相邻元素比较的冒泡排序逻辑,每次对比相邻两个学生的学分,前小后大则交换,实现降序排列。
- 交换时同步处理学分和姓名字段,保证两者的对应关系不会错乱。
- 调整内层循环范围,跳过已经排好序的末尾元素,减少无效计算。
- 修复了输入时姓名字段多余取地址符的小问题,避免潜在的运行错误。
内容的提问来源于stack exchange,提问作者Harl23
相关产品推荐
相关产品推荐

