Vous êtes sur la page 1sur 52

Cours de Programmation 2

(Programmation C et structures de données)


Présentation - Structures - Fonctions - Pile d’appel

Christophe Tollu
(Première version des diapos par Julien David)

A209 (poste 3691) - ct@lipn.univ-paris13.fr

23 janvier 2023

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 1 / 50
Organisation

Cours
1h30 de CM par semaine (12 semaines).
Les amphis de N2 math-DL et de N2 info seront peut-être fusionnés
après six semaines.

TD et TP
1h30 TD + 1h30 TP par semaine.
Des contrôles (QCM, TP) seront organisés pendant les plages de TD-TP.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 2 / 50
Contrôle des connaissances

Deux notes
EvC : contrôle continu (TP notés + QCM + participation) ;
Pa1 : partiel de mi-semestre : semaine du 20 mars 2023 ;
Pa2 : partiel de fin de semestre : semaine du 22 mai 2023.

Note finale
Max {(EvC + Pa1 + 2Pa2)/4 ; Pa}

Avertissement
Absence à un partiel, à une épreuve de contrôle continu ou TP noté
remis hors délai = note 0.
Absence à toutes les épreuves = défaillance.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 3 / 50
Contrôle des connaissances (2nde chance)

Une seule note


Pa : partiel de seconde chance : semaine du 26 juin 2023.

Note finale
Pa

Pour éviter d’en arriver là


Apprendre le cours au fur et à mesure, participer activement en TD et TP,
finir les exercices des feuilles de TD et TP.
Rappel : on apprend à programmer en programmant, pas simplement en
feuilletant son cours.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 4 / 50
Programmation 2 sur Moodle USPN
URL
Espace dédié au cours, ”Programmation 2 (N2 MATH-INFO)” à l’adresse :
https://moodlelms.univ-paris13.fr/course/view.php?id=547

Ressources
Y seront disponibles
les énoncés des TD et TP ;
les diapos du cours ;
des informations importantes ;
des recommandations (par exemple pour les partiels) ;
des zones de dépôt pour les TP notés ;
peut-être quelques corrigés (TP et partiels).

Vous devez consulter le cours sur Moodle plusieurs fois par semaine
Vous devez utiliser le forum ”Forum Prog. 2” pour poser vos questions sur
le contenu du cours et son organisation
Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 5 / 50
Programmation 2 : la suite de Programmation 1

Objectifs du cours
Se familiariser avec quelques notions et outils de programmation C
”avancés” et avec quelques structures de données que lesdits outils
permettent de définir et de manipuler ;
acquérir quelques bonnes pratiques de programmation ;
être capable d’implémenter et d’analyser des algorithmes ”classiques” de
recherche et de tri.

Quelques notions et structures de données nouvelles


Pointeurs ;
allocation dynamique de mémoire (et gestion des fuites mémoire) ;
listes (simplement et doublement) chaı̂nées ;
compilation séparée et configuration de la commande make ;
entrées-sorties généralisées (fichiers de type texte / fichiers binaires) ;
pointeurs de fonctions (peut-être omis cette année, faute de temps).

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 6 / 50
Bibliographie sommaire

La référence
Brian W. Kernighan and Dennis M. Ritchie, The C programming language
Prentice Hall, 1978 (2nd ed. 1988)
Traduction française : Le langage C. Norme ANSI. 2e édition, Dunod,
2000

Autres ouvrages recommandés


Claude Delannoy, Le livre du C premier langage, Eyrolles, 2002
Claude Delannoy, Programmer en langage C (5e édition), Eyrolles, 2016

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 7 / 50
Plan du cours d’aujourd’hui

Rappels et compléments
Retour sur quelques notions présentées dans l’UE de Programmation 1
1 Variables
nom, type, valeur, adresse, déclaration, initialisation ;
types scalaires, tableaux, structures.
2 Structures
définition des types structurées ;
accès des champs.
3 Fonctions
déclaration, définition, appel, exécution ;
récursivité (terminale et non terminale) ;
paramètres de la fonction principale.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 8 / 50
L`e˙s V`a˚r˚i`a˜b˝l´e˙s

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 9 / 50
Variable : définition

Définition
Une variable est une zone de mémoire caractérisée par :


un nom (ou identificateur)

un type (qui détermine la taille de l’espace mémoire occupé par la variable)


une valeur (codée en mémoire selon le type de la variable)
une adresse

Example
int x=4;
Nom : x
Type : entier positif ou négatif (int)
Valeur : 4
Une adresse : 990 (déterminée à l’exécution du programme pour une
variable locale)

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 10 / 50
Variable : définition

Définition
Une variable est une zone de mémoire caractérisée par :


un nom (ou identificateur)

un type (qui détermine la taille de l’espace mémoire occupé par la variable)


une valeur (codée en mémoire selon le type de la variable)
une adresse

Example
int x=4;
Nom : x
Type : entier positif ou négatif (int)
Valeur : 4
Une adresse : 990 (déterminée à l’exécution du programme pour une
variable locale)

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 10 / 50
Variable : déclaration et initialisation

Déclaration
La déclaration permet au programme de connaı̂tre le nom et le type d’une
variable :

int x;

Initialisation
L’initialisation permet d’affecter une valeur à une variable :
x=-17;

Adressage
L’opérateur unaire & permet de référencer une variable par son adresse :
scanf("%d", &x);

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 11 / 50
Locale/ Globale

Variable locale (à une fonction, à un bloc)


Déclaration : dans une fonction (et au début d’un bloc { · · · } !)
Portée et accessibilité : la partie du bloc suivant sa déclaration.
Par convention, le nom d’une variable locale commence par une
minuscule.
1 i n t main ( ) {
2 / ∗ D e c l a r a t i o n de deux v a r i a b l e s l o c a l e s ∗ /
3 i n t x = 4;
4 i n t y = 2∗x ;
5 p r i n t f ( ” x = %d , y = %d\n ” , x , y ) ;
6 r e t u r n EXIT SUCCESS ;
7 }

En mémoire
Une variable locale est stockée dans la pile d’appel

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 12 / 50
Locale/ Globale

Variable globale
Déclaration : en dehors de toute fonction
Portée (compilateur) : la partie du fichier source suivant la (première)
déclaration.
Accessibilité : par défaut étendue aux autres fichiers sources.
Par convention, le nom d’une variable globale commence par une
majuscule.
1 i n t X = 4; /∗ Variable globale ∗/
2 i n t main ( ) {
3 i n t y = 2∗X , x = 2∗y ;
4 p r i n t f ( ” X = %d , x = %d , y = %d\n ” , X , x , y ) ;
5 r e t u r n EXIT SUCCESS ;
6 }

En mémoire
Une variable globale est stockée dans la zone de données.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 13 / 50
Variable scalaire

Variable scalaire
Variable destinée à contenir une valeur atomique, une unique “donnée”.

Exemple
un nombre
entier : int, unsigned int, long int, long long int
“réel” (en vérité toujours un rationnel) : float, double
un caractère (affichable ou non) : char

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 14 / 50
Variable scalaire locale
1 i n t main ( ) {
2 i n t x =4;
3 f l o a t y =2.5;
4 p r i n t f ( ”%d\n ” , x ) ;
5 r e t u r n EXIT SUCCESS ;
6 }

Exécution du programme

y 2.5 996
Le programme affiche : ”4”.
x 4 1000
main

Conventions
Dans la zone grisée sont stockées des informations indispensables pour
l’exécution de l’appel (adresse de retour, etc.)
Le choix de 1000 comme adresse de x est arbitraire (et un peu ridicule !)
Les adresses décroissent vers le sommet de la pile.
Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 15 / 50
Tableaux

Tableau
Séquence de variables d’un même type. Un tableau permet de
déclarer plusieurs variables en une seule instruction,
parcourir plus facilement un ensemble de valeurs (ex : boucle)
...

Exemple
int tab[4]={1,2,3,4};
Nom : tab
Type : Tableau d’entiers : chaque case est de type int.
Valeur de chaque case : int tab[4];
tab[0]= 1; tab[1]= 2; tab[2]= 3; tab[3]= 4;
Adresse : l’adresse de tab est la même que celle de tab[0].

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 16 / 50
Tableaux

1 i n t main ( ) {
2 i n t tab [4]={3 ,5 ,1 ,2};
3 p r i n t f ( ” V a l e u r de l a 4eme case du t a b l e a u : %d\n ” , t a b [ 3 ] ) ;
4 r e t u r n EXIT SUCCESS ;
5 }

Exécution du programme

tab[0] 3 988
tab[1] 5 992
Le programme affiche :
tab[2] 1 996 ”Valeur de la 4eme case du tableau : 2”
tab[3] 2 1000
main

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 17 / 50
Tableaux à plusieurs dimensions

Tableaux à deux dimensions


Il est possible de créer des tableaux à deux dimensions (ou plus).
Chaque case d’un tableau à deux dimensions est un tableau à une
dimension.

Exemple
int tab[3][2]={ {3,5} , {1,2} , {4,1} };
0 1

0 3 5
1 1 2
2 4 1

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 18 / 50
Tableaux à plusieurs dimensions

1 i n t main ( ) {
2 i n t t a b [ 2 ] [ 2 ] = { {3 ,5} , {1 ,2} } ;
3 p r i n t f ( ” V a l e u r de l a case l i g n e 0 e t colonne 1 : %d\n ” , t a b [ 0 ] [ 1 ] ) ;
4 r e t u r n EXIT SUCCESS ;
5 }

Exécution du programme

tab[0][0] 3 988
tab[0][1] 5 992
Le programme affiche :
tab[1][0] 1 996”Valeur de la case ligne 0 et colonne 1 : 5”

tab[1][1] 2 1000
main

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 19 / 50
Tableaux particuliers

Les chaı̂nes de caractères


Les chaı̂nes de caractères sont des tableaux à une dimension dont chaque
case est de type char.
permet de stocker des mots, des phrases, etc.
la fin d’une chaı̂ne est obligatoirement signalée par un 0 \00 .
si on souhaite stocker un mot de longueur n il faut donc n + 1 cases dans
le tableau.
Exemple
Pour stocker le mot ”cours”, on définit le tableau suivant :
’c’ ’o’ ’u’ ’r’ ’s’ ’\0’

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 20 / 50
Chaı̂nes de caractères
Exécution du programme

s2[0] ’n’ 992

s2[1] ’o’ 993


1 # i n c l u d e <s t d i o . h>
2 # i n c l u d e<s t d l i b . h> s2[2] ’n’ 994
3
4
5 i n t main ( ) { s2[3] ’\0’ 995
6 char s1 [ 4 ] = ” o u i ” ;
7 char s2 [ 5 ] = { ’ n ’ , ’ o ’ , ’ n ’ , ’ \0 ’ } ; s2[4] ? 996
8 p r i n t f ( ”%s e t %s\n ” , s1 , s2 ) ;
9 r e t u r n EXIT SUCCESS ;
10 } s1[0] ’o’ 997

L’exécution du programme affiche : s1[1] ’u’ 998

”oui et non”
s1[2] ’i’ 999

s1[3] ’\0’ 1000

main

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 21 / 50
Question : qu’affiche le programme ci-dessous ?

Exécution du programme

s2[0] ’n’ 994


1 # i n c l u d e <s t d i o . h>
2 # i n c l u d e<s t d l i b . h> s2[1] ’o’ 995
3
4
5 i n t main ( ) { s2[2] ’n’ 996
6 char s1 [ 4 ] = ” o u i ” ;
7 char s2 [ 3 ] = { ’ n ’ , ’ o ’ , ’ n ’ } ; s1[0] ’o’ 997
8 p r i n t f ( ”%s e t %s\n ” , s1 , s2 ) ;
9 r e t u r n EXIT SUCCESS ;
10 } s1[1] ’u’ 998

L’exécution du programme affiche : s1[2] ’i’ 999

”oui et nonoui”
s1[3] ’\0’ 1000

main

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 22 / 50
Question : qu’affiche le programme ci-dessous ?

Exécution du programme

s2[0] ’n’ 994


1 # i n c l u d e <s t d i o . h>
2 # i n c l u d e<s t d l i b . h> s2[1] ’o’ 995
3
4
5 i n t main ( ) { s2[2] ’n’ 996
6 char s1 [ 4 ] = ” o u i ” ;
7 char s2 [ 3 ] = { ’ n ’ , ’ o ’ , ’ n ’ } ; s1[0] ’o’ 997
8 p r i n t f ( ”%s e t %s\n ” , s1 , s2 ) ;
9 r e t u r n EXIT SUCCESS ;
10 } s1[1] ’u’ 998

L’exécution du programme affiche : s1[2] ’i’ 999

”oui et nonoui”
s1[3] ’\0’ 1000

main

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 22 / 50
L`e˙s S˚tˇr˚u`cˇtˇu˚r`e˙s

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 23 / 50
Structures

Structure
Séquence de variables, appelées champs, pouvant être de types différents.

Définition
La définition d’un type structuré doit permettre au compilateur de
comprendre ce nouvel objet.
En particulier, il doit pouvoir déterminer la taille de l’espace occupé en
mémoire par chaque champ.

1 / ∗ Dans un f i c h i e r p o i n t . h ∗ /
2 typedef struct point s{
3 float x;
4 float y;
5 } point t;

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 24 / 50
Structures

Structure
Séquence de variables, appelées champs, pouvant être de types différents.

Déclaration d’une variable structurée


Une variable structurée se déclare (comme une variable scalaire ou un
tableau)
au début d’un bloc si c’est une variable locale ;
en dehors de toute fonction si c’est une variable globale.

1 #include ” point . h”
2
3 p o i n t t P; /∗ variable globale ∗/
4
5 i n t main ( ) {
6 p o i n t t p ; /∗ variable locale ∗/
7 r e t u r n EXIT SUCCESS ;
8 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 25 / 50
Structures

Structure
Séquence de variables, appelées champs, pouvant être de types différents.

Déclaration d’une variable structurée


Une variable structurée se déclare (comme une variable scalaire ou un
tableau)
au début d’un bloc si c’est une variable locale ;
en dehors de toute fonction si c’est une variable globale.

1 #include ” point . h”
2
3 p o i n t t P; /∗ variable globale ∗/
4
5 i n t main ( ) {
6 p o i n t t p ; /∗ variable locale ∗/
7 r e t u r n EXIT SUCCESS ;
8 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 26 / 50
Structures

Structure
Séquence de variables, appelées champs, pouvant être de types différents.

Accès des champs


Soit p une variable de type point t.
Les deux champs de p sont des variables identifiées par p.x et p.y,
respectivement.
Ce méthode d’identification vaut pour tout niveau d’imbrication de
structures.

1 #include ” point . h”
2
3 p o i n t t P; /∗ variable globale ∗/
4
5 i n t main ( ) {
6 p o i n t t p ; /∗ variable locale ∗/
7 r e t u r n EXIT SUCCESS ;
8 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 27 / 50
Structures

Structure
Séquence de variables, appelées champs, pouvant être de types différents.

Initialisation
Une variable de type structuré peut être initialisée de plusieurs façons :
globalement ou partiellement à la déclaration ;
champ par champ ou par recopie des valeurs des champs d’une
structure de même type.

1 #include ” point . h”
2 i n t main ( ) {
3 p o i n t t p1 = { −1.5 , 5 . 0 } ; / ∗ en r e s p e c t a n t l ’ o r d r e des champs , sans l e s nommer ∗ /
4 p o i n t t p2 = { . x = −2.25 } ; / ∗ ( p a r t i e l l e m e n t ) en nommant c e r t a i n s champs ∗ /
5 p o i n t t p3 ;
6 p2 . y = 6 . 7 5 ; / ∗ i n i t i a l i s a t i o n du 2e champ de p2 ∗ /
7 p3 = p1 ; / ∗ chaque champ de p3 prend l a v a l e u r du champ c o r r e s p o n d a n t de p1 ∗ /
8 r e t u r n EXIT SUCCESS ;
9 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 28 / 50
Structures

1 / ∗ Dans un f i c h i e r p o i n t . h ∗ /
2 typedef struct point s{
3 float x;
4 float y;
5 } point t;

On veut définir la notion de cercle.


Un cercle est défini par
son centre ;
son rayon.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 29 / 50
Structures

1 / ∗ Dans un f i c h i e r p o i n t . h ∗ /
2 typedef struct point s{
3 float x;
4 float y;
5 } point t;

1 / ∗ Dans un f i c h i e r c e r c l e . h ∗ /
2 #include ” point . h”
3 typedef s t r u c t cercle s{
4 p o i n t t centre ;
5 double rayon ;
6 } cercle t ;

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 30 / 50
Structures

1 / ∗ Dans un f i c h i e r p o i n t . h ∗ /
2 typedef struct point s{
3 float x;
4 float y;
5 } point t;

1 / ∗ Dans un f i c h i e r c e r c l e . h ∗ /
2 #include ” point . h”
3 typedef s t r u c t cercle s{
4 p o i n t t centre ;
5 double rayon ;
6 } cercle t ;

1 / ∗ Dans un f i c h i e r main . c ∗ /
2 #include ” cercle . h”
3 i n t main ( ) {
4 p o i n t t p = {1.5 , 4.0};
5 c e r c l e t c = {{0.25 , −2.5} , 5 . 3 3 } ;
6 r e t u r n EXIT SUCCESS ;
7 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 31 / 50
Structures

1 / ∗ Dans un f i c h i e r p o i n t . h ∗ /
2 typedef struct point s{
3 float x;
4 float y;
Exécution du programme
5 } point t;

c.centre.x 0.25 980


1 / ∗ Dans un f i c h i e r c e r c l e . h ∗ /
2 #include ” point . h”
3 typedef s t r u c t cercle s{ c.centre.y -2.5 984
4 p o i n t t centre ;
5 double rayon ; c.rayon 5.33 988
6 } cercle t ;
p.x 1.5 996
1 / ∗ Dans un f i c h i e r main . c ∗ /
2 #include ” cercle . h” p.y 4.0 1000
3 i n t main ( ) {
4 p o i n t t p = {1.5 , 4.0};
5 c e r c l e t c = {{0.25 , −2.5} , 5 . 3 3 } ; main
6 r e t u r n EXIT SUCCESS ;
7 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 32 / 50
L`e˙s F`o“n`cˇtˇi`o“n¯s

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 33 / 50
Fonctions

Fonction
Une fonction est un sous-programme, un ensemble d’instructions.
On distingue trois notions importantes associées aux fonctions :
la déclaration ;
la définition ;
l’appel.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 34 / 50
Fonctions
Fonction : déclaration
La déclaration donne les informations indispensables pour que le
compilateur reconnaisse une fonction et vérifie qu’elle est appelée
conformément à son prototype, à savoir :
les types des arguments passés à la fonction : à chaque appel, chacun
des paramètres formels d’entrées reçoit une valeur d’un type fixé ;
le nom de la fonction ;
le type du résultat qu’elle renvoie (ou void si elle ne renvoie pas de
résultat).
La déclaration de la fonction doit précéder tout appel à cette fonction dans le
code du programme.

Exemple de déclaration
On veut créer une fonction qui additionne deux entiers positifs.
1 unsigned i n t a d d i t i o n ( unsigned i n t , unsigned i n t ) ;

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 35 / 50
Fonctions
Fonction : définition
La définition reprend le prototype de la déclaration (avec le nom des
paramètres d’entrées) et ajoute le bloc, appelé corps de la fonction, constitué
des instructions qui seront exécutées lors de chaque appel à la fonction.
L’exécution d’un appel à une fonction qui renvoie une valeur doit se
terminer par l’exécution d’une instruction return (avec comme argument
une expression dont la valeur appartient au type du résultat de la
fonction.)
Le corps d’une fonction qui ne renvoie pas de valeur peut contenir des
instructions return sans argument.
L’exécution d’une instruction return met fin à l’exécution de l’appel.

Exemple de définition
1 unsigned i n t a d d i t i o n ( unsigned i n t x , unsigned i n t y ){
2 unsigned i n t r e s u l t =x+y ;
3 return result ;
4 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 36 / 50
Fonctions

Fonction : appel
Utilisation de la fonction.
1 i n t main ( ) {
2 unsigned i n t n = 1 ;
3 unsigned i n t r e s = a d d i t i o n ( n , 2+n ) ;
4 p r i n t f ( ”%d+2+%d = %d\n ” , n , n , r e s ) ;
5 r e t u r n EXIT SUCCESS ;
6 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 37 / 50
Fonctions

1 unsigned i n t a d d i t i o n ( unsigned i n t x , unsigned i n t y ){


2 unsigned i n t r e s u l t =x+y ;
3 return result ;
4 }
res ? 996

1 i n t main ( ) {
n 1 1000
2 unsigned i n t n = 1 ;
3 unsigned i n t r e s = a d d i t i o n ( n , 2+n ) ;
4 p r i n t f ( ”%d+2+%d = %d\n ” , n , n , r e s ) ; main
5 r e t u r n EXIT SUCCESS ;
6 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 38 / 50
Fonctions

result 4 968
1 unsigned i n t a d d i t i o n ( unsigned i n t x , unsigned i n t y ){
2 unsigned i n t r e s u l t =x+y ;
3 return result ; y 3 972
4 }
x 1 976

1 i n t main ( ) {
addition(1,2+n)
2 unsigned i n t n = 1 ;
3 unsigned i n t r e s = a d d i t i o n ( n , 2+n ) ;
4 p r i n t f ( ”%d+2+%d = %d\n ” , n , n , r e s ) ; res ? 996
5 r e t u r n EXIT SUCCESS ;
6 }
n 1 1000

main

La fonction renvoie 4 et on dépile.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 39 / 50
Fonctions

1 unsigned i n t a d d i t i o n ( unsigned i n t x , unsigned i n t y ){


2 unsigned i n t r e s u l t =x+y ;
3 return result ;
4 }
res 4 996

1 i n t main ( ) {
n 1 1000
2 unsigned i n t n = 1 ;
3 unsigned i n t r e s = a d d i t i o n ( n , 2+n ) ;
4 p r i n t f ( ”%d+2+%d = %d\n ” , n , n , r e s ) ; main
5 r e t u r n EXIT SUCCESS ;
6 }

Le programme affiche ”1+2+1=4”

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 40 / 50
Fonctions

Fonction : imbrication d’appels


Il est possible d’imbriquer les appels de fonction, d’utiliser le résultat d’un
appel comme argument d’un autre appel (à la même fonction ou à une autre).
Exemple : on souhaite calculer 4 + 3 + 2.
1 i n t res= a d d i t i o n (4 , a d d i t i o n ( 3 , 2 ) ) ;

Fonction : erreur classique


Lors d’un appel de fonction, on ne réécrit pas les types des variables.
1 unsigned i n t r e s = a d d i t i o n ( unsigned i n t n , unsigned i n t m) ;

Cette instruction ne veut rien dire.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 41 / 50
Paramètres formels et variables locales d’une fonction

Paramètres formels d’une fonction


Ils sont déclarés dans l’entête de la fonction.
Leur portée est le bloc contenant le corps de la fonction.
Par convention, leur nom est toujours en minuscule(s).
1 i n t f ( i n t n , i n t m)
2 {
3 i n t r e s = 3∗n ;
4 i n t m = 2 ; / ∗ ∗ DECLARATION ILLEGALE ∗ /
5 / ∗ ∗ => ERREUR A LA COMPILATION ∗ /
6 r e t u r n r e s + m;
7 }

En mémoire
Un paramètre de fonction est stocké dans la pile d’appel.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 42 / 50
Paramètres formels et variables locales d’une fonction

Paramètres formels d’une fonction


Leur portée est le bloc contenant le corps de la fonction.
1 i n t f ( i n t n , i n t m)
2 {
3 i n t r e s = 3∗n ;
4 {
5 i n t m ; / ∗ ∗ DECLARATION LEGALE MAIS ??? ∗ /
6 s c a n f ( ”%d ” , &m) ;
7 r e t u r n r e s + m;
8 }
9 }

Il faut être pervers pour écrire une définition de fonction comme celle-ci...
ou n’avoir rien compris à la notion de fonction !

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 43 / 50
Les fonctions : pour faire quoi ?

Les fonctions : pour faire quoi ?


Éviter la duplication de code.
En créant des bibliothèques de fonctions, on peut les réutiliser dans
différents programmes.
Un programme proprement découpé en fonctions est plus lisible.
Prévoir la liste des fonctions nécessaires permet de mieux structurer un
programme et facilite la conception.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 44 / 50
Fonctions récursives

Définitions
Une fonction récursive est une fonction qui, dans sa définition, contient
un appel à elle-même.
Un appel récursif est un appel réalisé alors que l’exécution d’un appel
précédent de la même fonction n’est pas achevé.

Exemple de fonction récursive (non terminale)


1 i n t so m m e p r e mi er s e nt ie r s ( unsigned i n t n )
2 {
3 unsigned i n t r e s ;
4 i f ( 0 == n )
5 return 0;
6 else
7 r e t u r n n + s om me p r e mi er s e n t i e r s ( n−1);
8 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 45 / 50
Deux exemples très classiques

Calcul de la factorielle d’un entier positif


1 unsigned i n t f a c t o r i e l l e ( unsigned i n t n )
2 {
3 i f ( 0 == n ) r e t u r n 1 ;
4 r e t u r n n∗ f a c t o r i e l l e ( n−1);
5 }

Calcul du ne terme de la suite de Fibonacci


1 unsigned i n t f ( unsigned i n t n )
2 {
3 i f ( 0 == n | | 1 == n )
4 return n;
5 r e t u r n f ( n−1) + f ( n−2);
6 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 46 / 50
Récursivité : terminaison
Empilement potentiellement infini des appels récursifs
1 int f ( int n)
2 { r e t u r n f ( n−1);}

Conditions d’arrêt et terminaison


Il faut soigneusement identifier les conditions d’arrêt...
...et s’assurer que pour tout appel, ces conditions d’arrêt seront
satisfaites après un nombre fini d’appels récursifs.

Un exemple plus compliqué à analyser


1 unsigned i n t ack ( i n t m, i n t n )
2 {
3 i f ( 0 == m)
4 return n + 1;
5 i f ( 0 == n )
6 r e t u r n ack (m−1, 1 ) ;
7 r e t u r n ack (m−1, ack (m, n − 1 ) ) ;
8 }

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 47 / 50
Récursivité et tableaux

Recherche dans un tableau de flottants trié


1 / ∗ ∗ Renvoie l ’ i n d i c e d ’ une v a l e u r du t a b l e a u egale a x ∗ /
2 / ∗ s i une t e l l e v a l e u r e x i s t e , r e n v o i e −1 s i n o n ∗ /
3 i n t r e c h e r c h e t a b ( f l o a t x , f l o a t ∗ tab , i n t deb , i n t f i n )
4 {
5 i n t m i l i e u = ( deb + f i n ) / 2 ;
6 i f ( f i n < deb )
7 r e t u r n −1;
8 i f ( x < tab [ m i l i e u ] )
9 r e t u r n r e c h e r c h e t a b ( x , tab , deb , m i l i e u − 1 ) ;
10 i f ( x > tab [ m i l i e u ] )
11 r e t u r n r e c h e r c h e t a b ( x , tab , m i l i e u + 1 , f i n ) ;
12 return milieu ;
13 }

L’appel initial pourrait être...


1 / ∗ En supposant que t e s t un t a b l e a u de f l o t t a n t s ∗ /
2 / ∗ de t a i l l e au moins n e t dont l e s v a l e u r s s o n t rangees dans l ’ o r d r e c r o i s s a n t ∗ /
3 i n t r e s u l t = r e c h e r c h e t a b ( −0.75 , t , 0 , n−1);

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 48 / 50
Récursivité et efficacité

Appels récursifs redondants


1 unsigned i n t f ( unsigned i n t n )
2 {
3 i f ( 0 == n | | 1 == n )
4 return n;
5 r e t u r n f ( n−1) + f ( n−2);
6 }

Pour exécuter l’appel f(20), on exécutera plus de trois mille trois cents appels
f(2) !

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 49 / 50
Récursivité et efficacité

Récursif vs itératif
Il existe des techniques pour remédier à cette redondance des appels,
comme la mémoı̈sation (stockage des valeurs renvoyées par les appels
selon la valeur des arguments).
Il ne faut donc pas croire que l’exécution d’une fonction récursive est
toujours nettement plus coûteuse que celle d’une fonction itérative
effectuant la même tâche !
En outre, l’écriture d’une fonction récursive est, dans de nombreuses
applications, beaucoup plus  naturelle  . . .

Où peut-on en savoir plus ?


En TD aujourd’hui, en CM demain... et les semaines suivantes.

Christophe Tollu (Première version des diapos par Julien David) (A209 (poste 3691) - ct@lipn.univ-paris13.fr) 23 janvier 2023 50 / 50

Vous aimerez peut-être aussi