为何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
相关产品推荐
相关产品推荐

