我已经看到了关于这个主题的其他一些答案,但是他们并没有真正理解它们以适应我的问题。我有一个指向char的指针的2D数组,我希望将其传递给函数。
如果声明了数组:char *params[50][50];
(50只是随意挑选)
,函数原型是:void test (char ***results);
我该怎么称呼这个功能?我尝试的所有内容最终都会出现不兼容的指针警告
在函数内部引用数组成员的最正确方法是什么?它只是简单:results[x][y];
?
由于
答案 0 :(得分:4)
你不能,指向指针和指向数组的指针是不同的东西。
void test (char *results[50][50]);
void test (char *results[][50]);
void test (char *(*results)[50]);
都是您正在寻找的函数的等效原型。
Suplement:如果要对尺寸变化较大的数组使用相同的函数,则必须使用VLA(变长数组)作为函数参数:
void test (size_t n, char *results[n][n]);
void test (size_t n, char *results[][n]);
void test (size_t n, char *(*results)[n]);
仅当您的编译器符合C99时才有效。
观察大小的参数在数组之前,以便在那里知道。
此外,您不必使用可变长度声明数组本身,以将此功能用于函数参数。但是如果你小心不要在堆栈上分配大型矩阵,否则你可能很容易产生堆栈溢出。
答案 1 :(得分:0)
如果将数组声明为
char *array[N][M];
并将其传递给函数
test(array)
然后原型到函数将需要
void test(char *(*arr)[M])
或
void test(char *arr[][M])
在任何一种情况下,arr
都有类型“指向指向char
的指针的M元素数组的指针”。这与char ***
的类型不同,并且在两者之间没有真正好的或干净的转换方式。
如果你按照以下方式分配了动态分配的array
,那么原型就是正确的:
char ***array = malloc(sizeof *array * N);
if (array)
{
size_t i;
for (i = 0; i < N; i++)
{
array[i] = malloc(sizeof *array[i] * M);
if (array[i])
{
size_t j;
for (j = 0; j < M; j++)
{
array[i][j] = some_initial_pointer_value();
}
}
}
}
请注意,在这种情况下,array
的类型为char ***
。
如果你正在处理声明为T a[M][N]
的数组,并且你想编写一个接受不同大小的数组的函数,那么你可以使用Jens建议的VLA语法,或者你可以做像这样的东西:
void test(char **a, size_t rows, size_t cols)
{
size_t i, j;
...
some_pointer_value = a[i * rows + j];
...
a[i * rows + j] = some_pointer_value;
}
...
test(&array[0][0], 50, 50);
在这种情况下,我们显式地将数组的第一个元素的地址和数组维度作为单独的参数传递。在test
的主体内,我们将数组视为具有1维(char *a[rows * cols]
)并手动计算偏移量。请注意,这仅适用于连续分配的数组;这不适用于为上面数组中的每一行进行零碎分配的版本。
答案 2 :(得分:-1)
我的C有点生疏,但是:
char *params[][];
是char *指针的2D数组,而不是char。如果你想要一个2D字符数组,它被定义为:
char params[valuex][valuey];
Iit将是静态内存分配,仅在定义范围内可用,我的意思是如果不是您正在寻找的行为尝试动态分配,则将您的数据放在范围内。)
然后,您可以通过将函数原型定义为:
将此数组传递给函数void foo(char param[valuex][valuey] );
此致