[C++] La honte : 39 erreurs :(

Résolu/Fermé
Utilisateur anonyme - 23 janv. 2008 à 23:36
 Utilisateur anonyme - 2 févr. 2008 à 22:00
Bonsoir,

J'ai écrit un programme et le compilateur m'a fait sortir ............ 39 erreurs :(

Je joints mes fichiers :

produit.h :
#include<iostream>
#include<string>

class produit
{
private :
	int Ref;
	char* Libelle[20];
	int Quantite;
	float prix;

public:
	void ChangerQuantite(int);
	void ChangerPrix(float);
	Produit operator+ (Produit);
	Produit(int, char*);
	Produit();
	friend void Affiche(Produit);

};


produit.cpp :
#include"produit.h"
#include<string>
#include<iostream>

void Produit::ChangerQuantite(int q)
{
	Quantite = q;
}
void Produit::ChangerPrix(float p)
{
	Prix = p;
}
Produit Produit::operator+(Produit p)
{
	Produit r;
	r.Ref=Ref;
	strcat(Libelle," ");
	strcat(Libelle,p.Libelle);
	strcpy(r.Libelle,Libelle);
	r.Quantite=Quantite+p.Quantite;
	r.Prix=((Quantite*Prix)+(p.Quantite*p.Prix)/(Quantite+p.Quantite));
	return r;
}
Produit::Produit(int r, char* l)
{
	Ref=r;
	strcpy(Libelle,l);
}
Produit::Produit()
{
	Ref=0;
	strcpy(Libelle,"inconnue");
}
void Affiche(Produit p)
{
	cout<<"\n le produit ref : "<<p.Ref<<"libelle : "<<p.Libelle<<endl;
	cout<<"\n la quantite : "<<p.Quantite<<"prix unitaire"<<p.Prix<<"DT"<<endl;
};


et ma main.cpp :
#include<iostream>
#include"produit.h"

int main()
{
	Produit p1(120, "verre V225"), p2(125, "verre V220"), p3;
	p1.ChangerPrix(0.125f);
	p1.ChangerQuantite(12000);
	p2.ChangerPrix(0.100f);
	p2.ChangerQuantite(5000);
	Affiche(p1);
	Affiche(p2);
	p3=p1+p2;
	Affiche(p3);
	return 0;
}


Merci de votre temps :)


15 réponses

Bonjour

Pour commencer, respecte la casse : Produit ou produit, Prix ou prix, ce n'est pas la même chose en C++
0
Utilisateur anonyme
24 janv. 2008 à 00:14
J'ai corrigé le premier produit dans class Produit et au niveau des attributs privés de la classe j'ai corrigé aussi float Prix;

J'ai ajouté le using namespace std dans le fichier produit.cpp

Il me reste que 5 erreurs :

error C2664: 'strcpy' : cannot convert parameter 1 from 'char *[20]' to 'char *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

J'ai un problème avec le header string ?

Merci.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
24 janv. 2008 à 00:20
Salut,

Alors pour commencer, comme Le Père l'a dit, respecte la casse. Usuellement, une classe et structure commencent par une majuscule, et une fonction et une variable en minuscule.

Ensuite, dans ton fichier header, tu as écrit char *libelle[20]; un simple char libelle[20]; fera l'affaire.
Et enfin dans ton fichier produit.cpp, tu as oublié de spécifier using namespace std; après les #include

Voilà ;)
0
Utilisateur anonyme
24 janv. 2008 à 10:31
Merci fiddy,
J'ai bien corrigé ces fautes.
:)
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
24 janv. 2008 à 10:12
Salut.
Ce que dit fiddy n'est pas obligatoire, tu peux très bien aire ce que tu veux avec les majuscules et minuscules. Si c'est un programme perso, le principale c'est que toi tu t'y retrouve
char *libelle[20]; est un tableau de 20 char*; donc de type char**. Ce qui est impossible à convertir en char* simple.
Petite question, est tu sur que dans l'opérateur d'affectectation par défaut copie la chaine Libelle et ne copie pas juste le pointeur ??
deuxièmement, dans ton affectation p3=p1+p2, as tu remarquer que tu modifiait p1 ?
Pour la somme, il vaut mieux utiliser la fonction : Produit operator+(const Produit&,const Produit&) qui sera préalablement déclarer friend dans la class.
Je pense que si tu ne veux pas avoir d'erreur de segmentation, tu devrais augmenter la taille de Libelle, à au moins 25 je pense. pour rappel, "ABC" est un const char[4] car "ABC" est en vrai la sucésion des caractères 'A' 'B' 'C' et '\0'.
0
Utilisateur anonyme
24 janv. 2008 à 11:00
Bonjour,

Tu as raison concernant le char *Libelle[20], je l'ai corrigé sur mon programme.
Pour l'opérateur d'affectation par défaut, je pense (je ne suis pas sûre) qu'il pourrait copier la chaine Libelle.
J'ai modifié le p1 car je n'ai pas d'autres alternatives, l'opérateur + a pour rôle de fusionner deux produits en un seul ayant la référence du premier, le libellé concaténation de deux libellés, la quantité en stock, la somme des deux quantités et le prix pondéré par les deux quantités.
J'ai augmenté aussi la taille de Libelle à 25 comme tu as indiqué.

Merci et bonne journée :)
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > Utilisateur anonyme
24 janv. 2008 à 12:52
Pour faire une fusion comme tu dit, je te propose plutôt de faire ce qi suit :
Produit Produit::operator+(const Produit& p)
{
	strcat(Libelle," ");
	strcat(Libelle,p.Libelle);
	Prix=((Quantite*Prix)+(p.Quantite*p.Prix)/(Quantite+p.Quantite));
	Quantite+=p.Quantite;
	return *this;
}
ça sera plus propre. Pour fusionner p1 avec p2, il suffir alors de faire p1+p2;. à l'issue de cette commande, p1 sera la fusion de p1 et p2, et p2 restera inchanger.
Ce que tu fait est un peu batard, et il risque d'y avoir des problèmes de mémoire.
0
Bonjour Char Snipeur

char *libelle[20]; est un tableau de 20 char*; donc de type char**.
Non, non et non, un char * libelle[20] n'est pas un char **. D'une manière générale, un tableau n'est pas un pointeur. Ce n'est pas avec toi que j'en ai déjà débattu ?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > le père
24 janv. 2008 à 17:00
on en a pas débattu.
En admettant qu'un tableau ne soit pas un pointeur, en tout cas, leur comportement est identique et les différences sont subtiles.
Il est vrai que dans la version 2.xx de gcc char c[a],d[a]; c=d; recopiait la valeur de 'd' dans 'c' sans égalité de pointeur, mais depuis c'est faut, faire c=d; reviens à faire une égalité de pointeur.
0
le père > Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
24 janv. 2008 à 17:33
on en a pas débattu.
En admettant qu'un tableau ne soit pas un pointeur, en tout cas, leur comportement est identique et les différences sont subtiles.

Si ce n'était pas toi, ça confirme que l'erreur est courante, ce qui te donne un peu raison ;-)
Mais le comportement N'EST PAS identique et la différence n'a rien de subtil :
char ** truc1; // truc1 est une variable simple (sur une machine 32 bits, elle occupe 4 octets en mémoire)
char *truc2[100]; // truc2 est un tableau (il occupe 400 octets en mémoire)
tu peux très bien faire :
truc1=truc2;
mais essaye donc truc2=truc1; pour voir...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
24 janv. 2008 à 11:30
Pour l'opérateur d'affectation par défaut, je pense (je ne suis pas sûre) qu'il pourrait copier la chaine Libelle.
Il vaudrait mieux en être sur ! Car sinon, tu risque d'avoir des soucis, en fait, p3=r (de la fonction operator+)et delete r;
Donc, si tu copie juste le pointeur : attention à la mémoire.
Tu as une alternative à la façon dont tu fait le somme : comme je te l'ai dit dans mon message précedent.
0
tu sais que selon les class il faut construire les contructeurs d'opérateur (>,<,+,=,==,++,--,etc etc)
0
hi
si tu me fai plaisir
tu peu bien me parler de ce pgm
c koi le sujet et c koi lapplication k tu veu implementer
bein je vai essayer de corriger les erreurs
mai je veu juste te dire k le bon developpeur et celui ki fai plus d'erreur car un jour
il va apprendre plein dastuce ...
c pa de la honte ...
parfoi les compliteurs a cause d'une simple ; peuven genere 29 erreur!
a+
je vai afficher la correction sur ce site ok?
a+
0
Bonjour

si tu déclare : int const *i;
tu peux modifier *i, mais pas i.(*i=3 : ok; i=\Ox3245 : erreur)


Sauf que c'est exactement le contraire *i=3 interdit , i= &truc autorisé.
Je suppose que tu voulais dire int * const i;. Dans ce cas, on peut modifier *i mais pas i. D'ailleurs cette définition ne sert à rien si elle ne comporte pas d'initialisation comme int * const i = &truc;, puisqu'on ne peut plus modifier la valeur de i après. Sans initialisation, le compilateur refusera la définition (sauf si c'est un extern).

je pense que ça peut aider les gens à comprendre
ça aide surtout à entretenir la confusion. Tu connais bien ce forum, tu dois savoir que 90% des questions sur les pointeurs en C viennent de gens qui confondent les pointeurs et les tableaux.
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
25 janv. 2008 à 09:15
En effet, erreur de ma pare, je me suis embrouiller avec les positions de const.
Bref, j'ai du mal à voir la différence entre un int*const et un tableau.

Par contre, moi je dirai que beaucoup de questions viennent de gens qui séparent trop bien pointeur de tableaux, et qui du coup font du char*C[] ou font des passage dans le même genre (fonction(C[N]) ). voir un tableau comme un pointeur aide beaucoup à la compréhension, une fois arriver plus avant dans la comprehension, on peut faire la distinction en considérant en effet leurs différences.
0
j'ai du mal à voir la différence entre un int*const et un tableau
Tu n'as pas l'air d'un débutant, et pourtant tu illustres tout à fait la confusion dont je parle.
Un int * const, c'est un pointeur, ça occupe (par exemple, ça dépend des machines) 4 octets en mémoire. Il contient l'adresse de quelque chose (un entier ici). On peut modifier le quelque chose en question, mais, à cause du const, on ne peut pas modifier l'adresse.

Un tableau est une zone mémoire d'autant plus grande que la dimension du tableau est grande.

Je suppose que l'origine de la confusion est la bizarrerie de la syntaxe du C qui autorise à utiliser un pointeur avec des [ ] comme si c'était un tableau d'une part, et d'autre part qui considère que le nom d'un tableau est une adresse et donc utilisable dans de nombreux contextes où un pointeur est utilisable aussi.
Personnellement, je suis passé par le pascal avant, où ce genre de mélange n'est même pas envisageable. Quand je suis passé au C, je n'ai jamais eu de problème de pointeur, il a fallu que je rencontre des gens qui avaient commencé par le C pour voir que des notions pourtant complètement distinctes pouvaient donner un affreux mélange dans la tête des gens.
En résumé, je suis tout à fait convaincu que c'est totalement anti-pédagogique de mêler des notions qui n'ont aucun rapport.
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
25 janv. 2008 à 10:32
Ok, je comprends mieux.
Il faudrai regarder le code assembleur, mais un tableaux occupe bien une place en mémoire, donc se lie à une adresse mémoire donc la conversion est logique.
Par contre, ce que je comprend de ce que tu dit, c''est que si int t[]; et int * const p; alors &t n'a pas de sens, car t n'est pas une variable mais que &p oui, car p est une variable qui doit don être stocker.Autrement dit, un appel à t fait implicitement &t[0] (on regarde l'adresse du premier élément) alors que l'appel à p lit juste l'adresse mémoire contenue dans la variable.
Moi aussi j'ai débuté par le Pascal, mais j'évitait un max les pointeurs (d'ailleurs c'est toujours le cas). Et j'évite un maximum de tripatouiller la mémoire, je préfère le C++ en fait et la STL qui s'en charge ma place.
De plus, je viens de re-jeter un coup d'oeil sur le livre de Stroutup (créateur du C++) qui en effet distinct bien pointeur et tableau, sans s'étendre sur le sujet, mais qui dit aussi :
"En C++, pointeurs et tableaux sont étroitements liés..."
Ne donnant pas explicitement les différence, il a entretenu l'illusion.
0
Il faudrai regarder le code assembleur, mais un tableaux occupe bien une place en mémoire, donc se lie à une adresse mémoire donc la conversion est logique.
Toutes le variables occupent une place en mémoire. Ce que je trouve parfaitement incohérent dans la syntaxe du C c'est par exemple :
int x;
int y[10];
fonction1(x);
fonction2(y);

Alors que les deux appels s'écrivent de la même manière
dans l'appel à fonction1, c'est la valeur de la variable qui est passée
dans l'appel à fonction2, c'est l'adresse qui est passée, ce qui fait croire aux gens que y est un pointeur.

&t n'a pas de sens
Si, cela a un sens. C'est aussi une adresse. Numériquement la même que &t[0], mais avec un type différent (adresse de tableau)
0
Utilisateur anonyme
26 janv. 2008 à 19:48
Bonsoir et merci de vos amples explications :)


Pour la somme, il vaut mieux utiliser la fonction : Produit operator+(const Produit&,const Produit&) qui sera préalablement déclarer friend dans la class.
--> je ne sais pas comment utiliser la fonction friend, même dans le cours, j'ai pas compris vraiment à quoi ça sert ni comment l'utiliser.

Par contre, quand j'ai modifié la définition de la fonction operator+ comme me l'a montré Char Snipeur, mon programme tourne normalement.

Bonne soirée :)

0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
28 janv. 2008 à 08:40
Salut.
Je ne t'ai pas explique comment fonctionnait friend, car tu l'utilise toi même pour Affiche().
déclarer un fonction "friend" dans une class autorise cette fonction à accéder aux membres privés de la classe.
Dans la class, il suffit de mettre friend suivi du prototype de la fonction.
0
Utilisateur anonyme
2 févr. 2008 à 22:00
Salut,

Pour la fonction amie, c'est la prof qui nous a "ordonnés" de la mettre, à l'époque je ne voiyais pas à quoi elle sert, mais j'ai compris maintenant son interêt.

Merci de votre aide, le père et toi.

:)
0