Innanzitutto, alcuni standard :
6.7.5.3 Dichiaratori di funzioni (inclusi i prototipi)
...
7 Una dichiarazione di un parametro come '' array di tipo '' deve essere adattata a '' puntatore qualificato al
tipo '', dove i qualificatori di tipo (se presenti) sono quelli specificati all'interno del [
e ]
della derivazione del tipo di matrice. Se la parola chiave static
compare anche all'interno del [
e ]
della derivazione del tipo di matrice, allora per ogni chiamata alla funzione, il valore dell'argomento effettivo corrispondente deve fornire l'accesso al primo elemento di un array con almeno tanti elementi quanti specificati dalla dimensione espressione.
Quindi, in breve, qualsiasi parametro di funzione dichiarato come T a[]
o T a[N]
viene trattato come se fosse dichiarato T *a
.
Allora, perché i parametri dell'array vengono trattati come se fossero stati dichiarati come puntatori? Ecco perché:
6.3.2.1 Valori, array e designatori di funzione
...
3 Tranne quando è l'operando sizeof
dell'operatore o dell'operatore unario &
, o è una stringa letterale usata per inizializzare un array, un'espressione che ha tipo '' array di tipo ' 'viene convertito in un'espressione con tipo "puntatore a tipo " "che punta all'elemento iniziale dell'oggetto array e non è un lvalue. Se l'oggetto array ha una classe di archiviazione del registro, il comportamento non è definito.
Dato il seguente codice:
int main(void)
{
int arr[10];
foo(arr);
...
}
Nella chiamata a foo
, l'espressione di matrice arr
non è un operando di sizeof
o &
, quindi il suo tipo viene convertito implicitamente da "matrice di 10 elementi di int
" a "puntatore a int
" secondo 6.2.3.1/3. Pertanto, foo
riceverà un valore di puntatore, anziché un valore di matrice.
A causa del 6.7.5.3/7, puoi scrivere foo
come
void foo(int a[]) // or int a[10]
{
...
}
ma sarà interpretato come
void foo(int *a)
{
...
}
Pertanto, le due forme sono identiche.
L'ultima frase in 6.7.5.3/7 è stata introdotta con C99, e in pratica significa che se hai una dichiarazione di parametro come
void foo(int a[static 10])
{
...
}
il parametro effettivo corrispondente a a
deve essere un array con almeno 10 elementi.