Cours de C apprendre les bases de la programmation avec le langage c
…
Présentation du langage C
Historique
Langage de programmation développé en 1970 par Dennie Ritchie aux Laboratoires Bell d'AT&T. Il est l'aboutissement de deux langages :
Il fut limité à l'usage interne de Bell jusqu'en 1978 date à laquelle Brian Kernighan et Dennie Ritchie publièrent les spécifications définitives du langage : «~The C programming Language~».
Au milieu des années 1980 la popularité du langage était établie. De nombreux compilateurs ont été écrits, mais comportant quelques incompatibilités portant atteinte à l'objectif de portabilité. Il s'est ensuivi un travail de normalisation effectué par l'ANSI (American National Standard Institue) qui a abouti en 1988 avec la parution par la suite du manuel : «~The C programming Language - 2ème édition~».
Intérêts du langage
Qualités attendues d'un programme
Le jeu de caractères utilisé pour ecrire une programme est composé de :
! |
* |
+ |
\ |
" |
< |
# |
( |
= |
| |
{ |
> |
% |
) |
~ |
; |
] |
/ |
^ |
- |
[ |
: |
, |
? |
& |
_ |
} |
' |
. |
(espace) |
Structure d'un programme C
Exemple :
#include<stdio.h>
#define PI 3.14159
/* calcul de la surface d'un cercle */
main()
{
float rayon, surface;
float calcul(float rayon);
printf("Rayon = ? ");
scanf("%f", &rayon);
surface = calcul(rayon);
printf("Surface = %f\n", surface);
}
/* définition de fonction */
float calcul(float r)
{
/* définition de la variable locale */
float a;
a = PI * r * r;
return(a);
}
La transformation d’un texte écrit en langage C en un programme exécutable par l’ordinateur se fait en deux étapes : la compilation et l'édition de liens.
La compilation est la traduction des fonctions écrites en C en des procédures équivalentes écrites dans un langage dont la machine peut exécuter les instructions. Le compilateur lit toujours un fichier, appelé fichier source, et produit un fichier, dit fichier objet.
Chaque fichier objet est incomplet, insuffisant pour être exécuté, car il contient des appels de fonctions ou des références à des variables qui ne sont pas définies dans le même fichier. Par exemple, le premier programme que vous écrirez contiendra déjà la fonction printf que vous n’aurez certainement pas écrite vous-même. L'édition de liens est l’opération par laquelle plusieurs fichiers objets sont mis ensemble pour se compléter mutuellement : un fichier apporte des définitions de fonctions et de variables auxquelles un autre fichier fait référence et réciproquement. L'éditeur de liens (ou linker) prend en entrée plusieurs fichiers objets et bibliothèques (une variété particulière de fichiers objets) et produit un unique fichier exécutable.
Exemples
x |
y12 |
somme_1 |
_temperature |
noms |
surface |
fin_de_fichier |
TABLE |
4eme |
commence par un chiffre |
x#y |
caractère non autorisé (#) |
no-commande |
caractère non autorisé (-) |
taux change |
caractère non autorisé (espace) |
Certains mots sont réservés par le langage car ils ont une signification particulière. Il est alors interdit d'utiliser un de ces mots comme identificateur. Bien que le compilateur fasse la différence entre majuscules et minuscules et qu'on puisse donc utiliser un de ces mots en majuscules comme identificateur, il est préférable, pour la clarté du source, d'éviter cette attitude de programmation.
Types |
Classes |
Instructions |
Autres |
char |
auto |
break |
case |
double |
const |
continue |
default |
float |
extern |
do |
enum |
int |
register |
else |
sizeof |
long |
static |
for |
typedef |
short |
volatile |
goto |
|
signed |
if |
||
struct |
return |
||
union |
switch |
||
unsigned |
while |
||
void |
Les différents séparateurs reconnus par le compilateur peuvent avoir plusieurs significations.
Type |
Nom |
Significations |
[…] |
Crochets |
Indice d'accès dans un tableau |
(...) |
Parenthèses |
1/ Groupement d'expressions (force la priorité) 2/ Isolement des expressions conditionnelles 3/ Déclaration des paramètres d'une fonction 4/ Conversion explicite d'un type (casting) |
{….} |
Accolades |
1/ Début et fin de bloc d'instructions 2/ Initialisation à la déclaration d'un tableau 3/ Déclaration d'une structure |
, |
Virgule |
1/ Sépare les éléments d'une liste d'arguments 2/ Concaténation d'instructions |
; |
Point virgule |
Terminateur d'instruction |
: |
Deux points |
Label |
. |
Point |
Accède à un champ d'une structure |
-> |
Flèche ("moins" suivi de "supérieur") |
Accède à un champ d'un pointeur sur une structure |
Les commentaires permettent de porter des remarques afin de faciliter la lecture d'un programme source. Chaque commentaire est délimité par les combinaisons suivantes "/* Commentaire */" Les commentaires ne sont pas pris en compte par le compilateur et n'augmentent donc pas la taille des programmes exécutables.
Les commentaires peuvent tenir sur plusieurs lignes du style :
/* Je commente mon programme Je continue mes commentaires J'ai fini mes commentaires */
Les commentaires ne peuvent pas être imbriqués comme dans le style :
/* Début Commentaire 1 /* Commentaire 2 */ Fin commentaire 1*/
Remarque :
Les compilateurs récents acceptent, comme commentaire, la séquence "//" spécifique au langage "C++" qui permet de ne commenter qu'une ligne ou une partie de la ligne.
// Cette ligne est totalement mise en commentaire
int i; // Le commentaire ne commence qu'à la séquence "//"
Comme tout langage déclaratif, le langage C exige que les variables soient déclarées avant leur utilisation. En fait, pour chaque bloc d'instructions délimité par des accolades "{", il faut déclarer toutes les variables avant que soit écrite la première instruction du bloc. Mais cette règle étant valable pour chaque bloc ; on peut aussi déclarer des variables dans des sous-bloc d'instructions.
Exemple :
/* Bloc d'instruction n° 1*/
{
Déclaration des variables (avant toute instruction du bloc n° 1)
Instruction
Instruction
…
/* Sous-bloc d'instruction n° 2 */
{
Déclaration des variables (avant toute instruction du bloc n° 2)
Instruction
Instruction
…
}
…
Instruction appartenant au bloc n° 1
}
Une variable est définie par plusieurs attributs; certains facultatifs mais ayants alors une valeur par défaut) :
Déclaration :
[classe] [unsigned/signed] <type> <identificateur>; (n'oubliez pas le point-virgule final)
Exemple :
static int nb; // Déclaration d'une variable nb de type int de classe static
int i; // Déclaration d'une variable i de type int (de classe auto par défaut)
Remarque :
la notion de classe sera revue plus en détail par la suite du cours. Jusque là, il suffira de ne pas spécifier de classe pour vos variables.
Lors de sa création en mémoire, une variable possède n'importe quelle valeur.
Un programme manipule des données de différents types sous la forme de constantes ou de variables. Les types de base correspondent aux types directement supportés par la machine. Dans le langage C, tout type de base est un nombre codé sur un ou plusieurs octets. Donc tout type de base accepte toute opération mathématique de base. Les principaux types de base sont:
Remarques :
Ajouter 1 à une variable ayant atteint sa limite maximale la fait basculer en limite minimale (perte de la retenue). C'est à dire que "127 + 1 = -128" si on travaille sur une variable de type "char signé". Il est possible de forcer un entier à être signé ou non-signé en rajoutant le mot clef "signed" ou "unsigned" avant son type (char, int, short int, long int). Une variable est signée par défaut donc le mot clef "signed" est inutile.
Ils respectent les règles de codage IBM des réels utilisant un bit pour le signe, "x" bits pour la mantisse et "y" pour l'exposant. Ils sont de deux types standard et un troisième non-standard :
[+/-]701 411 x 1038 à [+/-]701 411 x 1038
[+/-]1.0 x 10307 à [+/-]1.0 x 10307
[+/-]3.4 x 10-4932 à [+/-]1.1 x 104932. Mais ne faisant pas partie de la norme ANSI, il est souvent transformé en "double" par les compilateurs normalisés.
Il n'existe pas en langage C de type booléen. Mais la valeur zéro est considérée par le langage Comme "faux" et toute autre valeur différente de zéro est considérée comme "vrai".
Exemple
#include <stdio.h>
unsigned char mask;
long val;
main()
{
unsigned int indice;
float x;
double y;
char c;
...
return;
}
double f(double x)
{
unsigned short taille;
int i;
unsigned long temps;
double y;
...
return y;
}
L'affichage d'une valeur (variable ou constante) se fait en utilisant la fonction "printf( )" qui signifie "print formating"
Cette fonction s'utilise de la manière suivante :
®- Premier argument et le plus complexe : Message à afficher. Ce message, encadré par des " (double guillemets) constitue en fait tout le texte que le programmeur désire afficher. A chaque position du texte où il désire que soit reporté une variable ou une valeur d'expression, il doit l'indiquer en positionnant un signe "%" (pour cent) suivi d'un caractère indiquant la manière dont il désire afficher ladite valeur.
®- Autres arguments : Expressions et variables dont on désire afficher la valeur. Exemple :
main()
{
int a=5;
int b=6;
printf("Le résultat de %d ajouté à %d plus 1 est %d", a, b, a + b + 1);
}
La saisie d'une variable se fait en utilisant la fonction "scan( )" qui signifie "scan formating" Cette fonction s'utilise de la manière suivante :
®- Premier argument et le plus complexe : Masque de saisie. Ce masque, encadré par des " (double guillemets) constitue en fait tout ce que devra taper l'utilisateur quand il saisira ses variables. A chaque position du texte où le programmeur désire que soit reporté une variable à saisir, il doit l'indiquer en positionnant un caractère "%" (pour cent) suivi d'un caractère indiquant la manière dont il désire que soit saisie ladite valeur. Bien souvent, il n'y a aucun masque de saisie car c'est très contraignant.
®- Autres arguments : Variables à saisir, chacune précédée du caractère "&" Exemple :
main()
{
int jj;
int mm; int aa;
printf("Saisissez une date sous la forme jj/mm/aa :\n");
scanf("%d/%d/%d", &jj, &mm, &aa);
}
Les constantes permettent de symboliser les valeurs numériques et alphabétiques de la programmation courante. Il peut paraître trivial d'en parler tellement on y est habitué mais cela est utile en langage C car il existe plusieurs formats de notation.
5 (cinq) ; -12 (moins douze) ; 17 (dix-sept) ; -45 (moins quarante cinq) ; etc.
05 (cinq) ; -012 (moins dix) ; 017 (quinze) ; -045 (moins trente-sept) ; etc.
Remarque : il est possible de demander explicitement le codage des constantes précédemment citées sur un format "long" en les faisant suivre de la lettre "l" ou "L". Ex : 5L (nombre "cinq" codé sur 4 octets).
Ex : 3.1416 12.43 -0.38 .38 47. .27
Ex : 3e18 (3 x 1018).
4.25E4 |
4.25e+4 |
42.5E3 |
54.27E-32 |
542.7E-33 |
5427e-34 |
.48e13 |
48.e13 |
48.0E13 |
Remarque : toutes les constantes en virgule flottantes sont codées en format "double". Il est cependant possible de demander explicitement le codage de ces constantes sur un format "float" en les faisant suivre de la lettre "f ou "F". Ex : 3.1416F (nombre "3.1416" codé sur 4 octets).
Constante |
Signification |
Valeur |
\n |
Fin de ligne |
10 |
\t |
Tabulation horizontale |
99 |
\v |
Tabulation verticale |
11 |
\b |
Retour arrière |
8 |
\r |
Retour chariot |
13 |
\f |
Saut de page |
12 |
\a |
Signal sonore |
7 |
\\ |
Anti slash |
92 |
\" |
Guillemet |
34 |
\' |
Apostrophe |
44 |
Les énumérations sont des types définissant un ensemble de constantes qui portent un nom que l'on appelle énumérateur. Elles servent à rajouter du sens à de simples numéros, à définir des variables qui ne peuvent prendre leur valeur que dans un ensemble fini de valeurs possibles identifiées par un nom symbolique.
Syntaxe
enum [nom]
{
énumérateur1,
énumérateur2,
énumérateur3,
...
énumérateurn
};
Les constantes figurant dans les énumérations ont une valeur entière affectée de façon automatique par le compilateur en partant de 0 par défaut et avec une progression de 1. Les valeurs initiales peuvent être forcées lors de la définition.
enum couleurs {noir, bleu, vert, rouge, blanc,jaune};
enum couleurs
{
noir = -1,
bleu,
vert,
rouge = 5,
blanc,
jaune
};
Dans le 1er exemple, les valeurs générées par le compilateur seront :
noir |
0 |
vert |
2 |
blanc |
4 |
bleu |
1 |
rouge |
3 |
jaune |
5 |
et dans le 2e :
noir |
-1 |
vert |
1 |
blanc |
6 |
bleu |
0 |
rouge |
5 |
jaune |
7 |
Les opérateurs permettent de manipuler les variables et les constantes. Ils sont de trois type : ®- opérateurs unaires : ils prennent en compte un seul élément ®- opérateurs binaires : ils prennent en compte deux éléments ®- opérateurs ternaires : ils prennent en compte trois éléments
Ce sont les plus simples à appréhender. Les premiers peuvent s'appliquer à tout type de variable ou constante (entière ou à virgule flottante) :
Permet de vérifier l'égalité entre deux valeurs. Ex : a == b (si "a" est égal à "b" alors l'expression vaudra une valeur quelconque différente de "0" symbolisant le booléen "vrai" ; sinon l'expression vaudra "0"). Attention : Ecrire "=" en pensant "==" peut produire des incohérences graves dans le programme qui se compilera cependant sans erreur !
Permet de vérifier l'inégalité entre deux valeurs. Ex : a != b (si "a" est différent de "b" alors l'expression vaudra une valeur quelconque différente de "0" symbolisant le booléen "vrai" ; sinon l'expression vaudra "0"). Cet opérateur est l'opposé du "==".
Permet de vérifier les grandeurs relatives entre deux valeurs. Ex : a >= b (si "a" est supérieur ou égal à "b" alors l'expression vaudra une valeur quelconque différente de "0" symbolisant le booléen "vrai" ; sinon l'expression vaudra "0").
Les autres ne peuvent s'appliquer qu'aux valeurs (variables ou constantes) de type entière (char, short, long, int) :
Reste d'une division entière entre deux valeurs. Ex : 13 % 3
Opération booléenne "ET" entre deux booléens. Ex : a && b (si "a" est "vrai" ET "b" est "vrai", alors l'expression vaudra une valeur quelconque différente de "0" symbolisant le booléen "vrai" ; sinon l'expression vaudra "0").
Opération booléenne "OU" entre deux booléens. Ex : a || b (si "a" est "vrai" de "0" OU "b" est "vrai", alors l'expression vaudra une valeur quelconque différente de "0" symbolisant le booléen "vrai" ; sinon l'expression vaudra "0").
Les suivants ne peuvent s'appliquer qu'aux valeurs (variables ou constantes) de type entière (char, short, long, int) et agiront individuellement sur chaque bit de la constante ou variable.
Opération booléenne "ET" appliquée pour chaque bit des deux valeurs ; le nième bit de la première valeur étant comparé au nième bit de la seconde valeur. Ex : a & 5. Cette expression vaudra "5" si le premier et troisième bits de "a" sont à "1 " (masque).
Opération booléenne "OU" appliquée pour chaque bit des deux valeurs ; le nième bit de la première valeur étant comparé au nième bit de la seconde valeur. Ex : a | 5. Cette expression donnera une valeur où les premier et troisième bits seront toujours à "1".
Opération booléenne "OU EXCLUSIF" appliquée pour chaque bit des deux valeurs ; le nième bit de la première valeur étant comparé au nième bit de la seconde valeur. Ex : a ^ 5. Cet expression donnera une valeur où les premier et troisième bits seront à l'inverse de ceux de "a" (bascule).
Chaque bit de la valeur sera décalé vers la droite de "x" positions. Ex : 12 >> 3. Cela donne le même résultat que de diviser par 23.
Chaque bit d'une valeur sera décalé vers la gauche de "x" positions. Ex : 12 << 4. Cela donne le même résultat que de multiplier par 24.
Chaque opérateur binaire précédemment décrit peut être associé à l'opérateur "=" d'affectation. Cela permet de raccourcir une expression du style "a = a + x" par l'expression "a+=x" (sans espace entre le "+" et le "=").
Une fois que l'on a compris les opérateurs binaires, les opérateurs unaires viennent plus facilement. Les premiers peuvent s'appliquer à tout type de variable ou constante (entière ou à virgule flottante) :
Le suivant ne peut s'appliquer qu'aux valeurs (variables ou constantes) de type entière (char, short, long, int) et agira individuellement sur chaque bit de la constante ou variable.
Les quatre derniers ne s'appliquent qu'aux variables de type entière (char, short, long, int). Pour chaque exemple, nous prendrons une variable "i" initialement affectée avec "5".
Il n'y en a qu'un seul qui peut s'appliquer à tout type de valeur
Toute instruction renvoie une valeur. Exemple, l'instruction "5;" renvoie une valeur qui est… "5". Il est possible, pour ne pas la perdre, de récupérer cette valeur par l'opérateur d'affectation "=" dans l'instruction "a=5;". Mais cette dernière instruction renvoie aussi une valeur qui est… "5". Il est alors encore possible de la récupérer par un nouvel opérateur d'affectation "=" dans l'instruction "b=a=5" ; etc. Il est ainsi possible de récupérer la valeur de chaque instruction écrite. Ex : a=(b == 2) (récupère dans "a" le booléen "vrai" ou "faux" résultant de la comparaison entre "b" et "2").
Celui-ci ne s'applique qu'aux instructions
Calculez les résultats des expressions suivantes :
(2 + 3) * 4 |
/* Réponse : 20 */ |
(2 << 4) + 3 |
/* Réponse : 35 */ |
1 | 3 |
/* Réponse : 3 */ |
(2 << 1) > 3 ?25 >> 2 : 25 >> 1 |
/* Réponse : 6 */ |
4 > 5 |
/* Réponse : 0 ("faux") */ |
2,3,4+5 |
/* Réponse : 9 (2 et 3 ne sont pas traités) */ |
Dans un programme, les instructions sont exécutées séquentiellement, c'est-à-dire dans l'ordre où elles apparaissent Or la puissance et le "comportement intelligent" d'un programme proviennent essentiellement :
Ces possibilités sont offertes par des instructions, nommées "instructions de contrôle", permettant de réaliser ces choix ou ces boucles.
Cette instruction permet une exécution conditionnelle d’une partie du code.
Le mot else et l'instruction qu'il introduit sont facultatifs, de sorte que cette instruction présente deux formes.
if (expression) instruction_l else instruction_2 |
if (expression) instruction_1
|
Avec :
expression : expression quelconque
instruction__1 et instruction_2 : instructions quelconques, c'est-à-dire :
Partie de programme exécuté |
Résultat après exécution |
|
Partie de programme exécuté |
Résultat après exécution |
if (5<3) printf("Vrai"); else printf("Faux"); |
Faux |
if (5==3) printf("Vrai"); else printf("Faux"); |
Faux |
|
if (5!=3) printf("Vrai"); else printf("Faux"); |
Vrai |
if (5>=5) printf("Vrai"); else printf("Faux"); |
Vrai |
L'expression conditionnant le choix est quelconque. La richesse de la notion d'express; en C fait que celle-ci peut elle-même réaliser certaines actions. Ainsi :
if ( ++i < limite) printf ("OK") ;
est équivalent à :
i = i + 1 ;
if ( i < limite ) printf ("OK") ;
Par ailleurs :
if ( i++ < limite )
est équivalent à :
i = i + 1 ;
if ( i-1 < limite )
De même :
if { ( c=getchar() ) != '\n' )
peut remplacer :
c = getchar() ;
if ( c != '\n' )
Nous avons déjà mentionné que les instructions figurant dans chaque partie du choix d'une instruction pouvaient être absolument quelconques. En particulier, elles peuvent, à leur tour, renfermer d'autres instructions if. Or, compte tenu de ce que cette instruction peut comporter ou ne pas comporter de else, il existe certaines situations où une ambiguïté apparaît C'est le cas dans cet exemple :
if (a<=b) if (b<=c) printf ("ordonné") ;
else printf ("non ordonné") ;
est-il interprété comme le suggère cette présentation ?
if (a<=b)
if (b<=c) printf ("ordonné") ;
else printf ("non ordonné") ;
ou bien comme le suggère celle-ci ?
if (a<=b)
if (b<=c) printf ("ordonné") ;
else printf ("non ordonné") ;
La première interprétation conduirait à afficher "non ordonné" lorsque la condition a<=b est fausse, tandis que la seconde n'afficherait rien dans ce cas.
La règle adoptée par le langage C pour lever une telle ambiguïté est la suivante :
Un else se rapporte toujours au dernier if rencontré auquel un else n'a pas encore été attribué.
Dans notre exemple, c'est la seconde présentation qui suggère le mieux ce qui se passe.
soit à écrire un programme de facturation avec remise, qui doit lire le prix hors taxes et calcule le prix TTC correspondant (avec un taux de TVA constant de 18,6%), et qui établit ensuite une remise dont le taux dépend de la valeur ainsi obtenue, à savoir :
#include<stdio.h>
#define TAUX_TVA 18.6
Main()
{
double ht, ttc, net, tauxr, remise ;
printf("donnez le prix hors taxes : ") ;
scanf ("%lf", &ht) ;
ttc = ht * ( 1. + TAUX_TVA/100.) ;
if ( ttc < 1000.) tauxr = 0 ;
else if ( ttc < 2000 ) tauxr = 1. ;
else if ( ttc < 5000 ) tauxr = 3. ;
else tauxr =5. ;
remise = ttc * tauxr /100. ;
net = ttc - remise ;
printf ("prix ttc = %10.2lf\n", ttc) ;
printf ("remise = %10.2lf\n", remise) ;
printf ("net à payer = %10.2lf\n", net) ;
}
Exemple Nº1 d'exécution :
donnez le prix hors taxes : 500
prix ttc 593.00
remise 0.00
net à payer 593.00
Exemple Nº2 d'exécution :
donnez le prix hors taxes : 4000
prix ttc 4744.00
remise 142.32
net è payer 4601.68
L'instruction switch regarde si la valeur d'une expression fait partie d'un certain ensemble de constantes entières et effectue les traitements associés à la valeur correspondante.
switch(expression) { case expression-constante_1: [ suite_d'instructions_1 ]; case expression-constante_2: [ suite_d'instructions_2 ]; ... case expression-constante_n: [ suite_d'instructions_n ]; [ default: suite_d'instructions; ] } |
Avec:
expression : expression entière quelconque,
expression-constante : expression constante d'un type entier quelconque (char est accepté car il sera converti en int),
suite_d'instructions : séquence d'instructions quelconques.
N.B. : les crochets ( [ et ] ) signifient que ce qu'ils renferment est facultatif.
Chaque cas possible est étiqueté par une ou plusieurs constantes entières. L’expression est évaluée. Si elle correspond à une expression-constante, l’exécution commence par les instructions associées à cette étiquette.
L’instruction break permet de sortir immédiatement du switch. En effet lorsque le traitement d’un cas est terminé, l’exécution continue par le cas suivant. Pour différencier les divers cas il est donc nécessaire de terminer chacun d’entre eux par l’instruction break.
Voyez ce premier exemple de programme accompagné de trois exemples d'exécution.
#include<stdio.h> main() { int n ; printf ("donnez un entier : ") ; scanf ("%d", &n) ; switch (n) { case 0 : printf ("nul\n") ; break ; case 1 : printf ("un\n") ; break ; case 2 : printf ("deux\n") ; break ; } printf ("au revoir\n"); } |
Exemples d'exécution de ce programme |
donnez un entier : 0 nul au revoir donnez un entier : 2 deux au revoir donnez un entier : 5 au revoir |
Notez bien que le rôle de l'instruction break est fondamental. Voyez, à titre d'exemple, ce que produirait ce même programme en l'absence d'instructions break :
#include<stdio.h> main() { int n ; printf ("donnez un entier : "); scanf ("%d", &n) ; switch (n) { case 0 : printf ("nul\n"); case 1 : printf ("un\n"); case 2 : printf ("deux\n"); } printf ("au revoir\n"); } |
Exemples d'exécution de ce programme |
donnez un entier : 0 nul un deux au revoir donnez un entier : 2 deux au revoir |
II est possible d'utiliser le mot clé "default" comme étiquette à laquelle le programme se "branchera" dans le cas où aucune valeur satisfaisante n'aura été rencontrée auparavant En voici un exemple :
#include<stdio.h> main() { int n ; printf ("donnez un entier : ") ; scanf ("%d", &n) ; switch (n) { case 0 : printf ("nul\n") ; break ; case 1 : printf ("un\n") ; break ; case 2 : printf ("deux\n"); break ; default : printf ("grand\n") ; } printf ("au revoir\n") ; } |
Exemples d'execution de ce programme |
donnez un entier : 2 deux au revoir donnez un entier : 25 grand au revoir |
1. Ecrire le programme qui permet de lire un entier compris entre 1 et 7, désignant les jours de la semaine, et affiche le jour correspondant au chiffre saisi, sachant que 1 correspond à lundi. 2. Ecrire un programme C qui permet d'effectuer une opération arithmétique sur deux nombres saisis par l'utilisateur. Le type d'opération doit être indiqué par l'utilisateur. 3. Ecrire le programme qui permet à l'utilisateur de taper un caractère et indique si le caractère taper est un nombre ou la touche Escape (Esc: Echap) ou la touche Entré. |
Touche du clavier |
code ASCII en Décimale |
Entré |
10 |
Esc |
27 |
0 |
48 |
1 |
49 |
2 |
50 |
3 |
51 |
4 |
52 |
5 |
53 |
6 |
54 |
7 |
55 |
8 |
56 |
9 |
57 |
La première façon de réaliser une boucle (une itération) en C, à savoir l'instruction do... while.
do instruction while (expression) ; |
L’instruction est exécutée puis l’expression est évaluée. L'instruction do..while répète l'exécution de l'instruction qu'elle contient tant que la valeur de la condition exprimer dans (expression) est vraie.
#include<stdio.h> main() { int n ; do { printf ("donnez un nb >0 : ") ; scanf ("%d", &n) ; printf ("vous avez fourni %d\n", n) ; } white (n<=0) ; printf ("réponse correcte") ; } |
Exemples d'execution de ce programme |
donnez un nb >0 : -3 vous avez fourni -3 donnez un nb >0 : -9 vous avez fourni -9 donnez un nb >0 : 12 vous avez fourni 12 réponse correcte |
On ne sait pas a priori combien de fois une telle boucle sera répétée. Toutefois, de par sa nature même, elle est toujours parcourue au moins une fois. En effet, la condition qui régit cette boucle n'est examinée qu'à la fin de chaque.
la deuxième façon de réaliser une boucle conditionnelle, à savoir l'instruction while.
while (expression) instruction; |
L’expression est évaluée. Si sa valeur est VRAIE , l’instruction est alors exécutée. Puis l’expression est a nouveau évaluée.
L'instruction while répète alors l'instruction qui la suit tant que la condition mentionnée dans (expression) est vraie. comme le ferait do... while. Par contre, cette fois, la condition de poursuite est examinée avant chaque parcours de la boucle et non après. Ainsi, contrairement à ce qui se passait avec do... while, une telle boucle peut très bien n'être parcourue aucune fois si la condition est fausse dès qu'on l'aborde.
Ce programme permet de répéter la saisie de nombres entiers tant que leur somme est inférieure à 100.
#include<stdio.h> main() { int n, som ; som = 0 ; while (som<100) { printf ("donnez un nombre : ") ; scanf ("%d", &n) ; som += n ; } printf ("somme obtenue : %d", som) ; } |
Exemples d'execution de ce programme |
donnez un nombre : 15 donnez un nombre : 25 donnez un nombre : 12 donnez un nombre : 60 somme obtenue : 112 |
Etudions maintenant la dernière instruction permettant de réaliser des boucles, à savoir l'instruction for.
for ([expr1]; [expr2]; [expr3]) corps-de-boucle |
L'expression d'initialisation: expr1 est évaluée une seule fois, au début de l'exécution de la boucle.
L'expression de test d'arrêt: expr2 est évaluée et testée avant chaque passage dans la boucle, si elle est VRAIE le "corps-de-boucle" est exécutée.
L'expression d'incrémentation: expr3 est évaluée après chaque passage.
N.B. : les crochets ( [ et ] ) signifient que ce qu'ils renferment est facultatif.