Documente Academic
Documente Profesional
Documente Cultură
A) Les 3 boucles en C :
1) Boucle do ... while ... (Rpter .... Tant que) :
1.a) Syntaxe :
do
instruction rpter
while (condition de continuer rpter (boucler) encore);
L'instruction rpter peut tre simple (une seule action),
structure (une autre instruction de contrle) ou compose
(c'est le cas le plus frquent).
1.b) Fonctionnement :
tape 1 : effectuer (d'abord) l'instruction rpter
tape 2 : vrifier (aprs) la condition de continuer :
a) si la condition est vraie, on revient
l'tape 1
b) si non (la condition est fausse), on
termine la boucle
Attention :
Contrairement au langage PASCAL, la condition de cette boucle
est la condition pour continuer rpter encore. En
Pascal, c'est la condition d'arrter la boucle.
Page 27
age ;
sexe,
reponse ; /* Oui ou Non l'usager veut continuer */
do
{ printf("\nEntrez le sexe et l'ge ");
scanf("%c%d", &sexe, &age);
printf("C'est un ");
if (age <= 11)
printf("enfant ");
else
if (age < 18 )
printf("adolescent ") ;
else
printf("adulte ");
if ( toupper(sexe) == 'F' ) /* to upper : en majuscule*/
printf("de sexe fminin\n");
else
printf("de sexe masculin\n");
printf("\nVoulez-vous continuer ? (O/N) ");
fflush(stdin);
reponse = toupper (getchar());
}
while ( reponse == 'O' );
Page 28
2. Validation de donnes :
crire un bloc d'instructions permettant de saisir et
valider l'ge d'une personne (un entier situ entre 1 et 125).
Solution :
const int MAXI = 125 ;
int age,
valide ; /* Oui ou non l'ge est valide */
do
{ printf("Entrez l'ge entre 1 et %d
", MAXI);
scanf("%d", &age);
valide = (age >= 1 && age <= MAXI) ;
if ( !valide )
printf("age lu est hors intervalle, retapez S.V.P.\n");
}
while (!valide);
Attention :
La validation d'un type (entier ou non, rel ou non) sera prsente
au chapitre 3 (chanes des caractres).
3. Calcul scientifique :
Exemple 1 :
crire un bloc d'instructions permettant de calculer et
d'afficher la somme suivante :
somme =
10 + 15 + 20 + 25 + ... + 50
Solution :
const int BORNE1 = 10 ,
BORNE2 = 50 ,
LE_PAS = 5 ;
int
terme, somme ;
somme = 0 ;
terme = BORNE1 ;
Page 29
do
{ somme += terme ;
terme += LE_PAS;
}
while (terme <= BORNE2);
printf("La somme calcule est : %d\n", somme);
Exemple 2 :
crire un programme permettant d'estimer la valeur
de PI (3.141....) selon la formule suivante :
PI
----- = 1 - 1/3 + 1/5 - 1/7 + 1/9 + ....
4
1/9999
Solution :
/* Fichier PI.A95 */
#include <stdio.h>
void main()
{
const int LIMITE = 9999 ,
LE_PAS =
2 ;
int
denominateur
= 1
Excution :
La valeur estime de PI est
3.141397
Page 30
Attention :
On utilise souvent cette boucle pour estimer une racine de
l'quation f(x) = 0, pour la recherche squentielle d'un
lment dans un tableau (plus tard dans le cours), etc ....
1.d) Exercices :
Exercice 1 :
crire un programme permettant de saisir et de valider si un
entier lu est positif ou non. Ensuite, on affiche l'entier tel
que lu et l'envers (ici 4327).
Solution :
/* Fichier : Envers1.C */
#include <stdio.h>
void main()
{ int n
;
/* Saisie et valider : */
do
{
printf("Entrez un entier positif ");
scanf("%d", &n);
if ( n < 0 ) printf("n = %d est ngatif\n", n);
}
while (n < 0);
printf("L'entier lu :
%d\n", n);
printf("A l'envers
");
do
{ printf("%d", n % 10);
n /= 10 ;
}
while
( n > 0 );
printf("\n\nAppuyez sur Entre ");
fflush(stdin);
getchar();
}
Page 31
Excution :
Entrez un entier positif -8742
n = -8742 est ngatif
Entrez un entier positif 5329
L'entier lu : 5329
A l'envers : 9235
Appuyez sur Entre
Exercice 2 :
crire un programme permettant de saisir un entier positif
(exemple 5426). Il calcule l'envers du nombre lu (ici 6245)
et affiche ces deux valeurs.
Solution :
/* Fichier Envers2.C
*/
#include <stdio.h>
void main()
{ int n , envers
n = %d\n", n);
/* Calcul de l'envers : */
envers = 0 ;
do
{ envers = 10 * envers + n % 10 ;
n /= 10 ;
}
while ( n > 0 ) ;
printf("A l'envers
%d", envers);
Page 32
Excution :
Entrez un entier positif 1234
L'entier lu
n = 1234
A l'envers : 4321
Appuyez sur Entre
Exercice 3 :
crire un programme permettant de saisir les informations d'un
placement :
- le capital (un rel)
- le taux d'intrt (compos) annuel en %
- la dure du placement en nombre de mois.
Le programme calcule et affiche le capital la fin du terme.
Il fonctionne aussi pour plusieurs clients jusqu' ce que l'usager
dcide de quitter.
Exercice 4 :
crire un programme permettant de saisir et de valider d'un
entier positif (exemple n = 624). Le programme calcule et
affiche l'cran la somme des chiffres qui forment l'entier
lu (ici, la somme des chiffres est 12 = 6 + 2 + 4).
Exercice 5 (scientifique) :
crire un programme permettant de trouver toutes les racines
de l'quation f(x) = 0, o :
3
f(x) = x
- 19x + 30
( Thorme en mathmatique :
Si f est continue dans l'intervalle ]a, b[ (exemple :]0, 2.5[)
et f(a) * f(b) < 0, alors : il y a au moins une racine de
f(x) = 0 dans ]a, b[ )
Page 33
2.b) Fonctionnement :
tape 1 : vrifier d'abord la condition
tape 2 : si la condition vaut vraie alors
a) on effectue l'instruction rpter
b) on revient l'tape 1
si non, on quitte la boucle
:
:
:
while ( !feof(aLire) )
fscanf(aLire, .......) ;
fclose(aLire) ;
Page 34
Solution :
/* Fichier : WHILE1.A95 */
#include <stdio.h>
void main()
{
const int BORNE = 10 ;
int n
, nbFois = 0 ;
FILE * aLire ;
/* dclaration du fichier */
fclose(aLire);
Page 35
valide = n > 0 ;
if (!valide)
printf("valeur ngative, retapez, S.V.P.\n\n");
Page 36
Excution :
Entrez un entier suprieur zro -5678
valeur ngative, retapez, S.V.P.
Entrez un entier suprieur zro 8736
L'entier lu est 8736
La somme des chiffres de n = 8736 est
24
1/9999
Page 37
3.a) Syntaxe :
for
(<exp1>;<exp2>;<exp3>) instruction
3.b) Fonctionnement :
Initialiser la variable de contrle de la boucle
Tant que la condition de continue vaut vraie Faire
- effectuer l'instruction rpter
- incrmenter ou dcrmenter la variable de contrle
Page 38
Exercice 3 :
Donner une autre solution de l'exercice 2 en remplaant le
if par un switch.
Exercice 4 :
crire un bloc d'instruction permettant de calculer et
d'afficher la somme suivante :
somme = 1 + 1/2 + 1/3 + ... + 1/1000
Page 39
Solution :
const int BORNE1 =
1 ,
BORNE2 = 999 ;
int denominateur;
float somme = 0 ;
for ( denominateur = BORNE1 ; denominateur <= BORNE2 ;
denominateur = denominateur + 1 )
somme += 1.0 / denominateur ;
printf("La somme demande : %10.6f\n", somme);
Exercice 5 :
crire un bloc d'instructions utilisant la boucle for qui permet
d'estimer la valeur de PI selon la formule suivante :
PI
----- = 1 - 1/3 + 1/5 - 1/7 + 1/9 + ....
4
1/9999
Observations :
En premire vue, les dnominateurs ne sont pas conscutifs :
1
9 ...
9999
(2 * 1 + 1) (2 * 2 + 1)
3
5
.... ( 2 * 4999 + 1)
9999
Page 40
Notes :
Dans l'incrmentation de la variable k de la boucle for, on
utilise trs souvent k++ la place de k = k + 1.
++ est l'oprateur de post-incrmentation (utiliser d'abord
la valeur, incrmenter aprs avoir utilis la valeur) :
Exemples :
1.
int k = 5 ;
printf("k = %d\n", k); /* afficher 5 */
k++ ; /* incrmenter k, k vaut 6 */
printf("k = %d\n", k); /* afficher 6 */
2.
int k = 5 ;
if ( k++ )
printf("k = %d\n", k);
Cette instruction affiche k = 6 l'cran.
En effet, avec if ( k++ ) on a 2 actions :
a) if (5) , comme 5 est non nul => if (vrai)
b) k est incrment => k vaut 6
L'instruction printf... fait afficher la valeur 6 de k.
4 3 2 1
3 2 1
2 1
1
Solution :
#define NB_LIGNE 5
int L, C ;
/* Pour L varie de 5 en descendant 1 faire */
for ( L = NB_LIGNE ; L >= 1 ; L-- )
{ for ( C = L ; C >= 1 ; C-- ) printf("%2d", C);
printf("\n");
}
Chapitre 2 : Boucles de rptitions et fonctions
Page 41
f(A) + f(B)
= h [ -----------2
n-1
f( A + ih ) ]
i= 1
1
--- dx
1
x
| e
(Thoriquement, c'est
Log(x) |
= Log(e) - Log(1) = 1 - 0 = 1)
| 1
Exercice 8 :
Parmi les entiers entre 100 et 500, seuls 4 nombres peuvent tre
reprsents par la somme des cubes de leurs chiffres.
crire un bloc d'instructions pour dcouvrir et afficher ces
nombres.
Solution :
#define BORNE1 100
#define BORNE2 500
int nombre, sommeCube , valeur, Chiffre ;
for ( nombre = BORNE1 ; nombre < BORNE2 ; nombre++ )
{
valeur
= nombre ;
sommeCube = 0 ;
while ( valeur > 0 )
{
Chiffre
= valeur % 10 ;
sommeCube = sommeCube + Chiffre * Chiffre * Chiffre ;
valeur
= valeur / 10 ;
}
if ( nombre == sommeCube )
printf("nombre = %5d, somme des cubes de ses chiffres = %5d\n",
nombre, sommeCube);
}
Chapitre 2 : Boucles de rptitions et fonctions
Page 42
Exercice 9 :
Un nombre parfait est un nombre entier qui est gal la somme de
ses diviseurs propres (sauf lui-mme).
Exemples:
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
1 2)
2
etc ....
3)
4)
5)
Solution :
#include <stdio.h>
void main()
{
#define NOMBRE
720
#define PAR_ECRAN
5
Page 43
B) Adresses vs Pointeurs :
1) Domaines d'utilisation :
On utilise trs souvent les adresses dans :
1. la saisie des donnes avec scanf ;
2. les appels des fonctions pour recevoir des valeurs retournes ;
On utilise des pointeurs dans :
1. la transmission des arguments par pointeurs (rsultats de
retour) ;
2. la manipulation des tableaux ;
3. les fichiers :
Page 44
2. a) Les adresses :
En C, on ajoute un caractristique de plus une variable :
son adresse (son emplacement en mmoire) dtermine par
l'oprateur & (adresse de)
L'adresse d'une variable est dtermine souvent la compilation
de la manire squentielle :
a
x
d
c
=
=
=
=
void main()
{
printf("Nom
printf("---
5, b = 23 ;
123.4
;
'V'
;
100
;
Type
-------
Nb. octets
----------
Adresse
-----------
valeur\n");
--------\n");
printf(" a
int
%d
sizeof(a), &a, a);
%u
%d\n",
printf(" b
int
%d
sizeof(b), &b, b);
%u
%d\n",
printf(" x
float
%d
sizeof(x), &x, x);
%u
%6.2f\n",
printf(" d
char
%d
sizeof(char), &d, d);
%u
%c\n",
printf(" c
int
%d
sizeof(int), &c, c);
%u
%d\n",
Page 45
Excution :
L'excution du programme avec TURBO C++ sur un IBM PS/2 donne
ce qui suit :
Nom
--a
b
x
d
c
Type
------int
int
float
char
int
Nb. octets
---------2
2
4
1
2
Adresse
----------170
172
174
178
179
valeur
-------5
23
123.40
V
100
d
c
valeur
(en binaire)
23
123.4
'V'
100
Adresse
170
(adresse du dbut de a)
171
172
(adresse du dbut de b)
173
174
(adresse du dbut de x)
175
176
177
178
(adresse du dbut de d)
179
(adresse du dbut de c)
180
Page 46
dont :
2. b) Les pointeurs :
La valeur d'une variable entire est un entier :
int age = 23 ;
La valeur d'une variable de type rel est un rel : float Poids = 62.0 ;
La valeur d'un pointeur est une adresse.
a
*P
x
*Z
=
=
=
=
15, b = 23
&b, S = &a
123.4
&x
;
; /* 2 pointeurs vers le type int */
;
; /* Z, pointeur vers le type float */
void Continuer()
{ printf("\n\nAppuyez sur Entre ");
fflush(stdin);
getchar();
}
Page 47
void Demo1()
{
printf("Premire dmonstration:\n\n");
printf("Nom
printf("---
Type
-------
Nb. octets
----------
Adresse
-----------
valeur\n");
--------\n");
printf(" b
int
%d
sizeof(b), &b, b);
%u
%d\n",
printf(" P
int *
%d
sizeof(P), &P, P);
%u
%u\n\n",
printf(" x
float
%d
sizeof(x), &x, x);
%u
%6.2f\n",
printf(" Z
float *
%d
sizeof(Z), &Z, Z);
%u
%u\n",
printf("\constatations :\n\n");
printf("
printf("
printf("
printf("
printf("
printf("
printf("
printf("
Continuer();
void main()
{ Demo1();
}
Excution :
L'excution du programme avec TURBO C++ sur un IBM PS/2 donne
ce qui suit :
Premire dmonstration:
Nom
--b
P
x
Z
Type
------int
int *
float
float *
Nb. octets
---------2
2
4
2
Adresse
----------172
174
178
182
valeur
-------23
172
123.40
178
Page 48
Constatations :
1. valeur d'un pointeur est une adresse :
- valeur du pointeur P (172) est l'adresse de b (172)
- valeur du pointeur Z (178) est l'adresse de x (178)
2. Plusieurs manires pour les valeurs de *P et de *Z :
*P
*Z
*P
*Z
= Le contenu
= Le contenu
=
23 *(&b)
= 123.40 *(&x)
l'adresse
l'adresse
=
23
= 123.40
172 = 23
178 = 123.40
b =
23
x = 123.40
Notes :
Pour le bon droulement du cours, on se limite aux explications
suivantes concernant un pointeur :
Soit T le nom d'un type (exemple int, char, float, ...)
1. Dclaration :
2. Consquences:
p ;
C) Les fonctions en C :
En C, il n'existe qu'une seule sorte de sous-programme : la fonction.
Page 49
1.a) Syntaxe :
type du rsultat de retour nom de la fonction( liste de paramtre(s))
{ dclarations locales si ncessaire
calcule et retourne (avec return) le rsultat calcul
1.b) Remarques :
1. Le nom de la fonction ne contient pas de rsultat de retour
comme le PASCAL.
2. Il faut utiliser le rsultat retourn dans un bon contexte
(affichage, affectation, comparaison, ...).
3. L'instruction "return" provoque la fin de la fonction, on
revient la place qui appelle la fonction.
4. Sur l'en-tte, on ne peut pas grouper les paramtres de mme
type :
float
plusGrand ( float x, y )
/* erron! */
/* erron! */
1.c) Exemples :
Exemple 1 (fonction qui retourne un entier comme rsultat) :
crire un programme permettant de saisir un entier N suprieur
zro. Le programme calcule (par les fonctions) et affiche l'cran :
- la somme des chiffres du nombre n
- l'envers du nombre n
Page 50
Solution :
/* Fichier : Fonct1.A95 */
#include <stdio.h>
int sommeChiffre ( int n )
{ int somme = 0 ;
while (n)
{ somme += n % 10 ;
n
/= 10
;
}
return somme ;
}
int envers ( int n )
{ int K = 0 ;
while (n)
{ K = K * 10 + n % 10 ;
n /= 10;
}
return K ;
}
void main()
{ int nombre ;
printf("Entrez un entier > 0
scanf("%d", &nombre);
");
Excution:
Entrez un entier > 0 875
La somme des chiffres de 875 est 20
L'envers du nombre 875 est 578
Appuyez sur Entre
Exemple 2 (fonction qui retourne un rel comme rsultat) :
crire une fonction permettant de calculer le bonus dpendant
du poste de travail :
poste 'A' (analyste)
: 234.5
poste 'P' (programmeur) : 210.9
poste 'O' (oprateur)
: 189.0
crire quelques appels (utilisations)
Chapitre 2 : Boucles de rptitions et fonctions
$ de bonus
$ de bonus
$ de bonus
valides de cette fonction.
Page 51
Solution :
float bonus ( char poste )
{ float boni ;
switch ( toupper(poste) )
{
case 'A' : boni = 234.5 ; break ;
case 'P' : boni = 210.9 ; break ;
case 'O' : boni = 189.0 ;
}
return boni ;
Page 52
Solution :
char majuscule ( char c )
{
if ( c >= 'a' && c <= 'z' ) /* lette minuscule */
return c + 'A' - 'a' ; /* code ASCII
else
*/
return c ;
}
Une utilisation valide :
printf("Le caractre %c en majuscule est %c\n", 'e', majuscule ('e') );
toupper(lettre) )
'A'
'E'
'I'
'O'
'U'
'Y'
default
:
:
:
:
:
: reponse = 1 ; /* VRAI */
break ;
: reponse = 0 ; /* Faux */
}
return reponse ;
}
L'affichage des 20 consonnes en majuscules l'cran se fait comme
suit :
char lettre ;
for ( lettre = 'A' ; lettre <= 'Z' ; lettre++ )
if ( !voyelle(lettre) ) printf("%c", lettre) ;
printf("\n\n");
Chapitre 2 : Boucles de rptitions et fonctions
Page 53
Remarque :
Pour la clart, on peut aussi utiliser les #define dans le cas des
fonctions boolennes. Exemple : crire une fonction qui retourne
vrai ou faux selon qu'un entier n >= 2 est premier (a 2 diviseurs
seulement : 1 et n) ou non.
int Premier ( int n )
{
#define VRAI 1
#define FAUX 0
int k ;
for ( k = 2 ; k <= n / 2 ; k++ )
if ( n % k == 0 ) return FAUX ;
return VRAI ;
}
Simulation :
1. Avec n = 7 par exemple :
k = 2
k = 3
n % k vaut 1
n % k vaut 1
Page 54
int main()
{
........
return 1 ;
.......
}
2.a) Syntaxe :
void nom de la fonction ( liste de paramtre(s) )
{ dclarations locales
2.b) Exemples :
Cas 1 :
Quand on utilise des rsultats l'intrieur du corps d'une fonction,
on n'a que des paramtres transmis par valeur.
Exemple :
crire
nombre
crire
de 720
Page 55
Solution :
void compter ( int n )
{ int k = 1 , /* n est un diviseur de lui-mme */
i
; /* boucle for
*/
for ( i = 1 ; i <= n / 2 ; i++ )
if ( n % i == 0 ) k++ ;
printf("Le nombre de diviseurs de %d est %d\n", n, k);
}
Appels :
compter(720);
compter(984);
Exercice :
Un nombre parfait est un nombre entier qui est gal la somme de
ses diviseurs propres (sauf lui-mme).
Exemples:
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
return n == sommeDivPropre ;
Page 56
void main()
{
const int BORNE1 =
2 ,
BORNE2 = 500 ;
int nombre, compteur = 0 ;
printf("Voici les nombres parfaits entre %d et %d\n\n",
BORNE1, BORNE2 );
for ( nombre = BORNE1 ; nombre <= BORNE2 ; nombre++ )
if ( estParfait (nombre) )
{
printf("%3d) ", ++compteur);
}
afficher (nombre) ;
Excution du programme :
Voici les nombres parfaits entre 2 et 500
1)
2)
3)
6 = 1 +
28 = 1 +
496 = 1 +
2 +
2 +
2 +
3
4 +
4 +
7 +
8 +
14
16 +
31 +
62 + 124 + 248
Cas 2 :
La fonction calcule et retourne des rsultats travers des paramtres
transmis par pointeur.
Page 57
5.67
62000
P----------> 5.67
x
2. valeur de P est 62000 (adresse de x).
3. *P est de type float. Sa valeur est le contenu l'adresse
62000, ici c'est 5.67
On reviendra aux notions adresses et pointeurs au chapitre 3 (les
tableaux et les chanes de caractres).
Page 58
Exemples d'illustration :
1.
float b, float * P )
la plus petite valeur */
;
;
Utilisation :
float x, y , plusPetit ;
printf("Entrez 2 rels ");
scanf(&x, &y);
calculer (x, y, &plusPetit);
printf("La plus petite valeur est %8.2f\n", plusPetit);
Explications :
Supposons que x vaut 5.2, y vaut 3.4 et l'adresse de plusPetit
est 50000.
Avec l'appel :
On transmet la fonction :
void calculer ( float a, float b, float * P )
1. la valeur 5.2 a
2. la valeur 3.4 b
3. la valeur 50000 P :
52000
???
plusPetit
Adresse
52000
On excute la fonction :
if ( a < b ) *P = a ;
else
*P = b ;
Comme a < b est faux, on a : *P = b ;
C'est--dire : dposer l'adresse "52000" la valeur 3.4.
3.4
plusPetit
Page 59
temporaire = *p ;
*p
= *s ;
*s
= temporaire ;
Utilisation :
int a, b ;
printf("Entrez 2 entiers ");
scanf("%d%d",&a, &b);
printf("Avant l'change, a = %3d, b = %3d\n", a, b);
echanger (&a, &b ) ;
printf("Aprs l'change, a = %3d, b = %3d\n", a, b);
Explications :
Supposons que a vaut 15, b vaut 7 et l'adresse de a est 48000
et l'adresse de b est 48002.
Avec l'appel :
On transmet la fonction :
1. la valeur 48000 P
2. la valeur 48002 S
48000
48002
On excute la fonction :
temporaire = *p ; ===> temporaire vaut 15
*p
= *s ; ===> Le contenu l'adresse 48000 est
celui l'adresse 48002
Adresse
48000
a
Chapitre 2 : Boucles de rptitions et fonctions
Adresse
48002
b
Page 60
*s
15
Adresse
48002
k , valeur ;
* chaine
; /* une chane des caractres */
chaine = "abcdef" ;
valeur = atoi(chaine) ; /* alphabetic to integer */
printf("valeur = %d\n", valeur) ; /* valeur vaut zro, choue! */
chaine = "573" ;
valeur = atoi(chaine) ; /* alphabetic to integer */
printf("valeur = %d\n", valeur) ; /* valeur vaut 573, correct! */
Page 61