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

Gauss-Jacobi迭代法求解Ax=B的C代码运行异常问题排查

Gauss-Jacobi迭代法C程序故障排查

直接导致运行异常的错误点

  • 关键字冲突
    你使用bool作为普通整型变量名,bool是C标准规定的布尔类型关键字,需要引入<stdbool.h>才能使用,未引入对应头文件时会直接触发编译报错,即使编译通过也存在类型冲突隐患。
  • 维度变量逻辑混乱
    Gauss-Jacobi迭代求解的线性方程组Ax=B中系数矩阵A必须为n阶方阵,x、B均为n维向量,你额外定义了m变量控制列数完全没有必要。且你注释的输入代码存在笔误:printf("m=") ; scanf("%d", &n),如果放开注释会导致输入的m值直接覆盖n,维度逻辑完全混乱。
  • 对角线合法性检查时机错误
    你在输入a[i][j]的内层循环中判断a[i][i]是否趋近于0,但当j还未遍历到i时,a[i][i]是未初始化的垃圾值,该判断完全无效,可能触发程序无理由提前退出。
  • 无收敛校验与迭代上限
    Gauss-Jacobi迭代仅当系数矩阵满足严格对角占优或不可约对角占优时才会收敛,你未提前做收敛性校验,也没有设置最大迭代次数上限,输入不满足收敛条件的矩阵时会直接进入无限循环,看起来就是程序卡住无法运行。
  • 内存分配未做校验
    你调用malloc后没有检查返回值是否为NULL,一旦内存分配失败,后续对指针的读写操作会直接触发段错误崩溃。

核心修复示例

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

int main(void) {
    double **a, *b, *x, *f, eps = 1.e-2, c;  
    // 移除冗余m变量,修改bool变量名为iter_flag,增加最大迭代次数限制
    int n = 3, i, j, iter_flag = 1, max_iter = 1000, iter_cnt = 0;
    /* 修复输入笔误
    printf("n=") ; scanf("%d", &n);
    */
   
    a = malloc(n * sizeof *a);
    if (a == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    for (i = 0; i < n; i++) {
        a[i] = malloc(n * sizeof(double));
        if (a[i] == NULL) {
            printf("内存分配失败\n");
            return 1;
        }
    }

    b = malloc(n * sizeof *b);
    x = malloc(n * sizeof *x) ;  
    f = malloc(n * sizeof *f) ;
    if (b == NULL || x == NULL || f == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 输入系数矩阵
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) { 
            printf("a[%d][%d]=", i, j); 
            scanf("%le", &a[i][j]); 
        }
        printf("\n") ;
    }
    // 移到矩阵输入完成后判断对角线合法性
    for (i = 0; i < n; i++) {
        if(fabs(a[i][i])<1.e-10) {
            printf("系数矩阵对角线存在零元素,无法迭代\n");
            return 0;
        }
    }
        
    // 打印系数矩阵
    printf("输入的系数矩阵A:\n");
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) { 
            printf("%le  ", a[i][j]); 
        }
        printf("\n") ;
    }
    
    // 输入初始迭代值
    printf("输入初始迭代值x:\n");
    for (j = 0; j < n; j++) { 
        printf("x[%d]=", j); 
        scanf("%le", &x[j]); 
    } 
    printf("\n") ;
    
    // 输入常数项b
    printf("输入常数项b:\n");
    for (j = 0; j < n; j++) { 
        printf("b[%d]=", j); 
        scanf("%le", &b[j]); 
    }
    printf("\n")  ;

    // 迭代逻辑增加次数限制
    while (iter_flag && iter_cnt < max_iter) {
        iter_cnt++;
        iter_flag = 0;
        for (i = 0; i < n; i++) {
            c = 0.0;
            for (j = 0; j < n; j++) 
                if (j != i) 
                    c += a[i][j] * x[j];  
            f[i] = (b[i] - c) / a[i][i];
        }
       
        for (i = 0; i < n; i++)  
            if (fabs(f[i] - x[i]) > eps) 
                iter_flag = 1;
       
        if (iter_flag == 1) 
            for (i = 0; i < n; i++) 
                x[i] = f[i];
        else
            break;
    }

    if (iter_cnt >= max_iter) {
        printf("达到最大迭代次数,迭代可能不收敛,当前计算结果为:\n");
    } else {
        printf("迭代收敛,结果为:\n");
    }
    for (j = 0; j < n; j++) 
        printf("x[%d] = %le\n", j, f[j]);

    // 释放内存避免泄漏
    for (i = 0; i < n; i++) {
        free(a[i]);
    }
    free(a);
    free(b);
    free(x);
    free(f);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:57:01