Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parHippolyte Fleury Modifié depuis plus de 8 années
1
CINI – Li115 1 Semaine 6 Les fonctions ● Pourquoi écrire des fonctions ? ● Définition de fonctions ● Fonction main ● Appels de fonctions ● Portée des variables ● Passage par valeur
2
CINI – Li115 2 Pourquoi écrire des fonctions ? (1) ● Pourquoi écrire des fonctions ? ● Jusqu'à présent, nous avons écrit de petits programmes permettant de résoudre de petits problèmes. ● Pour de plus grands problèmes, il est nécessaire de les décomposer en sous-problèmes ● → écriture de fonctions ● Qu'est-ce qu'une fonction ? ● Une fonction définit le programme permettant de résoudre un problème. ● Ce problème peut lui-même être décomposé.
3
CINI – Li115 3 Pourquoi écrire des fonctions ? (2) ● Les fonctions constituent le mécanisme principal de structuration offert par le langage C. ● Avantages des fonctions : ● Meilleure organisation et lisibilité du code : – Le programme est décomposé en sous-programmes. ● Plus facile à « débugger » : – Chaque fonction peut être testée séparément du reste du programme. ● Ré-utilisabilité du code : – Il est possible de réutiliser des fonctions déjà écrites pour résoudre d'autres problèmes. C'est le cas des bibliothèques de fonctions prédéfinies. ● Mutualisation du code : – Possibilité d'échanger des fonctions avec d'autres programmeurs et d'utiliser leur code.
4
CINI – Li115 4 Pourquoi écrire des fonctions ? (3) ● Exemples : #include int main(){ /* affichage de factorielle 5 et factorielle 9 */ int fact5, fact9; int i; fact5 = 1; fact9 = 1; for(i=1; i<=5; i++){ fact5 = fact5 * i; } CINI_print_string("La factorielle de 5 vaut : "); CINI_print_int(fact5); CINI_newline(); for(i=1; i<=9; i++){ fact9 = fact9 * i; } CINI_print_string("La factorielle de 9 vaut : "); CINI_print_int(fact9); CINI_newline(); return 0; }
5
CINI – Li115 5 Pourquoi écrire des fonctions ? (4) ● Exemples : #include int factorielleN(int n){ int res = 1; int i; for(i=1; i<=n; i++){ res = res * i; } return res; } int main(){ /* affichage de factorielle 5 et factorielle 9 */ int fact5, fact9; fact5 = factorielleN(5); fact9 = factorielleN(9); CINI_print_string("La factorielle de 5 vaut : "); CINI_print_int(fact5); CINI_newline(); CINI_print_string("La factorielle de 9 vaut : "); CINI_print_int(fact9); CINI_newline(); return 0; }
6
CINI – Li115 6 Pourquoi écrire des fonctions ? (5) ● Exemples : #include int factorielleN(int n){ int res = 1; int i; for(i=1; i<=n; i++){ res = res * i; } return res; } void afficheFact(int n, int factN){ CINI_print_string("La factorielle de "); CINI_print_int(n); CINI_print_string(" vaut : "); CINI_print_int(factN); CINI_newline(); } int main(){ /* affichage de factorielle 5 et factorielle 9 */ afficheFact(5,factorielleN(5)); afficheFact(9,factorielleN(9)); return 0; }
7
CINI – Li115 7 Définition de fonctions (1) ● Principe d'une fonction : ● 0 à n 0 à 1 valeur ● paramètres de retour ● Définition d'une fonction Corps de la fonction : bloc d'instructions En-tête de la fonction type_retour identifiant (paramètres_formels) { Suite d'instructions }
8
CINI – Li115 8 Définition de fonctions (2) ● Exemples : int somme (int a, int b){ int res = a + b; return res; } int sommeBis(int a, int b){ return a + b; } float multiplie (float f, int a){ return f * a ; } void afficheCoucou(){ CINI_print_string("Coucou"); CINI_newline(); }
9
CINI – Li115 9 Définition de fonctions (3) ● Type de retour : type de la valeur renvoyée par la fonction ● → int, float, bool, char, void ● Une fonction dont le type de retour est « void » est une fonction qui ne retourne rien. Ces fonctions sont également appelées « procédures » dans d'autres langages. ● Identifiant : mêmes règles que pour les noms de variables ● Paramètres formels : ● Liste de déclarations des récipients (type et nom) associés aux arguments transmis à la fonction lors de son appel. ● Cette liste peut être vide. ● Le type de chaque variable doit être spécifié. ● Les déclarations des variables sont séparées par des virgules.
10
CINI – Li115 10 Définition de fonctions (4) ● Corps de la fonction : suite d'instructions Le corps de la fonction définit la suite des instructions nécessaires à la réalisation du sous-programme. ● Le corps de la fonction est un bloc d'instructions. ● Les déclarations de variables sont réalisées en tête du bloc de la fonction. ● Pour toute exécution de fonction dont le type de retour n'est pas void, chaque branche d'exécution doit se terminer par une instruction de retour de valeur : – return expression ; ● Où expression correspond au résultat retourné par la fonction. ● Le type de l'expression est le même que le type de retour de la fonction.
11
CINI – Li115 11 Définition de fonctions (5) ● Que se passe-t-il si l'instruction return d'une fonction de type de retour non void est « oubliée » ? int somme (int a, int b){ int res = a + b; } Cours6ex0.c:5: attention : « return » manquant dans une fonction devant retourner une valeur Attention à la compilation :
12
CINI – Li115 12 Définition de fonctions (6) ● Prototype d'une fonction : type_retour identifiant (paramètres_formels); ● Le prototype d'une fonction décrit comment utiliser cette fonction. ● Le prototype est une déclaration. Il déclare la fonction. ● Le prototype n'est pas suivi du corps de la fonction. ● Le prototype est également appelé : signature de fonction, en- tête de fonction ou déclaration de fonction. ● Exemples de prototypes : int factorielleN(int n); ● int somme(int a, int b); void afficheCube(int n);
13
CINI – Li115 13 Définition de fonctions (7) ● Conseils pour écrire des fonctions : ● Ecrire le plus possible de fonctions, les plus petites possibles (réutilisation future). ● Toujours regarder s'il n'existe pas une fonction dans une bibliothèque qui résout le problème. ● Toujours commencer par se demander quels sont les paramètres formels et le type de retour de la fonction. ● Différencier les fonctions qui réalisent des affichages et les fonctions qui retournent des résultats. ● Mettre un commentaire au dessus pour expliquer ce que fait la fonction et comment elle s'utilise !
14
CINI – Li115 14 Fonction main ● La fonction de nom « main » ● ne déclare aucun paramètre formel (pour l'UE LI115), ● et retourne un entier. ● L'entier 0 indique que le programme s'est terminé sans erreur (convention du langage C). ● La fonction de nom « main » est la fonction principale du programme. Elle est appelée automatiquement lorsque le programme est exécuté.
15
CINI – Li115 15 Appels de fonctions (1) ● La définition d'une fonction n'exécute pas le programme (suite d'instructions) qui la compose. ● Pour exécuter les instructions, il faut appeler la fonction : – identifiant (paramètres_effectifs); ● Paramètres formels, paramètres effectifs : ● Les paramètres formels sont utilisés lors de la définition de la fonction. ● Lors de l'appel, des valeurs doivent être données à ces paramètres → paramètres effectifs. ● Un paramètre effectif est soit une variable (sa valeur), soit une valeur d'expression ou de retour d'un appel de fonction.
16
CINI – Li115 16 Appels de fonctions (2) ● Exemple : #include ● int cube(int x){ ● return x * x * x; ● } ● void afficheCube(int x){ ● int cube = x * x * x; ● CINI_print_int(cube); ● } ● int main(){ ● int res = cube(3); ● CINI_print_int(res); ● CINI_newline(); ● afficheCube(4); ● CINI_newline(); ● return 0; ● } => L'exécution affiche 27 64 Paramètres effectifs Paramètres formels
17
CINI – Li115 17 Appels de fonctions (3) ● Attention : ● La définition d'une fonction doit toujours précéder son appel. ● L'appel d'une fonction peut se faire uniquement à l'intérieur d'une autre fonction. ● La seule fonction qu'il n'y a pas besoin d'appeler explicitement est la fonction main. ● Le nombre et l'ordre des paramètres formels et des paramètres effectifs d'une fonction doivent être identiques. ● Les variables utilisées au sein d'une fonction doivent être déclarées comme variables locales en tête du corps de la fonction, ou doivent correspondre à des paramètres de la fonction.
18
CINI – Li115 18 Appels de fonctions (4) ● Exemple : Cours6ex1.c: In function ‘main’: Cours6ex1.c:12: attention : implicit declaration of function ‘afficheCube’ 1#include 2 3int cube(int x){ 4 return x * x * x; 5} 6 7 8int main(){ 9 int res = cube(3); 10 CINI_print_int(res); 11 CINI_newline(); 12 afficheCube(4); 13 CINI_newline(); 14 return 0; 15} 16 17void afficheCube(int x){ 18 int cube = x * x * x; 19 CINI_print_int(cube); 20} Attention à la compilation :
19
CINI – Li115 19 Appels de fonctions (5) ● Exemple : 1#include ● 2 ● 3int cube(int x){ ● 4 return x * x * x; ● 5} ● 6 ● 7void afficheCube(int x){ ● 8 int cube = x * x * x; ● 9 CINI_print_int(cube); ● 10} ● 11 ● 12afficheCube(4); ● 13 ● 14int main(){ ● 15 int res = cube(3); ● 16 CINI_print_int(res); ● 17 CINI_newline(); ● 18 return 0; ● 19 } Cours6ex2.c:12: erreur: expected declaration specifiers or ‘...’ before numeric constant Cours6ex2.c:12: attention : data definition has no type or storage class Cours6ex2.c:12: attention : type defaults to ‘int’ in declaration of ‘afficheCube’ Cours6ex2.c:12: erreur: conflicting types for ‘afficheCube’ Cours6ex2.c:7: erreur: previous definition of ‘afficheCube’ was here Erreurs de compilation :
20
CINI – Li115 20 Appels de fonctions (6) ● Exemple : Cours6ex3.c: In function ‘main’: Cours6ex3.c:14: erreur: too many arguments to function ‘cube’ 1#include 2 3int cube(int x){ 4 return x * x * x; 5} 6 7void afficheCube(int x){ 8 int cube = x * x * x; 9 CINI_print_int(cube); 10} 11 12 13int main(){ 14 int res = cube(3, 5); 15 CINI_print_int(res); 16 CINI_newline(); 17 afficheCube(4); 18 CINI_newline(); 19 return 0; 20 } Erreurs de compilation :
21
CINI – Li115 21 Appels de fonctions (7) ● Exemple : 1#include 2 3int cube(int x){ 4 return a * a * a; 5} 6 7void afficheCube(int x){ 8 int cube = x * x * x; 9 CINI_print_int(cube); 10} 11 12 13int main(){ 14 int res = cube(3); 15 CINI_print_int(res); 16 CINI_newline(); 17 afficheCube(4); 18 CINI_newline(); 19 return 0; 20 } Cours6ex4.c: In function ‘cube’: Cours6ex4.c:4: erreur: ‘a’ undeclared (first use in this function) Erreurs de compilation :
22
CINI – Li115 22 Portée des variables (1) ● Variables locales / variables globales : ● Une variable déclarée à l'intérieur d'une fonction est une variable locale. ● Une variable déclarée en début de programme (après les #include et les #define) est une variable globale. ● Portée des variables : ● La portée d'une variable désigne la partie du programme dans laquelle on peut l'utiliser. ● Une variable locale n'est utilisable qu'à l'intérieur de la fonction dans laquelle elle est déclarée. ● Une variable globale est utilisable dans tout le programme. ● Les paramètres formels d'une fonction correspondent à des variables locales initialisées lors de l'appel de la fonction.
23
CINI – Li115 23 Portée des variables (2) ● Structure d'un programme : #include #define... /* Déclaration des variables globales */ /* Définition des fonctions */ int main(){ /* Définition des éventuelles variables locales de main */... return 0; }
24
CINI – Li115 24 Portée des variables (3) ● Exemple : #include int a = 2; int somme(int y){ int x = 3; return a + x + y; } int main(){ int res = somme(7); CINI_print_int(re s); CINI_newline(); return 0; } Portée de la variable globale a Portée de la variable locale x Portée de la variable locale res Portée de la variable locale y
25
CINI – Li115 25 Portée des variables (4) ● Que se passe-t-il en mémoire ? #include int a = 2; int somme(int y){ int x = 3; return a + x + y; } int main(){ int res = somme(7); CINI_print_int(re s); CINI_newline(); return 0; } Avant l'exécution de main : Empilement de la variable locale de main : Après l'appel à somme: Empilement du paramètre d'appel et de la variable locale de somme :
26
CINI – Li115 26 Portée des variables (5) ● Attention : ● Dans une fonction, les paramètres formels et les variables locales déclarées explicitement doivent porter des noms différents. #include int a = 2; int somme(int y){ int y = 3; return a + y + y; } int main(){ int res = somme(7); CINI_print_int(res); CINI_newline(); return 0; } Erreur de compilation : Cours6ex5.c: In function ‘somme’: Cours6ex5.c:7: erreur: ‘y’ redeclared as different kind of symbol Cours6ex5.c:6: erreur: previous definition of ‘y’ was here
27
CINI – Li115 27 Portée des variables (6) ● Variables locales et globales de même nom : ● Lorsqu'une variable locale et une variable globale portent le même nom, la portée de la variable locale masque la portée de la variable globale. #include int a = 2; int somme(int y){ int x = 3; int a = 5; return a + x + y; } int main(){ int res = somme(7); CINI_print_int(re s); CINI_newline(); CINI_print_int(a) ; CINI_newline(); return 0; } Affichage : 1 5 2
28
CINI – Li115 28 Portée des fonctions (1) ● Une fonction f peut être appelée dans n'importe quelle fonction définie après la définition de f. ● Une fonction ne peut pas être appelée en dehors de toute fonction. #include int f1(int y){ int a = 5; return a + x ; } int f2(int x){ return x*x; } int f3(int x){ return x* f2(x); } int main(){ int res = f1(7); CINI_print_int(f2(res )); CINI_newline(); CINI_print_int(f3(res )); CINI_newline(); return 0; } On ne peut PAS appeler f2 et f3 On peut appeler f1 On ne peut PAS appeler f3 On peut appeler f1 et f2 On peut appeler f1, f2 et f3
29
CINI – Li115 29 Portée des fonctions (2) ● Une fonction f1 peut être définie localement à une autre fonction f2. ● La définition de f2 doit être incluse dans f1. ● f2 n'est utilisable que dans f1. #include int f1(int x){ int f2(int x){ return x*x; } return x* f2(x); } int main(){ int res = f1(7); CINI_print_int(res); CINI_newline(); return 0; } Portée de f2 On peut appeler f1 On ne peut PAS appeler f2 A éviter absolument !
30
CINI – Li115 30 Passage par valeur (1) ● Que se passe-t-il ? #include void mystere(int y){ y = 3; } int main(){ int y = 7; CINI_print_int(y); CINI_newline(); mystere(y); CINI_print_int(y); CINI_newline(); return 0; } Quelles sont les valeurs affichées ?
31
CINI – Li115 31 Passage par valeur (2) ● Que se passe-t-il ? #include void mystere(int y){ y = 3; } int main(){ int y = 7; CINI_print_int(y); CINI_newline(); mystere(y); CINI_print_int(y); CINI_newline(); return 0; } Avant mystere :Entrée dans mystere : Avant de sortir de mystere : Après mystere : → y de main → y de mystere → y de main
32
CINI – Li115 32 Passage par valeur (3) ● En C, les paramètres d'une fonction sont passés par valeur : #include void mystere(int y){ y = 3; } int main(){ int y = 7; CINI_print_int(y); CINI_newline(); mystere(y); CINI_print_int(y); CINI_newline(); return 0; } On travaille sur la variable locale y de la fonction mystere et non sur la variable locale y de main. Seule la valeur de la variable y de main est passée en paramètre. => à la sortie de la fonction mystere, la variable locale y de main est inchangée
33
CINI – Li115 33 Passage par valeur (4) ● Comment, via l'exécution de la fonction mystere, modifier la valeur de y qui est affichée ? #include int mystere(){ return 3; } int main(){ int y = 7; CINI_print_int(y); CINI_newline(); y = mystere(); CINI_print_int(y); CINI_newline(); return 0; } En retournant une valeur : OU En déclarant y comme une variable globale : #include int y; void mystere(){ y = 3; } int main(){ y = 7; CINI_print_int(y); CINI_newline(); mystere(); CINI_print_int(y); CINI_newline(); return 0; }
34
CINI – Li115 34 Passage par valeur (5) ● En résumé, une fonction : ● Affiche un résultat (chaîne de caractères ou valeur d'une variable) ● OU ● Modifie une variable globale ● OU ● Retourne un résultat ● En LI115, ces « OU » seront exclusifs afin de mettre en oeuvre de bonnes pratiques de programmation. ● Nous ne définirons donc pas de fonctions qui affichent ET retournent un résultat.
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.