Vous êtes sur la page 1sur 50

Fonctions et procédures

Alogorithme & Programmation C


Les fonctions 1
Fonctions et procédures
• Certains problèmes conduisent à des programmes longs, difficiles à écrire et à
comprendre. On les découpe en des parties appelées sous-programmes ou
modules
• Les fonctions et les procédures sont des modules (groupe d'instructions)
indépendants désignés par un nom. Elles ont plusieurs intérêts :
– permettent de "factoriser" les programmes, càd de mettre en commun les parties
qui se répètent
– permettent une structuration et une meilleure lisibilité des programmes

– facilitent la maintenance du code (il suffit de modifier une seule fois)

– ces procédures et fonctions peuvent éventuellement être réutilisées dans d'autres


programmes

• Exemples : fonctions d'E/S (scanf, printf, …), mathématiques (sin, cos, …)

Alogorithme & Programmation C


Les fonctions 2
Fonctions
• Le rôle d'une fonction en programmation est similaire à celui d'une fonction en
mathématique : elle retourne un résultat à partir des valeurs des paramètres

• Une fonction s'écrit en dehors du programme principal sous la forme :

Fonction nom_fonction (paramètres et leurs types) : type_fonction


Instructions constituant le corps de la fonction
retourne …
FinFonction
• Pour le choix d'un nom de fonction il faut respecter les mêmes règles que celles pour
les noms de variables
• type_fonction est le type du résultat retourné
• L'instruction retourne sert à retourner la valeur du résultat
Alogorithme & Programmation C
Les fonctions 3
Fonctions : exemples
• La fonction SommeCarre suivante calcule la somme des carrées de deux
réels x et y :
Fonction SommeCarre (x : réel, y: réel ) : réel
variable z : réel
z ←x^2+y^2
retourne (z)
FinFonction

• La fonction Pair suivante détermine si un nombre est pair :

Fonction Pair (n : entier ) : booléen


retourne (n%2=0)
FinFonction
Alogorithme & Programmation C
Les fonctions 4
Utilisation des fonctions
• L'utilisation d'une fonction se fera par simple écriture de son nom dans le
programme principale. Le résultat étant une valeur, devra être affecté ou
être utilisé dans une expression, une écriture, ...
• Exepmle : Algorithme exepmleAppelFonction
variables z : réel, b : booléen
Début
b ←Pair(3)
z ←5*SommeCarre(7,2)+1
écrire("SommeCarre(3,5)= ", SommeCarre(3,5))
Fin
• Lors de l'appel Pair(3) le paramètre formel n est remplacé par le
paramètre effectif 3
Alogorithme & Programmation C
Les fonctions 5
Procédures
• Dans certains cas, on peut avoir besoin de répéter une tâche dans plusieurs
endroits du programme, mais que dans cette tâche on ne calcule pas de résultats
ou qu'on calcule plusieurs résultats à la fois

• Dans ces cas on ne peut pas utiliser une fonction, on utilise une procédure
• Une procédure est un sous-programme semblable à une fonction mais qui ne
retourne rien
• Une procédure s'écrit en dehors du programme principal sous la forme :

Procédure nom_procédure (paramètres et leurs types)

Instructions constituant le corps de la procédure

FinProcédure
• Remarque : une procédure peut ne pas avoir de paramètres
Alogorithme & Programmation C
Les fonctions 6
Type de la Exemple
valeur de
retour Argument

char minus_majus (char c1) {


char c2; /* déclarations locales */
if (c1 >= 'a' && c1 <= 'z')
c2 = c1+'A'-'a'; Instructions
else c2=c1;
return (c2);
Valeur renvoyée
}
void main() {
char c,majuscule;
printf("Donner un caractere\n");
c = getchar(); getchar(); Appel de la fonction
majuscule = minus_majus(c);
printf ("La majuscule de %c est %c\n",c,majuscule);
} Alogorithme & Programmation C
Les fonctions 7
Définition de fonction : syntaxe
type_fonction nom_fonction (type_arg1 arg1, …, type_argn argn) {

return (valeur retournée);
}

Dans l'exemple précédent :


type_fonction : char, c'est le type de la valeur renvoyée par return
nom_fonction : minus_majus

Le nombre d'arguments est quelconque, éventuellement aucun, les parenthèses


doivent toujours figurer (ex: main () )

Alogorithme & Programmation C


Les fonctions 8
Type de la fonction
• Une fonction peut ne pas renvoyer de valeur.
• Exemple
void print_majus (char c1) {
char c2;
if (c1 >= 'a' && c1 <= 'z')
c2 = c1+'A'-'a';
else c2=c1;
printf("la majuscule de % est %c, c1, c2);
return; /* ou bien return (); */
}

• Dans ce cas, le type de la fonction est : void


• Le type de la fonction ne peut être que :
• int, float, char, ou adresse de
• Mais pas un tableau, ni autre type complexe

Alogorithme & Programmation C


Les fonctions 9
Instruction return
1/ Indique la valeur de retour de la fonction.
2/ Arrête l'exécution de la fonction
char minus_majus (char c1) {

if (c1 >= 'a' && c1 <= 'z')


return (c1+'A'-'a');
else return (c1);
}
Pour les fonction de type void, return est optionnel
void print_majus (char c1) {
char c2;
if (c1 >= 'a' && c1 <= 'z')
c2 = c1+'A'-'a';
else c2=c1;
printf("la majuscule de % est %c, c1, c2);
}
Alogorithme & Programmation C
Les fonctions 10
Appel des fonctions
• L'appel d'une fonction se fait en donnant son nom, suivi de la liste des
paramètres entre parenthèses.
• Exemple paramètres formels
float puiss (float x, int n) { abstraits (n'existent pas réellement)
float y=1.0;
if (n>0) for (i=1;i<=n;i++) y = y*x;
else for (i=1;i<=n;i++) y = y/x;
return (y);
}
paramètres effectifs. ils contiennent
void main () { les valeurs pour effectuer le traitement
float z,t;
z = puiss(10.7,2);
Le nombre de paramètres effectifs doit
t = puiss (z, -6);
être égal au nombre de paramètres
...
formels. L'ordre et le type des
} paramètres doivent correspondre
Alogorithme & Programmation C
Les fonctions 11
Appel des fonctions

• Un appel de fonction peut se faire comme opérande d'une expression, soit comme paramètre
d'un autre appel de fonction.
• Exemple
int maximum (int x, int y) {
return((x>y)?x,y));
}
void main () {
int v1,v2,v3,m1;
scanf("%d %d %d , &v1,&v2,&v3);
m1 = maximum(v1,v2);
m1 = maximum(m1,v3);
printf("valeur maximale %d\n", m1);
}
ou bien
m1 =maximum(v1,v2);
printf("valeur maximale %d\n", maximum(m1,v3));
ou bien
printf("valeur maximale %d\n", maximum(maximum(v1,v2),v3));
Alogorithme & Programmation C
Les fonctions 12
Règles de déclaration et d'appel
• Toute fonction ne peut appeler que des fonctions déclarées avant elle ou elle-même (la
fonction main ne peut pas s'appeler).
... f1 (..) {
...
}
... f2 (...) {
...
}
... f3 (...) {
...
}
void main (...) {
...
}
la fonction main peut appeler f1,f2,f3
la fonction f3 peut appeler f1,f2,f3
la fonction f2 peut appeler f1, f2
la fonction f1 peut appeler f1

• Lorsqu'une fonction s'appelle elle-même, on dit qu'elle est "récursive".


Alogorithme & Programmation C
Les fonctions 13
Déclarations en "avance " : Prototype
• Règle précédente contraignante  Solution : Prototype
En début de programme on donne le type de chaque fonction , son nom, le nombre et les
types des arguments
• Information suffisante pour le compilateur.

float puiss (float,int); /*Prototype de la fonction puiss*/

void main()
{
puiss (10.2, 5); /*Appel avant déclaration*/

...}

float puiss (float x, int n) /*Déclaration de la fonction */


{
float y=1.0;
if (n>0) for (i=1;i<=n;i++) y = y*x;
else for (i=1;i<=n;i++) y = y/x;
return (y);
}
Alogorithme & Programmation C
Les fonctions 14
Exemple :
unsigned long pgcd(unsigned long x, unsigned long y) Déclaration et Prototype de la fonction
{ •Déclaration de fonction : son nom, ses
unsigned long r; arguments formels et le type (type de la valeur
if (x < y) { r = x; x = y; y = x; } retournée) de la fonction. Les variables x et y
do { sont les paramètres ou arguments formels de la
r = x % y; fonction. Leurs valeurs ne seront en fait connues
x = y; que lors de l'appel de cette fonction.
y = r; •Type de la fonction : Cette fonction retourne
} une valeur de type unsigned long qui correspond
while (r != 0); au pgcd calculé par cette fonction.
} •La variable r est une variable locale à la fonction
return x; /* retourne le pgcd calculé */ pgcd.
}
Voici une utilisation de la fonction pgcd définie plus haut :
main() {
unsigned long a, b;
printf("Donnez deux entiers\n"); Les variables a, b ainsi que la
scanf("%u %u", &a, &b); constante 5 sont les paramètres
printf("Le pgcd de %u et de %u est %u\n", a, b, pgcd(a, b)); ou arguments effectifs de la
printf("Le pgcd de 5 et de %u est %u\n", b, pgcd(5, b)); fonction pgcd pour cet appel.
}

Alogorithme & Programmation C


Les fonctions 15
Exemples à tester
void f (int a){
a=a+1;
}
void main(){
int b;
b=0;
f(b);
printf("%d\n",b); Résultat?
}

void f(int * a)
{ /* a est l'adresse, *a est l'entier
*a=*a+1;
}
void main(){
int b;
b=0; scanf( &
f(&b);
printf("%d\n",b);
}
Alogorithme & Programmation C
Les fonctions 16
Passage des paramètres
• Rappel : les paramètres sont associés aux arguments suivant l'ordre de
déclaration.
• En c, cette association se fait par COPIE de la valeur du paramètre dans
l'argument. Chaque argument est en fait une variable locale de la fonction. La
fonction travaille sur l'argument.

void f (int a){


a=a+1;
}
void main(){
int b; Résultat : 0
b=0; Conséquence : La fonction ne modifie pas les
f(b); paramètres d'appels
printf("%d\n",b);
}

Alogorithme & Programmation C


Les fonctions 17
void f (int a){
Détail
a=a+1; /*3*/
}
void main(){
int b;
b=0; /*1*/
f(b); /*2*/
printf("%d\n",b); /*4*/
}

b 0 b 0 b 0 b 0 Inchangé
Copie
a 0 a 1

/*1*/ /*2*/ /*3*/ /*4*/

Alogorithme & Programmation C


Les fonctions 18
Modification des paramètres
• Si l'on veut qu'une fonction modifie un paramètre, on ne passe pas
la variable mais l'adresse de la variable. Il y a copie de l'adresse de la
variable. Dans la fonction on va chercher la variable par son adresse.

• Rappels :
opérateur & : & variable -> adresse de la variable
opérateur * : * adresse -> valeur qui se trouve à cette adresse
int i;
int * adresse_i; /* déclaration d'une adresse d'entier */
i=0;
adresse_i=&i;
printf("%d\n",i); -> 0;
...

Alogorithme & Programmation C


Les fonctions 19
Modification des
paramètres
void f(int * a){ // a est l'adresse, *a est l'entier
*a=*a+1; /*t3 on incrémente le mot d'adresse a*/
}
void main(){
int b;
b=0; /*t1*/
f(&b); /*t2 &b est l'adresse de b */
printf("%d\n",b); /*t4*/ -> 1
}

b 0 728 b 0 b 1 *a b 1

&b 728 &b 728


Copie
a 728 a 728
/*t1*/ /*t2*/ /*t3*/ /*t4*/

Exemple : scanf ("%d",&v);


Alogorithme & Programmation C
Les fonctions 20
Transmission des paramètres
Il existe deux modes de transmission de paramètres dans les langages de
programmation :
• La transmission par valeur : les valeurs des paramètres effectifs sont affectées aux
paramètres formels correspondants au moment de l'appel de la procédure. Dans ce
mode le paramètre effectif ne subit aucune modification
• La transmission par adresse (ou par référence) : les adresses des paramètres effectifs
sont transmises à la procédure appelante. Dans ce mode, le paramètre effectif subit
les mêmes modifications que le paramètre formel lors de l'exécution de la procédure

– Remarque : le paramètre effectif doit être une variable (et non une valeur)
lorsqu'il s'agit d'une transmission par adresse

• En pseudo-code, on va préciser explicitement le mode de transmission dans la


déclaration de la procédure

Alogorithme & Programmation C


Les fonctions 21
Transmission des paramètres : exemples
Procédure incrementer1 (x : entier par valeur, y : entier par adresse)
x ← x+1
y ← y+1
FinProcédure

Algorithme Test_incrementer1
variables n, m : entier
Début
n←3
m←3
incrementer1(n, m) résultat :
écrire (" n= ", n, " et m= ", m) n=3 et m=4
Fin

Remarque : l'instruction x ← x+1 n'a pas de sens avec un passage par valeur
Alogorithme & Programmation C
Les fonctions 22
Transmission par valeur, par adresse : exemples

Procédure qui calcule la somme et le produit de deux entiers :


Procédure SommeProduit (x,y: entier par valeur, som, prod : entier par adresse)
som ← x+y
prod ← x*y
FinProcédure

Procédure qui échange le contenu de deux variabales :


Procédure Echange (x : réel par adresse, y : réel par adresse)
variables z : réel
z←x
x←y
y←z
FinProcédure

Alogorithme & Programmation C


Les fonctions 23
Les fonctions
Les fonctions sont stockées en mémoire, elles regroupent un ensemble d’instruction en
prenant des entrées (appelées passage de paramètre) et générant des sorties.

• Elles se déclarent comme suit (en C)


typeA ma_fonction(typeB *val1,typeB val2,…,typeA valN)
{
val2+=10; paramètres
*val1=val2;
par référence par valeur
return valN;}
• Alors quand j’exécute
toto =ma_fonction(&tutu, tata,…,titi);
• Donc ?
tutu = tata+10 et toto = titi

Alogorithme & Programmation C


Les fonctions 24
Passage par valeur
Lors de l'appel d'une fonction C, le système alloue une portion de la pile dédiée
au programme. Cette zone mémoire est utilisée pour :
• stocker les arguments
• les variables locales
• l'adresse de retour de la fonction.
A chaque appel de fonction, les arguments effectifs sont recopiés à
l'emplacement prévu.
Etat de la pile juste avant l'appel de la
main() { fonction pgcd :
10 15 0
unsigned long a=10, b=15, c;
a b c
c = pgcd(a, b) ;
...
} Etat de la pile après appel de la fonction pgcd :
Restitution de l'espace des arguments effectifs
et des variables locales. Au retour de cette
fonction, les valeurs de a et b sont inchangées.
10 15 5
a b c
Alogorithme & Programmation C
Les fonctions 25
Passage par adresse
􀂙Il est parfois utile de conserver les valeurs calculées par les paramètres formels.
Exemple : fonction qui calcule deux résultats que l'on voudrait récupérer.
☺ passage par adresse
Pour avoir un passage par adresse, on se contente de passer l'adresse d'une
variable.
La fonction ne travaille plus sur une copie de la valeur de l'argument effectif
mais directement sur celui-ci.

Alogorithme & Programmation C


Les fonctions 26
Exemple :

Modification de la fonction pgcd de telle sorte que l'appel de la cette fonction


modifie la valeur du premier paramètre effectif.
void pgcd(unsigned long *x, unsigned long y)
{
unsigned long r;
if (*x < y) {
r = *x;
*x = y;
y = *x;
}
do {
Etat de la pile juste
r = *x % y;
avant l'appel de la
*x = y;
fonction pgcd :
y = r;
10 15 0 Etat de la pile après appel de la
} while (r != 0);
a b c fonction pgcd :
}
5 15 5
a b c
main(){
unsigned long a=10, b=15;
C= pgcd(&a, b); A comparer au passage de paramètres par valeurs :
... 10 15 5
} a b c
Alogorithme & Programmation C
Les fonctions 27
Fonction sans argument
Fonction sans argument et/ou qui ne retourne rien
Le mot clé void permet de spécifier que la fonction n'a aucun argument :
int fonction(void) {
...
}
L'appel à une fonction sans argument se fait de la manière suivante :
{
...
i = fonction(); Ne pas oublier les parenthèses !!!
...
}

De même, une fonction qui ne retourne rien (procédure) se note :


void fonction(...)

Alogorithme & Programmation C


Les fonctions 28
Application
Analyser et éxecuter le programme suivant
#include <stdio.h>

void permute(short a, short b) {


short temp;
if (a > b){
temp = a;
a = b;
b = temp; }
}
/*Voici une utilisation de la fonction permute définie plus haut */
void main(){
short x, y; /* déclaration de deux entiers courts */

x = 5;
y = 2;
printf("%hd %hd\n", x, y); /* affiche les nombres */
permute(x, y); /* appel de notre fonction avec les variables x, y qui sont les paramètres ou
arguments effectifs de la fonction */
printf("%hd %hd\n", x, y); /* affiche les nombres */
}

 Mauvais passage de paramètres variants


Alogorithme & Programmation C
Les fonctions 29
Pour obtenir, le résultat souhaité nous devons transmette à notre fonction l’adresse des
variables afin que ce soit bien le contenu de ces variables qui soit échangé.
Pour cela notre routine r déclare des paramètres de type short* et non plus short, nous
sommes donc obligé de déréférencer ces variables afin de lire la valeur pointée et lors de l’appel
à cette routine nous devons transmettre les adresses grâce à l’opérateur “&”.
#include <stdio.h>

void permute(short* a, short* b) {


short temp;
if (*a > *b){
temp = *a;
*a = *b;
*b = temp; }
}
void main(){
short x, y; /* déclaration de deux entiers courts */
x = 5;
y = 2;
printf("%hd %hd\n", x, y); /* affiche les nombres */
permute(&x, &y); /* appel de notre fonction */
printf("%hd %hd\n", x, y); /* affiche les nombres */
}

Alogorithme & Programmation C


Les fonctions 30
Fonctions

int somme(int a, int b){


int x;
x = a+ b;
return x;}

void sommedif (int a,int b, int *somme,int *dif){


* somme = a+b;
*dif = a-b;}

Alogorithme & Programmation C


Les fonctions 31
Exemple : fonctions
#include <stdio.h>
int somme(int,int); //prototype
int sommedif(int,int,int*,int*);
int somme(int a, int b){
return a+b;
}
int main()
{ int x,y;
printf("la somme est %d",somme(10,20,);
sommedif(10,20,&x,&y);
printf(" %d %d",x,y)
return(0);
}
void sommedif (int a,int b, int *somme,int *dif){
* somme = a+b;
*dif = a-b;
}

Alogorithme & Programmation C


Les fonctions 32
Prototypes des fonctions
Dans la pratique, lorsqu’on souhaite écrire un programme qui contient de nombreuses
fonctions, on essaie de présenter le code de manière propre et structurée  V2
V2:
V1: #include <stdio.h>
#include <stdio.h> /* PROTOTYPES : */
int max (int x, int y) { int max (int x, int y); On préfèrera la version
if (x<y) int min (int x, int y);
return y;
V2 où les prototypes
int max (int x, int y) {
else if (x<y)
des fonctions
return x; return y; disponibles figurent en
} else début de code (un peu
int min (int x, int y) { return x;
if (x<y) comme une table des
}
return x; int min (int x, int y) { matières)
else if (x<y)
return y; return x;
} else
return y;
int main () { }
int i1,i2; int main () {
i1=123; int i1,i2;
i2=1267; i1=123;
printf("max : %d\n",max(i1,i2)); i2=1267;
printf("min : %d\n",min(i1,i2)); printf("max : %d\n",max(i1,i2));
return 0; printf("min : %d\n",min(i1,i2));
} return 0;
}
Alogorithme & Programmation C
Les fonctions 33
Passage d'un tableau à une dimension en
paramètre
• Rappels:
– Lorsqu'on déclare un tableau, par ex int t[10], t est l'adresse du 1er élément du tableau
– Chaque élément du tableau peut être accédé par t[i] ou *(t+i)
– La première dimension d'un tableau n'est pas utilisée dans le calcul de l'adresse d'une
case

• Exemple
void printtab (int t1[50]) {
int i;
for (i=0;i<50;i++)
printf("%d",t1[i]);
}
void main () {
int t[50];
.....
printtab(t);
}
Alogorithme & Programmation C
Les fonctions 34
Passage d'un tableau à une dimension en
paramètre
• Puisque la dimension n'est pas utilisée, on peut ne pas la donner
void printtab (int t1[50]){
int i;
for (i=0;i<50;i++)
printf("%d",t1[i]); Syntaxes équivalentes
}
ou bien
void printtab (int t1[]) {
int i;
for (i=0;i<50;i++)
printf("%d",t1[i]);
}

Alogorithme & Programmation C


Les fonctions 35
Passage d'un tableau à une dimension en
paramètre
Conséquence : on peut donc appeler cette fonction avec tout tableau d'entiers quelle que soit sa
dimension. C’est au programmeur à gérer les débordements de tableau =>donner le nombre de
cases sur lequel travaille la fonction
void printtab (int t1[], int n){
int i;
for (i=0;i<n;i++)
printf("%d",t1[i]);
}

void main () {
int t[50],t2[100];
...
printtab(t,50); /*affiche toutes les cases de t de 0 à 49*/
printtab(t2,100); /*affiche toutes les cases de t2 de 0 à 99*/
printtab(t+20,30);/*affiche toutes les cases de t de 20 à 49*/
printtab(t+20,10);/*affiche toutes les cases de t de 20 à 30*/
}
Alogorithme & Programmation C
Les fonctions 36
Passage d'un tableau à une dimension en
paramètre
Puisqu'en fait t1 est une adresse, on peut le déclarer comme tel
Si un argument est de type tableau (càd une adresse), la fonction peut modifier les
cases du tableau

void printtab (int t1,int n) {


int i; void main () {
for (i=0;i<n;i++)
int t[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",t1[i]);
} printtab(t,10); -> 1 2 3 4 5 6 7 8 9 10
misea0(t,10);
void misea0 (int t1[], int n){
printtab(t,10); -> 0 0 0 0 0 0 0 0 0 0
int i;
for (i=0;i<n;i++) }
t1[i]=0;
} Alogorithme & Programmation C
Les fonctions 37
Exemple
La procédure minmax calcule le minimum et le maximum des éléments d’un tableau
passé en paramètre. Le résultat est placé dans un autre tableau, également passé en
paramètre :
void minmax(int tab[], int res[], int n)
{
Voici un programme utilisant cette procédure
int i;
int max, min; #include <stdio.h>
max = min = tab[0]; int main () {
for (i=1; i<n; i++) {
{ int t[10]={1,2,3,5,6,8,10,12};
if (min > tab[i]) int res[2];
min = tab[i];
minmax( T, res, 10);
printf("%d %d\n", res[0], res[1]);
if (max < tab[i])
return 0;
max = tab[i];
}
}
res[0]=min;
res[1]=max;
}
Alogorithme & Programmation C
Les fonctions 38
Pour passer un tableau (et donc une chaîne
de caractères) en paramètre à une fonction
Nous devons simplement donner l’adresse du début du tableau. Les deux fonctions
suivantes sont donc équivalentes :

int ma_saisie (char chaine[]) { int ma_saisie (char* chaine) {


/* ...Faire ce qu'il faut... */ /* ...Faire ce qu'il faut... */
return 0; return 0;
} }
int main () { int main () {
char ma_chaine [30]; char ma_chaine [30];
ma_saisie (ma_chaine); ma_saisie (ma_chaine);
return 0; return 0;
} }
En fait, dans la pratique, l’écriture suivante :
int ma_saisie (char chaine[]) { est équivalente à celle-ci : int ma_saisie (char * chaine) {
Nous reviendrons longuement, par la suite, sur cette quasi-équivalence pointeurs/tableaux…
ne vous inquiétez pas si vous ne comprenez pas tout pour l’instant…

Alogorithme & Programmation C


Les fonctions 39
Exercice (chaînes)
Ecrire un programme qui détermine le nombre et la position d'une sous-chaîne dans
une chaîne (exemple ON dans FONCTION : en position 1 et 6)..
#include <stdio.h>
#define taille 255
int debut_egal(char *ch,char *sch) /* répond si sch est exactement le début de ch */
{ while (*sch && *ch)
{ if (*sch!=*ch) return(0);
else {ch++;sch++;} } return(!(*sch)); }
void recherche(char *ch,char *sch) {
int pos=0;
while (*ch) {
if (debut_egal(ch,sch))
printf("trouvé en position %d\n",pos); ch++;pos++; } }

void main(void) {
char ch[taille],sch[taille];
puts("chaîne à tester ? ");
gets(ch); puts("sous-chaîne à trouver ?");
gets(sch); recherche(ch,sch); }
Alogorithme & Programmation C
Les fonctions 40
#include <stdio.h>
void avance_Position (int* pointeur_int) { Imaginons que pointeur int se trouve en
*pointeur_int = *pointeur_int + 2; mémoire à l’adresse 20 et x à l’adresse 10 :
}
int main () {
int x=0; Nom de la x pointeur int
printf("Position de départ : %d\n",x); variable
avance_Position (&x);
Contenu mémoire
printf("Nouvelle position : %d\n",x);
return 0; Adresse mémoire 10 20
(0x)
}

À présent, déroulons le programme principal :


Nom de x pointeur
1. int x=0 ; : déclaration et initialisation de x à 0 la int
2. Avance Position (&x) ; : appel de la fonction Avance Position (&x) ; avec la valeur 10 variable
(l’adresse de x) en paramètre
3. void Avance Position (int* pointeur int) : on lance cette fonction et pointeur int vaut Contenu 0 10
donc 10 mémoire
4. * pointeur int = (* pointeur int) + 2 ; : (*pointeur int) pointe sur la variable x. Adresse 10 20
L’ancienne valeur de x va être écrasée par sa nouvelle valeur : 0+2 mémoire
5. printf("Nouvelle position :%d",x) ; : on se retrouve avec 2 comme valeur. (0x)

 Nous devons utiliser des pointeurs pour pouvoir modifier certaines variables en dehors de
l’endroit où elles sont déclarées. On dit généralement qu’une fonction n’est pas capable de
modifier ses arguments Alogorithme & Programmation C
Les fonctions 41
Exécutez les programmes suivants :

#include <stdio.h>
void calcule_double (int x) Pour rendre le programme fonctionnel en utilisant
{ les pointeurs, il faudrait écrire :
x=x+x ; Néanmoins, la bonne pratique
#include <stdio.h> (celle qui donne les programmes
} void calcule_double (int * p_i) les plus simples à comprendre
int main () { { et les plus faciles à déboguer)
int i=2; *p_i=*p_i+*p_i; serait d’écrire :
calcule_double(i); }
printf("i vaut à présent : #include <stdio.h>
int main () {
%d",i); /* il vaut toujours 2 !!! int calcule_double (int a)
int i=2;
*/ {
calcule_double(&i);
return 0; a=a+a;
printf("i vaut à présent :%d",i);
} return a;
return 0;
}
}
int main () {
int i=2;
Observez attentivement les trois exemples qui i=calcule_double(i);
précèdent et soyez sûr d’avoir bien compris printf("i vaut à présent :%d",i);
pourquoi le premier affiche 2 alors que les deux return 0;
suivants affichent 4. }

Alogorithme & Programmation C


Les fonctions 42
La fonction “main”
La fonction principale “main” est obligatoire pour créer un programme. Elle doit être
unique et ce nom (ainsi que la casse) est imposé.
• Code de retour
La valeur retournée par la fonction main est soit de type int soit de type void.

En fait main retourne toujours une valeur car le système qui a lancé votre programme
attend cette valeur de compte rendu d’exécution; si vous avez déclaré void, la
valeur retournée est imprévisible ou dépend de votre compilateur .
int main () { void main(void) {
……. #include <stdio.h>
……….
…… int main(int argc, char * argv[])
……….
{
return 0;
} ………
}
……….
void main() { return 0;
……. }
……

Les fonctions } Alogorithme & Programmation C


43
Exemple
La procédure minmax calcule le minimum et le maximum des éléments d’un tableau
passé en paramètre. Le résultat est placé dans un autre tableau, également passé en
paramètre :
void minmax(int tab[], int res[], int n)
{
Voici un programme utilisant cette procédure
int i;
int max, min; #include <stdio.h>
max = min = tab[0]; int main () {
for (i=1; i<n; i++) int main(int argc, char * argv[])
{ {
if (min > tab[i]) int t[10]={1,2,3,5,6,8,10,12};
min = tab[i];
int res[2];
minmax( T, res, 10);
if (max < tab[i])
printf("%d %d\n", res[0], res[1]);
max = tab[i];
return 0;
} }
res[0]=min;
res[1]=max;
}
Alogorithme & Programmation C
Les fonctions 44
VISIBILITE DES DONNEES

Variables globales et locales


Selon l'emplacement de la définition d'une variable, celle-ci est soit :
• une variable locale  Toute variable définie à l'intérieur des fonctions.
• une variable globale  Toute variable définie à l'extérieur des fonctions

Une variable globale est connue donc utilisable dans n'importe quelle partie du
fichier où elle est définie en particulier à l'intérieur de n'importe quelle fonction
du module.
Cette portée peut même s'étendre à d'autres modules du programme, si le
programme est constitué de plusieurs fichiers.
Une variable locale n'est connue qu'à l'intérieur du bloc dans lequel elle est
définie.

Alogorithme & Programmation C


Les fonctions 45
Variables locales Variables globales
#include <stdio.h>
#include <stdio.h> int val = 0;
int carre (int val) { int val_retour = 0;
int v = 0; /* Variable locale */ void carre () {
v = val * val; val_retour = val * val;
return v; }
} int main () {
int main () { val = 2;
int val_retour = 0; /* Variable locale */ carre ();
val_retour = carre (2); printf("Le carré de 2 est %d\n",
printf("Le carré de 2 est : %d\n", val_retour); val_retour);
return 0; return 0;
} }
La variable val retour de main et la variable v de carre
sont toutes deux des variables locales. Le passage des Les variables val et val retour sont des variables
valeurs se fait par copie. Lors du return v, on peut globales. On constate que le programme devient
imaginer que c’est le contenu de v qui est renvoyé, puis rapidement illisible et difficile à vérifier…
stocké dans val retour. La variable v est détruite lorsqu’on
revient dans main.

Le conseil à retenir est de ne pas utiliser de variable(s)


globale(s) lorsqu’il est possible de s’en passer.
Alogorithme & Programmation C
Les fonctions 46
Variables locales et globales (1)
• On peut manipuler 2 types de variables dans un module (procédure ou fonction) :
des variables locales et des variables globales. Elles se distinguent par ce qu'on
appelle leur portée (leur "champ de définition", leur "durée de vie")

• Une variable locale n'est connue qu'à l'intérieur du module ou elle a été définie. Elle
est créée à l'appel du module et détruite à la fin de son exécution

• Une variable globale est connue par l'ensemble des modules et le programme
principale. Elle est définie durant toute l’application et peut être utilisée et modifiée
par les différents modules du programme

Alogorithme & Programmation C


Les fonctions 47
Variables locales et globales (2)
• La manière de distinguer la déclaration des variables locales et globales diffère selon
le langage

– En général, les variables déclarées à l'intérieur d'une fonction ou procédure sont


considérées comme variables locales

• En pseudo-code, on va adopter cette règle pour les variables locales et on déclarera


les variables globales dans le programme principale

• Conseil : Il faut utiliser autant que possible des variables locales plutôt
que des variables globales. Ceci permet d'économiser la mémoire et
d'assurer l'indépendance de la procédure ou de la fonction

Alogorithme & Programmation C


Les fonctions 48
Exemple :
int g; g est une variable globale
main() {
int i; i est une variable locale
static int k; i est une variable globale privée
...
}
On retiendra que :
• Les variables globales sont statiques c'est-à-dire qu'elles sont permanentes.
Elles existent toute la durée de l'exécution du programme. Au démarrage du
programme, le système alloue l'espace nécessaire et effectue les
initialisations.
Tout cet espace sera rendu au système lors de la terminaison du programme.
• les variables locales et les arguments formels des fonctions sont
automatiques.
L'espace nécessaire est alloué lors de l'activation de la fonction ou du bloc
correspondant. Il est restitué au système à la fin du bloc ou de la fonction.

Alogorithme & Programmation C


Les fonctions 49
Les fonctions…
et les pointeurs (encore je sais…)

Soit la déclaration suivante


typeA (*ptr_fonction) (typeB *val1,typeB val2,…,typeA valN);

Alors je peux écrire


ptr_fonction = &ma_fonction;

Du coup quand je fais


toto= (*ptr_fonction)(&tutu, tata,…,titi);

Donne le même résultat que


toto= ma_fonction(&tutu, tata,…,titi);

Alogorithme & Programmation C


Les fonctions 50