TP C PDF
TP C PDF
TP C PDF
TP/TD de Programmation C
2016-2017
Sommaire
2. Création du projet
3. Configuration du projet
Sélectionner l’icône Fichier C++ et donner un nom à votre fichier (par exemple
Premier Programme) ainsi que la localisation de ce fichier sur le disque dur (par
défaut, il indique le répertoire correspondant à votre projet, nous vous conseillons de
conserver ce paramètre). Pour terminer, cliquer sur Ajouter.
5. Edition du programme
-2-
Le programme ouvert est vide, et vous devez alors saisir dans la fenêtre d’édition
votre programme. Ici par exemple, nous allons faire un programme qui réalise
l’addition de deux nombres entiers.
-3-
B) Compilation et exécution d’un programme
Pour être exécuté par votre ordinateur, le programme doit être traduit en langage
machine : c’est le langage que comprend le microprocesseur. C’est le compilateur
qui est chargé de cette tâche. Son rôle est tout d’abord de vérifier la bonne écriture
de votre programme (analyse syntaxique) puis de le traduire en langage machine.
6. Compilation du Programme
Si votre programme est écrit correctement (c'est-à-dire, suivant les règles du langage
C), le compilateur vous indique que la tâche de compilation n’a pas provoqué
d’erreurs (fenêtre du bas).
Si vous remarquez des erreurs, appuyez sur F4 et corrigez les.
Une fois que le programme ne comporte plus d’erreur, il est nécessaire d’effectuer
ce qu’on appelle l’édition des liens. En effet, les programmes en C utilisent
généralement des bibliothèques de fonctions prédéfinies et précompilées (par
exemple, la bibliothèque stdio.h contient la fonction printf()). Lors de la
phase d’édition des liens, le compilateur va ajouter le code objet correspondant à
cette fonction printf() au code généré lors de la phase précédente. Cette phase
peut également générer des erreurs si les correspondances entre les librairies et les
fonctions utilisées sont incorrectes.
8. Exécution du programme
Vous pouvez alors lancer l’exécution du programme, en vous rendant dans le menu
Debug / Exécuter (marqué par une icône représentant un point d’exclamation ou
CTRL+F5).
-4-
Afin de visualiser le résultat obtenu par notre programme, nous allons ajouter une
fonction qui permet de visualiser sur l’écran une chaîne de caractères. Pour cela
ajouter la ligne suivante au bon endroit dans votre programme :
Faire la compilation et l’édition des liens. Si vous observez des erreurs, corrigez-
les…
Une fois que le programme ne comporte plus d’erreurs et que l’édition des liens s’est
déroulée correctement, exécuter votre programme.
Une console s’ouvre et doit afficher le résultat de votre calcul. Dans l’exemple
proposé, on obtient un affichage tel qu’il est représenté ci-dessus.
-5-
C) « Monsieur, ça marche pas… »
Durant ces séances de TP, vous allez être confrontés à 2 types de problèmes :
1. Le compilateur indique que le programme contient des erreurs
2. Le programme se compile correctement, mais à l’exécution ça plante ou vous
n’obtenez pas le bon résultat
Conseil :
Afin de ne pas vous retrouver avec des dizaines voire des centaines d’erreurs à la
compilation, je vous suggère vivement de compiler régulièrement votre programme.
Une erreur "vraie" peut éventuellement déclencher plusieurs messages d'erreur. La
correction de cette seule erreur enlèvera donc tous les messages. De même, parfois
le compilateur "se perd" et génère beaucoup plus de messages que d'erreurs,
certains de ces messages étant erronés. Il est donc conseillé de corriger la 1ere
erreur (attachée au 1er message), de recompiler etc… jusqu'à ce qu'il n'y ait plus
d'erreurs.
Dans le deuxième cas, il faut se munir d’un autre outil qu’on appelle le
« débogueur ».
Déboguer un programme
Exercice : Cet exercice consiste à créer un programme qui permet de faire le calcul
N
suivant : somme= åi
i=1
-6-
Tapez le code suivant dans l’éditeur de texte de Visual Studio (partez du projet
existant) :
#include <stdio.h>
for(i=1;i<=N; i++);
{
somme=somme+i;
}
printf("somme=%d\n",somme);
}
-7-
L’interface de Visual Studio permet un débogage relativement aisé des programmes.
La première étape du débogage consiste à insérer des points d’arrêt :
Pour insérer un point d’arrêt, cliquez simplement dans la marge à gauche de la fenêtre
d’édition à l’endroit où vous voulez que le programme s’arrête lors de l’exécution.
Un point rouge apparaît alors à l’endroit où vous avez cliqué.
Dans cet exemple, on va mettre un point d’arrêt au niveau de la boucle for, puis
exécuter en mode pas à pas le programme.
On va maintenant exécuter en mode pas à pas tout le programme. Pour cela, aller
dans le menu Debug et essayez les différentes possibilités :
➔ Step Into (F11)
➔ Step Over (F10)
➔ Step Out (SHIFT+F11)
➔ Restart (CTRL+SHIFT+F5)
-8-
- Enfin, si vous êtes entrés dans un bloc d’instruction ou une fonction pour une
exécution pas à pas, mais que vous voulez en sortir, vous pouvez alors faire un Step
Out, qui vous permet de venir à l’instruction suivant le bloc.
- Quand vous avez plusieurs points d’arrêt, vous pouvez lancer l’exécution en mode
Debug plusieurs fois : l’exécution s’arrêtera systématiquement au prochain point
d’arrêt.
Conseil :
Utilisez de préférence le Step Over (touche F10) lorsque vous ne voulez pas rentrer
dans le détail de l’exécution de fonctions tels que le printf()
-9-
D) Raccourcis utiles
Edition :
Compilation :
Ctrl + F7 : Compiler
F7 : Build
Ctrl + F5 : Exécuter
Debug:
F5: Debug
F11: Step Into
F10: Step Over
Shift + F11: Step Out
Aide:
E) Remarque finale
- 11 -
TP 1 : INITIATION AU LANGAGE C
PROBLEME 1
- 13 -
Vous remarquerez que la fonction scanf() qui permet de saisir une valeur au clavier
et de la stocker en mémoire est indiquée comme étant « désapprouvée ». En effet,
vous pourrez vous-même faire l’expérience de certains inconvénients de cette
fonction plus tard.
En attendant, vous avez 2 possibilités pour supprimer les avertissements obtenus :
Soit vous remplacez simplement la fonction scanf() par scanf_s() qui est la version
sécurisée de scanf() et approuvée par le compilateur
Soit vous allez dans les propriétés du projet pour indiquer au compilateur que
vous n’êtes pas concernés par ces avertissements : pour cela, clic droit sur le nom
du projet, Propriétés, Propriétés de Configuration, C/C++, Préprocesseur et ajouter
à « Préprocesseur définitions » la valeur
_CRT_SECURE_NO_DEPRECATE
PROBLEME 2 : Pyramide
Nombre de lignes : 8
*
*o*
*ooo*
*ooooo*
*ooooooo*
*ooooooooo*
*ooooooooooo*
***************
- 14 -
TP 2 : STRUCTURES DE CONTRÔLE
On veut faire afficher un damier de n par n cases. Les cases noires (resp. blanches) sont
représentées par p * p un caractère C1 (resp. C2). Par exemple pour n=4, p = 3, C1=&,
C2=+, le programme doit afficher :
&&&+++&&&+++
&&&+++&&&+++
&&&+++&&&+++
+++&&&+++&&&
+++&&&+++&&&
+++&&&+++&&&
&&&+++&&&+++
&&&+++&&&+++
&&&+++&&&+++
+++&&&+++&&&
+++&&&+++&&&
+++&&&+++&&&
Question 2 :
Ecrire trois versions de la partie affichage du damier proprement dit n'utilisant que des
structures itératives ("pour", "tant que", "jusqu'à ce que"). L'exécution de ces trois
versions sera contrôlée par un menu interactif. Par exemple sur l'écran s'affichera le teste
suivant :
- 15 -
- en utilisant la structure pour (réponse c ou
C)
- acquérir de nouvelles valeurs pour n, p, C1
et C2 (réponse d ou D)
Indications : l'impression se fait caractère par caractère. Pour ce faire on peut utiliser
soit la fonction printf() soit la fonction putchar(). Par exemple pour
imprimer la lettre 'a', on peut écrire :
- Soit putchar ('a');
- Soit printf("%c",'a');
- 16 -
TP 3 : TABLEAUX A UNE DIMENSION
Exercice 1 :
a. Saisir une chaîne de caractères.
b. Après la saisie, calculer (sans utiliser de fonction) et afficher la longueur de la chaîne
de caractères.
Exercice 2 :
a. Saisir, caractère par caractère, une chaine composée exclusivement de chiffres et
afficher la chaine saisie. Le programme vérifiera que chaque caractère entré au clavier
est bien un chiffre compris entre '0' et '9'.
b. Convertir le tableau de caractères en un tableau de nombres entiers et afficher ce
tableau.
c. Convertir le nombre entré sous forme de chaîne de caractères en nombre entier et
l’afficher.
Exercice 3 :
a. Saisir un nombre entier positif composé de 5 chiffres maximum.
b. Convertir ce nombre en une chaîne de caractères.
c. Afficher la chaîne convertie.
Exercice 4 :
a. Saisir deux chaînes de caractères
b. Comparer, caractère par caractère, ces deux chaînes et déterminer si elles sont
identiques ou leur ordre lexicographique.
Exercice 5 :
Un palindrome est un mot qui reste le même qu'on le lise de gauche à droite ou de
droite à gauche (par exemple, PIERRE n'est pas un palindrome, alors que OTTO est
un palindrome).
a. Ecrire un programme qui vérifie si une chaîne simple (sans espace) introduite au
clavier est un palindrome.
b. Faire la même chose, mais cette fois avec une phrase complète (avec espaces et/ou
ponctuation).
Exercice 6 :
- 17 -
Refaire les exercices précédents avec les fonctions de la bibliothèque « stdlib.h » et
« string.h ».
- 18 -
TP 4 : ALGORITHME DU PLUS COURT CHEMIN (LEE)
Dans un labyrinthe, on recherche un chemin, le plus court possible, allant d'une case
de départ (Xd,Yd) à une case d'arrivée (Xa,Ya), données.
1. Représentation
On représente le labyrinthe par un tableau rectangulaire T[M][N] d'entiers (M<=60 et
N<=60, tous les deux plus petits pendant la mise au point). On emploiera le codage
suivant :
T[X][Y] Signification
-1 "case bloquée par un obstacle"
0 "case libre non encore traversée"
r>0 "case libre traversée au pas "r"
-2 "case du segment de chemin déjà tracée.
Conditions de cheminement :
On regarde le tableau T comme une carte géographique. D'une case (i,j) on peut
passer seulement à ses quatre voisines Nord, Sud, Est et Ouest, si elles existent
(attention au voisinage des bords) et si elles sont libres d'obstacle.
2. Algorithme
2.1 Phase d'expansion
On marque "1" la case de départ. On fixe lp=1 (longueur parcourue).
En balayant tout le tableau dans un ordre quelconque, on marque "lp+1" toutes les
cases libres d'obstacle, non déjà traversées et adjacentes par le Nord, le Sud, l'Est ou
l'Ouest à une case numérotée "lp". Puis on incrémente lp.
Cette opération est répétée jusqu'à ce que la case d'arrivée soit atteinte (cas où le
chemin existe) ou bien jusqu'à ce que l'exécution d'un balayage du tableau s'achève sans
qu'aucune case supplémentaire n'ait été marquée (cas où le chemin n'existe pas : les cases
de départ et d'arrivée sont séparées par des obstacles incontournables).
2.2 Phase de remontée ou de tracé
Quand un chemin existe, on le trace en remontant de la case d'arrivée à la case de
départ.
On mémorise la longueur du chemin trouvé : lp = T[Xa][Ya]. C'est la distance entre
(Xd,Yd) et (Xa,Ya) pour les conditions de cheminement adoptées. Puis on marque
comme appartenant au chemin ("-2") la case d'arrivée, qui est donc la case initiale de la
remontée.
Alors, tant que la dernière case marquée n'est pas la case de départ, on en recherche une
voisine qui soit marquée "lp-1" (on sait qu'il en existe une, car autrement la précédente
ne serait pas marquée lp), on la marque "appartenant au chemin" et on décrémente lp.
- 19 -
3. Présentation des résultats
Pour visualiser à l'écran le labyrinthe et le chemin, on convertit chaque valeur entière du
tableau T en un seul caractère imprimable selon la convention :
'0' = Obstacle
'*' = Case du chemin
'.' = Case libre hors chemin
Remarques :
Pour simplifier le traitement des cases se trouvant sur le bord du labyrinthe, on
pourra entourer celui-ci d'obstacles. Ainsi toute case "utile" du labyrinthe possède 4
voisins.
On pensera au cas où il n'existerait pas de chemin.
Afin d’améliorer la phase d’expansion on utilisera une file. Au lieu de balayer l’ensemble
du tableau pour retrouver les cases marquées "lp", les cases nouvellement marquées sont
alors stockées dans une file. Initialement la file contient la case départ. Ecrire le
programme correspondant en utilisant :
- Une fonction qui ajoute un élément à la file,
- Une fonction qui retire un élément,
- Une fonction qui teste si la file est vide
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
return nRand;
}
void main()
{
- 20 -
int i;
srand((unsigned)time(0));
Testez ce programme et utilisez cette fonction pour générer les obstacles de manière
aléatoire dans le programme précédent.
- 21 -
TP 5 : VARIABLES ET FONCTIONS
Rappels :
#define pi 3.14159
…
Surface= R * R * pi ; /* équivalent … R*R*3.14159 */
- Lors du déroulement d'un programme, dans la fonction main(), ou dans une autre
fonction, un branchement peut être fait vers une autre fonction. Après l'exécution de la
fonction appelée, un nouveau branchement se fait, en sens inverse, pour revenir à
l'endroit où le cours s'était interrompu. Pour effectuer le traitement, la fonction appelée
utilise des valeurs (nombres, caractères, ...) qui sont, soit communes à l'ensemble des
fonctions (variables globales), soit transmises par la liste des paramètres délimitée par des
parenthèses et attachée au nom de la fonction, soit définies au sein même de la fonction
(variables locales).
- Les paramètres d'une fonction sont un ensemble de valeurs qui, au moment de l'appel,
sont recopiées sur une pile mémoire (allocation dynamique). Vu de l'intérieur de la
fonction, les paramètres sont des variables locales qui disparaissent automatiquement
après l'exécution, tout comme les autres variables définies dans le corps de la fonction.
Par conséquent, après la fin d'exécution d'une fonction, les variables passées en
argument conservent les valeurs qu'elles avaient avant l'appel à la fonction.
...
int Fonction1(int j)
/* j prend la valeur de la variable au moment de l'appel
c-a-d i=1 */
{
- 23 -
- On peut et on doit renvoyer une valeur d'une fonction qui n'est pas déclarée void.
L'instruction de retour (return) précise une valeur de retour (voir exemple ci-dessus). Si
la fonction ne doit pas retourner de valeur, elle est déclarée void.
Exercices :
- 24 -
Intersectiont1t2() et de Uniont1t2() et permettra d'éviter la duplication
du code de vérification d'appartenance dans ces deux fonctions.
3/ Proposer trois nouvelles versions possibles de Acquisition() permettant de
compter et d'afficher le nombre d'appels à cette fonction. La première version utilisera
une variable globale (l'affichage du nombre d'appels étant externe à
Acquisition()), la deuxième version utilisera une variable locale à
Acquisition() (l'affichage du nombre de passages étant interne à la fonction), la
troisième version utilisera le passage par argument (l'affichage du nombre de passages
étant externe ou interne à la fonction).
Le compte rendu de TP doit contenir le listing de VarEtFonct.c après correction, les listings des 3
nouvelles versions de Acquisition() où l'on expliquera quelles sont les modifications
correspondantes à apporter au programme principal pour utiliser ces nouvelles fonctions.
- 25 -
TP 6 : STRUCTURES ET FICHIERS
But
L’objectif de ce TP est de développer un programme permettant de trier et
compter les mots qui sont contenus dans un fichier texte.
Notions utilisées
* Les chaînes de caractères
* Les fichiers
* Les structures
Indications
1/ Exemple de lecture d’un fichier
#include "stdio.h"
void main() {
FILE * fic;
char c;
// ouverture du fichier
fic=fopen("texte.txt","r");
// boucle sur les caractères lus
while((c=fgetc(fic)) != EOF) {
// dans cette boucle, c contient
26
successivement chaque caractère lu
printf("%c",c);
}
}
27
2/ La fonction strtok() déclarée dans string.h permet de découper une
chaîne de caractères en "morceaux" en se basant sur des séparateurs. Pour
commencer ce TP, vous pouvez partir du programme ci-dessous qui lit une ligne
envoyée au clavier et la découpe avec la fonction strtok().
#include <string.h>
#include <stdio.h>
char string[] = "A string\tof ,,tokens\nand some
more tokens";
char seps[] = " ,\t\n";
char *token;
void main( void )
{
printf( "%s\n\nTokens:\n", string );
/* Establish string and get the first token: */
token = strtok( string, seps );
while( token != NULL )
{
/* While there are tokens in "string"
*/
printf( " %s\n", token );
/* Get next token: */
token = strtok( NULL, seps );
}}
3/ La fonction strcmp() prototypée dans string.h compare des chaînes de
caractères selon l'ordre lexicographique.
4/ La fonction strlen() prototypée dans string.h permet de connaître la
longueur d'une chaîne de caractères.
Consignes
Pour coder le mot du texte et le nombre d'occurrences de ce mot dans le texte, on
utilisera la structure de données suivante :
On utilisera un tableau statique pour CompteMot. On peut lire le texte ligne par
ligne avec la fonction fgets().
28
Exemple d'exécution
Supposons que le programme ait été lancé avec un seul argument indiquant le nom
d'un fichier contenant le texte suivant :
Bonjour : 1 fois
Et : 1 fois
Très : 1 fois
bien : 1 fois
comment : 2 fois
toi : 1 fois
tu : 2 fois
vas : 2 fois
TP 7 : Structures de données
Principe de la liste chainée statique avec une structure « Exemple », composée d’un
champ Nom (tableau de caractères), et un champ Suivant (entier).
struct Exemple {
char Nom[20] ;
int Suivant;
};
Convention :
- Un élément de la liste qui n’a pas de successeur aura son champ Suivant
à « -1 ».
- On utilise deux identificateurs d’index, Vide et Pleine, qui permettent
de repérer l’index du premier élément de la liste « Pleine » et de la liste
« Vide »
- S’il n’y a aucun élément dans la liste, « Pleine » est à « -1 »
- Si la liste est complète, « Vide » est à « -1 »
29
Exemple :
Nom Suivant
Liste[0] / 1
Liste[1] / 2
Liste[2] / 3
Liste[3] / 4
Liste[4] / -1
30
On ajoute un élément dont le nom est « Alain », la liste devient :
Nom Suivant
Liste[0] Alain -1
Liste[1] / 2
Liste[2] / 3
Liste[3] / 4
Liste[4] / -1
Vide=1
Pleine=0
On ajoute un nouvel élément dont le nom est « Zizou », la liste devient :
Nom Suivant
Liste[0] Alain 1
Liste[1] Zizou -1
Liste[2] / 3
Liste[3] / 4
Liste[4] / -1
Vide=2
Pleine=0
Nom Suivant
Liste[0] Alain 2
Liste[1] Zizou -1
Liste[2] Bernard 1
Liste[3] / 4
Liste[4] / -1
Vide=3
Pleine=0
Nom Suivant
Liste[0] / 3
Liste[1] Zizou -1
Liste[2] Bernard 1
Liste[3] / 4
Liste[4] / -1
31
Vide=0
Pleine=2
Etc.
5/ Ecrire une fonction Affiche() qui affiche le contenu de l'annuaire dans l’ordre
alphabétique.
8/ Ecrire une fonction Efface() qui, pour un nom de personne donné supprime
l’élément de la liste. Si la personne n'existe pas le message "pas de personne à ce
nom" est affiché.
NB : On supposera qu'il n'y a pas d'homonymes et que chaque personne n'a qu'un numéro de
téléphone.
33
TP 8 : RECURSION
Structures de données
Les distances entre les N villes seront mémorisées dans une matrice Dist[N][N]. Ces
données sont stockées initialement dans un fichier dont la première ligne donne la
dimension N. Chaque ligne suivante du fichier correspond à une ligne de la matrice.
Un chemin entre les villes sera représenté par un tableau Chemin de N cases, chaque
case contenant le numéro d'une ville.
Par exemple
1 4 3 2 : représente le chemin 1->4->3->2->1
Chaque fois qu'un chemin est généré, on calcule sa longueur. Si sa longueur est plus
courte que celle du meilleur chemin déjà trouvé, ce chemin devient le meilleur
chemin.
34
Exercice 2 : TRIANGLE DE PASCAL
n=2 1 2 1
n=3 1 3 3 1
n=4 1 4 6 4 1
n=5 1 5 10 10 5 1
n=6 1 6 15 20 15 6 1
n
Det (M ) = (−1)i+1mi,1 det(M i )
i =1
Dans un premier temps, saisir les valeurs au clavier lors de l’exécution du programme,
et afficher la valeur du déterminant à l’écran.
Dans un deuxième temps, vous pourrez écrire un fichier texte contenant la matrice
M , puis créer un deuxième fichier et écrire la matrice M ainsi que son déterminant
dans ce nouveau fichier. Les fichiers 1 et 2 seront choisis par l'utilisateur des 2 façons
suivantes.
- soit les noms des fichiers sont donnés sur la ligne de commande. Par exemple
:
pgm fichier1 fichier2
35
- soit les noms des fichiers ne figurent pas sur la ligne de commande, et le
programme demande à l'utilisateur le nom des fichiers.
NB : pour accéder aux mots donnés sur la ligne de commande, utiliser argc et argv
36
Méthode:
Calculer et afficher seulement les valeurs jusqu'à la diagonale principale (incluse).
Limiter le degré à entrer par l'utilisateur à 13.
Construire le triangle ligne par ligne:
- Initialiser le premier élément et l'élément de la diagonale à 1.
- Calculer les valeurs entre les éléments initialisés de gauche à droite en utilisant la
relation:
Pi,j = Pi-1,j + Pi-1,j-1
- Réaliser le même exercice, mais cette fois en faisant le calcul de manière récursive.
37
TP 9 : LISTES CHAINEES
On souhaite créer une application permettant de saisir une liste d’étudiant sans en
connaître le nombre au départ. Cette liste est crée le jour de la rentrée.
On opte pour une structure de liste chaînée dont chaque enregistrement possède :
- Le nom de l’étudiant
- Le numéro de la carte étudiant
- La moyenne aux examens
- Un pointeur SUIV pointant vers l’adresse de l’enregistrement suivant
2/ Suite à la rentrée certains étudiants, ne sont pas présents. Il est donc nécessaire
de les supprimer de la liste. Pour cela on utilisera une fonction Supprimer()
permettant de supprimer un élément de la liste.
3/ Il est maintenant nécessaire de trier cette liste par ordre alphabétique : utiliser
un algorithme simple de tri (tri à bulle par exemple) pour trier la liste. (on utilisera
une fonction Tri()). Une fois la liste triée par ordre alphabétique, créer une
fonction InverseListe(), permettant d’inverser la liste.
4/ Une fois que la liste est triée, il est possible qu’un étudiant supplémentaire
arrive en cours d’année : modifier alors la fonction Ajout() afin de l’insérer
directement au bon emplacement dans la liste.
5/ En fin d’année, une fois les moyennes calculées, on désire conserver la liste
uniquement avec les étudiants qui ont une moyenne supérieure ou égale à 12/20. On
utilisera une fonction PromoFinale() pour faire les modifications nécessaires à
la liste. La liste chaînée résultante sera donc la liste finale des étudiants admis en
deuxième année.
38
TDs/TPs COMPLEMENTAIRES
Vous trouverez ci-joint une liste d’exercice afin de préparer au mieux les TD/TP et éventuellement
les examens d’informatique. Attention la liste n’est pas forcément classée par ordre de difficulté
Exercice 1-
Donner la structure d’un programme permettant de donner tous les nombres parfaits
inférieur à p donné.
Aide : un nombre est parfait si et seulement si il est égale à la somme de ses diviseurs
(hormis lui même)
39
Exercice 3- Calcul du PGCD méthode 1
Exemple :
PGCD (36,21) = PGCD(36-21,21)=PGCD(15,21)=
PGCD(6,15)=PGCD(6,9)=PGCD (6,3) =PGCD(3,3) =3
1071 = 1029 × 1 + 42
1029 = 42 × 24 + 21
42 = 21 × 2 + 0
On lit un texte dans un fichier lettres par lettre. On suppose que l'on utilise une
fonction qui lit un caractère et renvoie la valuer du caractère lu. Elle renvoie 0 à la
fin du fichier.
Exercice 6-
40
Exercice 7-
Exercice 8-
Donner l'organigramme et le programme qui détermine si une année est bissextile.
L'utilisateur doit entrer l'année.
Rappel : une année est bissextile si elle est divisible par 4. Ex: 2012 était bissextile
Exception 1 : si elle est divisible par 100 elle n'est pas bissextile. Ex : 1900 n'était
pas bissextile
Exception 2 : si elle est divisible par 400 elle est bissextile. 2000 était bissextile
Exception 3 : si elle est divisible par 10000, elle n'est pas bissextile. 10000 ne sera
pas bissextile.
Donner l'organigramme d'un pgm qui calcule le nombre de jours écoulés entre un
edate donnée et le 1er janvier de cette année.
Exercice 9-
Donner l'organigramme d'un pgm qui donne la valeur maximale et la valeur
minimale d'une suite de nombres donnés positifs entrés au clavier. L'acquisition
s'arrête lorsque on donne un nombre négatif
Exercice 10-
Donner l'organigramme et écrire le code C d'un pgm qui calcule le produit de deux
nombres suivant la méthode suivante :
41
= 252
Exercice 11-
Ecrire un programme permettant de saisir une chaîne de caractères composée
uniquement de caractères '0' et de caractères '1'. Cette chaîne de caractères représente
le codage binaire d'un entier.
Exemple :
valeur de l'entier : -6
Exercice 12-
On désire écrire un programme qui trie et affiche un ensemble de vecteurs du plan,
par ordre croissant, selon la valeur de leur norme euclidienne. Pour cela, on utilise la
fonction qsort, déclarée dans le fichier stdlib.h, qui réalise un tri rapide ("quick
sort"), et qui a l'en-tête suivant :
Remarques :
La fonction qsort est "doublement générique" : d'une part, elle peut trier des
éléments de type quelconque ; d'autre part, elle peut trier des éléments (de même
type) selon n'importe quel critère de comparaison.
Le mot-clé const signifie que les deux objets pointés par les deux paramètres de type
void * ne peuvent pas être modifiés à l'intérieur de la fonction pointée par compare.
Cela vise à éviter tout "effet de bord".
La fonction qsort réalise le tri (croissant) du tableau d'adresse tab, comportant
nb_elem éléments de taille octets. Pour cela, qsort va effectuer différentes
comparaisons entre les éléments du tableau, en appelant une fonction de
42
comparaison donnée par l'utilisateur. Cette fonction de comparaison devra
retourner :
Une valeur négative si l'élément pointé par son premier paramètre est inférieur à
l'élément pointé par son second paramètre (au sens d'un certain ordre).
Une valeur nulle si les deux éléments sont égaux.
Une valeur positive si le premier élément est supérieur au second.
Après avoir défini le type vecteur par :
Exercice 13-
Ecrire un programme qui permet de trouver les boucles dans une liste chaînés de
pointeurs de type bool findLoop(Instance *ip). Le programme renvoie 1 si il a
trouvé une boucle sinon 0. Pour tester le programme, créer une structure de type :
puis faire un programme qui génère une liste d’Instances avec et sans boucle de
type :
43
Le programme final sera du type :
ip = chainlist(size, doLoop)
loop = findLoop(ip) ;
If (loop == doLoop)
{
printf("mon programme marche, je suis le
meilleur\n ") ;
}
else
{
printf("il faut continuer a travailler mes
TP\n ") ;
}
}
Faire un test avec (size, doLoop) = (5, TRUE) et (size, doLoop) = (5,
FALSE).
Exercice 14-
Ecrire un programme contenant une fonction récursive Calcul() qui :
Note : On pourra utiliser le passage d'argument par adresse pour la variable somme.
Exercice 15-
Ecrire une fonction récursive (et le programme principal associé) permettant de
traduire un nombre romain en un nombre sous la forme décimale. La fonction ne
vérifiera pas la validité du nombre romain.
Rappels :
M = 1000 D = 500 C = 100 L = 50 X = 10 V = 5 I = 1
Principe :
Si un chiffre romain est suivi d'un chiffre romain de valeur supérieure, la valeur de
ce chiffre se soustrait, sinon la valeur de ce chiffre s'additionne.
45
Écrire une fonction numero(x,y), définie de façon récursive, qui retourne le
numéro du point de coordonnées (x; y).
#include "stdio.h"
void main() {
FILE * fic;
char c;
// ouverture du fichier
fic=fopen("texte.txt","r");
// boucle sur les carctères lus
46
while((c=fgetc(fic)) != EOF) {
// dans cette boucle, c contient
successivement chaque caractère lu
printf("%c",c);
// compléter le programme ici ………………….
}
// et ici …….
}
-1 -1 -1 -1 -1 -1
3 -1 -1 -1 -1 -1
1 3 -1 -1 -1 -1
1 3 5 -1 -1 -1
0
Remarque : il ne s'agit pas de trier le tableau une fois celui-ci rempli, mais de
rajouter chaque valeur à sa bonne place dans le tableau en "décalant" si nécessaire
les autres valeurs.
47
3 : A partir de deux tableaux TAB1 et TAB2 dans lesquels les éléments de type entier
sont rangés dans l'ordre croissant (on se servira du programme P1 pour construire
TAB1 et TAB2), écrire un programme P3 qui range toutes les données de TAB1 et
TAB2 dans un troisième tableau TAB3, de telle sorte que les données dans le tableau
TAB3 soient rangées dans l'ordre croissant. Remarque : le nombre de valeurs rangées
dans TAB1 et TAB2 peut être différent. On ne fera pas de tri sur TAB3.
4 : A partir d'un tableau d'entiers TABI dans lequel sont rangées des données non
triées, écrire un programme P5 qui prend les données de TABI et les range dans
l'ordre croissant dans un deuxième tableau TABF. Le tableau initial TABI pourra
contenir plusieurs fois les mêmes valeurs.
Il existe différentes méthodes de tri. On se propose ici de mettre en œuvre un tri par
« dichotomie ».
Pour cela, on considère la première valeur du tableau A appelée pivot. On place le
pivot à la place k de telle façon que :
- pour tout i<k, A[i]<=A[k]=pivot
- pour tout i>k, A[i]>A[k]=pivot
Exercice 20-
a/ Donner l'organigramme et un programme, utilisant une boucle while, qui affiche
une table de conversion des degrés Farenheit en degrés Celsius, de la forme suivante
:
Farenh. Celsius
0 17
20 6
40 4
60 15
.
.
48
.
300 148
Les bornes (0 et 300 dans le cas ci-dessus) sont données par l'utilisateur. On
vérifiera que la borne inférieure est réellement inférieure à la borne supérieure.
Dans le cas contraire, un message d'erreur sera affiché.
Remarque :
• La conversion Farenheit (F) - Celsius (C) est assurée par la formule suivante
:
C=(5/9)*(F-32)
Dans le tableau précédent, les valeurs numériques affichées sont toutes
entières
b/ Reprendre l'exercice précédent en remplaçant la boucle while par une boucle for.
Exercice 21-
Ecrire un programme qui demande la hauteur d'une pyramide et qui affiche celle-
ci en utilisant la fonction afficheCar().
*
***
*****
*******
Exercice 22-
Donner l'organigramme et le programme permettant d'afficher le losange suivant
formé d'étoiles et d’espaces de N lignes (N est fourni au clavier):
Nombre de lignes : 8
*
***
*****
*******
*****
***
*
Exercice 23-
49
Ecrire un programme qui permette d'acquérir des nombres positifs au clavier.
L'acquisition s'arrête lorsque on donne un nombre négatif. Le pgm affiche alors les
valeurs maximales et minimales données.
Exercice 24-
Ecrire un programme permettant de trouver tous les ‘p’ premiers nombres premiers
où p est donné par l’utilisateur.
II-1 Ecrire la fonction tirage() qui effectue le tirage aléatoire d’un point, et vérifie s’il
appartient ou pas au quart de disque D. Cette fonction renverra 1 si le point
appartient à D, et 0 dans le cas contraire.
II-2 Ecrire le programme principal pour qu’il exécute 10.000 tirages, et qu’il affiche
la valeur estimée de à chaque itération.
II-3 Dans le cas où une précision donnée sur est recherchée, que pourrait être le
critère d’arrêt du programme?
Rappels :
- Un point est intérieur à D si et seulement si x 2 + y 2 1 .
- La fonction rand() renvoie un entier compris entre 0 et la constante prédéfinie
MAX_INT
Exercice 26-
On se propose de calculer l'intégrale d'une fonction entre deux bornes a et b, tel que
:
50
b =3
dx
I=
a =1 x
On utilisera la méthode de calcul dite des rectangles (voir figure 1). On définit un pas
suffisamment petit appelé pas correspondant à la 10 000 ème partie de l'intervalle
considéré et on effectue la somme discrète des aires des rectangles inscrits entre la
courbe et l'axe des abscisses.
Ecrire le programme du calcul de l'intégrale en utilisant la méthode citée
précédemment.
Note : le programme principal doit se présenter sous la forme d'une simple boucle
d'itération grâce à laquelle on calcule, par cumul, une variable somme correspondant
à la somme des aires élémentaires définies par le découpage de l'intervalle en 10 000
éléments de largeur égale à pas. A titre d'exemple la première valeur calculée sera
l'aire du rectangle au point a, I[0]=f(a) * (a-b)/10000.
F(x)
pas
I[0]
x x
a b
Exercice 27-
Ecrire une fonction MIN et une fonction MAX qui déterminent le minimum et le
maximum de deux nombres réels selon les prototypes suivant :
a/ float MIN (float, float) float MAX (float,float)
b/ void MIN (float, float, *float) void MIN (float, float, *float)
Ecrire un programme principal se servant des fonctions MIN et MAX pour
déterminer le minimum et le maximum de quatre nombres réels entrés au clavier et
ce pour les versions de prototype.
Exercice 28-
Ecrire un pgm qui calcule le produit de deux entiers en utilisant le principe suivant :
a * b = a * (b-1) + a si b est impair
a * b = (2 * a) * (b / 2) si b est pair et différent de 0
Ainsi on se ramène à ne faire que des multiplications et divisions par 2 en plus des
additions.
Exemple :
51
36 * 7 = 36 * 6 +36
= 72 *3 +36
= 72 *2 + 108
= 144 *0 + 252
= 252
Exercice 29-
Ecrire un pgm se comportant comme une calculatrice, càd exécutant une boucle
sur :
1. lecture d'une ligne supposée contenir un entier, un opérateur et une entier
(ex : 1+2). Les opérateurs sont +, -, *, /, %
2. calcul de la valeur de l'expression
3. affichage du résultat à l'écran
On aura intérêt à utiliser la fonction sscanf pour extraire les opérandes et
l'opérateur de la ligne lue.
Exercice 30-
Donner l'organigramme et le programme qui lit la dimension N d'un tableau T du
type int (dimension maximale: 50 composantes), remplit le tableau par des valeurs
entrées au clavier et affiche le tableau.
Copiez ensuite toutes les composantes strictement positives dans un deuxième
tableau TPOS et toutes les valeurs strictement négatives dans un troisième tableau
TNEG. Afficher les tableaux TPOS et TNEG.
Exercice 31-
Ecrire un programme qui construit le triangle de PASCAL de degré N et le
mémorise dans une matrice carrée P de dimension N+1.
n=1 1 1
n=2 1 2 1
n=3 1 3 3 1
n=4 1 4 6 4 1
n=5 1 5 10 10 5 1
52
n=6 1 6 15 20 15 6 1
Méthode:
Calculer et afficher seulement les valeurs jusqu'à la diagonale principale (incluse).
Limiter le degré à entrer par l'utilisateur à 13.
Construire le triangle ligne par ligne:
- Initialiser le premier élément et l'élément de la diagonale à 1.
- Calculer les valeurs entre les éléments initialisés de gauche à droite en utilisant la
relation:
Pi,j = Pi-1,j + Pi-1,j-1
Exercice 32-
Exercice 33-
tA = t abcd = aei
ifgh bfj
ij kl cgk
dhl
Exercice 34-
Soit la séquence :
int tab[10];
int *p,i;
for (i=0;i<10;i++) tab[i]=0;
i=5;
53
p=tab; /* Equivalent à : p=&tab[0]; */
p=tab+i; /* Equivalent à : p=&tab[i]; */
A l'aide d'une représentation graphique, indiquer les modifications apportées au
tableau tab par la séquence d'instructions suivante, et ce après chaque instruction :
(*p)++;
(p++);
(*p)++;
(*(p+2))++;
(*(tab+2))++;
Exercice 35-
Exercice 36-
I-1 Quel doit être le type de la valeur retournée par la fonction ? Ecrivez la fonction,
ainsi que le programme principal en commentant votre solution.
I-2 Est-il possible de modifier les variables locales à main() a ou b à partir de la
fonction ? Pourquoi ?
I-3 Définissez une variable compteur locale à main(), et modifiez la fonction fct()
(utilisation de pointeur) pour que compteur stocke le nombre total d’additions
effectuées depuis le lancement du programme.
54
Exercice 37-
Exercice 38-
Exercice 39-
Exercice 40-
Réaliser la même chose que dans l’exercice précédent, mais en prévoyant, cette fois
une fonction pour la lecture des informations et une fonction pour l’affichage.
Exercice 41-
55
Exercice 42-
Ecrire un programme qui lit une chaîne de caractères CH et qui convertit toutes les
majuscules dans des minuscules et vice-versa.
Le résultat sera mémorisé dans la même variable CH et affiché après la conversion.
Exercice 43-
Exercice 44-
Ecrire un programme qui lit 10 phrases d'une longueur maximale de 200 caractères
au clavier et qui les mémorise dans un tableau de pointeurs sur char en réservant
dynamiquement l'emplacement en mémoire pour les chaînes. Ensuite, l'ordre des
phrases est inversé en modifiant les pointeurs et le tableau résultant est affiché.
Exercice 45-
Exercice 46-
56
i. Ecrire une procédure void crypt( char *p ) de cryptage d'un
caractère.
ii. Ecrire le main qui appellera la fonction crypt sur l'ensemble du
message et imprimera le résultat.
Exercice 47-
On veut savoir si une lettre est présente dans une chaîne de caractères et le nombre
de fois que cette lettre apparaît dans la chaîne.
iii. Ecrire une fonction void min2maj( char *p ) qui transforme une
chaîne de caractères quelconque en une chaîne identique mais
dont tous les caractères sont des majuscules.
iv. Ecrire une fonction int parcours( char *p , char c ) renvoyant le
nombre de fois que la lettre se trouve dans la chaîne de
caractères.
v. Ecrire le programme principal main().
Exercice 48-
Un palindrome est un mot qui reste le même qu'on le lise de gauche à droite ou de
droite à gauche (par exemple, PIERRE n'est pas un palindrome, alors que OTTO
est un palindrome). Ecrire de deux façons différentes, un programme qui vérifie si
une chaîne CH introduite au clavier est un palindrome.
vi. En utilisant uniquement le formalisme tableau.
vii. En utilisant des pointeurs au lieu des indices numériques.
Exercice 49-
Tri à bulle (bubblesort) : il consiste à faire glisser la plus petite valeur au début du
tableau. Si deux valeurs adjacentes A[i] et A[i+1] sont telles que A[i] > A[i+1] on les
échange. Ainsi après un premier passage la valeur la plus "légère" monte au début du
tableau. On recommence en ne considérant plus que A[2],A[3],...,A[n].
Exercice 50-
57
Exercice 51-
Un problème de planning
En début d’année, dans une université, chacun des M étudiants s’inscrit à k cours
parmi N.
On se propose d’établir la chronologie de l’ensemble des cours sous forme de
sessions. Une session est un ensemble de cours pouvant se dérouler simultanément.
Deux cours peuvent se dérouler simultanément lorsque aucun étudiant n’est inscrit
à ces deux cours. Dans le cas contraire, les cours sont dits en conflit.
On suppose donné les ensembles INSCRIPTION des cours suivis sous forme d’un
tableau de M par N où INSCRIPTION[i][j] = 1 si l'étudiant i est inscrit au cours j,
0 dans le cas contraire.
Soit CONFLIT un tableau à 2 dimensions pour lequel CONFLIT[c] est
l’ensemble des cours en conflit avec le cours c. On utilisera pour CONFLIT la
même convention que celle utilisée pour INSCRIPTION : CONFLIT[c1][c2]= 1 si
c1 et c2 sont en conflit, CONFLIT[c1][c2]= 0 sinon soit SESSION[s] l’ensemble
des cours se déroulant à la session s.
a- initialisations :
- Pour chaque cours c, établir CONFLIT[c]
- ses = 0
- RESTE = l’ensemble des cours
b- Tant que RESTE ≠ ø faire :
- ses = ses +1
/* construction de la session ses*/
- choisir un cours c0 appartenant à RESTE
- retirer c0 de RESTE
- placer le cours c0 dans la session ses
- CONFLIT_S = CONFLIT[c0] {c0}
58
- Pour tout cours c dans RESTE et qui n’est pas
en conflit avec la session ses, faire :
- rajouter c à la session ses
- CONFLIT_S = CONFLIT_S CONFLIT[c] {c}
- retirer c de RESTE
Questions :
On suppose dans la suite que N et M connus au moment de la compilation
Exercice 52-
Un fichier contient une séquence (de longueur inconnue) d'égalités entre les
sommes des nombres entiers positifs (un par ligne). A titre d'exemple,
considérons le fichier suivant :
2+3+12+8=9
2+3+4=9
22=3+4+5+10
3+5+1=4+44
Notez que les égalités peuvent être soit correctes (les trois premières) soit
fausses (la dernier). Ecrire une fonction C qui prend en paramètre le nom du
fichier et renvoie la fraction des égalités correctes. Dans cet exemple, la fonction
doit retourner 0,75.
Suggestion : vous pouvez utiliser des fonctions telles que atoi,
strtok,fgets
Exercice 53-
Ecrire une fonction qui permet de transformer un vecteur d'entiers en une chaine de
caractères. La fonction reçoit le pointeur de début du vecteur, sa dimension et le
pointeur de début de la chaine de caractères destination :
void ecrirevecteur (int v[], int dim, car s[]);
La chaine s devra contenir les nombres présents dans le vecteur séparés par des
virgules
Exemple : V 12 7 8 45 2 9 8 =
S= "12, 7, 8, 45, 2, 9, 8"
59
Version 1 : on utilisera la fonction sprintf qui permet d'écrire dans une chaine de
caractères et dont le fonctionnement est identique à celui de la fonction printf.
Son gabarit est int sprintf( char *chaine, const char *format [, argument] ... ) où
*chaine est l'adresse de la chaine destination.
Version 2 : on n'utilisera pas la fonction sprintf. Il est conseillé décrire une fonction
qui transforme un nombre entier en une chaine de caractères.
Exercice 54-
Exercice 55-
Écrire un programme pour afficher une chaîne de caractères (reçu à partir du
clavier) sur plusieurs lignes de longueur K (K choisi aussi par l’utilisateur) de
façon justifiée.
La chaîne doit être composée de maximum 3000 caractères et le nombre de
caractères par ligne doit être entre 20 et 80.
Exemple. Chaine introduite :
L'avantage d'être intelligent, c'est qu'on peut
toujours faire l'imbécile, alors que l'inverse
est totalement impossible
K=25
60
Résultat :
L'avantage d'être
intelligent, c'est qu'on
peut toujours faire
l'imbécile, alors que
l'inverse est totalement
impossible
Exercice 56-
Écrire une fonction SupprimeDoublons qui prend une liste de valeurs entières
(déjà triées dans l'ordre croissant) et qui supprime tous les nœuds qui
contiennent les mêmes valeurs. Idéalement, la liste ne doit être parcourue qu'une
seule fois. Il faut bien supprimer de la mémoire les nœuds effacés.
Par exemple, si vous avez la liste suivante :
0, 1, 1, 3, 4, 4, 5, 6, 6, 6, 7, 9
le programme modifiera la liste de façon à avoir :
0, 1, 3, 4, 5, 6, 7, 9
Écrire aussi la fonction main qui appellera la fonction Remplir (vois ci dessous),
puis qui affiche le contenu de la liste, puis la fonction SupprimeDoublons, et à
nouveau on affichera le contenu de la liste.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct liste {
int n;
struct liste* next;
};
srand (time(NULL));
*tete=(struct liste*)malloc(sizeof(struct liste));
t=*tete;
for (i=0; i<50; i++) {
t->n=v;
t->next=(struct liste*)malloc(sizeof(struct liste));
t=t->next;
61
v+=((int)rand())%5;
}
t->n=v;
t->next=NULL;
}
Exercice 57-
Ecrire un programme en C qui reçoit en entrée une séquence d’entiers positifs
non nuls (le 0 est considéré comme terminateur de la séquence). Montrer à
l’écran l’ensemble de valeurs distinctes reçues, chacune accompagnée par sa
fréquence d'apparition dans la séquence d'entrée.
Par exemple, si vous recevez la séquence suivante :
12
10
8
10
10
12
3
0
le programme affiche :
12: 28,6%
10: 42,8%
8: 14,3%
3: 14,3%
Utiliser une liste pour mémoriser les éléments de la séquence. Chaque nœud de la
liste contient 3 éléments : le nombre faisant partie de la séquence, sa fréquence,
et le pointeur au nœud suivant. Pour chaque valeur reçue, le programme va
chercher dans la liste si la valeur est déjà présente. Dans ce cas, le programme va
incrémenter la fréquence correspondante. Si la valeur n’est pas dans la liste, on
rajoutera (en tête de la liste) la nouvelle valeur.
Exercice 58- Passage d'une fonction comme paramètre d'une autre fonction
Il est possible de définir des variables ayant le type "pointeur de fonction". La valeur
d'une telle variable est l'adresse en mémoire du début du code exécutable d'une
fonction, et sa déclaration s'écrit selon l'une des deux syntaxes suivantes :
type_fonction
(*nom_variable)(paramètres_de_la_fonction);
type_fonction
(*nom_variable)(types_paramètres_de_la_fonction);
Pour lire de telles déclarations sans risque de confusion, on a intérêt à procéder en
plusieurs étapes.
Exemple :
62
int (*p_f)(float r); ou int (*p_f)(float);
Pour comprendre cette déclaration, on pourra procéder de la manière suivante :
p_f : le nom de la variable déclarée est p_f
*p_f : la variable p_f est un pointeur.
(*p_f)() : l'objet pointé est une fonction.
int (*p_f)(float r), ou int (*p_f)(float) : l'objet pointé est une fonction
retournant un entier, ayant un seul paramètre de type flottant.
Attention :
Il ne faut surtout pas oublier les parenthèses autour de *p_f, sans quoi le compilateur
comprendrait que p_f est une fonction retournant un pointeur sur un entier, ayant
un seul paramètre de type flottant !
L'intérêt essentiel de telles variables est de pouvoir passer des fonctions en
paramètres à une fonction. Dans un cas de ce genre, le paramètre formel doit être
de type "pointeur de fonction".
Exemple :
Le programme ci-après permet de calculer la valeur approchée de la dérivée d'une
fonction trigonométrique (cos, sin ou tan), en un point choisi par l'utilisateur. On
utilise pour cela l'identité suivante, permettant le calcul approché de la dérivée d'une
fonction f au point x pour EPSILON suffisamment petit :
f'(x) == (f(x+EPSILON)-f(x-EPSILON))/(2*EPSILON)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define EPSILON 0.001
int main(void)
{
char reponse='\n';
double x;
do
{
printf("Dérivées des fonctions
trigonométriques :\n");
63
printf("\t[c]osinus\n");
printf("\t[s]inus\n");
printf("\t[t]angente\n");
printf("\t[q]uitter\n");
printf("\tVotre choix (c,s,t ou q) : ");
fflush(stdout);
if (reponse!='\n')
while (getchar()!='\n') ;
scanf("%c",&reponse);
if
((reponse=='c')||(reponse=='s')||(reponse=='t'))
{
printf("En quel point voulez-vous calculer
la dérivée : ");
fflush(stdout);
scanf("%lf",&x);
}
printf("\n");
switch (reponse)
{
case 'c' : printf("Résultat :
%f\n\n",derivee(&cos,x));
break;
case 's' : printf("Résultat :
%f\n\n",derivee(&sin,x));
break;
case 't' : printf("Résultat :
%f\n\n",derivee(&tan,x));
break;
case 'q' : break;
default : printf("Tapez c, s, t ou q
!\n\n");
}
} while (reponse!='q');
exit(0);
}
Remarque :
64
Bien que cela puisse paraître surprenant, il n'y a aucune différence, tant à la
compilation qu'à l'exécution, entre les deux syntaxes d'appel suivantes :
derivee(&cos,x)
derivee(cos,x)
Exercice 59-
CRYPTOGRAPHIE - CRYPTANALYSE
(Lisez entièrement l’énoncé avant de commencer !)
Les deux parties suivantes peuvent être traitées de manière indépendante (seule
la dernière question de la partie 2 s’appuie sur une fonction de la partie 1). Il est
conseillé de faire deux projets séparés afin d’améliorer la lisibilité des
programmes.
PARTIE 1 : CRYPTOGRAPHIE
Une transformation similaire s'applique aux majuscules: 'A' est transformé en 'N',
'B' en 'O', etc.
2- Proposer une méthode (ou une fonction) pour décrypter une chaine de
caractères cryptée par la méthode de César.
4- Proposez une fonction pour décrypter une chaine de caractère cryptée par la
fonction EncryptLigne2().
Lettre
ABCDE F GH I J KLMNO P QR S TUVW X YZ
normale
Lettre
ZEPH I RABCD F G J K LMNOQS T U V WXY
cryptée
1
Utilisez une double allocation dynamique sur un pointeur char **, et renvoyer ce pointeur.
66
fonction main(). Le fichier crypté correspondant sera écrit dans un fichier
texte de sortie et également affiché dans la console.
PARTIE 2 : CRYPTANALYSE
Nous allons tenter de mettre en place cette analyse statistique sur un texte chiffré
par substitution.
67
3- Dans le programme principal, programmez l’affichage de l’ensemble des
symboles présents dans le texte, leur occurrence et leur probabilité d’apparition
(qui est un nombre réel égal à 1 sur le nombre d’occurrences).
6- Afin de voir s’il peut s’agir d’un chiffrement par décalage et à partir du résultat
du tri précédent, on calcule pour les 4 symboles les plus fréquents le décalage
correspondant avec les symboles les plus fréquents en français et en anglais (e,
s, a, n en français, et e, t, o, a en anglais voir les tableaux ci-dessous).
68
L 3.60 % Y 1.51 %
M 2.62 % Z 0.09 %
En francais :
Symbole 0: i Proba:
0.1267 Decalage avec e:
4
Symbole 1: x Proba:
0.0970 Decalage avec s:
5
Symbole 2: e Proba:
0.0787 Decalage avec a:
4
Symbole 3: s Proba:
0.0776 Decalage avec n: 5
En anglais :
Symbole 0: i Proba:
0.1267 Decalage avec e:
4
Symbole 1: x Proba:
0.0970 Decalage avec t:
4
Symbole 2: e Proba:
0.0787 Decalage avec o:
16
Symbole 3: s Proba:
0.0776 Decalage avec a:
18
69
7- Ensuite, appliquez un décalage (vous pouvez réutiliser les fonctions de la
partie 1) sur les lettres minuscules et les lettres majuscules correspondant aux
valeurs trouvées (4, 5, 16,18). Affichez le résultat dans la console et dans un
fichier texte pour voir si le fichier est lisible.
Rappels:
70
ANNEXE : INTRODUCTION AU SYSTEME WINDOWS/MS-DOS
Remarques :
- toutes ces commandes admettent de nombreuses options. Pour avoir le
détail de ces options utiliser la commande help
- En dehors des fenêtres MS-DOS, l'équivalent de la plupart de ces
commandes peut être effectué par l'explorateur Windows.
L'entrée standard est le clavier, la sortie standard l'écran. Tous deux sont en fait
considérés comme des fichiers.
On peut substituer à ces fichiers d'autres fichiers texte. Ainsi on peut conserver
la trace de l'exécution d'un programme dans un fichier ou remplacer son entrée
par une suite de caractères stockés dans un fichier.
75