Vous êtes sur la page 1sur 9

ALGORITHMES ET STRUCTURES DE DONNEES ELEMENTAIRES

(E.T. : 20heures, E.D. : 20 heures, E.P. : 18 heures)

Année Universitaire 2011/2012

Dr RAKOTOASIMBAHOAKA CYPRIEN ROBERT

Enseignant-chercheur à l’Ecole Nationale d’Informatique

UNIVERSITE DE FIANARANTSOA

1. ELEMENTS ELEMENTAIRES DES ALGORITHMES.


1.1. Les chaînes de caractères
1.2. Fonctions et variables entières
1.3. Itérations et conditions
1.4. Transmission des paramètres
1.5. Raisonnement par récurrence
2. VECTEURS
2.1. Introduction
2.2. Algorithmes traitant un seul vecteur
2.3. Tris d’un vecteur
2.4 Algorithmes de mise à jour d’un vecteur
3. FICHIERS
3.1. Définition et propriétés
3.2. Actions primitives d’accès
3.3. Algorithmes traitant un seul fichier
3.4. Algorithmes traitant plusieurs fichiers

1. ELEMENTS ELEMENTAIRES DES ALGORITHMES


Un algorithme est une suite d’instructions que devra effectuer un automate (ordinateur) pour arriver en un
temps fini, à un résultat déterminé (post-condition), à partir d’une situation donnée (pré-condition).

1.1. Les chaînes de caractères


Afficher un message à l’écran, ou imprimer un message sur papier.
1.1.1. l’instruction « écrire »
Nous voulons faire afficher un message de bienvenue.
Algorithme 1 :
écrire("Bonjour à tous") ;

Un caractère peut être une lettre majuscule ou minuscule, un chiffre, un signe de ponctuation, ou un espace
pris entre apostrophe, par exemple : ‘A’, ‘b’.
Une chaîne de caractère, ou chaîne pour abréger, est une suite quelconque de caractères, entourée de
guillemets, par exemple : "une classe". Si parmi ces caractères nous voulons imprimer une valeur on écrit le %
suivi d’un caractère qui indique le type de cette valeur (algorithme 2).

1.1.2. les variables de type chaîne, l’instruction lire


Nous pouvons .souhaiter « personnaliser » notre message d’accueil en affichant le nom de l’utilisateur. Bien
entendu, l’ordinateur ne connaît ce nom à priori et devra donc commencer par le lui demander.
Algorithme 2 :
écrire("Comment vous appelez-vous ? ") ; lire(nom) ;
écrire("Bonjour %s ! \n",nom) ;
Chaque variable ou identificateur est une suite de caractères pris parmi les lettres, les chiffres et le caractère
« souligné », mais doit commencer par une lettre. Ainsi : a, A3_b2, toto sont des identificateurs valables, alors
que 35, 5A, A+B ne le sont pas.

1
Exemple d’exécution de l’algorithme2.

1.2. Fonctions et variables entières


Une fonction est une suite d’instructions nommée, que l’on pourra appeler par ce nom chaque fois que l’on
veut l’utiliser. Une fonction doit être déclarée afin de pouvoir ensuite l’appeler par son nom.
Syntaxe de la déclaration :
type_de_valeur_de _retour nom_fonction(arguments)
{ corps de le fonction
}
vide bonjour1(vide)
{ chaine nom ;
écrire("Comment vous appelez-vous ? ") ; lire(nom) ;
écrire("Bonjour %s ! \n",nom) ;
}

1.2.1. Déclarations de variables


Elles servent à indiquer à l’ordinateur les identificateurs utilisés dans la fonction, ainsi que leur type. Dans la
fonction bonjour1, nous n’avons qu’une seule variable appelée nom et de type chaîne.
Syntaxe de déclaration : type identificateur ;
Exemple : chaine ch ;
ch est une variable de type chaine.

1.2.2. Variables entières et expressions arithmétiques


Notre fonction va indiquer à l’utilisateur son âge. C’est l’ordinateur qui calculera cet âge à partir de deux
données : l’année actuelle et l’année de naissance de l’utilisateur.
vide bonjour2(vide)
{ chaine nom ;
entier annee, naissance ;
écrire("A quelle annee sommes-nous ? ") ; lire(annee) ;
écrire("Comment vous appelez-vous ? ") ; lire(nom) ;
écrire("Votre annee de naissance ? ") ; lire(naissance) ;
écrire("Bonjour %s ! \n",nom) ;
écrire("Vous etes age de %d ans \n", annee-naissance) ;

Les entiers peuvent être positifs ou négatifs, et on peut leur appliquer les opérations arithmétiques classiques  :
addition, soustraction, multiplication, division notés +, -, *, et /, ainsi que l’opérateur modulo, noté %, tel que n
% p donne le reste de la division entière de n par p ;
Exemples :
3+5 donnera 8
2 * (-6) donnera -12
12 / 3 donnera 4
12 % 3 donnera 0
14 % 3 donnera 2
On appellera une expression entière toute expression formée à partir de variables entières, de nombres
entiers, d’opérateurs, et éventuellement de parenthèses, selon les règles habituelles de l’algèbre.

Exemple :
Si les variables abc et xy ont respectivement pour valeurs 3 et -5, l’expression suivante :
(abc + 25) / (4 * (7 + xy)) aura pour valeur :
(3 + 25) / (4 * (7 + -5)), soit 28 / 8 c’est-à-dire 3.
Dans la fonction bonjour2, nous utilisons une expression entière dans la dernière instruction écrire. Il s’agit de
l’expression annee – naissance, dont la valeur est calculée par l’ordinateur.
Exemple d’exécution de bonjour2

1.2.3. Paramètres, instruction d’affectation


Avec la fonction bonjour2, nous devons demander à chaque utilisateur la valeur de l’année en cours. On peut
supposer que cette valeur est déjà connue de l’ordinateur (par une saisie préliminaire). On pourra alors
paramétrer la fonction avec cette valeur.
vide bonjour3(entier annee)
{ chaine nom ;
entier naissance, age ;
écrire("A quelle annee sommes-nous ? ") ; lire(annee) ;

2
écrire("Comment vous appelez-vous ? ") ; lire(nom) ;
écrire("Votre annee de naissance ? ") ; lire(naissance) ;
écrire("Bonjour %s ! \n",nom) ;
age = annee-naissance ;
écrire("Vous etes age de %d ans \n", age) ;
}

Le paramètre annee est de type entier est appelé paramètre formel et il sera remplacé à l’appel de la fonction
par une valeur entière. On dit qu’on fait le passage par valeur.
Exemples d’instructions d’appel
 bonjour3(1993) ;
 Si la variable ancour contient une valeur entière :
bonjour3(ancour) ;
On dira que 1993 ou ancour sont des paramètres effectifs, dont la valeur remplace celle du paramètre formel
lors de l’exécution.
D’autre part, nous introduisons dans la fonction une instruction d’affectation : age = annee – naissance ;
Cette instruction permet de ranger une valeur dans une variable, autrement que par saisie directe (lire).

Exemple d’instructions d’affectation correctes


a1 = 3 ;
b = 3 * 5 ;
c = a1 ;
c = (b + 6) / 4 ;
nb = nb + 1 ;
nb = nb * (a1 + b) ;
L’instruction d’affectation nb = nb + 1 est tout à fait différente d’une égalité mathématique. En effet, l’égalité
nb = = nb + 1 serait évidemment toujours fausse, quelle que soit la valeur de nb alors que l’instruction nb = nb +
1 consiste simplement à modifier la valeur de la variable nb, en lui ajoutant 1.
Exemples d’instructions d’affectation incorrectes
a + 1 = 3 ; (a+ 1 n’est pas un identificateur de variable).
a = 3b ; (3b n’est ni un identificateur, ni une expression correcte)
Cette instruction d’affectation est aussi correcte :
x = y = z = 0 ; l’associativité est effectuée de droite à gauche. Cependant l’écriture suivante n’est pas acceptée :
double x = y = z = 0 ; // est rejeté.
Rappel : toute variable utilisée dans un programme doit être déclarée au début de l’algorithme, une fois et une
seule.

Lorsqu’une variable apparaît en partie droite d’une instruction d’affectation, c’est que l’on suppose qu’elle
contient une valeur. Cette valeur devra lui avoir été affectée auparavant (initialisation), sinon l’on dira que la
valeur est indéfinie, et le résultat de l’affectation ne sera pas défini.
Exemple d’algorithme correct :
vide corr(vide)
{ entier a, b, c ;
a = 12 ; b= 5 ;
c = a – b ;
a = a + c ;
/* il s’agit ici de modifier la valeur de a, en lui ajoutant c */
b = a ; }
Pour voir les contenus successifs des variables, nous allons en effectuer la trace : il s’agit tout simplement
d’un tableau dans lequel pour chaque ligne de l’algorithme, nous noterons les valeurs des variables.
a b c
int a, b, c ;
indéfini indéfini indéfini
a = 12;b = 5 ;
c = a - b ; 12 5 indéfini
a=a+c; 12 5 7
19 5 7
b = a;
19 19 7
Exemple d’algorithme incorrecte
vide incorr(vide)
{ entier a, b, c ;
a = 5 ;
c = a + b ;
d = c - 2 ;

3
} a b c
entier a, b, c ;
indéfini indéfini indéfini
a = 5 ;
c = a + b ; 5 indéfini indéfini
5 indéfini ?
d=c-2;
5 indéfini ?
1.3. Itérations et conditions
Ecrivez une fonction qui saisit le nom et l’année de naissance de toute une série de personnes et affiche pour
chaque personne son âge.
Une première méthode consiste à répéter les instructions de saisie et d’écriture un certain nombre de fois.
vide etudiants1(entier annee)
{ chaine nom ; entier naissance, age ;
écrire("Nom d’un etudiant ? ") ; lire(nom) ;
écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ;
écrire("%s est age de %d ans\n",age) ;

écrire("Nom d’un etudiant ? ") ; lire(nom) ;


écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ;
écrire("%s est age de %d ans\n",age) ;

écrire("Nom d’un etudiant ? ") ; lire(nom) ;


écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ;
écrire("%s est age de %d ans\n",age) ;
écrire("Nom d’un etudiant ? ") ; lire(nom) ;
écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ;
écrire("%s est age de %d ans\n",age) ;

écrire("Nom d’un etudiant ? ") ; lire(nom) ;


écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ;
écrire("%s est age de %d ans\n",age) ;
}
C’est une méthode laborieuse, en raison de la répétition cinq fois la même séquence d’instructions. Un
autre inconvénient si l’école a moins de cinq étudiants, on lui demande des données inexistantes, s’il a plus de
cinq étudiants on ne lui demande rien au sujet des étudiants « supplémentaires ».
1.3.1. Instruction d’itération
Pour éviter cette répétition et demander les données le nombre de fois nécessaire et suffisant, on utilise
l’instruction d’itération.
vide etudiants2(entier annee)
{ chaine nom ;
entier naissance, age, nbetudiants, i ;
écrire("Combien d\’etudiants avez-vous ? ") ; lire(nbetudiants) ;
i = 1 ;
tantque(i <= nbetudiants){
écrire("Nom d’un etudiant ? ") ; lire(nom) ;
écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ;
écrire("%s est age de %d ans\n",age) ;
i = i + 1 ;
}
}
Dans la fonction nous demandons à l’utilisateur combien de fois il faudra répéter les instructions de saisie et
d’affichage, nous utilisons le constructeur tantque, afin d’itérer, ou répéter, ces instructions le bon nombre de
fois.
Exemple d’exécution de etudiants2
( On suppose que le paramètre annee vaut 2008 ; en gras les réponses de l’utilisateur aux questions posées)
Combien d’etudiants ? 2
Nom d’un etudiant ? Rabe
Son annee de naissance ? 1990

4
Rabe est age de 18 ans
Nom d’un etudiant ? Rasoa
Son annee de naissance ? 1992
Rasoa est age de 16 ans

Les opérations de comparaison sont : <, <=, >, >=, ==, !=.


Les instructions sur lesquelles agit le constructeur tantque sont comprises entre { }. La forme générale d’une
instruction tantque est :
tantque (condition) { instruction1 ;
instruction2 ;……
}
Remarque : Cette instruction est elle-même une instruction, dite instruction d’itération. La suite d’instructions
est effectuée aussi longtemps que la condition demeure vraie.

1.3.2. Variables booléennes, instructions conditionnelles


Une autre méthode pour résoudre les problèmes posés par la fonction etudiants1 consiste à faire arrêter
l’itération par l’utilisateur, lorsqu’il le juge utile.
vide etudiants3(entier annee)
{ chaine nom ; entier naissance, age ;
booléen stop ;
stop = faux ;
tantque(non stop)faire
{ écrire("Nom d’un etudiant ? ") ; lire(nom) ;
si(nom <>’*’)
{ écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ; écrire("%s est age de %d ans\n",age) ;
}
sinon stop = vrai ;
}
}
La syntaxe d’une instruction conditionnelle est :
si(expression testée){ suite d’instructions 1}
sinon {suite d’instructions 2}
Si la condition est vraie, la suite d’instructions1 est effectuée ; si elle est fausse, on effectue la suite
d’instructions 2.

Les 2 suites d’instructions peuvent comporter à leur tour des instructions d’itérations ou encore d’autres
instructions conditionnelles.
Dans certains cas, on peut vouloir ne rien faire si la condition est fausse. La forme se réduit à :
si(expression testée){ suite d’instructions 1}
La première instruction que nous pouvons introduire sur la variable booléen est la négation :
Négation (non)
A Non A
vrai faux
faux vrai
Notons que A est faux est équivalent à non A, donc (A = faux)==(non A) et de même (A = vrai) ==(A) ;
Nous pouvons imaginer que des utilisateurs s’amusent à faire tourner indéfiniment l’itération de la fonction
enfants3, en refusant de frapper un nom égal à ‘*’. Nous allons forcer la fonction à s’arrêter au bout de 20
itérations au maximum, en ajoutant un second test d’ arrêt, contrôlé par un compteur.

vide etudiants4(entier annee)


{ chaine nom ; entier naissance, age, i ;
booléen stop ;
stop = faux ; /* en langage C, stop = 0 ; */
i = 0 ;
tantque((non stop) et (i < 20))faire
{ écrire("Nom d’un etudiant ? ") ; lire(nom) ;
si(nom <>’*’)
{ écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ; écrire("%s est age de %d ans\n", age) ; i=i+1 ;
}
sinon stop = vrai ;

5
}
}
La variable i a été utilisée à compter le nombre d’itérations.

Dans l’expression de test (non stop )et(i<20), nous utilisons une nouvelle opération, l’intersection. Le résultat
de l’intersection n’est vraie que si les deux opérandes on la valeur vrai.
Intersection (et)
A B A et B
vrai vrai vrai
vrai faux faux
faux vrai faux
faux faux faux

Dans certains cas nous serons amenés à utiliser l’opération d’union : Union (ou)
A B A ou B
vrai vrai vrai
vrai faux vrai
faux vrai vrai
faux faux faux
Assertions : nous pouvons améliorer la lisibilité de la fonction etudiants4 précédente en y ajoutant des
« assertions ». Une assertion est une expression logique (booléenne) ou condition qui est toujours vraie. Elle
est construite à partir de variables booléennes et de conditions élémentaires, à l’aide des opérateurs logiques
non, et et ou.

Par convention, les assertions sont écrites, dans les algorithmes, en italiques, et entourés des signes /* et */.
Afin de simplifier l’écriture, nous conviendrons aussi de remplacer, dans les assertions, le non par le symbole ¬,
le et par une virgule, et le ou par le symbole ν.
void etudiants4(entier annee)
/* spécification {}  {les âges des étudiants de l’utilisateur sont affichés}*/
{ chaine nom ; entier naissance, age, i ;
booléen stop ;
stop = faux ; /* en langage C, stop = 0 ; */
i = 0 ;
tantque((non stop) et (i < 20))faire
{ écrire("Nom d’un etudiant ? ") ; lire(nom) ;
si(nom <>’*’)
{ écrire("Son annee de naissance ? ") ; lire(naissance) ;
age = annee – naissance ; écrire("%s  est age de %d ans\n", age) ; i=i+1 ;
}
sinon /* nom=’*’ */ stop = vrai ;
} /* stop ν (i=10) */
}
Les assertions permettent de suivre la logique de l’algorithme et d’en vérifier le bien fondé. Mais qu’elles ne
modifient en rien le déroulement de l’algorithme. On dira que ce sont des commentaires.

1.3.3. Type caractère et instructions conditionnelles imbriquées.


Nous allons améliorer la fonction d’accueil bonjour en affichant Monsieur, Madame ou Mademoiselle devant
le nom de l’utilisateur. Pour cela, nous devons connaître son sexe, que nous coderons par la lettre ‘M’ ou ‘F’. Si
le sexe est féminin, nous devons de plus demander si la personne est mariée (réponse codée par ‘O’ pour oui,
‘N’ pour non).
vide bonjour4(vide)
{ chaine nom ; car sexe, marie ;
écrire("Comment vous appelez-vous ? ") ; lire(nom) ;
écrire("Quel est votre sexe (M ou F) ? ") ; lire(sexe) ;
si(sexe == ‘M’) /*sexe = ‘M’*/
{ écrire("Bonjour, Monsieur %s\n", nom) ;
sinon /*sexe = ‘F’ */
{ écrire("etes-vous mariee (O ou N) ? ") ; lire(marie) ;
si(marie == ‘O’) /*sexe=‘F’, marie = ‘O’ */
{ écrire("Bonjour, Madame %s\n", nom) ;
sinon /* sexe = ‘F’, marie = ‘N’ */
écrire("Bonjour, Mademoiselle %s\n", nom) ;
}

6
}
}
Car sexe, marie ; ce sont des variables de type caractère.

La forme la plus générale de l’instruction conditionnelle est :


Si(expression testée 1)
{ suite d’instructions 1 }
sinon
{ si(expression testée 2){ suite d’instructions2}
Sinon si(expression testée 3){ suite d’instruction3 }…
Cette instruction est appelé instruction conditionnelle imbriquée.

1.4 Fonction avec résultat


Pour simplifier la fonction bonjour4, nous allons regrouper les instructions de « calcul » du titre Monsieur,
Madame, Mademoiselle, dans une fonction qui délivre (retourner) une valeur d’un type déterminé que nous
nommerons résultat.
chaine fonction(car sexe, marie)
{ si(sexe ==’M’)retour ‘Monsieur’ ;
Sinon si(marie ==’O’)retour ‘Madame’ ;
sinon retour ‘Mademoiselle’ ;
}
Le type de la valeur que retourne la fonction est déclarée dans la première ligne de la fonction suivie du nom
de la fonction et des arguments de cette fonction. Il s’agit ici du type chaîne. La valeur que retourne la fonction
(le résultat) est déterminée par une ou plusieurs instructions retour.

1.4.1. Passage par valeur


Une fonction passée par valeur ne peut retourner qu’un seul résultat à la fois. Si l’on veut qu’une fonction
modifie un ou plusieurs valeurs extérieures à la fonction on utilise le passage par pointeur.
Exemple : écrire une fonction qui donne la valeur vrai si la personne a plus de 18 ans sinon la fonction retourne
la valeur faux.
booléen majeur1(entier age)
{ si(age>=18)retour vrai ;
Sinon retour faux ;
}
Une solution simple et correcte :
booléen majeur2(entier age)
{ retour age>=18 ;
}
Exemple d’appel de la fonction :
majeur1(14) ;
ou entier n=23 ;
majeur2(n) ;

1.4.2. Passage par pointeur


Le but d’un algorithme est de modifier la valeur d’un paramètre : celui-ci est une donnée, par sa valeur à
l’entrée de l’algorithme, et un résultat, par sa valeur à la sortie de l’algorithme. Dans on utilise le passage par
pointeur.
vide permut( entier* a, entier* b)
{ entier c ;
c = *a ; *a = *b ; *b = c ;
}

Exemple d’appel d’une telle fonction :


principale()
{ entier nb1, nb2 ;
écrire("saisir le premier nombre ? ") ; lire(nb1) ;
écrire("saisir le second nombre ? ") ; lire(nb2) ;
écrire("resultat avant echange\n") ;
écrire("nb1=%d\tnb2=%d\n",nb1, nb2) ;
permut(&nb1, &nb2) ;
écrire("resultat apres echange\n") ;
écrire("nb1=%d\tnb2=%d\n", nb1,nb2) ; }

7
Nous avons introduit deux nouveaux opérateurs : opérateur unaire d’adresse noté & et opérateur unaire
d’indirection noté *.
L’opérateur & permet d’obtenir l’adresse d’une variable. Elle s’applique à une variable. Si l’on a déclaré :
entier n ;
écrire("L\’adresse de n est : %s", &n) ;
/* &n permet d’obtenir l’adresse de n */
Pour que l’adresse de n existe, il faut tout d’abord déclarer n.
Par contre, l’opérateur d’indirection * permet d’obtenir le contenu de cette adresse. Elle doit s’appliquer à une
adresse.
*(&n) = 13 ; /*permet d’affecter la valeur 13 à la variable n, indirectement à partir de son adresse */
Cette écriture est équivalente à n=13 ;
Les développeurs du langage ont créé de nouveaux objets dont leurs contenus sont des adresses. Ces nou-
veaux objets sont appelés des pointeurs.

Déclaration d’un pointeur


entier * adri ; // adri est un pointeur qui pointe sur un entier.
Exemple :
principale(vide)
{ entier n, *adrn ;
adrn = &n ;
écrire("Adresse de n est %p\n", &n) ;
*adrn = 25 ;
écrire("Le contenu de adr est %d ou %d\n", *adrn, n) ;
n = 123 ;
écrire("Le contenu de la variable n est %d\n",*adrn) ; }

1.5. Raisonnement par récurrence


Une méthode proposée pour construire un algorithme itératif est basée sur la notion d’invariant et sur un
raisonnement par récurrence.
Exemple : soit à écrire une fonction qui retourne la valeur de n p, où p est un nombre entier positif, et n un
entier quelconque.
Nous pouvons définir récursivement np par les deux égalités suivantes :
n1 = n,
ni+1 = ni * n, i Є[1..p-1].

Supposons que nous avons partiellement résolu le problème : nous avons une variable r qui contient la valeur
de ni, et nous savons que i<=p.
On a donc l’hypothèse suivante : r = ni, i<=p.
Il y a deux possibilités :
 Soit i = p, alors r = np et le calcul est terminé.
 Soit i < p
Nous multiplions alors r par n en exécutant l’instruction : r = r * n ; r est donc alors égal à ni * n = ni+1.
Si nous incrémentons ensuite i de 1 en exécutant l’instruction : i = i + 1 ; nous obtenons de nouveau : r = ni,
i<=p.
L’instruction itérative s’écrit donc de la manière suivante :
/* r = ni, i<=p */
tantque(i<p)
{ r = r * n ; /* r = ni+1, i<p */
i = i + 1 ; /* r = ni, i <=p */
}
Pour laquelle l’assertion r = ni, i<=p est un invariant, à condition d’être vraie avant le début de l’itération. Pour
cela, il faut initialiser r et i avec des valeurs qui vérifient l’invariant.
Initialisation :
Il suffit d’écrire les affectations : r = n ; i = 1 ; /* r = ni, i <= p */

Pour vérifier l’hypothèse r = ni, i <= p quelle que soit la valeur de p > 0.
L’hypothèse ne devient un invariant que si l’initialisation a été effectuée.
A la sortie de l’instruction itérative nous pouvons affirmer :
 d’une part que ¬ (i < p) donc i >= p (condition de sortie de « tantque »)
 d’autre part que r = ni, i <= p (invariant).
De i <= p et i >= p, nous déduisons que i = p ;
de i = p et r = ni, nous déduisons que r = np.
En résumé, nous présenterons le raisonnement par récurrence sous la forme suivante :

8
Hypothèse  r = ni, i <= p
 i = p => r = np => résultat = r *
 i < p => r = r * n ; i = i + 1 ; => H
Itération tantque(i < p)....
Initialisation r = n ; i = 1 ; => H

L’algorithme complet est alors le suivant :


entier puissance (entier n, entier p)
/* spécification {p > 0} => {résultat = n p}*/
{ entier r, i ;
r = n ; i = 1 ; /* r = ni, i<=p */
tantque(i < p){
r = r * n ; /* r = ni+1, i<p */
i = i + 1 ; /* r = ni, i <= p */ }
/* i <= p, r = ni, i <= p => r = np */
retour r ;
}
Le raisonnement par récurrence nous a permis :
 de construire l’itération,
 de dégager l’invariant,
 de trouver les initialisations nécessaires,
 et enfin de prouver que la valeur finale de r est bien celle que l’on cherche, en combinant la condition de
sortie de l’itération avec l’invariant.

Vous aimerez peut-être aussi