Académique Documents
Professionnel Documents
Culture Documents
Les fonctions
XI
Rappel : Exemple d'un programme C
Remarque
- Avec des plus gros programmes qui font plusieurs lignes de code, on a besoin de découper nos
programmes en petits bouts pour les organiser.
- Chaque « petit bout de programme » sera ce qu'on appelle une fonction.
Exemple
1 #include <stdio.h>
2
3 double surfaceRectangle(double largeur, double hauteur)
4{
5 return largeur * hauteur;
6}
7
8 int main()
9{
10 printf("Rectangle de largeur 5 et hauteur 10. Surface = %.2f\n",
surfaceRectangle(5, 10));
11 printf("Rectangle de largeur 2.5 et hauteur 3.5. Surface = %.2f\n",
surfaceRectangle(2.5, 3.5));
12 printf("Rectangle de largeur 4.2 et hauteur 9.7. Surface = %.2f\n",
surfaceRectangle(4.2, 9.7));
13 return 0;
14 }
15
61
1. Définition d'une fonction
Définition : Une fonction
- Une fonction est un morceau de code qui sert à faire une tâche de précis. Elle exécute des actions et
renvoie un résultat.
- Le but des fonctions est de simplifier le code source, pour ne pas avoir à retaper le même code plusieurs
fois.
1. L'entrée : on fait « rentrer » des informations dans la fonction (en lui donnant des informations avec
lesquelles travailler).
2. Les calculs : grâce aux informations qu'elle a reçues en entrée, la fonction travaille.
3. La sortie : une fois qu'elle a fini ses calculs, la fonction renvoie un résultat. C'est ce qu'on appelle la
sortie, ou encore le retour.
1 type nomFonction(paramètres)
2{
3 // Insérez vos instructions ici
4}
- type (correspond à la sortie) : c'est le type de la fonction. Ce type dépend du résultat que la fonction
renvoie. Mais il est aussi possible de créer des fonctions qui ne renvoient rien.
Il y a donc deux sortes de fonctions :
- les fonctions qui renvoient une valeur : on leur met un des types que l'on connaît (char, int, double,
etc.) ;
- les fonctions qui ne renvoient pas de valeur : on leur met un type spécial void (qui signifie « vide
»).
- nomFonction : c'est le nom de la fonction. On peut appeler une fonction en respectant les mêmes règles
que pour les variables (pas d'accents, pas d'espaces, etc.).
- paramètres (correspondent à l'entrée) : entre parenthèses, on peut envoyer des paramètres à la fonction.
Ce sont des valeurs avec lesquelles la fonction va travailler.
- Les accolades qui indiquent le début et la fin de la fonction. À l'intérieur de ces accolades, on met les
instructions qu'on veut.
62
Remarque
- Si la fonction admet un type (type de résultat renvoyé), alors son corps doit être terminée obligatoirement
par le mot return suivi du résultat renvoyé.
- On peut envoyer autant de paramètres qu'on veut. On peut aussi n'envoyer aucun paramètre à la fonction.
Exemple
Exemple
Exemple
1 void bonjour()
2{
3 printf("Bonjour");
4}
Exemple
1 void Afferreur(int a)
2{
3 if(!a)
4 printf("erreur");
5 else
6 printf("ok");
7}
8
63
3. Appeler une fonction
- Si la fonction ne retourne pas de résultat (précédée du mot void lors de sa définition), alors elle est
appelée directement par son nom suivi de la liste des paramètres effectifs.
Exemple :
int x=0, b=10 ;
Afferreur(x) ;
Afferreur(b) ;
- Si la fonction admet un type (type de résultat renvoyé), alors elle est appelée dans une expression.
Exemple :
a = saisie( ) ;
n = cube(a) ;
printf("%lf ", cotg(x)) ;
Exemple
1 void ma_fonction()
2{
3 ...
4}
5
6 int main()
7{
8 ma_fonction();
9 return 0;
10 }
11
La règle du "sens de lecture" à la compilation doit être respectée lorsqu'une fonction utilisateur utilise une autre
fonction utilisateur.
1 void ma_fonction_1()
2{
3 ...
4}
5
6 void ma_fonction_2()
7{
8 ma_fonction_1();
9}
64
Exemple : Exemple incorrect
1 void ma_fonction_1()
2{
3 ma_fonction_2();
4}
5
6 void ma_fonction_2()
7{
8 ...
9}
Une autre possibilité consiste à mentionner, en début de programme, les prototypes de toutes les fonctions
utilisateur ; le compilateur connaît ainsi toutes les fonctions utilisateur avant de compiler.
- son nom ;
- le nombre de paramètres d'entrée et le type de chacun d'entre eux ;
- le type de résultat en sortie.
Les noms de paramètre sont optionnels, mais il est fortement conseillé de les laisser. Cela donne une bonne
indication sur leurs rôles.
Exemples :
void function_1(int x) ;
int function_2(void) ;
Exemple
1 void ma_fonction_1(void);
2 void ma_fonction_2(void);
3 void ma_fonction_3(void);
4
5 void ma_fonction_1()
6{
7 ma_fonction_2();
8}
9
10 void ma_fonction_2()
11 {
12 ...
13 }
14
15 int main()
65
16 {
17 ma_fonction_3();
18 ma_fonction_1();
19 return 0;
20 }
21
22 void ma_fonction_3()
23 {
24 ...
25 }
26
- Les paramètres utilisés dans l'appel d'une fonction sont appelés paramètres effectifs.
Exemples :
Afferreur(x) ; /* paramètre effectif x */
n = cube(a) ; /* paramètre effectif a */
- Lors de l'appel les paramètres formels et les paramètres effectifs d'une fonction doivent s'accorder du
point de vue type, ordre et nombre.
Fondamental
- Le passage de paramètres se fait par défaut par valeur => utilisation des paramètres sans aucun accès aux
variables elles mêmes.
- Dans ce type de passage, un paramètre est considéré comme une variable locale à la fonction initialisée
par la valeur indiquée lors de l'appel.
- Dans le corps de la fonction, on peut modifier les valeurs des paramètres formels sans aucun effet sur les
valeur d'origines (paramètres effectifs).
- Pour pouvoir modifier les valeurs originales des variables lors de l'appel des fonctions çàd pour assurer
effectivement la modification du paramètre effectif (passage par adresse), on aura besoin de
transmettre les adresses des variables à la fonction appelante (en utilisant des pointeurs).
Exemple
1 #include <stdio.h>
66
2
3 int x1;
4 void ma_fonction_1()
5{
6 ...
7}
8
9 int x2;
10
11 void ma_fonction_2()
12 {
13 ...
14 }
15
16 int main()
17 {
18 ...
19 }
20
21 void ma_fonction_3()
22 {
23 ...
24 }
25
Exemple
1 #include<stdio.h>
2 double var1;
3 int var2;
4 void fonction1(int par1)
5{
6 char var3;
7 { /* début bloc1 */
8 long var4;
9 ...
10 {
11 ... /* bloc 2 */
12 }
13 {
14 ... /* bloc 3 */
15 }
16 }
17 }
18 float var5;
19 int main()
20 {
21 short var6;
22 ... /* reste du programme */
23 return 0;
24 }
25
67
- var1, var2 et var5 sont dites variables globales. Chacune de ces variables est connue dans toutes les
fonctions qui suivent sa déclaration.
- var3 est connu uniquement dans toutes les parties de la fonction fonction1 (y compris bloc1, bloc2 et
bloc3).
- var6 est connu uniquement dans la fonction main
- var4 est connu dans bloc1, bloc2 et bloc3 uniquement et pas dans toute la fonction fonction1.
Remarque
Il est possible de déclarer une variable locale de même nom qu'une variable globale existante ; c'est alors la
variable locale qui a priorité.
Exemple
1 #include<stdio.h>
2 int b=50;
3 void fonction2()
4{
5 int b=150;
6 printf("b dans fonction2 = %d\n",b);
7}
8 int main()
9{
10 int b=250;
11 printf("b dans main = %d\n",b);//affiche "b dans main = 250"
12 fonction2();//affiche "b dans fonction2 = 150"
13 return 0;
14 }
15
Complément
De manière générale, même si cela pourrait paraître parfois plus pratique, il est déconseillé de déclarer dans un
programme 2 variables portant le même nom :
Si cela n'a aucune conséquence sur la compilation, cela est source de grande confusion pour le programmeur et
est néfaste pour la lisibilité du code source.
68
Exemple
Soit la suite suivante définie par :
- U0 = 3
- Un = 2*Un-1 + 2
On veut écrire un programme C qui permet de calculer Un à l'aide d'une fonction récursive suite de type int.
1 #include<stdio.h>
2
3 int suite(int); /* prototype de la fonction */
4
5 int main()
6{
7 int n, res;
8 printf("donner un entier : ");
9 scanf("%d", &n);
10 res = suite(n);
11 printf("U(%d) = %d", n, res);
12 return 0;
13 }
14 int suite(int a)
15 {
16 if(!a)
17 return 3;
18 else
19 return 2*suite(a-1)+2;
20 }
21
69