Structure, erreur de compilation [Résolu]

Signaler
Messages postés
14
Date d'inscription
samedi 15 octobre 2011
Statut
Membre
Dernière intervention
25 janvier 2013
-
Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
-
Bonjour a tous,
Je commence depuis peu la programmation avec c++. J'avance doucement, jusqu'à ce qu'un exemple donné dans un livre ne fonctionne pas. Mes connaissances étant très ... limitées, il m'est donc impossible de comprendre et résoudre les erreurs des autres.
Voici un code donné en exemple sur les structures qui ne compile pas :
#include 
#include <cstdlib>
using namespace std;
#include<cmath>

struct point
{
       double x, y;
};

void saisir_point(point &p)
{
    cout << "Tapez l'abscisse du point : "; cin >> p.x;
    cout << "Tapez l'ordonnée du point : "; cin >> p.y;
}

void afficher_point(point p)
{
    cout << "Abscisse du point : " << p.x << endl;
    cout << "Ordonnée du point : " << p.y << endl;
}

double distance(point a, point b)
{
    double dx,dy;
    dx = a.x - b.x;
    dy = a.y - b.y;
    return  sqrt((dx*dx) + (dy*dy));
}

void milieu(point a, point b, point &m)
{
    m.x = (a.x + b.x) /2;
    m.y = (a.y + b.y) /2;
}


int main()
{
    point X,Y,Z;
    double d;

    cout << "SAISIE DE X" << endl;
    saisir_point(X);

    cout << "SAISIE DE Y" << endl;
    saisir_point(Y);

    d=distance (X,Y);
    cout << "La distance de X à Y est : " << d << endl;

    milieu(X,Y,Z);
    cout << "AFFICHAGE DU POINT Z" << endl;
    afficher_point(Z);

    system("pause");
    return 0;
}


J'utilise plusieurs compilateur comme codeblocs, dev ... Ce dernier génére l'erreur suivant moins nombreuses que codeblocks, mais similaires sur certain type d'erreurs :
[b]In instantiation of `std::iterator_traits':
49 C:\Documents and Settings\Dolph\Bureau\Struct.cpp instantiated from here
129 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_iterator_base_types.h no type named `iterator_category' in `struct point'
130 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_iterator_base_types.h no type named `value_type' in `struct point'
131 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_iterator_base_types.h no type named `difference_type' in `struct point'
132 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_iterator_base_types.h no type named `pointer' in `struct point'
133 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_iterator_base_types.h no type named `reference' in `struct point' /b

voila, si vous pouvez m'aider à comprendre et me permettre ainsi d'avancer. Merci par avance

5 réponses

Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
114
Bonjour.

Nombreux sont les ouvrages de C++, et la grande majorité est de qualité déplorable ! Je peux te conseiller de bons livres par messages personnels (pas de publicité sur le forum).

Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace. Ici, comme la classe "point" (std::point) existe déjà dans la STL, il y a conflit. Tu peux l'éviter facilement en prenant de bonnes habitudes.

Quelques conseils:
- Seul un nom de classe ou de structure porte une majuscule.
- Les attributs sont généralement préfixé par "_".
- On déclare une variable au moment de l'utiliser, pas besoin de déclarer la variable en haut de la fonction en avance.
- Si tu as plusieurs std::cout à faire, à la suite, on peut les chaîner avec un seul std::cout (voir "afficherPoint" ci-dessous).

Je te propose une version plus propre (imparfaite car je ne veux pas introduire de notions que tu n'aurais pas encore vu):

#include 
#include <cstdlib>
#include <cmath>

struct Point
{
  double _x;
  double _y;
};

void saisirPoint(Point& p)
{
  std::cout << "Tapez l'abscisse du point: ";
  std::cin >> p._x;
  std::cout << "Tapez l'ordonnee du point: ";
  std::cin >> p._y;
}

void afficherPoint(Point p)
{
  std::cout << "Abscisse du point : " << p._x << std::endl
            << "Ordonnee du point : " << p._y << std::endl;
}

double distance(Point a, Point b)
{
  double dx = a._x - b._x;
  double dy = a._y - b._y;
  return std::sqrt((dx * dx) + (dy * dy));
}

void milieu(Point a, Point b, Point& m)
{
  m._x = (a._x + b._x) / 2;
  m._y = (a._y + b._y) / 2;
}

int main()
{
  Point x, y, z;
  std::cout << "Saisie de x" << std::endl;;
  saisirPoint(x);

  std::cout << "Saisie de y" << std::endl;;
  saisirPoint(y);

  double d = distance(x, y);
  std::cout << "La distance de X a Y est: " << d << std::endl;

  milieu(x, y, z);
  std::cout << "Affichage du point z" << std::endl;
  afficherPoint(z);

  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
114
et ensuite Fract p, p contient les variable déclarées dans la structure ? C'est bien ca ?

Créer une structure, c'est créer un type personnalisé. Il ne contient pas 2 variables, il *est* la composition de ces deux variables. Néanmoins, un type Frac, bien qu'étant identique à deux doubles, n'est pas considéré comme étant du même type. De même, deux type struct de nature identiques, mais de nom différents, seront aussi considéré comme étant de type différent.
Le souci dans ton exemple, c'est que tes fonctions retourne des "double" alors que tu veux retourner un type "Frac". Tu crées d'ailleurs une variable temporaire "c", dont la logique est tout à fait correcte, et au moment de retourner les valeurs, au lieu de retourner ce type "Frac", tu essaies de retourner deux doubles d'un coup. On ne peut en C++ retourner qu'une seule valeur d'un type donné (c'est bien là que les types personnalisés deviennent utiles, puisque tu peux, grâce à eux, retourner plusieurs valeurs indirectement).

Voici une modification de ton code:
#include 

struct Fract
{
  double _num;
  double _denom;
};

void saisieFract(Fract& fract)
{
  std::cout << "Donnez la valeur de nominateur de la fraction: ";
  std::cin >> fract._num;
  std::cout << "Donnez la valeur de denominateur de la fraction: ";
  std::cin >> fract._denom;
  std::cout << std::endl;
}

void affichageFract(Fract fract)
{
  std::cout << "Votre fraction finale est "
    << fract._num << "/" << fract._denom << std::endl;
}

Fract somFract(Fract a, Fract b)
{
  Fract c;
  c._num = a._num * b._denom + b._num * a._denom;
  c._denom = a._denom * b._denom;
  return c;
}

Fract diffFract(Fract a, Fract b)
{
  Fract c;
  c._num = (a._num * b._denom - b._num * a._denom);
  c._denom = a._denom * b._denom;
  return c;
}

Fract proFract(Fract a, Fract b)
{
  Fract c;
  c._num = a._num * b._num;
  c._denom = a._denom * b._denom;
  return c;
}

Fract rappFract(Fract a, Fract b)
{
  Fract c;
  c._num = a._num * b._denom;
  c._denom = a._denom * b._num;
  return c;
}

int main()
{
  Fract a;
  Fract b;

  std::cout << "Saisie de la fraction F1 " << std::endl;
  saisieFract(a);

  std::cout << "Saisie de la fraction F2 " << std::endl;
  saisieFract(b);

  Fract plus = somFract(a, b);
  Fract moins = diffFract(a, b);
  Fract fois = proFract(a, b);
  Fract sur = rappFract(a, b);

  std::cout << "Votre fraction addition vaut = " << std::endl;
  affichageFract(plus);
  std::cout << " FIN " << std::endl;

  std::cout<< "Votre fraction difference vaut = " << std::endl;
  affichageFract(moins);
  std::cout << " FIN " << std::endl;

  std::cout << "votre fraction produit vaut = " << std::endl;
  affichageFract(fois);
  std::cout << " FIN "<< std::endl;

  std::cout << "Votre fraction rapport vaut = " << std::endl;
  affichageFract(sur);
  std::cout << " FIN " << std::endl;

  return 0;
}


A noter qu'il y a encore des axes d'amélioration sur la "forme" du code, mais je ne te les mets pas afin de ne pas te noyer sous de trop nombreuses, nouvelles notions.

________________________________________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
14
Date d'inscription
samedi 15 octobre 2011
Statut
Membre
Dernière intervention
25 janvier 2013

Merci pour ta réponse. Je n'ai pas encore essayé ta solution, mais je m'y mettrai ce soir après le boulot.
J'avais lu qu'il n'était pas recommandé d'utiliser namespace std; , mais pour le moment et vu mon niveau, je m'en sert car c'est plus commode. Je sais, je prends de mauvaise habitude !
Mes ouvrages sont édités par Dunod ou Eyrolles. Mais pour ce code, j'ai utilisé la source sur Wikipédia ! Merci si tu as d'autres références à me donnner, mais tu me diras la démarche pour les "messages personnels".
Messages postés
14
Date d'inscription
samedi 15 octobre 2011
Statut
Membre
Dernière intervention
25 janvier 2013

Ca fonctionne, merci pour tes conseils
Messages postés
14
Date d'inscription
samedi 15 octobre 2011
Statut
Membre
Dernière intervention
25 janvier 2013

Bonsoir,
Je viens avec un nouveau problème de d'erreur de compilation :
Je pesais avoir compris (il me semble que oui !), mais un nouveau problème survient.
Lorsqu'on déclare une structure : ex. struc Fract{};
et ensuite Fract p, p contient les variable déclarées dans la structure ? C'est bien ca ?
Plutot qu'un long discours ou je ne suis pas sur de m'exprimer clairement voici donc le code qui me pose quelques soucis :
# include 
# include <cstdlib>


struct Fract
{
       double _num,_denom;
};

void saisie_Fract(Fract &F)
{
    std::cout << "donnez la valeur de nominateur de la Fraction "
      << std::endl;
    std::cin >> F._num;
    std::cout << "donnez la valeur de denominateur de la fraction "
      << std::endl;
    std::cin >> F._denom;
    std::cout << std::endl;
}

void affichage_Fract(Fract F)
{
    std::cout << " votre Fraction finale  est "<< F._num<< "/"
      << F._denom << std::endl
              << std::endl;
}

double som_Fract(Fract A, Fract B)
{
    Fract C;
    C._num = A._num * B._denom + B._num * A._denom;
    C._denom = A._denom * B._denom;
    return(C._num, C._denom);
}

double diff_Fract(Fract A, Fract B)
{
    Fract C;
    C._num = (A._num * B._denom - B._num * A._denom);
    C._denom = A._denom * B._denom;
    return(C._num, C._denom);
}

double pro_Fract(Fract A, Fract B)
{
    Fract C;
    C._num = A._num * B._num;
    C._denom = A._denom * B._denom;
    return(C._num, C._denom);
}

double rapp_Fract(Fract A, Fract B)
{
    Fract C;
    C._num = A._num * B._denom;
    C._denom = A._denom * B._num;
    return(C._num, C._denom);
}

int main()
{
    Fract a,b;
   
    
    std::cout << "Saisie de la Fraction F1 " << std::endl;
    	saisie_Fract(a);
            
    std::cout << "Saisie de la Fraction F2 " << std::endl;
    	saisie_Fract(b);
    
    Fract plus = som_Fract(a,b);
    Fract moins = diff_Fract(a,b);
    Fract fois = pro_Fract(a,b);
    Fract sur = rapp_Fract(a,b);
    
    std::cout << "Votre Fraction addition vaut " << " = " << std::endl;
    	affichage_Fract(plus);
    std::cout << " FIN " << std::endl;
    
    std::cout<< "Votre Fraction difference vaut " << " = " << std::endl;
    	affichage_Fract(moins);
    std::cout << " FIN " << std::endl;
    
    std::cout << "votre Fraction produit vaut " <<" = " << std::endl;
    	affichage_Fract(fois);
    std::cout << " FIN "<< std::endl;
    
    std::cout << "Votre Fraction rapport vaut " << " = " << std::endl;
    	affichage_Fract(sur);
    std::cout << " FIN " << std::endl;
    
    system("PAUSE");
    return 0;
}

Merci d'avance pour vos réponses et vos conseils.