Langage C - Exercices
Table des matières
- 1. Premiers pas
- 2. Variables et types de base
- 3. Opérateurs arithmétiques
- 4. Structures conditionnelles
- 5. Les boucles
- 5.1. Exercice 501 boucles reprise
- 5.2. Exercice 505 - Motif rectangle boucles motifs
- 5.3. Exercice 510 - Motif carré boucles motifs
- 5.4. Exercice 515 - Liste de nombres boucles entiers
- 5.5. Exercice 520 - Carrés boucles motifs
- 5.6. Exercice 525 - Un motif triangulaire boucles motifs
- 5.7. Exercice 530 - Un motif en losange boucles motifs
- 5.8. Exercice 531 - Un motif en permutation circulaire boucles motifs
- 5.9. Exercice 532 - Nombre hexadécimaux boucle table hexadecimaux
- 5.10. Exercice 535 - Table ASCII boucles char ascii
- 5.11. Exercice 540 - Code golf boucles int golf
- 5.12. Exercice 545 - Dépassement de capacité boucles depassement capacite
- 5.13. Exercice 550 - Dépassement de capacité et comparaison boucles depassement capacite comparaison entier signe
- 5.14. Exercice 555 - Dépassement de capacité II boucles depassement capacite sizeof int
- 5.15. Exercice 570 - Fonction puissance
- 5.16. Exercice 575 - Table de multiplications
- 5.17. Exercice 576 - Afficher un tableau boucles tableau
- 5.18. Exercice 580 - Saisir une chaîne de caractères boucles tableau scanf
- 5.19. Exercice 585 - Permutation circulaire d'une chaîne de caractères boucles tableau scanf
- 6. Fonctions
- 6.1. Exercice 601 - Une première fonction fonction aire float
- 6.2. Exercice 602 - Aire d'un rectangle fonction aire rectangle float
- 6.3. Exercice 605 - Majuscule fonctions char if
- 6.4. Exercice 610 - Minuscule fonctions char if
- 6.5. Exercice 615 - Caractère alphanumérique fonctions char alphanumerique if
- 6.6. Exercice 620 - Chiffre fonctions char digit chiffre
- 6.7. Exercice 625 - Somme d'entiers fonctions somme entiers boucles
- 6.8. Exercice 630 - Factorielle fonctions factorielle iteration boucles
- 6.9. Exercice 635 - Approximation de l'exponentielle
- 6.10. Exercice 646 - Echanger deux valeurs d'un tableau tableau echange valeurs
- 6.11. Exercice 650 - Copie locales des variables variables locales
- 6.12. Exercice 660 - Changer l'ordre
- 6.13. Exercice 690 - Passer une fonction à une fonction
- 7. Tableaux
- 7.1. Tableaux 700 - Déclarer un tableau
- 7.2. Exercice 720 - Tableaux
- 7.3. Exercice 730 - Afficher un tableau
- 7.4. Exercice 750 - Moyenne - Tableau en paramètre
- 7.5. Exercice 760 - Recherche de minimum
- 7.6. Exercice 770 - Recherche dans un tableau
- 7.7. Exercice 772 - Tableaux et adresses tableaux vocalbulaire adresse
- 7.8. Exercice 775 - Déterminer si un tableau est trié complexite lineaire n
- 7.9. Exercice 780 - Garnir un tableau
- 7.10. Exercice 790 - Garnir aléatoirement un tableau
- 8. Récursivité
- 8.1. Exercice 800 - Factorielle fonctions recursives factorielle
- 8.2. Exercice 810 - Fibonacci fonctions recursives fibonacci
- 8.3. Exercice 820 - Somme et produit de deux entiers fonctions recursives somme produit
- 8.4. Exercice 830 - \(\frac{x^{n}}{n!}\) fonctions recursives exponentielle
- 8.5. Exercice 840 - Une autre implémentation de l'exponentielle fonctions recursives exponentielles
- 8.6. Exercice 850 - Recherche de minimum fonctions recursives recherche minimum tableaux
- 8.7. Exercice 860 - Récursivité terminale - Fibonacci fonctions recursives terminales fibonacci
- 8.8. Exercice 870 - Afficher un tableau récursivement fonctions recursives tableau
- 8.9. Exercice 880 - Afficher une chaîne de caractères récursivement fonctions recursives chaine
- 9. Entrées / sorties ordinaires
- 9.1. Exercice 910 - Lire un caractère getchar
- 9.2. Exercice 920 - Une première entrée clavier
- 9.3. Exercice 930 - Analyser une chaîne de caractère I scanf chaine
- 9.4. Exercice 940 - Analyser une chaîne de caractères II scanf chaine
- 9.5. Exercice 950 - Analyser une chaîne de caractères III scanf chaine
- 10. Pointeurs
- 10.1. Exercice 1000 - Adresse mémoire d'une variable pointeurs adresse
- 10.2. Exercice 1010 - Adresses mémoire des cases d'un tableau pointeurs adresse tableaux
- 10.3. Exercice 1020 - Une variable et son adresse pointeurs esperluette
- 10.4. Exercice 1030 - Incrémenter une adresse - Arithmétique des pointeurs
- 10.5. Exercice 1040 - Un substitut à sizeof adresse conversion pointeur
- 10.6. Exercice 1050 - Tableau et pointeurs
- 10.7. Exercice 1060 - Parcourir un tableau en itérant sur les adresses
- 10.8. Exercice 1070 - Modifier une variable à l'aide d'une fonction
- 11. Modularité - Organisation du code
- 12. Les fichiers
- 12.1. Exercice 1200 - Lire un fichier I fichier fgetc CRLF
- 12.2. Exercice 1201 - Lire un fichier II fichier lecture CRLF
- 12.3. Exercice 1202 - Lire un fichier III fichiers lecture
- 12.4. Exercice 1205 - Compter les caractères d'un fichier
- 12.5. Exercice 1207 - Compter les différentes lettres d'un fichier
- 12.6. Exercice 1210 - Ecrire dans un fichier fichiers ecriture
- 12.7. Exercice 1215 - Transformer un fichier
- 12.8. Exercice 1220 - Conversion hexadécimal fichiers conversion hexadecimal
- 12.9. Exercice 1230 - Table de multiplication au format CSV fichiers ecritures table csv
- 12.10. Exercice 1240 - Transposition fichiers lecture ecriture transposition
- 12.11. Exercice 1250 - Lire un fichier en mode binaire fichiers lecture mode binaire
- 12.12. Exercice 1260 - Produire une image fichiers ecriture mode binaire
- 13. Les chaînes de caractères
- 13.1. Exercice 1300 - Introduction aux chaînes de type C
- 13.2. Exercice 1301 - Afficher une chaine de caractères
- 13.3. Exercice 1302 - Afficher une chaine de caractères à l'envers
- 13.4. Exercice 1303 - Palindrome
- 13.5. Exercice 1305 - Longueur d'une chaîne de type C
- 13.6. Exercice 1306 - Longueur d'une chaîne de type C - Bis
- 13.7. Exercice 1307 - Copier une chaîne de caractères
- 13.8. Exercice 1308 - Comparer deux chaînes de caractères
- 13.9. Exercice 1310 - Recherche de caractère dans une chaîne
- 13.10. Exercice 1311 - Vérifier qu'une chaîne de caractères ne contient que des chiffres
- 13.11. Exercice 1312 - Convertir une chaîne contenant des chiffres en int
- 13.12. Exercice 1315 - Conversion chaîne de caractère en chaîne de codes ascii
- 13.13. Exercice 1320 - Conversion d'une chaîne de codes ascii en chaîne de caractères
- 13.14. Exercice 1325 - Conversion d'une chaîne de codes ascii hexadécimaux
- 13.15. Exercice 1330 - Conversion d'une chaine de caractères en suite de bits
- 13.16. Exercice 1335 - Recherche de chaîne de caractères
- 13.17. Exercice 1340 - Mélanger deux chaînes de caractères
- 13.18. Exercice 1350 - Compter un caractère donné dans une chaine chaine analyser compter caractere
- 13.19. Exercice 1360 - chaine analyser compter caractere
- 14. Communication avec l'environnement
- 14.1. Exercice 1400 - Une autre signature pour la fonction main
- 14.2. Exercice 1402 - Passer des paramètres au programme
- 14.3. Exercice 1405 - Un programme pour les additionner des chiffres
- 14.4. Exercice 1406 - Une première calculatrice
- 14.5. Exercice 1408 - Une calculatrice complète en notation polonaise inverse
- 14.6. Exercice 1410 - Nombre de caractères
- 14.7. Exercice 1415 - malloc signature malloc
- 14.8. Exercice 1416 - malloc 2 malloc
- 14.9. Exercice 1420 - Allocation dynamique de mémoire et tableau allocation dynamique
- 14.10. Exercice 1430 - Allocation de mémoire et tableau 2d
- 15. Opérations sur les bits
- 15.1. Exercice 1500 - Opérateurs bit à bit (bitwise operator)
- 15.2. Exercice 1510 - Le dernier bit à 0
- 15.3. Exercice 1520 - Le dernier bit à 1
- 15.4. Exercice 1530 - Bit shifts
- 15.5. Exercice 1535 - Représentation binaire d'un int shift masque representation binaire
- 15.6. Exercice 1540 - Boutisme (Endianness) boutisme conversion pointeurs
- 16. Structures
- 16.1. Exercice 1600 - Première structure structures sizeof struct
- 16.2. Exercice 1605 - Poursuivre la familiarisation avec les structures structures tableau
- 16.3. Exercice 1610 - Quelques fonctions pour les points sruct fonctions
- 16.4. Exercice 1615 - Approximation de pi à l'aide de points struct point monte carlo
- 16.5. Exercice 1630 - Structure et modularité
- 16.6. Exercice 1635 - Un alias pour les points typedef alias structure
- 16.7. Exercice 1640 - Une structure en paramètre de fonction struct fonctions parametre
- 16.8. Exercice 1650 - Une structure contenant un tableau struct fonctions parametre valeur
- 16.9. Exercice 1660 - Une structure pour les nombres complexes struct fonctions
- 17. Structures de données
- 18. Rétro-ingénierie
- 19. Hasard
- 20. Le préprocesseur
- 21. Approfondissement
- 21.1. Exercice 10000 - Un échange astucieux
- 21.2. Exercice 10005 - Allocation dynamique et typage
- 21.3. Exercice 10010 - Représentation binaire representation binaire bitshift boucles
- 21.4. Exercice 10015 - Depuis la représentaton binaire
- 21.5. Exercice 10020 - Conversion de pointeur
- 21.6. Exercice 10025 - Distance à l'origine
- 21.7. Exercice 10030 - Stéganographie
- 21.8. Exercice 10035 - Chiffrement par décalage
- 21.9. Exercice 10040 - Déchiffrement par décalage
- 21.10. Exercice 10045 - PCR boucle recurrence
- 21.11. Exercice 10050 - Devinette
- 21.12. Exercice 10060 - Exploiter de vraies données
- 21.13. Exercice 10070 - Type punning 1 pointeurs type conversion
- 21.14. Exercice 10080 - Type punning 2 pointeurs type conversion
- 21.15. Exercice 10090 - Norme IEEE 754 type memcopy
1. Premiers pas
1.1. Exercice 100 - Hello World! hello world
- Dans un editeur de texte, taper le code source suivant :
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
- Enregistrer le fichier dans hello.c.
- Compiler ce fichier à l'aide de l'instruction gcc hello.c. Un fichier a.out a été produit.
- Executer ce fichier à l'aide de la commande ./a.out.
1.2. Exercice 102 - Hello World! hello world reprise
Ecrire et compiler un programme qui affiche :
+------------+ |Hello World!| +------------+
1.3. Exercice 110 - Afficher une variable printf declaration variable affectation
- Déclarer une variable nommée
entierde typeint. - Affecter la valeur 42 à cette variable.
- Afficher le contenu de cette variable à l'aide de l'instruction :
printf("Le contenu de la variable entier est : %d\n", entier);
On remarque que %d est remplacé par le contenu de la variable entier.
- Enlever le
\n. Qu'observe-t-on ? - Déclarer une variable de type
floatet lui affecter la valeur3.14. - Afficher le contenu de cette variable.
2. Variables et types de base
2.1. Exercice 210 - La taille des differents types variables types sizeof
A l'aide de l'opérateur sizeof, afficher dans deux colonnes différents types de données (char, int, float, …)
ainsi que la place occupée en mémoire par chacun de ces types.
Indication: sizeof ne "retourne" pas un int et ne peut être afficher avec %d; préférer %lu ou %ld.
2.2. Exercice 220 - Représentations d'un entier variable representation
- Déclarer une variable de type
intet initialiser la à une valeur de votre choix. - A l'aide de la fonction
printf, afficher cette variable en base décimale (à l'aide de%d) , en base hexadécimale (à l'aide de%X) et en base octale (à l'aide de%o). - Répéter l'opération pour quelques valeurs suivantes de la variable.
2.3. Exercice 215 - Représentation d'une variable de type char
- Déclarer une variable de type
char. - Affecter à cette variable la valeur 65.
- Afficher le
charà l'aide de%d. Qu'obtient-on ? - Afficher le
charà l'aide de%c. Qu'obtient-on ? - Que se passe-t-il lorsque l'on ajoute un petit nombre entier au
char?
2.4. Exercice 230 - Echanger les valeurs de deux variables variables affectation echange
- Déclarer deux variables
aetbde typeint. - Affecter la valeur
42la variableaet la valeur17à la valeurb. - A l'aide d'un appel à la fonction
printfafficher la valeur contenue dansaet la valeur contenue dansb. - Trouver un moyen de mettre la valeur contenue dans
adansbet la valeur contenue dansbdansa. - Afficher de nouveau les contenus de
aetbpour vérifier que la manipulation précédente a bien fonctionné.
3. Opérateurs arithmétiques
3.1. Exercice 310 - Les opérateurs arithmétiques
- Déclarer deux variables
netmde typeintet deux variablesxetyde typefloat. - Affecter une valeur non nulle à chacune de ces variables.
- Afficher
n+m,n-m,n*m,n/m. - Afficher
x+y,x-y,x*y,x/y. Comparer les résultats obtenus avec les résultats obtenus à la question précédente. - Tester l'opérateur
%. A quoi sert-il ?
4. Structures conditionnelles
4.1. Exercice 405 - Structure conditionnelle - Connecteurs logiques if else or
Ecrire un programme qui demande à l'utilisateur de saisir une lettre (minuscule). Le programme doit déterminer s'il s'agit d'une voyelle ou d'une consonne.
4.2. Exercice 410 - Représentation des variables - Structure conditionnelle
Ecrire un programme qui demande à l'utilisateur de saisir un nombre entre 32 et 127 inclus. Si le nombre est inclus dans cet intervalle, le programme doit afficher le caractère dont le code ASCII est ce nombre. Sinon, le programme doit afficher un message et se terminer.
Que signifie l'acronyme ASCII ?
4.3. Exercice 415 - Comparer un entier comparaison if
Ecrire un programme qui demande à l'utilisateur d'entrer son âge. Le
programme doit afficher Vous êtes majeur. si l'âge est supérieur ou
égal à 18 ans et Vous êtes mineur. sinon.
4.4. Exercice 420 - Un exemple de choix multiples switch
Ecrire un programme qui demande à l'utilisateur de choisir un
caractère parmi a, b ou c. Le programme doit alors écrire
Vous avez choisi a. (resp. b., c.) si l'utilisateur a choisi a
(resp. b, c). Sinon, le programme doit écrire Vous avez choisi quelque
chose qui n'est pas dans la liste..
5. Les boucles
5.1. Exercice 501 boucles reprise
Ecrire, compiler et exécuter un programme qui affiche :
+------------+ |Hello World!| +------------+ +------------+ |Hello World!| +------------+ +------------+ |Hello World!| +------------+ +------------+ |Hello World!| +------------+ +------------+ |Hello World!| +------------+ +------------+ |Hello World!| +------------+
5.2. Exercice 505 - Motif rectangle boucles motifs
Afficher un rectangle, consitué du caractère +, de largeur 10 et de
hauteur 30.
5.3. Exercice 510 - Motif carré boucles motifs
Afficher un carré, consitué du caractère +, de coté 30. Le caractère
+ ne doit pas apparaître deux fois de suite dans le code source.
La carré est-il carré ?
5.4. Exercice 515 - Liste de nombres boucles entiers
- Ecrire un programme qui affiche les 10000 premiers nombres entiers positifs en colonne.
- Modifier le programme pour qu'une ligne soit passée tous les dix nombres.
5.5. Exercice 520 - Carrés boucles motifs
Ecrire un programme qui demande cinq fois de suite un nombre à l'utilisateur et qui à chaque saisie affiche le carré de ce nombre.
5.6. Exercice 525 - Un motif triangulaire boucles motifs
Ecrire un programme permettannt d'afficher dans la console le motif suivant :
^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ ^^^^^^^^ ^^^^^^^^^
5.7. Exercice 530 - Un motif en losange boucles motifs
Ecrire un programme permettant d'afficher dans la console le motif suivant :
....^.... ...^^^... ..^^^^^.. .^^^^^^^. ^^^^^^^^^ .^^^^^^^. ..^^^^^.. ...^^^... ....^....
5.8. Exercice 531 - Un motif en permutation circulaire boucles motifs
Ecrire un programme permettant d'afficher dans la console le motifif suivant :
JKLMNOPQRSTUVWXYZABCDEFGHI KLMNOPQRSTUVWXYZABCDEFGHIJ LMNOPQRSTUVWXYZABCDEFGHIJK MNOPQRSTUVWXYZABCDEFGHIJKL NOPQRSTUVWXYZABCDEFGHIJKLM OPQRSTUVWXYZABCDEFGHIJKLMN PQRSTUVWXYZABCDEFGHIJKLMNO QRSTUVWXYZABCDEFGHIJKLMNOP RSTUVWXYZABCDEFGHIJKLMNOPQ STUVWXYZABCDEFGHIJKLMNOPQR TUVWXYZABCDEFGHIJKLMNOPQRS UVWXYZABCDEFGHIJKLMNOPQRST VWXYZABCDEFGHIJKLMNOPQRSTU WXYZABCDEFGHIJKLMNOPQRSTUV XYZABCDEFGHIJKLMNOPQRSTUVW YZABCDEFGHIJKLMNOPQRSTUVWX ZABCDEFGHIJKLMNOPQRSTUVWXY ABCDEFGHIJKLMNOPQRSTUVWXYZ BCDEFGHIJKLMNOPQRSTUVWXYZA CDEFGHIJKLMNOPQRSTUVWXYZAB DEFGHIJKLMNOPQRSTUVWXYZABC EFGHIJKLMNOPQRSTUVWXYZABCD FGHIJKLMNOPQRSTUVWXYZABCDE GHIJKLMNOPQRSTUVWXYZABCDEF HIJKLMNOPQRSTUVWXYZABCDEFG IJKLMNOPQRSTUVWXYZABCDEFGH
Remarque : le décalage initial doit être aléatoire.
5.9. Exercice 532 - Nombre hexadécimaux boucle table hexadecimaux
- Ecrire un programme qui affiche deux colonnes : une colonne avec les nombres entiers de 0 à 255 et une autre colonne avec leurs valeurs en base 16 (héxadécimale).
- Bonus: transformer le code pour obtenir 8 fois 2 colonnes de 16 nombres
5.10. Exercice 535 - Table ASCII boucles char ascii
Ecrire un programme qui affiche les caractères correspondant aux codes ascii allant de 33 à 127, à l'aide de trois colonnes :
- la première colonne affiche le caractère
- la deuxième colonne affiche le code du caractère en base 10
- la troisième colonne affiche le code du caractère en base 16
5.11. Exercice 540 - Code golf boucles int golf
Ecrire un programme qui affiche en colonne les entiers naturels de 0 à 100. Le code source doit prendre le moins de caractères possible.
5.12. Exercice 545 - Dépassement de capacité boucles depassement capacite
Ecrire un programme qui déclare une variable de type unsigned char
et une variable de type char. Coder une boucle de 500 itérations. A
chaque itération, afficher chacune des deux variables précédentes puis
incrémenter ces deux variables. Il doit y avoir deux colonnes dans la
console : une pour chaque variable. Que constate-t-on ?
5.13. Exercice 550 - Dépassement de capacité et comparaison boucles depassement capacite comparaison entier signe
Afficher les 127 premiers entiers naturels à l'aide d'une boucle dont le compteur est un char.
Qu'observe-t-on ?
5.14. Exercice 555 - Dépassement de capacité II boucles depassement capacite sizeof int
Déterminer (à l'aide d'une boucle, par exemple) le plus grand entier naturel qu'il est possible
de stocker dans int. En déduire le nombre de bits, puis le nombre d'octets sur lequel est codé
un int.
Indication: le bit le plus à gauche sert à code le signe de l'int.
5.15. Exercice 570 - Fonction puissance
Ecrire une fonction int puissance(int x, int p) qui calcule \(x^{p}\).
5.16. Exercice 575 - Table de multiplications
Ecrire un programme qui affiche la table de multiplication suivante :
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
5.17. Exercice 576 - Afficher un tableau boucles tableau
Ecrire un programme qui produit la sortie ci-dessous. Le programme doit utiliser des boucles.
1 11 21 31 41 51 61 71 81 91 2 12 22 32 42 52 62 72 82 92 3 13 23 33 43 53 63 73 83 93 4 14 24 34 44 54 64 74 84 94 5 15 25 35 45 55 65 75 85 95 6 16 26 36 46 56 66 76 86 96 7 17 27 37 47 57 67 77 87 97 8 18 28 38 48 58 68 78 88 98 9 19 29 39 49 59 69 79 89 99 10 20 30 40 50 60 70 80 90 100
5.18. Exercice 580 - Saisir une chaîne de caractères boucles tableau scanf
Ecrire un programme dans lequel un tableau de 30 char est
déclaré. Afficher un message demandant à l'utilisateur de saisir son
nom. A l'aide de la fonction scanf, stocker le nom qu'à tapé
l'utilisateur dans le tableau de char précedemment déclaré.
Afficher la troisième lettre du nom.
5.19. Exercice 585 - Permutation circulaire d'une chaîne de caractères boucles tableau scanf
Ecrire un programme dans lequel un tableau de 30 char est
déclaré. Afficher un message demandant à l'utilisateur de saisir un
mot. A l'aide de la fonction scanf, stocker le mot qu'à tapé
l'utilisateur dans le tableau de char précedemment déclaré. Le
programme doit afficher toutes les permutations circulaires du mot.
Voici un exemple d'exécution du programme :
Veuillez saisir un mot : bonjour bonjour onjourb njourbo jourbon ourbonj urbonjo rbonjou
Indication: il est possible d'utiliser la fonction strlen de la
librairie string.h qui donne la longeur d'une chaîne de caractères.
6. Fonctions
6.1. Exercice 601 - Une première fonction fonction aire float
- Rappeler la formule qui donne l'aire du disque.
Ecrire une fonction de prototype
float aire_disque(float rayon):- qui prend en entrée un réel noté
rayon - qui retourne l'aire du disque de rayon
rayon
On écrira cette fonction avant la fonction
main.- qui prend en entrée un réel noté
- Dans la fonction
main, apppeler la fonctionaire_disque.
6.2. Exercice 602 - Aire d'un rectangle fonction aire rectangle float
- Rappeler la formule qui donne l'aire du rectangle.
- Ecrire une fonction de prototype
float aire_rect(float largeur, float longueur):- qui prend en entrée deux réels notés
largeuretlongueur - qui retourne l'aire du rectangle correspondant
- qui prend en entrée deux réels notés
- Dans la fonction
main, apppeler la fonctionaire_rect.
6.3. Exercice 605 - Majuscule fonctions char if
Ecrire une fonction de prototype int est_majuscule(char c) qui
retourne 1 si c fait partie des caractères
ABCDEFGHIJKLMNOPQRSTUVWXYZ et 0 sinon.
6.4. Exercice 610 - Minuscule fonctions char if
Ecrire une fonction de prototype int est_minuscule(char c) qui
retourne 1 si c fait partie des caractères
abcdefghijklmnopqrstuvwxyz et 0 sinon.
6.5. Exercice 615 - Caractère alphanumérique fonctions char alphanumerique if
Ecrire une fonction de prototype int est_alpha_numerique(char c) qui
retourne 1 si c fait partie des caractères
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" et 0 sinon.
Les appels suivants, par exemple :
printf("est_alpha_numerique('D') = %d\n", est_alpha_numerique('D'));
printf("est_alpha_numerique('u') = %d\n", est_alpha_numerique('u'));
printf("est_alpha_numerique('9') = %d\n", est_alpha_numerique('9'));
printf("est_alpha_numerique('%') = %d\n", est_alpha_numerique('%'));
doivent afficher :
1 1 1 0
6.6. Exercice 620 - Chiffre fonctions char digit chiffre
Ecrire une fonction de prototype int est_chiffre(char c) qui
retourne 1 si c fait partie des caractères
"0123456789" et 0 sinon.
6.7. Exercice 625 - Somme d'entiers fonctions somme entiers boucles
Ecrire une fonction somme qui prend en paramètre un int n et qui
retourne la somme de tous les entiers compris entre 0 et n. Afficher
la somme des 100 premiers entiers.
6.8. Exercice 630 - Factorielle fonctions factorielle iteration boucles
Ecrire une fonction qui calcule \(k!\).
On rappelle que pour \(k\geq 1,\;k!=k\times(k-1)\times\dots\times 2\times 1\). Par exemple, \(4!=4\times 3\times 2\times 1\) et \(7!=7\times 6\times 5\times 4\times 3\times 2\times 1\). Par convention, \(0!=1\).
6.9. Exercice 635 - Approximation de l'exponentielle
On rappelle le développement en série entière de l'exponentielle : \[\exp(x)=\sum_{k=0}^{+\infty}\frac{x^{k}}{k!}\]
Ecrire
une fonction de prototype double expo(double x, int n). Cette
fonction doit retourner la somme partielle, pour k allant de 0 à n, du
développement ci-dessus.
6.10. Exercice 646 - Echanger deux valeurs d'un tableau tableau echange valeurs
Ecrire une fonction de prototype
void echanger(int tab[], int i1, int i2) qui échange les valeurs du
tableaux se trouvant aux positions i1 et i2. On fera l'hypthèse
que i1 et i2 sont des entiers positifs ou nuls inférieurs à la
taille du tableau passé en paramètre.
6.11. Exercice 650 - Copie locales des variables variables locales
On donne le code suivant :
#include <stdio.h>
void f(int i)
{
i = i+1;
}
int main()
{
int i = 42;
printf("i = %d\n",i);
// f(i);
printf("i = %d\n",i);
return 0;
}
- Compiler et tester le code ci-dessus.
- Décommenter l'instruction commmentée. A quoi peut-on s'attendre ?
- Tester. Qu'observe-t-on ? Comment expliquer cela ?
- Afficher les adresses des différentes variables.
6.12. Exercice 660 - Changer l'ordre
Ecrire une fonction de prototype void changer_ordre(int tab[], int taille). Cette
fonction doit échange la première valeur du tableau avec la dernières, la deuxième valeur
du tableau avec l'avant dernière, etc…
Par exemple, le code
int tab1[5] = {11,12,13,14,15};
int tab2[4] = {10,20,30,40};
afficher_tab(tab1, 5);
changer_ordre(tab1, 5);
afficher_tab(tab1, 5);
afficher_tab(tab2, 4);
changer_ordre(tab2, 4);
afficher_tab(tab2, 4);
doit produire l'affichage
11 12 13 14 15 15 14 13 12 11 10 20 30 40 40 30 20 10
6.13. Exercice 690 - Passer une fonction à une fonction
On donne les fonctions :
#include <stdio.h>
\\ Une fonction très simple
double f(double x) {
return x;
}
\\ Calcul de l'intégrale à l'aide de la méthode des rectangles
double integrale(double f, double a, double b, int n) {
double h = (b-a) / n;
double aire = 0;
for(int i = 0; i < n; i++) {
aire += h * f(a+i*h);
}
return aire;
}
- Après avoir copié-collé ces deux fonction dans un fichier, tester la fonction
integraleen l'appelant dans la fonctionmain. Qu'observe-t-on ? - A l'aide du message d'erreur fourni par le compilateur, corriger la signature de la fonction
integrale, autrement dit, corriger le type du paramètref.
7. Tableaux
7.1. Tableaux 700 - Déclarer un tableau
Déclarer un tableau de 5 entiers nommé
tab1à l'aide de l'instructionint tab1[5];Affecter la valeur
10dans la case d'indice0du tableau à l'aide de l'instructiontab1[0]=10;- Affecter des valeurs aux quatres autres cases du tableau
tab1. Quel est l'indice de la dernière case ? Tester l'instruction :
int tab2[8] = {-5, 10, 20, 15, 0, 0, 100, 1000};- Afficher le contenu de la case d'indice 2 de
tab2. - Afficher le contenu de toutes les cases à l'aide d'une boucle.
7.2. Exercice 720 - Tableaux
Ecrire un programme qui déclare un tableau de 20 int. A l'aide d'une
boucle, affecter la valeur \(2^{i}\) dans la case d'indice i du
tableau. Afficher ensuite la case d'indice 3, la case d'indice 10 et la case d'indice 19.
7.3. Exercice 730 - Afficher un tableau
Ecrire une fonction void afficher_tableau(int tab[], int taille) qui prend en
paramètres un tableau et sa taille. Cette fonction affiche en colonne chaque case
du tableau.
7.4. Exercice 750 - Moyenne - Tableau en paramètre
Ecrire une fonction de prototype
double moyenne(double notes[], int n)
qui retourne la moyenne des notes contenus dans le tableau passé
en paramètre.
7.5. Exercice 760 - Recherche de minimum
Ecrire une fonction de prototype int minimum(int tab[], int taille).
Cette fonction retourne l'indice de la valeur minimale du tableau.
7.6. Exercice 770 - Recherche dans un tableau
Ecrire une fonction de prototype int rechercher(int tableau[], int taille, int nombre).
Cette fonction doit retourner 1 si nombre est dans tableau et retourner 0 si nombre n'est pas dans tableau.
7.7. Exercice 772 - Tableaux et adresses tableaux vocalbulaire adresse
- Déclarer un tableau de 10
int. - Initialiser ce tableau avec des valeurs non nulles.
- A l'aide d'une boucle afficher :
- les valeurs contenues dans les cases du tableau
- les adresses des cases des tableaux
- Quelle est la différence entre deux adresses consécutives ? Que peut-on en déduire ?
- Recommencer 1., 2., 3. et 4. avec un tableau de
double.
7.8. Exercice 775 - Déterminer si un tableau est trié complexite lineaire n
Ecrire une fonction de prototype int est_trie(int tab[], int taille) qui retourne 1 si le tableau passé en paramètre est trié et qui retourne 0 sinon. Tester la fonction.
7.9. Exercice 780 - Garnir un tableau
Ecrire une fonction de prototype void garnir(int tab[], int taille) qui demande
à l'utilisateur d'entrer au clavier autant d'entiers qu'il y a de cases dans le
tableau. La fonction stocke les entiers saisis dans le tableau.
7.10. Exercice 790 - Garnir aléatoirement un tableau
Ecrire une fonction
void garnir_aleatoirement(int tab[], int taille, int m, int M) qui prend
en paramètres un tableau de int ainsi que sa taille. La fonction doit remplir
le tableau de nombres entiers aléatoires uniformément répartis entre m et M
inclus.
8. Récursivité
8.1. Exercice 800 - Factorielle fonctions recursives factorielle
Ecrire une fonction récursive de prototype int fact_rec(int n) qui prend en paramètres un
entier n et retourne n!.
8.2. Exercice 810 - Fibonacci fonctions recursives fibonacci
La suite de Fibonacci est la suite de nombres 0, 1, 1, 2, 3, 5, 8, 13, … où le \(i^{ieme}\) nombre \(F_{i}\) de la suite est la somme des deux précédents : \(F_{i}=F_{i-1}+F_{i-2}\) avec \(F_{0}=0\) et \(F_{1}=1\).
Implémenter une fonction récursive int fibo_rec(int i) qui prend en paramètre un indice \(i\) et retourne le \(i^{ieme}\)
terme \(F_{i}\) de la suite de Fibonacci.
8.3. Exercice 820 - Somme et produit de deux entiers fonctions recursives somme produit
- Ecrire une fonction récursive de prototype
int somme_rec(int a, int b)qui retourne la somme deaet deb. On pourra dans un premier temps supposeraetbpositifs. - Ecrire une fonction récursive de prototype
int produit_rec(int a, int b)qui retourne le produit deaet deb.
8.4. Exercice 830 - \(\frac{x^{n}}{n!}\) fonctions recursives exponentielle
On note \(u(n,x)=\frac{x^{n}}{n!}\). On remarque que \(\frac{x^{n}}{n!}=\frac{x}{n}\frac{x^{n-1}}{(n-1)!}\), ce qui signifie que \(u(n,x)\) peut être défini par récurrence : \(\begin{cases}u(n,x)=\frac{x}{n}*u(n-1,x)\;\text{si}\;n\geq 1\\u(0,x)=1\;\text{sinon}\end{cases}\)
Ecrire une fonction récursive de prototype double u(int n, double x) qui prend en paramètre un entier \(n\)
et un réel x et qui retourne \(\frac{x^{n}}{n!}\).
8.5. Exercice 840 - Une autre implémentation de l'exponentielle fonctions recursives exponentielles
Soit \(x\) un réel quelconque. On définit la suite \(exp(n,x)\) par \(\begin{cases}exp(n,x)=exp(n-1,x)+\frac{x^{n}}{n!}\;\text{si}\;n\geq 1\\exp(0,x)=1\end{cases}\)
Ecrire une fonction récursive double exp_rec(int n, double x) qui prend en paramètre un entier
\(n\) et un réel \(x\) et qui retourne \(exp(n,x)\).
8.6. Exercice 850 - Recherche de minimum fonctions recursives recherche minimum tableaux
Exercice une fonction récursive de prototype int indice_du_min_rec(int tab[], int taille). Cette
fonction retourne l'indice du minium du tableau passé en paramètre.
Indication: le minimum d'un tableau est le minimum entre sa première valeur et le minimum du sous-tableau commençant à la case d'indice 1. Que dire alors des indices ?
8.7. Exercice 860 - Récursivité terminale - Fibonacci fonctions recursives terminales fibonacci
Ecrire une fonction int fibo_rec_term(int i, int acc1, int acc2) récursive terminale qui retourne le nombre de Fibonacci
d'indice l'entier passé en paramètre.
8.8. Exercice 870 - Afficher un tableau récursivement fonctions recursives tableau
Ecrire une fonction récursive de prototype void afficher_tab_int_rec(int tab[], int taille) qui permet d'afficher un tableau d'entiers.
8.9. Exercice 880 - Afficher une chaîne de caractères récursivement fonctions recursives chaine
Ecrire une fonction récursive de prototype void afficher(char * chaine) qui permet d'afficher une chaîne de caractères.
9. Entrées / sorties ordinaires
9.1. Exercice 910 - Lire un caractère getchar
Tester le code suivant :
#include <stdio.h> int main() { getchar(); }- Que se passe-t-il ?
- Récupérer la valeur retourner par
getchardans une variable de typechar. - Afficher la valeur valeur récupérée.
Remarque : la fonction getchar peut être utilisée pour interrompre l'excution d'un programme.
9.2. Exercice 920 - Une première entrée clavier
Ecrire un programme qui demande à l'utilisateur d'entrer un entier, le stocke dans une variable puis affiche l'entier entré. Comment faire la même chose pour deux entiers ?
9.3. Exercice 930 - Analyser une chaîne de caractère I scanf chaine
Ecrire un prgramme qui demande à l'utilisateur d'entrée une chaîne de
caractères sous la forme hh:mm:ss.ss (heure, minutes, secondes). Le
programme dot enregistrer le nombre d'heures dans un int, le nombre
de minutes dns un autre int et le nombre de seconde dans un
float.
Le programme doit ensuite afficher l'heure au format hh-mm-ss.ss.
Indication: utiliser la fonction scanf avec des %d et %f
convenblemen choisis.
9.4. Exercice 940 - Analyser une chaîne de caractères II scanf chaine
On sait que %s= dans scanf va lire une chaîne de caractères
jusqu'au prohain espace. Que faire alors si l'on souhaite que
l'espace fase partie de la chaîne de caractères?
Il faut utilser les fonctionnalités avancées de scanf. Il est
possible de réciser à scanf les caractères à conserver à l'aide de
la syntaxe []. Par exemple %[abcdefghijklmnopqrstuvwxyz ]
(observez l'space après le z) conservera n'importe quelle minuscule
ainsi qu'un space.
Tester lecode ci-après en entrant différentes chaînes de caractères (des minucules, des majuscules, des espaces, pas d'espace, …) :
char str[00]; scanf("%[bcdefghijklmnopqrstuvwxyz ]", str); printf("%n",str);- Ecrie l'instruction
scanfqui permet de conserver une chaîne decaractère consituée de majuscules ou d'espace, jusqu'à rencontre le caractère;. Ecrire un instruction
scanfqui permet de conserver la première chaîne decaractères contituées de minuscules et d'espaces et étant délimitéepas les caractères;. Par exemple si on tapeBLABLA;bnjour toto;blabla blaon consere
bonjour toto.
#include <tdio.h>
int main(vid)
{
char str100];
char str[100];
char str[100];
scanf("%ABCDEFGHIJKLMNOPQRSTUVWXYZ ];", str);
printf("s\n", str);
scanf("%^; ];%[abcdefghijklmnopqrstuvwxyz ];",str1,str2);
printf("s\n%s\n",str1,str2);
return 0
}
9.5. Exercice 950 - Analyser une chaîne de caractères III scanf chaine
Ecrire un programme qui demande à l'utilisateur d'entrée une chaîne de
caractères au clavier. On suppose que la chaîne de caractères saisie
comporte au plus 2 caractères ;. Le programme doit couper la chaîne
au niveau des ;. Les caractères acceptés sont les minuscules de a
jusque z, les majuscules de A jusque Z et les chiffres de 0
jusque 9. Par exemple si on tape :
BLA bla 12;toto va bien;bonjour! titi
le programme doit stocker :
BLA bla 12dans une première chaîne de caractèrestoto va biendans une seconde chaîne de caractères etbonjourdans une troisème chaîne de caractères
10. Pointeurs
10.1. Exercice 1000 - Adresse mémoire d'une variable pointeurs adresse
Dans la fonction main, déclarer une variable de type int, une
variable de type double et une variable de type unsigned char.
Afficher les adresses mémoire de chacune de ces variables.
10.2. Exercice 1010 - Adresses mémoire des cases d'un tableau pointeurs adresse tableaux
Déclarer un tableau de 10 int. A l'aide d'une boucle, afficher les
adresses mémoire de chacune des 10 cases du tableau. Qu'observe-t-on ?
Quelle hypothèse peut-on faire sur la quantité de mémoire occupée par
un int ?
10.3. Exercice 1020 - Une variable et son adresse pointeurs esperluette
- Ecrire un programe dans lequel :
- une variable
nde typeintest déclarée - l'adresse de la variable
nest affichée - l'adresse de la variable
nest stockée dans une variable nomméeadrde typeint * - l'addrese de
nest affichée à l'aide de la variableadr
- une variable
- Afficher le contenu de
nà l'aide deadr.
Indication: utiliser l'opérateur &.
10.4. Exercice 1030 - Incrémenter une adresse - Arithmétique des pointeurs
- Déclarer une variable
cde typechar. - Stocker l'adresse de
cdans une variableadr_cde typechar *. - Afficher la valeur de
adr_cet celle deadr_c+1. Que constate-t-on ? - Recommencer les trois étapes ci-dessus avec une variable
nde typeint. Qu'observe-t-on ? - Avec une variable de type double ?
Indication: utiliser %p pour afficher les résultats
10.5. Exercice 1040 - Un substitut à sizeof adresse conversion pointeur
Ecrire un programme qui calcule la différence entre deux entiers consécutifs d'un tableau. Cette différence
indique le nombre d'octets sur lesquels est codé un int.
10.6. Exercice 1050 - Tableau et pointeurs
Déclarer un tableau tab de double. Afficher &tab[0] et tab. Que constate-t-on ?
Indication: %d ne fonctionnera pas; il faut utiliser %p.
Bonus: de & et [ ], quel est l'opérateur prioritaire ?
10.7. Exercice 1060 - Parcourir un tableau en itérant sur les adresses
- Déclarer et initialiser un tableau d'entiers.
- Afficher les éléments de ce tableau en colonne à l'aide d'une boucle, sans utiliser
la notation
[]. - Ajouter une colonne avec l'adresse de la case du tableau affichée.
Indication: lorsque l'on déclare int tab[10], la variable tab contient l'adresse
de la première case du tableau.
10.8. Exercice 1070 - Modifier une variable à l'aide d'une fonction
Ecrire une fonction de prototype void incrementer(???) qui permet d'incrémenter une variable
de type int.
11. Modularité - Organisation du code
11.1. Exercice 1100 - Un premier .h
- Ecrire un fichier fonctions_utiles.c qui contient une fonction
void afficher_tab_int(int tab[], int taille), qui permet d'afficher un tableau. Ce fichier ne contient pas la fonctionmain. - Ecrire un fichier fonctions_utiles.h qui contient le prototype de cette fonction. Ce fichier doit contenir le code suivant :
#ifndef FONCTIONS_UTILES #define FONCTIONS_UTILES void afficher_tab_int(int tab[], int taille); #endif
- Ecrire un fichier main.c :
- qui inclut le fichier fonctions.h à l'aide de l'instruction
#include "fonctions_utiles.h" - qui contient la fonction
maindans laquelle est déclaré un tableau deint - qui affiche ce tableau à l'aide de la fonction
afficher_tab_int
- qui inclut le fichier fonctions.h à l'aide de l'instruction
- Compiler à l'aide, par exemple, de
gcc fonctions.c main.c -o mon_executable.
11.2. Exercice 1110 - Compilation séparée
Reprendre l'exercice précédent en compilant séparément fonctions.c et main.c.
11.3. Exercice 1120 - Fonctions utiles
Ajouter une fonction de prototype void afficher_tab_double(double tab[], int taille) aux fichiers
fonctions_utiles.c et fonctions_utiles.h. Cette fonction doit afficher en colonne un tableau
de double dont on connaît la taille.
11.4. Exercice 1130 - Fonctions utiles II
Ajouter une fonction de prototype void afficher_tab_char(char tab[], int taille) aux fichiers
fonctions_utiles.c et fonctions_utiles.h. Cette fonction doit afficher en colonne un tableau
de char dont on connaît la taille.
12. Les fichiers
12.1. Exercice 1200 - Lire un fichier I fichier fgetc CRLF
- Télécharger le fichier communes-departement-region.csv.
- Lire la documentation de la fonction
fgetc. - Ecrire un programme qui ouvre le fichier
communes-departement-region.csvqui affiche chaque caractère contenu dans ce fichier.
12.2. Exercice 1201 - Lire un fichier II fichier lecture CRLF
- Télécharger le fichier Fruit-Prices-2022.csv.
- Lire la documentation de la fonctions
fgets. - Ecrire un programme qui ouvre le fichier
Fruit-Prices-2022.csven lecture, puis qui affiche la première ligne du fichier. - Modifier le programme pour qu'il affiche toutes les lignes du fichier.
- Faire précéder chaque ligne du numéro de ligne.
- Afficher les lignes 30 à 40.
- Appliquer le programme au fichier liste-coordonnees-gps-monuments.csv. Qe constate-t-on ?
12.3. Exercice 1202 - Lire un fichier III fichiers lecture
Ecrire un fichier bonjour.txt qui contient quelques lignes de texte.
Ecrire un programme qui :
- ouvre le fichier bonjour.txt
- compte et affiche le nombre de lignes
- affiche chaque ligne du fichier, précédée de son numéro
12.4. Exercice 1205 - Compter les caractères d'un fichier
- Créer un fichier
entree.txtqui contient du texte. - Ecrire un programme qui :
- ouvre le ficher
entree.txten lecture - donne le nombre de caractères contenus dans ce fichier
- ouvre le ficher
12.5. Exercice 1207 - Compter les différentes lettres d'un fichier
- Créer un fichier
entree.txtqui contient du texte constitué uniquement des caractères de la table ASCII. - Ecrire un programme qui :
- ouvre le ficher
entree.txten lecture - compte chaque caractère contenu dans le fichier : compte les 'a', les 'b', …, les 'A', les 'B', …, les '+', les '-', … TOUS les caractères
- affiche le décompte final de tous les caractères
- ouvre le ficher
12.6. Exercice 1210 - Ecrire dans un fichier fichiers ecriture
Ecrire un programme qui produit un fichier table_ascii.txt pour les caractères dont le code est compris entre 32 et 127.
Indication: utiliser la fonction fprintf.
12.7. Exercice 1215 - Transformer un fichier
- Créer un fichier
entree.txtqui contient du texte avec des majuscules et des minuscules. - Ecrire un programme qui :
- ouvre le fichier
entree.txten lecture - ouvre un fichier
sortie.txten écriture - lit chaque caractère du fichier d'entrée à l'aide de la fonction
fgetc - si le caractère lu est une minuscule, alors le caractère est écrit en majuscule dans le fichier de sortie
- sinon le caractère est écrit tel quel dans le fichier de sortie
- ouvre le fichier
- Ferme les deux fichiers.
12.8. Exercice 1220 - Conversion hexadécimal fichiers conversion hexadecimal
Ecrire un programme qui produit un fichier table_conversion_hexadecimal.txt. Ce fichier contient deux colonnes:
- une première colonne avec les nombres de 0 à 100 écrits en base 10
- une deuxième colonne avec les nombtes de 0 à 100 écrits en base 16
12.9. Exercice 1230 - Table de multiplication au format CSV fichiers ecritures table csv
Un ficher CSV (comma-separated values) est un ficher texte contenant des données séparée par des virgules. Les données en questions proviennent d'un tableau. Par exemple, le tableau
| Nom | Age |
| Toto | 19 |
| Jeanjean | 22 |
peut être représenté par un fichier CSV dont le contenu est:
Nom,Age Toto,19 Jeanjean,22
Ecrire un programme qui demande à l'utilisateur un nombre entier n
compris entre 1 et 10. Le programme doit produire un fichier table.csv
contenant la table (de multiplication) de n.
12.10. Exercice 1240 - Transposition fichiers lecture ecriture transposition
Ecrire un programme qui transpose un fichier.
Indication: utiliser fgets.
12.11. Exercice 1250 - Lire un fichier en mode binaire fichiers lecture mode binaire
- Télécharger le fichier paysage1.bmp.
- Afficher les propriétés du fichiers et déterminer :
- le nombre d'octets que pèse le fichier
- le nombre de pixels de large de l'image
- le nombre de pixels de haut de l'image
- Lire brièvement le format de l'entête d'un fichier bmp.
- Ecrire un programme qui ouvre le fichier paysage1.bmp en lecture en mode binaire.
- Faire en sorte que le programme lise :
- le nombre magique
- la taille du fichier
- le premier nombre réservé pour l'application qui a créé le fichier
- le deuxième nombre réservé
- l'offset pour le contenu effectif du BMP
- la taille de l'en-tête du fichier
- la largeur de l'image en pixels
- la hauteur de l'image en pixels
- Afficher ces informations à l'écran.
Indication: il est possible d'utiliser la fonction fread de la librairie stdio.h.
12.12. Exercice 1260 - Produire une image fichiers ecriture mode binaire
La table ci-dessous a été constituée à partir de l'article wikipedia décrivant le format d'un fichier .bmp. Elle décrit la signification des 54 premiers octets constituant un fichier .bmp. Ces octets contiennent des méta-données sur l'image.
Les octets qui suivent décrivent les quantités de bleu, de vert et de rouge (dans cet ordre) pour chacun des pixels constituant l'image, ligne par ligne.
Par exemple, l'octet 54 décrit la quantité de bleu du pixel tout en haut à gauche de l'image tandis que l'octet 58 donne la quantité de vert du pixel voisin.
| Offset (bytes) | Size (bytes) | Description |
|---|---|---|
| 0 | 2 | The header field used to identify the BMP and DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII. The following entries are possible:
|
| 2 | 4 | The size of the BMP file in bytes |
| 6 | 2 | Reserved; actual value depends on the application that creates the image, if created manually can be 0 |
| 8 | 2 | Reserved; actual value depends on the application that creates the image, if created manually can be 0 |
| 10 | 4 | The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found. |
| 14 | 4 | the size of this header, in bytes (40) |
| 18 | 4 | the bitmap width in pixels (signed integer) |
| 22 | 4 | the bitmap height in pixels (signed integer) |
| 26 | 2 | the number of color planes (must be 1) |
| 28 | 2 | the number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32. |
| 30 | 4 | the compression method being used. See the next table for a list of possible values |
| 34 | 4 | the image size. This is the size of the raw bitmap data; a dummy 0 can be given for BI_RGB bitmaps. |
| 38 | 4 | the horizontal resolution of the image. (pixel per metre, signed integer) |
| 42 | 4 | the vertical resolution of the image. (pixel per metre, signed integer) |
| 46 | 4 | the number of colors in the color palette, or 0 to default to 2n |
| 50 | 4 | the number of important colors used, or 0 when every color is important; generally ignored |
- Qu'est-ce qu'un fichier bmp ?
On donne le code suivant
#include <stdio.h>
#include <math.h>
int main()
{
char nom_fichier[20] = "image.bmp"; /* Attention au chemin */
FILE * ressource_fichier;
char nombre_magique[3] = "BM";
short int id_app1 = 0;
short int id_app2 = 0;
int largeur = 800;
int hauteur = 600;
int bpp = 24; // bits par pixel
int taille_metadonnees = 54;
int taille_image = ;
int taille_fichier = taille_image + taille_metadonnees;
int taille_entete = 40; // De l'octet 14 à l'octet 54
char b, g, r;
ressource_fichier = fopen(nom_fichier, "wb");
if(ressource_fichier != NULL)
{
printf("Le fichier est ouvert convenablement.\n");
/* L'entête d'un bmp tient sur 14 octet */
fwrite(&nombre_magique, 2, 1, ressource_fichier); // Octet 0
fwrite(&taille_fichier, 4, 1, ressource_fichier);
fwrite(&id_app1, 2, 1, ressource_fichier);
fwrite(&id_app2, 2, 1, ressource_fichier);
fwrite(&taille_metadonnees, 4, 1, ressource_fichier);
fwrite(&taille_entete, 4, 1, ressource_fichier); // Octet 14
fwrite(&largeur, 4, 1, ressource_fichier);
fwrite(&hauteur, 4, 1, ressource_fichier);
fputc(1, ressource_fichier); // Octet 26
fputc(0, ressource_fichier);
fwrite(, 2, 1, ressource_fichier);
fputc(0, ressource_fichier); // Octet 30
fputc(0, ressource_fichier);
fputc(0, ressource_fichier);
fputc(0, ressource_fichier);
fwrite(&taille_image, 4, 1, ressource_fichier); // Octet 34
for(int i = 0; i < 16; i++) // Octets 38 à 54
{
fputc(0, ressource_fichier);
}
for (int i = 0; i < hauteur; i++) {
for (int j = 0; j < largeur; j++) {
b = 0;
g = 0;
r = 0;
fwrite(&b,1,1,ressource_fichier);
fwrite(&g,1,1,ressource_fichier);
fwrite(&r,1,1,ressource_fichier);
}
}
printf("Nombre magique : %s\n", nombre_magique);
printf("Taille du fichier : %d\n", taille_fichier);
printf("Identifiant application 1 : %d\n", id_app1);
printf("Identifiant application 2 : %d\n", id_app2);
printf("Taille_Metadonnees : %d\n", taille_metadonnees);
printf("Taille en-tete : %d\n", taille_entete);
printf("Largeur : %d\n", largeur);
printf("Hauteur : %d\n", hauteur);
fclose(ressource_fichier);
}
else
{
printf("Erreur lors de l'ouverture du fichier.\n");
}
return 0;
}
- Combien de bits sont utilisés pour un pixel ? Combien d'octets cela fait-il ? A quoi correspondant chaque octet ?
- Comment calculer la taille d'une image en pixel ? En octets ?
- Copier-coller le code proposé. Compiler. Y a-t-il des erreurs ? Si oui, les corriger.
- Une fois la compilation réussie. Lancer l'exécutable obtenu. Que se passe-t-il ?
- Identifier la partie du code qui donne leurs couleurs aux pixels.
- Produire un gradient de couleurs.
- Produire autre chose.
13. Les chaînes de caractères
13.1. Exercice 1300 - Introduction aux chaînes de type C
En C une chaîne de caractère un tableau de char avec la particularité de se finir par le caractère '\0'. Une telle chaîne peut se définir à l'aide des doubles guillemets.
- Implémenter l'instruction
char mot[] = "Bonjour Toto!";. Combien de caractères contient cette chaîne ? - Afficher cette chaîne à l'aide de
printf. - Remplacer le troisème
opar unià l'aide de l'instructionmot[9] = 'i';(on observe qu'uncharest défini à l'aide des simples guillemets). Afficher la chaîne. - Remplacer le dernier
opar uni. Afficher la chaîne. - Remplacer le
rpar le caractère'\0'. Afficher la chaîne. Qu'observe-t-on ? - Remplacer le
jpar leint0. Afficher la chaîne. Qu'observe-t-on ? - Afficher le code du
charqui se trouve juste après le'!'.
13.2. Exercice 1301 - Afficher une chaine de caractères
Ecrire une fonction void afficher_chaine(char chaine[]) qui affiche à l'écran une chaîne de type
C.
Indication: utiliser la fonction putchar.
13.3. Exercice 1302 - Afficher une chaine de caractères à l'envers
Ecrire une fonction void afficher_chaine_envers(char chaine[]) qui affiche à l'écran une chaîne de type
C, à l'envers.
Indication: utiliser la fonction putchar.
13.4. Exercice 1303 - Palindrome
Ecrire une fonction int est_palindrome(char chaine[]) qui retourne
1 si la chaîne passée en paramètre est un palindrome et qui retourne
0 sinon.
13.5. Exercice 1305 - Longueur d'une chaîne de type C
Ecrire une fonction int longueur_chaine(char chaine[]) qui retourne la longueur de la chaîne de type
C passée en paramètre.
13.6. Exercice 1306 - Longueur d'une chaîne de type C - Bis
Ecrire une fonction int longueur_chaine(char * chaine) qui retourne la longueur de la chaîne de type
C passée en paramètre.
13.7. Exercice 1307 - Copier une chaîne de caractères
Ecrire une fonction void copier_chaine(char destination[], char
source[]) qui copie la chaîne de caractère source dans la chaîne
destination. Le caractère de fin de chaîne doit être pris en compte.
13.8. Exercice 1308 - Comparer deux chaînes de caractères
Ecrire une fonction int comparer_chaines(char chaine1[], char
chaine2[]) qui retourne :
0si les deux chaînes sont égales- un nombre négatif si
chaine1est inférieure àchaine2(dans l'ordre alphabétique) - un nombre positif si
chaine1est supérieure àchaine2(dans l'ordre alphabétique)
On utilisera l'ordre alphabétique de cette table.
13.9. Exercice 1310 - Recherche de caractère dans une chaîne
Ecrire une fonction de prototype int position_char(char * chaine, char car)
qui retourne :
- la position du caractère
cardans la chaînechainesicarest présent dans la chaîne - -1 sinon
13.10. Exercice 1311 - Vérifier qu'une chaîne de caractères ne contient que des chiffres
Ecrire une fonction de prototype int seulement_chiffres(char *
chaine), qui prend en paramètre une chaîne de caractères et qui
retourne :
1si la chaîne ne contient que des chiffres0sinon
13.11. Exercice 1312 - Convertir une chaîne contenant des chiffres en int
Ecrire une fonction de prototype
int chiffres_en_int(char * chaine)qui prend en paramètre une chaîne de caractères et qui :- vérifie que cette chaîne ne comporte que des chiffres (facultatif)
- retourne un
intcorrespondant à la valeur représentée par la chaîne
Remarque : on ne s'intéresse qu'aux nombres positifs dans un premier temps.
- Prendre en compte les nombres négatifs.
13.12. Exercice 1315 - Conversion chaîne de caractère en chaîne de codes ascii
Ecrire une fonction qui transforme une chaîne de caractères en la chaîne de caractères obtenue en concaténant les codes ascii en base 10 (sous forme de chaînes de caractères) de chacun des caractères de la chaîne de départ.
Par exemple pour l'entrée
"Bonjour! 2 + 2 = 4."
on obtient la sortie
66111110106111117114333250324332503261325246
Ecrire une fonction qui fais la même chose que la fonction précédente mais avec les codes ascii représentés à l'aide de deux chiffres en hexadécimal.
Par exemple pour l'entrée
"Bonjour! 2 + 2 = 4."
on obtient la sortie
426F6E6A6F7572212032202B2032203D20342E
13.13. Exercice 1320 - Conversion d'une chaîne de codes ascii en chaîne de caractères
Ecrire une fonction qui transforme une chaîne composée d'une suite de codes ascii en une chaîne de caractères "standard".
Par exemple pour l'entrée
66111110106111117114333250324332503261325246
on obtient la sortie
"Bonjour! 2 + 2 = 4."
On pourra supposer que tous les codes figurant dans la chaîne de départ sont compris entre 20 et 199.
13.14. Exercice 1325 - Conversion d'une chaîne de codes ascii hexadécimaux
Ecrire une fonction qui transforme une chaîne composée d'une suite de codes ascii en hexadécimal en une chaîne de caractères "standard".
Par exemple pour l'entrée
426F6E6A6F7572212032202B2032203D20342E
on obtient la sortie
"Bonjour! 2 + 2 = 4."
13.15. Exercice 1330 - Conversion d'une chaine de caractères en suite de bits
Ecrire une fonction qui transforme une chaîne de caractères en la chaîne de caractères obtenue en concaténant les codes ascii en base 2 (sous forme de chaînes de caractères) de chacun des caractères de la chaîne de départ.
Par exemple pour l'entrée
"Hi! 2+2=4."
on obtient la sortie
01001000011010010010000100100000001100100010101100110010001111010011010000101110
- Ecrire la fonction "réciproque", qui reconstruit la chaîne initiale depuis la suite de '0' et de '1'.
13.16. Exercice 1335 - Recherche de chaîne de caractères
Ecrire une fonction de prototype int souschaine(char * chaine1, char * chaine2) qui retourne
-1 si chaine2 n'est pas une sous-chaîne de chaine1 et la position de chaine2 dans chaine1
sinon.
13.17. Exercice 1340 - Mélanger deux chaînes de caractères
Ecrire une fonction de prototype
void melanger_chaines(char * cible, char * chaine1, char * chaine2)
qui construit une chaine en prenant le premier caractère de chaine1, le premier caractère de chaine2,
puis le deuximème caractère de chaine1, le deuxième de chaine2, etc… Si tous les caractères d'une
des deux chaînes ont été épuisés, on complète la cible à avec les caractères restants dans l'autre
chaîne.
Par exemple, le code :
int main()
{
char chaine1[] = "abcdefghijklmnop";
char chaine2[] = "ABCDEFGH";
char cible[500] = {};
melanger_chaines(cible, chaine1, chaine2);
printf("%s\n", cible);
return 0;
}
produit la sortie :
aAbBcCdDeEfFgGhHijklmnop
13.18. Exercice 1350 - Compter un caractère donné dans une chaine chaine analyser compter caractere
Ecrire une fonction de prototype
int compter_caractere(char * src, char car) qui compte le nombre de
fois que le caractère car est présent dans la chaîne src.
Vous pouvez tester votre fonction sur la chaîne
char test[] = "ALFA ROMEO ;159 ;ALFA ROMEO ;159 ;159 1750 Tbi (200ch) ;M10ALFVP000G340 ;939AXN1B52C ;ES ;non ;12;147;;M 6 ;11.3;5.8;7.8;182;0.647;0.052;0.032;;0.002;1505;1505;715/2007*692/2008EURO5 ;juin-14";
qui contient 25 caractères ;.
13.19. Exercice 1360 - chaine analyser compter caractere
Ecrire une fonction de prototype
int extraire_morceau(char * src, char * dest, int debut, char sep)qui :- recopie la sous-chaine de
srccomprise entre l'indicedebutet l'indice du premier caractèreseppositionner aprèsstart - retoure la position caractère se trouvant juste après le
septrouvé
Par exemple le le morceau de code suivant :
char test[] = "ALFA ROMEO ;159 ;ALFA ROMEO ;159 ;159 1750 Tbi (200ch) ;M10ALFVP000G340 ;939AXN1B52C ;ES ;non ;12;147;;M 6 ;11.3;5.8;7.8;182;0.647;0.052;0.032;;0.002;1505;1505;715/2007*692/2008EURO5 ;juin-14"; char dest[100]; int debut = 0; int nouveau_debut; nouveau_debut = extraire_morceau(test, dest, debut, ';'); printf("%d, %d\n", debut, nouveau_debut); printf(dest);affiche à l'écran :
0, 12 ALFA ROMEO
- recopie la sous-chaine de
Ecrire une boucle qui permette d'afficher la sortie suivante :
0, ALFA ROMEO 12, 159 17, ALFA ROMEO 29, 159 34, 159 1750 Tbi (200ch) 56, M10ALFVP000G340 73, 939AXN1B52C 86, ES 90, non 95, 12 98, 147 102, 103, M 6 108, 11.3 113, 5.8 117, 7.8 121, 182 125, 0.647 131, 0.052 137, 0.032 143, 144, 0.002 150, 1505 155, 1505 160, 715/2007*692/2008EURO5 184, juin-14
14. Communication avec l'environnement
14.1. Exercice 1400 - Une autre signature pour la fonction main
On donne le code ci-dessous :
#include <stdio.h>
int main(int argc, char* argv[])
{
return 0;
}
- Le code ci-dessus compile-t-il sans erreur ?
- Observer la signature de la fonction main. Quel est le type de
argc? - Afficher la variable
argc. Quelle valeur contient-elle ? - Quel est le type de
argv? - Afficher
argv[0]. Quelle valeur obtient-on ?
14.2. Exercice 1402 - Passer des paramètres au programme
Ecrire un programme arg.exe qui, lorsqu'il est appelé comme cela :
./arg.exe toto titi tutu
produit la sortie :
Nombre d'arguments : 4 L'argument 0 est : ./arg.exe L'argument 1 est : toto L'argument 2 est : titi L'argument 3 est : tutu
14.3. Exercice 1405 - Un programme pour les additionner des chiffres
Produire un programme addition_chiffres.exe qui, lorsqu'il est appelé comme cela :
./addition_chiffres.exe 3 9
produit la sortie :
Somme = 12
14.4. Exercice 1406 - Une première calculatrice
Produire un programme operation.exe qui, lorsqu'il est appelé comme cela :
./operation.exe 3 9 +
produit la sortie :
12
et comme ceci :
./operation.exe 60 18 -
produit la sortie :
-42
Les symboles autorisés pour le troisième argument sont '+', '-', '*' et '/'.
Remarques :
- Cet exercice requiert une fonction pour convertir une chaîne de caractères
contenant des chiffres en
int. - Que se passe-t-il pour l'opération
'*'.
14.5. Exercice 1408 - Une calculatrice complète en notation polonaise inverse
Produire un programme calc.exe qui, lorsqu'il est appelé comme cela :
./calc.exe 10 2 4 x 3 + x
produit la sortie :
110
et comme ceci :
./calc.exe 5 2 x 3 4 x +
produit la sortie :
22
14.6. Exercice 1410 - Nombre de caractères
Ecrire un programme qui compte le nombre de caractère d'un fichier passé en paramètre.
14.7. Exercice 1415 - malloc signature malloc
- A l'aide de la fonction
sizeofaficher la taille du typevoid. Que signifievoid?
La fonction malloc (raccourci pour memory allocation) permet d'allouer dynamiquement de la mémoire vive à un programme.
- En effectuant un appel à la fonction
mallocet en utilisant les messages fournis par le compilateur, deviner :- Le nombre et le type de paramètres requis par la fonction
malloc. - Le fichier
.hdans lequel est définimalloc.
- Le nombre et le type de paramètres requis par la fonction
- En stockant le résultat renvoyé par
mallocdans une variableadr, et en utilisant les messages fournis par le compilateur, deviner le type de retour de la fonctionmalloc. - Allouer 100 Mo de mémoire vive.
- Afin d'empêcher la fermeture instantanée du programme, faire un appel à
getcharjuste avant lereturndumain. - Ouvrir le gestionnaire des tâches (pour Windows, top pour linux, activity monitor pour mac), lancer le programme, puis rechercher ce même programme dans la liste des processus. Qu'observe-t-on ?
- A l'aide d'une boucle
forstocker une valeur dans chacun des octets alloués à la question 4. Qu'observe-t-on dans le gestionnaire de tâches ? - Qu'observe-t-on alors dans le gestionaire de tâches ?
- Libérer la mémoire allouée à l'aide de la fonction
free, après l'appel àgetchar. - Afin d'avoir le temps d'observer la libération de mémoire, appeler une seconde fois
getcharaprès l'appel àfree.
14.8. Exercice 1416 - malloc 2 malloc
- Demander à l'utilisateur combien d'octets il souhaite allouer (en Mo).
- Recueillir la réponse à l'aide de
scanf. - Allouer effectivement la mémoire et y stocker des 0.
- Tester si l'allocation a bien fonctionné.
- Tant que la quantité souhaitée est non nulle, recommencer 1., 2., 3. et 4. (utiliser une boucle while).
- Exécuter le programme tout en observant le gestionnaire de tâches.
- Comment libérer proprement la mémoire ?
- Imaginer un programme malveillant qui sature la mémoire de l'hôte.
14.9. Exercice 1420 - Allocation dynamique de mémoire et tableau allocation dynamique
Cette exercice peut utiliser fonctions_utiles.h.
Ecrire un programme qui :
- demande à un utilisateur d'entrer un nombre \(n\)
- alloue dynamiquement la mémoire nécessaire pour stocker \(n\)
doubledans un entier - demande à l'utilisateur de saisir \(n\) valeurs réelles
- stocke chacune de ces valeurs dans la mémoire précedemment allouée
- affiche le tableau
- libère la mémoire allouée
14.10. Exercice 1430 - Allocation de mémoire et tableau 2d
Ecrire un programme qui :
- demande à l'utilisateur un nombre n de lignes à saisir
- alloue la mémoire nécessaire pour stocker n variables de type
char * - demande à l'utilisateur de taper n phrases
- à chaque phrase alloue la mémoire nécessaire pour stocker cette phrase; le pointeur renvoyé par
malloclors de la ième allocation est stocké dans la ième case du tableau dechar *ci-dessus - enregistre chacune des phrases au bon endroit
- affiche les n phrases en colonne (voir exemple ci-dessous)
- libère convenablement la mémoire allouée
Un exemple d'exécution pourrait être :
Nombre de lignes :3 Bonjour Toto Hi Titi Guten Tag Titi BHG oiu n t jTe oin ut riT a T g o t T o i t i
15. Opérations sur les bits
15.1. Exercice 1500 - Opérateurs bit à bit (bitwise operator)
- Déclarer deux variables
netpde typeint, respectivement initialisées à 170 et à 27. Afficher (
%ude préférence) les valeurs auxquelles sont évaluées les expressions :n&pn|pn^p~n~p
Qu'observe-t-on ?
- Donner les expressions binaires de tous les nombres qui interviennent ci-dessus. Qu'observe-t-on ?
15.2. Exercice 1510 - Le dernier bit à 0
Ecrire une fonction de prototype int dernierBitAZero(int entier). Cette fonction doit
mettre le bit de poids faible de entier à 0.
15.3. Exercice 1520 - Le dernier bit à 1
Ecrire une fonction de prototype int dernierBitAUn(int entier). Cette fonction doit
mettre le bit de poids faible de entier à 0.
15.4. Exercice 1530 - Bit shifts
- Initialiser une variable
nde typeintà 1. - Afficher les valeurs prises par les expressions
n << 1,n << 2,n << 8,n << 9,n << 16. Qu'observe-t-on ? - Recommencer avec d'autres valeurs de
n.
15.5. Exercice 1535 - Représentation binaire d'un int shift masque representation binaire
- Implémenter une fonction
void binaryPrintf(int n)qui affiche les 32 bits de la représentation binaire duintpassé en paramètre. La fonction doit utiliser les bitwise shifts. - Que faire si on se trouve sur une architecture où les
intne sont pas codés sur 32 bits ?
Indication: si vous utilisez un masque, choisissez le de type unisgned int (pourquoi?).
15.6. Exercice 1540 - Boutisme (Endianness) boutisme conversion pointeurs
Ecrire un programme qui déclare un int à la valeur 1416590447. Interpréter cet int
comme un tableau de caractères que l'on affichera.
Quel mot découvre-t-on ?
Remarque : on réimplémentera ou réutilisera la fonction void afficher_tab_char(char tab[], int taille).
16. Structures
16.1. Exercice 1600 - Première structure structures sizeof struct
On considère le code ci-après :
#include <stdio.h>
struct point
{
double abs; /* l'abscisse du point */
double ord; /* l'ordonnee du point */
}; /* attention au point virgule */
int main()
{
struct point mon_point;
struct point mon_deuxieme_point = {-3.5, 6.8};
mon_point.abs = 2.3; /* initialisation de l'abscisse de point */
mon_point.ord = 3.7; /* initialisation de l'ordonnee de point */
return 0;
}
- Tester le code ci-dessus. Ce propose la modélisation d'un point du plan à l'aide d'une structure.
- Afficher l'abscisse et l'ordonnée des deux points.
- Afficher, à l'aide de
sizeof, la taille occupée en mémoire par la structurepoint.
16.2. Exercice 1605 - Poursuivre la familiarisation avec les structures structures tableau
- Reprendre la structure
struct pointde l'exercice 1600. - Déclarer un tableau de 4 points.
- Initialiser les points du tableaux de sorte qu'ils forment un carré.
- Afficher les points du tableaux sont la forme
{(x1,y1),(x2,y2),(x3,y3),(x4,y4)}. - Copier-coller le résultat de la question précédente dans https://www.geogebra.org. Obtient-on bien un carré ?
- Comment déterminer le centre du carré ?
16.3. Exercice 1610 - Quelques fonctions pour les points sruct fonctions
Cet exercice utilise la structure point.
- Ecrire et tester une fonction de prototype
double distance_carree(struct point p1, struct point p2)qui retourne le carré de la distance euclidienne entre les pointsp1etp2. - Ecrire une fonction de prototype
double distance(struct point p1, struct point p2)qui retourne la distance euclidienne entre les pointsp1etp2.
16.4. Exercice 1615 - Approximation de pi à l'aide de points struct point monte carlo
Cet exercice utilise la structure point.
- Déclarer un tableau de 1000
point. - Initialiser aléatoirement et uniformément sur \([0;1]\) les abscisses et les
ordonnées de ces points. On pourra utiliser les fonctions
randetsranddestdlib.h. - Compter les points qui sont à une distance au point \((0.5,0.5)\) inférieure à 0.5.
- Rappeler la formule qui donne l'aire d'un disque.
- Déduire de 3. et de 4. une approximation de \(\pi\).
- Recommencer avec un plus grand nombre de points.
- Commenter.
16.5. Exercice 1630 - Structure et modularité
Ecrire un fichier geometrie.h qui contient la structure point précédemment introduite.
16.6. Exercice 1635 - Un alias pour les points typedef alias structure
- Regrouper dans un même fichier :
- la structure représentant un point (
struct point) - la fonction
distance_carree - la fonction
distance
- la structure représentant un point (
- Déclarer trois points
A,BetC. Initialiser ces points de trois manières différentes.
Il est pénible de taper struct point à chaque fois que l'on souhaite manipuler une variable représentant un point. Le C permet de donner un surnom (ou alias) à un type de donnée. Il faut pour cela utiliser le mot-clef typedef.
Donner l'alias
Pointau type de donnéestruct pointà l'aide de l'instructiontypedef struct point Point.- Déclarer un nouveau point
Dà l'aide de l'aliasPoint. - Peut-on utiliser la fonction
distanceavec le pointD? - Utiliser l'alias
Pointdans le prototype de la fonctiondistance.
16.7. Exercice 1640 - Une structure en paramètre de fonction struct fonctions parametre
Ecrire une fonction de prototype
void set_abs(struct point * p, double nouvelle_abs) qui met à jour
l'abscisse du point passé en paramètre.
Pourquoi utiliser un pointeur ?
Ecrire de même la fonction
void set_ord(struct point * p, double nouvelle_ord).
16.8. Exercice 1650 - Une structure contenant un tableau struct fonctions parametre valeur
Exécutez le code ci-après et commentez les différentes adresses mémoire observées.
Que se passe-t-il au niveau des adresses mémoire si on utilise un
tableau de 48 char au lieu de 50 char pour le nom ?
#include <stdio.h>
#include <string.h>
struct Bonhomme {
char nom[50];
int age;
};
void modifier_bonhomme(struct Bonhomme b)
{
printf("adr b : %p, adr b.nom %p, adr b.age : %p (dans la fonction)\n", &b, &b.nom, &b.age);
strcpy(b.nom, "Titi");
b.age = 42;
}
int main(int argc, char* argv[])
{
struct Bonhomme monBonhomme = {"Toto", 23};
printf("adr monBonhomme : %p, adr monBonhomme.nom : %p, adr monBonhomme.age : %p\n",
&monBonhomme, &monBonhomme.nom, &monBonhomme.age);
printf("nom : %s, age : %d\n", monBonhomme.nom, monBonhomme.age);
modifier_bonhomme(monBonhomme);
printf("adr monBonhomme : %p, adr monBonhomme.nom : %p, adr monBonhomme.age : %p\n",
&monBonhomme, &monBonhomme.nom, &monBonhomme.age);
printf("nom : %s, age : %d\n", monBonhomme.nom, monBonhomme.age);
return 0;
}
16.9. Exercice 1660 - Une structure pour les nombres complexes struct fonctions
- Ecrire une structure
struct complexepermettant de représenter un nombre complexe. Cette structure doit disposer d'un champsrede typedoubleet d'un champimde typedouble. - Ecrire une fonction
double module(struct complexe z)qui retourne le module du nombre complexe. - Ecrire une fonction
double argument(struct complexe z)qui retourne l'argument (dans \(]-\pi;\pi]\)) dez. On pourra utiliser la formule \(\text{arg}(z=x+iy)=2\arctan\left(\frac{y}{\sqrt{x^{2}+y^{2}}+x}\right)\) lorque \(z\) n'est pas un réel négatif ou nul. Ecrire une fonction
void afficher_complexe(struct complexe z)qui affichezsous la forme "partie rélle + partie imaginaire fois i". Par exemple, sistruct complexe z = {1, 2};alors l'appel à la fonction
afficher_complexe(z)affiche :1+2iEcrire une fonction
void modifier_re(struc complexe * z, double nouveau_re)qui modifie la partie réelle du nombre complexe dont l'adresse est passée en paramètre. Par exemple, le code :struct complexe z = {2, -3.5}; afficher_complexe(z); modifier_re(&z, 42); afficher_complexe(z);produit la sortie :
2+-3.5i 2+42i
- Ecrire une fonction analogue pour la partie imaginaire.
- Améliorer la fonction
afficher_complexepour tenir compte d'une partie réelle ou imagine nulle ou négative.
17. Structures de données
17.1. Exercice 1700 - Une structure pour les triangles structures typedef alias tableaux
- Implémenter une structure de données
struct pointpermettant de modéliser un point du plan. - Déclarer et initialiser 3 points A, B et C, en utilisant trois manières différentes.
- En utilisant le mot réservé
typedefdonner l'alias (le surnom)Pointà la structure précédemment définie. - Déclarer et initialiser un point E et un point F à l'aide de cet alias.
- Implémenter une fonction de signature
float longueur(Point A, Point B)qui calcule la longueur entre deux points. Tester cette fonction.
On souhaite désormais représenter un triangle à l'aide d'un tableau de
type Point [].
- Déclarer est initialiser un tableau
t1contenant troisPoint. - Implémenter une fonction de prototype
float perimetre(Point t[]). Tester. - Implémenter une fonction
void afficher_tr(Point tr[]). - Comment translater un point ? Un triangle ?
17.2. Exercice 1730 - Vers les listes simplement chaînées liste structures
17.2.1. Première partie
Une liste simplement chaînée est une structure de donnée dynamique permettant de stocker un nombre (variable) de valeurs, que l'on peut représenter comme suit :
tete | v +----------+ +----------+ +----------+ | | | | | | | | | | 45 | ----->| 97 | ----->| -3 | -----> ∅ | | | | | | | | | +----------+ +----------+ +----------+
- 45, 97 et -3 sont les trois valeurs stockées dans la liste
- une flèche indique l'emplacement de l'élément suivant
Le but de l'exercice est de se familiariser avec certaines notions préalables à l'implémentation de cette structure. Un élément de la liste est constitué d'une valeur et d'une flèche (qui est l'adresse de l'élément suivant).
+-----------+ +---------------------+ | | | | | adresse de | | 97 | ------> <=> | valeur | l'élément | | | | | | suivant | +-----------+ +---------------------+
- Implémenter, à l'aide du mot réservé
structune structure représentant un élément de la liste. - A l'aide de
typedef, surnommer (alias)Elementcette structure. - Déclarer trois
Elementsnommépremier,deuxiemeettroisieme. - Faire en sorte que
premierstocke la valeur45, quedeuxiemestocke la valeur97et quetroisiemestocke la valeur-3. - Afficher la valeur stockée dans
premier. - Faire en sotre que l'adresse du suivant de
premiersoit l'adresse dedeuxieme. - Faire en sotre que l'adresse du suivant de
deuxiemesoit l'adresse detroisieme. - Quelle doit être l'adresse du suivant de
troisieme? - En utilisant la variable
premierafficher la valeur stockée dansdeuxieme. - En utilisant la variable
premierafficher la valeur stockée danstroisieme. Implémenter une fonction de prototype
void afficher(Element * adr_el)de telle sorte que l'appelafficher(&premier)produise une sortie ressemblant à :
45 à l'adresse 0x7ffe8840b760 97 à l'adresse 0x7ffe8840b750 -3 à l'adresse 0x7ffe8840b740
- Implémenter une fonction de prototype
int longueur(Element * adr_el)permettant de calculer la longueur de la liste commençant à l'élément d'adresseadr_el. Tester.
17.2.2. Deuxième partie
On aimerait pouvoir ajouter un quatrième élément à la liste, lors de l'exécution du programme.
- Reprise. Déclarer un
Elementnomméquatriemeet qui contient la valeur 23. - "Accrocher" cet élément à la fin de la liste.
- A l'aide de
scanfdemander à l'utilisateur s'il souhaite ajouter une valeur à la liste. Si oui, lui demander quelle valeur il souhaite ajouter et stocker cette valeur dans une variabletmp. Sinon, le programme s'arrête. - Afficher la valeur que l'utilisateur à saisie. Pour l'instant cette valeur n'est pas encore ajoutée à la liste.
- Déclarer une variable
adr_cinquieme. Quel est le type de cette variable? - A l'aide de
mallocallouer la mémoire permettant de stocker unElementsupplémentaire. Affecter l'adresse retournée parmallocdansadr_cinquieme. - Stocker la valeur
tmpdansadr_cinquieme->valeur. - Faire en sorte que l'adresse du suivant du cinquième élément soit
NULL. - Afficher à nouveau la liste à l'aide de
afficher. - Observer l'adresse de l'élément ajouté à l'exécution du programme. Que constate-t-on ?
- Libérer la mémoire allouée pour le cinquième élément.
17.2.3. Troisième partie
- Implémenter une fonction de prototype
Element * adr_dernier(Element * adr_el)qui prend en parammètre l'adresse d'un élément et qui retourne l'adresse du dernier élément de la liste qui commence par l'élément d'adresseadr_el. Que faire siadr_elestNULL? - Implémenter une fonction de prototype
ajouter_valeur(Element * adr_el, int val)qui ajoute dynamiquement (malloc) la valeurvalà la liste dont le premier élément a pour adresseadr_el. On suppose que l'élément à l'adresseadr_elexiste (c'est-à-dire que la liste n'est pas vide). Quel est le problème si la liste est vide ? - Implémenter une fonction de prototype
liberer_memoire(Element * adr_el)qui libère la mémoire allouée aux élements suivants l'élément d'adresseadr_el. - Quel est le problème avec les listes vides ? Que se passe-t-il si on ajoute un élément à l'adresse
NULLpar exemple ?
18. Rétro-ingénierie
18.1. Exercice 1800 retro
On cherche une fonction f telle que les appels
f("72101108108111328711111410810033")
f("8511032112101117321001013211410111611411145105110103101110105101114105101")
f("851103211611411110511510510110910132101120101109112108101")
retournent respectivement
"Hello World!" "Un peu de retro-ingenierie" "Un troisieme exemple"
- Implémenter
f. - Que vaut
f("66111110106111117114326710497116718084")?
18.2. Exercice 1810 retro
Appels:
f('A')
f('a')
f('1')
f('2')
Affichage:
1010 1010 1 10
f('b').f('9').
18.3. Exercice 1820 retro
Appels:
f(42) f(17) f(255) f(1)
Valeurs retournées:
3 2 8 1
19. Hasard
19.1. Exercice 1900 - Les fonctions rand et srand aleas rand srand
- Inclure la librairie
stdlib.h. - Afficher le résultat d'un appel à la fonction
rand. - Afficher 20 nombres aléatoires à l'aide d'une boucle.
- Exécuter plusieurs fois le programme. Que constate-t-on ?
- Appeler la fonction
srandune fois avant le premier appel àrand. - Modifier la valeur du paramètre de
srand. - Inclure la librairie
time.h. - Afficher le résultat de l'appel
time(NULL). Exécuter plusieurs fois le programme. - Utiliser la fonction
timepour faire un appel àsranddifférent à chaque exécution du programme.
19.2. Exercice 1910 - Loi uniforme sur un intervalle loi uniforme aleas rand
- Afficher la valeur maximale que la fonction
randpuisse retourner (cette valeur est contenu dans la variableRAND_MAXde la librairiestdlib.h). - Ecrire une fonction de prototype
double loi_uniforme(double a, double b)qui retourne un nombre réel aléatoire compris entre les réelsaetb. - Tester la fonction
loi_uniforme.
20. Le préprocesseur
20.1. Exercice 2000
- Produire un fichier
exo2000.ccontenant exactement le code source suivant :
int main() {
return 0;
}
- Compiler ce programme en utilisant l'option
Edu compilateur :gcc -E exo2000.c. Que se passe-t-il ? Le programme est-il vraiment compilé ? - Ajouter la directice
#include <stdio.h>au début du fichiet et recommencer l'étape de la question précédente. Qu'observe-t-on ? - Ajouter la directive
#define TOTO 42juste après la directive#defineprécédente et recompiler avec l'optionE. Qu'obeserve-t-on ?
21. Approfondissement
21.1. Exercice 10000 - Un échange astucieux
Trouver un moyen d'échanger le contenu de deux variables sans avoir recours à une variable auxiliaire.
21.2. Exercice 10005 - Allocation dynamique et typage
- Déclarer une variable
char * tab. - Allouer un tableau de 2
charà l'adressetab. - Affecter la valeur 0 à l'adress
tabet 1 à l'adressetab+1. - Afficher ce qui se trouve à l'adresse
tabaprès l'avoir converti enshort int *. - Expliquer le résultat obtenu.
- Libérer la mémoire allouée.
21.3. Exercice 10010 - Représentation binaire representation binaire bitshift boucles
Ecrire une fonction qui prend en paramètres un unsigned char et un
char *. Le paramètre de type char * pointe vers un tableau de char
permettant de stocker une chaîne de 8 catactères. La fonction doit
établir la représentation binaire du paramètre de type unsigned char
dans le tableau pointé par le deuxième paramètre.
21.4. Exercice 10015 - Depuis la représentaton binaire
Ecrire une fonction qui prend en paramètre une chaîne de 8 caractère composée de '0' et de '1'
et qui retourne le unsigned char correspondant.
21.5. Exercice 10020 - Conversion de pointeur
- Vérifier que sur votre environnment, un
long intest codé sur 8 octets. - Déclarer une variable
nde typelong int.
On souhaite que l'exécution des lignes de code suivantes :
char * tab = (char*)&n;
int i;
for(i=0;i<8;i++)
{
putchar(*(tab+i));
}
produise l'affichage :
Bonjour!
- A quelle valeur entière faut-il initialiser
npour obtenir ce résulat ?
21.6. Exercice 10025 - Distance à l'origine
Requiert geometrie.h.
- Dans un fichier geometrie.c, écrire une fonction de prototype
double distance_carre(struct point p)qui calcule le carré de la distance euclidienne entre l'origine et le pointp. - Placer le prototype de la fonction dans geometrie.h.
21.7. Exercice 10030 - Stéganographie
Pré-requis : ** Exercice 1250 - Lire un fichier en mode binaire
L'image paysage.bmp dissimule une information codée. Chaque pixel de cette image dispose d'une couleur déterminée par un triplet d'entiers noté (b,g,r), pour (blue, green, red). Chacune des trois valeurs est comprise entre 0 et 255. Par exemple (0,255,0) représente le vert "pur".
Un changement "de 1" dans la valeur d'une des couleurs est imperceptible à l'oeil nu. Par exemple, (123, 48, 84) et (122, 48, 84) représente deux couleurs quasiment indistingables. On peut alors modifier la parité de b, de g ou de r pour dissimuler de l'information. Dans cette exercice une image en noir et blanc à été codée dans la quantité de bleu (b) de l'image ci-dessus. Un pixel avec un b impair correspond à un pixel noir dans l'image codée tandis qu'un b pair correspond à un pixel blanc.
L'exercice consite à écrire un programme qui produit un fichier image_decodee.bmp.
21.8. Exercice 10035 - Chiffrement par décalage
Implémenter une fonction de prototype
void chiffrement_decalage(char * source, char * cible, char * alphabet, int longueur_alphabet, int decalage)
qui chiffre
par décalage la chaîne de caractères source a l'aide de l'aphabet alphabet avec un décalage de
decalage. La chaîne chiffrée est stockée à l'adresse cible. La longueur de l'alphabet est passée en
paramètre.
Par exemple, si source="bonjour le monde", alphabet="abcdefghijklmnopqrstuvwxyz ",
decalage=5, alors cible="gtsotzweqjertsij".
21.9. Exercice 10040 - Déchiffrement par décalage
Implémenter une fonction de prototype
void dechiffrement_decalage(char * source, char * cible, char * alphabet, int longueur_alphabet, int decalage)
qui déchiffre une chaîne de caractères chiffrée par la fonction
void chiffrement_decalage(char * source, char * cible, char * alphabet, int longueur_alphabet, int decalage)
précedemment codée.
21.10. Exercice 10045 - PCR boucle recurrence
Lors d'une réction de polymérase en chaîne (PCR) les quantités suivantes interviennent:
\(A_{n}\): quantité de brins d'ADN natif sens
\(B_{n}\): quantité de brins d'ADN antisens bien défini à l'extrémité 5' correspondants à l'amplicon
\(C_{n}\): quantite de brins d'ADN sens bien définis aux deux extrêmités correspondants à l'amplicon
\(D_{n}\): quantite de brins d'ADN antisens bien définis aux deux extrêmités correspondants à l'amplicon
\(E_{n}\): quantité de brins d'ADN sens bien défini à l'extrémité 5' correspondants à l'amplicon
\(F_{n}\): quantité de brins d'ADN natif antisens
A chaque cycle ces grandeurs sont liées par les relations :
\(\begin{cases}A_{n+1}=A_{n}\\B_{n+1}=B_{n}+A_{n}\\C_{n+1}=C_{n}+B_{n}+D_{n}\\D_{n+1}=D_{n}+E_{n}+C_{n}\\E_{n+1}=E_{n}+F_{n}\\F_{n+1}=F_{n}\end{cases}\)
On suppose que \(A_{0}=F_{0}=1\) et \(B_{0}=C_{0}=D_{0}=E_{0}\).
Ecrire un programme qui donne les quantités des différents constituants pour les vingt premiers cycles.
21.11. Exercice 10050 - Devinette
Ecrire un programme qui demande à l'utilisateur de devinez un nombre préalablement tiré au hasard entre 0 et 100. A chaque tour, le programme doit indiquer à l'utilisateur s'il a trouvé le bon nombre. Sinon le programme indique si le nombre proposé est plus grand ou plus petit que le nombre recherché. L'utilisateur à un nombre d'essais fixé à l'avance.
21.12. Exercice 10060 - Exploiter de vraies données
- Télécharger le fichier fic_etiq_edition_40-mars-2015.csv. Ce fichier provient du site https://www.data.gouv.fr/fr/datasets/emissions-de-co2-et-de-polluants-des-vehicules-commercialises-en-france/ et servira de prétexte à la manipulation de données réelles.
- Ouvrir le fichier à l'aide d'un tableur et examiner le. Combien y-a-t-il de colonnes ? A quoi sert la premiere ligne?
- Ouvrir le ficher avec un éditeur de texte. Quel caractère est utilisé pour séparer deux colonnes ?
On aimerait exploiter les données à l'aide d'un programme informatique. On va représenter les données de ce tableau à l'aide d'une structure :
struct vehicule {
char lib_mrq_doss[30];
char lib_mod_doss[30];
char mrq_utac[20];
char mod_utac[20];
char dscom[50];
char cnit[30];
char tvv[20];
char energ[20];
char hybride[10];
int puiss_admin;
int puiss_max;
int puiss_heure;
char typ_boite_nb_rapp[10];
float conso_urb_93;
float conso_exurb;
float conso_mixte;
int co2_mixte;
float co_typ_1;
float hc;
float nox;
float hcnox;
float ptcl;
int masse_ordma_min;
int masse_ordma_max;
char champ_v9[20];
char date_maj[20];
};
- Ecrire un programme permettant de stocker chacun des véhicules du fichier en mémoire, à l'aide de la structure ci-dessus.
21.13. Exercice 10070 - Type punning 1 pointeurs type conversion
Le but de cet exercice est de stocker un nombre réel (a priori de type
float) dans une variable de type uint32_t, sans perdre de précision.
- Vérifier qu'un
floatest qu'unuint32_toccupent la même place en mémoire. - Vérifier que deux conversions consécutives, comme
(float)(uint32_t)xperd de l'information. - Déclarer une variable
mde typeunint32_tet une variableyde typefloat. - Dans la variable
m, déréférencer l'adresse dex, préalablement convertie enuint32_t*. Afficher le contenu dem. - Dans la variable
y, déréférencer l'adresse dem, préalablement convertie enfloat*. Afficher le contenu dey.
21.14. Exercice 10080 - Type punning 2 pointeurs type conversion
- Déclarer une variable
nde typeuint32_tcontenant la valeur1078530011. Cette valeur correspond à une suite de 32 bits en mémoire. - Quel est le
float(en norme IEEE 754) représenté par cette suite de bits ?
21.15. Exercice 10090 - Norme IEEE 754 type memcopy
- Déclarer une variable
nde typeintet une variablex, de typefloat. - Affecter la valeur 1078530011 à
n. - A l'aide de la fonction
memcopyde la librairiestring.hcopier les octets se situant à l'adresse&nà l'adresse&x. - Afficher
x. Quelle valeut opbtient-on ?