[英]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.