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

矩阵行交换实现无零对角线上三角矩阵的代码问题排查

问题

尝试通过对角线元素相乘计算矩阵行列式,已实现将矩阵转为上三角矩阵的逻辑,但对角元出现零时,行交换功能失效。测试矩阵如下:

4   7  -2   3   8
 2  -4   5   3   0
 9  -6   4   5  -2
 4   8   3   0   1
-8   4   6   5   2

需将上述矩阵保存为.txt文件,代码指定路径读取。当前代码输出与输入矩阵一致,本该交换最后两行却未执行,代码如下:

#include<stdio.h>
#include<math.h> 
#define MAX 100

int main() 
{
    FILE *fr;
    int i,j,k,m=0,q=0,count=1;
    double cache;
    double ratio, det = 1;
    int n = 0;
    char c;
    char subor[MAX];

    printf("Input the name of your file: ");
    scanf("%s", subor); 

    fr = fopen(subor,"r");

    if (fr == NULL)
    {
    printf("Unable to open file: %s", subor);
    return 0;
    }

    for (c = getc(fr); c != EOF; c = getc(fr))
    if (c == '\n')
            n = n + 1;

    fclose(fr);
    printf("\nDimensions of the given matrix: %dx%d\n\n", subor, n, n);

    fr =fopen(subor,"r");
    
    float a[n][n];

    printf("Matrix:\n");

    for(i=0;i< n;i++)
    {
        for(j=0;j< n;j++)
        {
            fscanf(fr, "%g%*c",&a[i][j]);
            printf("%g\t",a[i][j]);
        }
        printf("\n");
    }
    fclose(fr);

    while(a[m][m] == 0.0 && m != n)
    {
    q=m;
    while(a[m][m] == 0.0 && q != n)
    {
        for(i=0;i<n;i++)
        {
                cache=a[m][i];
            a[m][i]=a[q+1][i];
            a[q+1][i]=cache;
            count = count*(-1);
        }
    ++q;
    }
    ++m;
    }

    printf("\nEdited: \n");

    for(i=0;i< n;i++)
    {
        for(j=0;j< n;j++)
        {
            printf("%g\t",a[i][j]);
    }
    printf("\n");
return 0;
}
问题排查与修复

核心问题分析

  • 行交换逻辑错误:内层循环直接交换m行和q+1行,未先检查目标行的对应列元素是否非零,且当q等于n-1时,q+1会越界访问非法内存。
  • 浮点数比较精度问题:直接用a[m][m] == 0.0判断浮点数是否为零,易因精度误差导致判断失误。
  • 维度输出参数错误:printf输出矩阵维度时参数不匹配,多余的subor会导致输出错乱。
  • 输入读取逻辑缺陷:%*c会强制读取一个字符,可能错误消耗矩阵元素的分隔符,导致读取异常。

修复后的代码

#include<stdio.h>
#include<math.h> 
#define MAX 100
#define EPS 1e-9  // 浮点数精度阈值,避免精度误差导致的零判断错误

int main() 
{
    FILE *fr;
    int i,j,m=0,count=1;
    double cache;
    int n = 0;
    char c;
    char subor[MAX];

    printf("Input the name of your file: ");
    scanf("%s", subor); 

    fr = fopen(subor,"r");
    if (fr == NULL)
    {
        printf("Unable to open file: %s", subor);
        return 0;
    }

    // 统计矩阵行数:最后一行可能无换行符,初始值设为1
    n = 1;
    for (c = getc(fr); c != EOF; c = getc(fr))
    {
        if (c == '\n')
            n++;
    }
    fclose(fr);

    printf("\nDimensions of the given matrix: %dx%d\n\n", n, n);

    fr = fopen(subor,"r");
    float a[n][n];

    printf("Matrix:\n");
    for(i=0;i< n;i++)
    {
        for(j=0;j< n;j++)
        {
            fscanf(fr, "%g", &a[i][j]);  // 去掉%*c,自动适配空格/制表符分隔
            printf("%g\t",a[i][j]);
        }
        printf("\n");
    }
    fclose(fr);

    // 处理对角元为零的行交换逻辑
    while(m < n)
    {
        // 判断当前对角元是否接近零
        if(fabs(a[m][m]) < EPS)
        {
            int swap_row = -1;
            // 从当前行下方寻找第m列非零的行
            for(i = m+1; i < n; i++)
            {
                if(fabs(a[i][m]) > EPS)
                {
                    swap_row = i;
                    break;
                }
            }
            // 找到可交换的行则执行交换
            if(swap_row != -1)
            {
                for(j=0;j<n;j++)
                {
                    cache = a[m][j];
                    a[m][j] = a[swap_row][j];
                    a[swap_row][j] = cache;
                }
                count *= -1;  // 行交换一次,行列式符号反转
            }
            else
            {
                // 第m列全为零,矩阵奇异,行列式为0
                printf("\nMatrix is singular, determinant is 0.\n");
                return 0;
            }
        }
        m++;
    }

    printf("\nEdited: \n");
    for(i=0;i< n;i++)
    {
        for(j=0;j< n;j++)
        {
            printf("%g\t",a[i][j]);
        }
        printf("\n");
    }

    // 计算行列式:上三角矩阵对角元乘积 × 行交换符号
    double det = count;
    for(i=0;i<n;i++)
    {
        det *= a[i][i];
    }
    printf("\nDeterminant: %g\n", det);

    return 0;
}

修复说明

  1. 修正行交换逻辑:先从当前行下方寻找对应列非零的行,找到后再执行交换,避免无效操作和越界访问。
  2. 解决浮点数精度问题:用fabs(a[m][m]) < EPS判断是否为零,适配浮点数计算的精度误差。
  3. 修复输出与输入逻辑:调整矩阵维度输出的参数,优化输入读取方式,避免分隔符导致的读取错误。
  4. 补充行列式计算:完成行交换后,直接计算上三角矩阵的行列式,完善功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:05:55