C语言新手求助:矩阵行交换功能异常问题排查
问题分析与解决方案
核心问题:错误的类型转换
你代码的关键错误是将二维数组mat强制转换为int**传入swap_mat函数。C语言中,二维数组int mat[3][3]的实际类型是int (*)[3](指向包含3个int的数组的指针),和int**(指向int指针的指针)属于完全不同的类型,强行转换会导致内存访问逻辑混乱,这就是你得到异常结果的根本原因。
当你执行(int**)mat转换后,ppMat[i]会错误地把数组中的元素当成指针地址读取:比如ppMat[0]会取mat[0][0]和mat[0][1]的值(32位系统下指针占4字节)拼接成一个非法地址,自然会输出乱码。
修复方案
提供两种实用修复方式,可根据场景选择:
方案1:逐元素交换行内容(适合列数固定的场景)
直接遍历每行的元素逐一交换,无需指针操作,逻辑简单直观:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> // 函数参数改为指向固定长度数组的指针,匹配二维数组类型 void swap_mat(int (*pMat)[3], int i, int j); int main(void) { int mat[][3] = { {2,4,6},{8,10,12},{14,16,18} }; // 打印原矩阵 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { printf("%d ", mat[i][j]); } printf("\n"); } printf("\n"); swap_mat(mat, 0, 1); // 打印交换后的矩阵 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { printf("%d ", mat[i][j]); } printf("\n"); } } void swap_mat(int (*pMat)[3], int i, int j) { // 遍历列,逐一交换两行对应位置的元素 for (int k = 0; k < 3; k++) { int tmp = pMat[i][k]; pMat[i][k] = pMat[j][k]; pMat[j][k] = tmp; } }
方案2:用指针数组实现行指针交换(适合列数不固定的场景)
如果想通过交换指针的方式避免逐元素拷贝,可以先定义一个指针数组存储二维数组每行的首地址,再交换指针数组中的元素:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void swap_mat(int** ppMat, int i, int j); int main(void) { int mat[][3] = { {2,4,6},{8,10,12},{14,16,18} }; // 定义指针数组,指向二维数组的每一行 int* pRows[3] = { mat[0], mat[1], mat[2] }; // 打印原矩阵(通过指针数组访问) for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { printf("%d ", pRows[i][j]); } printf("\n"); } printf("\n"); swap_mat(pRows, 0, 1); // 打印交换后的矩阵 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { printf("%d ", pRows[i][j]); } printf("\n"); } } void swap_mat(int** ppMat, int i, int j) { int* pTmp = ppMat[i]; ppMat[i] = ppMat[j]; ppMat[j] = pTmp; }
关键知识点补充
- 二维数组在内存中是连续存储的,比如
mat的内存布局为2,4,6,8,10,12,14,16,18,不存在单独的指针存储每行地址。 int (*p)[3]是指向固定长度数组的指针,与二维数组的类型完全匹配;int**仅适用于指针数组场景,不能直接和二维数组混用。
内容的提问来源于stack exchange,提问作者mapocorin
相关产品推荐
相关产品推荐

