我无法理解为什么我的代码在访问数组时崩溃了。将函数参数转换为int[3][3]
而不是int**
时,我没有遇到任何问题,但我无法理解为什么,因为int**
我作为参数给出的是一个有效的指针,指向main
typedef struct {const unsigned int m; const unsigned int n;} mat_size;
void print_mat(int** mat, mat_size s){ // <-- faulty version
int i,j;
for(i = 0; i < s.m; i++){
for(j = 0; j < s.n; j++){
printf("%d ", mat[i][j]);
}
printf("\n");
}
printf("=============");
}
int main(int argc, char** argv) {
int matrix[3][3] = {{1,4,2},{7,-1,15},{33,-10,-1}};
mat_size s = {3,3};
print_mat(matrix, s);
while(1);
return 0;
}
void print_mat(int mat[3][3], mat_size s){ // <-- good version
int i,j;
for(i = 0; i < s.m; i++){
for(j = 0; j < s.n; j++){
printf("%d ", mat[i][j]);
}
printf("\n");
}
printf("=============");
}
答案 0 :(得分:3)
函数参数的类型与传递的矩阵不匹配,因为matrix[3][3]
不是int**
而是(*int)[3]
。
通过评论,您还希望为矩阵设置动态尺寸,以便您可以使用VLA执行此操作:
#include <stdio.h>
typedef struct
{
const unsigned int m;
const unsigned int n;
} mat_size;
void print_mat(mat_size s, int (*mat)[s.n])
{
unsigned int i, j;
for (i = 0; i < s.m; i++)
{
for (j = 0; j < s.n; j++)
{
printf("%d ", mat[i][j]);
}
printf("\n");
}
printf("=============\n");
}
int main(int argc, char** argv)
{
int matrix[3][3] = { { 1, 4, 2 }, { 7, -1, 15 }, { 33, -10, -1 } };
mat_size s = { 3, 3 };
print_mat(s, matrix);
return 0;
}
答案 1 :(得分:1)
声明为函数参数的数组由编译器以静默方式调整为第一个对象。这就是为什么
void func (int a[5]);
相当于
void func (int* a);
类似地,由调用者声明并传递给这样一个函数的数组也“衰减”为指向第一个元素的指针。
这背后的基本原理是数组不应该通过值传递给函数,因为获取数组的硬拷贝会占用执行时间和内存。
在多维数组的情况下,适用相同的规则。给定函数void print_mat(int mat[3][3])
,数组将以静默方式调整为指向第一个元素的指针。 int [3][3]
数组中的第一个元素是类型int[3]
的数组。因此,指向此类元素的指针必须是数组指针,int (*)[3]
。
因此void print_mat(int mat[3][3])
相当于void print_mat(int (*mat)[3])
。所以你可以改变函数来使用这样的数组指针,它就等价了。
但是,我建议使用变量方法:
void print_mat (size_t x, size_t y, int mat[x][y])
指针指针与多维数组无关,尽管它们可以用来模拟动态内存分配。然而,这样做往往是糟糕和不正确的做法。有关详细信息,请参阅Correctly allocating multi-dimensional arrays。