web-dev-qa-db-fra.com

Passer un tableau à une fonction par valeur

Ci-dessous, un extrait du livre Programmation C Juste la FAQ . N'est-ce pas faux, car les tableaux ne peuvent jamais être transmis par référence?

VIII.6: Comment passer un tableau à une fonction par valeur?

Réponse: Un tableau peut être passé à une fonction par valeur en déclarant dans la fonction appelée le nom du tableau entre crochets ([ Et ]) Attachés à la fin . Lors de l'appel de la fonction, transmettez simplement l'adresse du tableau (c'est-à-dire le nom du tableau) à la fonction appelée. Par exemple, le programme suivant transmet le tableau x[] À la fonction nommée byval_func() par valeur:

Le paramètre int[] Indique au compilateur que la fonction byval_func() prendra un argument, un tableau d'entiers. Lorsque la fonction byval_func() est appelée, vous passez l'adresse du tableau à byval_func():

byval_func(x);

Étant donné que le tableau est transmis par valeur, une copie exacte du tableau est créée et placée sur la pile. La fonction appelée reçoit alors cette copie du tableau et peut l'imprimer. Étant donné que le tableau passé à byval_func() est une copie du tableau d'origine, la modification du tableau dans la fonction byval_func() n'a aucun effet sur le tableau d'origine.

36
Zuzu

Étant donné que le tableau est transmis par valeur, une copie exacte du tableau est créée et placée sur la pile.

Ceci est incorrect: le tableau lui-même n'est pas copié , seule une copie du pointeur vers son adresse est passée à l'appelé (placé sur la pile) . (Que vous déclariez le paramètre comme int[] ou int*, it se désintègre en un pointeur .) Cela vous permet de modifier le contenu du tableau depuis la fonction appelée . Ainsi, cette

Étant donné que le tableau transmis à byval_func () est une copie du tableau d'origine, la modification du tableau dans la fonction byval_func () n'a aucun effet sur le tableau d'origine.

est tout à fait faux (bravo à @Jonathan Leffler pour son commentaire ci-dessous). Toutefois, la réaffectation du pointeur à l'intérieur de la fonction ne modifiera pas le pointeur vers le tableau d'origine en dehors de la fonction.

60
Péter Török

Brûlez ce livre. Si vous voulez un vrai C FAQ qui n'a pas été écrit par un programmeur débutant, utilisez celui-ci: http://c-faq.com/aryptr/index.html .

En termes de syntaxe, à strictement parler, vous ne pouvez pas passer un tableau par valeur en C.

void func (int* x); /* this is a pointer */

void func (int x[]); /* this is a pointer */

void func (int x[10]); /* this is a pointer */

Cependant , pour l'enregistrement, il y a une sale astuce en C qui vous permet de passer un tableau par valeur en C. N'essayez pas cela à la maison ! Parce que malgré cette astuce, il n'y a toujours aucune raison de passer un tableau par valeur.

typedef struct
{
  int my_array[10];
} Array_by_val;

void func (Array_by_val x);
52
Lundin

En C et C++, il n'est PAS possible de passer un bloc complet de mémoire par valeur en tant que paramètre à une fonction, mais nous sommes autorisés à passer son adresse. En pratique, cela a presque le même effet et c'est une opération beaucoup plus rapide et plus efficace.

Pour être sûr, vous pouvez passer la taille du tableau ou mettre le qualificatif const avant le pointeur pour vous assurer que l'appelé ne le changera pas.

1
Rongkai Xu