IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Transmission d'une valeur d'une variable locale ?


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut Transmission d'une valeur d'une variable locale ?
    La fonction ci-dessous ne présente aucune erreur lors de la compilation, mais je n'ai pas compris la transmission de la valeur du pointeur "r" (variable locale) à travers les appels de la fonction create_node().


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
     
    // Node structure containing power and coefficient of variable 
    	typedef struct Node { 
        			int coeff; 
        			int pow; 
        			struct Node* next; 
    			}  Node; 
     
    	//A) Function to create new node 
    	void create_node(int x, int y, Node** temp) 
    	{ 
        	Node *r, *z; 
        	z = *temp; 
        	if (z == NULL) 
    		   {  
            	  r = (Node*)malloc(sizeof(struct Node)); 
            	  r->coeff = x; 
            	  r->pow = y; 
            	  *temp = r; 
           		  r->next = (Node*)malloc(sizeof(struct Node)); 
            	  r = r->next; 
            	  r->next = NULL; 
         	   } 
         	else 
    		   { 
            	  r->coeff = x; 
                  r->pow = y; 
                  r->next = (Node*)malloc(sizeof(Node)); 
                  r = r->next; 
                  r->next = NULL; 
               } 
        } 
     
    //B) Display Linked list 
    void show(Node* node) 
    { 
        while (node->next != NULL) { 
            printf("%dx^%d", node->coeff, node->pow); 
            node = node->next; 
            if (node->coeff >= 0) { 
                if (node->next != NULL) 
                    printf("+"); 
            } 
        } 
    } 
     
     
     
    int main()
    {
    	struct Node *poly1 = NULL, *poly2 = NULL, *poly = NULL; 
     
        // Create first list of 15x^3 + x^2 - 6x^1+ 10x^0 
        create_node(-15, 3, &poly1);
        create_node(1, 2, &poly1); 
        create_node(-6, 1, &poly1); 
        create_node(10, 0, &poly1);
     
     
        printf("\n Le Polynome : "); 
        show(poly1); 
     
    	return 0;
    }
    Merci pour votre aide.

  2. #2
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Je n'ai pas regardé en détail, mais ligne 31 à 35 tu déréférences r alors qu'il n'est pas initialisé.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  3. #3
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 773
    Par défaut
    En + de ce que a signalé @CGi :
    • on ne caste pas les malloc (void*) en C. Par contre en C++, il le faut
    • tu ne testes pas le retour des malloc.


    Pour ta question :
    On passe en paramètre sortie/ écriture l'adresse d'1 pointeur : Node** temp.

    La variable locale r ne sert à rien dans ton cas parce que tu ne testes pas le retour malloc.
    Et même avec le test, elle est très dispensable … sauf pour l'écriture moins lourde par rapport à temp (1 déférencement vs 2) : elle sert à stocker l'adresse du nouveau maillon, de l'initialiser et de chaîner

    Et à la fin, on "retourne" ce nouveau maillon grâce à temp: *temp = r;.

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut
    Bonjour,

    Je suis d'accord avec toi feotus :

    On passe en paramètre sortie/ écriture l'adresse d'1 pointeur : Node** temp. Ok : On récupére l'adresse de tête de liste comme temp est passée par adresse (lecture/écriture).

    Et à la fin, on "retourne" ce nouveau maillon grâce à temp: *temp = r;. Ok uniquement pour la création du premier noeud (élément) de la liste.

    En revanche, j'ai un problème avec la variable locale "r" lors de la création des noeuds (éléments) suivants de la liste (à partir du 2ème...), Comment récupérer la dernière adresse (adresse du noeud queue de liste) pour pouvoir le chainer avec le nouveau maillon à inserer.

    Dans la partie else de la fonction create_node () on a pas *temp=r;

    Merci pour vos réponses.

  5. #5
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 792
    Par défaut
    Hello,

    Dans la partie 'else', r n'est pas initialisé. C'est un UB.

    Si tu veux ajouter un maillon à la fin de la liste, tu dois:
    1) créer le nouveau maillon (et vérifier que le malloc() ait fonctionné),
    2) aller chercher le dernier maillon de la liste (=parcourir la liste depuis le début, jusqu'à trouver un maillon dont le suivant n'existe pas),
    3) faire pointer le dernier maillon de la liste (trouvé en 2) sur le nouveau maillon (créé en 1)

    NB: les 1) et 2) peuvent être inversés.

    Et quand tu auras un code qui fonctionne, tu t'apercevras qu'il y a des choses identiques faites dans le 'then' et dans le 'else', et que la fonction peut être simplifiée.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut
    Bonjour,

    Je suis d'accord mais ce programme fonctionne parfaitement (je ne cherche pas à écrire un autre) mais ma question est liée à la valeur de la variable locale "r" ou bien comment transmettre la valeur du dernier maillon alors qu'il n y a pas de boucle qui traverse la liste jusqu'à ce dernier élément pour qu'on puisse greffer le nouveau maillon en fin de liste (appel de la fonction create_node()).

    Ce programme m'intrigue !

    Merci.

  7. #7
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 792
    Par défaut
    Citation Envoyé par hogar Voir le message
    Je suis d'accord mais ce programme fonctionne parfaitement
    Que vaut r à la ligne 31 ? Edit: et suivantes ?

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut
    C'est ça la question, si on débugue ou on ajoute des printf() on remarque qur r contient l'adresse du dernier élement ce qui permet d'inserer le dernier node créé lors d'un appel ultérieur de la fonction create_node() cad après l'insersion du premier node (tête de liste) !!!

  9. #9
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 792
    Par défaut
    Si ce code fonctionne, c'est uniquement par chance (ou malchance). La valeur de r est indéfinie lorsque tu l'emploies à la ligne 31.

    Un code qui fonctionne suivant les 1) 2) 3) plus haut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
     
    struct node {
    	int coeff;
       	int pow;
       	struct node *next_node;
    };
     
     
    struct node *CreateNode(int c, int p) {
    	struct node *new_node=malloc(sizeof(struct node));
    	if(new_node) {
    		new_node->coeff=c;
    		new_node->pow=p;
    		new_node->next_node=NULL;
    	}
     
    	return(new_node);
    }
     
    struct node *GetLastNode(struct node *ptr) {
    	if(!ptr)
    		return(NULL);
    	struct node *last_node;
    	do {
    		last_node=ptr;
    		ptr=ptr->next_node;
    	} while(ptr);
     
    	return(last_node);
    }
     
    bool InsertNodeAtEndOfList(struct node **first_node, int c, int p) {
    	struct node *new_node=CreateNode(c, p);					// le 1)
    	if(!new_node)
    		return(false);
    	struct node *last_node=GetLastNode(*first_node);			// le 2)
    	if(!last_node)
    		*first_node=new_node;						// liste vide (le 'then')
    	else
    		last_node->next_node=new_node;					// le 3)
     
    	return(true);
    }
     
    void DisplayList(struct node *ptr) {
    	for(int n=1; ptr; ptr=ptr->next_node, ++n)
    		printf("%2d\t\%d\t%d\n", n, ptr->coeff, ptr->pow);
    	puts("--------------------------------");
    }
     
    void Check(struct node **first_node, int c, int p) {
    	if(InsertNodeAtEndOfList(first_node, c, p))
    		DisplayList(*first_node);
    	else
    		printf("Erreur insertion pour %d %d\n", c, p);
    }
     
    int main(void) {
    	struct node *first_node=NULL;
    	Check(&first_node, 50, 51);
    	Check(&first_node, 40, 41);
    	Check(&first_node, 10, 11);
    	Check(&first_node, 30, 31);
    	Check(&first_node, 20, 21);
     
    	return(0);
    }
    Edit: présentation

  10. #10
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut
    Merci beacoup edgarjacobs.

    J'ai voulu juste comprendre pourquoi le programme que j'ai posté fonctionne (il fonctionne sur mon poste et également en utilisant un compilateur en ligne).

    Je ne sais pas s'il fonctionne à votre niveau.

    Merci.

  11. #11
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 792
    Par défaut
    Citation Envoyé par hogar Voir le message
    Je ne sais pas s'il fonctionne à votre niveau.
    Je ne l'ai pas testé, car la compilation donne clairement le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    tyy.c: In function 'create_node':
    tyy.c:29:28: warning: 'r' may be used uninitialized [-Wmaybe-uninitialized]
       29 |                   r->coeff = x;
          |                   ~~~~~~~~~^~~
    tyy.c:15:15: note: 'r' was declared here
       15 |         Node *r, *z;
          |               ^
    Et utiliser r non initialisé, c'est un UB. Ça peut fonctionner, se ramasser, fonctionner dans un environnement et pas dans un autre, ne plus fonctionner suite à l'ajout de code.... Un UB, c'est la pire des choses dans un programme.


    Il faut demander au compilateur le maximum d'avertissements possibles, avec gcc au moins activer les options -Wall et -Wextra. Et bien sur, corriger toutes les warnings, à moins d'être très (très) sur de soi.

    Edit: juste pour le fun: C99 List of Undefined Behavior

  12. #12
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut
    C'est la répose que je cherchais.

    Un grand merci edgarjacobs.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/07/2019, 16h09
  2. valeur d'une variable locale ?:serveur lié
    Par realtolive dans le forum Développement
    Réponses: 1
    Dernier message: 12/04/2012, 19h01
  3. Utiliser la valeur d'un spinner lors de la déclaration d'une variable locale
    Par Jiggazzzzz dans le forum Composants graphiques
    Réponses: 4
    Dernier message: 05/12/2011, 09h31
  4. Echec de stockage d'une valeur dans une variable locale pointée par EBP
    Par homeostasie dans le forum x86 32-bits / 64-bits
    Réponses: 1
    Dernier message: 16/12/2008, 13h52
  5. Réponses: 2
    Dernier message: 08/04/2007, 22h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo