École Supérieure de Technologie
et d’Informatique
A.U. 2011/2012
Cours programmation en langage C
Chapitre :Les fonctions (12 pages)
Informatique Appliquée 1ère année
(cid:1) La structuration de programmes en sous-programmes se fait en C à l'aide de fonctions
(cid:1) nous avons déjà utilisé quelques fonctions prédéfinies dans des bibliothèques standard
(printf de <stdio>, sqrt de <math>, etc.).
Modularisation de programmes
(cid:1) Jusqu'ici, nous avons résolu nos problèmes à l'aide de fonctions prédéfinies et d'une
seule fonction nouvelle: la fonction principale main().
(cid:1) Pour des problèmes plus complexes, nous obtenons ainsi de longues listes d'instructions,
peu structurées et par conséquent peu compréhensibles.
(cid:1) En plus, il faut souvent répéter les mêmes suites de commandes dans le texte du
programme, ce qui entraîne un gaspillage de mémoire interne et externe.
La modularité et ses avantages
(cid:1) La plupart des langages de programmation nous permettent de subdiviser nos
programmes en sous-programmes, fonctions ou procédures plus simples et plus
compacts.
(cid:1) A l'aide de ces structures nous pouvons modulariser nos programmes pour obtenir des
solutions plus efficientes.
Avantages d’un programme modulaire:
(cid:1) Meilleure lisibilité
(cid:1) Diminution du risque d'erreurs
(cid:1) Possibilité de tests sélectifs
(cid:1) Dissimulation des méthodes
(cid:1) Réutilisation de modules déjà existants
(cid:1) Simplicité de l'entretien
(cid:1) Favorisation du travail en équipe
(cid:1) Hiérarchisation des modules
Exemple :
Ecrire un programme qui calcule la factorielle d’un entier n saisi au clavier.
#include <stdio.h>
void main ( )
{
int n,i,f=1;
printf("saisir un entier ");
scanf("%d",&n);
for (i=2; i<=n; i++)
f*=i;
Mme Wiem Yaiche Elleuch chapitre les fonctions
1
printf("la factorielle de %d est %d\n", n, f);
printf("fin du travail");
}
Voici une 2ème version du programme en utilisant les fonctions
#include <stdio.h>
void factorielle (int n)
{
int i, f=1;
for (i=2; i<=n; i++)
f*=i;
printf("la factorielle de %d est %d\n", n, f);
}
void main ( )
{
int n;
printf("saisir un entier ");
scanf("%d",&n);
factorielle (n);
printf("fin du travail");
}
La notion de blocs et la portée des identificateurs
(cid:2) Les fonctions en C sont définies à l'aide de blocs d'instructions. Un bloc
d'instructions est encadré d'accolades et composé de deux parties:
Blocs d'instructions en C
{ <déclarations locales> <instructions> }
(cid:2) ceci est vrai pour tous les blocs d'instructions, non seulement pour les blocs qui
renferment une fonction
(cid:2) Ainsi, le bloc d'instructions d'une commande if, while ou for peut théoriquement
contenir des déclarations locales de variables et même de fonctions.
Exemple
(cid:2) La variable d'aide i est déclarée à l'intérieur d'un bloc conditionnel. Si la condition
(n>0) n'est pas remplie, i n'est pas défini. A la fin du bloc conditionnel, i disparaît.
(cid:2) if (n>0) { int i; for (i=0; i<n; i++) ... }
Variable locale
Les variables déclarées dans un bloc d'instructions sont uniquement visibles à l'intérieur de
ce bloc. On dit que ce sont des variables locales à ce bloc
Exemple
La déclaration de la variable i se trouve à l'intérieur d'un bloc d'instructions conditionnel.
Elle n'est pas visible à l'extérieur de ce bloc, ni même dans la fonction qui l'entoure.
if (n>0)
{
int i;
for (i=0; i<n; i++) ...
}
(cid:2) Une variable déclarée à l'intérieur d'un bloc cache toutes les variables du même nom
des blocs qui l'entourent.
Mme Wiem Yaiche Elleuch chapitre les fonctions
2
#include<stdio.h>
void calculer()
{
int n=3;
printf("la valeur de n dans la fonction calculer est %d\n", n);
}
void main()
{
int n=5;
printf("la valeur de n avant l'appel de la fonction calculer est %d\n", n);
calculer();
printf("la valeur de n apres l'appel de la fonction calculer est %d\n", n);
}
exécution :
la valeur de n avant l'appel de la fonction calculer est 5
la valeur de n dans la fonction calculer est 3
la valeur de n apres l'appel de la fonction calculer est 5
Publicité
variable globale
(cid:2) Les variables déclarées au début du fichier, à l'extérieur de toutes les fonctions sont
disponibles à toutes les fonctions du programme. Ce sont alors des variables
globales. En général, les variables globales sont déclarées immédiatement derrière
les instructions #include au début du programme.
(cid:2) Les variables déclarées au début de la fonction principale main ne sont pas des
variables globales, mais elles sont locales à main !
#include <stdio.h>
int y=3;
void test ()
{
printf("la valeur de y dans test est %d\n",y);
}
void main ( )
{
printf("la valeur de y, dans main, avant l'appel de test est %d \n",y);
test();
printf("la valeur de y, dans main, apres l'appel de test est %d \n",y);
}
Exécution
la valeur de y, dans main, avant l'appel de test est 3
la valeur de y dans test est 3
la valeur de y, dans main, apres l'appel de test est 3
Déclaration et définition de fonctions
(cid:2) En général, le nom d'une fonction apparaît à trois endroits dans un programme:
1) lors de la déclaration
2) lors de la définition
3) lors de l'appel
Mme Wiem Yaiche Elleuch chapitre les fonctions
3
(cid:2) Dans le programme suivant, la fonction main utilise les deux fonctions:
(cid:2) saisir qui lit un nombre entier au clavier et le fournit comme résultat. La
fonction saisir n'a pas de paramètres.
(cid:2) maximum qui renvoie comme résultat le maximum de deux entiers fournis
comme paramètres.
#include <stdio.h>
void main()
{
int x,y, max;
printf("saisir un entier ");
scanf("%d",&x);
printf("saisir un entier ");
scanf("%d",&y);
if (x>y) max=x;
else max=y;
printf("\n le maximum est %d", max);
}
2ème version en utilisant les fonctions
#include <stdio.h>
int saisir ()
{
int a;
printf("saisir un entier ");
scanf("%d",&a);
return a;
}
int maximum (int a, int b)
{
int max;
if (a>b) max=a;
else max=b;
return max;
}
void main()
{
int x,y, max;
x=saisir();
y=saisir();
max=maximum (x,y);
printf("\n le maximum est %d", max);
}
(cid:2) Dans la définition d'une fonction, nous indiquons:
(cid:3) le nom de la fonction
(cid:3) le type, le nombre et les noms des paramètres de la fonction
(cid:3) le type du résultat fourni par la fonction
(cid:3) les données locales à la fonction
(cid:3) les instructions à exécuter
Mme Wiem Yaiche Elleuch chapitre les fonctions
4
(cid:2) Définition d'une fonction en C
<TypeRés> <NomFonct> (<TypePar1> <NomPar1>, <TypePar2> <NomPar2>, ... )
{
<déclarations locales> <instructions>
}
il n'y a pas de point-virgule derrière la définition des paramètres de la fonction.
Type d'une fonction
(cid:2) Si une fonction F fournit un résultat du type T, on dit que 'la fonction F est du type
T' ou que 'la fonction F a le type T'.
(cid:2) Une fonction ne peut pas fournir comme résultat des tableaux, des chaînes de
caractères ou des fonctions. (Attention: Il est cependant possible de renvoyer un
pointeur sur le premier élément d'un tableau ou d'une chaîne de caractères.)
(cid:2) Si une fonction ne fournit pas de résultat, il faut indiquer void (vide) comme type du
résultat. Si une fonction n'a pas de paramètres, on peut déclarer la liste des
paramètres comme (void) ou simplement comme () .
(cid:2) Le type par défaut est int; autrement dit: si le type d'une fonction n'est pas déclaré
explicitement, elle est automatiquement du type int.
(cid:2) Il est interdit de définir des fonctions à l'intérieur d'une autre fonction
(cid:2) En principe, l'ordre des définitions dans le texte du programme ne joue pas de rôle,
mais chaque fonction doit être déclarée ou définie avant d'être appelée
(cid:2) La fonction principale main est du type int. Elle est exécutée automatiquement lors
de l'appel du programme. À la place de la définition: int main(void) on peut écrire
simplement: main()
Déclaration d’une fonction
(cid:2) En C, il faut déclarer chaque fonction avant de pouvoir l'utiliser. La déclaration
informe le compilateur du type des paramètres et du résultat de la fonction.
(cid:2) A l'aide de ces données, le compilateur peut contrôler si le nombre et le type des
paramètres d'une fonction sont corrects.
(cid:2) Si dans le texte du programme la fonction est définie avant son premier appel, elle
Publicité
n'a pas besoin d'être déclarée.
Prototype d’une fonction
(cid:2) La déclaration d'une fonction se fait par un prototype de la fonction qui indique
uniquement le type des données transmises et reçues par la fonction.
(cid:2) Déclaration : Prototype d'une fonction
<TypeRés> <NomFonct> (<TypePar1>, <TypePar2>, ...);
ou bien
<TypeRés> <NomFonct> (<TypePar1> <NomPar1>, <TypePar2> <NomPar2>, ... );
(cid:2) Lors de la déclaration, le nombre et le type des paramètres doivent nécessairement
correspondre à ceux de la définition de la fonction.
Mme Wiem Yaiche Elleuch chapitre les fonctions
5
Noms des paramètres
(cid:2) On peut facultativement inclure les noms des paramètres dans la déclaration, mais
ils ne sont pas considérés par le compilateur. Les noms fournissent pourtant une
information intéressante pour le programmeur qui peut en déduire le rôle des
différents paramètres
Fonctions qui appellent des fonctions
Exemple :
#include <stdio.h>
int saisir()
{
int x;
printf("saisir un entier ");
scanf("%d",&x);
return x;
}
int somme (int x, int y, int z)
{
return (x+y+z);
}
float moyenne (int x, int y, int z)
{
int s;
s=somme (x,y,z);
return (float (s/3));
}
void main()
{
int a, b, c;
float m;
a=saisir();
b=saisir();
c=saisir();
m =moyenne (a,b,c);
printf("la moyenne est %f", m);
}
Exercice :
Ecrire un programme qui affiche un rectangle d’étoiles de l lignes et c colonnes.
#include<stdio.h>
void main()
{
int l, c, i,j;
printf("saisir nombre de lignes et nombre de colonnes");
scanf("%d%d",&l,&c);
for(i=0;i<l;i++)
{
for(j=0;j<c; j++)
printf("*");
printf("\n");
}
}
Mme Wiem Yaiche Elleuch chapitre les fonctions
6
Voici une 2ème version du programme en utilisant les fonctions
#include<stdio.h>
void ligne (int c)
{
int j;
for(j=0;j<c; j++)
printf("*");
}
void rectangle (int l, int c)
{
int i;
for(i=0;i<l;i++)
{
ligne(c);
printf("\n");
}
}
void main()
{
int l, c;
printf("saisir nbre de lignes et nbre colonnes");
scanf("%d%d",&l,&c);
rectangle (l,c);
}
Renvoyer un résultat
(cid:2) Par définition, toutes les fonctions fournissent un résultat d'un type que nous devons
déclarer. Une fonction peut renvoyer une valeur d'un type simple ou l'adresse d'une
variable ou d'un tableau.
(cid:2) Pour fournir un résultat en quittant une fonction, nous disposons de la commande
return:
La commande return
(cid:2) L'instruction return <expression>; a les effets suivants:
- évaluation de l'<expression>
- conversion automatique du résultat de l'expression dans le type de la fonction
-
-
renvoi du résultat
terminaison de la fonction
Paramètres d'une fonction
(cid:2) Les paramètres d'une fonction sont simplement des variables locales qui sont
initialisées par les valeurs obtenues lors de l'appel.
Généralités
(cid:2) Lors d'un appel, le nombre et l'ordre des paramètres doivent nécessairement
correspondre aux indications de la déclaration de la fonction. Les paramètres sont
automatiquement convertis dans les types de la déclaration avant d'être passés à la
Publicité
fonction.
(cid:2) void : Évidemment, il existe aussi des fonctions qui fournissent leurs résultats ou
exécutent une action sans avoir besoin de données. La liste des paramètres contient
alors la déclaration void ou elle reste vide
Mme Wiem Yaiche Elleuch chapitre les fonctions
7
Passage des paramètres par valeur
Exemple :
Ecrire un programme qui lit deux entiers au clavier, ensuite les permute.
#include <stdio.h>
void main()
{
int x,y, aide;
printf(" saisir deux entiers ");
scanf("%d%d",&x,&y);
printf("les valeurs avant permutation: x: %d et y:%d", x,y);
aide=x;
x=y;
y=aide;
printf("\n les valeurs après permutation: x: %d et y:%d", x,y);
}
exécution :
saisir deux entiers 4
7
les valeurs avant permutation: x: 4 et y:7
les valeurs après permutation: x: 7 et y:4
Voici une 2ème version du programme en utilisant les fonctions (la permutation ne va pas
avoir lieu)
#include <stdio.h>
void permuter (int x, int y)
{
int aide;
aide=x;
x=y;
y=aide;
}
void main()
{
int x,y;
printf(" saisir deux entiers ");
scanf("%d%d",&x,&y);
printf("les valeurs avant permutation: x: %d et y:%d", x,y);
permuter (x,y);
printf("\n les valeurs après permutation: x: %d et y:%d", x,y);
}
saisir deux entiers 4
7
les valeurs avant permutation: x: 4 et y:7
les valeurs aprÞs permutation: x: 4 et y:7
Mme Wiem Yaiche Elleuch chapitre les fonctions
8
Voici une 3ème version du programme en utilisant les fonctions (la permutation va avoir
lieu)
#include <stdio.h>
void permuter (int a, int b)
{
int aide;
aide=*a;
a=b;
*b=aide;
}
void main()
{
int x,y;
printf(" saisir deux entiers ");
scanf("%d%d",&x,&y);
printf("les valeurs avant permutation: x: %d et y:%d", x,y);
permuter (&x,&y);
printf("\n les valeurs après permutation: x: %d et y:%d", x,y);
}
Exécution
saisir deux entiers 4
7
les valeurs avant permutation: x: 4 et y:7
les valeurs après permutation: x: 7 et y:4
(cid:2) En C, le passage des paramètres se fait toujours par la valeur, c.-à-d. les fonctions
n'obtiennent que les valeurs de leurs paramètres et n'ont pas d'accès aux variables
elles-mêmes.
(cid:2) Les paramètres d'une fonction sont à considérer comme des variables locales qui
sont initialisées automatiquement par les valeurs indiquées lors d'un appel.
(cid:2) A l'intérieur de la fonction, nous pouvons donc changer les valeurs des paramètres
sans influencer les valeurs originales dans les fonctions appelantes.
Passage de l'adresse d'une variable
(cid:2) une fonction n'obtient que les valeurs de ses paramètres.
(cid:2) Pour changer la valeur d'une variable de la fonction appelante, nous allons procéder
comme suit:
(cid:3) la fonction appelante doit fournir l'adresse de la variable et
(cid:3) la fonction appelée doit déclarer le paramètre comme pointeur.
(cid:2) On peut alors atteindre la variable à l'aide du pointeur.
Passage de l'adresse d'un tableau à une dimension
(cid:2) Comme il est impossible de passer 'la valeur' de tout un tableau à une fonction, on
fournit l'adresse d'un élément du tableau.
(cid:2) En général, on fournit l'adresse du premier élément du tableau, qui est donnée par le
nom du tableau
Mme Wiem Yaiche Elleuch chapitre les fonctions
9
Déclaration
(cid:2) Dans la liste des paramètres d'une fonction, on peut déclarer un tableau par le nom
suivi de crochets, <type> <nom>[] ou simplement par un pointeur sur le type des
éléments du tableau: <type> *<nom>
Exemple :
Écrire un programme qui remplit et affiche un tableau de n éléments.
1ère version (formalisme pointeur)
#include<stdio.h>
void saisir2 (int *a)
{
printf("saisir nbre d'éléments");
scanf("%d", a);
Publicité
}
void remplir (int *p, int n)
{
int i;
for (i=0; i<n; i++)
scanf("%d",p+i);
}
void afficher (int *p, int n)
{
int i;
for (i=0; i<n; i++)
printf("%d \t",*(p+i));
}
void main()
{
int tab[50], n;
saisir2(&n);
remplir(tab,n);
afficher (tab,n);
}
2ème version (formalisme pointeur)
#include<stdio.h>
void saisir2 (int *a)
{
printf("saisir nbre d'éléments");
scanf("%d", a);
}
void remplir (int *p, int n)
{
int *h;
for (h=p; h<p+n; h++)
scanf("%d",p);
}
void afficher (int *p, int n)
{
int *h;
for (h=p; h<p+n; h++)
printf ("%d ",*p);
Mme Wiem Yaiche Elleuch chapitre les fonctions
10
}
void main()
{
int tab[50],n;
saisir2(&n) ;
remplir(tab,n);
afficher (tab,n);
}
3ème version (formalisme tableau)
#include<stdio.h>
void saisir2 (int *a)
{
printf("saisir nbre d'éléments");
scanf("%d", a);
}
void remplir (int tab[], int n)
{
int i;
for (i=0; i<n; i++)
scanf("%d",tab+i);
}
void afficher (int tab[], int n)
{
int i;
for (i=0; i<n; i++)
printf("%d \t",*(tab+i));
}
void main()
{
int tab[50],n;
saisir2(&n);
remplir(tab,n);
afficher (tab,n);
}
Passage de l'adresse d'un tableau à deux dimensions
#include<stdio.h>
void remplir (int *tab, int l, int c)
{
int i,j;
for (i=0; i<l; i++)
for (j=0; j<c; j++)
scanf("%d",tab+i*50+j);
}
void afficher (int *tab, int l, int c)
{
int i,j;
for (i=0; i<l; i++)
{
for (j=0; j<c; j++)
printf("%d",(tab+i50+j));
Mme Wiem Yaiche Elleuch chapitre les fonctions
11
printf("\n");
}
}
void main()
{
int mat[50][50];
int l,c;
printf("saisir nbre d'élémnets");
scanf("%d%d", &l,&c);
remplir((int *)mat,l,c);
afficher ((int *)mat,l,c);
}
Mme Wiem Yaiche Elleuch chapitre les fonctions
12