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 :

[Conseils/Aide] Structure de mon premier programme


Sujet :

C++

  1. #1
    Invité2
    Invité(e)
    Par défaut [Conseils/Aide] Structure de mon premier programme
    Bonjour à toutes et tous,

    Bonjour, je débute en C++, alors je vais tenté de resté très très très imble et sâchez que je prend toute vos réponses en considération. Attention : mon niveau est déconcertant

    Voilà comme premier projet, je veut faire un colorateur syntaxique, oui je sais, c'est gros, c'est dûr et pas la peine de réinventer la roue
    Bon, mon colorateur syntaxique devra faire, à peu prêt comme pygments pour les connaisseurs, colorer en html... il devra être modulable et performant...

    J'ai déjà fait un bout de code, mais, pour pas trop me ridiculiser, dès le début, voilà comment il est constuit :
    • Plus que trois fichier : main.cpp, fonctions.h et langages.h
    • Plus que deux namespace : KolorEngine, KolorEngineLangage
    • Plus de variable globale


    Descriptions des fichiers :

    langages.h :
    • Namepace : KolorEngineLangage (qui contient les fonctions de parsage)
    • Description du fichier : contient les prototypes des fonctions de parsage

    fonctions.h :
    • Namespace : KolorEngine (qui contient les fonctions uselles du programme)
    • Description du fichier : contient les fonctions uselles du programme


    main.cpp :
    • Namespace : KolorEngine, KolorEngineLangage, std
    • Description du fichier : fichier contenant tout le code du programme
    • Nombre de parties : 4


    Description des parties :
    • Partie 1 : Les includes, contient toutes les inclusions nécessaire au bon fonctionnement du programme (mes deux header, <map>, <boost/regex.hpp>, <boost/function.hpp>, <iostream>
    • Partie 2 : La fonction main, appel les fonctions, traite la demande et renvois le code
    • Partie 3 : Définie les fonctions de l'espace nom KolorEngine
    • Partie 4 : Définie les fonctions de l'espace nom KolorEngineLangage


    Fonction de KolorEngine :
    • implode, qui rassemble tout les arguments (sauf les index 0 et 1) pour pouvoir les passer aux REGEX.
    • Appel_fonction, qui contient le liste des langages et qui me permet de les appeler par leurs noms


    Voilà, armez vous de patience, je tente d'apprendre, dites moi en quoi mon approche est mauvaise, qu'elle points sont à revoir (et je sais qu'il y en a).

    Par avance merci de votre aide
    Dernière modification par Invité2 ; 15/08/2008 à 12h23.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par katagoto Voir le message
    Voilà, armez vous de patience, je tente d'apprendre, dites moi en quoi mon approche est mauvaise, qu'elle points sont à revoir (et je sais qu'il y en a).
    Ben écoute, dans le principe ça m'a l'air pas mal du tout mais difficile de t'en dire plus sans avoir lu ta première ligne de code ... Le seul conseil que je pourrais te donner est de ne pas multiplier les namespaces. Au vu de ton approche, il semble que ce que tu essaies de regrouper sous des espaces de nommages devrait précisément former des classes.

  3. #3
    Invité2
    Invité(e)
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Ben écoute, dans le principe ça m'a l'air pas mal du tout mais difficile de t'en dire plus sans avoir lu ta première ligne de code ... Le seul conseil que je pourrais te donner est de ne pas multiplier les namespaces. Au vu de ton approche, il semble que ce que tu essaies de regrouper sous des espaces de nommages devrait précisément former des classes.
    Déjà, merci de votre aide, je vais dors et déjà transformer mes namespace en en classe, si vous avez d'autres suggestions

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je vois au moins 2 optiques assez différentes pour ce genre de programme.

    Soit le travail peut se faire uniquement au niveau lexical (chaque fois que je vois un "int", je le met en bleu), et dans ce cas, ton programme peut ressembler à une suite de rechercher/remplacer à base d'expressions régulières.

    Soit le travail est un peu plus subtil (ce nom là, parmi ceux déclarés par l'utilisateur, c'est une variable, je le met en rouge, ah, non, c'est une fonction, je le met en vert), et dans ce cas là, il me semble que le centre de ton programme est une architecture permettant de représenter le code source, avec en entrée un parseur générant cette architecture à partir du code, et e sortie quelquechose qui génère ton format de sortie en fonction de cette architecture.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par katagoto Voir le message
    Déjà, merci de votre aide, je vais dors et déjà transformer mes namespace en en classe, si vous avez d'autres suggestions
    Attention, encore une fois, ce n'est qu'une impression, eue en lisant l'esquisse de ton projet. Sans en voir plus, je ne peux pas te dire si c'est bien ou mal.

    Par contre, d'une manière générale, il ne faut pas multiplier les namespaces. Ils sont une réponse au problème de la pollution de l'espace des noms, jusque là unique C, quand deux fonctions ou classes distinctes risquent d'être nommées de la même façon. Donc, si tu te mets à polluer l'espace de nommage des espaces de nommages ...

    Globalement, les namespaces sont utilisés lorsqu'il y a risque de conflit entre le nom d'une de tes entités avec celui d'une entité déjà existante dans une autre projet ou une autre bibliothèque. Par extension, ça va être utile si tu veux précisément réimplémenter toute une bibliothèque à ta propre sauce.

    Ça veut dire que l'on n'utilise en général qu'un seul namespace au sein d'un même (grand) projet, et qu'on ne le fait que si ce qui est écrit est destiné à être utilisé par d'autres projets sous forme de bibliothèque. Si c'est pour compiler directement une application terminale, c'est sans intérêt.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Soit le travail peut se faire uniquement au niveau lexical [...] Soit le travail est un peu plus subtil
    Et, en gros, on réécrit Lex & Yacc :-)

  7. #7
    Invité2
    Invité(e)
    Par défaut
    Merci de vos réponses et de l'intéret que vous portez à ce topic,

    Moi ce que je voudrait faire c'est, par exemple, dès qu'il tombe sur un type, hop il lui met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <div class="type_de_base">int</div>
    Pour des types de base (int, long, double, char) ou nom (std::string, std::map), des opérateurs (+, -, ++, --, ~, ., etc.) et biensûr qu'il sâche reconnaitre les variables et les fonctions, les mots clefs, bref, pas une cherche très très poussé...

    Quoi que, par la suite, j'aimerais y intégrer un auto-indenteur...

    Bref, j'ai tout placé en class, avec un static, ais-je fait comme il fallait ?

    Juste une question : le prototype de main est bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main(int argc, char* argv[])
    Et est-il bien interdit ou du moins déconseillé de le déclarer ?

    Je vous dêmmande ça, car un amis vient de me mettre le doute

    Par avance merci de votre aide et de votre patience...

    PS : si vous le voullez et que vous avez de la morphine je peux vous montrer mon travail...

    Edit : J'avais pas vu tes posts Obsidian, mais pour l'instant j'ai tout compris ^^"
    Dernière modification par Invité2 ; 13/08/2008 à 17h46. Motif: Voir en bas du message

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    Pour répondre à ta dernière question : en effet, on ne déclare jamais le prototype de main, on implémente la fonction. Voilà tout.

    Sinon le main à deux formes possible.

    Avec deux arguments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main(int argc, char* argv[]) // char** argv fait pareil
    Sans arguments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main(void) // le void est facultatif
    Et c'est tout.

    void main n'est absolument pas valide.

  9. #9
    Invité2
    Invité(e)
    Par défaut
    Merci beaucoup pour votre aide,

    Merci de cette confirmation Mikechaos,

    J'attends de voir, si mon architecture est bonne par rapport au travaille que mon application devra réalisé, et que mes modifications sont bien celles qui devait être réalisées, et je ous achève ^^

    Par avance merci de vos réponse et de votre aide précieuse

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par katagoto Voir le message
    Et est-il bien interdit ou du moins déconseillé de le déclarer ?
    On ne déclare pas main() au préalable parce que cette fonction a presque toujours le même prototype, n'est utilisé par aucune instance de niveau supérieur et n'a pas vocation a être exporté au sein d'un programme tiers (dans une lib).

    Cependant, c'est complètement anodin de le déclarer quand même. D'ailleurs, moi, je ne m'en prive pas quand je stacke tous mes prototypes en tête de fichier. Ça permet de ne pas en oublier, et évite les erreurs.

  11. #11
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    main est une fonction bien spéciale...

    Citation Envoyé par La norme, 3.6.1/2
    An implementation shall not predefine the main function. This function shall not be overloaded.
    De même
    Citation Envoyé par La norme, 3.6.1/3
    The function main shall not be used (3.2) within a program.

  12. #12
    Invité2
    Invité(e)
    Par défaut
    Bon, puisque vous n'avez pas l'air de désapprouver mon travail, le voilà, et, non, j'en suis pas fière, c'est juste une ébauche :
    changelog

    Voilà, soyez franc et courageux ^^"

    Par avance merci de vos réponses et de votre aide pécieuse

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    main est une fonction bien spéciale...

    An implementation shall not predefine the main function. This function shall not be overloaded.

    The function main shall not be used (3.2) within a program.
    C'est pas incompatible : il est écrit qu'une implémentation ne doit pas prédéfinir la fonction main() et que, de la même façon, elle ne doit pas être surchargée. C'est normal. On n'imaginerait pas une fonction main() incluse dans une bibliothèque par exemple.

    La norme affirme également que la fonction main() ne doit pas être utilisée à l'intérieur d'un programme. C'est plus discutable. Les programmes récursifs sont légions. Et faire un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main (void) { return depart(); }
    exprès pour ne pas établir la récursion sur main elle-même ne me paraît pas plus propre.


    Mais dans tout les cas, il n'y a rien qui interdit dans ces règles de prédéclarer main() dans un prototype en tête de fichier ...

  14. #14
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je ne vois effectivement pas de point qui interdise l'utilisateur de déclarer cette fonction avant de la définir. Mais avec le second point, je n'en vois absolument aucun intérêt.

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je ne vois effectivement pas de point qui interdise l'utilisateur de déclarer cette fonction avant de la définir. Mais avec le second point, je n'en vois absolument aucun intérêt.
    Certes.

    Les seuls points où çela pourrait être intéressant sont le cas où une sous-fonction veut connaître l'adresse du point d'entrée, et celui où on aurait besoin de connaître le prototype (void ou argc/argv). Pour le reste ...

  16. #16
    Invité2
    Invité(e)
    Par défaut
    Vous dormez donc jamais ? ^^
    J'aurait deux questions :
    1. Ma structure correspond-t-elle à ce que j'envisage de faire ?
    2. Mon programme contient-t-il des erreurs ?

  17. #17
    Invité2
    Invité(e)
    Par défaut
    Aucune remarque sur mon programme ? Aucune optimasation/amélioration à apporter ?

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    Premièrement, je tiens à dire que je n'ai pas une connaissance poussé du langage C++, ni une structure irréprochable.
    Mes remarques sont donc à prendre avec un esprit critique.

    Alors, comme disait Obsidian :

    Attention, encore une fois, ce n'est qu'une impression, eue en lisant l'esquisse de ton projet. Sans en voir plus, je ne peux pas te dire si c'est bien ou mal.
    Or dans ton cas, ni l'espace de nommage ni les classes ne sont nécessaires, selon l'implémentation que tu utilises.

    En effet, avoir un espace de nommage n'est utile que dans certains cas (entre autre, lorsque plusieurs fonctions, au sein de projet, risque d'avoir le même nom et d'être utilisé dans les mêmes fichiers).
    À date, ça ne semble pas du tout être ton cas.

    Ensuite, créer des classes pour y mettre des fonctions statiques... c'est complètement inutile.
    Je ne sais pas si tu connais bien le paradigme OO et si tu sais comment bien l'implanter en C++. Si ce n'est pas le cas, je te conseil de te plonger plus profondément dans celui-ci avant de te lancer dans un tel projet.
    Cela t'aidera fortement dans ta structure, entre autre.
    Si c'est le cas, je te suggère alors de revoir un peu ton code pour te permettre de le structurer en classe.
    Bien sûr, de ce que tu as de fais jusqu'ici, il est difficile de dire ce qui pourrait former une classe. Mais si tu as, avant de coder, tout mis sur papier (ou si tu sais exactement dans quel direction va ton code), il devrait être facile assez facile d'établir un squelette de ces classes.

    Sinon, en général, le code m'a l'air bien.

    Bonne continuation!

  19. #19
    Invité2
    Invité(e)
    Par défaut
    Citation Envoyé par Mikechaos Voir le message
    En effet, avoir un espace de nommage n'est utile que dans certains cas (entre autre, lorsque plusieurs fonctions, au sein de projet, risque d'avoir le même nom et d'être utilisé dans les mêmes fichiers).
    À date, ça ne semble pas du tout être ton cas.
    Déjà, merci de l'intéret porté à mon travail,

    Ensuite, je me suis servis des namespace pour "diviser" mon travail en plusieurs parties, la partie noyau (détection du langage, appel de la fonction) et la partie des différentes fonctions de parsage, je dois donc revenir aux namespace ^^

    J'avais pris le soins de faire un changelog => ZIP

    voilà mon travail...

    J'attends vos remarques

  20. #20
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par katagoto Voir le message
    J'attends vos remarques
    (Mon message est passé à la trappe ! Mauvaise manip' sans doute).
    Donc, en vrac :

    - Tes namespaces ne servent vraiment à rien si tes fonctions ne dépassent pas les frontières de ton application (mais bon, ils ne sont pas nocifs non plus).

    - L'un des avantages du C++ est de pouvoir continuer à écrire des fonctions quand ça se justifie plutôt que d'avoir à systématiquement instancier un objet pour le principe. Ok. Cela dit, si tu débutes et que comptes faire une bibliothèque, tu devrais dès le départ concevoir ton projet avec des classes. Enfin, ce n'est que mon avis.

    - Il y a des choses que tu peux factoriser dans ton code :
    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            for(int i = 2 ; i < nombre ; ++i)
            {
                if(i == 2)
                {
                    chaine.push_back(*tableau[i]);
                }
                else
                {
                    chaine.push_back(fixe);
                    chaine.push_back(*tableau[i]);
                }
            }
    se simplifie en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            for(int i = 2 ; i < nombre ; ++i)
            {
                if(i > 2) chaine.push_back(fixe);
     
                chaine.push_back(*tableau[i]);
            }
    Enfin, dans cette même fonction, tu définis directement dans le code une boucle commençant à 2 pour traiter argc et argv. Très bien, mais ce n'est pas l'objet en soi de ta fonction, et la liste de mots à concaténer pourrait venir d'une autre source.

    À la place, fais plutôt une boucle qui concatène tous les mots et appelle-là, toi, avec un argument de moins :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::string code = KolorEngine::implode(' ', argv+1, argc-1);

Discussions similaires

  1. Demande d'aide pour mon premier programme
    Par ne2sbeal dans le forum Windows Forms
    Réponses: 6
    Dernier message: 21/01/2009, 21h53
  2. Demande d'aide pour débuter mon premier algorithme
    Par Pierre.g dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 23/08/2006, 10h04
  3. [JDOM] Mon premier programme java-xml
    Par adilo dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 12/07/2006, 13h12
  4. [Language] Aide sur mon premier programme Java?
    Par hash2zo dans le forum Langage
    Réponses: 15
    Dernier message: 27/09/2005, 19h26
  5. [Débutant] Mon premier programme: rien ne va...
    Par vincent0 dans le forum OpenGL
    Réponses: 10
    Dernier message: 02/08/2005, 13h59

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