Le passage d'un tableau en argument d'une fonction en C
J'ai écrit une fonction contenant le tableau comme argument,
et de l'appeler en passant de la valeur de tableau comme suit.
void arraytest(int a[])
{
//changed the array a
a[0]=a[0]+a[1];
a[1]=a[0]-a[1];
a[0]=a[0]-a[1];
}
void main()
{
int arr[]={1,2};
printf("%d \t %d",arr[0],arr[1]);
arraytest(arr);
printf("\n After calling fun arr contains: %d\t %d",arr[0],arr[1]);
}
Ce que j'ai trouvé est que je suis d'appel arraytest()
de la fonction par la transmission de valeurs, la copie originale de int arr[]
est changé.
Pouvez-vous expliquer pourquoi?
- Vous êtes de passage le tableau par référence, mais vous êtes en train de modifier son contenu, c'est pourquoi vous voyez un changement dans les données
Vous devez vous connecter pour publier un commentaire.
Lors du passage d'un tableau comme paramètre, ce
signifie exactement le même que
de sorte que vous sont modifiant les valeurs dans la main.
Pour des raisons historiques, les tableaux ne sont pas des citoyens à part entière et ne peuvent pas être passés par valeur.
struct
a été ajouté à la langue que cela a été changé. Et puis, il était trop tard pour changer les règles pour les tableaux. Il y avait déjà 10 utilisateurs. 🙂void arraytest(int a[1000])
etc etc. Élargi réponse ici: stackoverflow.com/a/51527502/4561887.Vous n'êtes pas passer le tableau en tant que copie. C'est seulement un pointeur pointant vers l'adresse où le premier élément est en mémoire.
Vous êtes de passage à l'adresse du premier élément du tableau
En C, à l'exception de quelques cas particuliers, une référence de tableau toujours "désintègre" à un pointeur vers le premier élément du tableau. Par conséquent, il n'est pas possible de passer un tableau "par valeur". Un tableau dans une fonction d'appel sera passé à la fonction comme un pointeur, ce qui est analogue au passage de la matrice de référence.
EDIT: Il y a trois de ces cas spéciaux où un tableau ne tombe pas à un pointeur, c'est le premier élément:
sizeof a
n'est pas le même quesizeof (&a[0])
.&a
n'est pas le même que&(&a[0])
(et pas tout à fait la même que&a[0]
).char b[] = "foo"
n'est pas le même quechar b[] = &("foo")
.int a[10]
et attribuée à chaque élément de valeur aléatoire . Maintenant, si je passe ce tableau à une fonction à l'aide deint y[]
ouint y[10]
ouint *y
.Et puis dans cette fonction j'utilisesizeof(y)
Réponse sera les octets pointeur a été alloué. Donc, dans ce cas ,il se décomposerait comme un pointeur , Il Serait Utile Si Vous incluez ce trop. Voir ce postimg.org/image/prhleuezdsizeof
fonctionner dans la fonction de l'origine, nous avons défini la matrice puis il se décomposerait comme un tableau , mais si je passe dans une autre fonction puis il y a l'utilisationsizeof
opérateur, il se décomposerait comme un pointeur.Vous êtes de passage à la valeur de l'emplacement de mémoire de la première membre de la matrice.
Par conséquent, lorsque vous commencer à modifier le tableau à l'intérieur de la fonction, vous êtes en train de modifier le tableau d'origine.
Rappelez-vous que
a[1]
est*(a+1)
.Si vous voulez pass tableau à une seule dimension, comme un argument dans une fonction, vous devez déclarer un paramètre formel dans l'une des trois façons suivantes et tous les trois de la déclaration de méthodes produisent des résultats similaires parce que chaque indique au compilateur qu'un pointeur entier va être reçu.
Donc, vous êtes en train de modifier les valeurs d'origine.
Merci !!!
Tableaux en C sont convertis, dans la plupart des cas, un pointeur vers le premier élément du tableau lui-même. Et plus en détail dans les tableaux passées dans des fonctions sont toujours convertis en indicateurs.
Ici une citation de K&R2nd:
Écrit:
a le même sens que l'écriture:
Donc, en dépit de vous ne sont pas à l'écrire explicitement, c'est que vous êtes de passage d'un pointeur et donc vous êtes en train de modifier les valeurs dans la main.
Pour plus vraiment, je suggère la lecture de cette.
En outre, vous pouvez trouver d'autres réponses sur DONC ici
Le passage d'un tableau multidimensionnel comme argument d'une fonction.
En passant on dim tableau en argument est plus ou moins frivoles.
Jetons un coup d'oeil sur la plus intéressante cas de passage d'un 2 dim tableau.
En C, vous ne pouvez pas utiliser un pointeur de pointeur de construire (int **) au lieu de 2 dim tableau.
Nous allons faire un exemple:
Ici, j'ai spécifié une fonction qui prend comme premier argument un pointeur sur un tableau de 5 entiers.
Je peux la passer en argument à 2 dim tableau qui a 5 colonnes:
Vous pouvez venir à une idée de définir un cadre plus général de la fonction qui peut accepter toutes les 2 dim tableau et changer la signature de la fonction comme suit:
Ce code compile, mais vous obtiendrez une erreur d'exécution lorsque vous essayez d'affecter les valeurs de la même manière que dans la première fonction.
Donc, en C les tableaux multidimensionnels sont pas les mêmes que les pointeurs de pointeurs ... à des pointeurs. Un int(*arr)[5] est un pointeur sur tableau de 5 éléments,
un int(*arr)[6] est un pointeur sur tableau de 6 éléments, et ils sont une des pointeurs de types différents!
Eh bien, comment définir les fonctions des arguments pour les dimensions supérieures? Simple, il faut simplement suivre la tendance!
Hier ist la même fonction ajusté pour tenir un tableau de 3 dimensions:
Comment vous pouvez vous attendre, il peut prendre comme argument 3 dim tableaux qui ont dans le second dimensions les 4 éléments, et dans la troisième dimension 5 éléments. Quelque chose comme ce serait ok:
Mais nous devons spécifier toutes les dimensions des tailles allant jusqu'à la première.
@Bo Persson correctement unis, dans sa grande réponse ici:
=================================================
Lors du passage d'un tableau comme paramètre, ce
signifie exactement le même que
=================================================
Cependant, permettez-moi d'ajouter que c':
signifie exactement le même que
qui signifie exactement la même que
qui signifie exactement la même que
qui signifie exactement la même que
etc.
Comme une question de fait, la "taille" de la valeur à l'intérieur du tableau de paramètre ici est apparemment juste pour l'esthétique/auto-documentation, et peut être n'importe quel entier positif (
size_t
type je pense) que vous voulez!Dans la pratique, toutefois, vous devez l'utiliser pour spécifier la taille minimale de la matrice de vous attendre à la fonction de recevoir, de sorte que lors de l'écriture de code, il est facile pour vous de suivre et de vérifier. Le MISRA-C-2012 standard (acheter/télécharger le 236-pg 2012-version PDF de la norme pour £15.00 ici) va jusqu'à affirmer:
...
...
En d'autres termes, ils recommandent d'utiliser explicitement le format de la taille, même si le C standard, techniquement, ne pas l'appliquer--au moins permet de clarifier pour vous en tant que développeur, et pour les autres en utilisant le code, quelle est la taille de la matrice de la fonction vous attend pour passer en.
void arraytest(int (*a)[1000])
est mieux, car alors le compilateur générera une erreur si la taille est mal.