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

为何for循环修改变量值?C语言mat数组输出异常求助

问题根源:数组越界访问导致内存数据被破坏

你的程序输出异常的核心原因是多处数组越界访问,非法的内存读写直接覆盖了mat[2][0]的正确值,最终输出了垃圾数据。下面一步步拆解问题:

1. 数组大小与越界的直接矛盾

当n=2时,你定义的mat数组是mat[3][2]——这意味着它的行索引只能是0、1、2,列索引只能是0、1。但你的代码里多次超出了这个范围:

第一个循环的跳行与越界

第一个循环中,s每次加2的逻辑完全错误:

for (i = 0; i <= n ; i++) {
    mat[s][0] = x[i];
    mat[s][1] = y[i];
    s = s + 2;
}
  • 当i=0:写入mat[0][0]和mat[0][1],s变为2
  • 当i=1:写入mat[2][0]和mat[2][1],s变为4
  • 当i=2:s=4,mat[4][0]和mat[4][1]完全超出数组范围,属于非法写入,会破坏栈内存中的其他数据。

同时这个循环还跳过了mat[1]行,导致该行的两个元素都是未初始化的垃圾值。

第二个循环的列索引越界

第二个循环里,你尝试写入mat[t][i+1]:

mat[t][i + 1] = (mat[t + 1][i] - mat[t - 1][i]) / (mat[t + i][0] - mat[t - i][0]);
  • 当i=1时,i+1=2,超出了mat的列索引上限(1)
  • 当i=2时,i+1=3,越界更严重

这种非法写入会直接覆盖内存中其他位置的数据——包括你关心的mat[2][0],这就是为什么最后输出的是奇怪的负数。另外,循环中mat[t+i][0]的访问也存在越界(比如t=2、i=2时,t+i=4),计算出的结果本身就是错误的。

2. 修正方案

步骤1:调整数组大小适配需求

如果你是要构建差商表(从代码逻辑推测),需要3行3列的数组,把mat的定义改为:

double mat[n + 1][n + 1];

步骤2:修正第一个循环的填充逻辑

应该依次填充每一行,而不是跳行,把s的步长改为1:

for (i = 0; i <= n ; i++) {
    mat[s][0] = x[i];
    mat[s][1] = y[i];
    printf ("mat %d 0 is %.15lf\n", s, mat[s][0]);
    printf ("mat %d 1 is %.15lf\n", s, mat[s][1]);
    s++; // 改为每次加1,依次填充每一行
}

步骤3:修正差商计算的索引(避免越界)

以牛顿前向差商为例,调整索引确保所有访问都在合法范围内:

for (i = 1; i <= n; i++) {
    for (j = 0; j <= n - i; j++) {
        mat[j][i+1] = (mat[j+1][i] - mat[j][i]) / (mat[j+i][0] - mat[j][0]);
        printf ("mat[%d][%d] is %.15lf\n", j, i+1, mat[j][i+1]);
    }
}

修正后的完整代码

#include <math.h>
#include <stdio.h>

int main () {
    int i = 0, n, s = 0, j = 0;
    n=2;
    double x[n+1], y[n+1];
    double mat[n + 1][n + 1];

    y[0]=2.2;
    y[1]=2.3;
    y[2]=2.4;
    x[0]=0.110362266922174;
    x[1]=0.055539784445602;
    x[2]=0.002507683297244;

    for (i = 0; i <= n ; i++) {
        mat[s][0] = x[i];
        mat[s][1] = y[i];
        printf ("mat %d 0 is %.15lf\n", s, mat[s][0]);
        printf ("mat %d 1 is %.15lf\n", s, mat[s][1]);
        s++;
    }

    for (i = 1; i <= n; i++) {
        for (j = 0; j <= n - i; j++) {
            mat[j][i+1] = (mat[j+1][i] - mat[j][i]) / (mat[j+i][0] - mat[j][0]);
            printf ("mat[%d][%d] is %.15lf\n", j, i+1, mat[j][i+1]);
        }
    }

    printf("mat[2][0] is %.15lf",mat[2][0]);
    return 0;
}

运行后,mat[2][0]会正确输出0.002507683297244(也就是x[2]的原值)。如果你确实期望它输出0.055539784445602(x[1]的值),那需要调整mat的存储逻辑,但当前的核心问题(数组越界)已经解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:31:31