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 :

initialiser une structure


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Points : 26
    Points
    26
    Par défaut initialiser une structure
    Salut à tous, je débute en c++,j'ai écrit en dev c++ cette fonction qui initialise deux champs d'une structure (int,float) en utilisant des pointeurs mais ça ne marche pas ,alors qu'avec des références ça marche très bien.
    Voici mon code :
    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
     
    #include<iostream>
    #include<conio.h>
    using namespace std;
    struct essai
    {
    int n;
    float x;
    };
     
     
     
    struct essai raz(struct essai* es );
    main()
    {
          struct essai ess;
          struct essai e;
          ess->n=60;//
          ess->x=45.23;
          cout<<"ess :"<<"[ "<<ess->n<<" ]" << "[ "<<ess->x<<" ]"<<endl;
          e=raz(&ess);
          cout<<"ess a 0 :"<<"[ "<<e->n<<" ]" << "[ "<<e->x<<" ]"<<endl;
     
    getch();
    }
    struct essai raz(struct essai* es)
    {
         es->n=0;
         es->x=0;
       return es;
    }

    Merci d'avence pour votre aide.
    Fichiers attachés Fichiers attachés

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Points : 379
    Points
    379
    Par défaut
    Pour ton problème de pointeur, ton "ess" n'est pas un pointeur, tu ne peux donc pas utiliser l'opérateur "->", tu dois utiliser "ess.n" et "ess.x".

    Sinon ton programme à d'autres petits soucis, par exemple main doit renvoyer un int et donc finir par un return. Et puis <conio.h> c'est pas top

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct essai raz(struct essai* es)
    {
         es->n=0;
         es->x=0;
       return es;
    }
    Problème entre le type retour et la valeur retournée!

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut, et bienvenue sur le forum.

    Déjà, il faut se rendre compte que, contrairement au langage C, la définition d'une structure (d'une union, d'une classe ou d'une énumération) provoque d'office la définition du type qui est associé.

    Il n'est donc plus nécessaire de préciser le mot clé struct(class, union ou enum) à chaque fois

    Ensuite, il faut savoir que, dans la fonction main, es et es ne sont pas des pointeurs, et qu'il faut donc utiliser e.x, e.n, es.x ou es.n.

    En outre, il faut savoir que la seule différence entre une classe et une structure est la visibilité par défaut des membres et méthodes: une classe aura une visibilité par défaut private alors qu'une structure aura une visibilité par défaut public.

    Mais cela implique que tu peux très bien (et c'est à la limite conseillé) envisager de créer directement un (ou plusieurs) constructeur(s), plutôt qu'une fonction raz (ou init ou...).

    Ainsi, ta structure pourrait très bien être avantageusement transformée en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct essai
    {
        int n;
        float x;
        essai():n(0),x(0.0){}
        essai(int n, float x):n(n),x(x){}
    };
    afin de pouvoir mettre en oeuvre le principe cher au C++ qu'est le RAII (Ressource Acquisition Is Initialisation)

    Grâce aux constructeurs ajoutés, ta structure pourrait être utilisée sous des formes proches de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        essai e; // initialisée à 0 et 0.0
        essai e2(10,3.1415926) ;
        std::cout<<e.n<<" "<<e.x<<std::endl
                 <<e2.n<<" "<<e2.x<<std::end;
        return 0;
    }
    Pour finir, il faut savoir qu'il est toujours préférable d'utiliser des références partout où c'est possible plutôt que d'utiliser des pointeurs.

    Cela permet - principalement - de ne pas devoir modifier la syntaxe des différents appels

    L'utilisation des pointeurs se limitant pour finir à quelques cas particuliers pour lesquels il devient impossible d'envisager de travailler avec des références
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Nouveau membre du Club
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Points : 26
    Points
    26
    Par défaut initialiser une structure
    Merci pour vos réponses et vos conseils.

  6. #6
    Nouveau membre du Club
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Points : 26
    Points
    26
    Par défaut initialiser une structure
    j'ai essayé ce petit programme et ça se compile très bien,mais à l'execution
    il s'affiche toujours :

    12 15.000000
    0 0.000000

    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
    #include<iostream>
     
    using namespace std;
     
    struct essai
    {
        int n;
        float x;
        essai():n(0),x(0.0){}
        essai(int n, float x):n(n),x(x){}
    };
     
    int main()
    {
        essai e; // initialisée à 0 et 0.0
        essai e2(11,3.1415926) ;
        std::cout<<e.n<<" "<<e.x<<std::endl
                    <<e2.n<<" "<<e2.x<<std::end;
     
       return 0;
    }

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Pas chez moi.... J'ai le bon affichage.
    Toutefois deux remarques:
    -> Certains compilo (Visual Express par expl), considère par défaut les constantes réelles comme des doubles. Toi tu veux un float. Il faut écrire 3.1415926f
    -> Donner le même nom aux paramètres du constructeur (ou de n'importe quelle méthode) et aux attributs membres est une mauvaise habitude :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct essai
    {
        int m_n;
        float m_x;
        essai():m_n(0),m_x(0.0){}
        essai(int n_, float x_):m_n(n_),m_x(x_){}
    };

  8. #8
    Nouveau membre du Club
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Points : 26
    Points
    26
    Par défaut
    merci pour la réponse

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    <snip>
    -> Donner le même nom aux paramètres du constructeur (ou de n'importe quelle méthode) et aux attributs membres est une mauvaise habitude<sniped code>
    Autant je suis d'accord sur le principe général, comprend, pour toute autre méthode que le constructeur, autant je suis moins péremptoire lorsqu'il s'agit du constructeur.

    D'abord parce que le constructeur permet de définir une liste d'initialisation, et qu'il n'y a donc - normalement - que peu de risque de conflit entre le nom de l'argument et le nom de la variable membre, à condition bien sur d'utiliser pleinement les possibilités offertes par les liste d'initialisation

    Ensuite parce que, pour moi, un code doit être a priori "auto commenté".

    Cela implique que - bien que l'exemple donné plus haut ne respecte pas ce principe - je considère comme étant une "bonne pratique" que de donner noms explicites aux membres et au méthodes, de manière à ce que la simple lecture de ce nom permette de se faire une idée précise du rôle du membre dans la structure.

    Ce principe s'applique à mon sens tout à fait aux noms des arguments à passer, du fait que les systèmes d'auto complétion actuels permettent de savoir non seulement le type de l'argument attendu, mais également le nom de la variable qui l'utilisera.

    Tout cela fiat que, si le membre porte un nom explicite, et que les faits font que le constructeur prenne un argument pour pouvoir initialiser correctement la structure, je n'aie donc aucun scrupule à donner le même nom à l'argument qu'au membre.

    Maintenant, j'admets néanmoins tout à fait que, en dehors du constructeur, il reste préférable d'éviter de donner le même nom à un argument qu'à un membre de la structure
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    En fait, c'est à mon sens, surtout un problème de maintenance et de relecture du code. Tu démarres un projet, tu fais les choses bien, et tu écris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class A
    {
    public:
     A(int i):i(i){}
    private:
    int i;
    };
    Sauf que trois ans après, arrive un gus moins bon que toi qui fait une modif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class A
    {
    public:
     A(int i):i(i)
      {
         i = 7;
      }
    private:
    int i;
    };
    etc, etc, etc... Au final, tu arrives avec un code qui devient illisible. Malheureusement, dans un contexte pro, tu trouves rarement du code qui suit les bons principes et malheureusement tu n'a jamais le temps pour un refactoring adéquat. D'où des règles de codage souvent en place qui est de préfixer les variables suivant leur portée. D'où le côté péremptoire, surtout dans un forum débutant.

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Le type qui modifie le constructeur en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class A
    {
    public:
     A(int i):i(i)
      {
         i = 7;
      }
    private:
    int i;
    };
    faut le pendre

    Enfin...

    Je comprend ton point de vue, mais, dans le stricte cadre du constructeur, je ne suis vraiment pas sur que le fait d'avoir un argument nommé b ou truc puisse réellement apporter quoi que ce soit en maintenabilité dans pareil cas
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/01/2014, 09h49
  2. initialiser une structure numpy.ndarray
    Par awalter1 dans le forum Calcul scientifique
    Réponses: 2
    Dernier message: 10/10/2011, 08h52
  3. Initialiser une structure contenant un tableau
    Par Muetdhiver dans le forum C
    Réponses: 4
    Dernier message: 13/10/2010, 18h46
  4. initialiser une structure
    Par hdgetnet dans le forum Débuter
    Réponses: 1
    Dernier message: 21/06/2010, 14h55
  5. initialiser une structure
    Par scarfunk dans le forum VB.NET
    Réponses: 23
    Dernier message: 05/05/2010, 12h42

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