Il comportamento che hai trovato è in realtà una grande verruca nel linguaggio C. Ogni volta che dichiari una funzione che accetta un parametro di matrice, il compilatore ti ignora e cambia il parametro in un puntatore. Quindi queste dichiarazioni si comportano tutte come la prima:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a sarà un puntatore a int in tutti e quattro i casi. Se passi un array a func, decadrà immediatamente in un puntatore al suo primo elemento. (Su un sistema a 64 bit, un puntatore a 64 bit è due volte più grande di un int a 32 bit, quindi il rapporto sizeof restituisce 2.)
L'unico scopo di questa regola è mantenere la compatibilità all'indietro con i compilatori storici che non supportano il passaggio di valori aggregati come argomenti di funzione.
Ciò non significa che sia impossibile passare un array a una funzione. Puoi aggirare questa verruca incorporando l'array in una struttura (questo è fondamentalmente lo scopo dello std :: array di C ++ 11):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
o passando un puntatore all'array:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
Nel caso in cui la dimensione dell'array non sia una costante del tempo di compilazione, è possibile utilizzare la tecnica pointer-to-array con array a lunghezza variabile C99:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}