Les sous-programmes

Transcription

Les sous-programmes
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
Chapitre 5 : Les sous-progra mmes
INTRODUCTION
Lorsqu'un programme est long, il est irréaliste d'écrire son code d'un seul tenant. En fait, on décompose le
programme en plusieurs parties plus petites, on donne un nom à chacune de ces parties, et on les assemble
pour former le programme final. C'est le principe de la programmation modulaire , qui repose sur
l'écriture de sous-programmes.
Un sous-programme est, comme son nom l'indique, un petit programme réalisant un traitement particulier
qui s'exécute à l'intérieur d'un autre programme.
Les sous-programmes sont utilisés pour deux raisons essentielles :
- quand un même traitement doit être réalisé plusieurs fois dans un programme (ou qu'il est
utilisé dans plusieurs programmes): on écrit un sous-programme pour ce traitement et on l'appelle à
chaque endroit où l'on en a besoin. On évite ainsi de réécrire plusieurs fois le code du traitement.
- pour organiser le code , améliorer la conception et la lisibilité des gros programmes. En effet, le
découpage en sous-programmes permet de traiter séparément les difficultés.
Certains sous-programmes ont déjà été écrits et peuvent être utilisés directement dans n'importe quel
programme. Ce sont des sous -programmes standards ou prédéfinis. C'est le cas par exemple des sousprogrammes permettant de faire des calculs mathématiques (racine carrée, exposant, …). La nature et le
nombre de programmes standards dépendent des langages.
Mais les sous-programmes prédéfinis ne suffisent pas pour découper un gros programme : le programmeur
est amené à écrire le code de ses propres sous-programmes.
Il existe deux sortes de sous-programmes : les procédures et les fonctions
Nous allons étudier d'abord les procédures simples, puis les fonctions. Nous reviendrons ensuite sur les
procédures pour étudier tous les types de passage de paramètres.
LES PROCEDURES (1 ière partie)
Une procédure est un ensemble d'instructions regroupées sous un nom, qui réalise un traitement particulier
dans un programme lorsqu'on l'appelle.
Comme un programme, une procédure possède un nom, des variables, des instructions, un début et une fin.
Mais contrairement à un programme, un sous-programme ne peut pas s'exécuter indépendamment d'un autre
programme.
Syntaxe de la DEFINITION d'une procédure:
Procédure ligneEtoile( )
Var
i : entier
Début
Pour i de 1 jusqu'à 10 Faire
Afficher '*'
FinPour
Afficher '\n'
FinProc
EN-TETE
CORPS
Cette procédure permet d'afficher une ligne de 10 étoiles puis passe à la ligne.
1
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
APPEL d'une procédure
Pour déclencher l'exécution d'une procédure dans un programme, il suffit de l'appeler, c'est-à-dire d'indiquer
son nom suivi de parenthèses.
Programme RectangleEtoile
Var
nlignes: entier
cpt : entier
Début
Afficher "Ce programme dessine un rectangle d'étoiles. Combien voulez-vous de lignes?"
Saisir nlignes
Pour cpt de 1 jusqu'à nlignes Faire
Var
ligneEtoile ( )
i : entier
FinPour
Début
Fin
Pour i de 1 jusqu'à 10 Faire
Afficher '*'
FinPour
appel de la
Afficher '\n'
procédure
FinProc
Lorsque le processeur rencontre l'appel d'une procédure, il arrête momentanément l'exécution du
programme appelant pour aller exécuter les instructions de la procédure. Quand il a terminé l'exécution de
la procédure, le processeur reprend l'exécution du programme appelant là où il s'était arrêté.
Une procédure peut être appelée soit par un programme, soit par un autre sous-programme (qui lui même a
été appelé). Les appels de sous-programmes peuvent s'imbriquer autant qu'on le désire.
Notions de variables locales et de paramètres
Les variables déclarées dans une procédure ne sont pas utilisables dans le programme appelant et
inversement, les variables déclarées dans le programme appelant ne sont pas utilisables dans les procédures.
Chaque programme et sous-programme a son propre espace de variables, inaccessible par les autres. On dit
que les variables sont LOCALES. (on verra qu'il existe des variables globales, mais elles sont très peu
utilisées).
2
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
Dans notre exemple, on ne pourrait pas saisir ou afficher la variable i dans le programme principal, car i est
une variable de la procédure, utilisable seulement dans celle -ci. Le programme principal n'a pas le droit de
l'utiliser. De même, la procédure n’a pas le droit d’utiliser la variable cpt déclarée en local dans le
programme principal.
Une question qui se pose alors est de savoir comment procédures et programmes vont pouvoir
communiquer des données. Par exemple, on pourrait vouloir que le programme principal communique à le
procédure combien d'étoiles afficher par ligne. Cela est possible grâce aux paramètres.
Un paramètre est une variable particulière qui sert à la communication entre programme appelant et
sous -programme.
Exemple :
Dans notre exemple, nous allons mettre le nombre d'étoiles par lignes en paramètre.
Pour cela, nous indiquons entre parenthèses la déclaration du paramètre (qui est une variable de la
procédure !), précédé du mot clé donnée pour indiquer que le paramètre constitue une donnée du traitement
réalisé par la procédure. La valeur de cette donnée est communiquée à l'appel, par le programme appelant.
Procédure ligneEtoile(donnée nombre : entier )
//sous-programme
Var
paramètre formel
cpt : entier
Début
Pour cpt de 1 jusqu'à nombre Faire
Afficher '*'
FinPour
Afficher '\n'
FinProc
Programme RectangleEtoile
//programme appelant
Var
nlignes, netoiles: entier //nombre de lignes et nombre d'étoiles par ligne
i : entier
Début
Afficher "Ce programme dessine un rectangle d'étoiles."
Afficher "Combien voulez-vous d'étoiles par ligne?"
Saisir netoiles
Afficher "Combien voulez-vous de lignes?"
Saisir nlignes
Pour i de 1 jusqu'à nlignes Faire
ligneEtoile (netoiles)
FinPour
paramètre effectif
Fin
Fonctionnement du passage des paramètres (de type donnée)
Lors de l'appel de la procédure, la valeur de la variable netoiles passée en argument est copiée dans le
paramètre formel nombre (qui est une variable). La procédure effectue alors le traitement avec la variable
nombre qui a bien la valeur voulue: celle de netoiles.
La procédure n'utilise par directement la variable netoile : elle utilise sa valeur, qu'elle a recopiée dans sa
propre variable -paramètre.
3
S. Laporte
Chap 5
Programme RectangleEtoile
copie
Lycée Louise Michel BTS IG 1
Procédure ligneEtoile
paramètre
donnée
netoiles
nombre
i
nlignes
cpt
I $ Remarque importante sur l'ordre et le nombre des paramètres
Lorsqu'il y a plusieurs paramètres dans la définition d'une procédure, il faut absolument qu'il y en
ait le même nombre à l'appel et que l'ordre soit respecté (car la copie se fait dans l'ordre).
Les paramètres réels et formels
Il est primordial de bie n distinguer les paramètres qui se trouvent dans l'en-tête d'une procédure, lors de sa
définition et les paramètres (ou arguments) qui se trouvent placés entre parenthèses lors de l'appel.
Ø
Les paramètres placés dans la définition d'une procédure sont les paramètres formels . Ils servent
à décrire le traitement à réaliser par la procédure indépendamment des valeurs traitées. Les
paramètres formels sont des variables locales à la procédure, et à ce titre ils sont déclarés dans l'entête de la procédure.
Ø
Les paramètres placés dans l'appel d'une procédure sont les paramètres réels ou effectifs.
Lorsqu'ils sont de type donnée, ils contiennent effectivement les valeurs sur lesquelles sera effectué
le traitement de la procédure. Lors de l'appel, leur valeur est recopiée dans les paramètres formels
correspondants. Un paramètre effectif en donnée peut être soit une variable du programme appelant,
soit une valeur littérale, soit le résultat d'une expression.
LES FONCTIONS
Les fonctions sont des sous-programmes qui retournent un et un seul résultat au programme appelant. De ce
fait, les fonctions sont appelées pour récupérer une valeur, alors que les procédures ne renvoient aucune
valeur au programme appelant.
L'appel des fonctions est différent de l'appel des procédures :
L'appel d'une fonction doit obligatoirement se trouver à l'intérieur d'une instruction (affichage,
affectation,…) qui utilise sa valeur.
Le résultat d'une fonction doit obligatoirement être retourné au programme appelant par l'instruction
Retourne.
Syntaxe générale
Fonction nom(déclaration des paramètres) : type de la valeur retournée
Var
//variables locales
I instruction obligatoire
Début
//traitement
Retourne valeur à retourner
FinFonction
correspond à la valeur d'une variable, d'une
expression ou d'une valeur littérale.
4
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
Exemple :
déclaration du paramètre formel
Fonction factorielle(n: entier) : entier
type de la valeur retournée
/*Cette fonction retourne la factorielle
du nombre n passé en paramètre*/
Var
commentaires de spécifications
i : entier
fact : entier
Début
fact ß 1
Si n ? 0 Alors
Pour i de 1jusqu'à n faire
fact ß fact * n
FinPour
FinSi
Retourne fact
instruction de retour
FinFonction
DEFINITION
de la fonction
factorielle
Fonction saisie_nb_positif( ) : entier
/*Cette fonction permet de faire saisir à l'utilisateur un nombre positif qui est alors retourné*/
Var
nb_saisi :entier
Début
Afficher "Veuillez entrer un nombre positif"
Saisir nb_saisi
Tantque nb_saisi < 0 Faire
Afficher "Erreur. Saisissez un nombre supérieur à 0 s'il vous plait !"
Saisir nb_saisi
FinTantque
Retourne nb_saisi
FinFonction
Exemple de programme appelant utilisant ces deux fonctions:
Programme affiche_factorielle
Var
nombre: entier
appel de la fonction saisie_nb_positif
rep : chaîne
et affectation de sa valeur retournée à la
Début
variable nombre
Répéter
nombre ß saisie_nb_positif( )
paramètre effectif
Afficher "La factorielle de ", nombre, " est ", factorielle(nombre)
Afficher "Voulez-vous recommencez? (oui/non)"
appel
de
la
fonction
Saisir rep
factorielle et affichage de sa
valeur retournée
Jusqu'à rep = "non"
Afficher "A bientôt"
Fin
Remarque :
Les paramètres d'une fonction sont toujours de type donnée. La valeur des paramètres effectifs à
l'appel est recopiée dans les paramètres formels qui servent à réaliser le traitement de la fonction.
5
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
LES PROCEDURES (suite et fin)
Comment faire pour qu'un sous-programme communique plusieurs résultats au programme appelant? C'est
impossible avec une fonction qui ne donne qu'un seul résultat, mais c'est possible grâce aux procédures
ayant des paramètres de statut résultat.
Une procédure peut renvoyer plusieurs résultats au programme appelant à travers des paramètres de statut
résultat. Elle peut aussi modifier la valeur d'un paramètre : ce paramètre doit alors avoir le statut de donnéerésultat.
Rappel et mise en garde: une fonction ne communique pas son résultat à travers un paramètre, mais à
travers une simple valeur de retour. Ne pas confondre avec les paramètres résultats utilisés dans les
procédures ! Le mode de communication est totalement différent
Il existe donc trois statuts pour les paramètres des procédures: donnée, résultat et donnée-résultat
Programme appelant
Procédure
à l'appel
à la fin de la procédure
donnée
résultat
à l'appel
donnée-résultat
à la fin de la procédure
copie de valeur
Nous avons déjà étudié le fonctionnement des paramètres données dans la première partie de ce cours; nous
allons voir ci-dessous le fonctionnement des deux autres.
Les paramètres résultats (en sortie)
Les paramètres résultats sont communiqués au programme appelant au moment du retour d'appel, c'est-àdire à la fin de la procédure. La valeur du paramètre formel résultat est alors copiée dans la variable passée
en paramètre dans l'appel (le paramètre effectif). La valeur initiale du paramètre effectif (à l'appel) n'a
aucune importance ; elle est même souvent indéterminée. La procédure se charge de lui affecter une valeur.
Exemple:
Voilà tout d'abord une procédure qui permet de saisir les valeurs (c'est-à-dire d'initialiser) un tableau de 30
réels. Cette procédure n'a qu'un paramètre : le tableau. C'est un résultat de la procédure.
Procédure Saisietab( résultat untab : tableau[1..30] de réels)
Var
i: entier
Début
Pour i de 1 jusqu'à 30 Faire
Saisir untab[i]
FinPour
/*à la fin de la boucle, le tableau est rempli*/
FinProc
6
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
Voilà une autre procédure qui trouve le minimum et le maximum dans un tableau de 30 réels. Le tableau est
une donnée, le minimum et le maximum sont des résultats.
Procédure minmax (donnée letab : tableau [1..30] de réels
résultats mini, maxi : réels )
Var
i : entier
Début
mini ß letab[1]
maxi ßletab[1]
Pour i de 2 jusqu'à 30 Faire
Si tab[i]< mini Alors
mini ß letab[i]
FinSi
Si tab[i]> maxi Alors
maxi ß letab[i]
FinSi
FinPour
/*A la sortie de la boucle, mini et maxi contiennent respectivement la valeur du minimum et la
valeur du maximum*/
FinProc
Voilà comment ces procédures peuvent être appelées dans un programme qui saisit 30 notes et affiche la
note maximale et la note minimale
Programme notes
Var
tabnotes: tableau [1..30] de réels
notemin, notemax: réels
Début
Afficher "Veuillez saisir les 30 notes"
Appel de la procédure Saisietab
Le paramètre est un tableau
I Attention : on ne met pas de crochets !
Saisietab(tabnotes)
minmax(tabnotes, notemin, notemax)
I Attention à l'ordre des paramètres
Afficher " La note la plus haute est ", notemax, "et la note la plus basse est ", notemin
Fin
Programme notes
appel
notemin
au retour d'appel
Procédure Saisietab
notemax
i
7
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
Programme notes
à l'appel
Procédure minmax
notemin
au retour d'appel
mini
maxi
notemax
i
$ Remarques :
Ø
On peut passer tout un tableau en paramètre. C'est une exception à la règle de manipulation des
tableaux : normalement, on ne peut pas les manipuler globalement, mais par exception, on peut les
utiliser globalement lorsqu'on les passe en paramètre.
Ø
Les deux procédures utilisent toutes les deux une variable appelée i. Mais i correspond à deux
variables différentes. Le i de la première procédure ne correspond pas à la même variable que le i
de la deuxième procédure : chaque sous-programme a son espace mémoire propre.
Paramètres donnée-résultat (en entrée-sortie)
Les paramètres données-résultats correspondent à des données qui doivent être modifiées par une
procédure.
A l'appel, la valeur du paramètre effectif est copié dans le paramètre formel de la procédure. La procédure
se sert de cette valeur pour la modifier. A la fin de la procédure, la nouvelle valeur du paramètre formel est
recopiée dans le paramètre effectif du programme appelant.
Exemple :
Voilà une procédure qui prend pour paramètre un tableau de 10 entiers non trié et qui le renvoie trié en
ordre croissant. Le tableau est à la fois une donnée et un résultat de la procédure.
Procédure tabtri( donnée-résultat letab : tableau[1...10] d'entiers)
Var
échange : booléen
i, fin : entier
//indices (fin = dernier indice traité)
temp : entier
//variable servant à l'échange
Début
échange ß faux
fin ß 10 -1
Répéter
Tantque i < fin Faire
Si letab[i] > letab[i+1] Alors
échange ß vrai
temp ß letab[i]
letab[i] ß letab[i+1]
letab[i+1] ß letab[i]
FinSi
8
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
iß i + 1
FinTantque
fin ß fin – 1
Jusqu'à non échange
/* à la sortie de la boucle, il n'y a plus d'échanges possibles donc le tableau est trié */
FinProc
Programme tri
Var
montablo: tableau[1..10] d'entiers
i :entier
Début
Afficher "Tapez 10 valeurs entières"
Pour i de 1 jusqu'à 10 Faire
Saisir montab[i]
FinPour
Appel de la procédure
Le paramètre est un tableau
I Attention : on ne met pas les crochets à l'appel!
tabtri(montab)
Affiche r "Voilà les valeurs triées dans l'ordre"
Pour i de 1 jusqu'à 10 Faire
Afficher montab[i]
FinPour
Fin
Résumé des différents statuts pour les paramètres
• paramètre donnée (appelant à sous-programme)
la valeur du paramètre effectif est utilisée dans la procédure et elle reste inchangée.
• paramètre résultat (sous-programmeà appelant)
la valeur initiale du paramètre effectif est ignorée par la procédure. La valeur final du paramètre formel
résultat est copiée dans le paramètre effectif correspondant (qui doit obligatoirement être une variable de
même type)
• paramètre donnée-résultat ( appelant ßà sous-programme)
La valeur initiale paramètre effectif est utilisée par la procédure qui modifie cette valeur. Au retour d'appel,
la nouvelle valeur est recopiée dans le paramètre effectif correspondant (qui est obligatoirement une
variable)
Résumé des différences entre fonctions et procédures.
Les fonctions ne peuvent avoir que des
paramètres données.
Les fonctions ne peuvent communiquer qu'un
seul résultat au programme appelant à travers
une valeur de retour (et non à travers un
paramètre)
Une s'appelle à l'intérieur d'une instruction.
L'instruction utilise la valeur retournée par la
fonction.
Les procédures peuvent avoir des paramètres
résultats, données ou données-résultats.
Les procédures peuvent communiquer de 0 à
plusieurs résultats au programme appelant à
travers des paramètres résultats ou donnéesrésultats. La valeur de ces résultat est affectée
aux paramètres effectifs correspondant (qui
doivent obligatoirement être des variables du
programme appelant).
L'appel d'une procédure représente une
instruction en elle- même. On ne peut pas
appeler une procédure au milieu d'une
instructio n
9
S. Laporte
Chap 5
Lycée Louise Michel BTS IG 1
10