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

C语言冒泡排序异常:偶发终止、大数组首元素为负,新手求助

问题原因分析

你的程序出现异常终止、首元素变为负数的核心问题是数组越界访问,这是C语言中典型的未定义行为触发点:

  • 在bubble_swap函数的内层循环中,循环条件写为for (j = 0; j < size; j++),当j等于size-1时,j+1就等于size,而数组grades的合法下标范围是0到size-1,此时访问grades[j+1]会读取/修改数组之外的内存区域。
  • 这种越界操作会破坏其他内存数据(比如修改到main函数里的变量或栈内存),导致程序崩溃,或者出现奇怪的数值(比如首元素变成负数)。
  • 开头的函数声明(如void print_grades();)未指定参数类型,不符合C语言规范,可能引发编译警告或潜在调用错误。
  • 代码里的NULL;是无效语句,属于冗余代码,没有任何作用。
修复方案

1. 修正冒泡排序的循环边界(核心修复)

将bubble_swap的内层循环条件改为j < size - 1 - i,既避免数组越界,也是冒泡排序的标准优化(每一轮排序后末尾的i个元素已处于有序状态,无需重复比较):

// 修正后的冒泡排序函数
void bubble_swap(int grades[], int size)
{
    int i, j;
    for (i = 0; i < size; i++)
        // 内层循环修正边界,避免越界+减少无效比较
        for (j = 0; j < size - 1 - i; j++)
        {
            // 直接判断需要交换的情况,去掉冗余else分支
            if (grades[j] > grades[j+1])
            {
                swap(&grades[j], &grades[j+1]);
            }
        }
    printf("\nMy sorted grades are:\n");
    for (i = 0; i < size; i++)
    {
        printf("%i\t", grades[i]);
    }
}

如果仅临时解决越界问题,至少要把内层循环改为j < size - 1,但加上-i能大幅减少不必要的比较操作。

2. 修正函数声明

将开头的函数声明改为带参数类型的形式,与函数定义完全匹配:

void print_grades(int grades[], int size);
void average(int grades[], int size);
void swap(int *a, int *b);
void bubble_swap(int grades[], int size);

3. 移除冗余代码

直接删掉if (grades[j] < grades[j+1])分支里的NULL;语句,该分支无需执行任何操作,简化后逻辑更清晰。

4. 可选效率优化

可以加入交换标记,当某一轮排序未发生交换时,说明数组已经有序,直接提前终止循环,提升排序效率:

void bubble_swap(int grades[], int size)
{
    int i, j;
    int swapped; // 标记本轮是否发生交换
    for (i = 0; i < size; i++)
    {
        swapped = 0;
        for (j = 0; j < size - 1 - i; j++)
        {
            if (grades[j] > grades[j+1])
            {
                swap(&grades[j], &grades[j+1]);
                swapped = 1;
            }
        }
        if (!swapped) // 本轮无交换,数组已完全有序,提前退出
            break;
    }
    printf("\nMy sorted grades are:\n");
    for (i = 0; i < size; i++)
    {
        printf("%i\t", grades[i]);
    }
}

关于你的疑问解答

  • 不需要改用long或float数组,问题与数据类型无关,完全是内存越界导致的。
  • 增大数组大小只是碰巧让越界访问的内存区域未破坏关键数据,属于侥幸行为,并未解决根本问题,不能依赖。

内容的提问来源于stack exchange,提问作者mrstagg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:40:30