In primo luogo, si intende "typedef" non "typecast" nella domanda.
In C, un puntatore a T
può puntare a un oggetto di tipo T
:
int *pi;
int i;
pi = &i;
Quanto sopra è semplice da capire. Ora, rendiamolo un po 'più complesso. Sembra che tu sappia la differenza tra array e puntatori (ad esempio, sai che gli array non sono puntatori, a volte si comportano come loro). Quindi, si dovrebbe essere in grado di comprendere:
int a[3];
int *pa = a;
Ma per completezza: nell'assegnazione, il nome a
equivale a &a[0]
, vale a dire, un puntatore al primo elemento della matrice a
. Se non siete sicuri su come e perché funziona, ci sono molte risposte che spiegano esattamente quando il nome di un array "decadimenti" ad un puntatore e quando non lo fa:
Sono sicuro che ci sono molte altre domande e risposte su SO, ho appena menzionato alcune che ho trovato da una ricerca.
Torna il tema: quando abbiamo:
int foo[2][4];
foo
è di tipo "serie [2]
di serie [3]
di int
". Ciò significa che foo[0]
è un array di 3 int
s e foo[1]
è un array di 3 int
s.
Ora diciamo che vogliamo dichiarare un puntatore e vogliamo assegnarlo a foo[0]
. Cioè, vogliamo fare:
/* declare p somehow */
p = foo[0];
Quanto sopra non è diverso in forma alla linea int *pa = a;
, perché i tipi di a
e di foo[0]
sono gli stessi. Quindi, abbiamo bisogno di int *p;
come nostra dichiarazione di p
.
Ora, la cosa principale da ricordare sugli array è che "la regola" sul nome dell'array che decompone a un puntatore al suo primo elemento si applica solo una volta. Se si dispone di una matrice di un array, quindi in contesti di valore, il nome dell'array non decadrà sul tipo "puntatore al puntatore", ma su "puntatore all'array". Tornando al foo
:
/* What should be the type of q? */
q = foo;
Il nome foo
sopra è un puntatore al primo elemento di foo
, cioè, possiamo scrivere quanto sopra come:
q = &foo[0];
Il tipo di foo[0]
è "matrice [3]
di int
".Quindi abbiamo bisogno q
di essere un puntatore ad una "serie [3]
di int
": sono necessari
int (*q)[3];
Le parentesi attorno q
perché []
si lega più strettamente di *
in C, quindi int *q[3]
dichiara q
come un array di puntatori, e vogliamo un puntatore a un array. int *(q[3])
è, da sopra, equivalente a int *q[3]
, cioè un array di 3 puntatori a int
.
Spero che questo aiuti. Dovresti anche leggere C for smarties: arrays and pointers per un ottimo tutorial su questo argomento.
Informazioni sulla lettura di dichiarazioni in generale: le leggi "inside-out", a partire dal nome della "variabile" (se ce n'è una). Andate a sinistra il più possibile a meno che non ci sia un []
alla destra immediata, e onorate sempre le parentesi. cdecl
dovrebbe essere in grado di aiutarvi in misura:
$ cdecl
cdecl> declare p as pointer to array 3 of int
int (*p)[3]
cdecl> explain int (*p)[3]
declare p as pointer to array 3 of int
Per leggere
int (*a)[3];
a # "a is"
(*) # parentheses, so precedence changes.
# "a pointer to"
[3] # "an array [3] of"
int ; # "int".
Per
int *a[3];
a # "a is"
[3] # "an array [3] of"
* # can't go right, so go left.
# "pointer to"
int ; # "int".
Per
char *(*(*a[])())()
a # "a is"
[] # "an array of"
* # "pointer to"
( )() # "function taking unspecified number of parameters"
(* ) # "and returning a pointer to"
() # "function"
char * # "returning pointer to char"
(Esempio da c-faq question 1.21 In pra. ce, se stai leggendo una dichiarazione così complicata, c'è qualcosa di gravemente sbagliato nel codice!)
Potresti essere interessato a leggere http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html. – sand
Solo una piccola parte del collegamento fornito è correlata alla mia domanda originale che è stata già risolta in dettaglio dalle risposte di seguito. Grazie comunque per la tua risposta !! – fotNelton
Vedere anche [Leggere dichiarazioni di tipo C] (http://unixwiz.net/techtips/reading-cdecl.html), [Leggere le dichiarazioni C: una guida per i mistificati] (http://www.ericgiguere.com/articles /reading-c-declarations.html). – outis