C语言通过函数访问二维数组实现矩阵加法时3x3矩阵元素异常求助
问题根因
- 函数参数的指针类型和实际传入的二维数组类型不匹配:你声明的
get/add/print函数参数为int (*p1)[10],表示指向每行固定10个int元素的数组的指针,编译器计算p1+i的偏移量时,会按i * 10 * sizeof(int)计算。 - 但你在main函数中定义的是变长数组
int m1[r][c],每行实际只有c个int元素,比如3x3矩阵每行只有3个int,偏移量应该是i * 3 * sizeof(int),两者步长不一致导致访问内存地址完全错误,出现越界写、读取到错误值的问题。 - 2x2矩阵能正常运行属于巧合:此时越界访问的内存区域刚好没有被其他变量占用,没有触发可见的错误。
修复方案
方案1:固定矩阵最大尺寸(兼容性最好,不需要C99支持)
把main中的矩阵定义为固定10列的数组,和函数参数类型匹配,同时限制输入的行列数不超过10:
// 修改main中的矩阵声明部分 int m1[10][10], m2[10][10], m3[10][10]; // 输入r和c后增加校验 if(r>10 || c>10) { printf("行列数不能超过10"); return 1; }
其余代码不需要修改即可正常运行。
方案2:使用变长数组参数(C99及以上标准支持)
修改函数声明和定义,让参数支持动态列数的变长数组:
#include <stdio.h> // 函数声明要把列数参数放在数组参数前面,让编译器能识别变长参数 void add(int r, int c, int (*p1)[c], int (*p2)[c], int (*p3)[c]); void get(int r, int c, int (*p1)[c]); void print(int r, int c, int (*p1)[c]); int main() { int i, j, r, c; printf("\n\tenter the row and column of matrix\n\t"); scanf("%d %d", &r, &c); int m1[r][c], m2[r][c], m3[r][c]; printf("\n\tenter the element of first matrix\n\t"); // 调用函数时先传行列参数 get(r, c, m1); print(r, c, m1); printf("\n\tenter the element of second matrix\n\t"); get(r, c, m2); print(r, c, m2); add(r, c, m1, m2, m3); printf("\n"); print(r, c, m3); return 0; } void get(int r, int c, int (*p1)[c]) { int i, j; for(i = 0; i < r; i++) { printf("\n\t"); for(j = 0; j < c; j++) { scanf("%d", (*(p1+i)+j)); } } } void add(int r, int c, int (*p1)[c], int (*p2)[c], int (*p3)[c]) { int i, j; for(i = 0; i < r; i++) { for(j = 0; j < c; j++) { *(*(p3+i)+j) = *(*(p1+i)+j) + *(*(p2+i)+j); } } } void print(int r, int c, int (*p1)[c]) { int i, j; for(i = 0; i < r; i++) { printf("\n"); for (j = 0; j < c; j++) { printf("\t%d", *(*(p1+i)+j)); } } }
编译时如果报错需要指定C99标准,比如gcc编译命令为gcc test.c -o test -std=c99。
内容的提问来源于stack exchange,提问作者Avinash Kumar Gupta
相关产品推荐
相关产品推荐

