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 :

structures et tableaux


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut structures et tableaux
    Bonjour,

    j'ai une structure qui doit se présenter à priori de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct Test{
    	float	Min;
    	float	Max;
    	float	Coord[3];
    } Test;
    J'aimerai utiliser un tableau pour le dernier champ pour rentrer les coordonnées 3D d'un vecteur par exemple.
    Est-ce que c'est possible ?

    Je dois ensuite remplir grâce à une fonction les champs de cette structure, et je ne fais apparement pas ça comme il faut, à moins que le problème ne vienne de l'utilisation du tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void FillStruct( float *fStat, ClassPoint *fCoord, Test *StructTest )
    {
    	 StructTest->Min = fStat[0] ;
    	 StructTest->Max = fStat[1];
                  StructTest->Coord[0] = fCoord.x;
                  StructTest->Coord[1] = fCoord.y;
                  StructTest->Coord[2] = fCoord.z;
    }
    Voilà, j'ai à peu près ça, et j'ai une erreur :
    un indice requiert un tableau ou type pointeur.
    Je sens que j'ai soit fait une ptite erreur et que je m'endors sur mon clavier et ne la vois pas soit une grosse boulette
    Si qqun a la solution je prends
    Merci

  2. #2
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2008
    Messages
    144
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2008
    Messages : 144
    Par défaut
    heu juste comme ca par soucis de conception.
    ne pourrais-tu pas utiliser une classe plutot que une struct
    tu pourrais y inserer des methodes de remplissage. non?

  3. #3
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                  StructTest->Coord[0] = ClassPoint.x;
    Dans ton code ClassPoint est un type.

    Ce n'est pas plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                  StructTest->Coord[0] = fCoord->x;
    que tu voulais faire ?

  4. #4
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Citation Envoyé par Lucien63 Voir le message
    Ce n'est pas plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                  StructTest->Coord[0] = fCoord->x;
    que tu voulais faire ?

    mmh
    Si si, je me suis rendue compte de mon erreur avec le post de Dalini71, donc j'ai été éditer mon 1er post, pardon je l'ai écrit un peu vite

    Citation Envoyé par Dalini71
    - On préfère l'utilisation d'un vector à l'utilisation de tableaux
    Sinon pour ton erreur, la paramètre fStat est bien un tableau ?
    j'ai un peu simplifié le code pour le poster ici, mais en gros fStat est un pointeur et à priori l'erreur vient bien de Coord[3]


    En fait pour faire plus simple sur ce qui me pause à priori problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void FillStruct( ClassPoint *fCoord, Test *StructTest )
    {
                  StructTest->Coord[0] = fCoord.x;
                  StructTest->Coord[1] = fCoord.y;
                  StructTest->Coord[2] = fCoord.z;
    }

    Que veux tu dire par "- On préfère l'utilisation d'un vector à l'utilisation de tableaux" ?

  5. #5
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Citation Envoyé par adrien1 Voir le message
    heu juste comme ca par soucis de conception.
    ne pourrais-tu pas utiliser une classe plutot que une struct
    tu pourrais y inserer des methodes de remplissage. non?
    Je confirme, une classe serai bien plus simple,
    seulement dans mon cas je n'ai pas le choix, ça doit être une structure

  6. #6
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par LostInGeekLand Voir le message
    Je confirme, une classe serai bien plus simple,
    seulement dans mon cas je n'ai pas le choix, ça doit être une structure
    Les classes et les stuctures sont totalement identiques en C++. (enfin, excepté leur visibilité par défaut, public pour une struct, private pour une classe).

  7. #7
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Les classes et les stuctures sont totalement identiques en C++. (enfin, excepté leur visibilité par défaut, public pour une struct, private pour une classe).
    OK
    En fait j'en ai besoin pour un usage ensuite externe à C++
    Bref c'est compliqué mais en gros j'ai vraiment pas le choix

  8. #8
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Sinon, pour ton problème... et bien ça dépend probablement de la définition de ClassPoint...

    Edit : Hmm, d'après msdn :

    Message d'erreur
    un indice requiert un type tableau ou pointeur
    subscript requires array or pointer type

    L'indice a été utilisé sur une variable qui n'était pas un tableau.

    L'exemple suivant génère l'erreur C2109 :
    Tu nous montres bien le code que tu essayes réellement de compiler ?

    Edit 2 : Juste pour préciser, car la traduction automatique de msdn est complètement à coter de la plaque : Par subscript, il faut comprendre "opérateur []" et pas "indice".
    Donc a priori, tu essayes d'appliquer un [] à une variable qui n'est pas un tableau. Peut-être une erreur inattention?

  9. #9
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    Bonjour,

    Déjà, quand on code en C++ :

    - On préfère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct maStructure
    {
    ...
    };
    à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct maStructure
    {
    ...
    } maStructure;
    - On préfère le passage par référence au passage par pointeurs
    - On préfère l'utilisation d'un vector à l'utilisation de tableaux

    Sinon pour ton erreur, la paramètre fStat est bien un tableau ?
    Si non, ton erreur vient surement de là.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Déjà,le "Test" qui se trouve entre l'accolade fermante et le point virgule est inutile et... dangeureux...

    En effet, il déclare une variable globale Test qui est du type... Test, et ca risque de foutre le bordel intégral
    Ceci dit, lorsque tu essaye d'accéder à
    ClassPoint.x, ClassPoint.y et ClassPoint.z, tu utilise un nom de type là où tu devrais utiliser... un nom de variable (fCoord, en l'occurrence)

    Et, comme tu as passé fCoord sous la forme d'un pointeur sur un objet de type ClassPoint, tu dois utiliser la flèche " -> " pour accéder au membre souhaité
    Ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                  StructTest->Coord[0] = ClassPoint.x;
                  StructTest->Coord[1] = ClassPoint.y;
                  StructTest->Coord[2] = ClassPoint.z;
    doit donc être modifié en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                  StructTest->Coord[0] = fCoord -> x;
                  StructTest->Coord[1] = fCoord -> y;
                  StructTest->Coord[2] = fCoord -> z;
    Ceci dit...

    Il existe en C++ un mécanisme qui permet d'éviter l'utilisation de pointeurs et les problèmes qui y sont liés (dont la nécessité de récupérer l'adresse de l'objet, et le changement de syntaxe pour accéder aux membres) lorsqu'il s'agit, simplement, de passer des structures en en évitant la copie

    J'ai nommé: la référence.

    La référence agit comme un alias de l'objet que l'on transmet lors de l'appel, et, pour être sur que nous n'iront pas modifier, dans la fonction appelée, l'objet transmis, il est possible et conseillé de déclarer un argument qui ne doit pas être modifié sous la forme d'une référence constante.

    Ainsi, le code, finalement assez lourd proche de

    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
    void FillStruct( float *fStat, ClassPoint *fCoord, Test *StructTest )
    {
        /* ici, il faut accéder aux membres de fCoord et de StructTest
         * avec la fleche, parce que nous manipulons des pointeurs
         * et que nous voulons accéder au contenu des objet pointés
         */
    }
    void foo()
    {
        float ftab[2]; /* notre tableau de float */
        ClassPoint cp; /* notre instance de classe point origielle */
        Test t; /* notre instance de classe de teste */
        /*
         * initialisation de ftab[0] et de ftab[]1
         */
        /* pour passer des pointeurs sur cp et sur t, il faut en prendre l'adresse */
        FillStruct(ftab, & cp, & t);
    }
    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
    serait avantageusement remplacé par
    /* fStat doit rester un pointeur,
     * fCoord deviendrait une référence constante (car fCoord n'a
     * pas vocation à être modifié)
     * et StructTest deviendrait une référence (car les modification apportées 
     * au sein de FillStruct doivent être répercutées dans la fonction appelante )
     */
    void FillStruct( float *fStat, ClassPoint const & fCoord, Test &StructTest )
    {
        /* Il n'y a plus de changement de syntaxe entre l'objet et la référence
         */
    	 StructTest . Min = fStat[0] ;
    	 StructTest . Max = fStat[1];
                  StructTest . Coord[0] = fCoord.x;
                  StructTest . Coord[1] = fCoord.y;
                  StructTest . Coord[2] = fCoord.z;
     
    }
    void foo()
    {
        float ftab[2]; /* notre tableau de float */
        /*
         * initialisation de ftab[0] et de ftab[]1
         */
        ClassPoint cp; /* notre instance de classe point origielle */
        Test t; /* notre instance de classe de teste */
       /* nous pouvons passer cp et t sans même devoir en prendre l'adresse */
        FillStruct(ftab, cp, t);
    }
    Enfin, si le tableau de float à transmettre en tant que fStat venait à devoir contenir un nombre important ou inconnu d'éléments, il serait opportun d'utiliser de préférence la classe vector, fournie par le standard et disponible dans l'espace de noms std par simple inclusion du fichier <vector>.

    On peut d'ailleurs, bien que cela ne change pas grand chose dans le cas présent, envisager d'utiliser cette classe pour un tableau de taille minime et connue à l'avance

    Cela aurait pour avantages:
    1. De nous décharger de la gestion manuelle de la mémoire à allouer (et à libérer) dynamiquement
    2. De nous permettre de passer la structure sous forme de référence (éventuellement constante), et donc de supprimer la dernière utilisation de pointeurs présente dans le code
    3. le fait que la classe vector connait sa taille (au travers de la fonction membre size() ) alors qu'il nous serait nécessaire de la transmettre en paramètre autrement

    Nous en arriverions donc à un code proche de
    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
    /* tout est passé par référence
     * fStat et fCoord sous la forme de références constantes car
     * ils n'ont pas vocation à être modifés
     * et structTest sous la forme de référence non constante, car les
     * modifications apportées dans la fonction appelées doivent être
     * répercutées dans la fonction appelante
     */
    void FillStruct(std::vector<float> const &fStat, ClassPoint const & fCoord,
                    Test &StructTest )
    {
        /* Il n'y a plus de changement de syntaxe entre l'objet et la référence
         */
    	 StructTest . Min = fStat[0] ;
    	 StructTest . Max = fStat[1];
                  StructTest . Coord[0] = fCoord.x;
                  StructTest . Coord[1] = fCoord.y;
                  StructTest . Coord[2] = fCoord.z;
     
    }
    void foo()
    {
        std::vector<float> ftab(2); /* notre tableau de float */
        /*
         * initialisation de ftab[0] et de ftab[1]
         */
        ClassPoint cp; /* notre instance de classe point origielle */
        Test t; /* notre instance de classe de teste */
       /* nous pouvons passer cp et t sans même devoir en prendre l'adresse */
        FillStruct(ftab, cp, t);
    }
    Enfin, tant qu'à faire, nous pourrions envisager de mettre le RAII (Ressource Aquisition Is Initialization ou en francais l'acquisition des ressource vaut initialisation) en oeuvre...

    En effet, min et max peuvent être considérés comme étant des valeurs constantes connues à la compilation

    Cela nous donnerait une classe Test proche de
    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
    class Test
    {
        public:
            /* le constructeur par défaut */
            Test():min(-999.9999),max(999.9999),x(0.0)(0.0),z(0.0){}
            /* le constructeur prenant x, y et z */
            Test(float x, float y, float z):min(-999.9999), max(999.9999), 
                x(0.0)(0.0),z(0.0){}
             /* éventuellement, un constructeur prenant un ClassPoint en 
              * argument le mot clé explicit évite que ce constructeur ne serve
              * d'opérateur de conversion implicite d'un objet de type
              * ClassPoint en un objet de type Test
              */
             explicit Test (ClassPoint const & cp):min(-999.9999),max(999.9999),
                 x(cp.x)(cp.y),z(cp.z){}
             /* les accesseurs sur x, y et z */
             float getX() const{return x;}
             float getY() const{return y;}
             float getZ() const{return z;}
        private:
            /* interdisons l'acces à x, y et z en dehors de la classe */
            float x;
            float y;
            float z;
    }
    Nous pourrions alors utiliser un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void foo()
    {
        /* créons une instance avec les valeurs par défaut */
        Test t; /* plus besoin d'initialiser, c'est magique :D */
        /* créons une instance avec des valeurs données pour x, y et z */
        Test t2(3.1415, 6.2831, 9.4246);
        /* ou encore, utilisons un objet de type ClassPoint */
        ClassPoint cp;
        /* je laisse l'initialisation */
       Test t3(cp);
    }
    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

  11. #11
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    Que veux tu dire par "- On préfère l'utilisation d'un vector à l'utilisation de tableaux" ?
    Grosso-Modo, les vector représentent une alternative aux tableaux, c'est plus simple/intuitif, mieux optimisé.

    Je vais pas te faire un cours, certains l'ont fait mieux que moi, d'ailleurs voila un lien

    - Sur notre chère FAQ

    Edit : Grillé

  12. #12
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Citation Envoyé par LostInGeekLand
    mmh
    Si si, je me suis rendue compte de mon erreur avec le post de Dalini71, donc j'ai été éditer mon 1er post, pardon je l'ai écrit un peu vite
    Oui, sauf que tu as lu à moitier le bout de code que je t'ai posté !

  13. #13
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Merci à tous
    Je devrais arriver à m'en sortir avec tout ça, je ferme quand même pas le sujet pour l'instant, on sait jamais
    Et je vais essayer de regarder ces <vector> de plus près
    Merci

  14. #14
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Je ferme le sujet,
    ça m'a permit de mieux comprendre qques trucs
    Même si au final (à part ma mauvaise retranscription entre ClassePoint et les -> remplacés par des . ) je n'étais pas si loin de la solution. Une erreur s'était glissée dans la déclaration de fonctions au dessus de tout ça et la compilation ne l'avait pas vu (et moi non plus )
    merci à tous

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

Discussions similaires

  1. probleme pour structure et tableaux
    Par yassin123441 dans le forum C++
    Réponses: 1
    Dernier message: 18/06/2008, 01h11
  2. Type Structuré et Tableaux
    Par Aurazed dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 30/05/2007, 22h45
  3. [C++/CLI]Structures et tableaux en C++ .NET
    Par kinouseb dans le forum C++/CLI
    Réponses: 2
    Dernier message: 08/12/2006, 14h01
  4. [XSD]Créer structure de tableaux
    Par blastobi dans le forum Valider
    Réponses: 4
    Dernier message: 07/04/2006, 11h29
  5. Structures et tableaux, la galère
    Par kameha dans le forum C
    Réponses: 10
    Dernier message: 05/01/2006, 17h31

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