为何C语言矩阵乘积函数中计算行数n得到0值?
问题分析:为何矩阵行数计算得到n=0?
先看你提供的代码:
#include <stdio.h> void MatrixProduct(int arr1[][4],int arr2[][4]) { int i,j,k; int m=sizeof(arr1[0])/sizeof(arr1[0][0]); int n=sizeof(arr1)/sizeof(arr1[0]); int p=sizeof(arr2[0])/sizeof(arr1[0][0]); printf("%d",n); // debug int arr3[n][p],s; for (i=0;i<n;i++) { for (j=0;j<p;j++) { s=0; for (k=0;k<m;k++) s=s+arr1[i][k]*arr2[k][j]; arr3[i][j]=s; } } for (i=0;i<n;i++) { for (j=0;j<p;j++) { printf("%d ",arr3[i][j]); } printf("\n"); } return; } int main() { int mat1[4][4] = { { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 3, 3, 3, 3 }, { 4, 4, 4, 4 } }; int mat2[4][4] = { { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 3, 3, 3, 3 }, { 4, 4, 4, 4 } }; MatrixProduct(mat1,mat2); return 1; }
核心原因:数组作为函数参数时会退化为指针
在C语言中,当你把二维数组传递给函数时,第一维的长度信息会丢失,数组参数会被隐式转换为指向数组首元素的指针。也就是说,在MatrixProduct函数里,arr1的实际类型是int (*)[4](指向包含4个int的数组的指针),而不是你定义的int[4][4]。
这时候计算sizeof(arr1)得到的是指针的大小(比如64位系统中是8字节),而sizeof(arr1[0])是数组首元素的大小(即4个int的字节数,16字节,假设int占4字节)。用8除以16,结果就是0,所以n=0,后续的循环条件i<0不成立,自然没有任何输出。
你在网上看到的sizeof(arr)/sizeof(arr[0])写法是有效的,但那是在数组的原始定义作用域内(比如main函数里直接计算mat1的行数),一旦数组作为参数传递到其他函数,这个写法就失效了。
解决方案:显式传递行数参数
最直接的解决方法是把矩阵的行数作为参数传递给函数,修改后的代码如下:
#include <stdio.h> // 添加行数参数rows void MatrixProduct(int rows, int arr1[][4], int arr2[][4]) { int i, j, k; int m = sizeof(arr1[0]) / sizeof(arr1[0][0]); // 列数,这里是4,计算有效 int n = rows; // 使用传入的行数 int p = sizeof(arr2[0]) / sizeof(arr2[0][0]); printf("%d\n", n); // debug int arr3[n][p], s; for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { s = 0; for (k = 0; k < m; k++) s += arr1[i][k] * arr2[k][j]; arr3[i][j] = s; } } for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { printf("%d ", arr3[i][j]); } printf("\n"); } } int main() { int mat1[4][4] = { {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4} }; int mat2[4][4] = { {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4} }; MatrixProduct(4, mat1, mat2); // 传入行数4 return 0; }
修改后,函数能正确获取矩阵行数,循环正常执行,会输出矩阵乘积的结果:
4 10 10 10 10 20 20 20 20 30 30 30 30 40 40 40 40
内容的提问来源于stack exchange,提问作者CaptainPotato
相关产品推荐
相关产品推荐

