chapitre 04 : les fonctions
TRANSCRIPT
Introduction au langage C++
Chapitre 4
Les fonctions
Youssouf EL ALLIOUI, [email protected]
Université Hassan Premier de Settat
Ce cours est disponible en format électronique sur http://fr.slideshare.net/yelallioui/
Objectif de ce chapitre
la plupart des programmes informatique sont des programmes complexes. Ils
comportent des dizaines de milliers de lignes et les grosses applications en comportent
des millions. Si l'on garde tout dans une seule fonction, la fonction main() par exemple,
il va être très difficile de s'y retrouver. Il serait certainement plus simple de découper ce
programme en fonctions. Chaque fonction est destinée à effectuer une tâche précise et
renvoie généralement un résultat. Découper son programme en fonctions permet de
s'organiser.
En plus, si vous êtes plusieurs développeurs à travailler sur le même programme,
vous pourrez vous partager plus facilement le travail : chacun s'occupe d’une fonction
différente.
Et ce n'est pas tout ! Prenons par exemple le calcul de la racine carrée, que nous
avons vu précédemment. Si vous créez un programme de maths, il est bien possible que
vous ayez besoin, à plusieurs endroits, d'effectuer des calculs de racines. Avoir une
fonction sqrt() va nous permettre de faire plusieurs de ces calculs sans avoir à
2016
1 | 13
1 Introduction au langage C++ | Chapitre 4 : Les fonctions
recopier le même code à plusieurs endroits. On peut réutiliser plusieurs fois la même
fonction et c'est une des raisons principales d'en écrire.
Entraînez-vous via
Exercices applicatifs
QCM fourni à la fin de la séance
Les TPs
Sommaire
I. Créer et utiliser une fonction __________________________________________ 2
I. 1. Déclaration d’une fonction ________________________________________ 2
I. 2. Définition d’une fonction _________________________________________ 2
I. 3. Utilisation d’une fonction _________________________________________ 3
I. 4. Des fonctions qui ne renvoient rien _________________________________ 4
II. Surcharge des fonctions ______________________________________________ 5
III. Arguments par défaut _____________________________________________ 6
IV. Passage par valeur et passage par référence ____________________________ 7
IV. 1. Passage par valeur ____________________________________________ 7
IV. 2. Passage par référence _________________________________________ 8
V. Utilisation de plusieurs fichiers ________________________________________ 9
V. 1. Le fichier source ________________________________________________ 9
V. 2. Le fichier header ________________________________________________ 0
V. 3. Exemple d’utilisation des fichiers source et header __________________ 1
VI. Ce que vous devez retenir ! _________________________________________ 2
Références
Cours de C/C++ [Ouvrage] / aut. Casteyde Christian. - 2001. - Vol. Version 1.40.1 : p. 501. Programmez avec le langage C++ [Ouvrage] / aut. Mathieu Nebra et Matthieu Schaller. - [s.l.] : le Livre du Zéro, 2015.
2 | 13
2 Introduction au langage C++ | Chapitre 4 : Les fonctions
I. Créer et utiliser une fonction
Une fonction est caractérisée par :
1) son nom
2) le type de valeur qu’elle renvoie,
3) les paramètres qu’elle reçoit pour faire son travail,
4) l’instruction-bloc qui effectue le travail (corps de la fonction).
Les trois premiers éléments sont décrits dans la déclaration de la fonction. L’élément n◦4
figure dans la définition de la fonction. Toute fonction doit être définie avant d’être
utilisée.
I. 1. Déclaration d’une fonction
Toute fonction doit être déclarée avant d’être appelée pour la première fois. La définition
d’une fonction peut faire office de déclaration.
Il peut se trouver des situations où une fonction doit être appelée dans une autre fonction
définie avant elle. Comme cette fonction n’est pas définie au moment de l’appel, elle doit
être déclarée.
Le rôle des déclarations est donc de signaler l’existence des fonctions aux compilateurs
afin de les utiliser, tout en reportant leur définition de ces fonctions plus loin ou dans un
autre fichier.
La syntaxe de la déclaration d’une fonction est la suivante :
1 type nomDeLafonction (paramètres) ;
Exemples :
1 double Moyenne(double x, double y);
2 char LireCaractere();
3 void AfficherValeurs(int nombre, double valeur);
NB : la dernière fonction n’est pas destinée à renvoyer une valeur ; c’est pourquoi le type
du résultat est void, une telle fonction est parfois appelée procédure (voir I. 4 Des
fonctions qui ne renvoient rien).
I. 2. Définition d’une fonction
Il faut retenir la règle suivante :
Toute fonction doit être définie avant d’être utilisée
La définition des fonctions se fait comme suit :
1 type nomDeLafonction (paramètres) 2 { 3 instructions ; 4 }
3 | 13
3 Introduction au langage C++ | Chapitre 4 : Les fonctions
On retrouve les quatre éléments dont je vous ai déjà parlé :
1) type est le type de la valeur renvoyée par la fonction
2) nomDeLaFonction est le nom ou l’identificateur de la fonction, et
3) paramètres est une liste de paramètres. Ce sont les données avec lesquelles la
fonction va travailler. Il peut y avoir un, plusieurs ou aucun paramètre.
4) L’instruction-bloc : il s’agit des accolades qui délimitent le contenu de la fonction.
Toutes les opérations qui seront effectuées se trouvent entre les deux
accolades.
NB : Il est possible de créer plusieurs fonctions ayant le même nom. Il faut alors que la
liste des arguments des deux fonctions soit différente. C'est ce qu'on appelle
la surcharge d'une fonction.
Exemple :
Commençons par une fonction basique. Une fonction qui reçoit deux nombres réels a et
b, et renvoie la somme a+b.
1 double somme(double a, double b) 2 { 3 double r; 4 r = a + b; 5 return r; 6 }
Dans ce programme, on a créé une fonction nommée somme qui reçoit deux nombres
réels a et b en paramètre et qui, une fois qu'elle a terminé, renvoie un autre nombre r
réel qui représente la somme de a et b.
I. 3. Utilisation d’une fonction
Elle se fait grâce à l’appel de la fonction. Prenons l’exemple suivant :
1 #include <iostream> 2 using namespace std; 3 4 // définition de la fonction somme : 5 double somme(double a, double b) 6 { 7 double r; 8 r = a + b; 9 return r; 10 } 11 12 int main() 13 { 14 double x, y, resultat; 15 cout << "Tapez la valeur de x : "; cin >> x; 16 cout << "Tapez la valeur de y : "; cin >> y; 17 18 //appel de notre fonction somme 19 resultat = somme(x, y); 20
4 | 13
4 Introduction au langage C++ | Chapitre 4 : Les fonctions
21 cout << x << " + " << y << " = " << resultat << endl; 22 return 0; 23 }
Si vous avez essayé ce programme, Voici ce qu’il donne :
Le même exemple avec déclaration, ce qu’on appel prototype, de la fonction somme.
1 #include <iostream> 2 using namespace std; 3 4 // déclaration de la fonction somme : 5 double somme(double a, double b); 6 7 int main() 8 { 9 double x, y, resultat; 10 cout << "Tapez la valeur de x : "; cin >> x; 11 cout << "Tapez la valeur de y : "; cin >> y; 12 13 //appel de notre fonction somme 14 resultat = somme(x, y); 15 16 cout << x << " + " << y << " = " << resultat << endl; 17 return 0; 18 } 19 20 // définition de la fonction somme : 21 double somme(double a, double b) 22 { 23 double r; 24 r = a + b; 25 return r; 26 }
Dans cet exemple, le prototype est nécessaire, car la fonction est définie après la
fonction main() qui l'utilise. Si le prototype est omis, le compilateur signale une erreur.
Ce programme donne le même résultat que le précédent. Vous pouvez essayer !
I. 4. Des fonctions qui ne renvoient rien
C++ permet de créer des fonctions qui ne renvoient aucun résultat. mais, quand on la
déclare, il faut quand même indiquer un type. On utilise le type void. Cela veut tout dire
: il n'y a vraiment rien qui soit renvoyé par la fonction.
Exemple :
1 void direBonjour()
5 | 13
5 Introduction au langage C++ | Chapitre 4 : Les fonctions
2 { 3 cout << "Bonjour !" << endl; 4 //Comme rien ne ressort, il n'y a pas de return ! 5 } 6 7 int main() 8 { 9 direBonjour(); 10 //Comme la fonction ne renvoie rien 11 //On l'appelle sans mettre la valeur de retour dans une variable 12 13 return 0; 14 }
NB : Une fonction produit toujours au maximum un résultat, c’est-à-dire qu’Il n'est pas
possible de renvoyer plus qu'une seule valeur.
Surcharge des fonctions
II. Surcharge des fonctions
Il est possible de créer plusieurs fonctions ayant le même nom. Il faut alors que la liste
des arguments de ces fonctions soit différente. C'est ce qu'on appelle la surcharge d'une
fonction.
Exemples :
1 #include <iostream> 2 using namespace std; 3 4 // définition de la fonction somme qui calcul la somme de deux réels 5 double somme(double a, double b) 6 { 7 double r; 8 r = a + b; 9 return r; 10 } 11 12 // définition de la fonction somme qui calcul la somme de deux entiers 13 double somme(int a, int b) 14 { 15 double r; 16 r = a + b; 17 return r; 18 } 19 20 // définition de la fonction somme qui calcul la somme de trois réels 21 double somme(double a, double b, double c) 22 { 23 double r; 24 r = a + b + c; 25 return r; 26 }
Ces trois fonctions portent le même nom, et le compilateur les acceptera toutes les trois.
- Lors de l’appel de somme(2.4, 3.3), ce sera la première qui sera appelée, car
2.4 et 3.3 sont deux réels.
6 | 13
6 Introduction au langage C++ | Chapitre 4 : Les fonctions
- Lors de l’appel de somme(2,3), ce sera la deuxième, parce que 2 et 3 sont deux
entiers.
- Lors de l’appel de somme(2.4, 3.3, 5.5), ce sera la première qui sera appelée,
car 2.4, 3.3 et 5.5 sont trois réels.
NB : Dans un appel tel que somme(2.5,3), le flottant 2.5 sera converti en entier et la
deuxième fonction sera appelée. Il convient donc de faire très attention aux mécanismes
de surcharges du langage, et de vérifier les règles de priorité utilisées par le compilateur.
III. Arguments par défaut
On peut, lors de la déclaration d’une fonction, donner des valeurs par défaut à certains
paramètres des fonctions. Ainsi, lorsqu'on appelle une fonction, on ne sera pas obligé
d'indiquer à chaque fois tous les paramètres !
Voir l’exemple suivant :
1 #include <iostream> 2 3 using namespace std; 4 5 // Prototype avec les valeurs par défaut 6 int nombreDeSecondes(int heures, int minutes = 0, int secondes = 0); 7 8 // Main 9 int main() 10 { 11 cout << nombreDeSecondes(1, 10) << endl; 12 13 return 0; 14 } 15 16 // Définition de la fonction, SANS les valeurs par défaut 17 int nombreDeSecondes(int heures, int minutes, int secondes) 18 { 19 int total = 0; 20 21 total = heures * 60 * 60; 22 total += minutes * 60; 23 total += secondes; 24 25 return total; 26 }
Dans cet exemple, seul le paramètre heures sera obligatoire, les deux autres étant
désormais facultatifs. Si on ne renseigne pas les minutes et les secondes, les variables
correspondantes vaudront alors 0 dans la fonction. Les trois appels suivants sont alors
corrects :
11 cout << nombreDeSecondes(1, 10, 30) << endl;
11 cout << nombreDeSecondes(1, 10) << endl;
11 cout << nombreDeSecondes(1) << endl;
Il y a quelques règles que vous devez retenir pour les valeurs par défaut :
7 | 13
7 Introduction au langage C++ | Chapitre 4 : Les fonctions
seul le prototype doit contenir les valeurs par défaut (pas la définition de la
fonction) ;
les valeurs par défaut doivent se trouver à la fin de la liste des paramètres
vous pouvez rendre tous les paramètres de votre fonction facultatifs ?
IV. Passage par valeur et passage par référence
Il y a deux méthodes pour passer des variables en paramètres dans une fonction : le
passage par valeur et le passage par référence. Ces méthodes sont décrites ci-dessous.
IV. 1. Passage par valeur
La valeur de l’expression passée en paramètre est copiée dans une variable locale. C’est
cette variable qui est utilisée pour faire les calculs dans la fonction appelée.
Pour mieux comprendre, Prenons le programme suivant qui ajoute 1 à l'argument fourni en
paramètre.
1 #include <iostream> 2 using namespace std; 3 4 int incrementerArgument (int a) 5 { 6 a+=1; 7 return a; 8 } 9 10 int main() 11 { 12 int nombre(4), resultat; 13 resultat = incrementerArgument(nombre); 14 15 cout << "Le nombre original vaut : " << nombre << endl; 16 cout << "Le resultat vaut : " << resultat << endl; 17 18 return 0; 19 }
Cela donne le résultat suivant :
L’élément important dans ce programme est que la variable nombre reste inchangée (= 4).
La valeur de la variable passée en paramètre (nombre dans notre cas) est copiée dans une
variable locale. C'est cette variable qui est utilisée pour faire les calculs dans la fonction
appelée. Donc aucune modification de la variable locale dans la fonction appelée ne modifie
8 | 13
8 Introduction au langage C++ | Chapitre 4 : Les fonctions
la variable passée en paramètre, parce que ces modifications ne s'appliquent qu'à une
copie de cette dernière.
La mémoire ressemble donc à ce qui se trouve dans le schéma de la figure suivante.
IV. 2. Passage par référence
La deuxième technique consiste à passer non plus la valeur des variables comme
paramètre, mais plutôt d'ajouter une « deuxième étiquette » à la variable nombre à
l'intérieur de la fonction. Et c'est bien sûr une référence qu'il faut utiliser comme
argument de la fonction. Il n'y a donc plus de copie, plus de variable locale. Toute
modification du paramètre dans la fonction appelée entraîne la modification de la variable
passée en paramètre. Voir l’amélioration apportée à l’exemple précédent.
1 #include <iostream> 2 using namespace std; 3
4 int incrementerArgument (int& a) //Notez bien le petit & ! { a+=2; return a; } 5 { 6 a+=1; 7 return a; 8 } 9 10 int main() 11 { 12 int nombre(4), resultat; 13 resultat = incrementerArgument(nombre); 14 15 cout << "Le nombre original vaut : " << nombre << endl; 16 cout << "Le resultat vaut : " << resultat << endl; 17 18 return 0; 19 }
Essayons pour voir. Testons ce programme (sans oublié le petit &). On obtient cette fois-
ci le résultat suivant :
5
4
4
Mémoire
a resultat
nombre
9 | 13
9 Introduction au langage C++ | Chapitre 4 : Les fonctions
Cette fois, la variable a et la variable nombre sont confondues. On dit que
l'argument a est passé par référence. La mémoire ressemble dans ce cas à ce qu’est
présenté dans le schéma de la figure suivante.
V. Utilisation de plusieurs fichiers
Le C++ permet de découper son programme en plusieurs fichiers sources. Chacun étant
spécialisé dans une catégorie d’actions précise. Chaque fichier contient une ou plusieurs
fonctions. On peut alors inclure les fichiers, et donc les fonctions, dont on a besoin dans
différents projets.
Pour le faire il ne faut deux fichiers au lieu d’un seul :
1) un fichier source dont l'extension est .cpp : il contient le code source de la
fonction ;
2) un fichier header dont l'extension est .h : il contient uniquement le prototype de
la fonction.
V. 1. Le fichier source
Pour le créer, Choisissez Menu > File > New > File. Choisissez ensuite C/C++
source ().
Pour le créer, suivez les étapes suivantes :
1) Choisissez Menu > File > New > File (Figure 1).
2) Choisissez ensuite C/C++ source (Figure 2).
3) Cliquez ensuite sur Go(Figure 2).
4) Le programme vous demande le choix entre C ou C++. Choisissez C++ (Figure 3).
5) Choisir le nom et l’emplacement de votre fichier (Figure 4). J’ai choisi le
nom calcul.cpp.
6) Cochez ensuite toutes les options (Figure 4).
7) Cliquez sur Finish (Figure 4).
a resultat
nombre
5
4
Mémoire
Figure 1 : Création de nouveau fichier
Figure 2 : Model de fichier
Figure 3 : Langage de fichier (C ou C++)
Figure 4 : Emplacement & nom de fichier
Notre fichier source est maintenant créé. Passons au fichier header.
V. 2. Le fichier header
Pour créer le fichier header, nous gardons les mêmes étapes précédentes avec des petites
modifications :
1) Choisissez Menu > File > New > File (Figure 1).
2) Choisissez ensuite C/C++ header (Figure 2).
3) Cliquez ensuite sur Go(Figure 2).
4) Le programme vous demande le choix entre C ou C++. Choisissez C++ (Figure 3).
5) Choisir le nom et l’emplacement de votre fichier (Figure 4). Il est conseillé de lui
donner le même nom qu'au fichier source mais avec une extension .h au lieu
de .cpp. Dans notre cas, ce sera donc calcul.h.
6) Cochez ensuite toutes les options (Figure 4).
7) Cliquez sur Finish (Figure 4).
Et voilà ! Le deuxième fichier a été créé.
Vous devriez maintenant voir les deux fichiers calcul.cpp et calcul.h apparaître dans
la colonne de gauche de Code::Blocks (Figure 5).
1 | 13
1 Introduction au langage C++ | Chapitre 4 : Les fonctions
Figure 5 : Architecture de notre projet après l'ajout des fichiers source et header
V. 3. Exemple d’utilisation des fichiers source et header
Maintenant que nous avons nos fichiers source et header, il ne reste qu'à les remplir et
les inclure dans le fichier main.cpp.
Le fichier source : calcul.cpp
Voici le fichier calcul.cpp au complet :
1 #include "calcul.h" 2 3 double somme(double a, double b) 4 { 5 double r; 6 r = a + b; 7 return r; 8 }
Le compilateur a besoin de savoir que les fichiers .cpp et .h ont un lien entre eux. C’est
pour cela nous avons commencé le fichier par la ligne : #include "calcul.h". Elle
indique que l'on va utiliser ce qui se trouve dans le fichier calcul.h.
NB : Il faut utiliser ici des guillemets " et non des chevrons < et > .
Le fichier header : calcul.h
Dans ce fichier, il faut mettre les prototypes des fonctions. Voici ce que nous obtenons
pour notre fonction somme :
1 #ifndef CALCUL_H_INCLUDED 2 #define CALCUL_H_INCLUDED 3 4 double somme(double a, double b); 5 6 #endif // CALCUL_H_INCLUDED
NB :
- N'oubliez pas le point-virgule
- Si vous utilisez des variables plus compliquées en argument comme des strings,
vous devez ajouter la ligne d'inclusion #include <string> avant le prototype.
2 | 13
2 Introduction au langage C++ | Chapitre 4 : Les fonctions
Et voilà ! Il ne nous reste qu'une seule chose à faire : inclure tout cela dans le
fichier main.cpp.
Le fichier de test : main.cpp
Le fichier main.cpp au complet :
1 #include <iostream> 2 #include "calcul.h" 3 4 using namespace std; 5 6 int main() 7 { 8 double x, y, resultat; 9 cout << "Tapez la valeur de x : "; cin >> x; 10 cout << "Tapez la valeur de y : "; cin >> y; 11 12 //appel de notre fonction somme 13 resultat = somme(x, y); 14 15 cout << x << " + " << y << " = " << resultat << endl; 16 17 return 0; 18 }
Nous avons ajouté la ligne #include "calcul.h" pour que le compilateur puisse trouver
la fonction somme lorsqu'on essaiera de l'utiliser.
Et voilà ! Nous avons maintenant réellement des fichiers séparées utilisables dans
plusieurs programmes. Si vous voulez utiliser la fonction somme dans un autre projet, il
vous suffira de copier les fichiers calcul.cpp et calcul.h.
NB : On peut bien sûr mettre plusieurs fonctions par fichier. On les regroupe
généralement par catégories : les fonctions de calcul dans un fichier, les fonctions d’accès
à la base de données dans un autre fichier, etc.
VI. Ce que vous devez retenir !
Une fonction est un morceau de code contenant des instructions et ayant un rôle
précis.
Tous les programmes ont au moins une fonction : C'est la fonction main(). Elle
représente le point de démarrage d’un tel programme.
Découper votre programme en fonctions vous permettra d’avoir une meilleure
organisation.
Une même fonction peut être appelée plusieurs fois au cours de l'exécution d'un
programme.
Une fonction peut recevoir des informations en entrée (appelées paramètres ou
arguments) et renvoyer un résultat en sortie grâce à return.
Les fonctions peuvent recevoir des références en argument pour modifier
directement une information précise en mémoire.
3 | 13
3 Introduction au langage C++ | Chapitre 4 : Les fonctions
Lorsque le programme grossit, il est conseillé de créer plusieurs fichiers
regroupant des fonctions. Les fichiers .cpp contiennent les définitions des
fonctions et les fichiers .h contiennent leurs prototypes.
Les fichiers .h permettent d'annoncer l'existence des fonctions à l'ensemble des
autres fichiers du programme.
Notez bien qu’une fonction ne peut renvoyer plus qu'une valeur. Elle produit
toujours au maximum un seul résultat.