You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 20:39:01