VII. Solutions des exercices▲
VII-A. La lettre X (II-E-1)▲
Voici la solution la plus évidente et la plus lisible :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#include <stdio.h>
int
main
(
)
{
printf
(
"
* *
\n
"
);
printf
(
"
* *
\n
"
);
printf
(
"
*
\n
"
);
printf
(
"
* *
\n
"
);
printf
(
"
* *
\n
"
);
return
0
;
}
On peut cependant remarquer que les espaces après le dernier * de chaque ligne sont inutiles. De plus, rien ne nous oblige à faire un appel à printf pour chaque ligne. On peut faire tout le dessin avec un seul appel à cette fonction. Voici donc une autre solution, un peu moins éviddente que la première :
2.
3.
4.
5.
6.
7.
#include <stdio.h>
int
main
(
)
{
printf
(
"
* *
\n
* *
\n
*
\n
* *
\n
* *
\n
"
);
return
0
;
}
VII-B. Périmètre d'un rectangle (II-E-2)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#include <stdio.h>
#define LONGUEUR 100
#define HAUTEUR 60
int
perimetre
(
int
L, int
h);
int
main
(
)
{
printf
(
"
Le perimetre d'un rectangle de longueur %d et de hauteur %d est %d.
\n
"
,
LONGUEUR, HAUTEUR, perimetre
(
LONGUEUR, HAUTEUR)
);
return
0
;
}
int
perimetre
(
int
L, int
h)
{
return
2
*
(
L +
h);
}
Ayez l'habitude de représenter les valeurs figées par des macros. Cela permet d'avoir un code à la fois lisible et facilement maintenable : si un jour la spécification change, il suffit de changer les définitions des macros et non plusieurs parties du programme.
VII-C. Valeur absolue (III-G-1)▲
Il y a plusieurs façons d'y arriver. Voici deux exemples :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
#include <stdio.h>
int
main
(
)
{
double
x, y;
printf
(
"
Ce programme permet de determiner la valeur absolue d'un nombre.
\n
"
);
printf
(
"
Entrez un nombre :
"
);
scanf
(
"
%lf
"
, &
x);
if
(
x >=
0
)
y =
x;
else
y =
-
x;
printf
(
"
La valeur absolue de %f est : %f
\n
"
, x, y);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include <stdio.h>
int
main
(
)
{
double
x;
printf
(
"
Ce programme permet de determiner la valeur absolue d'un nombre.
\n
"
);
printf
(
"
Entrez un nombre :
"
);
scanf
(
"
%lf
"
, &
x);
printf
(
"
La valeur absolue de %f est : %f
\n
"
, x, (
x >=
0
? x : -
x));
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-D. Moyenne (III-G-2)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
#include <stdio.h>
int
main
(
)
{
int
note;
printf
(
"
Ce programme permet de determiner si vous avez eu la moyenne ou non.
\n
"
);
printf
(
"
Entrez votre note (0 a 20) :
"
);
scanf
(
"
%d
"
, &
note);
if
(
0
<=
note &&
note <=
20
)
{
if
(
note >=
10
)
printf
(
"
Vous avez eu la moyenne.
\n
"
);
else
printf
(
"
Vous n'avez pas eu la moyenne.
\n
"
);
}
else
printf
(
"
Cette note n'est pas valide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-E. L'heure dans une minute (III-G-3)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
#include <stdio.h>
int
main
(
)
{
int
h, m;
printf
(
"
Ce programme permet de determiner l'heure qu'il sera une minute plus tard.
\n
"
);
printf
(
"
Entrez l'heure actuelle :
"
);
scanf
(
"
%d
"
, &
h);
printf
(
"
Entrez la minute actuelle :
"
);
scanf
(
"
%d
"
, &
m);
m++
;
if
(
m ==
60
)
{
m =
0
;
h++
;
if
(
h ==
24
)
h =
0
;
}
printf
(
"
Dans une minute il sera : %02d:%02d
\n
"
, h, m);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-F. Rectangle (III-G-4)▲
Le programme a est complet. Pour les programmes b et c, seule la fonction main() est donnée
(les autres parties du programme restant inchangées par rapport à a).
a.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
#include <stdio.h>
void
affiche_car
(
char
c, int
n);
int
main
(
)
{
int
L;
printf
(
"
Ce programme dessine une ligne.
\n
"
);
printf
(
"
Entrez la longueur de la ligne (0 a 20) :
"
);
scanf
(
"
%d
"
, &
L);
if
(
0
<=
L &&
L <=
20
)
{
affiche_car
(
'
*
'
, L);
putchar
(
'
\n
'
);
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
void
affiche_car
(
char
c, int
n)
{
if
(
c >
0
&&
n >
0
)
{
int
i; /* i : nombres de caracteres deja affiches */
for
(
i =
0
; i <
n; i++
) /* on arrete des que i a atteint n */
putchar
(
c);
}
}
Vous ne vous attendiez certainement pas à ce que la valeur de c soit testée avant de le passer
à putchar. La raison est tout simplement que l'argument attendu par putchar est un int (qui doit avoir une valeur positive)
et non un char. Comme char peut faire référence à signed char, il vaut mieux tester la valeur du caractère reçu
avant de faire quoi que ce soit avec. putchar sera étudiée dans plus de détails dans le chapitre V.
b.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
int
main
(
)
{
int
L;
printf
(
"
Ce programme dessine un rectangle plein.
\n
"
);
printf
(
"
Entrez la longueur du rectangle (0 a 20) :
"
);
scanf
(
"
%d
"
, &
L);
if
(
0
<=
L &&
L <=
20
)
{
int
h;
printf
(
"
Entrez la hauteur du rectangle (0 a 20) :
"
);
scanf
(
"
%d
"
, &
h);
if
(
0
<=
h &&
h <=
20
)
{
/* On dessine h lignes (lignes 1 a h) */
int
i; /* i : numero de la ligne en cours */
for
(
i =
1
; i <=
h; i++
)
{
affiche_car
(
'
*
'
, L);
putchar
(
'
\n
'
);
}
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
c.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
int
main
(
)
{
int
L;
printf
(
"
Ce programme dessine un rectangle creux.
\n
"
);
printf
(
"
Entrez la longueur du rectangle (0 a 20) :
"
);
scanf
(
"
%d
"
, &
L);
if
(
0
<=
L &&
L <=
20
)
{
int
h;
printf
(
"
Entrez la hauteur du rectangle (0 a 20) :
"
);
scanf
(
"
%d
"
, &
h);
if
(
0
<=
h &&
h <=
20
)
{
int
i;
for
(
i =
1
; i <=
h; i++
)
{
/* Pour les lignes 1 et h, dessiner une ligne continue */
if
(
i ==
1
||
i ==
h)
affiche_car
(
'
*
'
, L);
else
{
/* Pour le reste, seules les extreimites sont visibles */
putchar
(
'
*
'
);
affiche_car
(
'
'
, L -
2
);
putchar
(
'
*
'
);
}
putchar
(
'
\n
'
);
}
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-G. Triangle isocèle (III-G-5)▲
Ici aussi, seule la fonction main() est donnée pour les mêmes raisons que dans VII-F.
a. Il faut juste remarquer qu'à la ligne i (i allant de 1 à h), il y a h - i espaces suivi de 1 + 2 * (i - 1) étoiles.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
int
main
(
)
{
int
h;
printf
(
"
Ce programme dessine un triangle.
\n
"
);
printf
(
"
Entrez la hauteur du triangle (0 a 20) :
"
);
scanf
(
"
%d
"
, &
h);
if
(
0
<=
h &&
h <=
20
)
{
int
i;
for
(
i =
1
; i <=
h; i++
)
{
affiche_car
(
'
'
, h -
i);
affiche_car
(
'
*
'
, 2
*
i -
1
);
putchar
(
'
\n
'
);
}
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
b.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
int
main
(
)
{
int
h;
printf
(
"
Ce programme dessine un triangle.
\n
"
);
printf
(
"
Entrez la hauteur du triangle (0 a 20) :
"
);
scanf
(
"
%d
"
, &
h);
if
(
0
<=
h &&
h <=
20
)
{
int
i, n, nb_etoiles; /* nb_etoiles : nombre d'etoiles deja affichees */
for
(
i =
1
, nb_etoiles =
0
; i <=
h; i++
)
{
n =
h -
i;
affiche_car
(
'
'
, n);
n =
2
*
i -
1
;
affiche_car
(
'
*
'
, n);
nb_etoiles +=
n;
putchar
(
'
\n
'
);
}
printf
(
"
Il y a %d etoile(s) affichee(s).
\n
"
, nb_etoiles);
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-H. Somme (III-G-6)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
#include <stdio.h>
int
main
(
)
{
int
n, saisis =
0
, fini =
0
, total =
0
;
printf
(
"
Ce programme permet de calculer une somme.
\n
"
);
printf
(
"
Entrez la liste des nombres a additionner (terminez en entrant 0).
\n
"
);
while
(!
fini)
{
scanf
(
"
%d
"
, &
n);
saisis++
;
total +=
n;
fini =
(
saisis ==
10
||
n ==
0
);
}
printf
(
"
Le total est : %d
\n
"
, total);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-I. Recherche dans un tableau (IV-D-1)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
#include <stdio.h>
int
main
(
)
{
int
t[10
], i, n, nb_occurrences =
0
;
printf
(
"
Ce programme permet de trouver toutes les occurrences d'un nombre.
\n
"
);
printf
(
"
Entrez 10 nombres :
\n
"
);
for
(
i =
0
; i <
10
; i++
)
{
printf
(
"
t[%d] :
"
, i);
scanf
(
"
%d
"
, t +
i);
}
printf
(
"
Entrez le nombre a rechercher :
"
);
scanf
(
"
%d
"
, &
n);
for
(
i =
0
; i <
10
; i++
)
{
if
(
t[i] ==
n)
{
printf
(
"
t[%d]
\n
"
, i);
nb_occurrences++
;
}
}
printf
(
"
%d occurrence(s) trouvee(s)
\n
"
, nb_occurrences);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-J. Calcul de la moyenne (IV-D-2)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
#include <stdio.h>
int
main
(
)
{
int
t[5
][3
], i, total_coefs =
0
, total_notes =
0
;
double
moyenne;
printf
(
"
Ce programme permet de calculer votre moyenne scolaire.
\n
"
);
for
(
i =
0
; i <
5
; i++
)
{
/* Saisie des notes */
printf
(
"
Note %d :
"
, i +
1
);
scanf
(
"
%d
"
, &(
t[i][0
]));
printf
(
"
Coef %d :
"
, i +
1
);
scanf
(
"
%d
"
, &(
t[i][1
]));
t[i][2
] =
t[i][0
] *
t[i][1
];
/* Calcul des totaux */
total_notes +=
t[i][2
];
total_coefs +=
t[i][1
];
}
moyenne =
((
double
)total_notes) /
total_coefs;
/* Affichage du resultat */
printf
(
"
+------+------+----------+
\n
"
);
printf
(
"
| Note | Coef | Note Def |
\n
"
);
printf
(
"
+------+------+----------+
\n
"
);
for
(
i =
0
; i <
5
; i++
)
{
printf
(
"
| %4d | %4d | %8d |
\n
"
, t[i][0
], t[i][1
], t[i][2
]);
printf
(
"
+------+------+----------+
\n
"
);
}
printf
(
"
| Tot. | %4d | %8d |
\n
"
, total_coefs, total_notes);
printf
(
"
+------+-----------------+
\n
"
);
printf
(
"
| Moy. | %15.2f |
\n
"
, moyenne);
printf
(
"
+------+-----------------+
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-K. Manipulation de chaînes (IV-D-3)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
char
*
str_cpy
(
char
*
dest, const
char
*
source)
{
int
i;
for
(
i =
0
; source[i] !=
'
\0
'
; i++
)
dest[i] =
source[i];
dest[i] =
'
\0
'
;
return
dest;
}
size_t str_len
(
const
char
*
t)
{
size_t len;
for
(
len =
0
; t[len] !=
'
\0
'
; len++
)
/* On ne fait rien, on laisse seulement boucler */
;
return
len;
}
int
str_equals
(
const
char
*
s1, const
char
*
s2)
{
int
i =
0
, equals =
1
;
while
(
equals &&
s1[i] !=
'
\0
'
&&
s2[i] !=
'
\0
'
)
{
if
(
s1[i] !=
s2[i])
equals =
0
;
i++
;
}
if
(
equals &&
(
s1[i] !=
'
\0
'
||
s2[i] !=
'
\0
'
))
equals =
0
;
return
equals;
}
Remarquez bien que nous avons choisi char * comme type de retour de str_cpy et non void. La valeur retournée n'est autre que la valeur du pointeur dest. Le prototype de str_cpy est strictement le même que celui de la fonction standard strcpy. Cela permet d'écrire du code compact lorsqu'on a envie, par exemple :
2.
char
s[50
];
strcat
(
strcpy
(
s, "
Bonjour
"
), "
tout le monde !
"
);
Le deuxième argument de la fonction (s2) est déclaré const char * et non simplement char *. En effet, les données pointées par s2 doivent être uniquement lues par la fonction, cette dernière ne doit pas avoir le droit de les modifier. L'ajout du qualificateur const ici est donc plus que recommandé. De plus, cela a un aspect documentaire : la présence ou l'abscence de const permet aux utilisateurs d'une fonction de savoir quelles données pourraient être modifiées par la fonction et quelles données seront justes lues.
VII-L. Calcul de la moyenne (version 2) (VI-C-1)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
#include <stdio.h>
#include <stdlib.h>
typedef
int
NOTE[3
];
int
main
(
)
{
int
n;
printf
(
"
Ce programme permet de calculer votre moyenne scolaire.
\n
"
);
printf
(
"
Entrez le nombre de notes que vous voulez entrer :
"
);
scanf
(
"
%d
"
, &
n);
if
(
n >
0
)
{
NOTE *
t =
malloc
(
n *
sizeof
(
NOTE));
if
(
t !=
NULL
)
{
int
i, total_coefs =
0
, total_notes =
0
;
double
moyenne;
for
(
i =
0
; i <
n; i++
)
{
printf
(
"
Note %d :
"
, i +
1
);
scanf
(
"
%d
"
, &(
t[i][0
]));
printf
(
"
Coef %d :
"
, i +
1
);
scanf
(
"
%d
"
, &(
t[i][1
]));
t[i][2
] =
t[i][0
] *
t[i][1
];
total_notes +=
t[i][2
];
total_coefs +=
t[i][1
];
}
moyenne =
((
double
)total_notes) /
total_coefs;
printf
(
"
+------+------+----------+
\n
"
);
printf
(
"
| Note | Coef | Note Def |
\n
"
);
printf
(
"
+------+------+----------+
\n
"
);
for
(
i =
0
; i <
n; i++
)
{
printf
(
"
| %4d | %4d | %8d |
\n
"
, t[i][0
], t[i][1
], t[i][2
]);
printf
(
"
+------+------+----------+
\n
"
);
}
free
(
t);
printf
(
"
| Tot. | %4d | %8d |
\n
"
, total_coefs, total_notes);
printf
(
"
+------+-----------------+
\n
"
);
printf
(
"
| Moy. | %15.2f |
\n
"
, moyenne);
printf
(
"
+------+-----------------+
\n
"
);
}
else
printf
(
"
Le tableau n'a pas pu etre cree.
\n
"
);
}
else
printf
(
"
Cette valeur est invalide.
\n
"
);
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
VII-M. Recherche dans un tableau (version 2) (VI-C-2)▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef
char
*
PCHAR;
size_t get_string
(
char
*
lpBuffer, int
nBufSize);
int
main
(
)
{
int
n;
char
s[21
];
printf
(
"
Ce programme permet de trouver toutes les occurrences d'une chaine.
\n
"
);
printf
(
"
Combien de chaines voulez-vous entrer ?
"
);
scanf
(
"
%d
"
, &
n);
get_string
(
s, sizeof
(
s)); /* Pour purger stdin */
if
(
n >
0
)
{
PCHAR *
t =
malloc
(
n *
sizeof
(
PCHAR));
if
(
t !=
NULL
)
{
int
i, nb_occurrences =
0
, succes =
1
;
printf
(
"
Entrez %d chaines de caracteres (20 caracteres par chaine au plus) :
\n
"
, n);
for
(
i =
0
; succes &&
i <
n; i++
)
{
size_t len;
printf
(
"
t[%d] :
"
, i);
len =
get_string
(
s, sizeof
(
s));
t[i] =
malloc
(
len +
1
);
if
(
t[i] !=
NULL
)
strcpy
(
t[i], s);
else
{
int
j;
for
(
j =
0
; j <
i; j++
)
free
(
t[j]);
succes =
0
;
printf
(
"
Memoire insuffisante pour continuer.
\n
"
);
}
}
if
(
succes)
{
printf
(
"
Entrez la chaine a rechercher :
"
);
get_string
(
s, sizeof
(
s));
for
(
i =
0
; i <
n; i++
)
{
if
(
strcmp
(
t[i], s) ==
0
)
{
printf
(
"
t[%d]
\n
"
, i);
nb_occurrences++
;
}
free
(
t[i]);
}
printf
(
"
%d occurrence(s) trouvee(s)
\n
"
, nb_occurrences);
}
free
(
t);
}
else
printf
(
"
Le tableau n'a pas pu etre cree.
\n
"
);
}
printf
(
"
Merci d'avoir utilise ce programme. A bientot !
\n
"
);
return
0
;
}
size_t get_string
(
char
*
lpBuffer, int
nBufSize)
{
size_t len =
0
;
if
(
fgets
(
lpBuffer, nBufSize, stdin) !=
NULL
)
{
char
*
p;
len =
strlen
(
lpBuffer);
p =
lpBuffer +
len -
1
;
if
(*
p ==
'
\n
'
)
{
*
p =
'
\0
'
; /* on ecrase le '\n' */
len--
;
}
else
{
/* On vide le tampon de lecture du flux stdin */
int
c;
do
c =
getchar
(
);
while
(
c !=
EOF &&
c !=
'
\n
'
);
}
}
return
len;
}