procédures et fonctions la modularité et ses avantages. exemples en c. notion de blocs et portée...

72
Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales. Déclaration et définition de fonctions. Communication entre fonctions. Renvoi d’un résultat. Paramètres formels et effectifs d’une fonction. Mode de transmission des données par valeur ou par adresse. Tableau à une ou deux dimensions comme paramètre d’entrée ou de sortie d’une fonction. Les enregistrements comme paramètres de fonctions. Pile d’exécution. Portée des variables. Le type « void ». Appels de fonctions. Fonction « main ». Fonctions arithmétiques standard. Décomposition d’un programme en fonctions.

Upload: corine-chopin

Post on 04-Apr-2015

136 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

Procédures et fonctions

La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales. Déclaration et définition de fonctions. Communication entre fonctions. Renvoi d’un résultat. Paramètres formels et effectifs d’une fonction. Mode de transmission des données par valeur ou par adresse. Tableau à une ou deux dimensions comme paramètre d’entrée ou de sortie d’une fonction. Les enregistrements comme paramètres de fonctions. Pile d’exécution. Portée des variables. Le type « void ». Appels de fonctions. Fonction « main ». Fonctions arithmétiques standard. Décomposition d’un programme en fonctions.

Page 2: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

2

Les modules Jusqu’ici, nous avons résolu nos problèmes à l’aide de fonctions prédéfinies

(printf de stdio, strlen de string, …) et d’une seule fonction nouvelle :la fonction principale main().

Pour résoudre des problèmes plus complexes, nous avons alors besoin deprogrammes longs, peu structurés et souvent peu compréhensibles.

En plus, dans un même programme, on doit répéter plusieurs fois plusieurssuites d’instructions ce qui entraîne un gaspillage en espace mémoire.

Objectif de ce chapitre :

Définir et utiliser nos propres fonctions afin de rendre nos programmesmodulaires.

Définition d’un module (une fonction en C) :

Désigne une entité constituée de données et d’instructions agissant surces données qui fournissent une solution à une partie bien définie d’unproblème plus complexe.

Un module peut faire appel à d’autres modules, leur transmettre desdonnées et en recevoir. L’usage de ces modules doit permettre derésoudre le problème original.

Page 3: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

3

Avantages d’un programme modulaire

Meilleure lisibilité.

Diminution du risque d’erreurs.

Dissimulation des méthodes :

Lors de l’utilisation d’un module, il faut seulement connaître son effet,sans devoir se préoccuper des détails de son implantation.

Réutilisation de modules déjà existants :

Cela permet d’utiliser maintes fois une portion de code déjà écrite.

Simplicité de l’entretien :

Des modifications peuvent être apportées à un module sans devoirtoucher aux autres modules du programme.

Favoriser le travail en équipe :

Un programme peut être développé en équipe par délégation de laprogrammation des modules à différentes personnes ou groupes.

Hiérarchisation des modules : Donne lieu à une méthodologie de program-mation (méthode de raffinement successif).

Page 4: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

4

Modules fonctions en C

Dans l’environnement de programmation C ou C++, il existe plusieurslibrairies de fonctions disponibles.

Exemple :

Page 5: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

5

Fonctions en tant que boîte noire

Par exemple, sqrt retourne la racine carrée d’un nombre x à virgule flottantepassé en paramètre.

On peut se servir de cette fonction sans connaître les détails de sonimplantation.

Lors d’un appel à cette fonction, la valeur du paramètre x est transmiseà la fonction sqrt.

1.

L’exécution de la fonction main est temporairement suspendue.2.

La fonction sqrt devient active et calcule la valeur de renvoi x.3.

Cette valeur de renvoi x est transmise en retour à la fonction main().4.

La fonction main() termine le calcul en employant cette valeur.5.

Page 6: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

6

Fonctions en tant que boîte noire

La valeur d’entrée d’une fonction n’est pasobligatoirement une variable unique, maispeut être une expression quelconque dontle type correspond au type du paramètre.

Exemple : b * b – 4 * a *c.

Page 7: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

7

Usage de la fonction sqrt

#include <stdio.h>#include <cmath>

void main(){

float a, b, c, discriminant;

printf("Entrez les coefficients a, b, c : ");scanf("%f%f%f", &a, &b, &c);

discriminant = (float) sqrt(b * b - 4 * a * c);

printf("L'equation du second degre %f x * x + " "%f x + %f = 0 possede les racines suivantes :" " %f et %f.\n",

a, b, c, (discriminant - b) / (2 * a),(discriminant + b) / (-2 * a));

}

Page 8: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

8

Généralités sur les fonctions

Certaines fonctions possèdent plusieurs entrées comme, par exemple, lafonction pow(x, y) possède 2 paramètres x et y en entrée et calcule xy.

Toute fonction accepte des entrées et une valeur de renvoi d’un typeparticulier.

Ex. : sqrt accepte en entrée et comme valeur de renvoi un nombre.

Pour définir notre propre fonction, nous avons la syntaxe suivante :

type de la valeur de renvoi nom de la fonction (paramètre1, paramètre2, …, paramètren)

{déclarations localessuite d’instructions

}Ex. : double absolu(double x)

{if (x >= 0) return x; else return –x;

}

Page 9: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

9

Modules fonctions en C

Exemple I : Afficher à l’écran un rectangle de longueur L et de hauteur H,formé d’astérisques.

********************************************

H

L

#include <stdio.h>// Affiche un rectangle formé d'astérisques.// Paramètres d’entrée :// Longueur : longueur du rectangle,// Hauteur : hauteur du rectangle. // Valeur de renvoi :// Nil.

void Rectangle(int Longueur, int Hauteur){

int i, j;for (i = 1; i <= Hauteur; i++){

for (j=1; j<=Longueur; j++) printf("*");printf("\n");

}}

Cette fonctionne possède pasde valeur de renvoi.

Page 10: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

10

Modules fonctions en C

void main(){

// Déclaration des variables de la fonction principale.

int L, // Longueur du rectangle.H; // Hauteur du rectangle.

// Saisie de la dimension du rectangle.

printf("Entrez la longueur(L) et la hauteur(H) du rectangle : ");scanf("%d%d", &L,&H);

// Affichage d'un rectangle L x H formé d'astérisques.

Rectangle(L, H);}

void main()Variables locales: L, HFonction : Rectangle(L, H)

void Rectangle(int Longueur, int Hauteur)Variables locales: Longueur, Hauteur, i, j

Page 11: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

11

Modules fonctions en C

main

L

H

Rectangle

Longueur

Hauteur

Les paramètres sontinitialisés lors del’appel de la fonction.

Note : L’ordre dans lequel les fonctions sont définies est importante. Unefonction doit être définie avant son utilisation.

Page 12: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

12

Calcul de la valeur d’un compte d’épargne

Exemple II : Calculer la valeur d’un compte d’épargne possédant un soldeinitial s au bout de n années. Si le taux d’intérêt est de p%,le solde au bout de n années est : s (1 + p / 100)n.

#include <stdio.h>#include <cmath>

// Calcule la valeur d'un compte d'épargne.// Paramètres d’entrée :// s : valeur initiale de l’investissement,// n : le nombre d’années de conservation de l’investissement,// p : taux d'intérêt par année, en pourcentage,// Valeur de renvoi :// le solde après n années.

double Valeur_Compte(double s, int n, double p){

double b = s * pow(1.0 + p / 100.0, (double) n);return b;

} L’instruction return permet de retourner la valeur de renvoi.On aurait pu écrire : return s * pow(1.0 + p / 100.0, (double) n);

Page 13: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

13

Calcul de la valeur d’un compte d’épargne

void main(){

// Déclaration des variables de la fonction principale.float solde_initial;int periode;float taux_d_interet;

// Entrée des trois paramètres de la fonction.

printf("Entrez le solde initial, la periode et le taux d'interet : ");scanf("%f%i%f", &solde_initial, &periode, &taux_d_interet);

// Affichage de la valeur du compte d'épargne.

printf("\nValeur du compte d'epargne : %f\n",Valeur_Compte(solde_initial, periode, taux_d_interet));

}

Note : On a pensé à la réutilisation lors de la définition de la fonctionValeur_Compte en optant pour 3 paramètres clés.

Page 14: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

14

Présence de commentaires

Les commentaires sont là pour le bénéfice des humains et non pour lescompilateurs.

Parmi les humains visés, la priorité doit être donnée à l’utilisateur de lafonction plutôt qu’au programmeur.

Les commentaires présents doivent décrire précisément le rôle joué parcette fonction et non des détails d’implantation.

Écrire d’abord les commentaires propres à une fonction avant son code.Cela permet de vérifier votre compréhension du rôle joué par cette fonction.

Ajouter, le cas échéant, les conditions qui s’appliquent aux paramètresd’entrée. Ces conditions seront prises en compte plus tard.

Ex. : // Calcule la sommation suivante : 1 + 2 + 3 + . . . + n.// Paramètre d’entrée :// n : le nombre de termes dans la sommation.// n ≥ 1.// Valeur de renvoi :// la valeur de l’expression : n (n + 1) / 2.

Page 15: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

15

Renvoi du résultat

Lorsque l’instruction return est exécutée, la fonction prend fin immédiatementavec la transmission de la valeur de retour.

double Valeur_Compte(double s, int n, double p){

if(n == 0 || p == 0) return s;double b = s * pow(1.0 + p / 100.0, (double) n);return b;

}

Il est important que chaque alternative à l’intérieur de la fonction nous mèneà une instruction return.

double Valeur_Compte(double s, int n, double p){

if(n >= 0 && p >= 0) return s * pow(1.0 + p / 100.0, (double) n);}

Le type du résultat peut être un type simple, un type pointeur, un type struct,un type union ou void. Une fonction ne peut pas fournir comme résultat untableau, une chaîne de caractères ou une fonction mais un pointeur sur le 1e

élément d’un tableau ou d’une chaîne de caractères.

Page 16: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

16

Fonction prédicat

Une fonction prédicat est une fonction qui retourne une valeur TRUE ouFALSE.

#include <iostream.h>#include <cmath>

// Détermine si un nombre entier positif est premier ou non.// Paramètre d'entrée :// n : un nombre entier positif.// Valeur de renvoi :// TRUE si n est un nombre premier,// FALSE autrement.

bool Premier(int n){

for (int i = 2; i <= (int) sqrt(n); i++)if ((n%i) == 0) return false;

return true;}

Page 17: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

17

Fonction prédicat

void main(){

int entier;

cout << "Entrez un nombre entier : ";cin >> entier;

if (Premier(entier)) cout << entier << " est un nombre premier.\n";else cout << entier << " n'est pas un nombre premier.\n";

}

Page 18: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

18

Paramètres

Lors de l’exécution d’une fonction, les paramètres de la fonction sont d’abordinitialisés à partir des expressions fournies lors de l’appel. Il s’agit simplementd’une copie où la vérification de types est effectuée.

#include <iostream.h>int min(int u, int v, int w){

if (u < v) v = u;if (v < w) w = v;return w;

}

void main(){

int A = 3, B = 2;cout << min(A, 2, A + B);

}

Les paramètres u, v, wde la fonction peuvent êtremodifiés par la suite; celan’a pas d’impact sur lafonction appelante.

Expressions permettant d’initialiserles paramètres de la fonction lors de l’appel.

Mauvaise habitude :cela porte à confusion(voir plus loin).

Page 19: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

19

Noms significatifs pour les paramètres

Choisir des noms explicites pour des paramètres possédant un rôle spécifiqueet des noms simples pour ceux restant génériques.

Objectif : Le lecteur doit comprendre le but du paramètre sans avoirà lire sa description.

Exemples :

double sin(double radian) est préférable à double sin(double x).

Cela précise que l’angle ne peut être fourni en degrés.

En C++, double atan2(double y, double x) porte à confusion.Est-ce tan-1(x / y) ou tan-1(y / x) ?Écrivons plutôt : double atan2(double numerator, double denominator)

bool approx_egal(double x, double y)// Des noms simples sont appropriés.

Page 20: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

20

Valeurs par défaut pour les paramètres

Évalue un polynôme de degré 3 de la forme :

a0 + a1 x + a2 x2 + a3 x3.

Paramètres d'entrée :a0, a1, a2, a3 : les coefficients du polynôme,x : la valeur de la variable indépendante.

Valeur de renvoi :la valeur du polynôme de degré 3.

#include <iostream.h>

float Polynome_de_degre_3(float x, float a0, float a1 = 0, float a2 = 0, float a3 = 0)

{return a0 + (a1 + (a2 + a3 * x) * x) * x;

}

Exemple :

valeurs par défaut

Page 21: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

21

Valeurs par défaut pour les paramètres

void main(){

float x = 2.3f;cout << "La valeur du polynome pour x = "

<< x << " est : " << Polynome_de_degre_3(x, 7) << endl;

cout << "La valeur du polynome pour x = " << x << " est : " << Polynome_de_degre_3(x, 7, 6) << endl;

cout << "La valeur du polynome pour x = " << x << " est : " << Polynome_de_degre_3(x, 7, 6, 5) << endl;

cout << "La valeur du polynome pour x = " << x << " est : " << Polynome_de_degre_3(x, 7, 6, 5, 4) << endl;

cout << endl << endl;}

Page 22: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

22

Déclaration de prototypes de fonctions

Une fonction doit être connue avant d’être employée. Nous avons résolu leproblème jusqu’à maintenant en définissant d’abord les fonctions élémentairespuis, les fonctions de plus haut niveau et, finalement, la fonction main.

Il se peut qu’une fonction f appelle une fonction g et g fasse de même avec f.On doit alors déclarer au début le prototype d’une fonction pour pouvoirl’appeler avant qu’elle ne soit définie.

type de la valeur de renvoi nom de la fonction (paramètre1, paramètre2, …, paramètren);

Idem à la définition d’une fonction mais sansle corps de la fonction et avec le point-virgule.

Exemple : int max(int u, int v);

Cela indique que la fonction est définie ailleurs, soit plus loin dans le fichieractuel soit dans un autre fichier.

Les déclarations de fonctions classiques comme sqrt sont contenues dans lesfichiers d’en-tête comme cmath.

Page 23: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

23

Déclaration de prototypes de fonctions

Certains programmeurs préfèrent énumérer tous les prototypes de fonctionen haut du fichier, puis écrire main et ajouter la définition des fonctions.

Exemple I :

#include <stdio.h>

// Affiche un rectangle formé d'astérisques.//// Paramètres d’entrée :// Longueur : longueur du rectangle,// Hauteur : hauteur du rectangle.// // Valeur de renvoi :// Nil.

void Rectangle(int Longueur, int Hauteur);

Lors de la déclaration, le nombre et le type des paramètres doiventnécessairement correspondre à ceux de la définition de la fonction.

Page 24: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

24

Déclaration de prototypes de fonctions

void main(){

// Déclaration des variables de la fonction principale.int L, // Longueur du rectangle.

H; // Hauteur du rectangle.

// Saisie de la dimension du rectangle.printf("Entrez la longueur(L) et la hauteur(H) du rectangle : ");scanf("%d%d", &L,&H);

// Affichage d'un rectangle L x H formé d'astérisques.Rectangle(L, H);

}void Rectangle(int Longueur, int Hauteur){

int i, j;for (i = 1; i <= Hauteur; i++){

for (j=1; j<=Longueur; j++) printf("*");printf("\n");

}}

Page 25: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

25

Déclaration de prototypes de fonctions

Exemple II :

Page 26: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

26

Effets secondaires à éviter

Examinons la fonction suivante :

double Valeur_Compte(double s, int n, double p){

if(n == 0 || p == 0) return s;double b = s * pow(1.0 + p / 100.0, (double) n);return b;

}

Pourquoi la fonction n’imprimerait-elle pas la valeur en même temps ?

double Valeur_Compte(double s, int n, double p){

if(n == 0 || p == 0) return s;double b = s * pow(1.0 + p / 100.0, (double) n);cout << "Le solde est maintenant " << b << endl;return b;

}

Un principe à respecter : une fonction ne doit laisser aucune trace à partrenvoyer une valeur.

Page 27: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

27

Effets secondaires à éviter

Une autre mauvaise pratique est d’imprimer des messages d’erreur àl’intérieur d’une fonction.

double Valeur_Compte(double s, int n, double p){

if(n < 0 || p < 0){

cout << "n ou p sont invalides.";return 0;

}

double b = s * pow(1.0 + p / 100.0, (double) n);return b;

}

Page 28: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

28

Modes de transmission des paramètres

Jusqu’à maintenant, nous avons opté pour un mode de transmission desparamètres par valeur qui consiste à copier la valeur des expressions lorsde l’appel de la fonction dans chaque paramètre de la fonction.

Avantage : La fonction appelée ne peut pas altérer le contenu des variablesde la fonction appelante.

Supposons maintenant que nous voulons écrire une fonction Lecturespécifiée comme suit :

#include <stdio.h>

// Lire un nombre entier positif et ranger cette valeur dans la variable// de la fonction appelante.//// Paramètre de sortie// *n : conservera la valeur entière positive lue.

Pour y arriver, on doit transmettre dans la fonction appelante l’adresse de lavariable entière qui conservera la valeur lue et la fonction appelée doit déclarerle paramètre comme pointeur.

Page 29: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

29

Mode de transmission par adresse

void Lecture(int * n){

int i = -1;while (i < 0) scanf("%i", &i);*n = i; // Range la valeur de i dans la variable pointée par n.

}void main(){

int j = 1;Lecture(&j); // L’adresse de la variable j est transmise.printf("%i", j); // Le contenu de j est modifié à partir de la valeur lue.

}

main Lecture

j 1 n à l’appel

après la lecture j 24 n

au retour de la fonction j 24

*n = -1;while (*n < 0) scanf("%i", n);

ou encore

Page 30: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

30

Mode de transmission par adresse

Exemple III : Écrire une fonction PERMUTER qui échange le contenu de 2variables de type int.

Pour modifier le contenude X et Y, PERMUTER abesoin des adresses de Xet Y.

Page 31: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

31

Mode de transmission par adresse

Page 32: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

32

Exemple de fonctions en C

Exemple IV : Tableau de valeurs d’une fonction.

Soit F(x) = x3 – 2 x + 1, on désire construire un tableau de valeurs de cettefonction où N (le nombre de valeurs) ainsi que les valeurs de x sont entrés auclavier.

#include <iostream.h>#include <iomanip.h>void Lire_Nombre_d_evaluations(int * n);

// Lecture du nombre d'évaluations à effectuer.//// Paramètre de sortie ://// *n : contiendra le nombre d'évaluations à réaliser.

Page 33: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

33

Exemple de fonctions en C

void Lire_Vecteur_reel(int n, float x[]);

// Lecture des n composantes réelles d'un vecteur x.//// Paramètre d'entrée ://// n : le nombre de composantes du vecteur x,//// Paramètre de sortie ://// x[] : contiendra les n composantes à évaluer.

x désigne l’adressede la 1ière composantedu vecteur.

Page 34: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

34

Exemple de fonctions en C

void Calculer_Valeurs(int n, float x[], float F[]);

// Calcul de la valeur de la fonction pour chaque composante// dans x.//// Paramètres d'entrée ://// n : le nombre de composantes à évaluer,// x[] : les n composantes du vecteur à évaluer.//// Paramètre de sortie ://// F[] : contiendra la valeur de la fonction// pour chaque composante du vecteur à évaluer.

Page 35: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

35

Exemple de fonctions en C

void Afficher_Resultats(int n, float x[], float F[]);

// Affichage de n valeurs réelles et de la valeur de la fonction pour chaque// valeur réelle.//// Paramètres d'entrée ://// n : le nombre de composantes évaluées,// x[] : les n composantes évaluées,// F[] : contient la valeur de la fonction pour chaque// composante.

Page 36: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

36

Exemple de fonctions en C

void main(){

float Valeurs_de_x[100]; // Valeurs de x.float Valeurs_de_F[100]; // Valeurs de F(x).

int Nombre_d_evaluations;

Lire_Nombre_d_evaluations(&Nombre_d_evaluations);Lire_Vecteur_reel(Nombre_d_evaluations, Valeurs_de_x);Calculer_Valeurs(Nombre_d_evaluations,Valeurs_de_x,Valeurs_de_F);Afficher_Resultats(Nombre_d_evaluations,Valeurs_de_x,Valeurs_de_F);

}

Page 37: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

37

Exemple de fonctions en C

void Lire_Nombre_d_evaluations(int * n){

do{

cout << "Entrez un entier entre 1 et 100 : ";cin >> *n;

}while (*n < 1 || *n > 100);

}

void Lire_Vecteur_reel(int n, float x[]){

cout << "Entrez " << n << " nombres reels :\n";for (int i = 0; i < n; i++) cin >> x[i];

}

Page 38: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

38

Exemple de fonctions en C

void Calculer_Valeurs(int n, float x[], float F[]){

float Fonction(float x);

// Retourne la valeur de la fonction évaluée à x.//// Paramètre d'entrée ://// x : valeur réelle.//// Valeur de renvoi ://// Valeur de la fonction évaluée à x.

for (int i = 0; i < n; i++) F[i] = Fonction(x[i]);}

Note : Il est interdit de définir des fonctions à l’intérieur d’une autre fonction.

Page 39: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

39

Exemple de fonctions en C

float Fonction(float x){

return x * x * x - 2 * x + 1;}

void Afficher_Resultats(int n, float x[], float F[]){

cout << "\n X : ";for (int i = 0; i < n; i++) cout << setw(10) << x[i];

cout << "\n F(X) : ";for (i = 0; i < n; i++) cout << setw(10) << F[i];cout << endl;

}

Page 40: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

40

Modes de transmission par valeur ou par adresse

Pour des raisons de sécurité, on ne choisit pas un mode de transmission paradresse si notre objectif consiste uniquement à transmettre la valeur d’uneexpression à une fonction.

En optant pour un mode de transmission par adresse, l’expression lors del’appel d’une fonction doit être obligatoirement l’adresse d’une variable.

Ex. : Lecture(5);Lecture(u + v);

Page 41: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

41

Passage de l’adresse d’un tableau à une dimension

Comme il est impossible de passer le contenu de tout un tableau à unefonction, on fournit l’adresse d’un élément du tableau.

En général, on fournit l’adresse du premier élément du tableau, qui estdonnée par le nom du tableau.

Déclaration :

Dans la liste des paramètres d’une fonction, on peut déclarer un tableaupar le nom suivi de crochets :

type des composantes nom du tableau []

ou simplement par un pointeur sur le type des éléments du tableau :

type des composantes * nom du tableau

Page 42: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

42

Passage de l’adresse d’un tableau à une dimension

Exemple :

Page 43: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

43

Passage de l’adresse d’un tableau à une dimension

Appel : L’adresse d’un tableau peut être donnée par le nom du tableau,par un pointeur ou par l’adresse d’un élément quelconque du tableau.

Exemple :

Page 44: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

44

Particularités avec un tableau qui n’est pas du type char

Il faut fournir la dimension du tableau ou le nombre d’éléments à traitercomme paramètre, sinon la fonction risque de sortir du domaine du tableau.

Exemple : Lecture de N données dans un tableau.

Page 45: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

45

Passage de l’adresse d’un tableau à 2 dimensions

Problème :

Écrire une fonction qui calcule la somme de tous les éléments d’une matricede réels dont nous fournissons les 2 dimensions N et M comme paramètres.

Comment passer l’adresse de la matrice à la fonction ?

1e option : Déclarer le tableau dans l’en-tête de la fonction sous la forme A[][].

Le compilateur a besoin de la 2ième dimension de A pour déterminerl’adresse de A[i][j].

2e option :

La fonction recevra un pointeur de type float * au début de la matrice.Il s’agit de parcourir tous les éléments comme s’il s’agissait d’un tableauà une dimension N*M.

Page 46: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

46

Passage de l’adresse d’un tableau à 2 dimensions

Appel de la fonction : Il faut transmettre l’adresse du début du tableau.

Prenons par exemple un tableau déclaré par : float A[3][4];

Le nom A correspond à la bonne adresse, mais cette adresse est du typepointeur sur un tableau de 4 éléments de type float. La conversion aura lieuautomatiquement mais vous recevrez un message d’avertissement.

On peut éviter ceci à l’aide d’une conversion explicite.

Page 47: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

47

Passage de l’adresse d’un tableau à 2 dimensions

L’idéal est de renvoyer explicitement l’adresse du 1e élément du tableau :SOMME(&T[0][0], 3, 4).

Page 48: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

48

Notion de bloc et portée des identificateurs

#include <stdio.h>void main(){

int i = 5;if (i == 5){

int j;for (j = 1; j <= i; j++) printf("%i", j);

}}

Les fonctions en C sont définies à l’aide de blocs d’instructions.

Un bloc d’instructions est encadré d’accolades et composé de 2 parties :

{déclarations localesinstructions

}

Exemple :

Cela est vrai aussipour les commandesif, while ou for.

Page 49: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

49

Variables locales

Les variables déclarées dans un bloc d’instructions sont uniquement visibles àl’intérieur de ce bloc. Ce sont des variables locales à ce bloc.

Ex. : Aucune autre fonction n’a accès à la variable NOM :

Ex. : La déclaration de la variable I n’est pas visible à l’extérieur du blocd’instructions conditionnel, ni dans la fonction qui l’entoure.

Page 50: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

50

Variables locales

Une variable déclarée à l’intérieur d’un bloc cache toutes les variablesde même nom des blocs qui l’entourent.

Réfère à la variable de type int.

Réfère à la variable de type double.La variable X de type int n’est pasaccessible.

Note : Éviter de cacher des variables; cela peut mener à des malentendus.Effectuer toutes nos déclarations locales au début des fonctions.

Les paramètres d’une fonction sontdes variables locales initialisées parles valeurs obtenues lors de l’appel.

Page 51: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

51

Passage des paramètres par valeur : exemple

La fonction ETOILES dessine une ligne de N étoiles.

Le paramètre N est modifié àl’intérieur de la fonction.

La fonction TRIANGLE, appelle la fonction ETOILES en utilisant la variable Lcomme paramètre :

Au moment de l’appel, la valeur de L estcopiée dans N. N peut donc être décrémentéeà l’intérieur de ETOILES sans influencer lavaleur originale de L.

Page 52: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

52

Passage des paramètres par valeur : exemple

Page 53: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

53

Variables globales

Les variables déclarées au début du fichier, à l’extérieur de toutes les fonctionssont disponibles partout. Ce sont des variables globales.

Exemple : La variable STATUS est déclarée globalement pour pouvoir êtreutilisée dans les procédures A et B.

Page 54: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

54

Usage des variables globales

Écrire nos programmes aussi localement que possible.

Les fonctions ont accès à des données qui ne leur appartiennent pas.Les données ne sont pas protégées.

Un programme n’est plus constitué de composantes indépendantes;Ces variables globales créent des liens entre les fonctions.

Lors de la définition d’une fonction, il est nécessaire de connaître letraitement accordé aux variables globales dans les autres fonctions.

Solution : Usage de classes.

Page 55: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

55

Règles pour la déclaration de fonctions (prototype)

De façon analogue aux déclarations de variables, nous pouvons déclarer unefonction localement ou globalement.

Déclaration locale

La fonction est déclarée localement dans la fonction qui l’appelle avant ladéclaration des variables. Elle est alors disponible à cette fonction.

Déclaration globale

La fonction est déclarée globalement au début du programme après lesinstructions #include. Elle est alors disponible à toutes les fonctions duprogramme.

Déclaration implicite par la définition

La fonction est disponible à toutes les fonctions qui suivent sa définition.

main

La fonction principale main n’a pas besoin d’être déclarée.

Page 56: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

56

Règles pour la déclaration de fonctions : exemple

Considérons la hiérarchie suivante : main FA FB

Il y a plusieurs possibilités pour déclarer et définir ces 3 fonctions.

1e cas : Déclarations locales des fonctions et définition top-down.

Avantage :

Reflète la hiérarchie des fonctions.

Facile pour un usager qui nes’intéresse qu’à la solution globaledu problème.

Page 57: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

57

Règles pour la déclaration de fonctions : exemple

2ième cas : Définition bottom-up sans déclarations.

Elle débute en bas de la hiérarchie et termine avec la fonction main.Les fonctions qui traitent des détails sont définies en premier lieu.

Inconvénient :

Il est plus difficile de retrouverles dépendances entre les fonctions.

Page 58: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

58

Règles pour la déclaration de fonctions : exemple

3ième cas : Déclaration globale des fonctions et définition top-down.

Approche la plus simplecar nous ne sommes pasforcés de nous occuperde la dépendance entreles fonctions.

Page 59: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

59

Pointeurs de fonctions

Un pointeur vers une fonction contient l’adresse de la fonction en mémoirei.e. l’adresse mémoire du début du code de la fonction.

Les pointeurs vers des fonctions peuvent être passés aux fonctions ourenvoyés, être stockés dans des tableaux et être affectés à d’autrespointeurs de fonction.

Exemple : Tri d’un tableau d’entiers en ordre croissant ou décroissant.

Tiré de Deitel & Deitel, Comment Programmer en C++. Prentice-Hall, 2000.

#include <iostream.h>#include <iomanip.h>// Vérifie si le 1e paramètre est plus grand que le 2e.//// Paramètres d'entrée :// a, b : 2 valeurs entières,// Valeur de renvoi :// TRUE : si a > b, FALSE : si a <= b.bool ascendant(int a, int b){ return a > b; }

Page 60: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

60

Pointeurs de fonctions

// Vérifie si le 1e paramètre est plus petit que le 2e.//// Paramètres d'entrée :// a, b : 2 valeurs entières,//// Valeur de renvoi :// TRUE : si a < b,// FALSE : si a >= b.

bool descendant(int a, int b){

return a < b;}

Page 61: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

61

Pointeurs de fonctions

// Permutation du contenu de 2 variables entières.//// Paramètres d'entrée :// int * pA, int * pB : contient l'adresse des 2 variables entières// à permuter.//// Paramètres de sortie :// int * pA, int * pB : contient l'adresse des 2 variables entières// dont les valeurs ont été permutées.

void permutation(int * pA, int * pB){

int temporaire = * pA;* pA = * pB;* pB = temporaire;

}

Page 62: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

62

Pointeurs de fonctions

// Tri des composantes d'un tableau d'entiers dans un ordre particulier.//// Paramètres d'entrée :// int tableau[] : renferme un tableau d'entiers à ordonner,// int dimension : renferme le nombre de composantes du tableau,// bool (*comparer)(int a, int b) :// pointeur vers une fonction booléenne qui retourne// TRUE si les paramètres a et b doivent être permutés.//// Paramètres de sortie :// int tableau[] : renferme le tableau d'entiers après ordonnancement.

void bulle(int tableau[], int dimension, bool (*comparer)(int a, int b)){

void permutation(int * pA, int * pB);for (int i = 1; i < dimension; i++)

for (int j = 0; j < dimension - 1; j++)if ((*comparer)(tableau[j], tableau[j+1]))

permutation(&tableau[j], &tableau[j+1]);}

Page 63: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

63

Pointeurs de fonctions

void main(){

const int dimensionTableau = 10;int Tableau_a_trier[dimensionTableau]

= {2, 6, 4, 8, 10, 12, 89, 68, 45, 37};int choix;

cout << "Entrez 1 pour un tri en ordre croissant,\n" << "entrez 2 pour un tri en ordre decroissant : ";

cin >> choix;

// Affichage des données dans l’ordre initial.

cout << "\n\nAffichage des donnees dans l'ordre initial : \n";for (int i = 0; i < dimensionTableau; i++)

cout << setw(4) << Tableau_a_trier[i];cout << endl << endl;

Page 64: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

64

Pointeurs de fonctions

// Tri des éléments du tableau en ordre croissant ou décroissant.

if (choix == 1) {

bulle(Tableau_a_trier, dimensionTableau, ascendant);cout << "Affichage des donnees en ordre croissant : \n";

}else{

bulle(Tableau_a_trier, dimensionTableau, descendant);cout << "Affichage des donnees en ordre decroissant : \n";

}

// Affichage des données une fois triée.

for (i = 0; i < dimensionTableau; i++)cout << setw(4) << Tableau_a_trier[i];

cout << endl << endl;}

Page 65: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

65

Pointeurs de fonctions

Un pointeur vers une fonction est aussi utilisé dans les systèmes pilotés parmenus où l’utilisateur doit sélectionner une option parmi les choix proposésqui correspondent chacun à une fonction différente.

Les pointeurs vers chaque fonction sont stockés dans un tableau depointeurs vers des fonctions. Le choix de l’utilisateur sert d’indice au tableau,tandis que le pointeur appelle la fonction.

Exemple : #include <iostream.h>// Calcule la somme de 2 entiers.//// Paramètres d'entrée :// a, b : 2 valeurs entières,//// Valeur de renvoi : a + b// la somme de a et de b.int somme(int a, int b){

return a + b;}

Page 66: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

66

Pointeurs de fonctions

// Calcule la différence de 2 entiers.//// Paramètres d'entrée :// a, b : 2 valeurs entières,//// Valeur de renvoi : a - b// la différence de a et de b.int difference(int a, int b){ return a - b; }

// Calcule le produit de 2 entiers.//// Paramètres d'entrée :// a, b : 2 valeurs entières,//// Valeur de renvoi : a * b// le produit de a et de b.int produit(int a, int b){ return a * b; }

Page 67: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

67

Pointeurs de fonctions

// Calcule le quotient de 2 entiers.//// Paramètres d'entrée :// a, b : 2 valeurs entières,//// Valeur de renvoi : a / b// le quotient de a avec b.

int quotient(int a, int b){

return a / b;}

Page 68: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

68

Pointeurs de fonctions

void main(){

int (*f[4])(int a, int b) ={ somme, difference, produit, quotient};

int u = 5, v = 2;

int choix;

cout << "\nEntrez un nombre entre 0 et 3, ou 4 pour terminer: ";cin >> choix;

while (choix >= 0 && choix <= 3){

cout << (*f[choix])(u, v);cout << "\nEntrez un nombre entre 0 et 3, ou 4 pour terminer: ";cin >> choix;

}}

Page 69: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

69

Structures et fonctions

une structure comme argument d’une fonction:

#include <iostream.h>struct etudiant{

int matricule; int age;char nom[20]; char prenom[20];

};void main(){

bool meme_age(struct etudiant E1, struct etudiant E2);struct etudiant P = {99876123, 23, "Dugre", "Luc"};struct etudiant Q = {98123987, 20, "Dupre", "Leon"};if (meme_age(P, Q)) cout << "Ils sont de meme age.\n";

else cout << "Ils sont d'ages differents.\n";}bool meme_age(struct etudiant E1, struct etudiant E2){

return E1.age == E2.age;}

Rien d’inhabituel.

Page 70: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

70

Structures et fonctions

un pointeur à une structure comme argument d’une fonction :

Si la structure possède un grand nombre de champs, il est préférable d’opterpour un pointeur vers la structure plutôt que la structure elle-même.

Motifs : Économie mémoire et réduction du temps d’exécution.

#include <iostream.h>struct etudiant{

int matricule; int age; char nom[20]; char prenom[20];};void main(){

bool meme_age(struct etudiant const * pE1, struct etudiant const * pE2);struct etudiant P = {99876123, 23, "Dugre", "Luc"};struct etudiant Q = {98123987, 20, "Dupre", "Leon"};if (meme_age(&P, &Q)) cout << "Ils sont de meme age.\n";

else cout << "Ils sont d'ages differents.\n";}bool meme_age(struct etudiant const * pE1, struct etudiant const * pE2){ return (* pE1).age == (* pE2).age; }

Des pointeurs à des structures constantes nousempêchant de modifier le contenu des structures.

Page 71: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

71

Structures et fonctions

un pointeur à une structure comme argument d’une fonction (suite) :

On ajoute const pour empêcher que l’on modifie les données dans la fonction.La fonction meme_age nécessite un accès en lecture seulement desparamètres.

Réécrivons la fonction précédente :

bool meme_age(struct etudiant * const pE1, struct etudiant * const pE2){

return (* pE1).age == (* pE2).age;}

Des pointeurs constants à des structures quinous empêchent de modifier le contenu despointeurs mais non celui des structures.

Page 72: Procédures et fonctions La modularité et ses avantages. Exemples en C. Notion de blocs et portée des identificateurs. Variables globales et variables locales

72

Structures et fonctions

une structure comme valeur de renvoi d’une fonction :

#include <iostream.h>struct etudiant{

int matricule; int age;char nom[20]; char prenom[20];

};void main(){

struct etudiant plus_jeune(struct etudiant E1, struct etudiant E2);struct etudiant P = {99876123, 23, "Dugre", "Luc"};struct etudiant Q = {98123987, 20, "Dupre", "Leon"};

cout << "Le plus jeune a comme age " << plus_jeune(P, Q).age << " ans.\n";

}struct etudiant plus_jeune(struct etudiant E1, struct etudiant E2){

if (E1.age < E2.age) return E1; else return E2;}

Note : La valeur de renvoi pourrait être un pointeur vers une structure.