2016-05-08 17 views
7

Ho una matrice bidimensionale che funziona con una funzione:Come si passa un puntatore a un array multidimensionale in C?

bool matrix[rows][cols]; 
func(rows, cols, matrix); 

void func(int rows, int cols, bool matrix[rows][cols]) { 
    //... 
} 

Tuttavia, non appena cercare di avere matrix nella funzione originale modificata da:

bool matrix[rows][cols]; 
func(rows, cols, &matrix); 

void func(int rows, int cols, bool *matrix[rows][cols]) { 
    //... 
} 

visualizzato un puntatore incompatibile digita errore Sono senza tracce sul perché.

+2

Basta sbarazzarsi di '&' e '' 'e tutto dovrebbe andare bene - gli array si decompongono in puntatori quando vengono passati come parametri di funzione. –

+3

Quali errori ottieni esattamente? – jboockmann

+0

@pytheos è un tipo di puntatore incompatibile. Il mio male - sembrava molto quando ho fatto la mia prima modifica. – Synlar

risposta

7

bool matrix[rows][cols] è un array di array di tipo bool

bool* matrix[rows][cols] è un array di array di un tipo puntatore a bool o semplicemente bool*.

Quindi se avete definito la vostra funzione di prendere un array di array di tipo bool*, è necessario passare quel tipo:

bool* m[row][col]; 
func(row , col , m); 

Se si desidera avere un puntatore a bool matrix[rows][cols], allora il vostro approccio non è corretto.
Un puntatore alla matrice ha il tipo: bool (*pmatrix)[rows][cols]. Quindi definire la funzione con quel tipo e passare l'indirizzo della matrice:

func(rows , cols , &matrix); 
0

Un puntatore a un singolo array bidimensionale, dicono int a[10] può apparire come di seguito:

int (*ptr)[10] 
     | |______________array of 10 integers(read type and number together) 
     |______a pointer to^

Un puntatore a un multi array bidimensionale, dire int a[10][10] può apparire come di seguito:

int (*ptr)[10][10] 
     | |  |_________________array of 10 integers(read type and number together) 
     | |______________array of^
     |______a pointer to^

Attenzione: Mind the parenthe sis.

*matrix[rows][cols]) è diverso da (*matrix)[rows][cols]). La differenza è indicata nella risposta da @ 2501.

+0

Inizialmente ho letto male la domanda :( – sjsam

-3

È possibile utilizzare uno *** per una matrice.

char ***matrix = alloc_matrix(BUFFER_SIZE, BUFFER_SIZE);

char ***alloc_matrix(unsigned rows, unsigned columns) { 
    char ***matrix = malloc(rows * sizeof(char **)); 
    if (!matrix) abort(); 

    for (unsigned row = 0; row < rows; row++) { 
     matrix[row] = calloc(columns, sizeof(char *)); 
     if (!matrix[row]) abort(); 
     for (unsigned column = 0; column < columns; column++) { 
      matrix[row][column] = NULL; 
     } 
    } 
    return matrix; 
} 

Ecco un esempio in cui si usa malloc e pointers per creare una matrice.

3

@2501 , ma, poiché si desidera che l'array modificato venga riflesso nella funzione principale, non è effettivamente necessario un puntatore all'array (il che complicherà maggiormente le cose)! Basta passare direttamente l'array mentre otterrai i risultati attesi!

Perché, chiedi?

Risposta breve: in C, gli array vengono passati per riferimento.

Risposta lunga:

tenere sempre a mente che quando si utilizza il nome di un array, esso viene convertito in un puntatore al suo primo elemento. Questo è comunemente chiamato "array decay".

Tornando al codice, il diagramma di bool matrix[rows][cols]; sarebbe:

+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
|  matrix[0][0] |  matrix[0][1] |  matrix[0][2] |   ...   | matrix[0][cols - 1] | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
|  matrix[1][0] |  matrix[1][1] |  matrix[1][2] |   ...   | matrix[1][cols - 1] | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
|   ...   |   ...   |   ...   |   ...   |   ...   | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
| matrix[rows - 1][0] | matrix[rows - 1][1] | matrix[rows - 1][2] |   ...   | matrix[rows - 1][cols - 1] | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 

Dal diagramma sopra, è chiaro che il primo elemento di

bool matrix[rows][cols]; 

è la prima sottomatrice matrix[0][0] a matrix[0][cols - 1]. Quindi, quello che succede qui è che l'indirizzo di questo subarray viene passato alla funzione. Questo è di tipo bool (*)[cols]. Ciò significherebbe che

void func(int rows, int cols, bool matrix[rows][cols]) 

avrebbe funzionato allo stesso modo di

void func(int rows, int cols, bool (*matrix)[cols]) 

Così, per esempio, se si voleva scrivere al terzo slot della seconda sottoarray di matrix, è possibile utilizzare matrix[1][2] = WHATEVER; e le modifiche apportate dalla funzione influirebbero anche sul chiamante poiché l'indirizzo è stato passato.


: Ci sono alcune eccezioni in cui allineamento "decadimento" non si verifica. Vedi Exception to array not decaying into a pointer?