Vous êtes sur la page 1sur 19

Royaume du Maroc

OFFICE DE LA FORMATION PROFESSIONNELLE ET DE LA PROMOTION DU TRAVAIL

Chap 13T
Langage C et Gestion des Entres/Sorties
Rsum de Thorie
Version prliminaire

Deuxime Anne
Programme de Formation des Techniciens
Spcialiss en lectronique
DIRECTION DE LA RECHERCHE ET INGENIERIE DE LA FORMATION
Septembre 1996

Rsum de Thorie

Langage C et Gestion des Entres/Sorties

TECCART INTERNATIONAL 2000 inc.


3155, rue Hochelaga,
Montral, Qubec (Canada)
H1W 1G4

RDACTION
Robert Pesant
DESSINS ET CONCEPTION GRAPHIQUE
Robert Pesant
RVISION TECHNIQUE
Robert Pesant
RVISION LINGUISTIQUE
Franois Gaudreau

COMMISSION DE VALIDATION
Formateurs de lOFPPT

Les droits de reproduction et de diffusion de ce document sont cds par Teccart


International 2000 inc. lOffice de la Formation Professionnelle et de la Promotion du
Travail du Royaume du Maroc, pour sa propre utilisation au Maroc.
Mis part lOFPPT, toute reproduction, en tout ou en partie, par quelque procd que ce
soit, est interdite.

Imprim Montral, le j May


270911578.doc/

Fonctions

Page 2

OFPPT/TECCART

Rsum de Thorie

Langage C et Gestion des Entres/Sorties

TABLE DES MATIRES


6. FONCTIONS
06.1 Fonctions et Standard ANSI
06.1.1 Quest-ce quune fonction?........................................................................................
16.1.2 Prototype de fonction.................................................................................................
26.1.3 Dfinition de fonction.................................................................................................
36.1.4 Dclaration de fonction..............................................................................................
46.1.5 Types de fonctions......................................................................................................
56.1.6 Appel de fonction........................................................................................................
16.2 Rdaction d'un programme avec fonctions
66.2.1 Documentation d'un programme................................................................................
76.2.2 Programme structur avec des fonctions: FONCTION.C..........................................
26.3 Passage des paramtres par les valeurs
86.3.1 Variables locales..........................................................................................................
96.3.2 Variables et modle des rcipients..............................................................................
106.3.3 Mcanisme de passage des paramtres par les valeurs.............................................

Fonctions

Page 3

OFPPT/TECCART

Fonctions
Fonctions et Standard ANSI
Quest-ce quune fonction?
Une fonction est un ensemble d'instructions et de variables regroupes dans un bloc pour
effectuer une tche spcifique.
Le rle premier d'une fonction est d'viter l'usager de rpter le mme code en diffrents
endroits du programme. Lorsque le code de la fonction sera crit et que l'usager lui aura attribu
un identificateur, c'est--dire un nom, il pourra en faire l'appel dans son programme aussi souvent
que ncessaire, comme c'est le cas pour des fonctions de la bibliothque de Borland C++ tels que
printf() et getch().
Par l'usage des fonctions, la programmation devient structure. Le programme principal, c'est-dire la fonction main(), pourra se construire partir d'un modle prdfini et se composer
presque exclusivement d'appels de fonctions. Il n'en sera que plus facile rdiger, comprendre,
dpanner et entretenir.
Pour rendre une fonction indpendante de la fonction main() ainsi que de toutes les autres
fonctions, le langage C permet l'usage de variables "prives". Ces variables dites locales ne sont
accessibles que par la fonction o elles sont dfinies. L'usager peut donc utiliser les identificateurs
de son choix, mme s'il les a dj utiliss ailleurs dans une autre fonction. Nous reviendrons sur
cette notion importante vers la fin de ce chapitre.
Pour changer des donnes avec le programme qui l'appelle, une fonction peut accepter
plusieurs paramtres mais ne peut retourner qu'une seule et unique valeur.
Pour manipuler correctement une fonction, il faut savoir...
1.
la dfinir,
2.
la dclarer
3.
et en faire l'appel.
Deux notions fondamentales sont ncessaires pour y parvenir:
4.
le prototype de fonction, adopt par le Standard ANSI;
5.
la technique du passage de paramtres par les valeurs.
Prototype de fonction
Le prototype d'une fonction est compos de trois lments crits sur une seule ligne:
6.
le type de donne de la valeur retourne;
7.
l'identificateur de la fonction;
8.
le type de donne et l'identificateur de chaque paramtre, spars par une virgule et
encadrs par une paire de parenthses.
Prenons comme exemple une fonction qui attend le choix de l'usager lorsqu'on lui prsente un
menu. Son prototype peut s'crire comme suit: int get_choix(void). Cette fonction se nomme
get_choix. Son rle est de retourner, sous forme d'un int, le code ASCII de la touche presse
par l'usager. Comme l'information recueillie par cette fonction provient directement du clavier,
elle n'a besoin d'aucun paramtre: on retrouve donc le mot-cl void entre ses parenthses.
Examinons maintenant le prototype d'une fonction qui affiche les codes ASCII compris entre
deux valeurs spcifies par l'usager: void affi_ascii(int code_min, int code_max). La fonction
affi_ascii affiche des caractres l'cran; elle n'a donc pas de valeur numrique retourner au
programme d'appel; c'est ce qui justifie l'emploi du mot-cl void devant son identificateur. Par
contre, cette fonction a besoin de connatre les codes de dbut et de fin qu'elle doit afficher: le

premier paramtre, de type int, est le code initial identifi par code_min; le deuxime paramtre,
galement de type int, est le code final code_max.
Sans mme connatre comment ces deux fonctions vont accomplir leur boulot respectif, nous
avons dj une trs bonne ide de la faon de les utiliser: entre autres choses, il ne faut pas passer
affi_ascii() des variables de type double!
Le prototype de fonction est une nouveaut du langage C introduite par le Standard ANSI. C'est
l'outil qu'utilise le compilateur pour dtecter et signaler par des avertissements (warnings) que
l'usager n'utilise pas les bons types de donnes dans le passage de paramtres.
Dfinition de fonction
Une dfinition de fonction se compose:
9.
du prototype de la fonction;
10. du bloc d'instructions.
Voici la dfinition de la fonction get_choix():
int get_choix(void)
{
int choix;
do

{
gotoxy(63, 11); putch('*'); gotoxy(63, 11);
choix = getche();
}
while(CLE_INTERDITE);
}

return(choix);

Aprs la dfinition de la variable choix, la boucle do ... while() effectue le verrouillage explicite
des touches interdites. L'expression tester est dcrite par la directive suivante:
#define CLE_INTERDITE !((choix == '1') || (choix == '2') || (choix == ESC)) .
Lorsque l'usager choisit une touche permise, 1, 2 ou Esc, le code ASCII dpos dans choix par
getche() est affich l'cran puis transfr ou retourn au programme d'appel par l'instruction
return(choix);. La variable choix a t obligatoirement dfinie de type int, pour tre conforme
au type de donne spcifi par le prototype de la fonction.
L'excution d'une fonction peut se terminer de deux faons diffrentes: par la rencontre de
l'accolade dlimitant la fin du bloc de la fonction ou par l'excution de l'instruction return.
Voyons maintenant la dfinition de la fonction affi_ascii():
void affi_ascii(int code_min, int code_max)
{
int i;
gotoxy(1, 17);
if((code_min < 0) || (code_min > 255) || (code_max < 0) || (code_max > 255))
{
puts("ERREUR!!! Au moins un des deux codes n'est pas compris entre 0 et 255.");
puts("Vous devez recommencer...");
return;
}
if(code_max < code_min)
{
puts("ERREUR!!! Le code final est plus petit que le code initial.");
puts("Vous devez recommencer...");
return;
}

for(i = code_min; i <= code_max ; i++)


{
putch(i); putch(' ');
}

Les deux paramtres, que requiert cette fonction, sont automatiquement dfinis par le prototype
qui prcde le bloc d'instructions. Seule la variable i, qui n'est pas un paramtre, est dfinie dans
le bloc de la fonction par l'instruction int i;.
Puis, deux instructions if vrifient la validit des codes ASCII de dbut et de fin que reoit la
fonction par l'intermdiaire de ses paramtres. Si l'un ou l'autre des codes est infrieur ASCII 0
ou suprieur ASCII 255, ou si le code de fin est infrieur au code de dbut, un message
d'erreur appropri est affich. L'excution de la fonction est alors interrompue par l'instruction
return;. tant donn que la fonction affi_ascii() ne retourne rien au programme d'appel, le motcl return doit donc tre utilis seul, sans aucune expression, pour pouvoir terminer la fonction
ailleurs qu' l'accolade de fin de bloc.
Par contre, si les codes de dbut et de fin sont valides, une boucle for affiche les caractres
ASCII dlimits par ces deux valeurs. L'excution de la fonction se termine alors l'accolade de
fin de bloc.
Dclaration de fonction
Une dclaration de fonction est constitue:
11. du prototype de la fonction;
12. suivie d'un point virgule.
La dclaration d'une fonction doit ncessairement se faire avant l'instruction d'appel. Dans
l'exemple qui suit, les dclarations de get_choix() et affi_ascii() prcdent la dfinition de la
fonction main() qui utilise ces deux fonctions:

La dclaration d'une fonction indique au compilateur comment prparer le code objet (code
machine) qui permettra le saut la sous-routine correspondant cette fonction. L'appel de cette
fonction peut alors tre fait mme si sa dfinition, c'est--dire son code, apparat plus loin dans le
programme.

Une dclaration de fonction ne gnre pas de code objet. Elle ne peut donc pas remplacer la
dfinition de fonction. Par contre, la dfinition de fonction peut servir de dclaration, si elle
prcde l'appel de cette fonction:

Types de fonctions
La Tableau 6 -1 prsente les quatre types de fonctions que l'on peut rencontrer.
T AB L E AU 6-1: L E S
Type
1
2
3
4

T Y P E S D E F O N C T I ON S

Valeur retourne
Aucune
Une seule
Aucune
Une seule

Paramtres
Aucun
Aucun
Un ou plusieurs
Un ou plusieurs

En voici des exemples:


void
int
void
double

menu
get_choix
affi_ascii
mise_a_echelle

(void);
<--------------------------------------------------(void);
<--------------------------------------------------(int code_min, int code_max);
<----------------------------(double courant, double portee_min, double portee_max);
<---

Type
Type
Type
Type

1
2
3
4

Appel de fonction
Pour faire l'appel d'une fonction de type 1, il suffit d'crire son nom, suivi de parenthses vides et
d'un point virgule:
Fonction de l'usager

Fonction de la bibliothque

menu();

clrscr();

Dans le cas du type 2, il faut au pralable dfinir une variable de mme type que la valeur
retourne pour pouvoir la rcuprer la fin de l'excution de cette fonction:
Fonction de l'usager

Fonction de la bibliothque

int choix;

int touche;

choix = get_choix();

touche = getch();

Lors de son appel, une fonction de type 3 doit recevoir des valeurs numriques par l'intermdiaire
de ses paramtres. Ces valeurs peuvent tre des variables ou des constantes, en autant qu'elles
soient du mme type de donne que les paramtres:
Fonction de l'usager

Fonction de la bibliothque

int ascii_min = 33, ascii_max = 65;

gotoxy(15, 10);

affi_ascii(ascii_min, ascii_max);

Enfin, l'appel d'une fonction de type 4 combine les techniques utilises pour le type 2 et le type 3:
Fonction de l'usager

Fonction de la bibliothque

double courant = 14.5, temperature;

int c_maj, c_min = 'a';

temperature = mise_a_echelle(courant, -25.0, 75.0);

c_maj = toupper(c_min);

Rdaction d'un programme avec fonctions


Documentation d'un programme
Avant mme de songer rdiger des fonctions pour structurer son programme, le programmeur
consciencieux se doit de bien le documenter. Il sera beaucoup plus simple comprendre,
dpanner et entretenir. On entend par entretien d'un programme, les modifications qu'on doit lui
faire subir pour amliorer ses performances aprs un certain temps d'utilisation.
La technique de documentation de programme prconise dans ce cours favorise dans l'ordre les
quatre lments suivants.
1.

2.

3.

4.

Un commentaire en dbut de programme contenant:


le titre;
le nom de l'auteur;
la date de cration;
la date de la dernire rvision;
la version;
le nom de volume du disque ou de la disquette de sauvegarde;
le nom du fichier, incluant le chemin du rpertoire;
la description du fonctionnement du programme.
Un commentaire de fonction prcdant la dfinition et contenant:
le nom de la fonction;
la description du fonctionnement;
la description des paramtres;
la description de la valeur retourne.
L'utilisation d'identificateurs de variables et de fonctions qui ont du sens comme:
temperature, courant;
menu(), get_choix();
plutt que:
var1, var2;
fonc1(), fonc2().
Un commentaire d'instruction ou de groupe d'instructions, lorsque le commentaire de
fonction ou le choix des identificateurs ne sont pas suffisants une bonne comprhension.

Programme structur avec des fonctions: FONCTION.C


Le programme FONCTION.C est construit selon le Modle #1 prsent au chapitre prcdent.
L'usager se voit offrir un menu de deux options: l'affichage des codes ASCII compris entre deux
valeurs de son choix et la simulation d'un transmetteur de temprature 4-20 mA. Ce programme
fait appel la technique du verrouillage explicite des touches interdites. De plus, il utilise les
fonctions qui ont servi d'exemples la section prcdente. Voici son listage.
/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*/

FONCTION.C
==========
Robert Pesant
22/02/1993
25/04/1995
V1.2
COURS_13T
\CHAP.007\FONCTION.C
Programme de dmonstration qui utilise des fonctions dfinies par l'usager.

/* Les fichiers d'en-tte de la bibliothque de Borland C++ -------------- */


#include
#include
#include
#include
#include

<stdio.h>
<conio.h>
<string.h>
<process.h>
<dos.h>

/* Les constantes symboliques -------------------------------------------- */


#define
#define
#define
#define
#define

MENU_1
MENU_2
MENU_3
MENU_4
MENU_5

""
" Programme de dmonstration "
" contenant des fonctions
"
"
rdiges par l'usager
"
""

#define
#define
#define
#define

MENU_6
MENU_7
MENU_8
MENU_9

"Affichage des codes ASCII ..................


"Mise l'chelle d'un transmetteur 4-20 mA .
"Quitter ....................................
"Votre choix ................................

#define
#define
#define
#define
#define
#define
#define

RETOUR
ASCII_1
ASCII_2
ECHELLE_1
ECHELLE_2
ECHELLE_3
ECHELLE_4

"Retour au menu: une touche, SVP"


"Entrez le code ASCII initial: "
"Entrez le code ASCII final: "
"Transmetteur de temprature 4-20 mA (-25 C +75 C)"
"====================================================="
"Entrez la valeur du courant du transmetteur .: "
"La temprature mesure correspondante est ...: "

#define
#define
#define
#define

CODE_ASCII
TX_4_20_MA
ESC
CLE_INTERDITE

'1'
'2'
27
!((choix == '1') || (choix == '2') || (choix == ESC))

< 1 >"
< 2 >"
<Esc>"
< * >"

/* Les dclarations des fonctions de l'usager ---------------------------- */


void
int
void
void
double

menu
get_choix
clr_lines
affi_ascii
mise_a_echelle

(void);
(void);
(int y);
(int code_min, int code_max);
(double courant, double portee_min, double portee_max);

void main(void)
{
int choix, ascii_min, ascii_max;
double courant, temperature;
clrscr();
menu();
do

{
choix = get_choix();
switch(choix)
{
case CODE_ASCII:
gotoxy(1, 15); printf(ASCII_1);
scanf("%d", &ascii_min); fflush(stdin);
gotoxy(41, 15); printf(ASCII_2);
scanf("%d", &ascii_max); fflush(stdin);
affi_ascii(ascii_min, ascii_max);
break;
case TX_4_20_MA:
gotoxy(1, 15); puts(ECHELLE_1);
gotoxy(1, 16); puts(ECHELLE_2);
gotoxy(1, 18); printf(ECHELLE_3);
scanf("%lf", &courant); fflush(stdin);
gotoxy(1 + strlen(ECHELLE_3), 18);
printf("%6.2f mA", courant);
if((courant < 4.0) || (courant > 20.0))
{
puts(" (...???)");
}
temperature = mise_a_echelle(courant, -25.0, 75.0);
gotoxy(1, 19); printf(ECHELLE_4);
printf("%6.2f C", temperature);
break;
case ESC:
clrscr(); exit(0);
}

gotoxy(41, 25); printf(RETOUR);


getch();
clr_lines(15);
}
while(1);

/* Fonction:
* ========
*
* Description:
*
* Paramtres:
*
* Valeur/retour:
*/
void menu(void)
{
gotoxy(41 gotoxy(41 gotoxy(41 gotoxy(41 gotoxy(41 -

gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

menu()
======
Affiche le menu du programme
1. Aucun
1. Aucune

strlen(MENU_1
strlen(MENU_2
strlen(MENU_3
strlen(MENU_4
strlen(MENU_5

)/2,
)/2,
)/2,
)/2,
)/2,

1);
2);
3);
4);
5);

puts(MENU_1
puts(MENU_2
puts(MENU_3
puts(MENU_4
puts(MENU_5

);
);
);
);
);

strlen(MENU_6
strlen(MENU_7
strlen(MENU_8
strlen(MENU_9

)/2, 8); puts(MENU_6


)/2, 9); puts(MENU_7
)/2, 10); puts(MENU_8
)/2, 11); puts(MENU_9

);
);
);
);

/* Fonction:
* ========
*
* Description:
*
*
* Paramtres:
*
* Valeur/retour:
*/

get_choix()
===========
Attend et retourne le choix de l'usager.
Les touches interdites du clavier sont verrouilles.
1. Aucun
1. Le code ASCII du choix de l'usager

int get_choix(void)
{
int choix;
do

{
gotoxy(63, 11); putch('*'); gotoxy(63, 11);
choix = getche();
}
while(CLE_INTERDITE);
}

return(choix);

/* Fonction:
* ========
*
* Description:
*
*
* Paramtres:
*
* Valeur/retour:
*/

clr_lines()
===========
Efface le bas de l'cran en faisant remonter le texte
partir de la ligne choisie par l'usager.
1. La ligne partir de laquelle on efface l'cran.
1. Aucune.

void clr_lines(int y)
{
int i;

gotoxy(1, y);
for(i=y; i<=25; i++)
{
delline();
delay(50);
}

/* Fonction:
* ========
*
* Description:
*
*
* Paramtres:
*
*
* Valeur/retour:
*/

affi_ascii()
============
Affiche les codes ASCII demands par l'usager
et compris entre 0 et 255.
1. Le code ASCII initial qui doit tre affich.
2. Le code ASCII final qui doit tre affich.
1. Aucune.

void affi_ascii(int code_min, int code_max)


{
int i;
gotoxy(1, 17);
if((code_min < 0) || (code_min > 255) || (code_max < 0) || (code_max > 255))
{
puts("ERREUR!!! Au moins un des deux codes n'est pas compris entre 0 et 255.");
puts("Vous devez recommencer...");
return;
}
if(code_max < code_min)
{
puts("ERREUR!!! Le code final est plus petit que le code initial.");
puts("Vous devez recommencer...");
return;
}

for(i = code_min; i <= code_max ; i++)


{
putch(i); putch(' ');
}

/* Fonction:
* ========
*
* Description:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* Paramtres:
*
*
*
* Valeur/retour:
*/

mise_a_echelle()
================
Effectue la mise l'chelle d'un transmetteur 4-20 mA
en fonction des portes minimale et maximale de son
tendue de mesure.
Exemple: Transmetteur de temprature 4-20 mA dont l'tendue
de mesure est comprise entre -25 C et +75 C.
20 mA ----------- 75 C
<-- porte maximale

B

I ----------- T
<-- grandeur mesure
C


4 mA ----------- -25 C <-- porte minimale
Calcul de mise l'chelle:
A/B = C/D
(T - (-25))/(75 - (-25)) = (I - 4)/(20 - 4)
(T + 25)/100 = (I - 4)/16

T = (100/16)*(I - 4) - 25 <-- Fonction de transfert

Pour n'importe quelle valeur de courant mesure entre


4 et 20 mA, on peut valuer la temprature laquelle est
soumis le capteur du transmetteur de temprature.
1. Le courant du transmetteur.
2. La porte minimale du transmetteur.
3. La porte maximale du transmetteur.
1. La grandeur physique mesure par le transmetteur.

double mise_a_echelle(double courant, double portee_min, double portee_max)


{
double grandeur;
courant = (courant < 4.0) ? 4.0: courant;
courant = (courant > 20.0) ? 20.0: courant;
grandeur = ((portee_max - portee_min)*(courant - 4.0)/16.0) + portee_min;
}

return(grandeur);

Le texte du programme FONCTION.C dbute par les directives au prprocesseur #include et


#define. Celles-ci sont immdiatement suivies des dclarations des fonctions de l'usager.
Par l'usage des fonctions de la bibliothque et de l'usager, le programme principal, dfini dans la
fonction main(), ressemble davantage un algorithme qu' une suite d'instructions:
13. clrscr() .....................................effacer l'cran.
14. menu() .....................................prsenter le menu l'usager.
15. get_choix() ..............................dtecte le choix de l'usager.

16.

switch(choix) ..........................excute la tche choisie par l'usager


case CODE_ASCII:
affi_ascii() ................ affichage des codes ASCII entre les limites dtermines par
l'usager.
case TX_4_20MA:
mise_a_echelle() ........ simulation d'un transmetteur de temprature; calcul de la
temprature mesure en fonction du courant choisi par
l'usager.
case ESC:
exit() ..........................fin du programme et sortie au DOS.
17. clr_lines() ................................effacer les rsultats la demande de l'usager.
18. retour l'tape 3.
La suite du programme contient les dfinitions des fonctions de l'usager. Consultez leur
description respective pour en connatre le fonctionnement.
Pour obtenir des programmes structurs, faciles comprendre et dpanner, chaque fonction
doit tre simple: elle doit tre conue pour accomplir autant que possible une seule tche. On doit
bannir les fonctions dont les dclarations ressemblent ceci:
void

je_fais_tout_a_moi_tout_seul(void);

Excutez le programme FONCTION.EXE. Vous devriez obtenir des rsultats semblables ceux
de la Figure 6 -1.

F I G U R E 6-1: E X C U T I ON

DE

F O NC T I O N . E X E

Passage des paramtres par les valeurs


Variables locales
ventuellement, on verra qu'il y a plusieurs faons de dfinir des variables. Jusqu' maintenant,
elles ont toujours t dfinies l'intrieur des parenthses des blocs de fonctions. Examinons les
caractristiques de ces variables.
Leur classe de stockage implicite est appele automatique. Une classe de stockage dtermine
comment une variable est sauve en mmoire. Une variable automatique est sauve sur la pile du
systme. Sa dure de vie est limite la dure d'excution de la fonction: elle est cre en dbut
d'excution et dtruite la fin.
Le mot-cl prcisant cette classe de stockage est auto. Pour dfinir une variable automatique,
on devrait utiliser une instruction comme auto int choix;. Toutefois auto reprsente la classe de
stockage implicite; il n'est donc pas ncessaire de la prciser: int choix; est quivalent auto int
choix;.
La visibilit d'une variable automatique est dite locale: elle est accessible seulement par les
instructions de la fonction o elle est dfinie. L'usager peut donc utiliser les identificateurs de son
choix, sans se soucier s'il les a dj utiliss ailleurs dans d'autres fonctions. Pour cette mme
raison, lorsqu'on met sur pied une quipe de programmeurs pour travailler un gros projet, on
peut leur demander de rdiger chacun leur groupe de fonctions, sans risque de confusion.
Pour vrifier ces notions, excutez le programme FONCTION.C en respectant la procdure
suivante.
1.

Dplacez le curseur sur l'identificateur de la variable ascii_min dfinie dans la fonction


main(). Utilisez la commande Debug/Watches/Add watch... pour ouvrir la fentre de
surveillance sur la valeur de cette variable.

2.

Ajoutez galement les variables suivantes dans la fentre de surveillance: ascii_max


dfinie dans main(), code_min et code_max dfinies dans affi_ascii(). Vous pouvez
utiliser Ctrl-F7 pour y arriver plus rapidement.

3.

Placez la curseur sur l'instruction affi_ascii(ascii_min, ascii_max); qui fait partie de case
CODE_ASCII de l'instruction switch ... case de la fonction main().

4.

Dmarrez l'excution du programme avec la commande Run/Go to cursor. Choisissez


l'option Affichage des codes ASCII. Entrez le code initial 45 et le code final 67.

5.

Jetez maintenant un coup d'oeil la fentre de surveillance:


ascii_min: 45
ascii_max: 67
code_min: Undefined symbol 'code_min'
code_max: Undefined symbol 'code_max'
Puisque le programme a t interrompu l'intrieur de la fonction main(), seules les
variables locales ascii_min et ascii_max sont visibles. code_min et code_max n'existent
mme pas encore.

6.

Reprenez l'excution du programme l'aide de F7 (Run/Trace into). La fentre de


surveillance change compltement d'aspect, car l'excution de la fonction affi_ascii() vient
de dbuter:
ascii_min: Undefined symbol 'code_min'
ascii_max: Undefined symbol 'code_min'
code_min: 47
code_max: 65
C'est maintenant au tour de code_min et code_max d'tre visibles et dfinies. La fonction
affi_ascii() n'est mme pas au courant de l'existence de ascii_min et ascii_max.

7.

Vous pouvez terminer l'excution du programme avec Ctrl-F2 (Run/Program reset).

Cet exercice confirme qu'une variable locale de classe de stockage automatique n'est visible que
de la fonction o elle est dfinie.
Mais une question se pose. Comment les fonctions peuvent-elles manipuler et s'changer des
donnes si leurs variables locales passent leur temps apparatre et disparatre continuellement?
La rponse sera apporte par la technique du passage des paramtres par les valeurs.
Pour faciliter la comprhension et l'apprentissage de cette technique, nous introduirons d'abord le
modle des rcipients pour reprsenter plus concrtement les variables.
Variables et modle des rcipients
Une variable peut tre reprsente par un rcipient dont la dimension est proportionnelle son
type de donne. Le rcipient lui-mme correspond la rgion mmoire occupe par la variable et
son emplacement sur la tablette de rangement est l'adresse de cette variable. L'identificateur et la
valeur de la variable sont associs respectivement l'tiquette colle sur le rcipient et son
contenu.
La Figure 6 -2 prsente ce modle pour des variables de type char, int et double.

F I G U R E 6-2: L E

MODLE DES RCIPIENTS

Mcanisme de passage des paramtres par les valeurs


L'excution d'une fonction s'effectue en un maximum de trois tapes:
19. le passage des paramtres cette fonction par le programme d'appel;
20. l'excution des instructions de cette fonction;
21. le transfert de la valeur retourne par cette fonction une variable du programme
d'appel.
Comparons les prototypes de quelques fonctions du programme FONCTION.C:
void
int
void
double

menu
get_choix
affi_ascii
mise_a_echelle

(void);
(void);
(int code_min, int code_max);
(double courant, double portee_min, double portee_max);

En examinant, pour chacune d'elles, les paramtres et le type de donne de la valeur retourne, on
peut dduire quelles sont les tapes ncessaires leur excution respective:
menu() ------------>
get_choix() ------->
affi_ascii() ------>
mise_a_echelle() -->

tape 2 seulement,
tapes 2 et 3,
tapes 1 et 2,
tapes 1, 2 et 3.

Comme l'excution de mise_a_echelle() implique les trois tapes, ce sera notre fonction cobaye
pour illustrer le mcanisme de passage des paramtres par les valeurs.
Reportez-vous la Figure 6 -2. Les fonctions peuvent tre considres comme des
compartiments spars par un mur qui les rend invisibles les unes par rapport aux autres.
Dans main(), il y a deux rcipients de type double, courant et temperature. Ce sont assurment
des variables locales puisqu'elles sont dfinies l'intrieur des accolades de main(). Cette
fonction contient galement deux constantes relles reprsentant respectivement les portes
minimale et maximale de l'tendue de mesure du transmetteur 4-20 mA: -25.0 C et 75.0 C.
Du ct de la fonction mise_a_echelle() se trouvent quatre rcipients de type double: les trois
paramtres de la fonction, courant, portee_min et portee_max, ainsi que la variable grandeur.
Comme toutes les variables du programme sont locales, elles sont invisibles d'une fonction
l'autre. Mme si l'on retrouve un rcipient courant dans chacune des deux fonctions, il n'y a pas
de risque de confusion: ce sont deux rgions mmoire bien distinctes.
L'appel de la fonction mise_a_echelle() s'effectue dans main() par l'instruction suivante:
temperature = mise_a_echelle(courant, -25.0, 75.0);
L'excution de cette fonction dbute par l'tape du passage des paramtres par le programme
d'appel, ici la fonction main(). Remarquez qu'entre les parenthses de mise_a_echelle() se trouve
dans l'ordre courant, -25.0 et 75.0. Cette variable et ces deux constantes appartiennent la
fonction main(). Leurs positions respectives dans les parenthses correspondent aux positions de
courant, portee_min et portee_max, les trois paramtres de mise_a_echelle().
Selon notre modle, le passage des paramtres se droule comme ceci.
22. On prend le rcipient courant de main(), dont le contenu est 16.0, et on l'approche de la
fentre ddie au passage des paramtres.
23. La fonction mise_a_echelle() prsente automatiquement le rcipient de son premier
paramtre. Dans ce cas, l'tiquette sur chaque rcipient est la mme, mais personne
de chaque ct n'est au courant. Ce qui est primordial toutefois, c'est que les deux
rcipients soient de la mme dimension; sinon, il y a risque de dbordement!

24.
25.

On balance ensuite la constante relle -25.0 par la mme fentre. La fonction


mise_a_echelle() lattrape automatiquement avec le rcipient de son deuxime
paramtre, portee_min.
Enfin, c'est au tour de 75.0 de s'envoler travers la fentre. Comme c'est la troisime valeur
franchir le mur, il tombe automatiquement dans le rcipient du troisime paramtre,
portee_max.

F I G U R E 6-3: L E

M C AN I S M E D E PAS S AG E D E S PAR AM T R E S PAR L E S VAL E U R S

L'tape 1 est maintenant franchie. Passons l'tape 2, l'excution des instructions de cette
fonction. L'instruction la plus importante de mise_a_echelle() effectue le calcul de la grandeur
physique mesure par le capteur du transmetteur en fonction de la valeur de son courant:
grandeur = ((portee_max - portee_min)*(courant - 4.0)/16.0) + portee_min;
Pour un courant de 16.0 mA, le contenu du rcipient grandeur est 50.0 C.
La troisime tape de l'appel de mise_a_echelle() consiste retourner cette valeur la fonction
d'appel, main(). L'instruction requise est:
return(grandeur);

Cette instruction approche le rcipient grandeur prs de la fentre ddie au transfert de la


valeur retourne. De son ct, main() prsente le rcipient temperature pour rcuprer le
contenu de grandeur; elle y parvient l'aide de l'oprateur = dans l'instruction d'appel de
mise_a_echelle():
temperature = mise_a_echelle(courant, -25.0, 75.0);
Prcisons une dernire fois qu'aucune des deux fonctions ne connat l'tiquette du rcipient de
l'autre. L'opration de transfert de donne s'effectuera correctement la seule condition que les
dimensions des deux rcipients soient identiques.
Un modle est rarement parfait. Malheureusement, le ntre n'chappe pas cette rgle.
L'utilisation de rcipients porte croire que le contenu se dplacent lors des transferts de donne.
Hors, c'est compltement faux. En ralit, c'est une copie de la valeur de la variable qui est
transfre de la fonction d'appel la fonction appele et non la valeur elle-mme. Ainsi, la
variable courant dfinie dans main() conserve toujours sa valeur 16.0. Mme si courant est
dfinie sur la pile parce qu'elle est locale, elle cessera d'exister seulement la fin de l'excution de
la fonction main(), c'est--dire la toute fin du programme lui-mme.
Pour confirmer cette notion fondamentale, excutez une dernire fois en pas--pas
FONCTION.C, aprs avoir ouvert la fentre de surveillance (Watch) sur la variable courant de
main(). Ds que l'excution de mise_a_echelle() sera termine, la reprise de main() s'effectuera
avec
courant: 16.0
Les notions prsentes dans ce chapitre sont dune importance capitale pour rdiger des
programmes structurs. Mme si ce sujet nest pas simple matriser, apportez-y toute votre
attention et nhsitez pas relire ces pages aussi souvent que ncessaire. Vous y gagnerez la
longue.