n, 'foo' è un tipo di matrice in entrambi i casi, ma quando un puntatore è previsto in un'espressione con 'foo', è implicitamente convertito in uno (che indica il primo elemento dell'array). Tutti gli array hanno questo comportamento. Nel caso, dato che l'aggiunta può essere eseguita tramite i tipi di puntatore, ma non con gli array, 'foo' viene convertito in 'int *'.
*(foo+2) // 'foo' is implicitly converted into 'int *', pointing to 'foo' first element
foo + 1 //same as above
Ma ora si può chiedere, quali sono le proprietà del tipo di 'allineamento' e perché dovremmo mai usare, al posto del puntatore implicito a primo cast elemento. Le cose sono che non sono molto.Si può dire la dimensione di un oggetto con tipo array come questo:
sizeof(foo) //returns the size which array 'foo' occupies
E ottenere il suo indirizzo usando il '&' operatore:
&foo // '&foo' has type of 'int (*)[5]'
È anche possibile creare funzioni con i parametri di 'serie 'riferimento (o puntatore) digitare per accettare solo quelli con dimensioni specificate (che non è possibile se sono solo puntatori e si aspettano che gli array siano passati a decadere in tali). Esempio:
void func(int (&)[5]);
void func1(int (*arg)[5]); // should be accessed by '*arg', allow the use of null-pointers
void func2(int *); //same as the misleading 'void func2(int [5])' or 'void func2(int [6])' etc.
int foo[5];
int foo1[6];
func(foo); // 'foo' type is ('int [5]') - ok
func1(&foo); // '&foo' type is ('int (*)[5]') - ok
func(foo1); // 'foo1' type is ('int [6]') - not allowed, param type is 'int (&)[5]' !
func1(&foo1); // '&foo1' type is ('int (*)[6]') - not allowed, param type is 'int (*)[5]' !
func2(foo); // 'foo' is implicitly converted to 'int *' - ok
func2(foo1); // 'foo1' is implicitly converted to 'int *' - ok
Nel secondo caso quando l'array è 2D, vengono applicate le stesse proprietà. La sua dichiarazione significa questo: 'un array di 3 elementi con tipo array di 4 elementi con tipo int' Quindi in realtà è solo un array di array e niente di più. Il suo puntatore implicito alla conversione del primo elemento non è di tipo 'int **' ma invece di 'int (*) [4]', poiché ogni elemento di esso è un altro array.
La dichiarazione può essere scritta in questo modo anche:
int (foo[3])[4];
Notare inoltre non possono essere assegnati 'allineamenti', in modo che non possono essere passate per valore o restituito dalle funzioni. Quello che voglio dire è:
int funcReturningArray()[2]; //not allowed
int funcAcceptingArray(int [2]); //just converted into pointer
int funcAcceptingArray(int *); //same as above
Anche se i parametri di matrice sono sintatticamente accettate a causa di motivi di eredità (? O perché qualcosa d'altro), il loro vero significato non è mai tollerato e sono solo 'aggiustato' per i puntatori.
Nota: la conversione implicita del tipo di matrice in un puntatore del suo primo elemento è talvolta denominata "Array to pointer decay".
* È davvero un punto il primo elemento dell'array? * - No, è un array. * È foo now a int \ * \ *? * - No, è un array 2D. Vedi [array] (http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c) – chris
@chris, quindi se volessi iterare su di esso usando la notazione del puntatore, vorrei bisogno di fare un 'int * ptr = & foo [0]'? – n0pe
@maxmackie 'int * ptr = foo' sarebbe sufficiente. –