Vous êtes sur la page 1sur 20

Les fonctions

Les fonctions 166

1) Introduction

▪ On appelle fonction un sous-programme qui permet d'effectuer un ensemble d'instructions par simple appel de la fonction dans le corps

du programme principal.

▪ Les fonctions permettent d'exécuter dans plusieurs parties du programme une série d'instructions,

→ cela permet une simplicité du code et donc une taille de programme minimale.

▪ Une fonction peut faire appel à elle-même, on parle alors de fonction récursive.

▪ Généralement, une fonction retourne une valeur qui est le résultat de l'exécution de son code.

→ Il est possible en C de définir des fonctions qui ne retournent aucune valeur.

→ De telles fonctions sont équivalentes aux procédures définies en algorithmique.

1
Les fonctions 167

2) Déclaration

► Déclaration d'une fonction

▪ La déclaration d'une fonction se fait comme suit:


➢ Syntaxe :
Type NomFonction (Type1 NomArg1,…, Type_n NomArg_n) ;

Avec : Type désigne le type de la valeur retournée par la fonction

Type_i NomArg_i désignent respectivement le type et le nom du ième argument de la fonction

➢ Exemple :

int f (int i, int j); // déclaration d’une fonction nommée f qui retourne un entier et qui a comme paramètres (i et j) de type entier

Les fonctions 168

2) Déclaration

► Déclaration du prototype d'une fonction

▪ Le prototype d'une fonction est une description d'une fonction qui est définie plus loin dans le programme.

▪ Cette description permet au compilateur de « vérifier » la validité de la fonction à chaque fois qu'il la rencontre dans le programme.

▪ On place donc le prototype en début de programme (avant la fonction principale main()).

▪ La déclaration se fait de la manière suivante:


➢ Syntaxe :
Type NomFonction (Type1,…, Type_n) ;

indications : →le prototype n'est pas suivi du corps de la fonction

→ il ne comprend pas le nom des paramètres (seulement leurs types)


➢ Exemple :

int f (int , int ); // déclaration du prototype d’une fonction f qui retourne un entier et qui a deux paramètres de type entier

2
Les fonctions 169

3) Définition

▪ La partie définition d'une fonction correspond au corps de la fonction.

▪ Il s'agit donc de la spécification de l'ensemble des instructions dont l'exécution réalise la tâche assurée par la fonction.

▪ La déclaration se fait de la manière suivante:


➢ Syntaxe :
Type NomFonction (Type1 NomArg1,…, Type_n NomArg_n) {
Déclarations des variables locales;
instruction_1 ;

instruction_n ;
return valeur ;
}

Indication : Les variables locales ne peuvent être utilisées qu'à l'intérieur de la fonction. Elles ne sont pas visibles à l'extérieur.

Les fonctions 170

4) Type d'une fonction et valeur de retour

▪ Le type de la fonction indique le type de sa valeur de retour.

▪ Si aucun type n'est spécifié pour une fonction alors cette dernière est considérée par défaut comme étant de type int.

▪ L'instruction return provoque un arrêt immédiat de l'exécution des instructions du bloc associé à la fonction.

→ Elle permet de renvoyer une valeur à l'extérieur de la fonction en utilisant la syntaxe suivante :

return (valeur) ; Indication : L'utilisation des parenthèses avec return est facultative.

▪ Si l’instruction return est absente du corps d'une fonction, alors le programme continue son exécution des instructions jusqu'à l'accolade
fermant.
▪ La valeur renvoyée par return doit être du même type que celui de la fonction.

3
Les fonctions 171

4) Type d'une fonction et valeur de retour

▪ Une fonction peut être exploitée comme n'importe quelle autre valeur du même type.

▪ Par exemple, elle peut être récupérée et stockée dans une variable de la manière suivante :
int var;
….
var = NomFonction (arg1, arg2, arg3…);

▪ Suite à une exécution, une fonction ne peut retourner qu'une seule valeur et pas plus.

➢ Stratégie 1 : La déclaration de la fonction avant sa première utilisation (avant main()) et la définition après le programme principal.

➢ Stratégie 2 : La déclaration et la définition de la fonction avant sa première utilisation ( avant le programme principal main() ).

Les fonctions 172

4) Type d'une fonction et valeur de retour

▪ Exemple d’application de la stratégie 1 :


#include <stdio.h>

int somme (int, int); // déclaration de la fonction somme


int main(){
int s ; // déclaration d’une variable s qui va recevoir la valeur retournée par la fonction somme
s= somme (5,4); // Appel de la fonction somme
printf(" %d ",s) ; // Affiche somme = 9
return 0;
}
int somme (int a , int b){ // définition de la fonction somme
return a+b ;
}

4
Les fonctions 173

4) Type d'une fonction et valeur de retour

▪ Exemple d’application de la stratégie 2 :


#include <stdio.h>

int somme (int a , int b){ // déclaration et définition de la fonction somme


return a+b;
}
int main(){
int s ; // déclaration d’une variable s qui va recevoir la valeur retournée par la fonction somme
s= somme (5,4); // Appel de la fonction somme
printf(" %d ",s) ; // Affiche somme = 9
return 0;
}

Les fonctions 174

4) Type d'une fonction et valeur de retour

▪ Il est possible d’avoir une fonction sans valeur de retour (procédure).

▪ Par exemple, si on veut définir une fonction qui prend comme paramètre un nombre et qui affiche un message indiquant si ce nombre est

strictement positif, strictement négatif ou nul.

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


Signe (5); // Appel de la fonction Signe
void Signe (int n ){ // déclaration et définition de la fonction Signe return 0;
if (n>0) { }
printf("Positif ") ;
} else if (n<0) {
printf("négatif ") ;
}else{
printf("null ") ;
}
}

5
Les fonctions 175

5) Fonction locale et fonction globale

► Fonction locale

▪ Tout comme les variables, une fonction peut être déclarée en C à l'intérieur d'un bloc (éventuellement une fonction) ou à l'extérieur.

▪ Si la déclaration est faite à l'intérieur alors la fonction est considérée comme locale à ce bloc et ne peut être appelée en dehors de celui-ci.

➢ Exemple :
#include <stdio.h>
int main(){
int somme (int a, int b ){ // déclaration et définition de la fonction somme
return a+b ;
}
int s = somme (5,4); // Appel de la fonction somme
printf("%d",s) ;
return 0 ;
}

Les fonctions 176

5) Fonction locale et fonction globale

► Fonction globale

▪ Une fonction est dite globale, si elle est déclarée en dehors de tout bloc.

▪ Elle peut être dans ce cas appelée de n'importe qu'elle endroit du programme.

➢ Exemple :

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

float moyenne (float n_ds , float n_ex ){ // déclaration et définition de la fonction moyenne int id ; float n_ds ; float n_ex ;

return (n_ds+(n_ex*2))/3; printf(" Donner id = ") ;

} scanf ("%d",&id) ;

void resultat (int id, float n_ds , float n_ex ){ // déclaration et définition de la fonction résultat printf(" Donner une note de DS = ") ;

float res ; res = moyenne (n_ds , n_ex ); scanf ("%d",&n_ds ) ;

if ( res >=10) { printf(" Donner une note de l’examen = ") ;

printf("L'étudiant possédant l’id : %f a réussi la matière ",id) ; scanf ("%d",&n_ex ) ;

}else {
printf("L'étudiant possédant l’id : %f a échoué la matière ",id) ; resultat (id, n_ds , n_ex ) ;

} return 0 ;

} }

6
Les fonctions 177

6) Les catégories des paramètres des fonctions

► Paramètres formels et paramètres effectifs

▪ Deux types de paramètres de fonctions peuvent être distingués : les paramètres formels et les paramètres effectifs.

➢ Les paramètres formels :


#include <stdio.h> Paramètres formels
→ sont ceux qui figurent dans la définition de la fonction.
int somme (int a , int b){
→ Ils sont utilisés dans les instructions faisant partie du bloc de la fonction et là seulement. return a+b ;
}
→ Ces paramètres sont considérés comme des variables locales à la fonction.
int main(){

➢ Les paramètres effectifs : int s, x , y ;


scanf ("%d",&x ) ;
→ sont ceux qui figurent dans l'instruction d'appel de la fonction. scanf ("%d",&y ) ; Paramètres effectifs
s= somme (x, y);
→ Ils sont substitués aux paramètres formels au moment de cet appel.
printf("somme = %d", s) ;
return 0;
}

Les fonctions 178

6) Les catégories des paramètres des fonctions

► Paramètres formels et paramètres effectifs

▪ NB: Les paramètres formels et effectifs doivent s'accorder en nombre, ordre et type.

➢ Exemple:

int main(){
#include <stdio.h>
int s, x , y, z=10 ;
scanf ("%d",&x ) ;
int somme (int a , int b){
scanf ("%d",&y ) ; Le compilateur va afficher un message d’erreur :
return a+b ;
s= somme (x, y, z); error: too many arguments to function ‘somme’
}
printf("somme = %d", s) ; → Les paramètres formels et effectifs doivent s'accorder en nombre
return 0;
}

7
Les fonctions 179

6) Les catégories des paramètres des fonctions

► Différents types des paramètres formels

▪ Suivant le rôle qu'ils assurent dans la fonction, les paramètres formels peuvent être classés en trois catégories :

1. Les paramètres données

2. Les paramètres résultats

3. Les paramètres données-résultats

Les fonctions 180

6) Les catégories des paramètres des fonctions

► Différents types des paramètres formels

▪ Suivant le rôle qu'ils assurent dans la fonction, les paramètres formels peuvent être classés en trois catégories :

1. Les paramètres données

→ Un paramètre "donnée" est une donnée nécessaire pour réaliser la tâche associée à la fonction.

→ Il ne subit aucune modification au cours de l'exécution de la fonction.

Exemple : Les paramètres a et b de la fonction somme sont des paramètres données.


int somme (int a , int b){
return a+b ;
}
….

8
Les fonctions 181

6) Les catégories des paramètres des fonctions

► Différents types des paramètres formels

▪ Suivant le rôle qu'ils assurent dans la fonction, les paramètres formels peuvent être classés en trois catégories :

2. Les paramètres résultats

→ Un paramètre "résultat" est une variable qui est destinée à contenir le résultat de l'action de la fonction.

→ Sa valeur n'est pas significative avant le début.

Exemple : Le paramètre triple de la fonction calculerTriple est un paramètre résultat.

int CalculerTriple (int a , int triple){ int CalculerTriple (int a ){


Généralement un paramètre "résultat" n'a pas
triple = 3 * a ; int triple ;
besoin d'être déclaré comme argument de la
return triple ; triple = 3 * a ;
fonction, mais plutôt comme une variable locale
} return triple ;
…. }
….

Les fonctions 182

6) Les catégories des paramètres des fonctions

► Différents types des paramètres formels

▪ Suivant le rôle qu'ils assurent dans la fonction, les paramètres formels peuvent être classés en trois catégories :

3. Les paramètres données-résultats

→ Un paramètre "donnée-résultat" est à la fois une donnée et un résultat.

→ Il sert à passer une donnée à la fonction et que cette dernière modifie sa valeur.

Exemple : Les paramètres a et b de la fonction Permutation sont des paramètres données-résultats.


void Permutation (int *a , int *b){
int aux ;
aux = *a ; *a=*b ; *b=aux ;
}
….

9
Les fonctions 183

7) Modes de passage des paramètres

► Passage par valeur

▪ C'est le mode de passage d'arguments le plus courant en C et le plus simple également.

▪ Dans ce mode, les valeurs des arguments au moment de l'appel (paramètres effectifs) sont recopiées dans les éléments de données locaux

correspondants à la fonction (paramètres formels).

▪ Après la sortie de la fonction, les valeurs des paramètres effectifs restent identiques à celles qu'ils avaient avant l'exécution de la fonction.

→ Ce mode de passage est adapté aux paramètres de type "données"

→ Pour les paramètres de type "résultat" ou "donnée-résultat", ce mode ne permet pas de récupérer les éventuelles modifications

effectuées au sein de la fonction.

Les fonctions 184

7) Modes de passage des paramètres

► Passage par valeur

▪ La déclaration d'un passage par valeur s'effectue de la manière suivante :

➢ Syntaxe :

TypeFonction NomFonction (……, Type ParamValeur,…);

// TypeFonction : Le type de la valeur retournée par la fontion (int, char, void,…)

// NomFonction : Nom de la fonction

// Type : Le type du paramètre passé par valeur

// ParamValeur : Le nom du paramètre passé par valeur

10
Les fonctions 185

7) Modes de passage des paramètres

► Passage par valeur

▪ La déclaration d'un passage par valeur s'effectue de la manière suivante :

➢ Exemple 1: Le paramètre a est passé à la fonction CalculerTriple par valeur.

… …

void CalculerTriple (int a ){ int main(){


a=3*a; int a ;

} scanf ("%d",&a ) ; // supposons que a = 3


…. CalculerTriple (a)
printf("le résultat est = %d ", a) ;// Affiche 3 puisque la valeur de a n'a pas changé
return 0;
}

Les fonctions 186

7) Modes de passage des paramètres

► Passage par valeur

▪ La déclaration d'un passage par valeur s'effectue de la manière suivante :

➢ Exemple 2 : Les deux paramètres a et b sont passées à la fonction Permutation par valeur.

… … Supposons que a = 1 et b = 2

void Permutation (int a , int b){ int main(){ // Appel de la fonction Permutation

int aux ; int a,b ; Résultat ?

aux = a ; scanf ("%d",&a ) ; scanf ("%d",&b ) ; Affiche a=1 b=2 (Les valeurs n’ont pas changé)
a=b; Permutation (a, b); → La modification effectuée sur a et b à l'intérieur
b = aux ; printf("a = %d | b = %d ", a , b) ; de la fonction Permutation n'est pas récupérée à
} return 0; l'extérieur de cette dernière.
} Pourquoi ?
….

11
Les fonctions 187

7) Modes de passage des paramètres

► Passage par valeur

▪ Réponse : Les valeurs des arguments au moment de l'appel (paramètres effectifs) sont recopiées dans les éléments de données locaux

correspondants à la fonction (paramètres formels).

… a 1 2 b …
void Permutation (int a , int b){ int main(){ Copier
int aux ; a b aux
aux = a ; 1 2 1 …
a=b; 2 2 1 Permutation (a, b); 1 2
b = aux ; 2 1 1 … a b
} }
….

Les fonctions 188

7) Modes de passage des paramètres

► Passage par adresse

▪ Dans un passage par adresse d'un argument on impose à la fonction de travailler non plus sur une copie locale du paramètre effectif, mais

plutôt directement sur ce dernier.

→ Pas de copie du paramètre effectif dans le paramètre formel, le travail se fait directement sur le paramètre effectif.

▪ De cette façon, toute modification effectuée à l'intérieur de la fonction sera en réalité réalisée sur le paramètre effectif.

→ Les modifications seront visibles à l'extérieur de la fonction.

▪ Ce mode de passage de paramètre est effectué en faisant passer à la fonction l'adresse du paramètre effectif.

→ Toute référence à ce dernier de l'intérieur de la fonction doit se faire à l'aide de l'opérateur d'indirection (*)

12
Les fonctions 189

7) Modes de passage des paramètres

► Passage par adresse

▪ La déclaration d'un passage par adresse s'effectue de la manière suivante :

➢ Syntaxe de déclaration

TypeFonction NomFonction (……, Type* ParamAdresse,…); // ParamAdresse étant le paramètre passé par adresse et Type étant son type

➢ Syntaxe de la manipulation d'un paramètre passé par adresse à l'intérieur de la fonction

TypeFonction NomFonction (……, Type* ParamAdresse,…){

… *ParamAdresse ;

➢ Syntaxe de passage du paramètre par adresse au moment de l'appel de la fonction

NomFonction (……, &ParamAdresse,…);

Les fonctions 190

7) Modes de passage des paramètres

► Passage par adresse

➢ Exemple

… a 1 2 b …

void Permutation (int *a , int *b){ int main(){


int aux ; int a, b ;
scanf ("%d",&a ) ; scanf ("%d",&b ) ; Supposons que a = 1 et b = 2
aux = *a ;
Permutation (&a, &b); // Appel de la fonction Permutation Résultat ?
*a=*b ;
*b=aux ; printf("a = %d | b = %d ", a , b) ; 1 2 Affiche a=2 | b=1

return 0; a b → Les valeurs ont changé


}
→ La fonction travaille
…. }
directement sur les
paramètres effectifs.

13
Les fonctions 191

8) Transmission des tableaux comme arguments d'une fonction

▪ Si un tableau figure comme argument d'une fonction alors son passage se fait toujours par adresse.

→ Le passage d'un tableau comme paramètre d'une fonction est impossible en tant que valeur.

→ La recopie du tableau prendrait trop de temps et de place.

→ On passe donc à la fonction l'adresse du tableau.

→ Cela permettra à la fonction d'effectuer des lectures et des écritures directement dans le tableau

→ Toutes les opérations et modifications appliquées à ses éléments seront visibles à l'extérieur de la fonction.

Les fonctions 192

8) Transmission des tableaux comme arguments d'une fonction

▪ Exemples :

➢ Méthode 1 : Paramètre de type tableau avec dimension


// Par adresse …
void Incrementation (int Taille , int TabEnt[Taille]){ int main(){
for (int i =0 ; i<Taille; i++){ // Taille est une constante qui représente la taille du tableau = 5
TabEnt[i]++ ; #define Taille 5
} int TabEnt [Taille]= {0,1,2,3,4} ;
} Incrementation (Taille, TabEnt); // Appel de la fonction Incrementation
for (int i =0 ; i<Taille; i++){
Passage par adresse : printf("%d ", TabEnt[i] ) ; // Affiche 1 2 3 4 5
Le tableau est converti implicitement en pointeur
}
vers son premier élément lors de l'appel .
Ceci serait donc équivalent : return 0;
void Incrementation (int *TabEnt , int Taille)
}

14
Les fonctions 193

8) Transmission des tableaux comme arguments d'une fonction

▪ Exemples :

➢ Méthode 2 : Paramètre de type tableau sans dimension


// Par adresse …
void Incrementation (int TabEnt[], int Taille){ int main(){
for (int i =0 ; i<Taille; i++){ // Taille est une constante qui représente la taille du tableau = 5
TabEnt[i]++ ; #define Taille 5
} int TabEnt [Taille]= {0,1,2,3,4} ;
} Incrementation (TabEnt, Taille); // Appel de la fonction Incrementation
for (int i =0 ; i<Taille; i++){
printf("%d ", TabEnt[i] ) ; // Affiche 1 2 3 4 5
}
return 0;
}

Les fonctions 194

Exercice d’application

▪ Écrire un programme en langage C qui contient les fonctions suivantes:

1) Une fonction « Remplissage » pour remplir un tableau T par N entiers positifs entrés au clavier.

2) Une fonction « Affichage » pour afficher le tableau T.

3) Une fonction « Recherche » qui permet de rechercher et d'afficher les valeurs qui se trouvent dans une plage donnée dans un tableau

d'entiers et l'utilisateur devra spécifier une valeur minimale et maximale de la plage de recherche.

4) Une fonction principale « main » permettant d’utiliser ces fonctions.

15
Les fonctions 195

Exercice d’application

▪ Écrire un programme en langage C qui permet de :

1) Une fonction « Remplissage » pour remplir un tableau T par N entiers positifs entrés au clavier.

// Fonction pour remplir le tableau T int main(){


void Remplissage (int T[], int N) { int N;
int i=0 ; // Demander à l'utilisateur la taille du tableau
printf("Entrez les éléments du tableau :\n"); printf("Entrez le nombre d'éléments dans le tableau : ");
for (i=0 ; i<N;i++) { scanf("%d", &N);
do{ int T[N]; // Déclarer le tableau avec la taille spécifiée
printf("Donner T[%d] : ", i ); Remplissage(T, N);
scanf("%d", &T[i]); return 0;
}while (T[i]<0); }
}}

Les fonctions 196

Exercice d’application

▪ Écrire un programme en langage C qui permet de :

2) Une fonction « Affichage » pour afficher le tableau T..

// Fonction pour afficher le tableau T int main(){


void Affichage (int T[], int N) { ….
int i ; Remplissage(T, N);
printf("les éléments du tableau :\n"); Affichage(T, N);
for ( i = 0; i < N; i++) { return 0;
printf("%d | ", T[i] ); }
}
}

16
Les fonctions 197

Exercice d’application

▪ Écrire un programme en langage C qui permet de :

3) Une fonction « Recherche » qui permet de rechercher et d'afficher les valeurs qui se trouvent dans une plage donnée.

// Fonction pour afficher les valeurs dans la plage spécifiée int main(){
void Recherche (int T[], int N, int valeurMin, int valeurMax ) { ….
int i ; bool valeursTrouvees = false; int valeurMin, valeurMax ;
for (i = 0; i < N; i++) { // Demander à l'utilisateur la plage de recherche
if (T[i] >= valeurMin && T[i] <= valeurMax) { printf("\nEntrez la valeur minimale de la plage : ");
printf("%d ", T[i]); scanf("%d", &valeurMin);
valeursTrouvees = true; } printf("\nEntrez la valeur maximale de la plage : ");
} scanf("%d", &valeurMax);
// Si aucune valeur n'est trouvée dans la plage, afficher un message approprié Recherche (T, N, valeurMin, valeurMax ) ;
if (valeursTrouvees==false) { return 0;
printf("Aucune valeur trouvée dans la plage spécifiée."); } }
}

Les fonctions 198

9) Les fonctions en ligne

▪ Une fonction en ligne est une fonction expansée à chaque appel.

→ En d'autres mots, le corps de la fonction est inséré dans le module appelant à l'endroit de l'appel.

▪ À quoi ça sert ?

→ Les fonctions en ligne permettent d'accélérer l'exécution en évitant les allées-retours entre la fonction et le module appelant.

▪ La fonction inline est l’une des fonctionnalités importantes de C.

Remarques : → La déclaration et la définition d'une fonction en ligne doivent obligatoirement précéder son appel.

→ Les fonctions en ligne sont généralement de petite taille (1 à 3 instructions).

17
Les fonctions 199

9) Les fonctions en ligne

▪ La déclaration de ce type de fonction s'effectue de la manière suivante :

➢ Syntaxe :

inline TypeFonction NomFonction (Type_1 arg_1,…, Type_n arg_n);

➢ Exemples :

// Fonction qui renvoie la valeur absolue de la variable x // Fonction qui renvoie le maximum de deux variables x et y

inline int signe(int x){ inline int max(int x, int y){

return x>0 ? x : -x ; return x>y ? x : y ;

} }

… …

Les fonctions 200

10) Surcharge de fonctions (surdéfinition)

▪ La surcharge de fonctions consiste à proposer plusieurs définitions d'une même fonction au sein d'un même programme.

→ Ces définitions doivent se distinguer par leurs signatures.

→ La signature d'une fonction est définie par le nombre, le type et l'ordre de ses paramètres.

→ La valeur de retour n'entre pas en considération dans ce cas.

// Surcharge correcte ✓ // Surcharge incorrecte ×


int f (int , char) ; int f (int , char) ;
int f (char, int) ; char f (char, int) ;

▪ À quoi ça sert ?

→ On surcharge généralement les fonctions qui font le même traitement, mais sur des données de types différents.

18
Les fonctions 201

10) Surcharge de fonctions (surdéfinition)

▪ La déclaration de ce type de fonction s'effectue de la manière suivante :

➢ Syntaxe :

TypeFonction NomFonction (Type_1 arg_1,…, Type_n arg_n);

➢ Exemples :
// Fonction qui renvoie la position de la valeur maximale dans le // Fonction qui renvoie la position de la valeur maximale dans le
tableau d’entiers T tableau de réels T
int MaxTab(int T[], int n) { int MaxTab(double T[], int n) {
int i, pos, max=T[0] ; int i, pos ; double max=T[0] ;
for(i=1 ; i<n ; i++) { for(i=1 ; i<n ; i++) {
if(T[i]> max) { if(T[i]> max){
max = T[i]; pos = i; } max = T[i]; pos = i; }
} }
return pos; return pos;
} }

Les fonctions 202

11) Arguments par défaut d'une fonction

▪ Etant la déclaration et l’exemple suivant :

TypeFonction NomFonction (Type_1 arg_1, Type_2 arg_2, , Type_3 arg_3 = Val); × n’est pas supporté en C

➢ Exemple

int f (int a , int b=0) ; // déclaration d’une fonction f qui a comme paramètre a et b qui a une valeur par défaut 0

▪ Le langage C ne supporte pas les arguments par défaut comme le C++ ou d’autres langages.

▪ Cela signifie que vous devez toujours fournir tous les arguments attendus par une fonction lorsque vous l’appelez,

▪ sinon vous aurez une erreur de compilation ou un comportement indéfini.

19
Fin du cours

20

Vous aimerez peut-être aussi