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

C语言数组排序求最值出现元素偏移1位问题排查

问题描述

使用C语言实现数组最值查找时,采用相邻元素两两交换的冒泡排序思路对数组做升序排列,计划直接取排序后数组首尾元素作为最值,但实际运行时出现疑似数组整体偏移1位的异常:

  • 以初始数组20, 10, 35, 30, 7(共5个元素,合法下标范围0~4)为例,预期排序后下标0存最小值7、下标4存最大值35,输出value[0]和value[4]即可得到正确结果
  • 实际运行时必须读取下标1和下标5的元素才能拿到正确最值,不符合数组下标访问的预期

原题要求:首先输入数字N确定待输入的数字个数,随后输入N个数字,输出所输入N个数字中的最小值和最大值。

对应实现代码如下:

#include<stdio.h>
#pragma warning(disable:4996)
int main(void)
{
    int input, i, j, temp, k;
    int value[100] = { 0 };
    scanf("%d", &input);
    for (i = 0; i < input; i++)
    {
        scanf("%d", &value[i]);
    }
    for (k = 0; k < input; k++)
    {
        for (j = 0; j < input; j++)
        {
            if (value[j] > value[j + 1])
            {
                temp = value[j + 1];
                value[j + 1] = value[j];
                value[j] = temp;
            }
        }
    }
    printf("%d %d\n", value[0], value[input-1]);
    return 0;
}
问题原因

不存在所谓的“元素偏移1位”,核心问题是内层循环边界设置错误导致数组越界访问,越界写入破坏了内存数据,才出现了不符合预期的表现:

  • 定义的value数组长度为100,初始化时所有元素被置为0,输入N个有效数字后,有效元素仅存储在下标0 ~ N-1的位置
  • 内层冒泡循环的终止条件写为j < input,当j取到input-1(最后一个有效元素的下标)时,代码会访问value[j+1]也就是value[input],这个位置不属于存入有效元素的范围,存储的是初始化留下的0
  • 每一轮冒泡排序的最后一次比较,都会拿最后一个有效元素和它后面的0做比较交换:以5个元素的测试用例为例,第一轮排序j=4时,会比较value[4](第一轮结束后该位置值为35)和value[5](初始值0),因35>0触发交换,把0换到value[4]、35写入value[5]。多轮排序后,原本应该在value[0]位置的最小值7会被一步步交换到value[1],最大值35会被交换到value[5],就出现了需要取下标1和5才能拿到正确值的现象。
  • 这类越界访问属于C语言的未定义行为,不同编译环境下可能表现出不同的异常,不会固定出现“偏移1位”的表现。
修复方法

修改内层循环边界即可,每轮比较只需要遍历到当前未排序段的倒数第二个元素,保证j+1始终在有效下标范围内。可以直接把内层循环条件改为j < input - 1,如果要做冒泡排序的常规优化(每轮排序后末尾k个元素已经是有序的最大值,不需要重复比较),可以写成j < input - 1 -k:

for (k = 0; k < input; k++)
{
    // 修正循环边界,避免j+1越界
    for (j = 0; j < input - 1 - k; j++)
    {
        if (value[j] > value[j + 1])
        {
            temp = value[j + 1];
            value[j + 1] = value[j];
            value[j] = temp;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:48:24