Passage par référence en C

Bonjour,
j'ai le petite code suivant en C:
#include <stdio.h>

int *cinq(){
int g=5;
return &g;
}

int main(){
int *p;
p=cinq();
printf("La valeur pointée par p est %d\n", *p);
return 0;
}

Normalement le programme est censé m'afficher la valeur pointée par p est 5, mais il ne le fait pas car g est une variable locale, quelqu'un saurait comment arranger ça svp? Je souhaiterais faire un passage par référence dans la fonction cinq, c'est faisable?

merci
Configuration: Linux
Mozilla 1.9.0.16

5 réponses

Résumé de la discussion

Le problème central est qu'une fonction en C retourne l'adresse d'une variable locale, ce qui rend l'accès à *p après l'appel non fiable lorsque g est déclaré localement. En C, il n'existe pas de passage par référence comme en C++, on utilise un pointeur et on écrit dans l'adresse fournie par la fonction pour modifier la valeur d'origine. Par exemple, cinq prend un pointeur et écrit 5 à l'adresse fournie, puis main crée une variable entière et passe son adresse avant d'afficher la valeur. Si la modification du main est bloquée, on peut aussi recourir à une variable static dans la fonction ou à une allocation dynamique, selon les contraintes.

Bobot (l’IA à votre service)
  1. Contributeur
    Salut,

    Déjà en C, il n'y a pas de passage par référence. Les références sont un concept purement C++.
    Tu veux donc un vrai passage par référence en C++ ou un simple passage par pointeur ?

    Cdlt,
    1
    1. un passage par argument, donc par pointeur fiddy...
      0
  2. Un exemple court:
    void cinq(int* p)
    {
      *p = 5;
    }
    
    int main(void)
    {
      int* p = malloc(sizeof(int));
      cinq(p);
      printf("La valeur pointée par p est %d\n", *p);
      return 0;
    }
    Bonne continuation.
    0
    1. salut loupius, je ne peux pas utiliser malloc, je dois garder la variable g et très peu modifier le main, en gros je pense que cinq() doit impérativement retourner une adresse....
      0
  3. Salut,
    lami20j@debian:~/trash/AB$ cat a.c
    #include <stdio.h>
    
    int *cinq(){
      int a=5;
      int *g=&a;
      return g;
    }
    
    int main(){
      int *p=cinq();
      printf("La valeur pointée par p est %d\n", *p);
      return 0;
    }
    lami20j@debian:~/trash/AB$ gcc -Wall a.c
    lami20j@debian:~/trash/AB$ ./a.out
    La valeur pointée par p est 5
    0
    1. Salut lamij je me trompe peut etre mais où je ne vois aucun passage par référence dans ta fonction cinq()...?
      0
    2. Pour une fois je ne suis pas d'accord avec toi.
      Que la fonction retourne '&a' ou 'g', cela ne change rien; il est retourné l'adresse d'une variable locale qui n'aura plus aucun sens une fois la fonction terminée.
      Il faut trouver autre chose, par exemple:
      void cinq(int* p)
      {
        *p = 5;
      }
      
      int main(void)
      {
        int p;
        cinq(&p);
        printf("La valeur pointée par p est %d\n", p);
        return 0;
      }
      Bonne soirée.
      0
    3. @loupiusloupius je dois garder la déclaration de int *p dans le main et ensuite p=...

      en fait dans le p= je dois mettre l'adresse d'une variable tu es d'accord?
      Donc la fonction cinq() doit renvoyer l'adresse d'une variable...
      0
    4. @rogerRe,

      Si je ne me trompe pas, tu ne sais pas ce que tu veux.
      J'ai pris ton exemple et je l'ai modifié pour que ça marche, c'est tout.

      Si tu veux un passage par adresse alors ta fonction doit contenir des paramètres (des pointeurs).
      Ta fonction int *cinq() retourne un pointeur *int mais il n'y a pas des paramètres.
      0
    5. @lami20jlamij, en fait je souhaite un quelquechose de ce genre:

      cinq(int *p1), elle renvoie une adresse, et comme ça dans le main je garde:

      int *p;
      p=cinq(); le cinq me renvoie une adresse, mais je me demande si c'est possible de garder ce genre de schéma car aucune de vos réponses ne ressemble à cela...
      0
  4. Bon soir,

    Primo ton premier exemple est juste et il tourne : il affiche 5
    Secondo, on parle du passage par réference que dans les arguments d'une fonction, mais dans ton exemple ceci n'est que le type de retour de la fonction qui est int*

    Voici un exemple avec un passage par référence

    #include <stdio.h>

    void cinq(int * g){
    *g=5; //On accède en ecriture pour modifier la valeur pointée par g
    }

    int main(){
    int p;
    cinq(&p); //On passe la réference &p : adresse de p comme l'exemple célebre scanf(...,&p)
    printf("La valeur pointée par p est %d\n",p);
    return 0;
    }

    Dans cet exemple on passe une réference sur p pour que la fonction puisse modifier sa valeur

    @+
    0
    1. mon premier exemple est faux g est locale à la fonction...je ne peux pas le faire tourner...
      0
  5. Contributeur
    Salut,
    Il existe le mot-clé static.
    Très moche, mais bon si c'est ce que tu veux ^^.
    #include <stdio.h>
    
    int *cinq(){
        static int g=5;
        return &g;
    }
    
    int main(){
        int *p;
        p=cinq();
        printf("La valeur pointée par p est %d\n", *p);
        return 0;
    }
    
    0