Nous avons vu dans les tous premiers chapitres qu'un programme en C commençait par une fonction appelée "main".
Je vous avais d'ailleurs même fait un schéma récapitulatif, pour vous rappeler quelques mots de vocabulaire. Attendez que je retrouve ce schéma
* va fouiller dans les archives poussièreuses *
Ah je l'ai

Souvenirs souvenirs :
C'était au tout début hein

En haut, les directives de préprocesseur (un nom barbare sur lequel on reviendra d'ailleurs). Ces directives sont faciles à identifier : elles commencent par un # et sont généralement mises tout en haut des fichiers sources.
Puis en-dessous, il y avait ce que j'avais déjà appelé "une fonction". Ici, sur mon schéma, vous voyez une fonction "main" (pas trop remplie il faut le reconnaître

)
Je vous avais dit qu'un programme en langage C
commençait par la fonction main. Que je vous rassure, c'est toujours vrai
Seulement, jusqu'ici nous sommes restés
à l'intérieur de la fonction main. Nous n'en sommes jamais sortis. Revoyez vos codes sources et vous le verrez : nous sommes toujours restés à l'intérieur des accolades de la fonction main.
Eh bien, c'est mal d'avoir fait ça ?
Non ce n'est pas "mal", mais ce n'est pas ce que les programmeurs en C font dans la réalité.
Quasiment aucun programme n'est écrit uniquement à l'intérieur des accolades de la fonction "main". Jusqu'ici nos programmes étaient courts, donc ça ne posait pas de gros problèmes, mais imaginez des plus gros programmes qui font des milliers de lignes de code ! Si tout était concentré dans la fonction main, bonjour le bordel
Nous allons donc maintenant
apprendre à nous organiser. Nous allons en fait découper nos programmes en petits bouts (souvenez-vous de l'image des legos que je vous ai donnée tout à l'heure).
Chaque "petit bout de programme" sera ce qu'on appelle une fonction.
Quel est le but d'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. Schématiquement, ça donne quelque chose comme ça :
Lorsqu'on appelle une fonction, il y a 3 étapes :
- L'entrée: on fait "rentrer" des informations dans la fonction (en lui donnant des informations avec lesquelles travailler)
- Les calculs : grâce aux informations qu'elle a reçues en entrée, la fonction travaille.
- La sortie : une fois qu'elle a fini ses calculs, la fonction renvoie un résultat. C'est ce qu'on appelle la sortie, ou encore le retour.
Concrètement, on peut imaginer par exemple une fonction appelée "triple" qui calcule le triple du nombre qu'on lui donne (en le multipliant par 3) :
Bien entendu, les fonctions seront en général plus compliquées

Le but des fonctions est donc de simplifier le code source, pour ne pas avoir à retaper le même code plusieurs fois d'affilée.
Rêvez un peu : plus tard, nous créerons par exemple une fonction "afficherFenetre" qui ouvrira une fenêtre à l'écran. Une fois la fonction écrite (c'est l'étape la plus difficile), on n'aura plus qu'à dire "Hep toi la fonction afficherFenetre, ouvre-moi une fenêtre !"

On pourra aussi écrire une fonction "deplacerPersonnage" dont le but sera de déplacer le personnage d'un jeu à l'écran etc etc
Schéma d'une fonction
Vous avez déjà eu un aperçu de comment est faite une fonction avec la fonction main.
Cependant pour bien que vous compreniez il va falloir que je vous montre quand même
comment on construit une fonction.
Voici le schéma d'une fonction, à retenir par coeur :
Code : C | type nomFonction(parametres)
{
// Insérez vos instructions ici
}
|
Vous reconnaissez là un peu la forme de la fonction main.
Voici ce qu'il faut savoir sur ce schéma :
Une fonction, c'est donc un mécanisme qui reçoit des valeurs en
entrée (les paramètres) et qui renvoie un résultat en
sortie.
Créer une fonction
Voyons voir un exemple pratique sans plus tarder : la fameuse fonction "triple" dont je vous parle depuis tout à l'heure. On va dire que cette fonction reçoit un nombre entier de type int et qu'elle renvoie un nombre entier aussi de type int. Cette fonction calcule le triple du nombre qu'on lui donne :
Code : C | int triple(int nombre)
{
int resultat = 0;
resultat = 3 * nombre; // On multiplie le nombre qu'on nous a transmis par 3
return resultat; // On retourne la variable resultat qui vaut le triple de nombre
}
|
Voilà notre première fonction

Une première chose importante : comme vous le voyez, 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".
La ligne qui indique de "renvoyer une valeur" est celle qui contient le "return". Cette ligne se trouve généralement à la fin de la fonction, après les calculs.
return resultat; dit à la fonction : arrête-toi là et renvoie le nombre "resultat". Cette variable "resultat" DOIT être de type int, car la fonction renvoie un int comme on l'a dit plus haut
La variable resultat est déclarée (= créée) dans la fonction "triple". Cela signifie qu'elle n'est utilisable que dans cette fonction, et pas dans une autre comme la fonction "main" par exemple. C'est donc une variable propre à la fonction "triple".
Mais est-ce la façon la plus courte de faire notre fonction triple ?
Non, on peut faire ça en une ligne en fait
Code : C | 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

Généralement, vos fonctions contiendront plusieurs variables pour effectuer leurs calculs et leurs opérations, rares seront les fonctions aussi courtes que "triple"
Plusieurs paramètres, aucun paramètre
Plusieurs paramètres
Notre fonction "triple" contient un paramètre, mais il est possible de créer des fonctions prenant plusieurs paramètres.
Par exemple, une fonction addition qui additionne deux nombres a et b :
Code : C | int addition(int a, int b)
{
return a + b;
}
|
Il suffit de séparer les différents paramètres par une virgule comme vous le voyez
Aucun paramètre
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 toujours le même texte !)
Imaginons une fonction "bonjour" qui affiche juste bonjour à l'écran :
Code : C | void bonjour()
{
printf("Bonjour");
}
|
Je n'ai rien mis entre parenthèses car la fonction ne prend aucun paramètre.
De plus, j'ai mis le type "void" dont je vous ai parlé plus haut.
En effet, comme vous le voyez ma fonction n'a pas non plus de "return". Elle ne retourne rien.
Une fonction qui ne retourne rien est de type void.
Appeler une fonction
On va maintenant tester un code source pour pratiquer un peu avec ce qu'on vient d'apprendre.
Nous allons utiliser notre fonction "triple" (décidément je l'aime bien) pour calculer le triple d'un nombre.
Pour le moment, je vous demande d'écrire la fonction "triple" AVANT la fonction main. Si vous la mettez après, ça ne marchera pas. Je vous expliquerai pourquoi par la suite
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | #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 comme vous le savez.
On demande à l'utilisateur de rentrer un nombre. On envoie ce nombre qu'il a rentré à la fonction triple, 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 :
Code : C | nombreTriple = triple(nombreEntre);
|
Entre parenthèses, on envoie une variable en
entrée à la fonction triple, c'est le nombre sur lequel elle va travailler.
Cette fonction renvoie une valeur, valeur qu'on récupère dans la variable nombreTriple. On demande donc à l'ordinateur dans cette ligne : "Demande à la fonction triple de me calculer le triple de nombreEntre, et stocke le résultat dans la variable nombreTriple".
Les mêmes explications sous forme de schéma
Vous avez encore du mal à comprendre comment ça fonctionne concrètement ?
Pas de panique ! Je suis sûr que vous allez comprendre avec mes schémas
Ce code particulièrement commenté vous indique
dans quel ordre le code est lu. Commencez donc par lire la ligne numérotée "1", puis "2", puis "3" (bon vous avez compris je crois

)
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | #include <stdio.h>
#include <stdlib.h>
int triple(int nombre) // 6) On saute à la fonction triple et on récupère un paramètre (nombre)
{
return 3 * 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
}
int main(int argc, char *argv[]) // 1) Le programme commence par la fonction main (cette ligne)
{
int nombreEntre = 0, nombreTriple = 0; // 2) Il lit les instructions dans la fonction une par une dans l'ordre
printf("Entrez un nombre... "); // 3) Il lit l'instruction suivante et fait ce qui est demandé (printf)
scanf("%d", &nombreEntre); // 4) Pareil, il lit l'instruction et fait ce qui est demandé (scanf)
nombreTriple = triple(nombreEntre); // 5) Il lit l'instruction... Ah ! On appelle la fonction triple, on doit donc sauter à la ligne de la fonction triple plus haut
printf("Le triple de ce nombre est %d\n", nombreTriple); // 8) On retourne dans le main à l'instruction suivante
return 0; // 9) Un return ! La fonction main se termine et donc le programme est terminé.
}
|
Si vous avez compris dans quel ordre l'ordinateur lisait les instructions, vous avez déjà compris le principal
Maintenant, il faut bien comprendre qu'une fonction reçoit des paramètres en entrée et renvoie une valeur en sortie.
Note : ce n'est pas tout le temps le cas comme ça pour toutes les fonctions. Parfois, une fonction ne prend aucun paramètre en entrée, ou au contraire elle en prend plusieurs (je vous ai expliqué ça un peu plus haut).
De même, parfois une fonction renvoie une valeur, parfois elle ne renvoie rien (dans ce cas il n'y a pas de
return).
Testons ce programme
Voici un exemple d'utilisation du programme (y'a rien de bien extraordinaire car c'est une fonction toute bête hein

) :
Code : Console | Entrez un nombre... 10
Le triple de ce nombre est 30 |
Vous n'êtes pas obligés de stocker le résultat d'une fonction dans une variable ! Vous pouvez directement envoyer le résultat de la fonction triple à une autre fonction, comme si triple(nombreEntre) était une variable.
Regardez bien ceci, c'est le même code mais y'a un changement au niveau du dernier printf, et on n'a pas déclaré de variable nombreTriple car on ne s'en sert plus :
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | #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;
}
|
Comme vous le voyez,
triple(nombreEntre) est directement envoyé au printf.
Que fait l'ordinateur quand il tombe sur cette ligne ?
C'est très simple. 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. Le premier paramètre est le texte à afficher, et le second est un nombre.
Votre ordinateur voit que pour envoyer ce nombre à la fonction printf il doit d'abord appeler la fonction triple. C'est ce qu'il fait : il appelle triple, il effectue les calculs de triple, 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 top, 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 Legos
Au final, le plus dur sera d'écrire vos fonctions. Une fois que vous les aurez écrites, vous n'aurez plus qu'à appeler les fonctions sans vous soucier des calculs qu'elles peuvent bien faire à l'intérieur. Ca va permettre de simplifier considérablement l'écriture de nos programmes, et ça croyez-moi on en aura bien besoin !
