Qual è il tipo di puntatore di un array multidimensionale quando viene passato a una funzione?

Sto imparando a conoscere C e i puntatori nella mia class universitaria, e penso di avere una buona conoscenza del concetto, fatta eccezione per la somiglianza tra array multidimensionali e indicatori.

Ho pensato che dal momento che tutti gli array (anche multidimensionali) sono memorizzati in memoria continua, è ansible convertirlo in modo sicuro in un int* (supponendo che l’array specificato sia un int[] .) Tuttavia, il mio professore ha detto che il numero di stelle nel la definizione dipende dal numero di dimensioni dell’array. Quindi, un int[] diventerebbe un int* , un int[][] diventerebbe un int** , ecc.

Così ho scritto un piccolo programma per testare questo:

 void foo(int** ptr) { } void bar(int* ptr) { } int main() { int arr[3][4]; foo(arr); bar(arr); } 

Con mia sorpresa, il compilatore ha emesso avvisi su entrambe le chiamate di funzione.

 main.c:22:9: warning: incompatible pointer types passing 'int [3][4]' to parameter of type 'int **' [-Wincompatible-pointer-types] foo(arr); ^~~ main.c:8:16: note: passing argument to parameter 'ptr' here void foo(int** ptr) ^ main.c:23:9: warning: incompatible pointer types passing 'int [3][4]' to parameter of type 'int *' [-Wincompatible-pointer-types] bar(arr); ^~~ main.c:13:15: note: passing argument to parameter 'ptr' here void bar(int* ptr) ^ 2 warnings generated. 

Cosa sta succedendo qui? Come potresti cambiare le chiamate di funzione in modo che uno di loro accetti l’array?

Modifica: Questo non è un duplicato di Come passare un array multidimensionale a una funzione in C e C ++ perché sto chiedendo come modificare le chiamate di funzione stesse, non le firme di funzione.

Array e puntatori non sono interamente convertibili liberamente. Per non ricevere un avvertimento, avresti bisogno di una firma come void foo(int (*ptr)[4]) . Puoi sostituire solo il primo [] con un * quando passi un array come quello a una funzione.