Passer par référence en C

J’essaie d’utiliser pass par référence en C pour que la fonction puisse modifier les valeurs des parameters qui lui sont transmis. Ceci est la signature de la fonction:

int locate(char *name, int &s, int &i) 

Cependant, lorsque j’essaie de le comstackr, j’obtiens cette erreur qui fait spécifiquement référence à la ligne ci-dessus:

erreur: attendu ‘;’, ‘,’ ou ‘)’ avant ‘&’ jeton

Si je supprime le ‘&’, le programme comstackra, mais il ne fonctionnera évidemment pas correctement. Quel est le problème ici? Comment puis-je effectuer un travail d’appel par référence?

    C n’a pas de références. Vous devez passer un pointeur sur la variable que vous souhaitez modifier:

     int locate(char *name, int *s, int *i) { /* ... */ *s = 123; *i = 456; } int s = 0; int i = 0; locate("GMan", &s, &i); /* s & i have been modified */ 

    C n’a pas de variables de référence, mais vous pouvez considérer référence comme un pointeur constant vers des données.

    Placez le pointeur const sur des données comme celle-ci afin que le pointeur ne puisse pas pointer sur d’autres données mais que les données pointées par celle-ci puissent être modifiées.

     int locate (char *name, int * const s, int * const i) 

    C ne supporte pas passer par référence. Vous aurez besoin de C ++ pour le faire comme il est écrit, ou le modifier en

     int locate(char *name, int *s, int *i) 

    et passez les pointeurs aux deuxième et troisième variables de paramètre.

    Les réponses précédentes semblent manquer de contexte et ne traitent pas de la propriété de surcharge des pointeurs C. Il est tout à fait juste de prétendre que C “passe par référence”. Un pointeur est aussi une référence. Cependant, plus formellement, une “référence” en C est le mécanisme permettant de représenter l’adresse de mémoire d’un symbole.

    • Un pointeur est simplement une variable en mémoire dont la valeur est traitée comme une adresse.
    • Une référence est simplement le littéral valeur d’une adresse de mémoire.
    • Le langage C permet de passer par référence – mais seulement dans le bon contexte!

    La séparation du contexte est celle de la définition de la signature et de son invocation.

    Considérons les primitives int a = 0x22e8; et ailleurs nous déclarons int* b = &a; (J’irai aux fonctions dans une minute).

    Nous pourrions visualiser ceci en mémoire (en supposant que l’endianisme n’a aucune importance pour cet exemple):

     ... 0x00000200: 22e8 ; this is the variable for int a's literal value: ; a == 0x000022e8 ; &a == 0x00000200 0x00000???: 9090 ; ... more code ... 0x00000400: 0200 ; this is pointer b pointing to a's address: ; b == 0x00000200 ; *b == 0x000022e8 ; &b == 0x00000400 ... 

    Il est facile de voir que nous pouvons affecter un pointeur à n’importe quelle adresse sans astuces spéciales. Un pointeur est juste une variable, mais C nous permet de référencer l’adresse vers laquelle il pointe. nous pouvons “déréférencer” le pointeur à partir de son adresse de valeur pour le traiter à la place de la valeur sous-jacente de sa pointe lors d’un contexte d’appel: while ( *b == a ) ... Nous pourrions facilement invoquer b == &a .

    Lorsque vous appliquez cela aux appels de fonction, vous devez séparer le contexte de la définition de la fonction (signature) et celui de l’invocation afin de différencier passe par référence.

     int* foo(int* blah, int nah) { .. } // signature definition context: // These are parameters ... vs ... b = foo( &a, 4); // invocation context: // These are arguments 

    En définissant une signature de fonction, nous ne disons pas au compilateur à partir de quelle adresse on accède à un argument – le moteur d’exécution ne le sait même pas encore! C’est absurde de définir la void bar(int &blah) {...} . À la place, nous utilisons la syntaxe de pointeur déréférencée – “quel que soit l’argument transmis, il sera chargé à l’adresse indiquée” – pour référencer la valeur de l’argument souhaité lors de l’exécution. Ainsi, C peut transmettre des arguments par référence.

    Les contextes des définitions de signature de fonction et des appels de fonction modifient la manière dont le compilateur considère la surcharge de pointeur par rapport à la référence et la manière dont le moteur d’exécution peut réellement y remédier.

    Vous ne pouvez pas faire cela en c. c n’a pas de référence, vous pouvez utiliser le pointeur à la place.

    Si vous souhaitez utiliser la méthode pass par référence pour modifier un paramètre utilisé dans un appel de fonction, utilisez toujours des pointeurs comme arguments formels de fonction.

    Par conséquent, au lieu d’utiliser cette

     int locate(char *name, int &s, int &i) 

    utilisation,

     int locate(char *name, int *s, int *i) 

    Lorsque vous appelez cette fonction, vous pouvez utiliser

    ………

     int a=5; int d=10; char c='A'; int result; result=locate(&c, &a, &d); 

    J’espère que tout sera clair maintenant,

    Pour en savoir plus sur le passage par valeur ou par référence et lequel est le meilleur, cette source est bonne pour les débutants

    http://www.learnc.net/call-by-reference.php

    S’amuser.

    (J’utilise C depuis un moment, mais je connais encore peu de concepts en C. J’essaie d’y répondre au mieux de mes connaissances, n’hésitez pas à me corriger si je me trompe.)

    Lorsque vous dites passer par référence, vous transmettez l’adresse et vous utiliserez des pointeurs pointant vers les adresses. Vous devez donc transmettre les pointeurs au prototype de votre fonction, mais vous passez directement à l’adresse.

    Ce que votre fonction essaie, c’est de dé-référencer (en utilisant &) votre pointeur, mais vous n’avez jamais eu de pointeur sur les parameters ‘s’ et ‘i’ pour le dé-référencer.

    La bonne façon de faire pour la fonction prototype / définition est

     int locate(char *name, int *s, int *i) 

    et lorsque vous devez appeler cette fonction, vous utilisez la déclaration ci-dessous dans la fonction principale ou appelante

     int locate(char *name, &s, &i)