6. Les sous-programmes6. Les sous-programmes
P. Costamagna – ISEN N1
P. Costamagna 2
A. IntroductionA. Introduction
Traitements identiques à plusieurs endroits d’un programme. Méthode immédiate mais peu habile = répéter le code correspondant
autant de fois que nécessaire.
programme lourd, illisible, difficile à maintenir.
Une autre stratégie consiste à - séparer ce traitement du corps du programme - et à appeler ces instructions (qui ne figurent donc plus qu’en un
seul exemplaire) à chaque fois qu’on en a besoin. Le programme est alors décomposé en plusieurs sous-tâches.
Le corps du programme = le programme principal (main), Les groupes d’instructions auxquels on a recours = des sous-
programmes.
P. Costamagna 3
B. Qu’est ce qu’un sous-programme ?B. Qu’est ce qu’un sous-programme ?
Sous-programme = association d’un nom et d’un ensemble d’instructions.
Soit une tortue qui sait seulement se déplacer tout droit et tourner à droite ou à gauche.
On lui apprend à dessiner un carré en la faisant aller tout droit, puis tourner à droite, puis continuer tout droit, etc, quatre fois.
Ces actions ou instructions peuvent être regroupées au sein d'une procédure que l'on appellerait "dessiner_un_carré".
Ainsi, quand on dirait à la tortue "dessiner_un_carré", elle effectuerait les instructions de la procédure les unes à la suite des autres et dessinerait un carré.
Exemple
Programmation modulaire Scission en plusieurs parties (programmation structurée) Moins de répétitions dans les séquences d’instructions Partage d’outils
P. Costamagna 4
C. Fonction standardC. Fonction standard
Prototype : void sautDeLigne ( void ); Utilisation: sautDeLigne ( ); sautDeLigne = nom de la fonction 2 parenthèses obligatoires
Exemple 1
Il existe dans la plupart des langages, des fonctions définies en standard qui fonctionnent de la même façon que le feront nos sous-programmes.
Prototype : void fixePrecision ( int n ); Utilisation: fixePrecision ( 3 ); 3 = argument / paramètre de la fonction 2 parenthèses obligatoires
Exemple 2
Prototype : int lisEntier ( void ); Utilisation: A = lisEntier ( ); int = type de la fonction A = variable dans laquelle est
récupérée le résultat de la fonction
Exemple 3
P. Costamagna 5
D. Fonctions et procéduresD. Fonctions et procédures
Dans la plupart des langages évolués, il existe:
Des fonctions : notion proche des maths. Arguments = informations transmises pour le bon fonctionnement – Retour d’un résultat.
Des procédures: Arguments – Pas de retour à proprement parler d’un résultat mais possibilité d’utiliser certains arguments pour renvoyer des résultats.
En C on ne programme que des fonctions. Mais les fonctions en C sont aussi puissantes que les fonctions et les procédures d’autres langages.
P. Costamagna 6
E. Définir un sous-programmeE. Définir un sous-programme
Avant d'être utilisé, un sous-programme doit être défini. Déterminer le type de valeur que le sous-programme renverra (int/float/char/void)
Indiquer le nom du sous-programme
Préciser si besoin les arguments (= informations nécessaires au bon fonctionnement). Nombre variable d’un sous-programme
à un autre (0, 1, 2 …) Chaque argument est caractérisé par un nom et un type.
Enumérer le bloc d’instructions correspondant aux actions à réaliser par le sous-programme. Bloc délimité par des accolades
et pouvant contenir des déclarations de variables et des instructions.
intfloatcharvoid
Type à déterminer en fonction du résultat renvoyé par le ss-prog
id_fonction
Identificateur choisi pour représenter le ss-prog
( )
Les parenthèses sont obligatoires même s’il n’y a pas de paramètre
Pas de ; à la fin de cette instruction
type1 p1, type2 p2, …
Enumération des paramètres (facultatif)
Entête du sous-programme:
P. Costamagna 7
E. Définir un sous-programme E. Définir un sous-programme (suite1)(suite1)
Ne signifie pas que le sous-programme n’a pas d’arguments Le programmeur ne souhaite pas que ses appels soient contrôlés par le
compilateur. On préfèrera donc la forme suivante:
Type_donnee id_fonction ( )
{
}
Délimitation du bloc ss-prog
Déclaration de variables locales
Instructions
return résultat; Retour du résultat
Type_donnee id_fonction ( void )
Absence d’arguments:
intfloatcharvoid
id_fonction ( )type1 p1, type2 p2, …
P. Costamagna 8
F. Définition de plusieurs sous programmesF. Définition de plusieurs sous programmes
Un programme peut contenir plusieurs sous-programmes.
Un sous-programme ne peut pas être défini dans le corps d’un autre.
Tous les sous-programmes sont au même niveau. Ils sont définis les uns à la suite des autres.
Un sous programme peut appeler un autre sous programme à condition qu’il soit défini avant lui.
Le programme principal sera placé en dernière position.
P. Costamagna 9
G. Les arguments d’un sous-programmeG. Les arguments d’un sous-programme
Peut être nécessaire de récupérer ou de transmettre des informations vers l’extérieur = paramètres ou arguments.
Un argument est caractérisé par
- un nom
- un type
- un mode de transmission
Chaque argument est ainsi décrit dans les parenthèses au moment de la définition.
intfloatcharvoid
id_fonction ( )type1 p1, type2 p2, …
P. Costamagna 10
H. H. Les modes de transmission des argumentsLes modes de transmission des arguments
Par valeur (entrée)
Les valeurs des arguments sont recopiées dans des emplacements locaux au sous-programme (copies). Toute modification de la copie n’a aucune incidence sur la valeur originale.
Exemple: int fct1 ( float p, float q, int r )
Les identificateurs choisis pour les arguments lors de la définition du sous-programme sont génériques. Ils pourront être remplacés lors de l’appel du sous-programme par n’importe quelle variable comme pour une fonction mathématique.
Exemple: f(x) = ax2 + bx + c f(t) = at2 + bt + c
Par adresse (sortie)
Le sous-programme travaille sur les valeurs originales des arguments. Les identificateurs des arguments doivent être précédés du signe *.
Exemple: int fct2 ( float *p, float *q, int *r )
P. Costamagna 11
I. I. Renvoi d’une valeur par un sous-programmeRenvoi d’une valeur par un sous-programme
return = dernière instruction d’un sous-programme.
Syntaxe
return; (pour une fonction de type void)
return valeur variable ;
expression
Le sous programme évalue la valeur/variable/expression et la renvoie au programme appelant.
Le type de la valeur retournée doit correspondre au type de la fonction précisé au moment de la définition.
P. Costamagna 12
I. I. Renvoi d’une valeur par un sous-programme Renvoi d’une valeur par un sous-programme (suite1)(suite1)
return peut apparaître à plusieurs reprises dans un sous-programme. c’est la 1ère instruction rencontrée qui provoque la sortie du sous-programme.
Exemple
float absom (float u, float v){ float s; s = u + v; if ( s > 0) return (s); else return (-s);}
P. Costamagna 13
J. Appel d’un sous-programmeJ. Appel d’un sous-programme
Après définition, un sous-programme devient utilisable en tout endroit du programme. Un sous-programme ne s’exécutera que si on fait appel à lui.
S’il existe des arguments, ils doivent être énumérés en respectant:- leur nombre- leur type- leur mode de transmission
Les paramètres transmis seront affectés respectivement aux paramètres définis.
S’il n’existe pas d’arguments, les parenthèses doivent rester présentes, sinon aucun appel au sous-programme ne sera effectué.
Si le sous-programme renvoie un résultat, le récupérer au moment de l’appel dans une variable de même nature.
P. Costamagna 14
J. Appel d’un sous-programme J. Appel d’un sous-programme (suite1)(suite1)
Exemplefloat absom (float u, float v){ float s; s = u + v; if ( s > 0) return (s); else return (-s);}
int main (void){ float res, a, b; ecrisChaine (« Saisir 2 valeurs »); a = lisFlottant ( ); b = lisFlottant ( ); res = absom (a, b); ecrisChaine (« Somme des 2 »); ecrisFlottant (res);
system(« pause »); return 0;}
Définition du sous-programme
Programme principal
Type de la valeur renvoyée par le sous-programme
Variable locale au sous-programme utilisée pour stocker la valeur retournée
Retour de la valeur
Appel du sous-programme
la valeur de a remplace le paramètre u
la valeur de b remplace le paramètre v
La variable res récupère le résultat renvoyé par le sous-programme
P. Costamagna 15
K. La fonction mainK. La fonction main
Un programme C comporte obligatoirement une fonction main (=programme principal).
Fonction comme les autres. Seule particularité: son nom
void main (void) le programme s’exécute sans tenir compte de l’OS et sans lui retourner de
résultat.
int main (void) le programme s’exécute sans tenir compte de l’OS et lui retourne un code de
fin d’exécution (valeur nulle = bon déroulement)
P. Costamagna 16
L. ExercicesL. Exercices
Ecrire une fonction qui calcule et renvoie vers le programme principal le cube d’un nombre entier.
Exercice1
Exercice 2
Ecrire une fonction qui réalise l’échange des valeurs de 2 valeurs entières transmises en arguments.
- 1ère méthode: passage des arguments par valeur
- 2ème méthode: passage des arguments par adresse.
P. Costamagna 17
L. CorrectionsL. Corrections
#include "ESLib.h"int cub (int nb){ int res; /* résultat du calcul */ res = nb * nb * nb; return res; } int main (void){ int x; /* nombre à élever au cube */ int c; /* résultat de l‘élévation au cube */ ecrisChaine ("Saisir un entier: "); x = lisEntier(); sautDeLigne();
Correction Exercice1 /* Appel de la fonction de calcul du cube */ c = cub (x); ecrisEntier (x); ecrisChaine (" au cube = "); ecrisEntier (c); sautDeLigne(); system ("pause"); return 0;}
P. Costamagna 18
L. Corrections L. Corrections (suite1)(suite1)
1ère méthode: transmission des arguments par valeur#include "ESLib.h"void ech1 (int a, int b){ int tmp; /* variable temporaire utilisée pour l'échange */
tmp = a; /* sauvegarde du contenu de la 1ère valeur */
a = b; /* la 1ère variable prend la 2ème valeur */
b = tmp; /* la 2ème variable prend la 1ère valeur précédemment sauvegardée */
return; }
int main (void){ int n, p; /* 2 valeurs à échanger */ ecrisChaine ("Saisir un entier: "); n = lisEntier(); sautDeLigne(); ecrisChaine ("Saisir un 2ème entier: "); p = lisEntier();
Correction Exercice2 /* Affichage avant échange */
sautDeLigne(); ecrisChaine ("n = "); ecrisEntier (n); ecrisChaine (" - p = "); ecrisEntier (p); /* Appel de la fonction d'échange */
ech1 (n, p); /* Affichage après échange */
sautDeLigne(); ecrisChaine ("n = "); ecrisEntier (n); ecrisChaine (" - p = "); ecrisEntier (p); sautDeLigne(); system ("pause"); return 0;}
P. Costamagna 19
L. Corrections L. Corrections (suite2)(suite2)
2ème méthode: transmission des arguments par adresse#include "ESLib.h"void ech1 (int *a, int *b){ int tmp; /* variable tempo utilisée pour l'échange */
tmp = *a; /* sauvegarde du contenu de la 1ère valeur */
*a = *b; /* la 1ère variable prend la 2ème valeur */
*b = tmp; /* la 2ème variable prend la 1ère valeur précédemment sauvegardée */
return; }
int main (void){ int n, p; /* 2 valeurs à échanger */ ecrisChaine ("Saisir un entier: "); n = lisEntier(); sautDeLigne(); ecrisChaine ("Saisir un 2ème entier: "); p = lisEntier();
Correction Exercice2 /* Affichage avant échange */
sautDeLigne(); ecrisChaine ("n = "); ecrisEntier (n); ecrisChaine (" - p = "); ecrisEntier (p); /* Appel de la fonction d'échange */
ech1 (&n, &p); /* Affichage après échange */
sautDeLigne(); ecrisChaine ("n = "); ecrisEntier (n); ecrisChaine (" - p = "); ecrisEntier (p); sautDeLigne(); system ("pause"); return 0;}
P. Costamagna 20
M. Quelques erreurs à éviterM. Quelques erreurs à éviter
…..int addition ( int a, int b ) ;{ return a+b;}
Pas de point virgule lors de la définition d’un sous-programme:
Ne pas déclarer comme variable un paramètre transmis par le sous-programme : …..int addition ( int a, int b ){ int a, b; return a+b;}
…..int addition ( int a, int b ){ int c c = a+b; }
Ne pas oublier de renvoyer un résultat si le type du sous-programme l’impose:
return c;
P. Costamagna 21
G. Quelques erreurs à éviter G. Quelques erreurs à éviter (suite1)(suite1)
i = 0;while( i < 10 ){ ecrisChaine ("hello world !");}
Le compteur de la boucle TANT QUE n’est pas incrémenté boucle infinie:
i = 0;while( i < 10 ){ ecrisChaine ("hello world !"); i = i + 1;}
Attention aux ; en trop. La boucle suivante ne fait rien pendant 10 fois puis affiche la phrase hello world ! une seule fois :
for ( i = 0; i < 10; i = i+1 );
ecrisChaine ("hello world !"); for ( i = 0; i < 10; i = i+1 )
ecrisChaine ("hello world !");