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

Langage C++ Discussion :

Sous-programmes en C++


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Etudiant en génie mécanique
    Inscrit en
    Mars 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Etudiant en génie mécanique

    Informations forums :
    Inscription : Mars 2011
    Messages : 146
    Par défaut Sous-programmes en C++
    Salut!

    Depuis quelques temps, j'ai pu écrire plusieurs programmes simples en C++, et j'essaie de mettre des nouveautés à chaque fois.

    Quand mes programmes sont devenus plus conséquents (500 lignes en gros), on m'a un peu reproché de tout faire dans le Main.
    J'ai demandé ce que je pouvais faire d'autre, et on m'a expliqué qu'il fallait faire des fonctions.
    Mais en lisant la théorie sur les fonctions, j'ai pas trop compris comment c'était censé sortir du Main..?
    Autre chose: pour que les variables soient liées entre un sous-programme et les autres, est-ce que je dois utiliser une subtilité?

    Merci pour vos indications =D

  2. #2
    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,

    En fait, le principe est tout bête: pour passer de la fonction (parce qu'on parle de fonction, voir de routine et non de sous programme ) main à une autre fonction, il "suffit" d'appeler cette fonction.

    une fois que la fonction appelée aura terminé son boulot, on retournera automatiquement dans la fonction appelante pour reprendre "là où on l'avait laissée".

    Un exemple tout bête, pour te permettre de comprendre:
    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
     
    #include <iostream>
    /* une fonction "toute bête" qui avise juste l'utilisateur qu'on arrive dedans */
    void foo()
    {
       std::cout<<"bienvenue dans foo()"<<std::endl;
    }
    /* et la fonction principale qui l'appelle */
    int main()
    {
        std::cout<<"nous sommes au debut de main()"<<std::endl;
        foo();
        std::cout<<"nous somme de retour dans main()"<<std::endl;
        return 0;
    }
    A l'exécution, tu verra apparaitre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    nous sommes au debut de main()
    bienvenue dans foo()
    nous sommes de retour dans main()
    Il faut cependant savoir que le compilateur travaille de la même manière que toi quand tu lis un livre:
    Tout comme, la première fois que tu lis le livre, tu ne sais pas ce qui va se passer à la page 10 quand tu n'en es qu'à la page 8, le compilateur ne sait pas ce qu'il y a à la ligne 10 lorsqu'il se trouve à la ligne 9.

    Et s'il ne connait pas "quelque chose", il n'est pas content et t'éjecte sans vergogne.

    Ainsi, alors que les deux fonctions existent, si on en inverse simplement l'ordre sous la forme 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
    #include <iostream>
     
    /* et la fonction principale qui l'appelle */
    int main()
    {
        std::cout<<"nous sommes au debut de main()"<<std::endl;
        foo();
        std::cout<<"nous somme de retour dans main()"<<std::endl;
        return 0;
    }/* une fonction "toute bête" qui avise juste l'utilisateur qu'on arrive dedans */
    void foo()
    {
       std::cout<<"bienvenue dans foo()"<<std::endl;
    }
    le compilateur refusera de compiler le programme sous prétexte "qu'il ne connait pas foo" quand il est dans main

    Mais il "suffit" de lui dire, avant d'entrer dans main, que la fonction foo existe, et il sera content . On parle alors d'une déclaration de fonction.

    Ainsi, le code
    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
     
    #include <iostream>
    /* déclare la fonction foo() pour que le compilateur sache qu'elle existe */
    void foo();
    /* définition de la fonction main */
    int main()
    {
        std::cout<<"nous sommes au debut de main()"<<std::endl;
        foo();
        std::cout<<"nous somme de retour dans main()"<<std::endl;
        return 0;
    }
    /* et enfin la définition de la fonction foo */
    void foo()
    {
       std::cout<<"bienvenue dans foo()"<<std::endl;
    }
    sera parfaitement accepté par le compilateur.

    Afin de savoir de quoi l'on parle, on utilise le terme "déclaration d'une fonction" (ou toute utilisation adéquate du verbe "déclarer", bien sur) lorsqu'on ne fait qu'indiquer la signature (*) de la fonction, mais on parle de définition (ou toute utilisation adéquate du verbe "définir", bien sur) ou encore d'implémentation (ou tout autre utilisation du verbe ... implémenter) lorsque l'on fournit le corps de la fonction (comprends : lorsque l'on indique ce que doit faire la dite fonction )

    Toute définition (ou implémentation) de fonction vaut d'office déclaration pour "le code qui suit", mais tu auras de gros problèmes si tout ce qui existe au sujet d'une fonction, c'est sa déclaration: tout le processus de compilation se passera correctement jusqu'au moment où... il s'agira de faire coincider l'appel d'une fonction avec l'adresse mémoire à laquelle elle se trouve, et là, tu sera confronté à une erreur de "référence indéfinie"

    (*) On utilise régulièrement plusieurs termes lorsque l'on parle des fonction:
    • Le prototype, qui est composé du nom de la fonction et des arguments éventuels qu'elle accepte
    • La signature, qui est composée du prototype de la fonction et du type de donnée qu'elle renvoie
    • le corps de la fonction qui est composé de toutes les instructions qu'elle doit effectuer.

    Pour déclarer une fonction, la signature de celle-ci suffit
    Pour implémenter une fonction, il faut que la signature de celle-ci soit suivi de son corps placé entre accolades "{" et "}"
    De manière générale, la signature sera proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <type de retour> <nom de la fonction> ( <liste des arguments qu'elle accepte, séparés par une virgule>)
    Pour définition d'un argument de fonction se fait exactement comme la déclaration d'une variable, c'est à dire que nous pourrions modifier le code précédant sous la forme 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
    #include <iostream>
    /* on déclare une fonction (qui ne renvoie rien) foo() qui prend un entier 
     * comme argument
     */
    void foo(int valeur);
    /* que l'on peut alors appeler depuis "n'importe où" */
    int main()
    {
     
        std::cout<<"nous sommes au debut de main()"<<std::endl;
        for(int i=1;i<=10;++i)
        {
            foo(i);
            std::cout<<"nous somme de retour dans main()"<<std::endl;
        }
        std::cout<<"merci et au revoir"<<std::endl;
    }
    void foo(int valeur)
    {
        /* les argument passés à une fonction s'utilisent exactement comme s'il
         * s'agissait d'une variable classique au sein de la fonction
         */
        std::cout<<"bienvenue dans foo()"<<std::endl;
        std::cout<<"c'est la "<<valeur<<" ieme fois qu'on passe dedans"<<std::endl;
    }
    Après, il y a quelques particularités au sujet du passage de paramètres aux fonctions, mais, si tu as déjà compris ceci, tu devrais arriver à comprendre la suite dans n'importe quel tutoriel
    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

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    ^Attention, tu as oublié le point-virgule sur la première déclaration anticipée.
    Quant à ton dernier bloc de code, il a un commentaire non-terminé.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    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
    Citation Envoyé par Médinoc Voir le message
    ^Attention, tu as oublié le point-virgule sur la première déclaration anticipée.
    Quant à ton dernier bloc de code, il a un commentaire non-terminé.
    Bien vu!

    Corrigé, merci
    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

  5. #5
    Membre très actif
    Homme Profil pro
    Etudiant en génie mécanique
    Inscrit en
    Mars 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Etudiant en génie mécanique

    Informations forums :
    Inscription : Mars 2011
    Messages : 146
    Par défaut
    Youpi, c'est tout nice!
    En fait, on écrit tout dans le même fichier, mais pas tout dans le main...
    C'est cool.

  6. #6
    Membre très actif
    Homme Profil pro
    Etudiant en génie mécanique
    Inscrit en
    Mars 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Etudiant en génie mécanique

    Informations forums :
    Inscription : Mars 2011
    Messages : 146
    Par défaut
    Génial!
    Avec les pototypes c'est parfait! =D

    Maintenant, un petit détail: est-ce qu'on peut créer une fonction dont le type soit une structure?
    (Je crois savoir que les structures sont des types personnalisés, en gros, mais est-ce que ça marche?)

    Ou plus simple: comment fait-on pour que toutes les fonctions puissent utiliser (et modifier) un groupe de variables déclarées (une seuls fois) dans le main?

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

Discussions similaires

  1. sous programme et parametre
    Par Krispy dans le forum Langage
    Réponses: 2
    Dernier message: 10/04/2006, 17h55
  2. Envoi d'informations dans un sous programme
    Par Tanguy Sarela dans le forum Linux
    Réponses: 3
    Dernier message: 22/12/2005, 16h57
  3. Réponses: 31
    Dernier message: 30/08/2005, 13h10
  4. Réponses: 2
    Dernier message: 04/06/2004, 10h36
  5. [langage] les sous programmes
    Par giverny dans le forum Langage
    Réponses: 6
    Dernier message: 21/07/2003, 19h24

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