C语言二维数组输入异常排查:4阶完美矩阵输入出错
问题定位:指针偏移计算错误
嘿,我一眼就揪出了问题所在——你在矩阵输入环节的指针偏移计算完全错了!这就是为什么输入4阶矩阵时数据会乱掉的核心原因。
错误原因分析
你用malloc分配了一块连续的一维内存来存储二维矩阵,但在输入和打印元素时,错误地用(pmatrix + i) + j来计算地址。这个写法的问题在于:pmatrix + i指向的是一维数组的第i个元素,而不是第i行的起始位置。
举个size=4的例子:
- 当你输入第2行第2列(i=1,j=1)的元素时,错误地址是
pmatrix+1+1 = pmatrix+2(对应一维数组的第3个元素) - 但正确的地址应该是
pmatrix + 1*4 +1 = pmatrix+5(对应一维数组的第6个元素)
这种错误会导致你输入后面的元素时,直接覆盖前面已经输入的元素,最终出现你看到的矩阵数据错乱的情况。
另外还有两个小问题需要注意:
- 你忘记包含
stdlib.h头文件,malloc和free函数需要这个头文件才能正常工作 - 标准C中
main函数的返回类型应该是int,而不是void
修正后的完整代码
主函数修正(核心是地址计算)
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> // 补充malloc需要的头文件 int IsPerfect(int *arr, int size); int main() { // 修正main的返回类型为int int size = 0, i = 0, j = 0; printf("please enter matrix size, 0 to exit:\n"); scanf("%d", &size); printf("size is :%d\n", size); while (size != 0) { int *pmatrix = (int *)malloc(size*size * sizeof(int)); if (pmatrix == NULL) { // 增加内存分配失败的判断,让程序更健壮 printf("Memory allocation failed!\n"); break; } printf("please input matrix:\n"); for (i = 0; i < size; i++) for (j = 0; j < size; j++) { printf("[%d][%d]\n", i, j); // 修正地址计算:用i*size +j定位二维元素在一维数组中的位置 scanf("%d", &pmatrix[i * size + j]); } printf("You entered matrix:\n"); for (i = 0; i < size; i++) { for (j = 0; j < size; j++) printf("[%d]", pmatrix[i * size + j]); printf("\n"); } IsPerfect(pmatrix, size); free(pmatrix); printf("please enter matrix size, 0 to exit:\n"); scanf("%d", &size); } printf("bye bye!\n"); return 0; // 标准main需要返回值 }
IsPerfect函数优化(可选,提升效率)
原函数中一旦判断出矩阵不完美,后续的检查还会继续执行,我们可以加上判断提前跳出;同时也修正里面的地址计算:
int IsPerfect(int *arr, int size) { int i = 0, j = 0, w = 0, perf = 1; int *check = (int *)malloc(sizeof(int) * size); if (check == NULL) { printf("Memory allocation failed in IsPerfect!\n"); return 0; } // 行检查:perf为0时直接跳出循环 for (w = 0; w < size && perf; w++) { for (i = 0; i < size; i++) check[i] = 0; for (i = 0; i < size; i++) { int val = arr[w * size + i]; if (val <1 || val > size) { // 提前判断值是否在合法范围内 perf = 0; break; } check[val -1]++; } for (i = 0; i < size && perf; i++) { if (check[i] != 1) { perf = 0; break; } } } // 列检查:同样在perf为0时提前跳出 for (w = 0; w < size && perf; w++) { for (i = 0; i < size; i++) check[i] = 0; for (i = 0; i < size; i++) { int val = arr[i * size + w]; if (val <1 || val > size) { perf = 0; break; } check[val -1]++; } for (i = 0; i < size && perf; i++) { if (check[i] != 1) { perf = 0; break; } } } if (perf) printf("the matrix is perfect\n"); else printf("the matrix is not perfect\n"); free(check); return perf; }
测试验证
当你输入你提到的4阶矩阵:
1 2 3 4 2 1 4 3 3 4 2 1 4 3 1 2
修正后的代码会正确存储并打印矩阵,并且IsPerfect会判断它是完美矩阵。
内容的提问来源于stack exchange,提问作者Nitzane
相关产品推荐
相关产品推荐

