[英]passing a pointer to 2D array of pointers in C
我已经看到了有关此主题的其他一些答案,但对它们的理解不足以使其完全适合我的问题。 我有一个二维数组的char指针,我想传递给函数。
如果声明了数组: char *params[50][50];
(50个是任意选择的)
函数原型为: void test (char ***results);
我将如何调用该函数? 我尝试的所有操作都以不兼容的指针警告结尾
另外,在函数内部时引用数组成员的最正确方法是什么? 简单吗: results[x][y];
?
谢谢
您不能,指向数组的指针和指向数组的指针是不同的东西。
void test (char *results[50][50]);
void test (char *results[][50]);
void test (char *(*results)[50]);
是您要寻找的功能的所有等效原型。
补充:如果要对长度不同的数组使用相同的函数,则必须使用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的编译器时,此方法才有效。
请注意,size的参数位于数组之前 ,以便在那里知道。
同样,您不必使用可变长度声明数组本身,即可将此功能用于函数参数。 但是,如果您一定要小心,不要在堆栈上分配大矩阵,否则很容易发生堆栈溢出。
如果您将数组声明为
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]
),并手动计算偏移量。 注意,这仅适用于连续分配的数组。 这不适用于上面数组的每一行进行零碎分配的版本。
我的C有点生锈,但是:
char *params[][];
是char *指针的2D数组,而不是char。 如果需要二维char数组,则将其定义为:
char params[valuex][valuey];
它将是静态内存分配,仅在定义范围内可用,我的意思是,如果不是您要寻找的行为,请离开范围,然后松开数组(尝试动态分配)。
然后,您可以通过将函数原型定义为:将此数组传递给函数:
void foo(char param[valuex][valuey] );
问候
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.