SlideShare ist ein Scribd-Unternehmen logo
1 von 147
Downloaden Sie, um offline zu lesen
Aziz DAROUICHI
UCA-Marrakech
Mail to: pr.azizdarouichi@gmail.com
1
Programmation Orientée Objet (C++):
Les fonctions
2
Notion de fonction
Définition de fonction
Instruction return
Appel de fonction
Prototype de fonction
La fonction main()
Évaluation de l’appel d’une fonction
Les fonctions et leurs déclarations
Passage des arguments par valeur
Passage des arguments par référence
Passage par référence constante
Variables globales et locales
Récursivité
Fonctions inline
Surcharge (ou surdéfinition) de fonctions
La fonction exit()
Q & A
Notion de fonction
Définition de fonction
Instruction return
Appel de fonction
Prototype de fonction
La fonction main()
Évaluation de l’appel d’une fonction
Les fonctions et leurs déclarations
Passage des arguments par valeur
Passage des arguments par référence
Passage par référence constante
Variables globales et locales
Récursivité
Fonctions inline
Surcharge (ou surdéfinition) de fonctions
La fonction exit()
Q & A
Programmation procédurale
3
Notion de fonction
Fonction
Définition:
Une fonction est un sous-programme indépendant qui retourne ou
non une valeur.
Fonction = portion de programme réutilisable ou importante en soi.
Une fonction reçoit des informations en entrée, exécute des actions
et renvoie un résultat.
SortieEntrée
Fonction
4
Notion de fonction
Plus précisément, une fonction est un objet logiciel caractérisé par :
un corps : la portion de programme à réutiliser ou mettre en évidence,
qui a justifié la création de la fonction ; il est délimité par des
accolades.
un nom : par lequel on désignera cette fonction ;
des paramètres : (les « entrées », on les appelle aussi « arguments »)
ensemble de variables extérieures à la fonction dont le corps dépend
pour fonctionner ;
un type et une valeur de retour : (la « sortie ») ce que la fonction
renvoie au reste du programme.
5
Notion de fonction
Les « 3 facettes » d’une fonction
Résumé / Contrat (« prototype »)
Création / Construction (« définition »)
Utilisation (« appel »)
6
Notion de fonction
7
Définition de fonction
Syntaxe d’une fonction
type_valeur_de_retour nom_de_la_fonction(liste des paramètres avec leurs types)
{
Bloc d‘instructions; // déclarations locales si nécessaire
// calcul et retour (avec return) du résultat
}
N. B: choisir un nom de la fonction qui décrit bien ce qu'elle fait, comme pour les
variables.
8
Définition de fonction
Exemple 1:
Type de la valeur de retour float max(float a, float b)
{
float plusGrand;
if (a<b) plusGrand = b;
else plusGrand = a;
return plusGrand ;
}
La première ligne dans la définition, float max(float a, float b), s‘appelle l‘entête
de la fonction.
Il n'y a pas de point-virgule ! Ni après la déclaration, ni après l'accolade fermante.
Nom de
la fonction
Liste des paramètres
avec leurs types
Corps de la fonction
Valeur de retour
9
Définition de fonction
Exemple 2:
Une fonction qui reçoit un nombre entier, calcule son carré et le
renvoie.
int carre(int x)
{
int y;
y = x*x;
return y ;
}
10
Définition de fonction
Exemple 3: plusieurs paramètres
Une fonction qui calcule la somme de 2 entiers et la renvoie.
int addition(int x, int y)
{
return x+y;
}
Une fonction qui calcule le produit des 4 réels et le renvoie.
double multiplication(double a, double b, double c, double d )
{
return a*b*c*d ;
}
11
Définition de fonction
Exemple 4: cas des fonctions qui renvoient un booléen
Les fonctions peuvent retourner des valeurs booléennes (true ou
false).
bool estValide(int nombre)
{
bool statut;
if (nombre >= 1 && nombre <= 100)
statut = true;
else
statut = false;
return statut;
}
12
Définition de fonction
Exemple 4: cas des fonctions qui renvoient un booléen
Voici un code utilisant cette fonction:
int valeur(20);
if (estValide(valeur))
cout << "La valeur est dans le domaine." << endl;
else
cout << "La valeur est hors de domaine." << endl;
13
Définition de fonction
1313
Instruction return
14
Instruction Return
L’instruction return peut apparaître à plusieurs reprises dans une
fonction.
Une fonction peut ne renvoyer aucune valeur : elle peut alors
disposer de plusieurs instructions return sans expression,
interrompant simplement l’exécution de la fonction.
La fonction qui ne renvoie aucune valeur peut ne comporter aucune
instruction return.
Si le type de l’expression de l’instruction return est différent du
type de la valeur de retour, le compilateur mettra automatiquement
en place des instructions de conversion.
15
Appel de fonction
Toute fonction doit être déclarée avant son utilisation.
L’utilisation de la fonction dans une autre partie du programme se
nomme un appel de la fonction.
La syntaxe pour appeler une fonction:
résultat = nomDeLaFonction(arguments);
L‘appel (avec ou sans paramètres) de la fonction déclenche
l‘exécution de son bloc d‘instructions.
Une fonction se termine en retournant ou non une valeur.
16
Arguments muets et arguments effectifs
Les noms des arguments figurant dans l’en-tête de la fonction se
nomment des « arguments muets ». Leur rôle est de permettre, au
sein du corps de la fonction, de décrire ce qu’elle doit faire.
Les arguments fournis lors de l’appel de la fonction portent quant à
eux le nom des « arguments effectifs ».
Remarque:
Arguments muets= arguments formels = paramètres formels.
Arguments effectifs = paramètres effectifs = paramètres réels.
17
Arguments muets et arguments effectifs
Les arguments formels sont ceux déclarés avec la fonction :
void f(int i, int j, double x)
Les paramètres effectifs (ou réels) sont ceux qui sont envoyés au
moment de l’appel de la fonction :
int k, l;
double y;
f(k, l, y);
18
Prototype de fonction
La déclaration d’une fonction porte le nom de prototype.
Toute fonction doit être annoncée avant d’être utilisée : prototype
Une fonction ne peut être définie qu’une seule fois dans un programme
Elle peut être utilisée autant de fois que nécessaire
L’objectif du prototype est d’informer le compilateur du type de la
valeur de retour, du nombre de paramètres et du type de chacun
Prototype = déclaration de la fonction, sans en définir le corps :
nom
paramètres
type de la valeur de retour
19
Prototype de fonction
Syntaxe de déclaration de fonction:
type_valeur_de_retour nom_de_la_fonction (type1 param1, ..., typeN paramN ) ;
Exemples :
double moyenne(double x, double y);
int nbHasard();
int score (double points, double temps_jeu);
float min(float x, float y);
float f(float, int, int);
20
Fonction simple
Exemple complet
21
Une fonction peut ne pas renvoyer de résultat ou ne pas avoir
d’arguments:
s’il n’y a pas de résultat renvoyé : dans l’en-tête de la fonction,
on remplace le type de la valeur de retour par le mot clé void
s’il n’y a pas d’arguments : dans les parenthèses de l’en-tête de
la fonction, on remplace la liste d’arguments et leurs types par
rien du tout (parenthèses vides).
Fonctions sans valeur de retour ou sans arguments
22
Fonctions sans valeur de retour
Syntaxe d’une fonction qui ne renvoie rien
void nom_de_la_fonction(liste des paramètres avec leurs types)
{
Bloc d‘instructions; // déclarations locales si nécessaire
// return n’est pas obligatoire
}
Pour appeler cette fonction il suffit d’écrire:
nom_de_la_fonction(liste des paramètres)
23
Fonctions sans valeur de retour
Exemple:
Voici une fonction qui affiche n fois bonjour:
void afficherBonjour(int n)
{
for(int i(0); i<n;++i)
cout << "Bonjour " << endl ;
return; // pas obligatoire
}
24
Fonctions sans valeur de retour
Exemple: fonction affiche n fois bonjour
void afficherBonjour(int n)
{
for(int i(0); i<n;++i)
cout << "Bonjour " << endl ;
}
Dans la fonction main():
int main(){
afficherBonjour(3); //Comme la fonction ne renvoie rien
//On l'appelle sans mettre la valeur de retour dans une variable
return 0;
}
25
Fonctions sans arguments
On peut aussi créer des fonctions sans arguments. Il suffit de ne
rien écrire entre les parenthèses.
Syntaxe
[type_de_retour] (ou void) nom_de_la_fonction( )
{
Bloc d‘instructions; // déclarations locales si nécessaire
// return n’est pas obligatoire si le type de
//retour est void
}
Pour appeler cette fonction il suffit d’écrire:
[résultat=]nom_de_la_fonction()
Liste des paramètres
vide
26
Fonctions sans arguments
string afficherNom( ){
string nom("Marrakchi");
cout << "Saisir votre nom : " << endl ;
cin >> nom;
return nom;
}
Dans la fonction main():
int main(){
string name;
name = afficherNom(); // Comme la fonction renvoie une valeur
// On l'appelle en mettant la valeur de retour dans une variable
cout << "Votre nom saisi est : " << name << endl ;
return 0;}
Exemple 1:
27
Fonctions sans arguments
Exemple 2:
Voici une fonction ne possédant ni argument ni valeur de retour:
void afficherBonjour( )
{
cout << "Bonjour " << endl ;
}
Dans la fonction main():
int main(){
afficherBonjour(); //Comme la fonction ne renvoie rien
//On l'appelle sans mettre la valeur de retour dans une variable
return 0;
}
28
Comparaison
En-tête de fonction void afficherBonjour( )
Prototype de fonction void afficherBonjour( );
Appel de fonction afficherBonjour( );
Définition de fonction :
void afficherBonjour( )
{
cout << "Bonjour " << endl ;
}
Fonctions en C++
29
Remarque: Attention à la syntaxe!
int f; : déclaration de variable non initialisée
int f(); : prototype de fonction sans paramètre
int f(5); : déclaration et initialisation de variable
f(5); : appel de fonction à un argument
Fonctions en C++
30
Comment on peut réutiliser la même fonction?
Calcul des carrés des nombres entre 1 et 10:
double carreNombre(double x){
return x*x;
}
int main(){
for(int i(1); i<=10 ; i++){
cout << "Le carre de " << i << " est : " << carreNombre(i) << endl;
}
return 0;
}
Fonctions en C++
31
Comment on peut réutiliser la même fonction?
Calcul des carrés des nombres entre 1 et 10:
Le carre de 1 est : 1
Le carre de 2 est : 4
Le carre de 3 est : 9
Le carre de 4 est : 16
Le carre de 5 est : 25
Le carre de 6 est : 36
Le carre de 7 est : 49
Le carre de 8 est : 64
Le carre de 9 est : 81
Le carre de 10 est : 100
Fonctions en C++
32
main est aussi une fonction avec un nom et un prototype imposés.
Par convention, tout programme C++ doit avoir une fonction
main, qui est appelée automatiquement quand on exécute le
programme.
Cette fonction doit retourner une valeur de type int. La valeur 0
indique par convention que le programme s’est bien déroulé.
Les deux seuls prototypes autorisés pour main sont :
int main();
int main(int argc, char** argv);
La fonction main()
33
Évaluation de l’appel d’une fonction
Que se passe-t-il lors de l’appel suivant :
z = moyenne( 1.5 + 0.8, 3.4 * 1.25 );
1. Évaluation des expressions passées en arguments :
1.5 + 0.8 2.3
3.4 * 1.25 4.25
2. Affectation des paramètres :
x = 2.3
y = 4.25
3. Exécution du corps de la fonction
4. Évaluation de la valeur de retour (expression de l’instruction return)
(x + y) / 2.0 3.275
5. Replacement de l’expression de l’appel par la valeur retournée :
z = 3.275;
double moyenne (double x, double y)
{
return (x + y) / 2.0;
}
2.3 2.3
x
copie
34
Évaluation de l’appel d’une fonction
L’évaluation de l’appel
f(arg1, ..., argN)
d’une fonction définie par
typeDeRetour f(type1 x1, ..., typeN xN) { ... }
s’effectue de la façon suivante :
1. Les expressions arg1, ..., argN passées en argument sont évaluées
2. Les valeurs correspondantes sont affectées aux paramètres x1,..., xN de la
fonction f.
Concrètement, ces deux premières étapes reviennent à faire :
x1 = arg1, x2 = arg2, ..., xN = argN
3. Le programme correspondant au corps de la fonction f est exécuté
4. L’expression suivant la première instruction return rencontrée est évaluée...
5. ...et retournée comme résultat de l’appel :
cette valeur remplace l’expression de l’appel, i.e. l’expression
f(arg1, ..., argN)
34
Évaluation de l’appel d’une fonction
35
L’évaluation de l’appel d’une fonction peut être schématisé de la
façon suivante :
35
Évaluation de l’appel d’une fonction
36
L’évaluation de l’appel d’une fonction s’effectue de la façon suivante :
1. Les expressions passées en argument sont évaluées
2. Les valeurs correspondantes sont affectées aux paramètres de la
fonction
3. Le corps de la fonction est exécuté
4. L’expression suivant la première instruction return rencontrée est
évaluée...
5. ...et retournée comme résultat de l’appel :
cette valeur remplace l’expression de l’appel.
36
37
Appel de fonctions
Une fonction peut appeler une autre fonction.
Il faut simplement respecter la règle d’or : avoir prototypé la
fonction avant l’appel.
Exemple:
int score (double points, double tempsJeu);
void afficherScore (int joueur, double points, double tempsJeu);
void afficherScore(int joueur, double points, double temps)
{
cout << " Joueur " << joueur << score(points, temps) << " points" << endl;
}
int score (double points, double tempsJeu){
// Mettre le corps de la fonction score ici
}
37
Les fonctions et leurs déclarations
1. Les différentes façons de déclarer une fonction
float nomDeLaFonction(float x, int k, int l) // définition de la fonction
{
bloc d’instructions;
}
int main() // fonction main()
{
float nomDeLaFonction(float x, int k, int l) ; // prototype de la fonction
// ou float nomDeLaFonction(float, int, int) ;
.....
y = nomDeLaFonction(x, n, p) ; // appel de la fonction
.....
return 0;
}
3838
Les fonctions et leurs déclarations
2. Les différentes façons de déclarer une fonction
int main(){// fonction main()
float nomDeLaFonction(float x, int k, int l) ; // prototype de nomDeLaFonction
// ou float nomDeLaFonction(float, int, int) ;
.....
y = nomDeLaFonction (x, n, p) ; // appel de la fonction
.....
return 0;
}
// Définition de la fonction nomDeLaFonction
float nomDeLaFonction(float x, int k, int l){
bloc d’instructions;
}
3939
Les fonctions et leurs déclarations
3. Les différentes façons de déclarer une fonction
Il est également possible d’utiliser des déclarations globales, en
les faisant apparaître avant la définition de la première fonction.
4040
Les fonctions et leurs déclarations
3. Les différentes façons de déclarer une fonction
float nomDeLaFonction(float x, int k, int l) ; //prototype de nomDeLaFonction
// ou float nomDeLaFonction(float, int, int) ;
int main(){// fonction main()
.....
y = nomDeLaFonction (x, n, p) ; // appel de la fonction
.....
}
// Définition de la fonction nomDeLaFonction
float nomDeLaFonction(float x, int k, int l)
{
bloc d’instructions;
}
4141
Les fonctions et leurs déclarations
3. Les différentes façons de déclarer une fonction
float nomDeLaFonction(float, int, int ) ; //prototype de nomDeLaFonction
int main(){
.....
y = nomDeLaFonction(x, n, p) ; // appel de la fonction
.....
return 0;
}
void fct(…)
{
.....
}
La déclaration de nomDeLaFonction est connue à la fois de main et de fct.
4242
Les fonctions et leurs déclarations
Remarque:
Le prototype de la fonction doit correspondre exactement à la
définition, il n’est pas permis de changer d’avis en cours de route :
int f(int a, float x); // prototype
// autres...
int f(long a, float x) // erreur ! différent du prototype
{
//corps de la fonction
}
4343
44
Passage des arguments par valeur
CONCEPT:
Lorsqu'un paramètre est passé en argument, seule une copie de la
valeur du paramètre s’est passé.
Les modifications apportées à l'argument n'affectent pas le paramètre
original.
Les modifications effectuées à l’intérieur de la fonction ne sont donc
pas répercutées à l’extérieur de la fonction.
45
Passage des arguments par valeur
Prenons une fonction simple qui multiplie simplement par 2 l'argument
fourni:
int multiplierParDeux(int x)
{
x* = 2;
return x;
}
46
Passage des arguments par valeur
Exemple 1:
Testons donc cette fonction:
#include <iostream>
using namespace std;
int multiplierParDeux(int x){//définition de la fonction: multiplierParDeux()
x *= 2;
return x;
}
int main(){
int nombre(2), resultat;
resultat = multiplierParDeux(nombre); //appel de la fonction: multiplierParDeux()
cout << "Le nombre original vaut : " << nombre << endl;
cout << "Le résultat vaut : " << resultat << endl;
return 0;
}
47
Passage des arguments par valeur
Ce code donne le résultat suivant:
Le nombre original vaut : 2
Le résultat vaut : 4
47
48
Passage des arguments par valeur
Lors de l'appel à la fonction, il se passe énormément de choses :
1. Le programme évalue la valeur de nombre. Il trouve 2.
2. Le programme alloue un nouvel espace dans la mémoire et y écrit
la valeur 2. Cet espace mémoire possède l'étiquette x, le nom de la
variable dans la fonction.
3. Le programme entre dans la fonction.
4. Le programme multiplie la variable x par 2.
5. La valeur de x est ensuite copiée et affectée à la variable resultat,
qui vaut donc maintenant 4.
6. On sort alors de la fonction.
48
49
Passage des arguments par valeur
Il est important de noter que la variable nombre est copiée dans
une nouvelle case mémoire.
Il est à noter également que la valeur de la variable nombre reste
inchangée.
On dit que l'argument nombre est passé par valeur.
La valeur de retour (lorsqu’elle existe) est elle aussi transmise par
valeur, c’est-à-dire qu’elle fait l’objet d’une recopie de la fonction
appelée dans la fonction appelante.
Par défaut, les arguments d’une fonction sont transmis par
valeur.
Ce mode de transmission ne permet pas à une fonction de modifier
la valeur d’un argument.
49
50
Passage des arguments par valeur
Exemple 2:
Voyez cet deuxième exemple :
#include <iostream>
using namespace std;
void changeMoi(int); //prototype de la fonction:
int main(){
int nombre(12);
cout << "La valeur de nombre est " << nombre << endl;
changeMoi(nombre);
cout << "Retournons à la fonction main encore une fois, la valeur de ";
cout << "nombre est " << nombre << endl;
return 0;
}
void changeMoi(int maValeur){//définition de la fonction
maValeur = 0;
cout << " Maintenant la valeur est " << maValeur << endl;
}
50
51
Passage des arguments par valeur
Exemple 2:
Sortie du programme
La valeur de nombre est 12
Maintenant la valeur est 0
Retournons à la fonction main encore une fois, la valeur de nombre est 12
51
52
Passage des arguments par valeur
Exemple 3:
Voyez cet troisième exemple :
#include <iostream>
using namespace std ;
void echanger(int a, int b) ;
int main (){
int n(10), p(20) ;
cout << "Avant appel : " << n << " " << p << endl;
echanger(n, p) ;
cout << "Après appel : " << n << " " << p << endl ;
}
void echanger(int a, int b){
int temporaire (a) ;
cout << "Début échange dans la fonction : "<< a << " " << b << endl ;
a = b ;
b = temporaire ;
cout << "Fin échange dans la fonction : " << a << " " << b << endl ;
}
52
53
Passage des arguments par valeur
53
Ce code affiche :
Avant appel : 10 20
Début échange dans la fonction : 10 20
Fin échange dans la fonction : 20 10
Après appel : 10 20
54
Passage des arguments par référence
54
CONCEPT:
Lorsqu'il est utilisé en tant que paramètres, les variables de
référence permettent d'accéder à l’argument initial du paramètre
d’une fonction.
Les modifications apportées au paramètre sont également faite à
l'argument.
Une modification effectuée à l’intérieur de la fonction se répercute
alors à l’extérieur de la fonction.
55
Passage des arguments par référence
55
Au lieu de copier la valeur de nombre dans la variable x, il est
possible d'ajouter une « deuxième étiquette » à la variable nombre
à l'intérieur de la fonction.
Il faut utiliser dans ce cas une référence comme argument de la
fonction.
La référence d’une variable = son adresse mémoire.
56
Passage des arguments par référence
56
Une variable de référence est un alias pour une autre variable.
Toutes les modifications apportées à la variable de référence sont
réellement effectué sur la variable pour laquelle il est un alias.
En utilisant une variable de référence en tant que paramètre, une
fonction peut modifier une variable qui est définie dans une autre
fonction.
Les variables de référence sont définies comme des variables
ordinaires, sauf que vous placez une esperluette (&) devant le
nom; par exemple: double & x.
57
Passage des arguments par référence
57
Exemple 1: Noter la présence de &
int multiplierParDeux(int & x)
{
x* = 2;
return x;
}
La notation int & x signifie que x est une information de type int
transmise par référence.
N.B: La variable x est appelée "une référence à un int."
58
Passage des arguments par référence
58
Lorsque l'on appelle la fonction, il n'y a plus de copie. Le
programme donne simplement un alias à la variable nombre.
Dans ce cas, les deux variables x et nombre sont confondues.
On dit que l'argument nombre est passé par référence.
59
Passage des arguments par référence
59
Exemple 1:
Testons maintenant cette fonction:
#include <iostream>
using namespace std;
int multiplierParDeux(int &x){//définition de la fonction: multiplierParDeux()
x *= 2;
return x;
}
int main(){
int nombre(2), resultat;
cout << "Avant appel, nombre est " << nombre << endl;
resultat = multiplierParDeux(nombre); //appel de la fonction: multiplierParDeux()
cout << "Le nombre original vaut : " << nombre << endl;
cout << "Le résultat vaut : " << resultat << endl;
return 0;
}
60
Passage des arguments par référence
60
Cela donne comme résultat:
Avant appel, nombre est 2
Le nombre original vaut : 4
Le résultat vaut : 4
Comme les deux variables x et nombre correspondent à la même
case mémoire, faire x*=2 a modifié la valeur de nombre!
Utiliser des références peut donc être très dangereux. C'est pour
cela qu'on ne les utilise que lorsqu'on en a réellement besoin.
Passage des arguments par référence
Exemple 1:
Remarque:
Le paramètre x "pointe " à la valeur de la variable dans la fonction
main.
Quand un programme travaille avec une variable de référence,
il travaille en fait avec la variable qui référence ou qui pointe sur.
6161
62
Passage des arguments par référence
Exemple 2:
Voyez cet deuxième exemple en utilisant les références:
#include <iostream>
using namespace std ;
void echanger(int& , int&) ; // prototype de la fonction
int main (){
int n(10), p(20) ;
cout << "Avant appel : " << n << " " << p << endl;
echanger(n, p) ; // appel de la fonction: attention, ici pas de &n, &p
cout << "Après appel : " << n << " " << p << endl ;
}
void echanger(int& a, int& b){// définition de la fonction
int temporaire (a) ;
cout << "Début échange dans la fonction : "<< a << " " << b << endl ;
a = b ;
b = temporaire ;
cout << "Fin échange dans la fonction : " << a << " " << b << endl ;
}
62
63
Passage des arguments par référence
63
Cela affiche :
Avant appel : 10 20
Début échange dans la fonction : 10 20
Fin échange dans la fonction : 20 10
Après appel : 20 10
Les valeurs des deux variables ont été échangées.
64
Passage des arguments par référence
64
Appel de fonction
Lors de l’appel d’une fonction recevant un argument par
référence, seules les variables peuvent être passés par référence.
Si vous essayez de passer un argument non variable, comme une
constante ou une expression, dans un paramètre de référence, une
erreur se produit.
La transmission par référence impose à un argument effectif
d’être une lvalue du type prévu pour l’argument muet.
65
Passage des arguments par référence
65
Appel de la fonction
Exemple:
void f (int &) ; // f reçoit la référence à un entier
.....
const int n(5) ;
int p ;
f(p) ; // OK
f(3*p+2) ; // erreur : 3*p+2 n’est pas une lvalue
f(4) ; // erreur : 4 n’est pas modifiable
f(n) ; // erreur : n n’est pas modifiable
.....
float y ;
f(y) ; // erreur : y n’est pas de type int
66
Passage des arguments par référence
66
Cas d’un argument muet constant
Il est possible de transmettre par référence une constante, comme
dans ce prototype :
void fct(const int & n) ;
Dans ce cas, la fonction fct s’attend à recevoir l’adresse d’une
constante et elle ne devra pas, dans sa définition, modifier la
valeur de n ; dans le cas contraire, on obtiendra une erreur de
compilation.
67
Passage des arguments par référence
67
Cas d’un argument muet constant
Cette fois, les appels suivants seront corrects :
const int c(5) ;
.....
fct(3) ; // correct ici
fct(c) ; // correct ici
fct(exp); //exp: une expression quelconque acceptée quel que soit son type
float x ;
.....
fct(x) ; // correct : fct reçoit la référence à une variable temporaire
// contenant le résultat de la conversion de x en int
68
Passage par référence constante
68
Imaginez une fonction recevant en argument un string.
Le passage par référence offre un gros avantage sur le passage par
valeur : aucune copie n'est effectuée.
Un passage par référence, aucune copie n'est effectuée. Mais il
autorise la modification de l'argument.
void fonctionChaine(string texte) //Implique une copie coûteuse de 'texte'
{
}
void fonctionChaine(string& texte) //Implique que la fonction peut modifier 'texte'
{
}
69
Passage par référence constante
69
La solution est d'utiliser ce que l'on appelle un passage par référence
constante.
Il nous permet d’éviter la copie en utilisant une référence.
Il empêche la modification de l'argument en le déclarant constant.
Voici la syntaxe:
void fonctionChaine (string const& texte)//Pas de copie et pas de modification possible
{
}
Variables globales et locales
Une variable locale est définie à l'intérieur d'une fonction et n'est pas
accessible à l'extérieur de la fonction.
Une variable globale est définie à l'extérieur de toutes les fonctions
et est accessible à toutes les fonctions dans son étendue.
7070
Variables locales
Les variables définies à l'intérieur d'une fonction sont locales à
cette fonction.
Ils sont cachés des déclarations des autres fonctions qui normalement
ne peuvent pas les accéder.
7171
Variables locales
Exemple:
#include <iostream>
using namespace std;
void autreFonction(); //prototype
int main(){
int nbre(1); //variable locale
cout << " Dans la fonction main, nbre est " << nbre << endl;
autreFonction(); //appel de fonction
cout << " Retour à la fonction main, nbre est " << nbre << endl;
return 0;
}
void autreFonction(){ //définition de fonction
int nbre(20); // variable locale
cout << " Dans la fonction autreFonction, nbre est " << nbre << endl;
}
7272
Variables locales
Sortie du programme
Dans la fonction main, nbre est 1
Dans la fonction autreFonction, nbre est 20
Retour à la fonction main, nbre est 1
7373
Variables locales
Schéma explicatif
7474
Portée des variables locales
Les variables locales d'une fonction existent seulement pendant son
exécution.
Quand la fonction commence, ses variables locales et ses variables
paramètres sont créées dans la mémoire, et quand la fonction
termine, les variables locales et variables paramètres sont détruites.
Cela veut dire que toute valeur stockée dans une variable locale est
perdu entre appels à la fonction.
7575
Variables globales
Une variable globale est toute variable définie à l'extérieur de toutes
les fonctions dans un programme.
La portée d'une variable globale est tout le programme .
Cela veut dire qu'une variable globale peut être accédée par toutes les
fonctions qui sont définies après que la variable globale soit définie.
7676
Variables globales
Remarque:
Les variables globales sont initialisés par zéro automatiquement.
7777
Variables globales
Exemple 1:
#include <iostream>
using namespace std;
void autreFonction(); //prototype
int nbre(2); //variable globale
int main(){
cout << " Dans la fonction main, nbre est " << nbre << endl;
autreFonction(); //appel de fonction
cout << " Retournons dans la fonction main, nbre est " << nbre<< endl;
return 0;
}
void autreFonction(){ //définition de fonction
cout << " Dans la fonction autreFonction, nbre est " << nbre << endl;
nbre = 50;
cout << " Mais, maintenant sa valeur est changée à " << nbre << endl;
}
7878
Variables globales
Output:
Dans la fonction main, nbre est 2
Dans la fonction autreFonction, nbre est 2
Mais, maintenant sa valeur est changée à 50
Retournons dans la fonction main, nbre est 50
7979
Variables globales constantes
Exemple 2:
#include <iostream>
using namespace std;
void autreFonction(); //prototype
const int nbre (2); //constante globale
int main(){
cout << " Dans la fonction main, nbre est " << nbre << endl;
autreFonction(); //appel de fonction
cout << " Retournons dans la fonction main, nbre est " << nbre << endl;
return 0;
}
void autreFonction() { //définition de fonction
cout << " Dans la fonction autreFonction, nbre est " << nbre << endl;
nbre = 50; //erreur
cout << " Mais, maintenant sa valeur est changée à " << nbre << endl;
}
8080
Variables globales et locales portant même nom
Vous ne pouvez pas avoir deux variables locales avec le même nom
dans la même fonction.
Même remarque pour une variable paramètre et une variable locale
dans la même fonction.
Cependant, vous pouvez avoir une variable locale ou un paramètre
avec le même nom comme une variable globale, ou une constante
globale.
8181
Variables globales et locales portant même nom
Exemple
#include <iostream>
using namespace std;
void autreFonction(); //prototype
const int nbre(2); //constante globale
int main(){
int nbre(5); //variable locale
cout << " Dans la fonction main, nbre est " << nbre << endl;
autreFonction(); //appel de fonction
cout << " Retour dans la fonction main, nbre est " << nbre << endl;
return 0;
}
void autreFonction(){ //définition de fonction
cout << " Dans la fonction autreFonction, nbre est " << nbre << endl;
int nbre(50);
cout << " Mais, maintenant sa valeur est changée à " << nbre << endl;
}
8282
Variables globales et locales portant même nom
Sortie du programme
Dans la fonction main, nbre est 5
Dans la fonction autreFonction, nbre est 2
Mais, maintenant sa valeur est changée à 50
Retour dans la fonction main, nbre est 5
8383
Variables locales statiques
Si une fonction est appelée plusieurs fois dans un programme, les
valeurs stockées dans les variables locales ne sont pas conservées
entre les appels de fonction.
C'est parce que les variables locales sont détruites lorsque la fonction
se termine, puis sont recréés lorsque la fonction recommence.
8484
Variables locales statiques
Exemple 1:
Ce programme montre que les variables locales ne conservent pas leurs valeurs
entre les appels de fonction.
#include <iostream>
using namespace std;
void montrerVariableLocale(); //prototype
int main(){
montrerVariableLocale(); //1er appel de la fonction
montrerVariableLocale(); //deuxième appel de la fonction
return 0;
}
void montrerVariableLocale(){ //définition de la fonction
int nbreLocal(5); //variable locale
cout << " nbreLocal est " << nbreLocal << endl;
nbreLocal = 99;
}
8585
Variables locales statiques
Sortie du programme :
nbreLocal est 5
nbreLocal esr 5
8686
Variables locales statiques
Les variables locales statiques ne sont pas détruites lors d'un retour
de la fonction.
Ils existent pour la durée du programme, même si leur portée est
seulement la fonction dans laquelle elles sont définies.
Comme les variables globales, les variables locales statiques sont
initialisés à zéro par défaut.
8787
Variables locales statiques
Exemple:
static double x (4.5); // déclaration de la variable statique x
const int MAX(5) ; // déclaration de la constante MAX
static int limit(3*MAX + 1); // 3*MAX+1 est une expression constante
static short X(50) ; // 50 de type int est converti en short int
static float Y(3) ; // 3 de type int est converti en float
static long Z(7.5) ; // 7.5 de type float est converti en long (déconseillé)
8888
Variables locales statiques
Exemple 2 : ce programme utilise une variable locale statique
#include <iostream>
using namespace std;
void montrerVarStatique();
int main(){
for (int compteur(0); compteur < 5; compteur ++)
montrerVarStatique();
return 0;
}
void montrerVarStatique(){
static int nbreStat;
cout << " nbreStat est " << nbreStat << endl;
nbreStat ++;
}
8989
Variables locales statiques
Sortie du programme :
nbreStat est 0
nbreStat est 1
nbreStat est 2
nbreStat est 3
nbreStat est 4
9090
Variables locales statiques
Exemple 3 : ce programme utilise une variable locale statique
#include <iostream>
using namespace std;
void montrerVarStatique();
int main(){
for (int compteur(0); compteur < 5; compteur ++)
montrerVarStatique();
return 0;
}
void montrerVarStatique(){
static int nbreStat(5);
cout << " nbreStat est " << nbreStat << endl;
nbreStat ++;
}
9191
Variables locales statiques
Sortie du programme :
nbreStat est 5
nbreStat est 6
nbreStat est 7
nbreStat est 8
nbreStat est 9
9292
Variables locales statiques
Même si la déclaration qui définit nbreStat, est initialisée à 5,
l'initialisation ne se produit pas à chaque fois que la fonction est
appelée.
Si c'était le cas, la variable ne serait pas en mesure de conserver sa
valeur entre les appels de fonction.
9393
Variables locales à un bloc
C++ permet de déclarer des variables locales à un bloc.
Leur portée est limitée à ce bloc.
Leur emplacement est alloué à l’entrée dans le bloc et il disparaît à
la sortie.
9494
Variables locales à un bloc
Exemple:
void f(){
int n ; //n est accessible de tout le bloc constituant f
.....
for (...){
int p ; // p n’est connue que dans le bloc de for
int n ; // n masque la variable n de portée "englobante"
..... // attention, on ne peut pas utiliser ::n ici qui désignerait une variable globale (inexistante ici)
}
.....
{
int p ; // p n’est connue que dans ce bloc ; elle est allouée ici
..... // et n’a aucun rapport avec la variable p ci-dessus
} // et elle sera désallouée ici
.....
}
9595
96
Valeurs par défaut pour les arguments
96
CONCEPT:
Les arguments par défaut sont passées aux paramètres
automatiquement si aucun argument n'est fourni dans l'appel de
fonction.
Les arguments par défaut sont généralement indiquées dans le
prototype de fonction.
Il n’est alors pas nécessaire de fournir d’argument à ces
paramètres avec valeurs par défaut lors de l’appel de la fonction.
97
Valeurs par défaut pour les arguments
97
CONCEPT:
La syntaxe d’un paramètre avec valeur par défaut est :
type identificateur = valeur
Voici un exemple:
void montrerAire(double longueur = 20.0, double largeur = 10.0);
void montrerAire(double = 20.0, double = 10.0);
98
Valeurs par défaut pour les arguments
98
On peut donner des valeurs par défaut à certains paramètres des
fonctions.
Lorsqu'on appelle une fonction, on ne sera pas obligé d'indiquer à
chaque fois tous les paramètres.
Rendre certains paramètres des fonctions facultatifs en modifiant
le prototype de la fonction (et non sa définition, attention).
Valeurs par défaut pour les arguments
Voici la définition de la fonction :
void montrerAire(double longueur, double largeur)
{
double aire(longueur * largeur);
cout << " L’aire est " << aire << endl;
}
9999
Valeurs par défaut pour les arguments
Voici l’appel de la fonction :
Parce que les deux paramètres ont des arguments par défaut, elles
peuvent éventuellement être omis dans l'appel de fonction, comme
indiqué ici:
montrerAire(); //appel sans argument
Sortie de la fonction :
L’aire est 200
100100
Valeurs par défaut pour les arguments
Les appels de la fonction :
1) Dans l'appel ci-dessous, le premier argument est spécifié, mais le second
est omis:
montrerAire(12.0); //appel avec un seul argument
La valeur 12.0 sera transmis à la longueur, tandis que la valeur par
défaut 10.0 seront transmis à largeur.
La sortie de la fonction sera:
L‘aire est 120
101101
Valeurs par défaut pour les arguments
Les appels de la fonction :
1) Bien sûr, tous les arguments par défaut peuvent être remplacés.
Dans l'appel de fonction ci-dessous, les arguments sont fournis
pour les deux paramètres:
montrerAire(12.0, 5.5); //appel normal
La sortie de l'appel de fonction ci-dessus sera:
L‘aire est 66
102102
Valeurs par défaut pour les arguments
Remarque importante :
Si une fonction n‘a pas un prototype, les arguments par défaut
peuvent être spécifiée dans l'en-tête de fonction.
La fonction montrerAire() peut être défini comme suit:
void montrerAire(double longueur = 20.0, double largeur = 10.0)
{
double aire(longueur*largeur);
cout << " L’aire est " << aire << endl;
}
103103
Valeurs par défaut pour les arguments
Attention:
Lorsqu'un argument est omis dans un appel de fonction, tous les
arguments qui viennent après il doit être laissé de côté aussi.
montrerAire( , 10.50); // Appel de fonction illégal.
104104
Valeurs par défaut pour les arguments
Attention:
Lorsqu'une fonction utilise un mélange de paramètres avec et sans
arguments par défaut, le paramètre avec les arguments par défaut
doit être défini en dernier.
Exemple:
Les prototypes suivants sont illégales:
void calculPayement(int numEmp, double heurs = 40.0, double tauxRemun);
void calculPayement(double heurs = 40.0, int numEmp, double tauxRemun);
105105
106
Valeurs par défaut pour les arguments
106
Considérons l’exemple suivant:
int sommeDeDeuxValeurs(int x, int y) // en-tête
{
int total(0);
total = x+y;
return total; // ou directement return x+y;
}
107
Valeurs par défaut pour les arguments
107
Exemple 1:
#include <iostream>
using namespace std;
// Prototype de la fonction
int sommeDeDeuxValeurs(int , int y=5); // prototype avec une valeur par défaut
/* ou int sommeDeDeuxValeurs(int , int =5); */
// Main
int main(){
int n(10), p(20), y1, y2;
y1 = sommeDeDeuxValeurs(n, p); // appel " normal"
y2 = sommeDeDeuxValeurs(n); // appel avec un seul argument
cout << "y1 = " << y1 << " y2 = " << y2 << endl ;
return 0;
}
// Définition de la fonction
int sommeDeDeuxValeurs(int x, int y){
int total(0);
total = x + y;
return total; }
108
Valeurs par défaut pour les arguments
108
Exemple 1:
Output:
y1 = 30 y2 = 15
109
Valeurs par défaut pour les arguments
109
Explication:
La déclaration de sommeDeDeuxValeurs(), est réalisée par le
prototype :
int sommeDeDeuxValeurs(int, int = 5) ;
La déclaration du second argument apparaît sous la forme : int = 5
Elle précise au compilateur que, en cas d’absence de ce second
argument dans un éventuel appel de sommeDeDeuxValeurs, il lui
faudra « faire comme si » l’appel avait été effectué avec cette
valeur.
Notez qu’un appel tel que :
sommeDeDeuxValeurs( )
serait rejeté à la compilation puisque ici il n’était pas prévu de valeur
par défaut pour le premier argument de la fonction.
110
Valeurs par défaut pour les arguments
110
Exemple 2:
#include <iostream>
using namespace std;
// Prototype de la fonction
int sommeDeDeuxValeurs(int =0 , int =5); // prototype avec deux valeurs par défaut
// Main
int main(){
int n(10), p(20), y1, y2, y3;
y1 = sommeDeDeuxValeurs(n, p); // appel " normal"
y2 = sommeDeDeuxValeurs(n); // appel avec un seul argument
y3 = sommeDeDeuxValeurs(); // appel sans argument
cout << "y1 = " << y1 << " y2 = " << y2 << " y3 = " << y3 << endl ;
return 0;
}
// Définition de la fonction
int sommeDeDeuxValeurs(int x, int y){
int total(0);
total = x + y;
return total;}
111
Valeurs par défaut pour les arguments
111
Exemple 2:
Output:
y1 = 30 y2 = 15 y3 = 5
112
Les propriétés des arguments par défaut
112
Les valeurs par défaut sont spécifiées uniquement dans le
prototype, pas dans la définition de la fonction.
Les valeurs par défaut doivent obligatoirement apparaître en
dernier dans la liste des paramètres d’une fonction (c'est-à-dire à
droite).
Le compilateur analyse les paramètres de gauche à droite.
113
Les propriétés des arguments par défaut
113
Exemple:
1. float f(int = 10, long, int = 5) ; // déclaration interdite
2. sommeDeDeuxValeurs(3, , 5); //on ne peut pas « sauter » des
//paramètres, même s'ils sont facultatifs.
114
Récursivité
114
Une fonction est dite récursive si elle s’appelle elle-même.
C++ autorise la récursivité des appels de fonctions.
Elle peut prendre deux aspects :
récursivité directe : une fonction comporte, dans sa définition, au
moins un appel à elle-même;
récursivité croisée : l’appel d’une fonction entraîne celui d’une
autre fonction qui, à son tour, appelle la fonction initiale (le cycle
pouvant d’ailleurs faire intervenir plus de deux fonctions).
115
Récursivité
115
Un programme récursif se compose de deux parties:
Au moins une condition d’arrêt des appels récursifs, où les
valeurs à déterminer sont immédiatement connues.
Un appel récursif. La fonction s’appelle elle-même, dans un
autre environnement.
116
Récursivité
116
La structure d’une fonction récursive
typeDeValeurRetour fonctionRecursive(liste des paramètres)
{
if (condition d‘arrêt) //condtion d‘arrêt et de retour
{
return (…);
}
else
{ //appel récursif
return (fonctionRecursive(liste des nouveaux paramètres));
}
117
Récursivité
117
Exemple 1:
long facto(int n)
{
if (n>1) return (facto(n-1)*n) ;
else return(1) ;
}
118
Récursivité
118
Exemple 2: la suite de Fibonacci
U0 = 0;
U1 = 1;
Un = Un-1 + Un-2, pour tout entier n tel que n>=2;
119
Récursivité
119
Exemple 2: la suite de Fibonacci
int Fibonacci(int n)
{
if (n == 0) //première condition d‘arrêt et de retour
return 0; // cas où n=0
else if (n == 1) // seconde condition d‘arrêt et de retour
return 1; //cas où n=1
else
return (Fibonacci(n-1) + Fibonacci (n-2));
//appel récursif en utilisant la formule
}
120
Récursivité
120
Exemple 3: système des suites réccurentes
U0 = 1/2;
V0 = -3/2;
Un = Un-1 + Vn-1, pour tout entier n tel que n>=1;
Vn = 2Un-1 + Vn-1, pour tout entier n tel que n>=1;
121
Récursivité
121
Exemple 3: système des suites réccurentes
double V(int n); //prototype de la fonction récursive V(n)
double U(int n){ //défintion de la fonction récursive U(n)
if (n == 0) //condition d‘arrêt et de retour
return 1./2.; // cas où n=0
else
return (U(n-1) + V(n-1)); //appel récursif en utilisant la formule
}
double V(int n){ //défintion de la fonction récursive V(n)
if (n == 0)
return -3./2.;
else
return (2*U(n-1) + V(n-1));
}
122
Fonctions inline
122
Pour de petites fonctions, il peut être plus efficace d’éviter un
appel de fonction et à la place, expanser le corps de la fonction en
lieu et place de chaque appel.
C’est possible avec le mot-clé inline.
inline int max(int a, int b =0) //défintion de la fonction inline max
{
if (a>b) return a ;
else return b ;
}
123
Fonctions inline
123
Exemple:
inline int max(int a, int b =0); // prototype de la fonction inline max
int main(){
cout << max(10,5) << endl; // appel de la fonction inline max
return 0;
}
inline int max(int a, int b =0) //défintion de la fonction inline max
{
if (a>b) return a ;
else return b ;
}
En règle générale, les fonctions inline sont donc des fonctions très
courtes que l'on est susceptible de réutiliser souvent, comme c'est
le cas de la fonction max ici.
Surcharge (ou surdéfinition) de fonctions
CONCEPT:
Deux ou plusieurs fonctions peuvent avoir le même nom, à condition
que leurs listes de paramètres soient différents: nombre ou types de
paramètres différents.
Ce mécanisme est appelé surcharge (ou surdéfinition ) des
fonctions.
124124
Surcharge (ou surdéfinition) de fonctions
Exemple:
Ce programme utilise des fonctions surchargées.
#include<iostream>
#include<iomanip>
using namespace std;
int square(int);
double square(double);
int main(){
int intUtilisateur;
double floatUtilisateur;
// Saisir un int et un double.
cout << fixed << showpoint << setprecision(2);
cout << "Entrer un entier et une valeur flottante: ";
cin >> intUtilisateur >> floatUtilisateur;
// Afficher leurs carrés.
cout << "Voici leurs carrés: ";
cout << square(intUtilisateur) << " et " << square(floatUtilisateur);
return 0;
}
125125
Surcharge (ou surdéfinition) de fonctions
int square(int nombre)
{
return nombre*nombre;
}
double square(double nombre)
{
return nombre*nombre;
}
126126
Surcharge (ou surdéfinition) de fonctions
Sortie du programme
Entrer un entier et une valeur flottante: 12 4.2
Voici leurs carrés: 144 et 17.64
127127
Surcharge (ou surdéfinition) de fonctions
Voici les en-têtes des fonctions carrés:
int square(int nombre)
double square(double nombre)
128128
Surcharge (ou surdéfinition) de fonctions
Signature de la fonction
La signature de la fonction est le nom de la fonction et les types de
données des paramètres de la fonction dans le bon ordre.
Les fonctions carrés auraient les signatures suivantes:
square(int)
square(double)
129129
Surcharge (ou surdéfinition) de fonctions
Remarque:
Les fonctions suivantes ne pouvaient pas être utilisés dans le même
programme parce que leurs listes de paramètres ne sont pas différents.
int square(int nombre)
{
return nombre * nombre;
}
double square(int nombre) //Faux! Les listes de paramètres doivent être différent
{
return nombre * nombre;
}
130130
Fonctions génériques
Fonction template:
template<typename T> //sans ;
T sum(T a, T b){
return a+b;
}
int main(){
cout << sum(3,4) << endl; //le compilateur détecte automatique le type des paramètres
cout << sum(3.7,4.8) << endl;
cout << sum<int>(3.7,4.8) << endl; //on spécifie le type à utiliser
return 0; }
Output:
7
8.5
7
131131
La fonction exit()
CONCEPT:
La fonction exit() met fin l’exécution d’un programme, quel que soit
la fonction ou le mécanisme de contrôle qui est en cours d'exécution.
132132
La fonction exit()
Exemple:
#include <iostream>
#include <cstdlib> // Pour exit
using namespace std;
void fonction(); // Prototype
int main(){
fonction(); //Appel de fonction
return 0;
}
void fonction(){ //Définition de fonction
cout << " Ce programme se termine avec la fonction exit. " << endl;
cout << "Bye!" << endl;
exit(0);
cout << " Ce message ne sera pas affiché" << endl;
cout << " Car le programme a déjà terminé." << endl;
}
133133
La fonction exit()
Sortie du programme
Ce programme termine avec la fonction exit.
Bye!
134134
Utilisez plusieurs fichiers
Le langage C++ permet de découper son programme en plusieurs
fichiers sources.
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.
On a ainsi réellement des briques séparées utilisables pour
construire différents programmes.
135135
Utilisez plusieurs fichiers
Les fichiers nécessaires
Pour cela, il faut deux fichiers :
un fichier source dont l'extension est .cpp: il contient le code
source de la fonction, ce qu'on appelle la définition de la fonction.
un fichier d'en-tête dont l'extension est .h: il contient uniquement
le prototype de la fonction.
136136
Utilisez plusieurs fichiers
Le fichier source:
1. Pour le créer, il suffit de passer par les menus: File>New>File.
2. Choisir ensuite C/C++ source.
3. Cliquer ensuite sur Go.
4. Finalement, donner un nom à ce fichier, par exemple finance.cpp
137137
Utilisez plusieurs fichiers
Le fichier d'en-tête:
1. Pour le créer, il suffit de passer également par les menus:
File>New>File.
2. Sélectionner ensuite C/C++ header.
3. Indiquer ensuite le nom du fichier. Il vaut mieux de lui donner le
même nom qu'au fichier source mais avec une extension .h au
lieu de.cpp. Dans notre cas, finance.h
138138
Utilisez plusieurs fichiers
Exemple 1/3:
Le fichier source : finance.cpp
#include "finance.h"
float ROI(float c, float g)
{
return ;
}
139139
Utilisez plusieurs fichiers
Exemple 2/3:
Le fichier d'en-tête : finance.h
#ifndef FINANCE_H_INCLUDED
#define FINANCE_H_INCLUDED
float ROI(float c, float g); //le prototype de la fonction
#endif // FINANCE_H_INCLUDED
140140
Utilisez plusieurs fichiers
Exemple 3/3:
#include <iostream>
#include "finance.h"
using namespace std;
int main()
{
float c, g, r;
cout << "Coûts de l'investissement: " << c << endl;
cout << "Gains de l'investissement: " << g << endl;
r = ROI(c,g); //Appel de la fonction
cout << "Le ROI est : " << r << endl;
return 0;
}
141141
142
Quiz
142
1. Est ce le suivant une entête de fonction ou un appel de fonction?
calculerTotal();
2. Est ce le suivant une entête de fonction ou un appel de fonction?
void afficheResultats()
3. Indiquez lequel des énoncés suivants est le prototype de fonction,
l’entête de fonction, et appel de fonction:
void montrerNumerique(double num)
void montrerNumerique(double);
montrerNumerique(45.67);
4. Il y a une erreur dans ce programme ?
void afficheValeur(int x);
int main(){
int y(3);
afficheValeur(y); //Appel fonction afficheValeur
afficheValeur(int x); //Appel fonction afficheValeur
afficheValeur(3+4); //Appel fonction afficheValeur
}
143
Quiz
143
5. Que produira ce programme si l’utilisateur saisit 10?
#include<iostream>
using namespace std;
void fonction1(){
cout << " Hellon";
}
void fonction2(){
cout << "Bonjourn";
}
void main(){
int input;
cout << "Entrer un nombre: "; cin >> input;
if (input < 10){
fonction1();
fonction2();
}
else{
fonction2();
fonction1();
}
return 0; }
144
Q & A
144
Exercices de cours
Exercice 1
1. Écrire une fonction nommée tempsDix(). La fonction doit avoir un
paramètre entier appelé nombre. Lorsque tempsDix() est appelée,
elle doit présenter le produit de dix fois le nombre.
2. Donner le prototype de la fonction tempsDix().
145145
Exercices de cours
Exercice 2
Écrire une fonction récursive qui calcule la puissance xn.
Exercice 3
Écrire une fonction, estPair ayant en paramètre un entier et qui
renvoie un booléen : Vrai si l'entier est pair Faux sinon.
Exercice 4
Écrire une fonction récursive, suite, qui calcule la suite récurrente
suivante:
146146
Références
147
1) http://www.cplusplus.com
2) https://isocpp.org/
3) https://openclassrooms.com/fr/courses/1894236-programmez-avec-le-langage-c
4) https://www.tutorialspoint.com/cplusplus/
5) https://en.cppreference.com
6) Programmer en C++, Claude Delannoy, éditions Eyrolles, 2014.
7) Initiation à la programmation (en C++), Jean-Cédric Chappelier, & Jamila Sam,
coursera, 2019.
8) Introduction à la programmation orientée objet (en C++), Jamila Sam & Jean-Cédric
Chappelier, coursera, 2019.
147

Weitere ähnliche Inhalte

Was ist angesagt?

Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonAbdoulaye Dieng
 
Introduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniIntroduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniShellmates
 
Partie 11: Héritage — Programmation orientée objet en C++
Partie 11: Héritage — Programmation orientée objet en C++Partie 11: Héritage — Programmation orientée objet en C++
Partie 11: Héritage — Programmation orientée objet en C++Fabio Hernandez
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++coursuniv
 
Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Fabio Hernandez
 
Python For Data Science - French Course
Python For Data Science - French CoursePython For Data Science - French Course
Python For Data Science - French CourseHaytam EL YOUSSFI
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage PythonAziz Darouichi
 
Formation python
Formation pythonFormation python
Formation pythonj_lipaz
 
Cours : les listes chainées Prof. KHALIFA MANSOURI
Cours : les listes chainées  Prof. KHALIFA MANSOURI Cours : les listes chainées  Prof. KHALIFA MANSOURI
Cours : les listes chainées Prof. KHALIFA MANSOURI Mansouri Khalifa
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptxLamissGhoul1
 
POO Java Chapitre 6 Exceptions
POO Java  Chapitre 6 ExceptionsPOO Java  Chapitre 6 Exceptions
POO Java Chapitre 6 ExceptionsMouna Torjmen
 

Was ist angesagt? (20)

Chapitre 01 - Notions de base
Chapitre 01 - Notions de baseChapitre 01 - Notions de base
Chapitre 01 - Notions de base
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en Python
 
Chap2fonctionscpp
Chap2fonctionscppChap2fonctionscpp
Chap2fonctionscpp
 
Python avancé : Lecture et écriture de fichiers
Python avancé : Lecture et écriture de fichiersPython avancé : Lecture et écriture de fichiers
Python avancé : Lecture et écriture de fichiers
 
Introduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniIntroduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El Hassani
 
Partie 11: Héritage — Programmation orientée objet en C++
Partie 11: Héritage — Programmation orientée objet en C++Partie 11: Héritage — Programmation orientée objet en C++
Partie 11: Héritage — Programmation orientée objet en C++
 
Cours de c
Cours de cCours de c
Cours de c
 
Introduction à Python
Introduction à PythonIntroduction à Python
Introduction à Python
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++
 
Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++
 
Python For Data Science - French Course
Python For Data Science - French CoursePython For Data Science - French Course
Python For Data Science - French Course
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage Python
 
Chapitre05 : Les tableaux
Chapitre05 : Les tableauxChapitre05 : Les tableaux
Chapitre05 : Les tableaux
 
Formation python
Formation pythonFormation python
Formation python
 
Cours : les listes chainées Prof. KHALIFA MANSOURI
Cours : les listes chainées  Prof. KHALIFA MANSOURI Cours : les listes chainées  Prof. KHALIFA MANSOURI
Cours : les listes chainées Prof. KHALIFA MANSOURI
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptx
 
COURS_PYTHON_22.ppt
COURS_PYTHON_22.pptCOURS_PYTHON_22.ppt
COURS_PYTHON_22.ppt
 
TP C++ : Correction
TP C++ : CorrectionTP C++ : Correction
TP C++ : Correction
 
Langage C#
Langage C#Langage C#
Langage C#
 
POO Java Chapitre 6 Exceptions
POO Java  Chapitre 6 ExceptionsPOO Java  Chapitre 6 Exceptions
POO Java Chapitre 6 Exceptions
 

Ähnlich wie Chapitre2fonctionscppv2019

02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSSAyoubElmrabet6
 
03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdf03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdfAhmed12314
 
Les fonctions.pptx
Les fonctions.pptxLes fonctions.pptx
Les fonctions.pptxsouadsadki2
 
Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Fabio Hernandez
 
Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Fahad Golra
 
Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14Aurélien Regat-Barrel
 
Javascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryJavascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryneuros
 
Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDotNetHub
 
C++11 en 12 exemples simples
C++11 en 12 exemples simplesC++11 en 12 exemples simples
C++11 en 12 exemples simplesPethrvs
 
PL LSQL.pptx
PL LSQL.pptxPL LSQL.pptx
PL LSQL.pptxMaNl13
 
Chapitre 4 Fonctions et procédures.pdf
Chapitre 4 Fonctions et procédures.pdfChapitre 4 Fonctions et procédures.pdf
Chapitre 4 Fonctions et procédures.pdfC00LiMoUn
 

Ähnlich wie Chapitre2fonctionscppv2019 (20)

02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSS
 
Chapitre 04 : les fonctions
Chapitre 04 : les fonctionsChapitre 04 : les fonctions
Chapitre 04 : les fonctions
 
03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdf03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdf
 
Theme 7
Theme 7Theme 7
Theme 7
 
Ch07
Ch07Ch07
Ch07
 
Les fonctions.pptx
Les fonctions.pptxLes fonctions.pptx
Les fonctions.pptx
 
C4 fonctions
C4 fonctionsC4 fonctions
C4 fonctions
 
Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++
 
Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C
 
Ch04
Ch04Ch04
Ch04
 
Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14
 
Javascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryJavascript ne se limite pas à jquery
Javascript ne se limite pas à jquery
 
Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCL
 
C++11
C++11C++11
C++11
 
POO-chapitre2.pptx
POO-chapitre2.pptxPOO-chapitre2.pptx
POO-chapitre2.pptx
 
C++11 en 12 exemples simples
C++11 en 12 exemples simplesC++11 en 12 exemples simples
C++11 en 12 exemples simples
 
Theme 6
Theme 6Theme 6
Theme 6
 
Ch08
Ch08Ch08
Ch08
 
PL LSQL.pptx
PL LSQL.pptxPL LSQL.pptx
PL LSQL.pptx
 
Chapitre 4 Fonctions et procédures.pdf
Chapitre 4 Fonctions et procédures.pdfChapitre 4 Fonctions et procédures.pdf
Chapitre 4 Fonctions et procédures.pdf
 

Mehr von Aziz Darouichi

Chapitre 2: String en Java
Chapitre 2:  String en JavaChapitre 2:  String en Java
Chapitre 2: String en JavaAziz Darouichi
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaAziz Darouichi
 
Chapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaChapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaAziz Darouichi
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfacesAziz Darouichi
 
Cours Visual Basic.NET
Cours Visual Basic.NETCours Visual Basic.NET
Cours Visual Basic.NETAziz Darouichi
 

Mehr von Aziz Darouichi (9)

Chapitre 2: String en Java
Chapitre 2:  String en JavaChapitre 2:  String en Java
Chapitre 2: String en Java
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en Java
 
Chapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaChapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En Java
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
 
Partie3BI-DW-OLAP2019
Partie3BI-DW-OLAP2019Partie3BI-DW-OLAP2019
Partie3BI-DW-OLAP2019
 
Partie2BI-DW2019
Partie2BI-DW2019Partie2BI-DW2019
Partie2BI-DW2019
 
Partie1BI-DW2019
Partie1BI-DW2019Partie1BI-DW2019
Partie1BI-DW2019
 
Cours Visual Basic.NET
Cours Visual Basic.NETCours Visual Basic.NET
Cours Visual Basic.NET
 
Chapitre3 tableauxcpp
Chapitre3 tableauxcppChapitre3 tableauxcpp
Chapitre3 tableauxcpp
 

Chapitre2fonctionscppv2019

  • 1. Aziz DAROUICHI UCA-Marrakech Mail to: pr.azizdarouichi@gmail.com 1 Programmation Orientée Objet (C++): Les fonctions
  • 2. 2 Notion de fonction Définition de fonction Instruction return Appel de fonction Prototype de fonction La fonction main() Évaluation de l’appel d’une fonction Les fonctions et leurs déclarations Passage des arguments par valeur Passage des arguments par référence Passage par référence constante Variables globales et locales Récursivité Fonctions inline Surcharge (ou surdéfinition) de fonctions La fonction exit() Q & A Notion de fonction Définition de fonction Instruction return Appel de fonction Prototype de fonction La fonction main() Évaluation de l’appel d’une fonction Les fonctions et leurs déclarations Passage des arguments par valeur Passage des arguments par référence Passage par référence constante Variables globales et locales Récursivité Fonctions inline Surcharge (ou surdéfinition) de fonctions La fonction exit() Q & A Programmation procédurale
  • 3. 3 Notion de fonction Fonction Définition: Une fonction est un sous-programme indépendant qui retourne ou non une valeur. Fonction = portion de programme réutilisable ou importante en soi. Une fonction reçoit des informations en entrée, exécute des actions et renvoie un résultat. SortieEntrée Fonction
  • 4. 4 Notion de fonction Plus précisément, une fonction est un objet logiciel caractérisé par : un corps : la portion de programme à réutiliser ou mettre en évidence, qui a justifié la création de la fonction ; il est délimité par des accolades. un nom : par lequel on désignera cette fonction ; des paramètres : (les « entrées », on les appelle aussi « arguments ») ensemble de variables extérieures à la fonction dont le corps dépend pour fonctionner ; un type et une valeur de retour : (la « sortie ») ce que la fonction renvoie au reste du programme.
  • 5. 5 Notion de fonction Les « 3 facettes » d’une fonction Résumé / Contrat (« prototype ») Création / Construction (« définition ») Utilisation (« appel »)
  • 7. 7 Définition de fonction Syntaxe d’une fonction type_valeur_de_retour nom_de_la_fonction(liste des paramètres avec leurs types) { Bloc d‘instructions; // déclarations locales si nécessaire // calcul et retour (avec return) du résultat } N. B: choisir un nom de la fonction qui décrit bien ce qu'elle fait, comme pour les variables.
  • 8. 8 Définition de fonction Exemple 1: Type de la valeur de retour float max(float a, float b) { float plusGrand; if (a<b) plusGrand = b; else plusGrand = a; return plusGrand ; } La première ligne dans la définition, float max(float a, float b), s‘appelle l‘entête de la fonction. Il n'y a pas de point-virgule ! Ni après la déclaration, ni après l'accolade fermante. Nom de la fonction Liste des paramètres avec leurs types Corps de la fonction Valeur de retour
  • 9. 9 Définition de fonction Exemple 2: Une fonction qui reçoit un nombre entier, calcule son carré et le renvoie. int carre(int x) { int y; y = x*x; return y ; }
  • 10. 10 Définition de fonction Exemple 3: plusieurs paramètres Une fonction qui calcule la somme de 2 entiers et la renvoie. int addition(int x, int y) { return x+y; } Une fonction qui calcule le produit des 4 réels et le renvoie. double multiplication(double a, double b, double c, double d ) { return a*b*c*d ; }
  • 11. 11 Définition de fonction Exemple 4: cas des fonctions qui renvoient un booléen Les fonctions peuvent retourner des valeurs booléennes (true ou false). bool estValide(int nombre) { bool statut; if (nombre >= 1 && nombre <= 100) statut = true; else statut = false; return statut; }
  • 12. 12 Définition de fonction Exemple 4: cas des fonctions qui renvoient un booléen Voici un code utilisant cette fonction: int valeur(20); if (estValide(valeur)) cout << "La valeur est dans le domaine." << endl; else cout << "La valeur est hors de domaine." << endl;
  • 14. 14 Instruction Return L’instruction return peut apparaître à plusieurs reprises dans une fonction. Une fonction peut ne renvoyer aucune valeur : elle peut alors disposer de plusieurs instructions return sans expression, interrompant simplement l’exécution de la fonction. La fonction qui ne renvoie aucune valeur peut ne comporter aucune instruction return. Si le type de l’expression de l’instruction return est différent du type de la valeur de retour, le compilateur mettra automatiquement en place des instructions de conversion.
  • 15. 15 Appel de fonction Toute fonction doit être déclarée avant son utilisation. L’utilisation de la fonction dans une autre partie du programme se nomme un appel de la fonction. La syntaxe pour appeler une fonction: résultat = nomDeLaFonction(arguments); L‘appel (avec ou sans paramètres) de la fonction déclenche l‘exécution de son bloc d‘instructions. Une fonction se termine en retournant ou non une valeur.
  • 16. 16 Arguments muets et arguments effectifs Les noms des arguments figurant dans l’en-tête de la fonction se nomment des « arguments muets ». Leur rôle est de permettre, au sein du corps de la fonction, de décrire ce qu’elle doit faire. Les arguments fournis lors de l’appel de la fonction portent quant à eux le nom des « arguments effectifs ». Remarque: Arguments muets= arguments formels = paramètres formels. Arguments effectifs = paramètres effectifs = paramètres réels.
  • 17. 17 Arguments muets et arguments effectifs Les arguments formels sont ceux déclarés avec la fonction : void f(int i, int j, double x) Les paramètres effectifs (ou réels) sont ceux qui sont envoyés au moment de l’appel de la fonction : int k, l; double y; f(k, l, y);
  • 18. 18 Prototype de fonction La déclaration d’une fonction porte le nom de prototype. Toute fonction doit être annoncée avant d’être utilisée : prototype Une fonction ne peut être définie qu’une seule fois dans un programme Elle peut être utilisée autant de fois que nécessaire L’objectif du prototype est d’informer le compilateur du type de la valeur de retour, du nombre de paramètres et du type de chacun Prototype = déclaration de la fonction, sans en définir le corps : nom paramètres type de la valeur de retour
  • 19. 19 Prototype de fonction Syntaxe de déclaration de fonction: type_valeur_de_retour nom_de_la_fonction (type1 param1, ..., typeN paramN ) ; Exemples : double moyenne(double x, double y); int nbHasard(); int score (double points, double temps_jeu); float min(float x, float y); float f(float, int, int);
  • 21. 21 Une fonction peut ne pas renvoyer de résultat ou ne pas avoir d’arguments: s’il n’y a pas de résultat renvoyé : dans l’en-tête de la fonction, on remplace le type de la valeur de retour par le mot clé void s’il n’y a pas d’arguments : dans les parenthèses de l’en-tête de la fonction, on remplace la liste d’arguments et leurs types par rien du tout (parenthèses vides). Fonctions sans valeur de retour ou sans arguments
  • 22. 22 Fonctions sans valeur de retour Syntaxe d’une fonction qui ne renvoie rien void nom_de_la_fonction(liste des paramètres avec leurs types) { Bloc d‘instructions; // déclarations locales si nécessaire // return n’est pas obligatoire } Pour appeler cette fonction il suffit d’écrire: nom_de_la_fonction(liste des paramètres)
  • 23. 23 Fonctions sans valeur de retour Exemple: Voici une fonction qui affiche n fois bonjour: void afficherBonjour(int n) { for(int i(0); i<n;++i) cout << "Bonjour " << endl ; return; // pas obligatoire }
  • 24. 24 Fonctions sans valeur de retour Exemple: fonction affiche n fois bonjour void afficherBonjour(int n) { for(int i(0); i<n;++i) cout << "Bonjour " << endl ; } Dans la fonction main(): int main(){ afficherBonjour(3); //Comme la fonction ne renvoie rien //On l'appelle sans mettre la valeur de retour dans une variable return 0; }
  • 25. 25 Fonctions sans arguments On peut aussi créer des fonctions sans arguments. Il suffit de ne rien écrire entre les parenthèses. Syntaxe [type_de_retour] (ou void) nom_de_la_fonction( ) { Bloc d‘instructions; // déclarations locales si nécessaire // return n’est pas obligatoire si le type de //retour est void } Pour appeler cette fonction il suffit d’écrire: [résultat=]nom_de_la_fonction() Liste des paramètres vide
  • 26. 26 Fonctions sans arguments string afficherNom( ){ string nom("Marrakchi"); cout << "Saisir votre nom : " << endl ; cin >> nom; return nom; } Dans la fonction main(): int main(){ string name; name = afficherNom(); // Comme la fonction renvoie une valeur // On l'appelle en mettant la valeur de retour dans une variable cout << "Votre nom saisi est : " << name << endl ; return 0;} Exemple 1:
  • 27. 27 Fonctions sans arguments Exemple 2: Voici une fonction ne possédant ni argument ni valeur de retour: void afficherBonjour( ) { cout << "Bonjour " << endl ; } Dans la fonction main(): int main(){ afficherBonjour(); //Comme la fonction ne renvoie rien //On l'appelle sans mettre la valeur de retour dans une variable return 0; }
  • 28. 28 Comparaison En-tête de fonction void afficherBonjour( ) Prototype de fonction void afficherBonjour( ); Appel de fonction afficherBonjour( ); Définition de fonction : void afficherBonjour( ) { cout << "Bonjour " << endl ; } Fonctions en C++
  • 29. 29 Remarque: Attention à la syntaxe! int f; : déclaration de variable non initialisée int f(); : prototype de fonction sans paramètre int f(5); : déclaration et initialisation de variable f(5); : appel de fonction à un argument Fonctions en C++
  • 30. 30 Comment on peut réutiliser la même fonction? Calcul des carrés des nombres entre 1 et 10: double carreNombre(double x){ return x*x; } int main(){ for(int i(1); i<=10 ; i++){ cout << "Le carre de " << i << " est : " << carreNombre(i) << endl; } return 0; } Fonctions en C++
  • 31. 31 Comment on peut réutiliser la même fonction? Calcul des carrés des nombres entre 1 et 10: Le carre de 1 est : 1 Le carre de 2 est : 4 Le carre de 3 est : 9 Le carre de 4 est : 16 Le carre de 5 est : 25 Le carre de 6 est : 36 Le carre de 7 est : 49 Le carre de 8 est : 64 Le carre de 9 est : 81 Le carre de 10 est : 100 Fonctions en C++
  • 32. 32 main est aussi une fonction avec un nom et un prototype imposés. Par convention, tout programme C++ doit avoir une fonction main, qui est appelée automatiquement quand on exécute le programme. Cette fonction doit retourner une valeur de type int. La valeur 0 indique par convention que le programme s’est bien déroulé. Les deux seuls prototypes autorisés pour main sont : int main(); int main(int argc, char** argv); La fonction main()
  • 33. 33 Évaluation de l’appel d’une fonction Que se passe-t-il lors de l’appel suivant : z = moyenne( 1.5 + 0.8, 3.4 * 1.25 ); 1. Évaluation des expressions passées en arguments : 1.5 + 0.8 2.3 3.4 * 1.25 4.25 2. Affectation des paramètres : x = 2.3 y = 4.25 3. Exécution du corps de la fonction 4. Évaluation de la valeur de retour (expression de l’instruction return) (x + y) / 2.0 3.275 5. Replacement de l’expression de l’appel par la valeur retournée : z = 3.275; double moyenne (double x, double y) { return (x + y) / 2.0; } 2.3 2.3 x copie
  • 34. 34 Évaluation de l’appel d’une fonction L’évaluation de l’appel f(arg1, ..., argN) d’une fonction définie par typeDeRetour f(type1 x1, ..., typeN xN) { ... } s’effectue de la façon suivante : 1. Les expressions arg1, ..., argN passées en argument sont évaluées 2. Les valeurs correspondantes sont affectées aux paramètres x1,..., xN de la fonction f. Concrètement, ces deux premières étapes reviennent à faire : x1 = arg1, x2 = arg2, ..., xN = argN 3. Le programme correspondant au corps de la fonction f est exécuté 4. L’expression suivant la première instruction return rencontrée est évaluée... 5. ...et retournée comme résultat de l’appel : cette valeur remplace l’expression de l’appel, i.e. l’expression f(arg1, ..., argN) 34
  • 35. Évaluation de l’appel d’une fonction 35 L’évaluation de l’appel d’une fonction peut être schématisé de la façon suivante : 35
  • 36. Évaluation de l’appel d’une fonction 36 L’évaluation de l’appel d’une fonction s’effectue de la façon suivante : 1. Les expressions passées en argument sont évaluées 2. Les valeurs correspondantes sont affectées aux paramètres de la fonction 3. Le corps de la fonction est exécuté 4. L’expression suivant la première instruction return rencontrée est évaluée... 5. ...et retournée comme résultat de l’appel : cette valeur remplace l’expression de l’appel. 36
  • 37. 37 Appel de fonctions Une fonction peut appeler une autre fonction. Il faut simplement respecter la règle d’or : avoir prototypé la fonction avant l’appel. Exemple: int score (double points, double tempsJeu); void afficherScore (int joueur, double points, double tempsJeu); void afficherScore(int joueur, double points, double temps) { cout << " Joueur " << joueur << score(points, temps) << " points" << endl; } int score (double points, double tempsJeu){ // Mettre le corps de la fonction score ici } 37
  • 38. Les fonctions et leurs déclarations 1. Les différentes façons de déclarer une fonction float nomDeLaFonction(float x, int k, int l) // définition de la fonction { bloc d’instructions; } int main() // fonction main() { float nomDeLaFonction(float x, int k, int l) ; // prototype de la fonction // ou float nomDeLaFonction(float, int, int) ; ..... y = nomDeLaFonction(x, n, p) ; // appel de la fonction ..... return 0; } 3838
  • 39. Les fonctions et leurs déclarations 2. Les différentes façons de déclarer une fonction int main(){// fonction main() float nomDeLaFonction(float x, int k, int l) ; // prototype de nomDeLaFonction // ou float nomDeLaFonction(float, int, int) ; ..... y = nomDeLaFonction (x, n, p) ; // appel de la fonction ..... return 0; } // Définition de la fonction nomDeLaFonction float nomDeLaFonction(float x, int k, int l){ bloc d’instructions; } 3939
  • 40. Les fonctions et leurs déclarations 3. Les différentes façons de déclarer une fonction Il est également possible d’utiliser des déclarations globales, en les faisant apparaître avant la définition de la première fonction. 4040
  • 41. Les fonctions et leurs déclarations 3. Les différentes façons de déclarer une fonction float nomDeLaFonction(float x, int k, int l) ; //prototype de nomDeLaFonction // ou float nomDeLaFonction(float, int, int) ; int main(){// fonction main() ..... y = nomDeLaFonction (x, n, p) ; // appel de la fonction ..... } // Définition de la fonction nomDeLaFonction float nomDeLaFonction(float x, int k, int l) { bloc d’instructions; } 4141
  • 42. Les fonctions et leurs déclarations 3. Les différentes façons de déclarer une fonction float nomDeLaFonction(float, int, int ) ; //prototype de nomDeLaFonction int main(){ ..... y = nomDeLaFonction(x, n, p) ; // appel de la fonction ..... return 0; } void fct(…) { ..... } La déclaration de nomDeLaFonction est connue à la fois de main et de fct. 4242
  • 43. Les fonctions et leurs déclarations Remarque: Le prototype de la fonction doit correspondre exactement à la définition, il n’est pas permis de changer d’avis en cours de route : int f(int a, float x); // prototype // autres... int f(long a, float x) // erreur ! différent du prototype { //corps de la fonction } 4343
  • 44. 44 Passage des arguments par valeur CONCEPT: Lorsqu'un paramètre est passé en argument, seule une copie de la valeur du paramètre s’est passé. Les modifications apportées à l'argument n'affectent pas le paramètre original. Les modifications effectuées à l’intérieur de la fonction ne sont donc pas répercutées à l’extérieur de la fonction.
  • 45. 45 Passage des arguments par valeur Prenons une fonction simple qui multiplie simplement par 2 l'argument fourni: int multiplierParDeux(int x) { x* = 2; return x; }
  • 46. 46 Passage des arguments par valeur Exemple 1: Testons donc cette fonction: #include <iostream> using namespace std; int multiplierParDeux(int x){//définition de la fonction: multiplierParDeux() x *= 2; return x; } int main(){ int nombre(2), resultat; resultat = multiplierParDeux(nombre); //appel de la fonction: multiplierParDeux() cout << "Le nombre original vaut : " << nombre << endl; cout << "Le résultat vaut : " << resultat << endl; return 0; }
  • 47. 47 Passage des arguments par valeur Ce code donne le résultat suivant: Le nombre original vaut : 2 Le résultat vaut : 4 47
  • 48. 48 Passage des arguments par valeur Lors de l'appel à la fonction, il se passe énormément de choses : 1. Le programme évalue la valeur de nombre. Il trouve 2. 2. Le programme alloue un nouvel espace dans la mémoire et y écrit la valeur 2. Cet espace mémoire possède l'étiquette x, le nom de la variable dans la fonction. 3. Le programme entre dans la fonction. 4. Le programme multiplie la variable x par 2. 5. La valeur de x est ensuite copiée et affectée à la variable resultat, qui vaut donc maintenant 4. 6. On sort alors de la fonction. 48
  • 49. 49 Passage des arguments par valeur Il est important de noter que la variable nombre est copiée dans une nouvelle case mémoire. Il est à noter également que la valeur de la variable nombre reste inchangée. On dit que l'argument nombre est passé par valeur. La valeur de retour (lorsqu’elle existe) est elle aussi transmise par valeur, c’est-à-dire qu’elle fait l’objet d’une recopie de la fonction appelée dans la fonction appelante. Par défaut, les arguments d’une fonction sont transmis par valeur. Ce mode de transmission ne permet pas à une fonction de modifier la valeur d’un argument. 49
  • 50. 50 Passage des arguments par valeur Exemple 2: Voyez cet deuxième exemple : #include <iostream> using namespace std; void changeMoi(int); //prototype de la fonction: int main(){ int nombre(12); cout << "La valeur de nombre est " << nombre << endl; changeMoi(nombre); cout << "Retournons à la fonction main encore une fois, la valeur de "; cout << "nombre est " << nombre << endl; return 0; } void changeMoi(int maValeur){//définition de la fonction maValeur = 0; cout << " Maintenant la valeur est " << maValeur << endl; } 50
  • 51. 51 Passage des arguments par valeur Exemple 2: Sortie du programme La valeur de nombre est 12 Maintenant la valeur est 0 Retournons à la fonction main encore une fois, la valeur de nombre est 12 51
  • 52. 52 Passage des arguments par valeur Exemple 3: Voyez cet troisième exemple : #include <iostream> using namespace std ; void echanger(int a, int b) ; int main (){ int n(10), p(20) ; cout << "Avant appel : " << n << " " << p << endl; echanger(n, p) ; cout << "Après appel : " << n << " " << p << endl ; } void echanger(int a, int b){ int temporaire (a) ; cout << "Début échange dans la fonction : "<< a << " " << b << endl ; a = b ; b = temporaire ; cout << "Fin échange dans la fonction : " << a << " " << b << endl ; } 52
  • 53. 53 Passage des arguments par valeur 53 Ce code affiche : Avant appel : 10 20 Début échange dans la fonction : 10 20 Fin échange dans la fonction : 20 10 Après appel : 10 20
  • 54. 54 Passage des arguments par référence 54 CONCEPT: Lorsqu'il est utilisé en tant que paramètres, les variables de référence permettent d'accéder à l’argument initial du paramètre d’une fonction. Les modifications apportées au paramètre sont également faite à l'argument. Une modification effectuée à l’intérieur de la fonction se répercute alors à l’extérieur de la fonction.
  • 55. 55 Passage des arguments par référence 55 Au lieu de copier la valeur de nombre dans la variable x, il est possible d'ajouter une « deuxième étiquette » à la variable nombre à l'intérieur de la fonction. Il faut utiliser dans ce cas une référence comme argument de la fonction. La référence d’une variable = son adresse mémoire.
  • 56. 56 Passage des arguments par référence 56 Une variable de référence est un alias pour une autre variable. Toutes les modifications apportées à la variable de référence sont réellement effectué sur la variable pour laquelle il est un alias. En utilisant une variable de référence en tant que paramètre, une fonction peut modifier une variable qui est définie dans une autre fonction. Les variables de référence sont définies comme des variables ordinaires, sauf que vous placez une esperluette (&) devant le nom; par exemple: double & x.
  • 57. 57 Passage des arguments par référence 57 Exemple 1: Noter la présence de & int multiplierParDeux(int & x) { x* = 2; return x; } La notation int & x signifie que x est une information de type int transmise par référence. N.B: La variable x est appelée "une référence à un int."
  • 58. 58 Passage des arguments par référence 58 Lorsque l'on appelle la fonction, il n'y a plus de copie. Le programme donne simplement un alias à la variable nombre. Dans ce cas, les deux variables x et nombre sont confondues. On dit que l'argument nombre est passé par référence.
  • 59. 59 Passage des arguments par référence 59 Exemple 1: Testons maintenant cette fonction: #include <iostream> using namespace std; int multiplierParDeux(int &x){//définition de la fonction: multiplierParDeux() x *= 2; return x; } int main(){ int nombre(2), resultat; cout << "Avant appel, nombre est " << nombre << endl; resultat = multiplierParDeux(nombre); //appel de la fonction: multiplierParDeux() cout << "Le nombre original vaut : " << nombre << endl; cout << "Le résultat vaut : " << resultat << endl; return 0; }
  • 60. 60 Passage des arguments par référence 60 Cela donne comme résultat: Avant appel, nombre est 2 Le nombre original vaut : 4 Le résultat vaut : 4 Comme les deux variables x et nombre correspondent à la même case mémoire, faire x*=2 a modifié la valeur de nombre! Utiliser des références peut donc être très dangereux. C'est pour cela qu'on ne les utilise que lorsqu'on en a réellement besoin.
  • 61. Passage des arguments par référence Exemple 1: Remarque: Le paramètre x "pointe " à la valeur de la variable dans la fonction main. Quand un programme travaille avec une variable de référence, il travaille en fait avec la variable qui référence ou qui pointe sur. 6161
  • 62. 62 Passage des arguments par référence Exemple 2: Voyez cet deuxième exemple en utilisant les références: #include <iostream> using namespace std ; void echanger(int& , int&) ; // prototype de la fonction int main (){ int n(10), p(20) ; cout << "Avant appel : " << n << " " << p << endl; echanger(n, p) ; // appel de la fonction: attention, ici pas de &n, &p cout << "Après appel : " << n << " " << p << endl ; } void echanger(int& a, int& b){// définition de la fonction int temporaire (a) ; cout << "Début échange dans la fonction : "<< a << " " << b << endl ; a = b ; b = temporaire ; cout << "Fin échange dans la fonction : " << a << " " << b << endl ; } 62
  • 63. 63 Passage des arguments par référence 63 Cela affiche : Avant appel : 10 20 Début échange dans la fonction : 10 20 Fin échange dans la fonction : 20 10 Après appel : 20 10 Les valeurs des deux variables ont été échangées.
  • 64. 64 Passage des arguments par référence 64 Appel de fonction Lors de l’appel d’une fonction recevant un argument par référence, seules les variables peuvent être passés par référence. Si vous essayez de passer un argument non variable, comme une constante ou une expression, dans un paramètre de référence, une erreur se produit. La transmission par référence impose à un argument effectif d’être une lvalue du type prévu pour l’argument muet.
  • 65. 65 Passage des arguments par référence 65 Appel de la fonction Exemple: void f (int &) ; // f reçoit la référence à un entier ..... const int n(5) ; int p ; f(p) ; // OK f(3*p+2) ; // erreur : 3*p+2 n’est pas une lvalue f(4) ; // erreur : 4 n’est pas modifiable f(n) ; // erreur : n n’est pas modifiable ..... float y ; f(y) ; // erreur : y n’est pas de type int
  • 66. 66 Passage des arguments par référence 66 Cas d’un argument muet constant Il est possible de transmettre par référence une constante, comme dans ce prototype : void fct(const int & n) ; Dans ce cas, la fonction fct s’attend à recevoir l’adresse d’une constante et elle ne devra pas, dans sa définition, modifier la valeur de n ; dans le cas contraire, on obtiendra une erreur de compilation.
  • 67. 67 Passage des arguments par référence 67 Cas d’un argument muet constant Cette fois, les appels suivants seront corrects : const int c(5) ; ..... fct(3) ; // correct ici fct(c) ; // correct ici fct(exp); //exp: une expression quelconque acceptée quel que soit son type float x ; ..... fct(x) ; // correct : fct reçoit la référence à une variable temporaire // contenant le résultat de la conversion de x en int
  • 68. 68 Passage par référence constante 68 Imaginez une fonction recevant en argument un string. Le passage par référence offre un gros avantage sur le passage par valeur : aucune copie n'est effectuée. Un passage par référence, aucune copie n'est effectuée. Mais il autorise la modification de l'argument. void fonctionChaine(string texte) //Implique une copie coûteuse de 'texte' { } void fonctionChaine(string& texte) //Implique que la fonction peut modifier 'texte' { }
  • 69. 69 Passage par référence constante 69 La solution est d'utiliser ce que l'on appelle un passage par référence constante. Il nous permet d’éviter la copie en utilisant une référence. Il empêche la modification de l'argument en le déclarant constant. Voici la syntaxe: void fonctionChaine (string const& texte)//Pas de copie et pas de modification possible { }
  • 70. Variables globales et locales Une variable locale est définie à l'intérieur d'une fonction et n'est pas accessible à l'extérieur de la fonction. Une variable globale est définie à l'extérieur de toutes les fonctions et est accessible à toutes les fonctions dans son étendue. 7070
  • 71. Variables locales Les variables définies à l'intérieur d'une fonction sont locales à cette fonction. Ils sont cachés des déclarations des autres fonctions qui normalement ne peuvent pas les accéder. 7171
  • 72. Variables locales Exemple: #include <iostream> using namespace std; void autreFonction(); //prototype int main(){ int nbre(1); //variable locale cout << " Dans la fonction main, nbre est " << nbre << endl; autreFonction(); //appel de fonction cout << " Retour à la fonction main, nbre est " << nbre << endl; return 0; } void autreFonction(){ //définition de fonction int nbre(20); // variable locale cout << " Dans la fonction autreFonction, nbre est " << nbre << endl; } 7272
  • 73. Variables locales Sortie du programme Dans la fonction main, nbre est 1 Dans la fonction autreFonction, nbre est 20 Retour à la fonction main, nbre est 1 7373
  • 75. Portée des variables locales Les variables locales d'une fonction existent seulement pendant son exécution. Quand la fonction commence, ses variables locales et ses variables paramètres sont créées dans la mémoire, et quand la fonction termine, les variables locales et variables paramètres sont détruites. Cela veut dire que toute valeur stockée dans une variable locale est perdu entre appels à la fonction. 7575
  • 76. Variables globales Une variable globale est toute variable définie à l'extérieur de toutes les fonctions dans un programme. La portée d'une variable globale est tout le programme . Cela veut dire qu'une variable globale peut être accédée par toutes les fonctions qui sont définies après que la variable globale soit définie. 7676
  • 77. Variables globales Remarque: Les variables globales sont initialisés par zéro automatiquement. 7777
  • 78. Variables globales Exemple 1: #include <iostream> using namespace std; void autreFonction(); //prototype int nbre(2); //variable globale int main(){ cout << " Dans la fonction main, nbre est " << nbre << endl; autreFonction(); //appel de fonction cout << " Retournons dans la fonction main, nbre est " << nbre<< endl; return 0; } void autreFonction(){ //définition de fonction cout << " Dans la fonction autreFonction, nbre est " << nbre << endl; nbre = 50; cout << " Mais, maintenant sa valeur est changée à " << nbre << endl; } 7878
  • 79. Variables globales Output: Dans la fonction main, nbre est 2 Dans la fonction autreFonction, nbre est 2 Mais, maintenant sa valeur est changée à 50 Retournons dans la fonction main, nbre est 50 7979
  • 80. Variables globales constantes Exemple 2: #include <iostream> using namespace std; void autreFonction(); //prototype const int nbre (2); //constante globale int main(){ cout << " Dans la fonction main, nbre est " << nbre << endl; autreFonction(); //appel de fonction cout << " Retournons dans la fonction main, nbre est " << nbre << endl; return 0; } void autreFonction() { //définition de fonction cout << " Dans la fonction autreFonction, nbre est " << nbre << endl; nbre = 50; //erreur cout << " Mais, maintenant sa valeur est changée à " << nbre << endl; } 8080
  • 81. Variables globales et locales portant même nom Vous ne pouvez pas avoir deux variables locales avec le même nom dans la même fonction. Même remarque pour une variable paramètre et une variable locale dans la même fonction. Cependant, vous pouvez avoir une variable locale ou un paramètre avec le même nom comme une variable globale, ou une constante globale. 8181
  • 82. Variables globales et locales portant même nom Exemple #include <iostream> using namespace std; void autreFonction(); //prototype const int nbre(2); //constante globale int main(){ int nbre(5); //variable locale cout << " Dans la fonction main, nbre est " << nbre << endl; autreFonction(); //appel de fonction cout << " Retour dans la fonction main, nbre est " << nbre << endl; return 0; } void autreFonction(){ //définition de fonction cout << " Dans la fonction autreFonction, nbre est " << nbre << endl; int nbre(50); cout << " Mais, maintenant sa valeur est changée à " << nbre << endl; } 8282
  • 83. Variables globales et locales portant même nom Sortie du programme Dans la fonction main, nbre est 5 Dans la fonction autreFonction, nbre est 2 Mais, maintenant sa valeur est changée à 50 Retour dans la fonction main, nbre est 5 8383
  • 84. Variables locales statiques Si une fonction est appelée plusieurs fois dans un programme, les valeurs stockées dans les variables locales ne sont pas conservées entre les appels de fonction. C'est parce que les variables locales sont détruites lorsque la fonction se termine, puis sont recréés lorsque la fonction recommence. 8484
  • 85. Variables locales statiques Exemple 1: Ce programme montre que les variables locales ne conservent pas leurs valeurs entre les appels de fonction. #include <iostream> using namespace std; void montrerVariableLocale(); //prototype int main(){ montrerVariableLocale(); //1er appel de la fonction montrerVariableLocale(); //deuxième appel de la fonction return 0; } void montrerVariableLocale(){ //définition de la fonction int nbreLocal(5); //variable locale cout << " nbreLocal est " << nbreLocal << endl; nbreLocal = 99; } 8585
  • 86. Variables locales statiques Sortie du programme : nbreLocal est 5 nbreLocal esr 5 8686
  • 87. Variables locales statiques Les variables locales statiques ne sont pas détruites lors d'un retour de la fonction. Ils existent pour la durée du programme, même si leur portée est seulement la fonction dans laquelle elles sont définies. Comme les variables globales, les variables locales statiques sont initialisés à zéro par défaut. 8787
  • 88. Variables locales statiques Exemple: static double x (4.5); // déclaration de la variable statique x const int MAX(5) ; // déclaration de la constante MAX static int limit(3*MAX + 1); // 3*MAX+1 est une expression constante static short X(50) ; // 50 de type int est converti en short int static float Y(3) ; // 3 de type int est converti en float static long Z(7.5) ; // 7.5 de type float est converti en long (déconseillé) 8888
  • 89. Variables locales statiques Exemple 2 : ce programme utilise une variable locale statique #include <iostream> using namespace std; void montrerVarStatique(); int main(){ for (int compteur(0); compteur < 5; compteur ++) montrerVarStatique(); return 0; } void montrerVarStatique(){ static int nbreStat; cout << " nbreStat est " << nbreStat << endl; nbreStat ++; } 8989
  • 90. Variables locales statiques Sortie du programme : nbreStat est 0 nbreStat est 1 nbreStat est 2 nbreStat est 3 nbreStat est 4 9090
  • 91. Variables locales statiques Exemple 3 : ce programme utilise une variable locale statique #include <iostream> using namespace std; void montrerVarStatique(); int main(){ for (int compteur(0); compteur < 5; compteur ++) montrerVarStatique(); return 0; } void montrerVarStatique(){ static int nbreStat(5); cout << " nbreStat est " << nbreStat << endl; nbreStat ++; } 9191
  • 92. Variables locales statiques Sortie du programme : nbreStat est 5 nbreStat est 6 nbreStat est 7 nbreStat est 8 nbreStat est 9 9292
  • 93. Variables locales statiques Même si la déclaration qui définit nbreStat, est initialisée à 5, l'initialisation ne se produit pas à chaque fois que la fonction est appelée. Si c'était le cas, la variable ne serait pas en mesure de conserver sa valeur entre les appels de fonction. 9393
  • 94. Variables locales à un bloc C++ permet de déclarer des variables locales à un bloc. Leur portée est limitée à ce bloc. Leur emplacement est alloué à l’entrée dans le bloc et il disparaît à la sortie. 9494
  • 95. Variables locales à un bloc Exemple: void f(){ int n ; //n est accessible de tout le bloc constituant f ..... for (...){ int p ; // p n’est connue que dans le bloc de for int n ; // n masque la variable n de portée "englobante" ..... // attention, on ne peut pas utiliser ::n ici qui désignerait une variable globale (inexistante ici) } ..... { int p ; // p n’est connue que dans ce bloc ; elle est allouée ici ..... // et n’a aucun rapport avec la variable p ci-dessus } // et elle sera désallouée ici ..... } 9595
  • 96. 96 Valeurs par défaut pour les arguments 96 CONCEPT: Les arguments par défaut sont passées aux paramètres automatiquement si aucun argument n'est fourni dans l'appel de fonction. Les arguments par défaut sont généralement indiquées dans le prototype de fonction. Il n’est alors pas nécessaire de fournir d’argument à ces paramètres avec valeurs par défaut lors de l’appel de la fonction.
  • 97. 97 Valeurs par défaut pour les arguments 97 CONCEPT: La syntaxe d’un paramètre avec valeur par défaut est : type identificateur = valeur Voici un exemple: void montrerAire(double longueur = 20.0, double largeur = 10.0); void montrerAire(double = 20.0, double = 10.0);
  • 98. 98 Valeurs par défaut pour les arguments 98 On peut donner des valeurs par défaut à certains paramètres des fonctions. Lorsqu'on appelle une fonction, on ne sera pas obligé d'indiquer à chaque fois tous les paramètres. Rendre certains paramètres des fonctions facultatifs en modifiant le prototype de la fonction (et non sa définition, attention).
  • 99. Valeurs par défaut pour les arguments Voici la définition de la fonction : void montrerAire(double longueur, double largeur) { double aire(longueur * largeur); cout << " L’aire est " << aire << endl; } 9999
  • 100. Valeurs par défaut pour les arguments Voici l’appel de la fonction : Parce que les deux paramètres ont des arguments par défaut, elles peuvent éventuellement être omis dans l'appel de fonction, comme indiqué ici: montrerAire(); //appel sans argument Sortie de la fonction : L’aire est 200 100100
  • 101. Valeurs par défaut pour les arguments Les appels de la fonction : 1) Dans l'appel ci-dessous, le premier argument est spécifié, mais le second est omis: montrerAire(12.0); //appel avec un seul argument La valeur 12.0 sera transmis à la longueur, tandis que la valeur par défaut 10.0 seront transmis à largeur. La sortie de la fonction sera: L‘aire est 120 101101
  • 102. Valeurs par défaut pour les arguments Les appels de la fonction : 1) Bien sûr, tous les arguments par défaut peuvent être remplacés. Dans l'appel de fonction ci-dessous, les arguments sont fournis pour les deux paramètres: montrerAire(12.0, 5.5); //appel normal La sortie de l'appel de fonction ci-dessus sera: L‘aire est 66 102102
  • 103. Valeurs par défaut pour les arguments Remarque importante : Si une fonction n‘a pas un prototype, les arguments par défaut peuvent être spécifiée dans l'en-tête de fonction. La fonction montrerAire() peut être défini comme suit: void montrerAire(double longueur = 20.0, double largeur = 10.0) { double aire(longueur*largeur); cout << " L’aire est " << aire << endl; } 103103
  • 104. Valeurs par défaut pour les arguments Attention: Lorsqu'un argument est omis dans un appel de fonction, tous les arguments qui viennent après il doit être laissé de côté aussi. montrerAire( , 10.50); // Appel de fonction illégal. 104104
  • 105. Valeurs par défaut pour les arguments Attention: Lorsqu'une fonction utilise un mélange de paramètres avec et sans arguments par défaut, le paramètre avec les arguments par défaut doit être défini en dernier. Exemple: Les prototypes suivants sont illégales: void calculPayement(int numEmp, double heurs = 40.0, double tauxRemun); void calculPayement(double heurs = 40.0, int numEmp, double tauxRemun); 105105
  • 106. 106 Valeurs par défaut pour les arguments 106 Considérons l’exemple suivant: int sommeDeDeuxValeurs(int x, int y) // en-tête { int total(0); total = x+y; return total; // ou directement return x+y; }
  • 107. 107 Valeurs par défaut pour les arguments 107 Exemple 1: #include <iostream> using namespace std; // Prototype de la fonction int sommeDeDeuxValeurs(int , int y=5); // prototype avec une valeur par défaut /* ou int sommeDeDeuxValeurs(int , int =5); */ // Main int main(){ int n(10), p(20), y1, y2; y1 = sommeDeDeuxValeurs(n, p); // appel " normal" y2 = sommeDeDeuxValeurs(n); // appel avec un seul argument cout << "y1 = " << y1 << " y2 = " << y2 << endl ; return 0; } // Définition de la fonction int sommeDeDeuxValeurs(int x, int y){ int total(0); total = x + y; return total; }
  • 108. 108 Valeurs par défaut pour les arguments 108 Exemple 1: Output: y1 = 30 y2 = 15
  • 109. 109 Valeurs par défaut pour les arguments 109 Explication: La déclaration de sommeDeDeuxValeurs(), est réalisée par le prototype : int sommeDeDeuxValeurs(int, int = 5) ; La déclaration du second argument apparaît sous la forme : int = 5 Elle précise au compilateur que, en cas d’absence de ce second argument dans un éventuel appel de sommeDeDeuxValeurs, il lui faudra « faire comme si » l’appel avait été effectué avec cette valeur. Notez qu’un appel tel que : sommeDeDeuxValeurs( ) serait rejeté à la compilation puisque ici il n’était pas prévu de valeur par défaut pour le premier argument de la fonction.
  • 110. 110 Valeurs par défaut pour les arguments 110 Exemple 2: #include <iostream> using namespace std; // Prototype de la fonction int sommeDeDeuxValeurs(int =0 , int =5); // prototype avec deux valeurs par défaut // Main int main(){ int n(10), p(20), y1, y2, y3; y1 = sommeDeDeuxValeurs(n, p); // appel " normal" y2 = sommeDeDeuxValeurs(n); // appel avec un seul argument y3 = sommeDeDeuxValeurs(); // appel sans argument cout << "y1 = " << y1 << " y2 = " << y2 << " y3 = " << y3 << endl ; return 0; } // Définition de la fonction int sommeDeDeuxValeurs(int x, int y){ int total(0); total = x + y; return total;}
  • 111. 111 Valeurs par défaut pour les arguments 111 Exemple 2: Output: y1 = 30 y2 = 15 y3 = 5
  • 112. 112 Les propriétés des arguments par défaut 112 Les valeurs par défaut sont spécifiées uniquement dans le prototype, pas dans la définition de la fonction. Les valeurs par défaut doivent obligatoirement apparaître en dernier dans la liste des paramètres d’une fonction (c'est-à-dire à droite). Le compilateur analyse les paramètres de gauche à droite.
  • 113. 113 Les propriétés des arguments par défaut 113 Exemple: 1. float f(int = 10, long, int = 5) ; // déclaration interdite 2. sommeDeDeuxValeurs(3, , 5); //on ne peut pas « sauter » des //paramètres, même s'ils sont facultatifs.
  • 114. 114 Récursivité 114 Une fonction est dite récursive si elle s’appelle elle-même. C++ autorise la récursivité des appels de fonctions. Elle peut prendre deux aspects : récursivité directe : une fonction comporte, dans sa définition, au moins un appel à elle-même; récursivité croisée : l’appel d’une fonction entraîne celui d’une autre fonction qui, à son tour, appelle la fonction initiale (le cycle pouvant d’ailleurs faire intervenir plus de deux fonctions).
  • 115. 115 Récursivité 115 Un programme récursif se compose de deux parties: Au moins une condition d’arrêt des appels récursifs, où les valeurs à déterminer sont immédiatement connues. Un appel récursif. La fonction s’appelle elle-même, dans un autre environnement.
  • 116. 116 Récursivité 116 La structure d’une fonction récursive typeDeValeurRetour fonctionRecursive(liste des paramètres) { if (condition d‘arrêt) //condtion d‘arrêt et de retour { return (…); } else { //appel récursif return (fonctionRecursive(liste des nouveaux paramètres)); }
  • 117. 117 Récursivité 117 Exemple 1: long facto(int n) { if (n>1) return (facto(n-1)*n) ; else return(1) ; }
  • 118. 118 Récursivité 118 Exemple 2: la suite de Fibonacci U0 = 0; U1 = 1; Un = Un-1 + Un-2, pour tout entier n tel que n>=2;
  • 119. 119 Récursivité 119 Exemple 2: la suite de Fibonacci int Fibonacci(int n) { if (n == 0) //première condition d‘arrêt et de retour return 0; // cas où n=0 else if (n == 1) // seconde condition d‘arrêt et de retour return 1; //cas où n=1 else return (Fibonacci(n-1) + Fibonacci (n-2)); //appel récursif en utilisant la formule }
  • 120. 120 Récursivité 120 Exemple 3: système des suites réccurentes U0 = 1/2; V0 = -3/2; Un = Un-1 + Vn-1, pour tout entier n tel que n>=1; Vn = 2Un-1 + Vn-1, pour tout entier n tel que n>=1;
  • 121. 121 Récursivité 121 Exemple 3: système des suites réccurentes double V(int n); //prototype de la fonction récursive V(n) double U(int n){ //défintion de la fonction récursive U(n) if (n == 0) //condition d‘arrêt et de retour return 1./2.; // cas où n=0 else return (U(n-1) + V(n-1)); //appel récursif en utilisant la formule } double V(int n){ //défintion de la fonction récursive V(n) if (n == 0) return -3./2.; else return (2*U(n-1) + V(n-1)); }
  • 122. 122 Fonctions inline 122 Pour de petites fonctions, il peut être plus efficace d’éviter un appel de fonction et à la place, expanser le corps de la fonction en lieu et place de chaque appel. C’est possible avec le mot-clé inline. inline int max(int a, int b =0) //défintion de la fonction inline max { if (a>b) return a ; else return b ; }
  • 123. 123 Fonctions inline 123 Exemple: inline int max(int a, int b =0); // prototype de la fonction inline max int main(){ cout << max(10,5) << endl; // appel de la fonction inline max return 0; } inline int max(int a, int b =0) //défintion de la fonction inline max { if (a>b) return a ; else return b ; } En règle générale, les fonctions inline sont donc des fonctions très courtes que l'on est susceptible de réutiliser souvent, comme c'est le cas de la fonction max ici.
  • 124. Surcharge (ou surdéfinition) de fonctions CONCEPT: Deux ou plusieurs fonctions peuvent avoir le même nom, à condition que leurs listes de paramètres soient différents: nombre ou types de paramètres différents. Ce mécanisme est appelé surcharge (ou surdéfinition ) des fonctions. 124124
  • 125. Surcharge (ou surdéfinition) de fonctions Exemple: Ce programme utilise des fonctions surchargées. #include<iostream> #include<iomanip> using namespace std; int square(int); double square(double); int main(){ int intUtilisateur; double floatUtilisateur; // Saisir un int et un double. cout << fixed << showpoint << setprecision(2); cout << "Entrer un entier et une valeur flottante: "; cin >> intUtilisateur >> floatUtilisateur; // Afficher leurs carrés. cout << "Voici leurs carrés: "; cout << square(intUtilisateur) << " et " << square(floatUtilisateur); return 0; } 125125
  • 126. Surcharge (ou surdéfinition) de fonctions int square(int nombre) { return nombre*nombre; } double square(double nombre) { return nombre*nombre; } 126126
  • 127. Surcharge (ou surdéfinition) de fonctions Sortie du programme Entrer un entier et une valeur flottante: 12 4.2 Voici leurs carrés: 144 et 17.64 127127
  • 128. Surcharge (ou surdéfinition) de fonctions Voici les en-têtes des fonctions carrés: int square(int nombre) double square(double nombre) 128128
  • 129. Surcharge (ou surdéfinition) de fonctions Signature de la fonction La signature de la fonction est le nom de la fonction et les types de données des paramètres de la fonction dans le bon ordre. Les fonctions carrés auraient les signatures suivantes: square(int) square(double) 129129
  • 130. Surcharge (ou surdéfinition) de fonctions Remarque: Les fonctions suivantes ne pouvaient pas être utilisés dans le même programme parce que leurs listes de paramètres ne sont pas différents. int square(int nombre) { return nombre * nombre; } double square(int nombre) //Faux! Les listes de paramètres doivent être différent { return nombre * nombre; } 130130
  • 131. Fonctions génériques Fonction template: template<typename T> //sans ; T sum(T a, T b){ return a+b; } int main(){ cout << sum(3,4) << endl; //le compilateur détecte automatique le type des paramètres cout << sum(3.7,4.8) << endl; cout << sum<int>(3.7,4.8) << endl; //on spécifie le type à utiliser return 0; } Output: 7 8.5 7 131131
  • 132. La fonction exit() CONCEPT: La fonction exit() met fin l’exécution d’un programme, quel que soit la fonction ou le mécanisme de contrôle qui est en cours d'exécution. 132132
  • 133. La fonction exit() Exemple: #include <iostream> #include <cstdlib> // Pour exit using namespace std; void fonction(); // Prototype int main(){ fonction(); //Appel de fonction return 0; } void fonction(){ //Définition de fonction cout << " Ce programme se termine avec la fonction exit. " << endl; cout << "Bye!" << endl; exit(0); cout << " Ce message ne sera pas affiché" << endl; cout << " Car le programme a déjà terminé." << endl; } 133133
  • 134. La fonction exit() Sortie du programme Ce programme termine avec la fonction exit. Bye! 134134
  • 135. Utilisez plusieurs fichiers Le langage C++ permet de découper son programme en plusieurs fichiers sources. 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. On a ainsi réellement des briques séparées utilisables pour construire différents programmes. 135135
  • 136. Utilisez plusieurs fichiers Les fichiers nécessaires Pour cela, il faut deux fichiers : un fichier source dont l'extension est .cpp: il contient le code source de la fonction, ce qu'on appelle la définition de la fonction. un fichier d'en-tête dont l'extension est .h: il contient uniquement le prototype de la fonction. 136136
  • 137. Utilisez plusieurs fichiers Le fichier source: 1. Pour le créer, il suffit de passer par les menus: File>New>File. 2. Choisir ensuite C/C++ source. 3. Cliquer ensuite sur Go. 4. Finalement, donner un nom à ce fichier, par exemple finance.cpp 137137
  • 138. Utilisez plusieurs fichiers Le fichier d'en-tête: 1. Pour le créer, il suffit de passer également par les menus: File>New>File. 2. Sélectionner ensuite C/C++ header. 3. Indiquer ensuite le nom du fichier. Il vaut mieux de lui donner le même nom qu'au fichier source mais avec une extension .h au lieu de.cpp. Dans notre cas, finance.h 138138
  • 139. Utilisez plusieurs fichiers Exemple 1/3: Le fichier source : finance.cpp #include "finance.h" float ROI(float c, float g) { return ; } 139139
  • 140. Utilisez plusieurs fichiers Exemple 2/3: Le fichier d'en-tête : finance.h #ifndef FINANCE_H_INCLUDED #define FINANCE_H_INCLUDED float ROI(float c, float g); //le prototype de la fonction #endif // FINANCE_H_INCLUDED 140140
  • 141. Utilisez plusieurs fichiers Exemple 3/3: #include <iostream> #include "finance.h" using namespace std; int main() { float c, g, r; cout << "Coûts de l'investissement: " << c << endl; cout << "Gains de l'investissement: " << g << endl; r = ROI(c,g); //Appel de la fonction cout << "Le ROI est : " << r << endl; return 0; } 141141
  • 142. 142 Quiz 142 1. Est ce le suivant une entête de fonction ou un appel de fonction? calculerTotal(); 2. Est ce le suivant une entête de fonction ou un appel de fonction? void afficheResultats() 3. Indiquez lequel des énoncés suivants est le prototype de fonction, l’entête de fonction, et appel de fonction: void montrerNumerique(double num) void montrerNumerique(double); montrerNumerique(45.67); 4. Il y a une erreur dans ce programme ? void afficheValeur(int x); int main(){ int y(3); afficheValeur(y); //Appel fonction afficheValeur afficheValeur(int x); //Appel fonction afficheValeur afficheValeur(3+4); //Appel fonction afficheValeur }
  • 143. 143 Quiz 143 5. Que produira ce programme si l’utilisateur saisit 10? #include<iostream> using namespace std; void fonction1(){ cout << " Hellon"; } void fonction2(){ cout << "Bonjourn"; } void main(){ int input; cout << "Entrer un nombre: "; cin >> input; if (input < 10){ fonction1(); fonction2(); } else{ fonction2(); fonction1(); } return 0; }
  • 145. Exercices de cours Exercice 1 1. Écrire une fonction nommée tempsDix(). La fonction doit avoir un paramètre entier appelé nombre. Lorsque tempsDix() est appelée, elle doit présenter le produit de dix fois le nombre. 2. Donner le prototype de la fonction tempsDix(). 145145
  • 146. Exercices de cours Exercice 2 Écrire une fonction récursive qui calcule la puissance xn. Exercice 3 Écrire une fonction, estPair ayant en paramètre un entier et qui renvoie un booléen : Vrai si l'entier est pair Faux sinon. Exercice 4 Écrire une fonction récursive, suite, qui calcule la suite récurrente suivante: 146146
  • 147. Références 147 1) http://www.cplusplus.com 2) https://isocpp.org/ 3) https://openclassrooms.com/fr/courses/1894236-programmez-avec-le-langage-c 4) https://www.tutorialspoint.com/cplusplus/ 5) https://en.cppreference.com 6) Programmer en C++, Claude Delannoy, éditions Eyrolles, 2014. 7) Initiation à la programmation (en C++), Jean-Cédric Chappelier, & Jamila Sam, coursera, 2019. 8) Introduction à la programmation orientée objet (en C++), Jamila Sam & Jean-Cédric Chappelier, coursera, 2019. 147