j'aimerais avoir vos différents aides sur le programme ci-joint.
en effet, je voudrais afficher l'historique des différents débits et crédits effectués au niveau de la fonction annuler(), et si possible optimiser mon code.
#include <iostream>
#include <stdlib.h>
#include<stdio.h>
#include <string>
using namespace std;
string name;
string p;
string const pwd("1234");
int const taille(6);
string t1[taille]={"toto","tata","tutu","titi","tete","tyty"};
int t2[taille]={100,100,100,100,100,100};
bool isConnected=false;
int operation;
int montant;
int solde;
int sauv;
void crediter(int montant);
void debiter(int montant);
void annuler();
void crediter(int montant){
t2[sauv]+= montant;
cout<<"votre nouveau solde est de:"<<t2[sauv]<<endl;
}
void debiter(int montant){
if((t2[sauv]- montant)<100){
cout<<"solde insuffisant"<<endl;
}
else{
t2[sauv]-= montant;
cout<<"votre nouveau solde est de:"<<t2[sauv]<<endl;
}
}
void annuler(){
cout<<"---------votre satisfaction c'est notre priorite, aurevoir!!!------------"<<endl;
exit(isConnected);
}
int main(){
//fonction login
do{
cout<<"entrez votre nom"<<endl;
cin>>name;
cout<<"saisir le mot de passe"<<endl;
cin>>p;
if(p==pwd){
for(int i=0; i<taille; i++){
if(t1[i]==name);{
isConnected=true;
} sauv=i;
}
}
}while(isConnected==false);
while(isConnected=true){
cout<<"------------------bienvenue dans notre banque--------"<<" "<<name<<endl;
cout<<"------------------choisir une opération-------------------------"<<endl;
cout<<"1:crediter"<<endl;
cout<<"2:debiter"<<endl;
cout<<"3:annuler"<<endl;
cin>>operation;
if(operation == 1){
cout<<"entrer le montant"<<endl;
cin>>montant;
crediter(montant);
}else{
if(operation==2){
cout<<"entrer le montant"<<endl;
cin>>montant;
debiter(montant);
}else{
if(operation==3){
annuler();
}else{
cout<<"---------bien vouloir choisir une opération existante------------"<<endl;
}
}
}
}
}
- Au lieu de plusieurs if tu peux faire un switch(){ case: ...} ;
- Tu n'es pas obligée d'avoir tes variables accessibles globalement.
- Opte pour les std::array<int> / std::vector au lieu des typename[]
. Et pour l'historique, crée une fonction qui va enregistrer chaque opération dans un tableau par exemple(std::vector plutôt même). Et affiche le contenu de la structure pour avoir l'historique.
Ca serait chouette d'avoir vraiment une classe CompteBancaire je trouve
- Au lieu de plusieurs if tu peux faire un switch(){ case: ...} ;
- Tu n'es pas obligée d'avoir tes variables accessibles globalement.
- Opte pour les std::array<int> / std::vector au lieu des typename[]
. Et pour l'historique, crée une fonction qui va enregistrer chaque opération dans un tableau par exemple(std::vector plutôt même). Et affiche le contenu de la structure pour avoir l'historique.
Ca serait chouette d'avoir vraiment une classe CompteBancaire je trouve
- Edité par Asmitta il y a 38 minutes
j'ai lu certains pdf sur "vector", mais je ne comprends pas toujours pas comment l'utiliser dans le code.
concernant la fonction qui va enregistrer chaque opération dans un tableau, je n'arrive pas à la faire
il faut noté que je suis au niveau débutant, merci Asmitta
std::vector est assez simple je trouve. Bon voila un exemple de code:
std::vector<string> historique; // Meilleur dans une classeCompteBancaire, mais ici c'est une variable globale
void sauvegarder_operation(string type_operation = "credit", double montant = 0.0); // Dans crediter() ou debiter() tu devras appeler aussi cette fonction
void voir_historique();
void sauvegarder_operation(string type_operation, double montant) {
string text{""};
switch(type_operation) {
case "credit":
text += "Vous avez credite votre compte de " + montant;
break;
case "debit":
text += ...;
...
}
historique.push_back(text);
}
void voir_historique(){
for ( auto elt : historique){
std::cout<<elt<<std::endl; // ou "\n"
}
}
C'est assez moche je trouve mais suivant ton travail on pourrait avoir le code ci-dessus pour l'historique
31: historique.push_back("vous avez crediter votre compte de :" +std::basic_string(montant)+ "et votre nouveau solde est:"
+std::basic_string(t2[sauv]));
41: historique.push_back("vous avez debiter votre compte de :" +std::basic_string(montant)+ "et votre nouveau solde est:" +std::basic_string(t2[sauv]));
96: annuler(std::vector<std::string> historique);
30-->31
40-->41
95-->96
- Edité par MelissaNgouleu 14 avril 2022 à 15:27:57
Il y a tellement à dire sur ce petit code que je ne sais presque pas par quoi commencer. Enfin, si: il faut toujours commencer par les bases. C'est donc ce que je vais faire
1- Ton code est plus proche d'un code C auquel tu as ajouté quelques fonctionnalités issues du C++ que d'un code C++
La meilleure preuve en est que tu inclus des en-tête qui sont typiques du C, comme <stdlib.h> ou <stdio.h>.
Ce n'est pas vraiment une bonne idée de travailler comme cela. Car même si C++ assume parfaitement sa descendance venue du C, il faut bien comprendre que ce sont deux langage totalement différents!
La relation qui existe entre le C et le C++ est -- toutes proportions gardées -- la même que celle qui relie le Latin de Jules Cesar au Français.
Tu dois donc choisir: ou bien tu décide de faire du C et tu vires tout ce qui est issu du C++ (et tu demande à la modération de déplacer cette discussion), ou bien tu décide de faire du C++, et, dans ce cas, il faut vraiment essayer de se limiter aux possibilités issues exclusivement du C++.
Car de nombreuses "bonnes pratiques" du C sont en réalité de véritables calamités en C++, à cause des particularités propres aux deux langages.
2- les variables globales C'EST MAL
Parce qu'elles sont accessibles littéralement depuis partout, ce qui fait que tu risques d'en modifier à peu près n'importe quand, et, surtout, à des moments où leur valeur n'avait aucune raison d'être modifiée.
Plus tes variables ont une portée limitée (comprend: plus tes variables ne seront accessibles qu'à des (aussi) petits morceaux de code (que possible), plus tu pourra avoir confiance dans le fait que leur valeur n'a pas été changée de manière totalement impromptue.
Et plus tu pourras limiter l'utilisation de tes variables à l'usage auquel tu les a destinées à la base.
Tu utilises beaucoup trop de variables globales dans ton code. Il faut vraiment corriger cet état de fait.
3- Pourquoi limiter le nombre d'utilisateurs à six?
Que va-t-il se passer si "Albert" demande à pouvoir utiliser l'application lui aussi?
Dans l'idéal, tu ne devrais pas avoir à modifier ton code (et donc à recompiler l'ensemble de ton programme) uniquement pour avoir la possibilité de rajouter un utilisateur.
4- La directive using namespace std; est une vieillerie qu'il ne faudrait plus utiliser depuis plus de 20 ans
Ce n'est pas catastrophique si tu ne t'intéresse au C++ que pour apprendre à programmer, mais la possibilité d'avoir recours à cette directive a été prévue pour une raison bien particulière à un moment bien particulier de l'histoire du langage (voir ==>ICI<== les explications longues)
A l'heure actuelle, ces raisons n'ont plus vraiment de sens, et l'utilisation de cette directive apporte plus de problèmes que de solutions.
Tu serais donc sans doute bien inspiré de t'habituer dés le départ à ne pas l'utiliser
5- Une remarque sur la déclaration des fonctions
Ce n'est clairement qu'un détail, mais une fonction ne doit réellement être déclarée (ex: <code >void crediter(int montant);) que si elle est destinée à être utilisée avant que l'on en ait donné la définition (ou si la définition se trouve dans une autre unité de compilation).
L'idée de base, c'est que le compilateur va lire ton code du début à la fin, exactement de la même manière que tu lirais un bon roman:
Quand il est à la ligne 13, il sait bien sur tout ce qui s'est passé depuis la ligne 1, par contre, il n'a aucune idée de ce qui va se passer à la ligne 20.
Evidemment, si tu fais référence, la ligne 13, à quelque chose dont le compilateur ne prend connaissance qu'à la ligne 20, il ne va pas être content, et il va donc s'arrêter de travaillé après t'avoir envoyer un message du genre de "je ne connais pas cette chose".
La déclaration d'une fonction (ou d'une variable) est donc là pour dire au compilateur que
il existe "quelque chose" (une variable, une fonction, un type de donnée même) qui porte tel nom et qui a "telles caractéristiques"
Dans le cas d'une fonction, ce serait donc "il existe une fonction portant tel nom, qui renvoie (s'il échoit) tel type de donnée et qui prend tels et tels types de données en paramètre" afin que le compilateur sache que la fonction existe, qu'il peut y faire appel à condition de lui transmettre "tel et tel type de données" comme paramètre, et qu'il peut s'attendre à récupérer tel type de donnée une fois que la fonction a fini son travail
Tes différentes fonctions ne sont appelées que dans main. Mais leur définition arrive avant celle de la fonction main. Leur déclaration est donc inutile, car, lorsque le compilateur croisera l'appel de ces fonctions dans main, il aura aussi déjà croisé les définitions de ces fonctions, et qu'il saura donc qu'elles existent.
Par contre, si tu décidais de prendre la définition de tes fonction et de la déplacer après la définition de main (et donc des moments où ces fonction sont appelées), alors la déclaration de ces fonctions deviendrait indispensable, car autrement, le compilateur ne saurait absolument rien des fonctions -- dont il ignorerait jusqu'à l'existence -- au moment où il croiserait les appels dans la fonction main.
L'idée est toujours la même: il y a ce que le compilateur sait à un moment donné et ce qu'il doit savoir au même moment.
S'il ne sait pas absolument tout ce qu'il doit savoir à un moment donné, il va pas être content. Par contre, il n'est pas forcément nécessaire (cela pose d'ailleurs parfois quelques problèmes) de lui faire savoir ce qu'il peut encore se permettre d'ignorer au même moment
6- un principe de base : le SRP (Single Responsability Principle ou principe de la responsabilité unique)
Ce principe nous dit que "toute notion" (qu'il s'agisse d'un type de donnée, d'une donnée ou d'une fonction) ne devrait s'occuper que d'une et une seule chose pour que nous puissions nous assurer qu'elle le fasse correctement.
Or, toutes tes fonctions:
effectuent une action en rapport avec leur nom
affichent un message en rapport avec ce qui a été fait
Ca fait deux responsabilités, cela en fait donc une de trop.
C'est encore pire pour ta fonction main, car elle s'occupe
du "login" de l'utilisateur entre la ligne 50 et la ligne 63
de l'affichage d'un menu de base (lignes 69 à 73)
de la récupération du choix de l'utilisateur (ligne 74)
de l'affichage d'un autre message (deux fois: lignes 77 et 82)
de la récupération d'un montant (deux fois : lignes 78 et 83)
Cela fait cinq responsabilité, cela en fait quatre de trop
Plus un code est présent à de nombreux endroit, plus il va poser problème lorsque les circonstances feront qu'il doit être modifié/corrigé parce que l'on peut être sur que l'on oubliera "forcément" un endroit où il aurait du être modifié.
C'est de l'ordre du détail ici, mais tes lignes 77 et 78 sont exactement les mêmes que tes lignes 82 et 83. Il y a donc ... répétition.
Ne pourrait on pas faire de manière à ce que ce soit les mêmes lignes de codes qui soient utilisées dans les deux cas?
8- tu sembles avoir codé "à la rache".
L'impression générale que donne ton code est d'avoir été écrit "sans la moindre préparation", sans même que tu aies réfléchis plus loin que "tiens, ce serait pas mal si je m'amusais à faire une application de gestion bancaire":
Tu as eu l'idée, tu as "sauté" sur ton clavier, et tu as écrit ton code "comme il te venait", en fonction des besoins qui te venaient à l'esprit et / ou des problèmes que tu rencontrait.
C'est le meilleur moyen de perdre énormément de temps lors du développement et, surtout, d'arriver tôt ou tard à un point où le projet devient tellement embrouillé qu'il est carrément impossible de continuer à le faire évoluer.
J'ai bien conscience que tu ne vas sans doute pas maintenir ce projet particulier pendant des mois, qu'il s'agit d'un "projet jetable" dont le seul objectif est de te permettre de t'améliorer.
C'est la raison pour laquelle je ne vais pas me lancer dans une diatribe par laquelle je reprendrait la conception "depuis le début". Du moins, tant que tu ne m'en aura pas fait la demande.
Cependant, ce genre de projet est typiquement l'occasion rêvée d'améliorer sa compréhension du besoin de conception, car il reste simple, même si on peut le complexifier "à l'envi".
Peut être serais tu bien inspiré de profiter de cette occasion
- Edité par koala01 15 avril 2022 à 4:32:00
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
JadeSalina merci pour ton attention et ta sincérité. je n'en souviendrais
mais avant d'être de meilleurs programmeurs aujourd'hui, ils ont certainement commencés au niveau 0
Oui bien sûr il faut bien commencer quelque part il n’y a pas de mal. Tant qu’on continue à pratiquer et qu’on a toujours une poussée vers l’avant, il n’y a pas de raison de ne pas devenir très bon, les experts de demain sont actuellement tous de grands débutants voire même ne sont pas encore nés
On peut le dire autrement. On réfléchit sur papier (ou sur l'écran) plutôt que seulement dans sa tête. Il faut parfois écrire en français plutôt qu'en code ce qu'on veut faire comme si on l'expliquait à une autre personne. Ça rend les idées plus claires et ça nous amène vers du pseudo-code qui deviendra éventuellement du vrai code.
Le Tout est souvent plus grand que la somme de ses parties.
- on perd du temps à réfléchir "dans le vide" et pas sur du concret qu'on a sous les yeux
- on se ferme des portes en s'enfermant prématurément dans un design particulier sans avoir eu l'occasion d'en explorer d'autres
- on perd du temps à remettre en place toute la structure en place quand on se rend compte qu'elle ne fait pas ce qu'on veut ou que de nouveaux requirements arrivent du client
- Edité par JadeSalina il y a environ 1 heure
Je suis pas vraiment d'accord, les inconvénients que tu sembles soulignées ne surviennent qu'avec une mauvaise analyse. Avoir le plan a l'avance est vraiment meilleur pour moi, surtout si l'analyse a été très bien faite. Y'a des projets qu'on ne peut pas bien gérer en rajoutant des parties a chaque fois pendant le développement faut toujours une bonne base et un bon plan surtout dans un travail de groupe par exemple.
Les architectures "correctes" sont celles qui permettent la flexibilité, et on ne perd pas de temps car elles ont déjà été éprouvées et outillées.
Mais encore faut-il que le projet en question soit adapté. Bien sur que dans les cas simples ou qu'on a déjà fait 36 fois, ça ne fait que accélérer d'utiliser des design patterns existants, mais moi je parle de ce qu'il vaut mieux faire quand ce qu'on fait est intrinsèquement difficile et/ou qu'on ne l'a jamais fait et donc qu'on ne sait pas à quoi la solution pourrait ressembler, et ce n'est pas moi qui le dit, mais des personnes qui sont des grands noms de l'informatique
Bin moi, je ne suis pas un grand nom de l'Informatique, je suis très très con, c'est pour ça que je fais des choses simples, je repompe le travail des autres en attendant de mieux comprendre les spécificités du problème et de me prendre les difficultés dans la gueule à ce moment là.
Mais au moins, j'ai pas à résoudre des problèmes que des personnes ben plus éclairées et expérimentées ont défrichés.
Je ne travaille pas pour la NASA, contrairement à toi visiblement @JadeSalina et tes problèmes "originaux".
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Petit problème banquaire ou prochain vol habité vers Sirius? Moi non plus je ne suis pas un génie. Je réinvente de petites roues, mais pas les grandes ...
Le Tout est souvent plus grand que la somme de ses parties.
Mais encore faut-il que le projet en question soit adapté. Bien sur que dans les cas simples ou qu'on a déjà fait 36 fois, ça ne fait que accélérer d'utiliser des design patterns existants, mais moi je parle de ce qu'il vaut mieux faire quand ce qu'on fait est intrinsèquement difficile et/ou qu'on ne l'a jamais fait et donc qu'on ne sait pas à quoi la solution pourrait ressembler, et ce n'est pas moi qui le dit, mais des personnes qui sont des grands noms de l'informatique
Et nous, on te parle simplement de l'apprentissage...
Les données globales ne sont pas vraiment un problème ici. Le fait d'utiliser des tableaux (C style) de taille fixes ou la directive using namespace std; non plus. Et il en va de même pour chacun des points que j'ai cités dans mon intervention précédente, nous sommes bien d'accord.
Seulement, quand tu as un débutant devant toi, si tu ne lui dit pas ce qu'il peut "mal faire" ou ce qu'il "pourrait mieux faire", comment veux tu qu'il apprenne à faire "le mieux possible" ?
Il faut, justement, profiter de petits projets comme celui-ci, de projets qui ne présentent pas énormément de difficultés, sur lesquels il n'y a pas de deadline stressante parce qu'on sait d'avance qu'elle ne pourra pas être respectée, pour essayer d'inculquer "un maximum de choses utiles" à la personne qui apprend.
Et plus ce projet nous permettra d'aborder les différents aspects (de conception, d'organisation et de présentation du code, d'utilisation des outils offerts par le langage, de respect des conventions, ou que sais-je), plus le projet sera "bénéfique" à celui qui apprend.
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
C'est assez moche je trouve mais suivant ton travail on pourrait avoir le code ci-dessus pour l'historique
ecris
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.