Vous êtes sur la page 1sur 10

S.

Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Chapitre 3 : Les fonctions en C++


I. Introduction aux fonctions : les fonctions standards
A. Notion de Fonction
Imaginons que dans un programme, vous ayez besoin de calculer une racine carre. Rappelons que l'oprateur racine carre n'existe pas en C++, pas plus que l'oprateur puissance. Comment faire? Deux possibilits s'offrent vous : soit vous crivez vous-mme entirement la partie du programme qui permet d'extraire une racine carre, partir des oprateurs de base du langage (les oprateurs primitifs). Mais le programme d'extraction d'une racine est dlicat crire voir impossible quand on n'en matrise pas l'algorithme. soit vous utilisez une fonction dj existante qui permet d'extraire une racine carre. Une telle fonction existe dans le langage C++ : c'est une fonction standard appele sqrt. Une fonction est un morceau de programme autonome, utilis par un autre programme pour raliser une opration prcise. Une fonction est standard quand elle est livre avec l'EDI du langage. Le programmeur peut l'utiliser comme s'il s'agissait d'un oprateur du langage. Une fonction peut aussi tre crite par le programmeur pour ses propres besoins. Nous verrons comment crire et utiliser une fonction dans la partie suivante. Une fonction au sens strict peut tre reprsente par une boite noire (un mcanisme invisible) qui donne un et un seul rsultat partir d'une ou plusieurs donnes (voire aucune). RESULTAT (Valeur de retour)

DONNEES (Paramtres Effectifs)

Fonction

Le rsultat d'une fonction est appele VALEUR DE RETOUR. Les donnes partir desquelles une fonction calcule son rsultat sont appeles PARAMETRES EFFECTIFS ou ARGUMENTS En C++, la notion de fonction est plus large : en C++, une fonction peut ne rien retourner. En C++, on utilise le mot fonction pour dsigner tous les sous-programmes, y compris les procdures. (voir le cours d'algo)

B. Utilisation des fonctions standards


En C++, les fonctions standards sont regroupes dans des bibliothques (library en anglais). Pour utiliser une fonction standard, il faut inclure le fichier d'en-tte o elle est dclare. Par exemple, pour utiliser la fonction getch( ), qui se contente de saisir sans retour l'cran d'un caractre tap au clavier, il faut inclure le fichier d'en-tte <conio.h>.
1

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Ensuite, pour excuter une fonction l'intrieur d'un programme, il faut effectuer un APPEL de cette fonction. L'appel d'une fonction consiste tout simplement crire son nom, suivi entre parenthses des paramtres effectifs (les donnes). Exemple Voil un programme qui permet tout simplement d'afficher la racine carre d'un nombre entier saisi par l'utilisateur. Pour cela, on utilise la fonction sqrt dclare dans le fichier d'en-tte math.h. #include <iostream.h> #include <math.h>
inclusion du FICHIER d'EN-TETE

main( ) { int n; cout << "Taper un nombre "; cin >> n; cout << "La racine carre de ce nombre est "<< sqrt(n) ; }

APPEL de la fonction sqrt

PARAMETRE effectif ou ARGUMENT

A l'excution, l'appel d'une fonction est remplac par la valeur retourne (rsultat) : sqrt(n) correspond la valeur de la racine carre de n. Donc on peut utiliser l'appel d'une fonction comme toute autre valeur : on peut l'afficher, l'affecter une variable ou l'utiliser dans une expression (calcul, condition,). Cas particulier : Dans le cas d'une fonction qui ne retourne rien (fonction void ou procdure en algorithmique), l'appel correspond une instruction part entire et non une valeur. L'appel d'une procdure ne peut en aucun cas se trouver l'intrieure d'une expression.

C. Les spcifications d'une fonction


Pour pouvoir utiliser une fonction, il est inutile de connatre comment elle fonctionne. Il suffit de savoir quoi elle sert et comment s'en servir. (savez vous exactement comment fonctionne un tlviseur? Non, et pourtant vous savez vous en servir !) Les spcifications d'une fonction servent justement indiquer quand et comment s'en servir : Les spcifications d'une fonction (ou d'une procdure) rassemblent les informations ncessaires son utilisation c'est--dire : son nom, son rle, ses paramtres (leur ordre, leur type), le type de la valeur retourne et sa localisation (en C++, le fichier d'en-tte dans lequel elle est dclare). Exemple : spcifications de la fonction sqrt( ) du C++ nom rle paramtre

La fonction sqrt extrait la racine carre du nombre de type double pass en paramtre. La valeur retourne est de type double . Elle est dclare dans le fichier d'en-tte math.h type de la valeur retourn localisation
2

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

On peut trouver les spcifications des fonctions standards dans l'aide en anglais !- de l'environnement de dveloppement. Quand un programmeur crit une fonction, il doit toujours en fournir les spcifications pour que les autres programmeurs puissent l'utiliser.

D. Les fonctions standards les plus utilises


Les fonctions mathmatiques du fichier d'en-tte math.h Fonction ceil (x) fabs(x) floor(x) pow(x, p) sqrt(x) Description retourne la valeur de x arrondie l'entier suprieur retourne la valeur absolue de x retourne la valeur de x arrondie l'entier infrieur retourne x la puissance p retourne la racine carre de x Exemple ceil(3.1416) retourne 4.0 fabs(-2) retourne 2.0 floor(3.1416) retourne 3.0 pow(2, 3) retourne 8 (23) sqrt(2) retourne 1.41421

Toutes ces fonctions retournent une valeur de type double. Les paramtres sont aussi de type double. Mais si on utilise des paramtres de type int ou float, ils seront automatiquement convertis en double. Autres fonctions utiles - clrscr( ) efface l'cran conio.h

- random(n) stdlib.h retourne un entier alatoire compris entre 0 et n (exclu). A chaque fois que cette fonction est appele, elle retourne un nombre diffrent. Mais chaque utilisation du programme, c'est la mme srie de nombre alatoire qui est gnre. Pour viter cela, on rinitialise la liste de nombre alatoires avec la fonction (procdure) suivante : - randomize( ) stdlib.h randomize( ) ne doit tre appel qu'une seule fois en dbut de programme (mme si on utilise plusieurs fois random par la suite. Exemple : Simulation d'un tirage pile ou face # include <iostream.h> # include <conio.h> # include <stdlib.h> main() { int res; randomize( ); //rinitialisation du gnrateur de nombres alatoires res = random(2); //permet de choisir au hasard entre 0 et 1 if (res == 0) //on dfinit arbitrairement que 0 est PILE et on affiche le rsultat cout << "PILE"; else cout << "FACE"; getch( ); }
3

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

II. La cration de fonctions


En vertu des principes de la programmation modulaire, qui prconise de dcouper le code des applications en petites units, les programmeurs sont conduits crer leurs propres sousprogrammes. Nous allons voir comment faire en C++. Spcificits du C et C++: tous les sous-programmes sont appels FONCTIONS mme ceux qui ne renvoie rien (et qu'on appelle procdure en algorithmique et dans les autres langages). le programme principal est lui mme une fonction, appele obligatoirement main( ) car c'est la toute premire fonction appele l'excution du programme.

Dfinition et appel d'une fonction (au sens algorithmique)


Dfinition Syntaxe: type_retourn nom_fonction (type_paramtre nom_paramtre, ) { /*corps de la fonction*/ return valeur_retourne; } Exemple: dfinition de la fonction somcarre ( ) double somcarre (float a, float b) { double sc; sc = a * a + b * b; return sc; }
ou plus simplement double somcarre (float a, float b) { return a*a + b*b; }

//en-tte

Attention : il faut indiquer le type devant chaque paramtre, mme si c'est le mme (sinon, par dfaut, le paramtre est de type int)

L'appel d'une fonction L'appel d'une fonction est utilis dans une instruction comme une valeur. On peut mme utiliser l'appel d'une fonction comme valeur de paramtre pour une autre fonction. ex: appel de la fonction somcarre pour calculer la variance v de deux nombres n1 et n2. double v; float n1, n2; //saisie de n1 et n2 v = (somcarre(n1, n2) (n1+n2)) / n; Remarquez que les types des paramtres effectifs correspondent au type des paramtres formels correspondants.
4

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Dfinition et appel d'une procdure (au sens algorithmique) : les fonctions void
Le mot procdure n'existe pas en C++. On parle de fonction void. (void veut dire vide en anglais). Il faut obligatoirement indiquer void comme type retourn. Une fonction void ne contient pas d'instruction return.

void Affiche_acceuil (char s, char em)


{ if ( s == 'm' ) cout << "Bonjour Monsieur"; else { if (em== 'c' ) cout <<"Bonjour Mademoiselle"; else cout << "Bonjour Madame"; }

Si vous oubliez le void, le compilateur affectera int comme type de retour (car int est le type par dfaut), ce qui entranera une erreur. L'appel d'une fonction void correspond une instruction part entire et se fait donc sur une ligne part. On ne peut pas utiliser l'appel l'intrieur d'une instruction puisqu'il ne correspond aucune valeur. Exemple: # include main( ) { char hf, ec; cout<< "Tapez m si vous tes un homme ou f si vous tes une femme"; cin >> hf; cout << "Tapez c si vous tes clibataire ou m si vous tes mari"; cin >> ec;

Affiche_acceuil(hf, em); //l'appel lui-mme est une instruction


getch( ); }

Agencement des fonctions entre elles


Le compilateur n'accepte d'appeler une fonction que s'il connat toutes ses caractristiques (nom, type de la valeur de retour et type des paramtres). Si l'appel d'une fonction se trouve aprs la dfinition de cette fonction, celle-ci est connue du compilateur, donc cette mthode va fonctionner. Mais cette solution n'est gure utilise en pratique. En ralit, une fonction est seulement dclare avant d'tre appele et sa dfinition est reporte aprs celle de la fonction appelante.

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Pour les fonctions dfinies par le programmeurs, deux mthodes sont possibles: - soit on dfinit compltement la fonction appele avant la fonction appelante - soit on commence par dclarer le prototype de la fonction appele, on dfinit la fonction appelante puis on dfinit compltement la fonction appele ( la suite de la fonction appelante ou dans un autre fichier). La deuxime mthode est la plus courante et c'est celle que nous utiliserons. Dclaration d'une fonction : le prototype La dclaration d'une fonction passe par l'criture de son prototype. Le prototype d'une fonction a la mme syntaxe que son en-tte, et est termin par un ; La dclaration des fonctions se fait au dbut du code source, avant le main( ).
Exemple complet // 1) inclusion des fichiers d'en-tte pour utiliser les fonctions prdfinies # include <iostream.h> # include <math.h> // 2) dclaration = prototype de la fonction somcarre ( )

float somcarre (float a, float b);


// 3) dfinition de la fonction main ( ) : programme principal main ( ) { double v; float n1, n2; cout << "entrez deux nombres"; cin >> n1, n2; v = (somcarre(n1, n2) (n1+n2)) / n; // instruction contenant l'appel de la fonction somcarre ( ) cout << "l'cart type de ces nombres est" << sqrt(v); } // 4) dfinition de la fonction somcarre ( ) float somcarre (float a, float b) //en-tte { float sc; sc = a * a + b * b; return sc; }

Remarque : Le prototype des fonctions prdfinies est contenue dans le fichier d'en-tte correspondant la directive #include Le compilateur connat toutes les fonctions dfinies dans les fichiers d'en-tte inclus dans le code source.

Le passage des paramtres


le passage par valeur : passage par dfaut Par dfaut les paramtres d'une fonction en C++ sont passs par valeur. Cela signifie qu' l'appel, la valeur des paramtres effectifs est copie dans les paramtres formels correspondants. Au retour d'appel, la valeur des paramtres effectifs est inchange, mme si les paramtres formels ont t modifis par la fonction.

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Ce type de passage de paramtre par valeur est donc bien adapt pour les paramtres correspondant des donnes. En revanche, il est inadapt pour grer des paramtres rsultats ou donnes-rsultats. Voyons un exemple qui montre que le passage par valeur ne permet pas de modifier les paramtres effectifs: //cette fonction void change les valeurs des paramtres (croit-on) void echange (int x, int y) { int temp; cout << "\n\nDans la fonction"; cout << "avant echange \npremier parametre " << x << "\tdeuxieme parametre " << y; temp = x; x = y; y = temp; cout << "\naprs echange \npremier parametre " << x << "\tdeuxieme parametre " << y; } //test de la fonction main() { int n = 10; int p = 20; cout << "avant appel \npremier nombre " << n << "\ndeuxieme nombre " << p; echange(n, p); cout << "\n\naprs appel \npremier nombre " << n << "\ndeuxieme nombre " << p; } /*on s'attend ce que les valeurs de n et de p soient inverses aprs l'appel de la fonction, mais il n'en est rien, car le passage par valeur ne permet pas d'accder aux paramtres effectifs*/ Sortie d'cran correspondante :

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Le passage par rfrence : & Pour crer un paramtre rsultat ou donne-rsultat, il faut utiliser un autre mode de passage de paramtre : le passage par rfrence (appel passage par variable dans d'autres langages). Pour dclarer un paramtre formel qui doit tre pass par rfrence, on le prcde du signe &. Ainsi, toute modification du paramtre formel se rpercute directement sur le paramtre effectif correspondant. Tout se passe comme si la fonction agissait directement sur le paramtre effectif. Dans notre exemple, les deux paramtres formels x et y ont le statut donne-rsultat. Pour que l'change se rpercute sur les paramtres effectifs n et p, il faut donc passer x et y par rfrence. //cette fonction void change les valeurs des paramtres (vraiment !) void echange (int & x, int & y) { int temp; cout << "avant echange \npremier parametre " << x << "\ndeuxieme parametre " << y; temp = x; x = y; y = temp; cout << "aprs echange \npremier parametre " << x << "\ndeuxieme parametre " << y; } /* la fonction principale ne change pas. L'appel se fait de la mme manire, que les paramtres soient transmis par valeur ou par rfrence. */ main( ) { int n = 10; int p = 20; cout << "avant appel \npremier nombre " << n << "\ndeuxieme nombre " << p; echange(n, p); cout << "aprs appel \npremier nombre " << n << "\ndeuxieme nombre " << p; }

Le cas particulier des tableaux


Le langage C++ permet de transmettre un tout un tableau en paramtre d'une fonction, mais le mcanisme de transmission par dfaut est particulier (les tableaux ne sont jamais passs par valeur) Un seul mode de transmission des paramtres existe pour les tableaux : il s'agit du passage par adresse. Avec ce mode de transmission, tout comme le passage par rfrence, tout se passe comme si la fonction appele travaillait directement avec le tableau mentionn lors de l'appel. Bien que le passage par adresse et le passage par rfrence ont des points communs, ils ne fonctionnent pas de la mme manire. Un tableau ne peut pas tre pass par rfrence : il ne faut jamais le faire prcder de &, mme si c'est un rsultat !

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Exemple : void raz(int tab[5]);

//prototype de la fonction void raz

main( ) { int i; int t1[5] = {2, 6, 3 , 1, 4} cout << " tableau avant appel de raz\n"; for( i=0; i<5; i++) cout << t1[i] << " "; raz(t1); //appel de la fonction avec le tableau en paramtre cout << "\ntableau aprs appel de raz"; for( i=0; i<5; i++) cout << t1[i]; } void raz(int tab[5]) //dfinition de la fonction void raz { for(int i = 0; i<5; i++) tab[i] =0; } sortie d'cran : tableau avant appel de raz 2 6 3 1 4 tableau aprs appel de raz 0 0 0 0 0

Cas des paramtres tableau de taille variable Il est possible de passer en paramtre un tableau dont la taille est variable (crochets vides). La taille effective (ou le nombre d'lments utiliss) du tableau pass en paramtre doit alors tre passe aussi en paramtre. Cela permet d'utiliser une fonction traitant des tableaux, avec des tableaux de taille diffrente. Voil comment on pourrait adapter la fonction raz dfinie prcdemment : void raz(int tab[ ], int taille) //dfinition de la fonction void raz { for(int i = 0; i<taille; i++) tab[i] =0; } l'appel de cette fonction void comporterait alors deux paramtres: le nom du tableau, puis sa taille : raz ( t1, 5); et on pourrait utiliser cette fonction avec d'autres tableaux de int de taille diffrente raz(t2, 10); //avec t2 un tableau d'entiers d'au moins 10 lments

S. Laporte

Cours de C++ : les fonctions

Lyce Louise Michel BTS IG 1

Les variables globales ( utiliser le moins possible !)


Il est possible de dfinir des variables globales : ce sont des variables communes toutes les fonctions d'un mme fichier source (y compris le programme principal). Toutes les fonctions peuvent utiliser et modifier une variable globale. Une variable globale doit tre dclare avant le main, juste avant ou aprs les prototypes des fonctions. int g; //variable globale void ajoute_un( ); //prototype main( ) { g = 10; //initialisation de g ajoute_un( ); cout << g; //affiche la nouvelle valeur de g qui est 11 } void ajoute_un( ) { g = g + 1; } Attention ! Une variable globale peut tre cache par une variable locale! Les variables globales ont une porte qui s'tend l'ensemble du programme et de ses fonctions. Mais si une variable locale une fonction porte le mme nom qu'une variable globale, cette variable locale cache la variable globale qui ne peut alors plus tre utilise. Cela entrane souvent des erreurs difficilement dcelables. Il ne faut donc jamais dclarer une variable de mme nom qu'une variable globale. Mme exemple avec redclaration de g dans la fonction int g; //variable globale void ajoute_un( ); main( ) { g = 10; //initialisation de g ajoute_un( ); cout << g; //affiche la valeur de la variable globale g qui n'a pas t modifie par la fonction ajoute_un } void ajoute_un( ) { int g; //la variable locale g cache la variable globale de mme nom g = g + 1; //la variable globale n'est plus accessible. L'incrmentation se fait en local }

10