C语言双指针实现矩阵转置 非方阵场景运行异常求助
问题说明
- 待实现功能:接收用户输入的二维矩阵,打印输出其转置矩阵
- 故障现象:现有代码仅在输入行列数相等的方阵(如2×2、3×3规格)时可正常运行,输入行列数不等的普通矩阵时运行结果不符合预期
原始问题代码
#include<stdio.h> #include<stdlib.h> void Trans(int **, int, int); int main() { int n, m; int **p; printf("Number of rows: \n"); scanf("%d", &n); printf("Nuber of columns: \n"); scanf("%d", &m); p = malloc(n * sizeof(int *)); for (int i = 0; i < n; i++) { p[i] = malloc(m * sizeof(int)); } printf("Elements of matrix: \n"); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { printf("P[%d][%d] = ", i, j); scanf("%d", (*(p+i)+j)); } } Trans(p, n, m); return 0; } void Trans(int **p, int n, int m) { int **a; a = malloc(m * sizeof(int *)); for (int i = 0; i < m; i++) { a[i] = malloc(n * sizeof(int)); } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i == j) a[i][j] = *(*(p+i)+j); else a[j][i] = *(*(p+i)+j); } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { printf ("%d ", *(*(a+i)+j)); } puts(""); } return 0; }
故障原因
核心错误位于Trans函数的转置赋值逻辑段:
- 矩阵转置的固定规则为:原矩阵为n行m列时,转置矩阵为m行n列,且转置矩阵第i行第j列的元素 恒等于 原矩阵第j行第i列的元素,不需要额外判断行列索引是否相等。
- 原始代码错误增加了
i == j的分支判断,非对角线分支的赋值目标写反了索引位置。在非方阵场景下,循环变量i取值范围为0m-1、`j`取值范围为0n-1,二者范围不重合,执行a[j][i] = *(*(p+i)+j)时会出现数组索引越界、元素映射错位的问题;只有方阵场景下m=n,i和j取值范围完全一致,才会凑巧输出看似正确的结果。 - 附带两个小问题:一是列数输入提示存在拼写错误,
Nuber正确拼写为Number;二是代码中通过malloc申请的堆内存未手动释放,存在内存泄漏风险。
修复后完整代码
#include<stdio.h> #include<stdlib.h> void Trans(int **, int, int); int main() { int n, m; int **p; printf("Number of rows: \n"); scanf("%d", &n); printf("Number of columns: \n"); scanf("%d", &m); p = malloc(n * sizeof(int *)); for (int i = 0; i < n; i++) { p[i] = malloc(m * sizeof(int)); } printf("Elements of matrix: \n"); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { printf("P[%d][%d] = ", i, j); scanf("%d", (*(p+i)+j)); } } Trans(p, n, m); // 释放原矩阵内存 for (int i = 0; i < n; i++) { free(p[i]); } free(p); return 0; } void Trans(int **p, int n, int m) { int **a; a = malloc(m * sizeof(int *)); for (int i = 0; i < m; i++) { a[i] = malloc(n * sizeof(int)); } // 按转置规则正确赋值 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { a[i][j] = p[j][i]; } } // 打印转置矩阵 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { printf ("%d ", *(*(a+i)+j)); } puts(""); } // 释放转置矩阵内存 for (int i = 0; i < m; i++) { free(a[i]); } free(a); return; }
内容的提问来源于stack exchange,提问作者zon
相关产品推荐
相关产品推荐

