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

为何两段C语言代码输出不一致?声明顺序影响解析

两段C代码输出差异的原因解析

问题背景

两段代码仅局部变量的声明顺序不同:

  • Code 1 先声明i、num、pos,再初始化数组a[9]
  • Code 2 先初始化数组a[9],再声明i、num、pos

输入55 6时,输出差异明显:

1st code : 1       55      3       5       7       9       8       6       4       2

2nd code : 1       3       5       7       9       55      6       4       2       9

其中Code 2输出符合预期(将55插入到第6位),但Code 1中55始终固定在第2位。

Code 1

#include <stdio.h>
int main()
{
    int i, num, pos, a[9] = { 1, 3, 5, 7, 9, 8, 6, 4, 2 };
    scanf("%d", &num);
    scanf("%d", &pos);
    for (i = 9; i >= pos; i--)
    {
        a[i] = a[i - 1];
    }
    a[pos - 1] = num;
    for (i = 0; i < 10; i++)
    {
        printf("%d\t", a[i]);
    }
    return 0;
}

Code 2

#include <stdio.h>
int main()
{
    int a[9] = { 1, 3, 5, 7, 9, 8, 6, 4, 2 }, i, num, pos;
    scanf("%d", &num);
    scanf("%d", &pos);
    for (i = 9; i >= pos; i--)
    {
        a[i] = a[i - 1];
    }
    a[pos - 1] = num;
    for (i = 0; i < 10; i++)
    {
        printf("%d\t", a[i]);
    }
    return 0;
}

核心原因:数组越界+栈内存布局影响

1. 数组越界是根源

两段代码中,数组a被定义为int a[9],仅包含9个元素(索引范围0~8),但代码中:

  • 循环操作a[i]时,i从9开始,直接访问了a[9](超出数组边界)
  • 最后打印时循环i<10,也输出了a[9]

C语言不做数组边界检查,越界访问会直接读写栈上相邻变量的内存空间,而栈上变量的布局由声明顺序决定。

2. 栈内存布局的差异

大多数C编译器(如GCC)中,局部变量在栈上的分配顺序是声明顺序的逆序:先声明的变量位于栈的高地址区域,后声明的位于低地址区域;数组的元素则是从低地址到高地址依次排列。

  • Code 1的栈布局:
    声明顺序为i → num → pos → a[9],栈上从高到低的布局是:
    i → num → pos → a[0] → a[1] → ... → a[8]
    此时a[9]的内存地址恰好与pos变量的地址重合。

  • Code 2的栈布局:
    声明顺序为a[9] → i → num → pos,栈上从高到低的布局是:
    a[0] → a[1] → ... → a[8] → i → num → pos
    此时a[9]的内存地址与i变量的地址重合。

3. 具体执行过程(输入55 6时)

Code 1的异常逻辑:

  1. 输入pos=6后,循环从i=9开始执行a[i] = a[i-1]
  2. 第一次循环i=9时,a[9] = a[8] → 实际上是把a[8]的值(2)写入了pos变量的内存,导致pos被修改为2
  3. 后续循环正常移动数组元素,但插入步骤a[pos-1] = num中,pos已经变成2,所以最终是a[1] =55,也就是55出现在第2位
  4. 最后打印的a[9]实际是pos的值(2),对应输出最后一位是2

Code 2的正常逻辑:

  1. 输入pos=6后,循环从i=9开始执行a[i] = a[i-1]
  2. 第一次循环i=9时,a[9] = a[8] → 实际上是把a[8]的值(2)写入了i变量的内存,但循环是基于i的递减操作,后续循环会重新赋值i为8、7...6,不影响插入位置
  3. 插入步骤a[pos-1] = num中,pos始终是6,所以a[5] =55,符合预期
  4. 最后打印的a[9]实际是循环结束后i的值(9),对应输出最后一位是9

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 20:17:51