Exercices de programmation en C
Exercices de programmation en C
Dr Alun Moon
Janvier 2007
Abstrait
Instructions : Effectuez les exercices. La première section est un ensemble général de problèmes pour vous aider à vous souvenir
de ce que vous savez sur la programmation. Les sections suivantes détaillent certaines parties de C. Si vous êtes bloqué dans une
section, réessayez, puis passez à la section suivante et revenez plus tard.
Les lectures importantes incluent (McGrath 2006) une bonne introduction à C. (Kernighan & Ritchie 1988) est le livre sur la norme
C89 pour ANSI C. (Holmes 1995) est un très bon didacticiel Internet et une référence.
1 Exemples généraux
Il s’agit d’exercices généraux de complexité variable. Un bon moyen de rafraîchir la mémoire du C et de développer des compétences
en résolution de problèmes.
Exercice. 1.1 Écrivez et exécutez le programme « hello, world ! ». Expérimentez différents formats de sortie en insérant des nouvelles
lignes et des tabulations dans la chaîne de contrôle.
Exercice. 1.2 Écrivez un programme pour générer un entier au format décimal et un nombre à virgule flottante au format float.
Expérimentez la sortie d'un entier au format flottant et vice versa. Affiche un caractère au format décimal (imprime le code du
caractère, par exemple ascii). Résolvez tous les problèmes en utilisant une coercition ou un cast de type explicite.
Exercice. 1.3 Écrivez un programme pour déterminer, par essais et erreurs, la valeur minimale de 196/n + n où n est un entier.
N'utilisez pas de boucle, essayez différentes valeurs de n. Notez qu'en général 196/n + n sera une quantité flottante.
Exercice. 1.4 Écrivez un programme pour vérifier que le volume et l'aire de surface d'une sphère de rayon 0,1234567789e2 sont
respectivement d'environ 7881,948508 et 1915,313445. Le volume d'une sphère est égal à quatre tiers de Pi fois le rayon au cube et
l'aire est égale à quatre Pi fois le rayon au carré. Considérez que Pi est égal à 3,14159265.
Exercice. 1.5 Un nombre est spécial s’il est divisible (sans reste) par 15. Un nombre est grand s'il est supérieur à 999. Un nombre est
étrange s’il est divisible par 5 et 6 mais pas par 18. Un nombre fait peur s’il est grand ou étrange.
Écrivez un programme pour vérifier lesquels des nombres suivants, 450, 540, 600 et 675, sont spéciaux mais pas effrayants.
Déclarez quatre variables appelées spéciale, grande, étrange et effrayante et attribuez-leur des affectations appropriées au fur et
à mesure qu'un nombre est testé.
Exercice. 1.6 Écrivez un programme pour exprimer un nombre donné de secondes (qui peut être un littéral dans le programme) en
termes d'heures, de minutes et de secondes et affichez le résultat. Utilisez des variables distinctes pour des quantités distinctes. Par
exemple, pour représenter le nombre total de secondes qui peut être supérieur à 59 et la partie secondes de la sortie qui ne peut
jamais être supérieure à 59.
Exercice. 1.7 Écrivez un programme pour stocker et extraire indépendamment deux entiers courts de 16 bits (appelés car et cdr)
dans un entier de 32 bits (appelé cell). Tous les entiers sont positifs.
cellule
voiture cdr
Le stockage ou l’accès à un numéro ne doit pas affecter l’autre. Par exemple, si la cellule contient une valeur car de 2 et une
valeur cdr de 3, alors la valeur de la cellule est 131075 (hex 00020003). Si la valeur de la voiture est ensuite stockée dans la cellule,
la valeur de la cellule devient 65539 (hex 00010003).
Commencez par déclarer des entiers appropriés et initialisez-les. Écrivez des fonctions pour définir et extraire les valeurs de car
et cdr.
Écrivez une version du programme précédent en utilisant une structure avec les champs car et cdr.
Testez les deux avec divers exemples de voiture et de cdr.
1
Exercice. 1.8 Écrire des fonctions en utilisant des expressions conditionnelles,
2 Chaînes et E/S
Exercice. 2.1 Considérez le programme
• mot[1]='e' ;
• mot[3]='d';
• mot[4]='\n';
Exercice. 2.2 Écrivez un programme pour écrire les arguments de chaîne dans main dans l'ordre inverse.
Exercice. 2.3 Un argument de main est soit une option, soit un mot. Une option commence par un trait d'union '-', la partie restante est
le nom de l'option.
Écrivez un programme pour examiner chaque argument et imprimer s'il s'agit d'une option ou d'un mot, ainsi que le nom de
l'option ou la valeur du mot. Un exemple de sortie est présenté ci-dessous.
option: version
mot : 1.5.a
Exercice. 2.4 scanf divise naturellement son entrée au niveau des espaces (voir la page de manuel). En utilisant ce fait, écrivez un
programme qui compte les mots lus à partir de l'entrée standard. Astuce : lisez la page de manuel de scanf, consultez la section
« VALEUR DE RETOUR » pour savoir comment terminer la boucle.
2
3 caractères et chaînes
Les ordinateurs représentent les caractères avec des chiffres, chaque chiffre représentant une lettre de l'alphabet. Le système le plus
courant est ASCII, dans lequel « A » est 65, « B » est 66, « C » est... Les lettres majuscules sont comprises entre 65 et 90, et les
lettres minuscules sont comprises entre 32 et 97, soit entre 122 et 128. En C, les individus peuvent être stockés dans un type de
données char. Les valeurs peuvent être écrites sous la forme de la lettre entre guillemets simples « A ». Alternativement, le nombre
peut être écrit, auquel cas la valeur doit être convertie en un type char.
Les affirmations suivantes sont équivalentes
c = 'A' ; c = ( char ) 65 ;
En plus des caractères imprimables, il existe des codes ascii pour les caractères « spéciaux », dont certains sont 0 '\n'
caractère nul (terminateur de chaîne)
7 '\un'cloche (bip)
9 '\t'onglet horizontal
13 '\r'retour
3.1 Personnages
Exercice. 3.1 Le programme suivant imprime l'alphabet de A à Z. Copiez, compilez et exécutez le programme.
#include < st di o . h> principal ()
{
char i ;
pour ( i='A' ; i<='Z ' ; ++i ) putchar( i ) ;
Exercice. 3.2 Copiez, compilez et exécutez le programme suivant. Il prend ses entrées de la même manière que cat (sauf qu'il ne lit
pas les fichiers). Si vous lisez à partir du clavier, il faut au moins un retour chariot et un contrôle-D pour terminer la saisie. Cela est dû
à la manière dont le noyau met en mémoire tampon les entrées, et non à la manière dont le programme lit les données.
#inclure<st dio . h>
principal ()
{
caractère c ;
c = getchar() ;
tandis que ( c != EOF ) {
si ( 'A ' <= c && c <= ' Z ' )
c = c + 32 ;
putchar(c); c = getchar();
3
}
}
3.2 Cordes
Les chaînes en C sont stockées sous la forme d'une séquence de codes ASCII (tableau de caractères) terminée par un caractère
nul \0. La chaîne « hello-world » comporte 11 caractères visibles, mais nécessite 12 emplacements de stockage pour les 11
caractères et le caractère nul.
a[26] = '\0';
imprimerf (a);
}
Le programme essaiera toujours d'imprimer les lettres « A »... « Z ». Avec le zéro, la sortie s'arrête. Sans le zéro, le programme
continue, en imprimant tout ce qui se trouve en mémoire – des caractères aléatoires, jusqu’à ce qu’un octet zéro soit atteint.
Dans un programme C, une valeur de chaîne peut être écrite en utilisant des guillemets doubles ", le compilateur allouera la
mémoire et ajoutera l'octet zéro. Les fonctions d'entrée fgets et le champ %s dans scanf ajoutent également l'octet zéro. Il existe un
certain nombre de fonctions permettant de fournir des informations sur des chaînes ou de les manipuler. Pour les utiliser, le fichier
d'en-tête string.h est nécessaire.
• strcat(char s,char cs) copiera les caractères de la deuxième chaîne à la fin de la première. Si la première chaîne n'a pas
assez d'espace, strcat continuera à écraser tout ce qui se trouve en mémoire.
principal ()
{
énumération { BUFSIZE = 1 00 } ;
char buf[BUFSIZE] ;
int i ;
fgets ( buf , BUFSIZE, stdin ) ;
buf [ strlen ( buf)-1]= ' \0 ' ; /∗ supprimer le for ( i = 0 ; buf [ i caractère de nouvelle ligne ∗/
] ; ++i )
si ( est inférieur (buf[ i ]))
printf (”%c1_____1 est 1_______1 inférieur 1 buf[i]);
____________________1case\n” , sinon si ( isupper
(buf [ i ]printf
)) (”%c1—1 est 1—1 majuscule 1—1case\ buf[i]);
n” , else
printf (”'%c '1_______1 est 1 1ni \n” , buf[i]);
}
comment le programme peut-il être amélioré (pour plus de clarté) en incluant plus d'accolades et
Exercice. 3.6 Le programme suivant lira les mots de l'entrée standard et les concatènera ensemble. Il s'arrête lorsque la fin du fichier
(contrôle-D) est atteinte ou que le tampon est plein. La fonction scanf renvoie une valeur EOF si elle tente de lire au-delà de la fin d'un
fichier.
#inclure<st dio . h>
#include < stri ng . h>
4
principal ()
{
énumération { BUFSIZE = 1000 , INPUTSIZE = 100 };
const char SEP [ ] = ” Je__________JE";
caractère s [ BUFSIZE] ;
char cs [ TAILLE D'ENTRÉE] ;
∗s = '\0';
tandis que ( scanf(”%s” , cs)!=EOF && strlen (s) < (BUFSIZE - INPUTSIZE)) { strcat ( s , SEP ) ;
strcat(s , cs);
}
printf (”%s” ,s ) ;
}
Exercice. 3.7 3. Écrivez un programme qui lit le prénom et le nom d'un utilisateur, sur des lignes séparées (astuce : utilisez fgets, il
s'arrête à la fin d'une ligne, scanf("%s") s'arrête à un espace). La sortie correspond aux deux noms sous forme d'une seule chaîne,
par exemple « smith, john » en conservant la casse de l'entrée.
Exercice. 3.8 Écrivez un programme similaire qui génère le nom sous la forme « SMITH, John », cette fois en utilisant la casse dans
la chaîne d'exemple.
5
Références
Eckel, B. (2000). Penser en C++, Volume 1 : Introduction au C++ standard (2e édition), Prentice Hall.
[Link]
Hanly, JR, Koffman, EB et Horvath, JC (1997). Conception de programme C pour les ingénieurs, Addison-Wesley. classmark
518.567.5 HAN.
Kernighan, BW et Ritchie, D. (1988). Langage de programmation C (2e édition), Prentice Hall PTR.
Raymond, ES (1999). La cathédrale et le bazar : réflexions sur Linux et l'Open Source par un révolutionnaire accidentel (O'Reilly
Linux), O'Reilly.
van der Linden, P. (1994). Programmation experte en C : les secrets profonds du C, Prentice Hall.