• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

Ce cours existe en livre papier.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 14/02/2024

Découpez votre programme en fonctions

Nous allons apprendre à organiser notre code en fonctions. Il s'agit en fait de découper nos programmes en petits morceaux. Chaque petit morceau sera ce qu'on appelle une fonction.

Une fonction exécute des actions et renvoie un résultat. C'est un morceau de code qui sert à faire quelque chose de précis. On dit qu'une fonction possède une entrée et une sortie.

Fonction avec une entrée et une sortie
Fonction avec une entrée et une sortie

Créez une fonction

Voilà comment on représente une fonction, schématiquement (c'est un modèle à connaître !) :

type nomFonction(parametres)
{
    // Insérez vos instructions ici
}

type  (correspond à la sortie) : c'est le type de la fonction.

Si la fonction renvoie un nombre décimal, vous mettrez sûrement double  ; si elle renvoie un entier, vous mettrez int ou long par exemple. Mais il est aussi possible de créer des fonctions qui ne renvoient rien, elles seront alors de type void  ("vide", en français).

nomFonction  : c'est le nom de votre fonction.

Vous pouvez appeler votre fonction comme vous voulez, du moment que vous respectez les mêmes règles que pour les variables (pas d'accents, pas d'espaces, etc.).

parametres  (correspond à l'entrée) : ce sont les paramètres de la fonction.

Ils sont entre parenthèses. Ce sont en fait des valeurs avec lesquelles la fonction va travailler.

Maintenant que vous savez ça, voyons un exemple pratique ! Disons que :

  • notre fonction triple reçoit un nombre entier de type  int  ;

  • et qu'elle renvoie un nombre entier également de type int.

La fonction triple reçoit en entrée le nombre 10. Elle retourne donc en sortie le nombre 30.
exemple de fonction triple

Elle calcule le triple du nombre qu'on lui donne :

int triple(int nombre)
{
    int resultat = 0;

    resultat = 3 * nombre;  // On multiplie le nombre fourni par 3
    return resultat;       // On retourne la variable resultat qui vaut le triple de nombre
}

La fonction est de type int. Elle doit donc renvoyer une valeur de type int.

Entre les parenthèses, vous avez les variables que la fonction reçoit. Ici, notre fonction triple reçoit une variable de type int appelée nombre.

Ce code signifie pour la fonction :

« Arrête-toi là et renvoie le nombre resultat».

Mais est-ce la façon la plus courte d'écrire notre fonction triple  ?

Non, on peut faire tout cela en une ligne :

int triple(int nombre)
{
    return 3 * nombre;
}

Cette fonction fait exactement la même chose que la fonction de tout à l'heure, elle est juste plus rapide à écrire.

Affectez (ou non) des paramètres à une fonction

Vous pouvez envoyer autant de paramètres que vous le voulez. Vous pouvez aussi n'envoyer aucun paramètre à la fonction, mais ça se fait plus rarement.

Affectez plusieurs paramètres à une fonction

Notre fonction triple contient un paramètre, mais il est possible de créer des fonctions acceptant plusieurs paramètres, comme par exemple une fonction addition qui additionne deux nombres a et b  :

int addition(int a, int b)
{
    return a + b;
}

N'affectez aucun paramètre à fonction

Certaines fonctions, plus rares, ne prennent aucun paramètre en entrée. Ces fonctions feront généralement toujours la même chose. En effet, si elles n'ont pas de nombres sur lesquels travailler, vos fonctions serviront juste à effectuer certaines actions, comme afficher du texte à l'écran. Et encore, ce sera forcément toujours le même texte, puisque la fonction ne reçoit aucun paramètre susceptible de modifier son comportement !

Imaginons une fonction bonjour qui affiche juste "Bonjour" à l'écran :

void bonjour()
{
    printf("Bonjour");
}

Je n'ai rien mis entre parenthèses car la fonction ne prend aucun paramètre. De plus, j'ai utilisé le type void dont je vous ai parlé plus haut.

En effet, ma fonction n'a pas non plus de return : elle ne retourne rien.

Appelez une fonction

Nous allons reprendre notre fonction triple  (décidément, je l'aime bien) pour calculer le triple d'un nombre.

Pour le moment, écrivez la fonction triple AVANT la fonction main  (si vous la placez après, ça ne marchera pas, je vous expliquerai pourquoi par la suite).

Testez donc ce code pour comprendre :

#include <stdio.h>
#include <stdlib.h>

int triple(int nombre)
{
    return 3 * nombre;
}    

int main(int argc, char *argv[])
{
    int nombreEntre = 0, nombreTriple = 0;
    
    printf("Entrez un nombre... ");
    scanf("%d", &nombreEntre);
    
    nombreTriple = triple(nombreEntre);
    printf("Le triple de ce nombre est %d\n", nombreTriple);
    
    return 0;
}

Notre programme commence par la fonction main :

  1. On demande à l'utilisateur d'entrer un nombre.

  2. On envoie ce nombre qu'il a entré à la fonction triple  .

  3. Et on récupère le résultat dans la variable nombreTriple  .

Regardez en particulier cette ligne, c'est la plus intéressante car c'est l'appel de la fonction :

nombreTriple = triple(nombreEntre);

Entre parenthèses, on envoie à la fonction triple une variable en entrée (c'est le nombre sur lequel elle va travailler).

Cette fonction renvoie une valeur qu'on récupère dans la variable nombreTriple  .

Dans cette ligne de code, on ordonne donc à l'ordinateur :

« Demande à la fonction triple de me calculer le triple de nombreEntre  ,

et stocke le résultat dans la variable nombreTriple  ».

Dans la vidéo suivante, nous allons reprendre le même exemple, et voir les différentes étapes pour créer la fonction  triple  et l’appeler dans le  main  :

Comprenez le sens de lecture d'une fonction

Le code ci-dessous est commenté de manière un peu particulière. C'est pour vous montrer dans quel ordre le code est "lu". Commencez donc par lire la ligne commentée 1, puis 2, puis 3 (vous avez compris 🤣) :

#include <stdio.h>
#include <stdlib.h>

int triple(int nombre) // 6
{
    return 3 * nombre; // 7
}    

int main(int argc, char *argv[]) // 1
{
    int nombreEntre = 0, nombreTriple = 0; // 2
    
    printf("Entrez un nombre... "); // 3
    scanf("%d", &nombreEntre); // 4
    
    nombreTriple = triple(nombreEntre); // 5
    printf("Le triple de ce nombre est %d\n", nombreTriple); // 8
    
    return 0; // 9
}

Voici ce qui se passe, ligne par ligne.

  1. Le programme commence par la fonction main.

  2. Il lit les instructions dans la fonction, une par une, dans l'ordre.

  3. Il lit l'instruction suivante et fait ce qui est demandé (printf).

  4. De même, il lit l'instruction et fait ce qui est demandé (scanf).

  5. Il lit l'instruction… Ah ! On appelle la fonction triple, on doit donc sauter à la ligne de la fonction triple plus haut.

  6. On saute à la fonction triple et on récupère un paramètre (nombre).

  7. On fait des calculs sur le nombre et on termine la fonction :return signifie la fin de la fonction, et permet d'indiquer le résultat à renvoyer.

  8. On retourne dans main pour prendre l'instruction suivante.

  9. Un return : la fonction  main  se termine, et donc le programme est terminé.

Si vous avez compris dans quel ordre l'ordinateur lit les instructions, vous avez déjà compris le principal.

Voici un exemple d'utilisation du programme :

Entrez un nombre... 10
Le triple de ce nombre est 30

Regardez bien ceci, c'est le même code mais il y a un changement au niveau du dernier printf. De plus, on n'a pas déclaré de variable nombreTriple car on ne s'en sert plus :

#include <stdio.h>
#include <stdlib.h>

int triple(int nombre)
{
    return 3 * nombre;
}    

int main(int argc, char *argv[])
{
    int nombreEntre = 0;
    
    printf("Entrez un nombre... ");
    scanf("%d", &nombreEntre);

    // Le résultat de la fonction est directement envoyé au printf et n'est pas stocké dans une variable
    printf("Le triple de ce nombre est %d\n", triple(nombreEntre));
     
    return 0;
}

triple(nombreEntre)  est directement envoyé au printf.

Que fait l'ordinateur quand il tombe sur cette ligne ?

Il voit que la ligne commence par printf, il va donc appeler la fonction printf.

Il envoie à la fonction printf tous les paramètres qu'on lui donne :

  1. Le premier paramètre est le texte à afficher.

  2. Et le second est un nombre.

Votre ordinateur voit qu'il doit d'abord appeler la fonction triple pour envoyer ce nombre à la fonction printf :

  1. Il appelle triple.

  2. Il effectue les calculs de triple.

  3. Et une fois qu'il a le résultat, il l'envoie directement dans la fonction printf !

C'est un peu une imbrication de fonctions. Et le plus fin dans tout ça, c'est qu'une fonction peut en appeler une autre à son tour : notre fonction triple pourrait appeler une autre fonction, qui elle-même appellerait une autre fonction, etc. C'est ça le principe de la programmation en C : tout est combiné, comme dans un jeu de LEGO.

Intégrez le principe en pratique avec ces exemples

Je vais donc maintenant vous montrer plusieurs exemples d'utilisation de fonctions, pour que vous ayez une idée de leur intérêt. Je vais m'efforcer de faire des cas différents à chaque fois, pour que vous puissiez avoir des exemples de tous les types de fonctions qui peuvent exister.

Je ne vous apprendrai rien de nouveau, mais ce sera l'occasion de voir des exemples pratiques. Si vous avez déjà compris tout ce que j'ai expliqué avant, c'est très bien, et normalement aucun des exemples qui vont suivre ne devrait vous surprendre.

Analysez une fonction qui prend 1 paramètre

Intéresserons-nous à une fonction qui ne renvoie rien (pas de sortie). Imaginons une fonction qui copie des lignes, comme les punitions que l'on avait lorsqu'on était petit :

void punition(int nombreDeLignes)
{
    int i;
    
    for (i = 0 ; i < nombreDeLignes ; i++)
    {
        printf("Je ne dois pas copier sur mon voisin\n");
    }    
}    

int main(int argc, char *argv[])
{    
    punition(10);
    
    return 0;
}

C'est une fonction qui affiche le même message à l'écran autant de fois qu'on lui demande. Elle prend un paramètre en entrée : le nombre de fois où il faut afficher la punition.

Résultat :

Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin
Je ne dois pas copier sur mon voisin

On a ici affaire à une fonction qui ne renvoie aucune valeur. Cette fonction se contente juste d'effectuer des actions (ici, elle affiche des messages à l'écran).

Il aurait été bien plus intéressant de créer une fonction punition qui s'adapte à n'importe quelle sanction. On lui aurait envoyé deux paramètres : le texte à répéter, et le nombre de fois qu'il doit être répété.

Analysez une fonction qui prend 2 paramètres en entrée

Imaginons une fonction qui calcule l'aire d'un rectangle. L'aire d'un rectangle est facile à calculer :largeur * hauteur.
Notre fonction nommée aireRectangle va prendre deux paramètres : la largeur et la hauteur pour renvoyer l'aire :

double aireRectangle(double largeur, double hauteur)
{
    return largeur * hauteur;
}    

int main(int argc, char *argv[])
{    
    printf("Rectangle de largeur 5 et hauteur 10. Aire = %f\n", aireRectangle(5, 10));
    printf("Rectangle de largeur 2.5 et hauteur 3.5. Aire = %f\n", aireRectangle(2.5, 3.5));
    printf("Rectangle de largeur 4.2 et hauteur 9.7. Aire = %f\n", aireRectangle(4.2, 9.7));
      
    return 0;
}
Rectangle de largeur 5 et hauteur 10. Aire = 50.000000
Rectangle de largeur 2.5 et hauteur 3.5. Aire = 8.750000
Rectangle de largeur 4.2 et hauteur 9.7. Aire = 40.740000

Pourrait-on afficher directement la largeur, la hauteur et l'aire dans la fonction ?

Bien sûr ! Dans ce cas, la fonction ne renverrait plus rien, elle se contenterait de calculer l'aire et de l'afficher immédiatement :

void aireRectangle(double largeur, double hauteur)
{
    double aire = 0;
    
    aire = largeur * hauteur;
    printf("Rectangle de largeur %f et hauteur %f. Aire = %f\n", largeur, hauteur, aire);
}    

int main(int argc, char *argv[])
{    
    aireRectangle(5, 10);
    aireRectangle(2.5, 3.5);
    aireRectangle(4.2, 9.7);
       
    return 0;
}

printf est à l'intérieur de la fonction aireRectangle et produit le même affichage que tout à l'heure. C'est juste une façon différente de procéder.

Analysez une fonction qui ne prend aucun paramètre en entrée

Ce code est plus intéressant et concret : on crée une fonction menu qui ne prend aucun paramètre en entrée. Cette fonction se contente d'afficher le menu, et demande à l'utilisateur de faire un choix. La fonction renvoie le choix de l'utilisateur.

int menu()
{
    int choix = 0;
    
    while (choix < 1 || choix > 4)
    {
        printf("Menu :\n");
        printf("1 : Poulet de dinde aux escargots rotis a la sauce bearnaise\n");
        printf("2 : Concombres sucres a la sauce de myrtilles enrobee de chocolat\n");
        printf("3 : Escalope de kangourou saignante et sa gelee aux fraises poivree\n");
        printf("4 : La surprise du Chef (j'en salive d'avance...)\n");
        printf("Votre choix ? ");
        scanf("%d", &choix);
    }    
    
    return choix;
}    

int main(int argc, char *argv[])
{    
    switch (menu())
    {
        case 1:
            printf("Vous avez pris le poulet\n");
            break;
        case 2:
            printf("Vous avez pris les concombres\n");
            break;
        case 3:
            printf("Vous avez pris l'escalope\n");
            break;
        case 4:
            printf("Vous avez pris la surprise du Chef. Vous etes un sacre aventurier dites donc !\n");
            break;    
    }
       
    return 0;
}

La fonction menu affiche à nouveau le menu tant que l'utilisateur n'a pas entré un nombre compris entre 1 et 4. Comme ça, aucun risque que la fonction renvoie un nombre qui ne figure pas au menu !

Dans le main, vous avez vu qu'on fait un switch(menu())  : une fois que la fonction menu()est terminée, elle renvoie le choix de l'utilisateur directement dans le switch. C'est une méthode rapide et pratique.

En résumé

  • Les fonctions s'appellent entre elles. Ainsi, le main peut appeler des fonctions toutes prêtes telles que printf ou scanf, mais aussi des fonctions que nous avons créées.

  • Une fonction récupère en entrée des variables qu'on appelle les paramètres.

  • Elle effectue certaines opérations avec ces paramètres, puis retourne en général une valeur à l'aide de l'instruction return.

Dans le prochain chapitre, vous allez vous initiez à la programmation modulaire… J'espère que cela vous plaira ! Cela nous permettra de clôturer cette partie avant de nous attaquer à un gros morceau : les pointeurs.

Exemple de certificat de réussite
Exemple de certificat de réussite