2010-06-01 17 views
26

Esempio completo:Perché un array C ha un valore sizeof() errato quando viene passato a una funzione?

#include <stdio.h> 

void test(int arr[]) { 
    int arrSize = (int)(sizeof(arr)/sizeof(arr[0])); 
    printf("%d\n", arrSize); // 2 (wrong?!) 
} 

int main (int argc, const char * argv[]) { 
    int point[3] = {50, 30, 12}; 

    int arrSize = (int)(sizeof(point)/sizeof(point[0])); 
    printf("%d\n", arrSize); // 3 (correct :-)) 

    test(point); 

    return 0; 
} 

Prima di passare ad una funzione, mi sizeof dà il valore corretto. Fare la stessa identica cosa sullo stesso array nella funzione dà risultati strani. C'è un elemento mancante. Perché?

risposta

37

Quando si passa un array in una funzione in C, l'array decade in un puntatore al suo primo elemento. Quando si utilizza sizeof sul parametro, si sta prendendo la dimensione del puntatore, non la matrice stessa.

Se avete bisogno della funzione di conoscere la dimensione della matrice, si dovrebbe passare come un parametro a parte:

void test(int arr[], size_t elems) { 
    /* ... */ 
} 

int main(int argc, const char * argv[]) { 
    int point[3] = {50, 30, 12}; 
    /* ... */ 
    test(point, sizeof(point)/sizeof(point[0])); 
    /* ... */ 
} 

Si noti inoltre che, per una ragione simile (prendendo il sizeof un puntatore), il Il trucco sizeof(point)/sizeof(point[0]) non funziona per un array allocato dinamicamente, solo un array allocato nello stack.

2

Perché, quando viene passato, viene effettivamente passato solo il puntatore all'array.

La tua domanda ha anche una risposta allo The C Programming FAQ. Domanda 6.21.

+0

Per essere pignoli: è un puntatore al primo elemento dell'array che viene passato. Stesso valore, ma di tipo diverso. – alk

0

Poiché sizeof() NON indica la dimensione di un array in C. Fa qualcosa di completamente diverso.

sizeof C++ reference

+0

Se hai dato un'occhiata all'esempio, vedresti che non uso sizeof per ottenere direttamente il numero di elementi nell'array ... sizeof dovrebbe dirmi quanta memoria è riservata per l'array ... e in realtà ciò dovrebbe corrispondere al numero di elementi presenti, quando si conosce la dimensione di un elemento. O mi sta sfuggendo qualcosa? – dontWatchMyProfile

+0

Sono corretto. Ma come detto sopra, fai attenzione ai puntatori.Ti dicono le loro dimensioni, non le dimensioni del tipo che stai indicando. – PeterK

12

Poiché array è decayed ad un puntatore quando passata come argomento della funzione, così sizeof ti dà 4 e 8 per le piattaforme 32 e 64 bit rispettivamente.

6

Inoltre, è importante capire che sizeof viene valutato al tempo di compilazione. Dato che questo è il caso, non ha senso aspettarsi output diversi in test() a seconda di ciò che è stato passato. Il calcolo sizeof è stato eseguito quando la funzione è stata compilata.

2

Perché in C, C++ e Objective-C, le funzioni non possono avere effettivamente parametri di array. Possono solo avere parametri che somigliano ai parametri dell'array, ma sono non. Nel tuo esempio,

void test(int arr[]) 

il compilatore vede "c'è un parametro che si presenta come una serie di int", e sostituisce il parametro con un "puntatore a int". Quindi la funzione che hai scritto è assolutamente, al cento per cento, identico a

void test (int* arr) 

Pertanto, all'interno della funzione sizeof (arr) vi darà la dimensione di un "puntatore a int".

Problemi correlati