3.1 Instructions de contrôle
On appelle instruction de contrôle toute instruction qui
permet de contrôler la succession des actions d'un programme. Parmi
les instructions de contrôle, on distingue les instructions de
branchement et les instructions de boucle. L'étude
de ce type d'instruction va occuper cette section et la suivante.
3.1.1 Les instructions de branchement conditionnel
Il existe deux type d'instructions de branchement.
Branchement if ... then ... else
La forme générale d'une conditionnelle en C est :
| if( condition 1 ) |
| instruction 1 |
| else if( condition 2 ) |
| instruction 2 |
| : |
| else instruction n |
Exercice 3.0 --- Correction d'une erreur.
Corriger le programme suivant :
#include <stdio.h>
int main(void){
char foo = 0 ;
if(foo=1) printf("La valeur initiale de foo est 1\n");
return 0 ;
}
Exercice 3.1 --- Indice de masse corporelle.
Le statisticien et sociologue belge Quételet a observé au milieu
du XIXième siècle, que le rapport (I) du poids en
kilogrammes (P) par la taille en mètres (T) au carré était
constant chez des individus de constitution moyenne. En 1998,
l'Organisation Mondiale de la Santé a établit une classification
suivant ce rapport I=P/T2 :
-
maigreur pour I<18.5
- limite moyenne pour 18.5 ... 24.9
- surpoids pour I>25
Construisez une procédure qui demande à l'utilisateur son poids
en kilogrammes et sa taille en mètres, calcul l'indice I et
affiche sa condition par rapport à la classification de l'OMS.
N'oublions pas le seul indice qui compte : être bien dans sa peau !
Indication :
pour saisir au clavier un flottant et le stocker
dans une variable puis l'afficher, on peut s'inspirer du code :
#include<stdio.h>
int main(void){
float var ;
scanf("%f",&var) ;
printf("%f\n",var) ;
return 0 ;
}
Exercice 3.2 --- Procédure de tarification.
Les tarifs d'une piscine sont les suivants :
-
trois euros si vous avez entre 18 et 65 ans ;
- deux euros si vous avez plus de 65 ans ;
- un euros si vous avez moins de 18 ans.
De plus, vous pouvez bénéficier d'une réduction de 20% si
vous avez une carte de réduction.
Construire une procédure principale qui prend en entrée l'âge
du client et un entier indiquant s'il a une carte (0 pour non et 1
pour oui), et qui renvoie la somme à payer. L'exercice consiste
à compléter le squelette suivant :
#include <stdio.h> /* pour afficher et saisir au clavier scanf */
int main(void){
int Age ; /* variable locale stockant l'age */
int Carte ; /* 1 si carte, 0 sinon */
float APayer ; /* variable locale stockant le r\'esultat */
/* On collecte les donn\'ees concernant le client */
printf("Age du client ? ") ; /* on affiche la cha\^ine a l'\'ecran */
scanf("%d", &Age); /* nous expliciterons plus tard la */
/* syntaxe &Age */
printf("Le client a-t-il une carte ? ") ;
scanf("%d", &Carte);
/* La partie de conditionnelle proprement dite */
/* (a completer) */
/* L'affichage du r\'esultat */
printf("La somme a payer est %f",APayer) ;
return 0 ;
}
Les affectations et les opérations usuelles sont classiques. On
affecte la valeur 3 à la variable foo en utilisant
l'instructions foo=3.0; et on a des instructions du
type foo=foo*5.0;.
Branchement multiple switch ... case ... default
La forme générale d'une conditionnelle multiple en C est :
| switch( expression ) |
|
{ |
| case cste :
instruction(s) 1 break ; |
| ... |
| default : instruction(s)
break |
| } |
Exercice 3.3 --- Association entre nombres et jours.
On se propose de construire une procédure qui prend au clavier un
entier correspondant à un jour de la semaine --- 1 correspond
à lundi --- et retourne sa traduction en anglais. Pour ce faire,
on décide d'utiliser une instruction de branchement multiple et de
compléter le squelette suivant :
#include <stdio.h> /* pour saisir au clavier et afficher */
int main(void){
int jour ;
/* On collecte un entier correspondant \`a un jour */
printf("Le jour de la semaine (entrer un entier, lundi = 1) ? ") ;
scanf("%d", &jour);
/* La partie de conditionnelle proprement dite */
/* \`a compl\'eter */
return 0 ;
}
Exercice 3.4 --- Tarification hôtel.
Pour conclure cette séance, on se propose de programmer une
procédure de tarification d'un hôtel. Les tarifs sont les
suivants :
-
40 euros pour un adulte en chambre individuelle ;
- 38 euros par chambre pour trois chambres individuelles ou plus
réservées ;
- 60 euros pour deux adultes en chambre double ;
- 58 euros par chambre pour quatre chambres doubles ou plus
réservées ;
- gratuité pour les deux premiers enfants ;
- 30 euros par enfant à partir du troisième. Les enfants
dorment en réfectoire et ne comptent pas dans le prix des
chambres individuelles ou doubles ;
- le petit déjeuner est obligatoire et fixé à 6 euros.
Pour calculer le prix total à payer, on saisit au clavier les
informations suivantes : nombre de chambre individuelle, nombre de
chambre double, nombre d'enfant, nombre de nuit.
3.1.2 Itérations
Itération énumérative
Ceci étant dits, on peut maintenant définir la syntaxe d'une
itération énumérative.
| for( expr 1 ; expr 2 ;
expr 3 ) |
| instructions |
Par exemple, si l'on exécute la boucle :
int N ;
for( N=1 ; N<11 ; N++)
putchar('A') ;
On obtiendra l'affichage de 10 lettre A.
Exercice 3.5 --- Calcul de factorielle.
Construire un programme qui calcule la factorielle d'un nombre saisi
au clavier.
Calculer la factorielle de 13 puis celle de 12. Que constatez
vous ? Comment expliquez vous ce phénomène ?
Exercice 3.6 --- Suite de Fibonacci.
Pour un entier n saisi au clavier, nous allons construire une
procédure qui calcule et affiche le nième terme de la suite de
Fibonacci. Cette suite est définie par la récurrence et les
conditions initiales suivantes :
uj+1=uj+uj-1, u0=0, u1 =1.
Itération conditionnelle testée en début de boucle
Une instruction spécifique existe pour le cas fréquent où une
condition est testé au début de chaque itération. Il s'agit de
l'instruction while dont la forme générale est :
| while (condition) |
| instructions |
La condition est ainsi évaluée à chaque itération.
Exercice 3.7 --- Implantation itérative de l'algorithme d'Euclide.
On se propose de calculer le plus grand commun diviseur --- pgcd ---
de deux entiers par l'algorithme d'Euclide. Cet algorithme repose
sur le fait que, étant donné deux entiers a et b, le pgcd
de a et de b est égal au pgcd de b et de r où r est
le reste de la division euclidienne de a par b et ceci tant
que r est différent de zéro. Le pgcd est alors le dernier
diviseur utilisé.
Écrivez une procédure qui, à partir de deux entiers saisis au
clavier, calcule leur pgcd. Pour information, en C la condition b
différent de zéro s'énonce b!=0 et le reste de la
division euclidienne de a par b s'obtient par l'instruction
a%b.
Remarque.
Il est évident que la justesse de l'implantation de l'algorithme
d'Euclide que nous venons de faire repose sur la relation :
pgcd(a,b) == pgcd(b,a%b).
De même, cet algorithme se termine bien car le reste de la
division euclidienne de a par b est nul ou strictement
inférieur à b.
Par contre, la complexité de cet algorithme i.e. le nombre de pas
nécessaire, n'est pas évident. Bien que cet algorithme soit
millénaire, il a fallut attendre 1845 et un résultat de Lamé
pour avoir la proposition :
Soient a et b deux entiers avec 0£ b£ a. L'algorithme
d'Euclide calculant le pgcd de a et b nécessite au
plus 3 (log b)/2+1 pas d'exécution.
La démonstration repose sur la suite de Fibonacci
(cf. [1, § 1.4.4]).
Exercice 3.8 --- Racine carrée par défaut d'un entier positif.
La racine carrée par défaut d'un entier positif n est un
entier positif p qui vérifie :
p2£ n <(p+1)2.
Construire un programme qui permet à l'utilisateur de saisir un
entier et qui affiche sa racine carrée par défaut.
Vous pouvez tester deux approches : la recherche linéaire de la
racine par défaut et la recherche dichotomique.
Nous allons consacré cette section à consolider les acquis des
séances précédentes en traitant quelques exercices.
Exercice 3.9 --- Affichage d'étoiles.
On se propose d'afficher des étoiles dans les dispositions suivantes :
***** * ***** ***** *
***** ** **** **** **
***** *** *** *** ***
***** **** ** ** ****
***** ***** * * *****
Construisez un programme C qui affiche successivement ces dispositions.
Pour tout commentaire : Alexandre Sedoglavic.