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 :

modifier le champ d'une structure en entrée


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2021
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2021
    Messages : 7
    Par défaut modifier le champ d'une structure en entrée
    Bonjour, j'ai du mal a comprendre un résultat, je veux que ma fonction fct modifie un champ d'une structure en entrée, j'ai donc fait:

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct ma_structure_t {
        int nombre;
    } ma_structure_st;
     
    void fct(ma_structure_st * ma_structure){
        ma_structure = (ma_structure_st*)malloc(sizeof(ma_structure_st));
        ma_structure->nombre=11;
    }
     
    int main()
    {
        ma_structure_st * ma_structure;
        fct(ma_structure);
        printf("%i",ma_structure->nombre);
    }
    et mon résultat est un nombre "aléatoire" (je pense une adresse), pourtant les lignes de ma fonction seules dans un int main fonctionnent.
    j'ai du mal à comprendre pourquoi le résultat n'est pas 11?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Parce que les paramètres d'une fonction sont des copies.
    Donc dans fct, ma_structure est un pointeur qui copie l'adresse passée en paramètre.
    Mais les 2 pointeurs pointent vers la même chose.
    Mais étant non initialisé, ils pointent vers n'importe quoi.
    Puis la première chose que tu fais est de modifier ce pointeur, qui pointe donc vers autre chose.
    À partir de là, le paramètre, la variable interne à la méthode, et le truc passé en paramètre dans main n'ont plus rien à voir.
    Puis tu changes la valeur de cette autre chose.
    En plus de créer une fuite mémoire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Commençons par le début du programme.
    Ligne 15 tu définis un pointeur, tu ne lui donne pas de valeur.
    Ligne 16 tu passes la valeur de ce pointeur (donc un nombre très quelconque) à ta fonction. Que peut-elle faire de ce nombre aléatoire? D'ailleurs le compilateur a dû te le signaler par un beau "warning"!

    Reprenons, tu veux modifier une structure.
    Ligne 15 tu dois définir cette structure, surtout pas un pointeur!
    Ligne 16, tu dois passer l'adresse de cette structure pour que la fonction puisse la modifier.
    Ligne 8, ok tu reçois bien cette adresse, c'est bien un pointeur.
    Ligne 9, ôte vite entièrement cette ligne. Tu as reçu un pointeur ne surtout pas en perdre la valeur et ne surtout pas allouer dynamiquement de la mémoire mémorisée dans une variable locale à ta fonction.
    Ligne 10, c'est bon tu effectues bien la modification souhaitée.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par HfaitduC Voir le message
    je veux que ma fonction fct modifie un champ d'une structure en entrée
    Pas tout à fait. Tu veux que ta fonction alloue de la mémoire pour un pointeur sur une structure qu'elle reçoit en argument ; et ensuite qu'elle modifie le champ de cette structure allouée. Et enfin que le pointeur alloué (donc modifié) remonte chez l'appelant par ricochet. Et ça ce n'est pas pareil !!! Bien poser son besoin c'est déjà assurer la moitié du code

    Or pour qu'une fonction puisse modifier une variable qui se trouve chez l'appelant, elle doit recevoir l'adresse de cette variable, adresse qu'elle stocke dans un pointeur (tu as dû déjà avoir des exemples ne serait-ce qu'avec scanf()).
    Ce principe est valable pour toute variable. C'est donc valable pour une variable de type "int" dont l'adresse sera stockée dans un "int étoile", pour une variable de type "float" dont l'adresse sera stockée dans une variable de type "float étoile", et aussi pour une variable de type "ma_structure_st*" dont l'adresse sera stockée dans une variable de type "ma_structure_st* étoile".

    Prenons un exemple avec un float...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void fct(float *ma_structure){
            (*ma_structure)=12.345;
    }
     
    int main() {
        float ma_structure;
        fct(&ma_structure);
        printf("%f",ma_structure);
    }
    ... et adaptons cet exemple à un "ma_structure_st*" (on remplace chaque "float" par "ma_structure_st*")

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void fct(ma_structure_st* *ma_structure){
        (*ma_structure) = (ma_structure_st*)malloc(sizeof(ma_structure_st));
        (*ma_structure)->nombre=11;
    }
     
    int main() {
        ma_structure_st *ma_structure;
        fct(&ma_structure);
        printf("%i",ma_structure->nombre);
    }

    Maintenant, l'usage est plutôt que la fonction qui alloue renvoie le pointeur alloué. Ca évite ces doubles indirections...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ma_structure_st* fct(int v){
        ma_structure_st *pt=(ma_structure_st*)malloc(sizeof(ma_structure_st));
        pt->nombre=v;
        return pt;
    }
     
    int main() {
        ma_structure_st *ma_structure;
        ma_structure=fct(11);
        printf("%i",ma_structure->nombre);
    }
    Et cesse de mettre un espace avant et après l'étoile (on a l'impression que tu ne sais pas trop quoi en faire). Soit tu écris ma_structure_st *ma_structure sigifiant "ce qui est pointé par ma_structure est un type ma_structure_st", soit tu écris ma_structure_st* ma_structure signifiant "ma_structure est un pointeur sur un type ma_structure_st". Les deux écritures sont possibles et du point du compilateur strictement équivalentes. Mais choisir l'une ou l'autre te permet de te positionner dans une façon de voir ta variable. Tandis qu'avec cette étoile isolée...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2021
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2021
    Messages : 7
    Par défaut
    Merci à vous 3, vos 3 commentaire mon chacun aidé. Je ne dirais pas que je maitrise, mais je comprend mieux. Je tiens à vous dire que le temps que vous m'avez accordé a embelli ma soirée.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 18/06/2019, 16h24
  2. Réponses: 4
    Dernier message: 10/04/2006, 09h28
  3. Comment modifier un champ dans une table liée ?
    Par HookerSeven dans le forum Access
    Réponses: 11
    Dernier message: 05/02/2006, 23h50
  4. modifier les champs d'une table
    Par zidenne dans le forum Bases de données
    Réponses: 1
    Dernier message: 27/10/2005, 15h22
  5. [EJB2.1 Entity] [CMP] Modifier un champ d'une clé primaire
    Par Medo_free dans le forum Java EE
    Réponses: 4
    Dernier message: 14/03/2005, 18h04

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