2010-11-01 19 views
1

Lors du passage d'un argument de tableau à une fonction, son adresse mémoire est copiée dans un paramètre de tableau. Pour cette raison:Quel type fait et retourne pour un paramètre de tableau dans une fonction C?

  • sizeof() retourne la taille de l'ensemble du réseau pour l'argument Array (intérieur appelant)
  • sizeof() retourne la taille d'un pointeur pour le tableau des paramètres (à l'intérieur appelé Fonction)

Ma question est, quel type est le paramètre de tableau dans la fonction? Et plus précisément, quel type est renvoyé lors de l'utilisation de l'opérateur & sur un paramètre Array? Ce n'est pas un pointeur sur un tableau de type, ni un pointeur de type, comme indiqué dans ce code (étiqueté BAD):

void doSomething(int arrayParam[10]); 

int main() 
{ 
    int array[10] = { 0 }; 
    int (*arrayPtr)[] = &array;   // OK 
    printf("%p\n", array);    // 0x7fff5fbff790 
    doSomething(array); 

    return 0; 
} 

void doSomething(int arrayParam[10]) 
{ 
    printf("%p\n", arrayParam);   // 0x7fff5fbff790 

    int (*arrayPtr)[] = &arrayParam; // BAD: Initialization from incompatible pointer type 
    int * element0Ptr = &arrayParam; // BAD: Initialization from incompatible pointer type 

    element0Ptr = arrayParam;   // OK 
    element0Ptr = &arrayParam[0];  // OK 
} 

Merci pour toute aide que vous pouvez offrir! :)

Répondre

3

La plupart du temps, lorsque vous utilisez un tableau, il se décompose en un pointeur vers son élément initial. Donc, si vous avez:

void f(int* x); 

int array[10]; 
int* initial_element_of_array = array; // array decays to a pointer to initial element 
f(array);        // same here 

f() obtient un pointeur sur l'élément initial de array. Quelque chose qui est plutôt confus au début est que si une fonction a un paramètre qui est d'un type tableau (comme si vous aviez void f(int x[])), il est réellement converti de sorte qu'il est exactement le même que void f(int* x). Il n'y a pas de différence entre eux: les paramètres de type tableau sont les mêmes que les paramètres de type pointeur.

Une fois que vous passez un tableau à une fonction, tout ce que vous avez est un pointeur vers son élément initial, donc si vous appliquez l'opérateur & au int*, vous obtenez un int** (un pointeur sur un int*).

+0

Impressionnant James, merci pour la réponse super-claire! :) –

+0

Notez que cela peut devenir vraiment horrible avec des choses comme 'typedef int foo [1]; void f (foo x); 'Maintenant, quelqu'un raisonnable s'attendrait à ce que' & x' ait le type 'foo *', mais il a en fait un niveau supplémentaire d'indirection (c'est 'int **' au lieu de 'int (*) [1] '). Une version très pratique de ce problème se pose avec 'va_list', qui est souvent défini comme un type de tableau ... –