Vous êtes sur la page 1sur 180

Ecole Normale Supérieure

Département d’Informatique
Rabat

Encadré par : Mr.Brahim Lamharchi


Réalisé par : Benallou Imane

Lazrak Chaïmae

Razzoug Milouda
Année
universitaire : 2003 / 2004

A l’occasion de la
présentation de ce travail,
nous tenons à exprimer notre
gratitude et notre
reconnaissance à Mr . Brahim
Lamharchi, notre encadrant
de projet de fin d’étude à
l’Ecole Normale Supérieure de
Rabat pour les conseils qu’il
nous a prodigués tout au long
de ce travail.

Nous adressons également


nos sincères remerciements à
tous les autres enseignants
Sommaire

Sommaire
Introduction..........................................................................................................................1
ÉlÉments de base d’un programme en Pascal et en C.........................................................3
II-1.1 Les variables..................................................................................................4
II-1.2 Les constantes................................................................................................6
II-2.1 En langage Pascal .........................................................................................7
II-2.2 En langage C..................................................................................................8
II-3.1 En langage Pascal..........................................................................................8
II-3.2 En langage C..................................................................................................9
Structures de traitement alternatives et itÉratives.............................................................20
Notion de sous-programmes..............................................................................................27
Les structures de
donnÉes statiques...............................................................................................................35
Les structures de donnÉes dynamiques.............................................................................44
Les fichiers.........................................................................................................................57
Solutions des exercices......................................................................................................65
Gestion de l’écran............................................................................................................174
Conclusion.......................................................................................................................176
Références........................................................................................................................177

ENS – Rabat – Département d’Informatique


Introduction

INTRODUCTION

Un programme informatique se compose d’une série d’instructions, qui sont


exécutées successivement par l’ordinateur. Lors de la création d’un programme,
il est nécessaire d’y inclure les instructions correspondant à la tâche qu’on
souhaite voir accomplie par l’ordinateur. Le processus consistant à définir les
instructions, devant être exécutées par l’ordinateur, se nomme programmation.

Beaucoup de langages de programmation sont apparus au fil des années en


commençant par les langages intimement liés à la machine (langage machine et
assembleur), viennent après les langages dits évolués : interprétés tels que Basic
et compilés tels que Pascal et C.

Langage Pascal

Le langage Pascal est un langage de programmation de haut niveau. Il a été


conçu par le professeur WIRTH à Zurich en 1970 comme une aide à
l’enseignement de la programmation structurée.

Langage C

Le langage C a été créé en 1972 par Denis RITCHIE avec un objectif


relativement limité : écrire un système d’exploitation (UNIX). Mais, ses qualités
opérationnelles l’ont très vite fait adopté par une large communauté de
programmeurs.

Une première version du langage est apparue en 1978 avec l’ouvrage de


Kernighan et Ritchie « The C programming language ». Mais le langage a
continué d’évoluer après cette date à travers les différents compilateurs qui ont
vu le jour. Son succès internationnel a amené l’ANSI (American National
Standard Institute) à définir un C standard (on le qualifie souvent par le C ANSI).

Choix du sujet

L’enseignement de l’informatique se répand de plus en plus dans les


établissements scolaires et pour toutes les options, à l’université, aux écoles
d’ingénieurs, plus récemment dans les lycées et collèges et même dans les écoles
primaires privées.

ENS – Rabat – Département d’Informatique 1


Introduction

En particulier, l’enseignement de l’algorithmique et de la programmation est, et


reste toujours un passage obligatoire pour la formation des futurs informaticiens.
Malgré l’apparition d’autres systèmes de programmation très évolués et reposant
sur la programmation orientée objets, ceux-ci restent liés aux langages de
programmation de base tels que Pascal et C.

Objectif
Notre objectif c’est de palier aux difficultés que le programmeur (universitaire,
élève ingénieur, analyste-programmeur, etc.) puisse rencontrer au moment de son
apprentissage en lui proposant une série d’exercices diversifiés et couvrant la
totalité des notions de base de la programmation. On lui propose aussi, à la fin du
document, toutes les solutions des exercices proposés en Pascal et en C.

ENS – Rabat – Département d’Informatique 2


Eléments de base d’un programme en Pascal et en C

ÉLÉMENTS DE BASE D’UN


PROGRAMME EN PASCAL ET EN C

I- Structure d’un programme


I-1. En langage Pascal
Un programme PASCAl se compose des éléments suivants :

1- En-tête qui se compose du mot réservé PROGRAM suivi d’un identificateur


du nom du programme, suivi du point virgule ‘ ;’.

Exemple : PROGRAM Operations ;

2- Préambule déclaratif qui comporte :

 La déclaration des bibliothèques utilisées, précédée par le mot réservé


USES. Les identificateurs des bibliothèques sont séparés par des
virgules et la liste est terminée par un point virgule ‘;’.

Exemple : USES Crt, Graph, Dos ;

 La déclaration des identificateurs de types de données, définis par


l’utilisateur, précédée par le mot réservé TYPE.

Exemple : TYPE Nombre = 0..99 ;

 La déclaration des identificateurs de constantes, précédée par le mot


réservé CONST.

Exemple : CONST Pi = 3.14 ;

 La déclaration des identificateurs de variables, précédée par le mot


réservé VAR.

Exemple : VAR A : INTEGER ;

3- Définition des différents sous-programmes (voir chapitre des sous-


programmes).

ENS – Rabat – Département d’Informatique 3


Eléments de base d’un programme en Pascal et en C

4- Définition du bloc principal du programme : ce bloc commence par le mot


réservé BEGIN suivi d’une séquence d’instructions (séparées par des points
virgules ‘ ;’) et se termine par le mot réservé END suivi du point ‘.’.

I-2. En langage C
1- Préambule déclaratif qui comporte :

 La déclaration des bibliothèques utilisées, précédée par le mot réservé


‘#include’

Exemple : #include <stdio.h>

 La déclaration de l’identificateur de constante, précédée par le mot


réservé define.

Exemple : Define Pi 3.14.

 La déclaration des identificateurs de variables, précédée par le type des


variables et suivie du point virgule ‘ ;’.

Exemple : int x ;

2- En-tête : précise le début du programme principal. Il se compose du mot


réservé Main().

3- Définition du bloc principal du programme : ce bloc commence par une


accolade ouvrante ’{‘ et se termine par une accolade fermante ‘}’.

II- Types de données


II-1. Variables et constantes

II-1.1 Les variables

On appelle variable, un emplacement mémoire dans lequel est codée une


information que l’on peut modifier et utiliser grâce à un identificateur. Toute
variable doit être déclarée avant d’être utilisée.

En langage Pascal

ENS – Rabat – Département d’Informatique 4


Eléments de base d’un programme en Pascal et en C

Syntaxe : Var <identificateur> : <type>;


Exemple : var x : integer ;

Variables globales et variables locales

Les variables déclarées dans la partie déclaration du programme sont dites


globales.
Les variables déclarées dans la partie déclaration d’un sous-programme sont
dites locales.
Les variables globales sont connues par tous les sous-programmes, tandis que les
variables locales sont connues seulement par le sous-programme dans lequel
elles sont déclarées.

ENS – Rabat – Département d’Informatique 5


Eléments de base d’un programme en Pascal et en C

En langage C
Syntaxe : <type> <identificateur> ;

Le de l’identificateur peut être composé de chiffres, de lettres et du caractère ‘_’.


Le premier caractère doit être nécessairement une lettre.

Exemple : int ident_1

Variables globales et variables locales

Selon l'endroit où on déclare une variable, celle-ci pourra être accessible (visible)
de partout dans le code ou bien dans une portion confinée de celui-ci (à l'intérieur
d'une fonction par exemple), on parle de portée (ou visibilité) d'une variable.
Lorsqu'une variable est déclarée à l'extérieur de toute fonction ou de tout bloc
d'instructions, elle est accessible de partout dans le code (n'importe quelle
fonction du programme peut faire appel à cette variable). On parle alors de
variable globale.
Lorsque l'on déclare une variable à l'intérieur d'un bloc d'instructions (entre des
accolades), sa portée se confine à l'intérieur du bloc dans lequel elle est déclarée.

II-1.2 Les constantes

Contrairement à une variable, une constante ne peut être modifiée


(théoriquement).

En langage Pascal

Syntaxe : const <identificateur> = valeur ;


Exemple :

Remarque
Contrairement aux variables, il n'est nullement besoin de spécifier le type de la
constante. On peut tout de même le faire, en utilisant le double point, comme
pour les variables.
Exemple : const Gravite : Real = 9.81;

En langage C

Syntaxe : const <type> <identificateur> = valeur ;

ENS – Rabat – Département d’Informatique 6


Eléments de base d’un programme en Pascal et en C

II-2. Les types de base

II-2.1 En langage Pascal

Mémoire
Type Description Intervalle Exemples
requise
Shortint Entiers courts -128 à 127 -125; 0; 32 1 octet
Integer Entiers "relatifs" -32 768 à 32 767 -30 000; 421; 2 octets
-2147483648 à -12 545 454; 3
Longint Entiers longs 4 octets
2147483647 257
Entiers sur 1 Bit
Byte 0 à 255 12; 157 1 octet
(Byte ou Octet)
Entiers sur 2 Bits
Word 0 à 65 535 27; 4 589 2 octets
(Word ou Mot)
3.1415;
Real Nombres réels 2.9E-39 à 1.7E38 6 octets
789.457851
Nombres décimaux 3.1415926; 178
Single 1.5E-45 à 3.4E38 4 octets
(simple précision) 925.455678
54.5899; 9 897
Nombres décimaux
Double 5E-324 à 1.7E308 669 8 octets
(double précision)
651.45568959
3.14159265458;
Extended Nombres réels 3.4E-4932 à 1.1E4932 10 octets
9.81
Comp Entier -9.2E18 à 9.2E18 -271; 6 548 8 octets
Boolean logique sur 1 octet false ou true false; true 1 octet
256 caractères au
Chaîne de 'Hello!'; 'Allez- 256
String maximum (0 à
caractères vous bien ?' octets
255)
Chaîne de n n caractères String[6]-
String[n] n octets
caractères maximum >'Hello!'
1 caractère
Char 1 caractère 'R' 1 octet
maximum

ENS – Rabat – Département d’Informatique 7


Eléments de base d’un programme en Pascal et en C

II-2.2 En langage C

Taille (en
Type de données Signification Plage de valeurs acceptée
octets)
Char Caractère 1 -128 à 127
Caractère non
unsigned char 1 0 à 255
signé
short int Entier court 2 -32768 à 32767
Entier court non
unsigned short int 2 0 à 65535
signé
int Entier 2 -32768 à 32767
unsigned int Entier non signé 2 0 à 65535
-2 147 483 648 à 2 147 483
long int Entier long 4
647
Entier long non
unsigned long int 2 0 à 4 294 967 295
signé
float flottant (réel) 4 3.4*10-38 à 3.4*1038
double flottant double 8 1.7*10-308 à 1.7*10308
flottant double
long double 10 3.4*10-4932 à 3.4*104932
long

II-3. Créer un type de données

II-3.1 En langage Pascal

Il est possible au programmeur de créer ses propres types. Les types doivent être
déclarés avec le mot-clef Type à fortiori avant la déclaration des variables.

Exemple
Type matrice = Array[1..10,1..10] of integer;
Définit un type nommé matrice pour représenter une matrice carrée d’ordre 10.

Type énuméré
Dans la déclaration d’un type énuméré, il faut énumérer toutes les valeurs de ce
type.
Syntaxe : type nom_du_type = (identificateur_1, identificateur_2,..,
identificateur_n)

ENS – Rabat – Département d’Informatique 8


Eléments de base d’un programme en Pascal et en C

Exemple : type jour = (lundi, mardi, mercredi, jeudi, vendredi, samedi,


dimanche) ;

Type intervalle
Syntaxe : type nom_du_type = début_de_l_intervalle..fin_de_l_intervalle
Exemple : Type age = 1..150 ;
Déclare un type nommé age dont les valeurs sont des entiers compris entre 1 et
150.

II-3.2 En langage C

Syntaxe : typedef Caracteristiques_du_type Nom_du_type


Où :
Caracteristiques_du_type : représente un type de données existant (par exemple
float, short int, etc.)
Nom_du_type : définit le nom qu’on donne au nouveau type de données.
Exemple : typedef short int entier

Le type énuméré
Le type énuméré donne une liste de constantes par énumération. Le premier
identificateur a, par défaut, la valeur 0, le second a la valeur 1, etc. Une variable
de type énuméré est une variable entière.

Exemple :
typedef enum = {JAUNE = -2, ROUGE, VERT, VIOLET, BLEU} COULEUR;
main()
{
COULEUR coul1, coul2;
coul1 = VERT; // coul1 = 0
coul2 = coul1+2; // coul2 = 2
}

III- Opérateurs et expressions


III-1. En langage Pascal
Les expressions sont composées d’opérateurs et d’opérandes. La
plupart des opérateurs sont binaires, c’est à dire qu’ils mettent en
œuvre deux opérandes (exemple A+B). Les opérateurs à un opérande

ENS – Rabat – Département d’Informatique 9


Eléments de base d’un programme en Pascal et en C

sont dits unaires (exemple –A). Dans les expressions plus complexes,
l’existence de règles de priorité permet d’éliminer toute ambiguïté dans
l’ordre de réalisation des opérations.

Table de priorité des opérateurs

Or Or Opér
Opérateur
dr dr ateur
s
s
0 (,[ 5 +,-
*, /,
1 OR 6 DIV,
MOD
(+),
2 AND 7
(-)
3 NOT 8
< , >, <= ,
4 9
>= , <> , =

Remarque : (+) et (-) deux opérateurs unaires.


Les trois règles fondamentales de priorité des opérateurs sont les
suivantes :

1- Un opérande placé entre deux opérateurs de priorités différentes sera


lié à celui possédant la priorité la plus élevée.
2- Un opérande placé entre deux opérateurs de même priorité sera lié à
celui qui se trouve à gauche.
3- Les expressions contenues entre parenthèses sont évaluées d’abord
afin de traiter leur résultat comme un seul opérande.
Dans une expression arithmétique, les opérateurs sont les opérateurs
arithmétiques (+,-,*, /, DIV, MOD).

Un opérande peut être :

- Un nom de variable ou de constante numérique.


- Une constante numérique.
- Un nom de fonction de type numérique tel que COS, SIN, etc.
Une expression logique simple est une comparaison entre deux

ENS – Rabat – Département d’Informatique 10


Eléments de base d’un programme en Pascal et en C

expressions arithmétiques. Les opérateurs de comparaison sont =, <>,


<, >, <=, >=.

Une expression logique est la composée d’expressions logiques simples


par les opérateurs logiques :

- OR et AND opérateurs logiques binaires, OR pour la disjonction et


AND pour la conjonction.

- NOT opérateur unaire, NOT opérateur de négation.

III-2. En langage C
 Opérateurs arithmétiques

Une expression peut comporter des opérations. Les objets d’une opération sont
les opérandes, qui sont manipulés par les opérateurs.

Opérateur Fonction Nbre


d'opérandes
- Opposé 1
* Multiplicati 2
on
/ Division 2
% Modulo 2
(reste)
+ Addition 2
- Soustraction 2

Remarque : L'opérateur modulo ne peut s'appliquer qu'à deux entiers, le résultat


est le reste de la division entière.

 Opérateurs d’égalité, relationnels et logiques

Ces opérateurs travaillent sur des opérandes ayant deux valeurs : nul (faux) et
non-nul (vrai). Le résultat est soit nul (faux), soit non-nul (vrai).
L'opérateur && (ET logique) a pour résultat vrai si les deux opérandes ont une
valeur vraie. L'opérateur || (OU logique) a pour résultat vrai si l'un au moins des
deux opérandes a une valeur vraie. Les évaluations des opérations logiques sont
effectuées de la gauche vers la droite. On peut imposer un ordre en utilisant des
parenthèses. L'évaluation cesse dès que la valeur de l'expression est établie.

ENS – Rabat – Département d’Informatique 11


Eléments de base d’un programme en Pascal et en C

Opérateur Fonction Nbre


d'opérandes
! NON logique 1
< Inférieur 2
<= Inférieur ou 2
égal
> Supérieur 2
>= Supérieur ou 2
égal
== Égalité 2
!= Inégalité 2
&& ET logique 2
|| OU logique 2

Remarque : Les opérateurs d'égalité et logiques ne doivent pas s'appliquer sur


des flottants à cause des erreurs d'arrondi. Pour tester l'égalité à 0 d'un réel, il est
préférable de tester que sa valeur absolue est inférieure à un ε très petit.
 Opérateurs de décrémentation et d'incrémentation

Syntaxe : <variable> OP ou OP <variable>

Où OP est l’un des opérateurs ++ ou --.

L’expression le_nombre = le_nombre +1 peut être remplacé par le_nombre++


ou ++le_nombre. Mais, ces expressions ne sont pas équivalentes ; la valeur de
l’expression le_nombre++ est égale à la valeur de le_nombre avant
l’incrémentation alors que ++le_nombre a pour valeur le_nombre après
l’incrémentation.

L’opérateur de décrémentation a le même comportement que le précédent. Ainsi


l’instruction le_reel-- diminue de 1 le contenu de le_reel.

Exemple : i++

 Opérateur conditionnel

Cet opérateur nécessite trois opérandes et s'apparente à un "si".

Syntaxe : expr1?expr2:expr3;

ENS – Rabat – Département d’Informatique 12


Eléments de base d’un programme en Pascal et en C

expr1 est évaluée. Si elle est vraie, le résultat est la valeur de expr2, sinon le
résultat est la valeur de expr3.
Exemple : a==b?a=2:b=3;

 Opérateurs sur les bits

Les opérandes de ces opérateurs doivent être de type entier (char, int, long,
short), mais ils sont traités comme une suite de bits (donc de 0 et de 1).
L'opérateur ~ remplace chaque 0 par 1 et vice-versa.
Les opérateurs &, ^ et ! opèrent sur chaque bit indépendamment. Ils sont
associatifs.
expr1 << expr2 décale tous les bits de expr1 de expr2 positions vers la gauche ;
les bits vacant sont remplis par des 0.
expr1 >> expr2 décale tous les bits de expr1 de expr2 positions vers la droite ; il
ne remplit les bits vacants par des 0 que si expr1 est de type unsigned, sinon,
selon les implémentations, il insère des copies du bit de signe ou des 0.

Opérateur Fonction Nbre


d'opérandes
~ Complémentatio 1
nà1
<< Décalage à 2
gauche
>> Décalage à 2
droite
& ET logique 2
^ OU exclusif 2
| OU logique 2

Exemple:
unsigned char val = 1; // 00000001
val = val << 3; // 00001000
val = val >> 2; // 00000010
Remarque: Ne pas confondre les opérateurs sur les bits & et | et les opérateurs
sur les expressions && et ||.

ENS – Rabat – Département d’Informatique 13


Eléments de base d’un programme en Pascal et en C

 Oprérateur sizeof

L’opérateur sizeof fournit la taille en octets. Par exemple, dans une


implémentation où le type int est représenté sur 2 octets, si l’on suppose que l’on
a affaire à la déclaration int n ; l’expresion sizeof(n) vaudra 2.

 Priorité entre opérateurs

Les priorités entre opérateurs définissent l'ordre dans lequel ils sont exécutés. Le
tableau suivant récapitule tous les opérateurs avec leur priorité.
En langage C, un certain nombre de notations servant à référencer des objets sont
considérées comme des opérateurs et, en tant que tels, soumises à des règles de
priorité.
Ce sont essentiellement :
- les références à des éléments d’un tableau réalisées par [ ] ;
- des références à des champs d’une structure opérateur -> ;
- des opérateurs d’adressage * et &.
Ces opérateurs seront étudiés ultérieurement dans les chapitres correspondant
aux tableaux, structures et pointeurs.

Catégorie Opérateurs
référence () [ ] -> .
unaire + - ++ -- | ~ * &
arithmétique */%
arithmétique +-
décalage << >>
relationnels < <= > >=
relationnels == !=
manip. de
&
bits
manip. de
^
bits
manip. de
|
bits
logique &&
logique ||
conditionnel ?:

ENS – Rabat – Département d’Informatique 14


Eléments de base d’un programme en Pascal et en C

Catégorie Opérateurs
affectation = += -= /= %= &= ^= |= <<= >>=

IV- Instructions simples


IV-1. Instructions d’entrée
Une instruction d’entrée permet de lire une donnée à partir du clavier.

En langage Pascal:
Syntaxe :

Read (V 1, V2,…., Vn) Où Vi est une variable de tout type simple (sauf
énuméré) ou de type chaîne de caractères.

ReadLn (V1,V2,...Vn) même effet que Read, mais il faut taper la touche
Entrée après l’entrée de la donnée. L’instruction ReadLn (sans argument)
attend la frappe de la touche Entrée au clavier.

Exemple : read(x) ;

En langage C:
La fonction scanf
Syntaxe : scanf (format, liste_d’adresses)

Format : constante chaîne (entre ""),

Pointeur sur une "chaîne de caractères"

Scanf("%d",&x) ;

Le tableau suivant présente les différents formats existants :

Type de la Ivalue
Format
correspondant
c char
d int
hd short int
hu unsigned short

ENS – Rabat – Département d’Informatique 15


Eléments de base d’un programme en Pascal et en C

ld long int
lu unsigned long
f Float
lf double
s chaîne de caractères
u unsigned int
Liste_d’adresses : liste de "lvalue", séparées par des virgules, d’un type en
accord avec le code de format correspondant.

La macro getchar()

Elle permet la lecture d’un caractère. L’expression : c=getchar(), joue le même


rôle que : scanf("%c",&c).

IV-2. Instructions de sortie


Une instruction de sortie permet l’affichage sur l’écran des valeurs
correspondantes aux arguments considérés.

En Pascal
Syntaxe

Write (val1,val2,…,valn) Où vali est une valeur d’une donnée constante ou


variable (sauf type énuméré), une constante chaîne de caractères, ou une
valeur d’une expression.
WriteLn(val1,val2,…valn) même effet que Write, mais le curseur passe à la
ligne suivante après l’affichage.

Exemple : write(‘salut ’,nom) ;

Remarque :
• Une constante chaîne de caractères est mise entre apostrophe. Une
apostrophe comprise dans une chaîne doit être dédoublée.
• L’instruction WriteLn (sans arguments) permet un saut de ligne.

En langage C :
La fonction printf
Syntaxe : printf (format, liste_d’expressions)

ENS – Rabat – Département d’Informatique 16


Eléments de base d’un programme en Pascal et en C

Format : constante chaîne (entre ""),


Pointeur sur une "chaîne de caractères"
Liste_d’expressions : suite d’expressions séparées par des virgules d’un type en
accord avec le code format correspondant.

Exemple : printf("salut %s",nom) ;

La macro putchar

Permet l’écriture d’un caractère. L’expression putchar(c), joue le même rôle


que : printf("%c",c).

IV-3. Instruction d’affectation


En langage Pascal :

Cette instruction permet de transcrire une valeur dans une variable. Le symbole
d’affectation est ‘ := ’

Syntaxe : <Var> := <Val> ;

Où la variable <Var> peut être de tout type et la valeur <Val> peut être une
valeur constante, la valeur d’une donnée constante ou variable, la valeur d’une
fonction, ou le résultat d’une expression.

Exemple : x :=2 ;

En langage C :

 Affectation ordinaire

Syntaxe : <variable> = <expression> ;

Exemple : x=2 ;

Remarque :
La valeur affectée à une variable doit être de même type ou de type compatible à
celui de la variable.

 Notion de Ivalue

On constate que l’opérateur d’affectation impose des restrictions sur son premier
opérande. En effet, ce dernier doit être une référence à un emplacement mémoire

ENS – Rabat – Département d’Informatique 17


Eléments de base d’un programme en Pascal et en C

dont on pourra effectivement modifier la valeur.


Dans les autres langages, on désigne souvent une telle référence par le nom
d’une variable. Cependant, en langage C, la syntaxe est telle que cette notion
de variable n‘est pas assez précise. Il faut introduire un mot nouveau : la
« Ivalue » ; ce terme désigne une valeur à gauche, c’est-à-dire tout ce qui peut
apparaître à gauche d’un opérateur d’affectation.

 Affectation élargie
Le langage C permet de condenser les affectations de la forme :
Ivalue = Ivalue opérateur expression
En : Ivalue opérateur= expression
Cette possibilité concerne tous les opérateurs binaires arithmétiques et de
manipulation de bits (voir chapitre suivant). La liste complète de tous ces
nouveaux opérateurs d’affectation élargie est : +=, -=, *=, /=, %=, |=, ^=, &=,
<<= et >>=.

Remarque
Ne confondez pas l’opérateur de comparaison <= avec un opérateur d’affectation
élargie. Notez bien que les opérateurs de comparaison ne sont pas concernés par
cette possibilité.

V-Enoncé des exercices


Exercice 1
Ecrire un programme qui permet d’afficher le message suivant : mon premier
programme.
Exercice 2
Ecrire un programme qui demande à l'utilisateur les valeurs de 2 entiers x et y,
qui permute leurs valeurs et qui les affiche.
Exercice 3
Ecrire un programme qui échange 3 entiers.
Exercice 4
Ecrire un programme qui demande à l'utilisateur les coordonnées de 2 points
distincts du plan et qui affiche les coordonnées du point milieu.
Exercice 5

ENS – Rabat – Département d’Informatique 18


Eléments de base d’un programme en Pascal et en C

Ecrire un programme qui demande à l'utilisateur une valeur pour U0, r et n et qui
affiche la nième valeur de la suite arithmétique définie par U0 et Un+1 = Un + r.
(On rappelle la propriété : Un = U0 + n.r ).

ENS – Rabat – Département d’Informatique 19


Structures de traitement alternatives et itératives

STRUCTURES DE TRAITEMENT
ALTERNATIVES ET ITÉRATIVES

Les instructions structurées sont des instructions composées d’autres


instructions devant être exécutées sous certaines conditions (instructions
conditionnelles) ou répétées plusieurs fois (instructions répétitives).

I- Instructions conditionnelles
En langage Pascal :
 Instruction IF…Then

Syntaxe : IF <Cond> THEN <Bloc> ;

Si <Cond> est vraie, le bloc d’instructions <Bloc> sera exécuté, sinon il sera
ignoré.

Cette instruction représente l’alternative simple (instruction de choix unaire).

Exemple : if a=b then a :=a+b ;

 Instruction IF…THEN…ELSE

Syntaxe : IF <Cond> THEN <Bloc1> ELSE <Bloc2>;

Si <Cond> est vraie, le bloc d’instructions <Bloc1> sera exécuté et le bloc


d’instructions <Bloc2> sera ignoré, sinon c’est le bloc d’instructions <bloc2> qui
sera exécuté et le bloc d’instructions <Bloc1> sera ignoré.

Cette instruction représente l’alternative complète (instruction de choix binaire).

Exemple : if a>b then a:=a-b

Else a:=b-a;

Remarque : la clause ELSE ne doit pas être précédée par un point virgule ‘ ;’.

 Instruction CASE

ENS – Rabat – Département d’Informatique 20


Structures de traitement alternatives et itératives

L’instruction CASE est constituée d’une expression de type scalaire,


représentant le sélecteur, et d’une liste de blocs d’instructions ; chacun étant
précédé par une étiquette de cas de même type que le sélecteur. Le bloc
d’instructions exécuté est celui dont l’étiquette de cas correspond à la valeur
courante du sélecteur.

Une étiquette de cas est constituée de tous nombres de constantes ou


d’intervalles, séparés par des virgules et terminés par le symbole ’ :’.

Syntaxe :

CASE <Sélecteur> OF
Val1 : <Bloc1> ;
Val2 : <Bloc2> ;
..........................
Valn : <Blocn> ;
ELSE <Bloc>;
END;

En langage C :

 Instruction IF :
Syntaxe : if (expression) instruction

Expression : expression quelconque.


Instruction : instruction simple terminée par un point virgule, bloc d’instructions
placées entre { et }, ou instruction structurée.

 Instruction IF…Else :
Syntaxe : IF (expression) instruction1 ELSE instrucion2

 Instruction SWITCH:

Syntaxe:
Switch(expression)
{ case constante1: [suite_d’instruction1]
case constante2: [suite_d’instruction2]
..........................................................
case constante n: [suite_d’instruction n]
[default : suite_d’instruction ]
}

ENS – Rabat – Département d’Informatique 21


Structures de traitement alternatives et itératives

Expression : expression entière quelconque,


Constante : expression constante d’un type entier quelconque (char est
accepté car il sera convertit en int),
Suite_d’instructions : séquence d’instructions quelconques.
N.B : les crochets ([et]) signifient que ce qu’ils renferment est
facultatif.

L’exécution de l’instruction switch commence par évaluer l’expression


figurant après le mot switch, ensuite, chercher l’étiquette de la forme
case x correspondant à la valeur obtenue et exécuter, enfin,
l’instruction figurant après cette étiquette. Dans le cas où l’étiquette ne
figure pas dans la liste, c’est le bloc par défaut qui est exécuté.

Remarque :
• On peut ajouter l’instruction break qui permet de sortir de l’instruction
switch juste après l’exécution du bloc de l’étiquette choisie.
Switch(expression)
{ case constante1: [suite_d’instruction1]
break ;
case constante2: [suite_d’instruction2]
break ;
..........................................................
case constante n: [suite_d’instruction n]
break ;
[default : suite_d’instruction ]
}
• les “case” peuvent apparaître dans n’importe quel ordre.

II- Instructions répétitives

Structu En langage
En langage C
res Pascal
While While
Tant
<expression> (<expression>)
que
Do <bloc> <instruction>
Répéter Repeat<instructi Do <instruction>
- on> While(<expressio

ENS – Rabat – Département d’Informatique 22


Structures de traitement alternatives et itératives

Until
jusqu’à n>)
<expression>
For comp :=Vint For
To Valf (<initialisation> ;<c
Do <bloc> ondition de
Pour
For comp :=Vint continuation ;<modi
DownTo Valf fication>)
Do <bloc> <instruction>

III- Enoncé des exercices


Exercice 6
Ecrire un programme qui échange les contenus de 2 données si elles sont de
signes contraires.
Exercice 7
Ecrire un programme qui échange les contenus de 2 données si elles sont de
signes contraires, sinon, il met leur produit dans la première donnée et leur
somme dans la deuxième
Exercice 8
Ecrire un programme qui, étant donné un mois et son premier jour, affiche le
premier jour du mois suivant.
Exercice 9
Ecrire un programme qui calcule la somme des N premiers termes positifs.
Exercice 10
Ecrire un programme qui calcule la somme des N premiers termes positifs
impairs.

ENS – Rabat – Département d’Informatique 23


Structures de traitement alternatives et itératives

Exercice 11
Ecrire un programme qui calcule la somme des N premiers termes positifs pairs
non multiples de 3.
Exercice 12
Ecrire un programme qui calcule la somme 1/2 + 1/4 + 1/8 +…+1/2n (n Є N*).
Exercice 13
Ecrire un programme qui calcule la somme 1+1/2-1/4+ 1/8-1/16+…±1/2n (n Є
N*).
Exercice 14
Ecrire un programme qui donne le nombre N tel que la série 1+1/2-1/3+1/4- 1/5+
…±1/N donne un résultat égal (à 1/100 près) à 1,33.
Exercice 15
Ecrire un programme qui donne la plus grande valeur inférieure à 1000 de la
somme 1+2+4+8+…+2N.
Exercice 16
Ecrire un programme qui calcule la somme 1+x+x2+…+xn (x réel et n entier).
Exercice 17
Calcul approché de x
Soient les deux suites: An+1= (An+Gn)/2 et Gn+1=2AnGn/(An+Gn) avec A0=x et
G0=1, on montre que lim An=lim Gn= x
n∞ n∞
Ecrire un programme qui donne la valeur de x avec une précision relative
Є=10-6, c’est à dire |An-Gn|/|Gn|<Є
Exercice 18
Sachant que la somme 1-1/3+1/5-1/7+1/9-…, tend vers П/4. Écrire un
programme qui calcule le nombre П à 10-6 près
Exercice 19
Le développement limité de la fonction sinus au voisinage de zéro est sin x= x -
x3/3! + x5/5! -…+(-1)p x2p+1/(2p+1)!+…
Ecrire un programme qui calcule sin x à 10-6 près.
Exercice 20
Ecrire un programme qui calcule la somme, le produit et la différence de deux
données numériques.
Exercice 21
Ecrire un programme qui retourne le code d’une donnée de type Caractere.

ENS – Rabat – Département d’Informatique 24


Structures de traitement alternatives et itératives

Exercice 22
Ecrire un programme qui calcule le salaire net d’un employé, sachant que celui-
ci a assuré un certain nombres d’heures de travail à un prix fixe par heure, et que
l’employeur doit réduire de son salaire des charges qui sont calculées avec un
coefficient donné.
Exercice 23
Ecrire un programme qui permet de reprendre l’exercice précédant en
considérant que l’employé a assuré des heures normales, des heures à 25% et des
heures à 50%.
Exercice 24
Ecrire un programme qui retourne si une donnée numérique est paire ou impaire
(utiliser le reste de la division par 2).
Exercice 25
Ecrire un programme qui permet de lire trois données numériques et retourne si
la troisième donnée est la somme des deux autres ou pas.
Exercice 26
Ecrire un programme qui, à partir du salaire brut d’un employé, détermine
l’impôt à payer sachant que les règles de calcul des impôts sont comme suit :

salaire brut(SB) l’impôt à payer


SB<1500 0%
1500<=SB<3000 10% du SB
3000<=SB<5000 450+30%(SB-3000)
SB>=5000 750+40%(SB-
5000)
Exercice 27
Ecrire un programme qui fournit les racines de l’équation Ax2+Bx+C=0.
Exercice 28
Ecrire un programme qui, étant donnée une date (jour, mois, année), affiche la
date du jour suivant.
Exercice 29
Ecrire un programme qui, étant donnée une date (jour, mois, année), affiche la
date du jour précédent.
Exercice 30
Ecrire un programme qui calcule la somme 5+6+7+….+N (N>=5).
Exercice 31

ENS – Rabat – Département d’Informatique 25


Structures de traitement alternatives et itératives

Ecrire un programme qui calcule le produit des N (N>0) premiers entiers


positifs.
Exercice 32
Ecrire un programme qui calcule la somme 1+1/2+1/4+1/6+…+1/2N (N>0).
Exercice 33
Ecrire un programme qui échange les contenus de trois données numériques si
leur somme est paire, sinon il met la somme des trois dans la première donnée,
leur produit dans la seconde et la valeur zéro dans la troisième.
Exercice 34
Ecrire un programme qui calcule la somme 1-1/2+1/3-1/4+…±1/N.

ENS – Rabat – Département d’Informatique 26


Notion de sous-programmes

NOTION DE SOUS-PROGRAMMES

Un sous-programme permet :
• d’éviter d’appliquer à plusieurs endroits d’un programme le même traitement,
même s’il porte sur des objets différents.
• d’appliquer sous forme transportable un traitement dont on prévoit que
d’autres programmes peuvent aussi en avoir besoin.
• de dégager d’un programme des tâches de moindre importance ne laissant
dans son corps que la partie importante de l’algorithme d’où le gain de
lisibilité et de sécurité.

I. En langage Pascal
Les sous-programmes en Pascal sont des procédures et des fonctions.

I.1 Les procédures


Une procédure doit être déclarée dans un programme, ou dans une procédure,
avant le corps du programme (de la procédure) et après les déclarations des
variables.
Le nom de la procédure est un identificateur qui, comme les autres déclarations
environnantes, sera local au programme ou à la procédure l’environnant.
La structure d’une procédure est à peu près celle d’un programme, l’en-tête
diffère, la procédure se termine par un point virgule au lieu d’un point.
Syntaxe : procedure <Ident> ;
<Déclarations> ;
Begin
<Instructions> ;
End ;

Paramètres formels
La déclaration des procédures peut être suivie d’une liste de paramètres entre
parenthèses. Un paramètre formel est destiné à être remplacé, chaque fois que la

ENS – Rabat – Département d’Informatique 27


Notion de sous-programmes

procédure est activée, par un autre objet dit paramètre effectif, le plus souvent
une variable, ou le résultat d’une expression, de la procédure appelante.
Syntaxe : Procedure <Nom> ( <mode> <Ident>.., <Ident> : <Type> ;.. ; <mode>
<Ident>,.., <Ident> : <Type>) ;
Où <mode> = rien ou var.
Paramètres par valeurs et paramètres par adresse
Les objets sont transmis comme données dont la valeur doit être inchangée par
la procédure appelée (on dit qu’on a une lecture pure).
Les objets sont transmis comme résultat dont la valeur doit être calculée par la
procédure appelée et transmise à la procédure appelante (on dit qu’on a une
écriture pure).
Les objets sont transmis comme données qui doivent être modifiées par la
procédure appelée (on dit qu’on a une lecture-écriture).
En Pascal, la transmission des paramètres se fait de deux manières :
• Transmission par valeur (lecture pure).
• Transmission par adresse (écriture pure, lecture-écriture).
On indique les paramètres transmis par adresse, précédés par le mot réservé Var,
les autres ne sont précédés par aucune chose.

I.2 Les fonctions


Une fonction en Pascal se comporte comme une procédure sauf que la fonction
doit fournir un résultat, elle a donc un type.
Syntaxe : Function <Ident> : <Type> ;
Function <Ident> (<liste_paramètres> ) : <Type> ;
Dans le corps de la fonction, on doit trouver quelque part l’affectation d’une
valeur à l’identificateur de la fonction.
Exemple :
Function Minimum (x, y : Integer ) : Integer ;
Begin
If x<y then Minimum :=x
Else Minimum:=y
End;

II. En langage C

ENS – Rabat – Département d’Informatique 28


Notion de sous-programmes

Les fonctions sont les seuls sous-programmes en C; elles permettent de


regrouper des instructions et de lancer leur exécution grâce à un
identificateur. La fonction peut admettre des paramètres.

La fonction peut retourner une valeur. La définition d’une fonction est


composée de deux éléments :

• son prototype :

Permet de préciser la classe de mémorisation, le type, l’identificateur et


les paramètres de la fonction ; c’est l’entête de la fonction.

Syntaxe :

[classe][type]<identificateur>([liste des paramètres formels]). La liste


est composée de la déclaration des paramètres formels :
<type><arg1>,<type><arg2>,…,<type><argn>.
Si la liste est vide alors elle peut être remplacée par le mot void.

• Son corps : c’est un bloc d’instructions

[classe][type]<identificateur>([liste des paramètres formels])


{

<corps de la fonction>

}/*fin de la fonction*/
Dès qu’une instruction de retour est rencontrée, l’exécution de la
fonction s’interrompt. Cette instruction permet de transmettre
éventuellement une valeur au programme appelant.

Syntaxe :

return ; /*pas de valeur retournée*/


return <expression> ;
return(<expression>) ;
Si la fonction ne contient pas l’instruction return, elle s’achève
automatiquement à la fin de son bloc.

Passage des paramètres par valeur

ENS – Rabat – Département d’Informatique 29


Notion de sous-programmes

En langage C, le passage des paramètres se fait toujours par valeur,


c.-à-d. les fonctions travaillent sur les valeurs de leurs paramètres et n'ont pas
d'accès aux variables elles-mêmes. Les paramètres d'une fonction sont à
considérer comme des variables locales qui sont initialisées automatiquement
par les valeurs indiquées lors d'un appel. A l'intérieur de la fonction, nous
pouvons donc changer les valeurs des paramètres sans influencer les données
originales dans les fonctions appelantes.

Passage par adresse

Pour changer la valeur d'une variable de la fonction appelante, il faut que la


fonction appelante fournisse l'adresse de la variable et la fonction appelée déclare
le paramètre comme pointeur.
On peut alors atteindre la variable à l'aide du pointeur (voir chapitre structure de
données).

III. La récursivité
Un sous-programme est dit récursif s’il s’appelle lui-même. Il doit
contenir une condition d’arrêt. Considérons l’exemple de la fonction
pgcd(a, b) qui retourne le plus grand diviseur commun des deux entiers
a et b :

En langage C En langage Pascal


int pgcd(int a, int b) Funtion pgcd (a,b :
{ if (a = = b) return a; integer): integer;
else if (a>b) return pgcd(a- Begin
b,b); If (a=b) then pgcd:=a
else pgcd(a,b-a); Else if (a>b) then
} pgcd:=pgcd(a-b,b)
Else
pgcd:=pgcd(a,b-a)
End;

IV- Enoncé des exercices


Exercice 35
Ecrire une fonction paramétrée qui retourne si un nombre donné est premier ou
non.

ENS – Rabat – Département d’Informatique 30


Notion de sous-programmes

Exercice 36
Ecrire une fonction paramétrée qui retourne si un nombre donné est parfait ou
non.

Exercice 37
Ecrire une fonction paramétrée qui retourne si deux nombres donnés sont amis
ou non.

Exercice 38
Ecrire une fonction paramétrée qui retourne l’inverse d’un nombre entier donné.

Exercice 39
Ecrire une fonction récursive permettant de calculer le PGDC de deux nombres
entiers positifs A et B.

Exercice 40
Ecrire une fonction récursive permettant de calculer le PPMC de deux nombres
entiers positifs A et B.

Exercice 41
Ecrire une fonction récursive qui permet de calculer le factoriel d’un nombre
donné.

Exercice 42
Ecrire une fonction récursive qui permet de calculer la puissance d’un entier
donné.

Exercice 43
Ecrire une fonction récursive qui calcule la valeur de la fonction d’Ackermann
« A » définie pour m>0 et n>0 par :
A(m, n)=A((m-1),A(m,n-1)) pour n>0, m>0 ;
A(0,n)=n+1 pour n>0;
A(m,0)=A(m-1,1) pour m>0 ;

Exercice 44
Ecrire une fonction qui fournit le nombre de chiffres d’un entier donné.

Exercice 45

ENS – Rabat – Département d’Informatique 31


Notion de sous-programmes

Ecrire une procédure qui permet de dessiner la lettre X, à l'aide d'espaces et d'une
"lettre" fournie par l'utilisateur, auquel on demande aussi la "hauteur" du dessin
qu'il désire obtenir.
Par exemple : avec les réponses a et 5, elle donnera :
a a
a a
a
a a
a a

Exercice 46
Soit un programme qui visualise un menu composé de trois rubriques : Hors
d’œuvre, plat chaud et dessert.
Ecrire une procédure qui permet d’effectuer, à chaque fois, un choix exclusif.

Exercice 47
Ecrire une procedure paramétrée, qui permet l’échange des contenus de deux
paramètres formels par valeur A et B. Appeler cette procédure dans un
programme principal.On écrira les résultats dans le corps de la procédure, et dans
le programme principal.

Exercice 48
Ecrire une procedure paramétrée, qui permet l’échange des contenus de deux
paramètres formels par adresse A et B. Appeler cette procédure dans un
programme principal.On écrira les résultats dans le corps de la procédure, et dans
le programme principal.

Exercice 49
Ecrire une procédure qui affiche tous les nombres premiers qui sont compris
entre 1 et 200.

Exercice 50
Ecrire une procédure qui affiche tous les nombres parfaits qui sont compris entre
1 et 200.

Exercice 51
Ecrire une procédure qui permet d’afficher tous les diviseurs d’un entier N ainsi
que leur nombre.

Exercice 52

ENS – Rabat – Département d’Informatique 32


Notion de sous-programmes

Affichez un triangle isocèle formé d'étoiles sur N lignes (N est fourni au clavier).

ENS – Rabat – Département d’Informatique 33


Notion de sous-programmes

Exemple : N=8
*
***
*****
*******
*********
***********
*************
***************

Exercice 53
Calculer pour une valeur X donnée du type réel la valeur numérique d'un
polynôme de degré n:
P(X) = AnXn + An-1Xn-1 + ... + A1X + A0
Les valeurs de n, des coefficients An, ..., A0 et de X seront entrées au clavier.
Utiliser le schéma de Horner qui évite les opérations d'exponentiation lors du
calcul:

Exercice 54
Ecrire une procédure qui affiche la table des produits pour N variant de 1 à 10 :
X*Y I 0 1 2 3 4 5 6 7 8 9 10
--------------------------------------------------
0 I 0 0 0 0 0 0 0 0 0 0 0
1 I 0 1 2 3 4 5 6 7 8 9 10
2 I 0 2 4 6 8 10 12 14 16 18 20
3 I 0 3 6 9 12 15 18 21 24 27 30
4 I 0 4 8 12 16 20 24 28 32 36 40
5 I 0 5 10 15 20 25 30 35 40 45 50
6 I 0 6 12 18 24 30 36 42 48 54 60
7 I 0 7 14 21 28 35 42 49 56 63 70
8 I 0 8 16 24 32 40 48 56 64 72 80
9 I 0 9 18 27 36 45 54 63 72 81 90
10 I 0 10 20 30 40 50 60 70 80 90 100

ENS – Rabat – Département d’Informatique 34


Les structures de données statiques

LES STRUCTURES DE
DONNÉES STATIQUES

Une structure de données est un ensemble organisé d’informations reliées


logiquement, ces informations peuvent être traitées collectivement ou
individuellement.
Une structure de données est caractérisée par ses composantes et leur
organisation, mais surtout par ses méthodes d’accès.

I. Les structures de données homogènes


En langage Pascal:

 Tableau

Un tableau est une suite d’éléments de même type. En Pascal, la déclaration des
tableaux se fait comme suit :
Syntaxe : Var NomTab : Array[Min..Max] Of Type;
On accède à un élément du tableau en utilisant un index : Exemple NomTab[4].

 Chaînes de caractères

En Pascal, la définition du type chaîne est constituée du mot réservé STRING


suivi de la longueur maximale entre crochets. La longueur est une constante
entière dans l’intervalle [0,255]. Si la longueur maximale n’est pas précisée, elle
est égale à 255 par défaut.
Les variables chaînes occupent en mémoire la longueur maximale définie +1
octet. Le premier octet contient la longueur courante de la chaîne. Les caractères
individuels sont indexés de 1 à la longueur maximale de la chaîne.

Expressions chaînes

Le signe ‘ + ’ est utilisé pour concaténer des chaînes.


Exemple : ‘123’ + ‘456’ = ‘123456’.

ENS – Rabat – Département d’Informatique 35


Les structures de données statiques

On peut comparer deux chaînes, le résultat est une valeur booléenne.


Exemple : ‘12’ < ‘2’ est vraie

Affectation de chaînes

L’opérateur d’affectation est utilisé pour affecter la valeur d’une expression à


une variable chaîne.
Exemple : p :=’Programmation’ ;

Procédures sur les chaînes

Procédure Commentaires
supprime dans la chaîne st une sous-chaîne contenant
DELETE (st,pos,num)
num caractères à partir du caractère de position pos.
permet l’insertion de la chaîne obj dans la chaîne target
INSERT(obj,target,pos)
à la position pos.
convertit la valeur numérique de value en une chaîne,
STR(value,st)
et range le résultat dans st.
convertit l’expression chaîne st en une valeur entière
ou réelle (en fonction de type de var) et range la valeur
dans var. code doit être une variable entière. Si aucune
VAL(st,var,code)
erreur n’est détectée, code est mise à zéro, sinon code a
la valeur de la position du premier caractère en erreur
et la valeur de var est indéfinie.

Fonctions sur les chaînes

Fonctions Commentaires
retourne une sous-chaîne contenant num caractères de
COPY(st,pos,num)
st en commençant par le caractère de position pos.
retourne une chaîne qui est la concaténation de ces
CONCAT(st1,st2,…,stn)
arguments dans l’ordre où ils sont déclarés.
LENGTH(st) retourne la longueur effective de la chaîne st.
si obj est contenu dans target alors pos retourne la
POS(obj,target) position du premier caractère de obj dans target sinon
pos retourne zéro.

 Ensembles

ENS – Rabat – Département d’Informatique 36


Les structures de données statiques

La structure de données Ensemble permet de représenter l’objet mathématique


ensemble sur lequel on peut effectuer les opérations d’appartenance, de réunion,
etc.
Bien qu’en mathématiques il n’y ait pas de restriction sur les objets qui pourront
être membre d’un ensemble, Pascal ne procure qu’une forme restreinte
d’ensemble. Les membres d’un ensemble doivent être tous de même type appelé
type de base.
Déclaration : <ident> : SET of <type>
Exemple: ens: set of char

Remarques
• Le nombre maximum d’un ensemble est 256.
• On note par [ ] l’ensemble vide compatible avec tout type ensemble.

Opérateurs sur les ensembles


Le symbole d’appartenance est IN
Le symbole d’intersection est *
Le symbole de réunion est +
Le symbole de différence est -
= test d’égalité
<> test d’inégalité
>= vrai si tous les membres du second opérande sont inclus dans le premier.
<= vrai si tous les membres du premier opérande sont inclus dans le second.

En langage C

 Tableau

En langage C, la syntaxe de la définition d'un tableau est la suivante :

Syntaxe : type Nom_du_tableau [Nombre d'éléments]

Type : définit le type d'éléments que contient le tableau (un tableau en langage C
est composé uniquement d'éléments de même type).

Nombre d'éléments : est un nombre entier qui détermine le nombre de cases du


tableau.

Exemple : int T[]20 ;

ENS – Rabat – Département d’Informatique 37


Les structures de données statiques

Chaîne de caractères

En langage C, une chaîne de caractères est un tableau de type char, dont le


dernier élément est le caractère nul '\0', c'est-à-dire le premier caractère du code
ASCII (dont la valeur est 0).
Ce caractère est un caractère de contrôle (non affichable) qui permet d'indiquer la
fin de la chaîne de caractères. Ainsi, une chaine composée de n éléments sera en
fait un tableau de n+1 éléments de type char.
On peut par exemple représenter la chaîne "Bonjour" de la manière suivante:

B o n j o u r \0

Pour définir une chaîne de caractères en langage C, il suffit de définir un tableau


de caractères. Le nombre maximum de caractères que comportera la chaîne sera
égal au nombre d'éléments du tableau moins un (réservé au caractère de fin de
chaîne).
Syntaxe : char Nom_du_tableau[Nombre_d_elements]

Lecture et écriture des chaînes

Le langage C offre plusieurs possibilités de lecture ou d’écriture de chaînes :


- L’utilisation du code de format %s dans les fonctions printf et scanf.
- Les fonctions spécifiques de lecture (gets) ou d’affichage (puts) d’une
chaîne.
Exemple : char ville[25] ;
gets(ville) ;
puts(ville) ;
Remarque : Avec le code %s de scanf, on utilise les délimiteurs habituels
(espace ou la fin de ligne). Cela interdit donc la lecture d’une chaîne contenant
des espaces. Avec gets seule la fin de ligne sert de délimiteur.

Les fonctions de manipulation de chaînes de caractères

De nombreuses fonctions de manipulation de chaînes se trouvent dans le fichier


d'en-tête <string.h>, c'est la raison pour laquelle il faut ajouter la ligne suivante
au début du programme : #include <string.h>

ENS – Rabat – Département d’Informatique 38


Les structures de données statiques

Fonctions Commentaires
recopie la seconde chaîne (source) à la
strcat(but,source)
suite de la première (but).
travaille de façon semblable à strcat en
offrant en outre un contrôle sur le
strncat(but,source,lgmax)
nombre de caractères qui seront
concaténés à la chaîne d’arrivée (but).
compare deux chaînes dont on lui
fournit l’adresse et elle fournit une
valeur entière définie comme étant :
strcmp(chaîne1,chaîne2)
• Positive si chaîne1 > chaîne2
• Nulle si chaîne1 = chaîne2
• Négative si chaîne1 < chaîne2
travaille comme strcmp mais elle limite
strncmp(chaîne1,chaîne2,lgmax) la comparaison au nombre maximal de
caractères indiqués par l’entier lgmax.
travaillent respectivement comme
stricmp(chaîne1,chaîne2) et strcmp et strncmp, mais sans tenir
strnicmp(chaîne1,chaîne2,lgmax) compte de la différence entre
majuscules et minuscules.
recopie la chaîne située à l’adresse
strcpy(destin,source) source dans l’emplacement d’adresse
destin.
procède de manière analogue à strcpy,
en limitant la copie au nombre de
strncpy(destin,source,lgmax)
caractères précisés par l’expression
entière lgmax.
recherche dans chaîne la première
strchr(chaîne,caractère) position où apparaît le caractère
mentionné.
réalise le même traitement que strchr,
strrchr(chaîne,caractère) mais en explorant la chaîne concernée à
partir de la fin.
recherche dans chaîne la première
strstr(chaîne,sous-chaîne) occurrence de la sous-chaîne
mentionnée.

ENS – Rabat – Département d’Informatique 39


Les structures de données statiques

II. Les structures de données hétérogènes


En langage Pascal

 Les enregistements

Un enregistrement est un ensemble d’informations de types différents accessibles


individuellement ou collectivement. C’est une structure constituée d’un nombre
fixe de composantes appelées champs.
Syntaxe : TYPE nom_type = RECORD champ1:type ; champ2:type ;.... END;
Exemple : TYPE date = RECORD
Jour : 1..31 ;
Mois : (jan,fev,mars,avr,mai,jui,juil,aout,sep,oct,nov,dec) ;
An : 1900..2000 ;
END ;
VAR date_nais : date ;
L’accès au champ jour dans date_nais par exemple se fait par date_nais.jour.
L’affectation entre deux variables enregistrements de même type est autorisée.
Exemple : with date do jour:=2;
Instruction with

Syntaxe: WITH nom_enregistrement DO instruction

Elle permet d'omettre le nom_enregistrement dans l'instruction.

En langage C

 Les structures

Dans un tableau, tous les constituants doivent être semblables. Ce n'est pas le cas
des structures, qui sont des variables composées de plusieurs variables (ou
CHAMPS) de types différents.

Syntaxe : struct Nom_Structure {


type_champ1 Nom_Champ1;
type_champ2 Nom_Champ2;
...
};

ENS – Rabat – Département d’Informatique 40


Les structures de données statiques

Exemple : struct date{


Int jour;
Int mois ;
Int annee ;
};
Définition d’une variable structurée
C’est une variable ayant comme type celui d'une structure que l'on a
précédemment déclarée.
Syntaxe : struct Nom_Structure Nom_Variable_Structuree;

- Nom_Structure représente le nom d'une structure que l'on aura


préalablement déclarée.
- Nom_Variable_Structuree est le nom de la variable de type
Nom_Structure.
Pour accéder aux champs d'une structure, on utilise un point placé entre le nom
de la variable structurée que l'on a définie et le nom du champ.
Exemple : date_naiss.jour;

III- Enoncé des exercices


Exercice 55
Ecrire une procédure qui affiche les nombres négatifs d’une liste réelle.

Exercice 56
Ecrire une procédure qui met à zéro la diagonale d’une matrice carrée.

Exercice 57
Ecrire une procédure qui affiche l’occurrence d’existence d’un nombre réel dans
une liste de nombres réels.

Exercice 58
Ecrire une procédure qui met le plus petit élément d’une liste au début de celle-
ci.

Exercice 59
Ecrire une procédure qui met les éléments négatifs d’une liste à gauche et les
éléments positifs à droite de la liste.

ENS – Rabat – Département d’Informatique 41


Les structures de données statiques

Exercice 60
Ecrire une procédure qui classe une liste de notes de la plus petite à la plus
grande.

Exercice 61
Etant donné N étudiants, leurs notes correspondantes à M matières et leur
moyenne. Ecrire une procédure qui affiche à côté de chaque étudiant son
classement.

Exercice 62
Le tri à bulles est un tri par échange. Le principe de base est de réordonner les
couples non classés tant qu’ils existent. La méthode de tri à bulles consiste à
parcourir la liste en comparant deux éléments successifs et en les permutant s’il y
a lieu. Ecrire une procédure qui réalise ce tri.

Exercice 63
Un palindrome est un mot, ou une phrase, lisible indifféremment de la gauche
vers la droite ou inversement. Ecrire une fonction qui retourne si une chaîne de
caractères est un palindrome ou non.

Exercice 64
Ecrire une fonction qui retourne la fréquence d’occurenced’un mot dans une
phrase.

Exercice 65
Ecrire une procédure qui enlève tous les blancs au début d’une phrase et qui
laisse un seul blanc entre les différents mots de la phrase.

Exercice 66
Soit un nombre entier positif N. Ecrire une fonction qui donne son équivalent
dans une base donnée B (2≤ B≤ 16).

Exercice 67
Soit N un nombre donné en base B (B ≠ 10). Ecrire une fonction qui donne son
équivalent en base 10.

Exercice 68
Soit N un nombre donné en base B1. Ecrire une fonction qui donne son
équivalent en base B2.

ENS – Rabat – Département d’Informatique 42


Les structures de données statiques

Exercice 69
Si on est amené à réaliser des opérations sur des nombres entiers très grands, on
peut utiliser les chaînes de caractères pour représenter ces nombres et ensuite
faire l’opération par bloc.
Ecrire une procédure pour réaliser l’opération d’addition sur de tels nombres.

Exercice 70
Ecrire une procédure qui permet de passer de la représentation d’un nombre en
chiffres romains à sa représentation décimale.

Exercice 71
Ecrire une procédure qui permet de passer de la représentation décimale d’un
nombre à sa représentation en chiffres romains.

Exercice 72
Ecrire une fonction qui retourne le déterminant d’une matrice carrée.

Exercice 73
Ecrire une procédure qui calcule l’inverse d’une matrice carrée.

Exercice 74
Un carré magique est un carré divisé en cellules dans lesquelles les nombres
entiers, à partir de 1 sont disposés de telle sorte que les sommes de chaque ligne,
de chaque colonne et de chaque diagonale soient égales.
Exemple :
6 1 8
7 5 3
2 6 4

Ecrire une procédure qui permet de réaliser le carré magique d’ordre n (n


impair).
Exercice 75
Ecrire un programme qui permet de saisir et d’afficher les informations d’une
liste d’étudiants.

Exercice 76
Ecrire les procédures qui donnent le calcul sur les nombres complexes au moyen
d’un type enregistrement.

ENS – Rabat – Département d’Informatique 43


Les structures de données dynamiques

LES STRUCTURES DE DONNÉES


DYNAMIQUES

Dans la pratique, très souvent, on veut représenter des objets, soit dont on ne
connaît pas à priori la taille, soit dont la taille est variable, selon les cas ou au
cours du traitement. On est alors amené à utiliser des structures qui peuvent
évoluer, pour bien s’adapter à ces objets. Ce sont les structures de données
dynamiques.

I- En langage Pascal
I-1. Les pointeurs

Un pointeur est une variable contenant l'adresse d'une autre variable d'un type
donné.
Syntaxe : type type_pointeur = ^type_base ;
type_base = ident_type ;
Si le type de base type_base est un identificateur non encore déclaré, il doit l’être
dans la même partie de la déclaration que le type pointeur type_pointeur.
Exemple : type ref = ^integer ;
Remarques :
• ref est une variable pointeur et ref^ la variable pointée.
• La constante NIL peut être affectée à n’importe quelle variable pointeur
(NIL ne fait référence à aucun élément du type associé).
• Le type prédéfini Pointer indique un pointeur non typé, c’est-à-dire un
pointeur qui ne pointe pas sur un type particulier.
• L’opérateur @ fait pointer la variable pointeur sur une zone mémoire
contenant une variable.

 Procédures et fonctions d’allocation dynamique de mémoire

ENS – Rabat – Département d’Informatique 44


Les structures de données dynamiques

Ces procédures et fonctions permettent de manipuler le tas (zone de mémoire qui


correspond à tout ou partie de l’espace mémoire laissé vacant après chargement
du programme).

Procédures ou fonctions Commentaires


crée un espace mémoire de la taille de la
New (var p:pointeur) variable pointée et affecte l’adresse de
celui-ci au pointeur
crée une nouvelle variable dynamique de la
GetMem (var p:pointeur;
taille indiquée et place son adresse dans une
taille:word)
variable pointeur.
fait pointer la variable pointeur sur une
adresse mémoire spécifique sans faire
intervenir de notion de variable occupant
Ptr (seg,dep:word)
cet espace. Ptr convertit une adresse format
segment:déplacement en une valeur de type
pointeur.
libère la mémoire d’une variable
Dipose (var p:pointeur)
dynamique.
FreeMem (var libère la mémoire d’une variable
p:pointeur;taille:word) dynamique d’une certaine taille
mémorise la valeur du pointeur de tas dans
Mark (var p:pointeur)
une variable de type pointeur.
restaure le tas dans une configuration
Release (var p:pointeur) donnée. Le pointeur p doit être initialisé par
la procédure Mark.

 Les listes chaînées

Une liste chaînée est une suite de données (liste) liées entre elles. Le lien est
réalisé par des pointeurs. Chaque élément de la liste est un enregistrement dont
l’un des champs est un pointeur qui pointe vers l’élément suivant.

ENS – Rabat – Département d’Informatique 45


Les structures de données dynamiques

Tête de la liste
L a1

e1 a2 e2 a3 en NIL

Queue de la liste

Exemple :
type nbrpoint = ^nombre ;
nombre = record
nbr : integer ;
suivant : nbrpoint ;
end ;

L’insertion d’un élément x dans une liste chaînée se fait en deux étapes :
1. allocation de l’espace mémoire qu’occuperait x.
2. création des liens avec l’élément de gauche puis de droite.

L’élimination d’un élément x d’une liste chaînée se fait en deux étapes :


1. création des liens entre l’élément de gauche et de droite.
2. libération de l’espace mémoire qu’occupait x.

 Les arbres

Lorsqu’on généralise la notion de listes chaînées en associant à chaque élément


de la liste 2 ou plusieurs successeurs, tout en gardant une structure à une seule
tête, on obtient ce qu’on peut appeler un arbre.

B C

D E F G

I
H
J

ENS – Rabat – Département d’Informatique 46


Les structures de données dynamiques

Définitions :

 Nœud : chaque élément d’un arbre est appelé nœud.


 Racine d’arbre : le premier nœud d’arbre est appelé racine (ici A).
 Feuille : un nœud sans successeur est appelé feuille (comme D, E, F, H,
I,J).
 Arc : un lien entre 2 nœuds successifs est appelé arc.
 Chemin : un chemin est une séquence d’arcs reliant deux nœuds d’un
même arbre (A B E).
 Père / Fils / Ancêtre / Descendant :
- Un successeur B d’un nœud A est appelé fils de A, A est alors père
de B ;
- Si A dispose d’un autre fils C alors B et C sont frères ;
- B et C sont aussi appelés des descendants immédiats ;
- Les fils de B et C sont aussi des descendants de A ;
- A est alors l’ancêtre des fils de B et C ainsi que de leurs fils.
 Arbre évalué : c’est un arbre dont les arcs portent des étiquettes permettant
de définir ce qu’on appelle un coût pour se rendre d’un nœud à l’autre. Il
est possible de calculer le coût relativement à un chemin.
 Arbre binaire : les arbres binaires sont le type d’arbre le plus utilisé car il
est plus simple à gérer et à implémenter, il dispose au maximum de 2 fils.
Le premier est appelé fils gauche, le deuxième fils droit. Par contre, un
arbre multiple est un arbre dont chaque nœud peut disposer de plus de 2
fils. Il s’agit donc d’une structure plus complexe que celle des arbres
binaires. Pour faciliter leur gestion, il existe plusieurs méthodes pour
transformer un arbre en son équivalent binaire. Parmi ces méthodes, on
peut citer la suivante :
• Le 1er fils d’un nœud est marqué comme fils gauche de
l’arbre binaire correspondant.
• Les autres fils sont rangés successivement comme fils
er
droit du 1 fils c'est-à-dire pour chaque nœud de l’arbre binaire obtenu,
son 1er fils se trouve à gauche et son 1er frère se trouve à droite.

Parcours d’arbres binaires

ENS – Rabat – Département d’Informatique 47


Les structures de données dynamiques

On appelle parcours d’un arbre tout algorithme permettant d’accéder une et une
seule fois à tous les nœuds de l’arbre. On distingue six parcours généraux,
symétriques deux à deux, valides pour les arbres binaires quelconques et répartis
en trois catégories qui sont :
 Les parcours en préordre (préfixés)
Parcourir un arbre binaire en préordre c’est d’abord inspecter la racine, puis
parcourir en préordre le sous-arbre gauche (respectivement le sous-arbre droit) et
enfin parcourir en préordre le sous- arbre droit (respectivement le sous-arbre
gauche).
Exemple :

8
5
10
1 4
1
2
7

Parcours en préordre racine, sous-arbre gauche, sous-arbre droit 2, 5, 1, 7, 4, 8,


10, 12.
Parcours en préordre racine, sous-arbre droit, sous-arbre gauche 2, 8, 10, 12, 5, 4,
1, 7.
 Les parcours en postordre (postfixés)
Parcourir un arbre binaire en postordre c’est d’abord parcourir en postordre le
sous-arbre gauche (respectivement le sous-arbre droit), puis parcourir en
postordre le sous-arbre droit (respectivement le sous-arbre gauche) et enfin
inspecter la racine.
Exemple : même exemple que précédemment.
Parcours en postordre sous-arbre gauche, sous-arbre droit 7, 1, 4, 5, 12, 10, 8, 2.
Parcours en postordre sous-arbre droit, sous-arbre gauche 12, 10, 8, 7, 1, 4, 5, 2.
 Les parcours en ordre (infixés)

ENS – Rabat – Département d’Informatique 48


Les structures de données dynamiques

Parcourir un arbre binaire en ordre c’est d’abord parcourir en ordre le sous-arbre


gauche (respectivement le sous-arbre droit), puis inspecter la racine et enfin
parcourir en ordre le sous-arbre droit (respectivement le sous-arbre gauche).
Exemple : même exemple que précédemment.
Parcours en ordre sous-arbre gauche, racine, sous-arbre droit 1, 7, 5, 4, 2, 8, 12,
10.
Parcours en ordre sous-arbre droit, racine, sous-arbre gauche 10, 12, 8, 2, 4, 5, 7,
1.

Arbres ordonnés

 Arbre binaire ordonné horizontalement


Un arbre binaire est ordonné horizontalement (de gauche à droite) si la clé de
tout nœud non feuille est supérieure à toutes celles de son sous-arbre gauche et
est inférieure à toutes celles de son sous-arbre droit.
Exemple :
8

4 1
0
9
5
1
3

 Recherche d’un élément dans un arbre ordonné horizontalement


La recherche d’un élément dans un arbre ordonné horizontalement qui tient
compte de l’ordre est dichotomique et donc très supérieure à une recherche
systématique à l’aide d’un parcours général.
 Insertion d’un élément
Le principe de l’insertion d’un élément dans un arbre binaire ordonné
horizontalement est le suivant : on recherche de façon récursive la place de
l’élément, ce qui conduit nécessairement à une feuille si l’élément ne figure pas
déjà dans l’arbre, puis on accroche l’élément à cette feuille.
Exemple : insertion de l’élément 6 dans l’arbre suivant

ENS – Rabat – Département d’Informatique 49


Les structures de données dynamiques

8 8
1
4 1 4
0
0
9
5 5 9 1
1 3
3 Insertion 6

 Suppression d’un élément


Le principe de la suppression d’un élément d’un arbre binaire ordonné
horizontalement est le suivant :
- si l’élément est une feuille alors on le supprime simplement.
- si l’élément n’a qu’un descendant alors on le remplace par ce
descendant.
- si l’élément a deux descendants, on le remplace au choix, soit par
l’élément le plus à droite du sous-arbre gauche, soit par l’élément le
plus à gauche du sous-arbre droit, afin de conserver la propriété
d’ordre horizontal.

Exemple : Suppression de l’élément 7


1 1
6 6

1 1
7 6
8 8

4 9 2 4 9 2
4 4
1 1
2 6 8 2 8
0 0
Suppression

Représentation d’un arbre en Pascal

ENS – Rabat – Département d’Informatique 50


Les structures de données dynamiques

Une manière possible de représenter un arbre est la suivante : l’ensemble des fils
du même père forme une liste, donc chaque fils a un pointeur vers son frère qui
le suit. Le dernier frère a 0. Chaque père a un pointeur vers son premier fils.
Les fils de la dernière génération (feuilles) ont 0. Chaque fils à un pointeur vers
son père. L’ancêtre (racine) a 0.
Cela va être contenu dans un array of record :
type gene = Record
nom : string;
pere : integer ;
frere : integer ;
fils : integer;
end ;
arbre = array [1..max] of gene ;
var mafamille : arbre;
Exemple : (entre parenthèse figure l’indice dans le tableau)

Pierre (1)

Paul (2) Jacques (3)

Marcel (4) George (5) Jean (6)

Gérard (7) Alain (8) Louis (9)

1 2 3

Pierre 0 0 2 Paul 1 3 4 Jacques 1 0 6

II. En langage C
 Les pointeurs

Un pointeur est une variable qui doit être définie en précisant le type de la
variable pointée, de la façon suivante :
Syntaxe : type * Nom_du_pointeur
Le type de la variable pointée peut-être aussi bien un type primaire (tel que int,
char, etc.) qu'un type complexe (tel que struct, etc .).

ENS – Rabat – Département d’Informatique 51


Les structures de données dynamiques

Après avoir déclaré, un pointeur il faut l'initialiser en utilisant l'opérateur


d'affectation '=' suivi de l'opérateur d'adresse '&' auquel est accollé un nom de
variable (celle-ci doit bien sûr avoir été définie auparavant).
Syntaxe : Nom_du_pointeur = &nom_de_la_variable_pointee;
Après (et seulement après) avoir déclaré et initialisé un pointeur, il est possible
d'accéder au contenu de l'adresse mémoire pointée par le pointeur grâce à
l'opérateur '*'.
 Fonctions d’allocation dynamique de mémoire

Le prototype de ces fonctions figure à la fois dans stdlib.h et dans alloc.h.

Fonctions Commentaires
alloue un emplacement de taille octets,
sans l’initialiser et fournit l’adresse
void * malloc(size_t taille) correspondante lorsque l’allocation a
réussi ou un pointeur nul dans le cas
contraire.
alloue l’emplacement nécessaire à
void * calloc(size_t nb_blocs,size_t
nb_blocs consécutifs, ayant chacun
taille)
une taille de taille octets.
permet de modifier la taille d’une zone
void * realloc(void * pointeur, size_t
préalablement allouée (par malloc,
taille)
calloc ou realloc).
libère la mémoire d’adresse adr. Ce
pointeur doit obligatoirement désigner
void free(void* adr) une zone préalablement allouée par
malloc, calloc, realloc. Si adr est nul,
cette fonction ne fait rien.

 Les tableaux dynamiques

Syntaxe : Type *T ;
T = (type*) malloc (sizeof(type)*N) ; Avec N étant le nombre
d’éléments
du tableau.

 Les listes chaînées

ENS – Rabat – Département d’Informatique 52


Les structures de données dynamiques

Une liste chaînée est une structure comportant des champs contenant des données
et un pointeur vers une structure de même type. Ainsi, la structure correspondant
à une liste chaînée contenant une chaîne de 15 caractères et un entier ressemble à
ceci:

struct Nom_de_la_liste {
char Chaine[16];
int Entier;
struct Nom_de_la_liste * pSuivant;
};

 Les arbres

La représentation dynamique non contiguë consiste à créer des nœuds


séparément les uns des autres et les relier par le chaînage adéquat pour
préciser qu’un nœud donné est fils gauche ou fils droit d’un autre nœud.
Ainsi, chaque nœud est constitué de 3 parties : l’information, un pointeur sur
le nœud gauche et un pointeur sur le nœud droit.

info
g d

info
info d
g
g d

info
g d

Exemple :
Pour le cas d’un arbre de caractères, la structure est la suivante :
Typedef struct str{
char info ;
str *g, *d ;
} *Arbre p;

ENS – Rabat – Département d’Informatique 53


Les structures de données dynamiques

III- Enoncé des exercices


Exercice 77
Ecrire une procédure qui permet la création en file d’une liste chaînée.

Exercice 78
Ecrire une procédure qui permet la création en pile d’une liste chaînée.

Exercice 79
Ecrire une procédure qui recherche un élément dans une liste chaînée.

Exercice 80
Ecrire une procédure qui insert un élément dans une liste chaînée.

Exercice 81
Ecrire une procédure qui élimine un élément d’une liste chaînée.

Exercice 82
Ecrire une procédure qui empile un élément dans une pile représentée par une
liste chaînée.

Exercice 83
Ecrire une procédure qui désempile un élément dans une pile représentée par une
liste chaînée.

Exercice 84
Ecrire une procédure qui permet la création d’une liste doublement chaînée.

Exercice 85
Ecrire une procédure qui recherche un élément dans une liste doublement
chaînée.

Exercice 86
Ecrire une procédure qui insert un élément dans une liste doublement chaînée.

Exercice 87
Ecrire une procédure qui élimine un élément d’une liste doublement chaînée.

Exercice 89
Ecrire une fonction qui recherche un élément dans une liste chaînée circulaire.

ENS – Rabat – Département d’Informatique 54


Les structures de données dynamiques

Exercice 90
Ecrire une procédure qui insert un élément dans une liste chaînée circulaire.

Exercice 91
Ecrire une procédure qui élimine un élément d’une liste chaînée circulaire.

Exercice 92
Un paragraphe est une suite de phrases. Une phrase est une suite de mots qui se
termine par un point (‘.’). Deux mots sont séparés par un blanc (‘ ’).
Dans cet exercice on représentera un paragraphe par une liste chaînée, et aussi
une phrase par une liste chaînée.
1- Ecrire une procédure qui permet la création d’une telle représentation.
2- Ecrire une procédure qui permet la recherche de la première occurrence
d’un mot dans le paragraphe. Le résultat de la recherche donne la position
de ce mot.
3- Ecrire une procédure qui permet l’insertion d’un mot M1 après un mot
M2 donné. Si le mot M2 ne se trouve pas dans le paragraphe, on ne fait
pas d’insertion.
4- Ecrire une procédure qui permet l’élimination d’un mot M1 du
paragraphe.
5- Ecrire une fonction qui permet la recherche d’une phrase, donnée par son
premier mot, dans le paragraphe. Le résultat de la recherche donne la
position de cette phrase dans le paragraphe.
6- Ecrire une procédure qui permet l’insertion d’une phrase ph1 après une
phrase ph2 donnée. Si la phrase ph2 ne se trouve pas dans le paragraphe,
on insert ph1 à la fin du paragraphe.
7- Ecrire une procédure qui permet l’élimination d’une phrase ph1 du
paragraphe.

Exercice 93
Ecrire la procédure du parcours d’un arbre binaire en préordre.

Exercice 94
Ecrire la procédure du parcours d’un arbre binaire en postordre.

Exercice 95
Ecrire la procédure du parcours d’un arbre binaire en ordre.

Exercice 96

ENS – Rabat – Département d’Informatique 55


Les structures de données dynamiques

Ecrire une fonction qui recherche un élément dans un arbre ordonné


horizontalement.

Exercice 97
Ecrire une procédure qui insert un élément dans un arbre ordonné
horizontalement.

Exercice 98
Ecrire une procédure qui supprime un élément dans un arbre ordonné
horizontalement.

ENS – Rabat – Département d’Informatique 56


Les fichiers

LES FICHIERS

Dans tous les langages de programmation, on utilise la notion de fichier. Il s'agit


d'enregistrer des données sur un support plus durable (disquette, disque dur, etc.).
Les principales manipulations sur un fichier sont :
- L'ouverture du fichier
- La lecture ou l’écriture d'un élément du fichier
- Le déplacement sur le fichier.
- La fermeture du fichier.
Des erreurs de manipulation d'un fichier peuvent survenir. En particulier, on a
comme erreurs classiques :
- La tentative d'ouvrir en lecture un fichier qui n'existe pas.
- La tentative de lire au delà de la fin d'un fichier.
- La tentative d'écrire sur une disquette déjà pleine ou sur un fichier protégé
en écriture.
Dans la majorité des langages de programmation, on distingue deux types de
fichiers: les fichiers textes et les fichiers binaires.

Fichier texte
La tête de lecture et d'écriture se trouve sur un octet et cet octet est interprété
comme un caractère en code ASCII. On a alors ce qu'on appelle un fichier texte.
Un texte est en général divisé en lignes, marquées par des caractères de fin de
ligne et terminé par un code de fin de fichier. Un fichier texte peut se lire
caractère par caractère ou ligne par ligne.

Fichier binaire
La tête de lecture et d'écriture recouvre une variable, d'un type quelconque (réel,
double, structure, tableau, etc.) codée sur n octets comme en mémoire centrale.
On parle alors de fichier binaire. Une opération de lecture lit en bloc tous les
octets constituant cette variable.

I. En langage Pascal
En Pascal, un type fichier est défini par le mot réservé "File Of" suivi du type des
composantes de ce fichier.

ENS – Rabat – Département d’Informatique 57


Les fichiers

Exemple :
Type Fic_mess = File Of string[80] ;
Fic_pers = File Of Record
Nom, prn:string[14];
Doti:string[6];
End;

I.1 Opérations sur les fichiers


Soit filvar un identificateur de variable de type fichier.

Expression Commentaires
str est une expression chaîne résultant en tout nom légal de
fichier. Le nom du fichier est affecté à la variable filval et
Assign(filval,str) toutes les opérations suivantes sur filval affecteront le fichier
disque (externe) str. Assign ne doit jamais être utilisée sur un
fichier en cours d’utilisation.
un nouveau fichier disque dont le nom est assigné à la variable
filval est crée et préparé pour le traitement. Le pointeur de
Rewrite(filval) fichier est placé au début de celui-ci (c’est-à-dire : sur
l’enregistrement numéro 0). Un fichier disque crée par
Rewrite est vide.
le fichier disque affecté à la variable filval est préparé pour le
traitement. Le pointeur de ce fichier est positionné sur le
Reset(filval)
composant numéro 0. filval doit référencer un fichier existant,
sinon il se produira une erreur d’entrée/sortie.
var représente une ou plusieurs variables de même type que
les éléments de filval. Chaque variable est lue sur le fichier
Read(filval,var)
disque. Après chaque opération de lecture le pointeur de
fichier est avancé sur le composant suivant.
var représente une ou plusieurs variables de même type que
les éléments de filval. Chaque variable est écrite sur le fichier
Write(filval,var)
disque. Après chaque opération d’écriture le pointeur de
fichier est avancé sur le composant suivant.
déplace le pointeur de fichier sur le nième composant du fichier
Seek(filval,n)
référencé par filval. N est une expression entière.
Filesize(filval) retourne le nombre de composants d’un fichier.
Close(filval) le fichier disque associé à filval est fermé et le répertoire du
disque est mis à jour. Pour tenir compte des modifications
apportées au fichier, il est nécessaire de fermer un fichier

ENS – Rabat – Département d’Informatique 58


Les fichiers

Expression Commentaires
après traitement.
fonction booléenne qui retourne vraie si le pointeur de fichier
Eof(filval)
est positionné à la fin du fichier disque.
fonction entière retournant la position courante du pointeur de
Filepos(filval)
fichier.

Remarque : un paramètre formel de type fichier doit être toujours donné par
adresse.

I.2 Les fichiers textes


 Déclaration

La déclaration d’un fichier texte se fait par le mot réservé Text.


Exemple : var fich_text : Text ;

 Opérations sur les fichiers textes

Toute opération sur les fichiers textes doit être précédée par un appel à la
procédure Assign, Un appel à Reset ou Rewrite doit précéder toute opération
de lecture ou d’ecriture.

Rewrite permet de créer un nouveau fichier texte et la seule opération autorisée


est l’ajout de nouveaux éléments à la fin de ce fichier.

Reset est utilisée pour ouvrir un fichier existant en lecture, la seule opération
permise sur ce fichier est la lecture séquentielle. Lorsqu’un nouveau fichier texte
est fermé, une marque de fin de fichier est mise à la fin du fichier.

L’entrée et la sortie des caractères dans les fichiers textes s’effectuent par les
procédures Read(filvar,c) et Write(filval,c). Les procédures Readln, Writeln et la
fonction EoLn permettent le traitement des lignes d’un fichier texte.

Expressions Commentaires
va au début de la ligne suivante, c’est-à-dire
Readln(filvar) ou
écarte tous les caractères jusque et y compris la
readln(filvar,st1,st2,..,stn)
séquence CR/LF (la marque de la fin de ligne).

ENS – Rabat – Département d’Informatique 59


Les fichiers

Expressions Commentaires
Writeln(filvar) ou écrit une marque de fin de ligne, c’est-à-dire une
writeln(filvar,st1,..,stn) séquence CR/LF dans le fichier texte.
fonction booléenne retournant vrai si la fin de
ligne a été atteinte, c’est-à-dire si le pointeur de
EoLn(filvar) fichier est positionné sur le caractère CR de la
séquence CR/LF. Si Eof(filvar) est vrai alors
EoLn(filvar) est également vrai.
similaire à EoLn, mais écarte les espaces et les
seekEoLn(filvar)
Tabs avant de faire le test.
retourne vrai si le pointeur de fichier est
Eof(filvar)
positionné sur la fin de fichier (Ctrl-Z).
similaire à Eof, mais écarte les espaces, les Tabs
SeekEof(filvar) et les marques de fin de ligne avant de faire le
test.
ouvre un fichier texte existant en mode ajout.
Append(var filvar :Text) Après un appel à Append, seule l’écriture est
autorisée.
vide la mémoire tampon associée à un fichier
Flush(var filvar :Text)
texte ouvert en mode écriture.
assigne un tampon d’entrée/sortie à un fichier
texte. Toute variable fichier de type texte dispose
SetTextBuf(var d’un tampon mémoire, dont la taille est de 128
filvar:Text;var octets par défaut. Le tampon est utilisé lors des
tampon[ ;taille :Word]) opérations de lecture et d’écriture. La taille est
suffisante pour la plupart des applications.
SetTextBuf doit être utilisée juste après Assign.

Remarques :

• Les procédures et fonctions Seek, FilePos et FileSize ne s’appliquent pas aux


fichiers textes.
• Ctrl-Z a pour code ASCCI 26, CR 13 et LF 10.

II. En langage C
Pour pouvoir manipuler les fichiers en C, on doit déclarer un pointeur sur la
structure FILE.

ENS – Rabat – Département d’Informatique 60


Les fichiers

Exemple : FILE *sortie ;

II.1 Ouverture et création d'un fichier


La fonction fopen a pour argument deux chaînes de caractères, le nom du fichier
et le mode d'ouverture. Elle donne comme résultat un pointeur qui est NULL si
l'ouverture a échoué, sinon le pointeur renvoyé est utilisé dans les écritures, les
lectures et les déplacements ultérieurs.

Exemple:
#include <stdio.h>
FILE *Pointeur_sur_fichier;
Pointeur_sur_fichier = fopen("C:\IUT\essai.txt", "wt");
Ouvre (ou crée s'il n'existe pas) un fichier texte nommé essai.txt dans le
répertoire IUT du disque C. Les modes de base sont :
• "r" (read : lecture) : lecture seulement ; le fichier doit exister.
• "w" (write : écriture) : écriture seulement. Si le fichier n’existe pas,
il est créé. S’il existe, son ancien contenu est perdu.
• "a" (append : ajout) : si le fichier existe déjà, il sera étendu. S’il
n’existe pas, il sera créé.
• "r+" : mise à jour (lecture et écriture). Le fichier doit exister.
• "t" ou "b" : lorsque l’implémentation distingue les fichiers de texte
des autres, il est possible d’ajouter l’une de ces deux lettres à chacun des
modes précédents. La lettre t précise que l’on a affaire à un fichier texte ; la
lettre b précise que l’on a affaire à un fichier binaire.

II.2 Ecriture dans un fichier


fprintf : écriture formatée dans un fichier. Cette fonction est l'équivalent pour un
fichier de printf pour les sorties à l'écran. Les formats (précédés du symbole %)
sont les mêmes.
Exemple :
char erreur;
erreur = fprintf(Pointeur_sur_fichier, "Le chiffre %d s'écrit quatre", 4);

Dans un fichier texte

ENS – Rabat – Département d’Informatique 61


Les fichiers

• fputc : ce qui signifie "met un caractère dans un fichier". Comme son nom
l'indique, cette fonction écrit un octet dans un fichier.
Exemple:
char erreur;
erreur = fputc('x', Pointeur_sur_fichier);
• fputs : ce qui signifie "met une chaîne dans un fichier". Comme son
nom l'indique également, cette fonction écrit une chaîne de caractères dans
un fichier.
Exemple :
char erreur;
erreur = fputs("chaîne de caractère", Pointeur_sur_fichier);
Remarque :
Dans ces deux cas, la variable erreur de type char contient le dernier caractère
écrit et EOF si une erreur se présente (fin de fichier, disque plein, etc.).

Dans un fichier binaire

• fwrite : écrit dans un fichier des objets d'un type quelconque. Il faut
préciser la taille d'un objet (par exemple avec sizeof(objet)), le nombre
d'objets à écrire et le pointeur du fichier destination. Cette fois, la fonction
renvoie le nombre d'éléments effectivement écrits. Pour tester que tout va
bien, il faut comparer le nombre d'éléments écrits avec le nombre d'objets à
écrire.
Syntaxe :
nombre_d_elements_ecrits = fwrite(ptr_sur_tableau, taille_element,
nb_elements, fichier)

II.3 Lecture dans un fichier


Les opérations de lecture sont les symétriques de celles d'écriture. On retrouve la
même classification et à peu près la même syntaxe.

• fscanf : lecture formatée analogue à scanf.


Syntaxe : Nb_lu = fscanf(Pointeur_sur_fichier, format, liste de pointeurs);
Où : Nb_lu est le nombre d'arguments lus et acceptés. Par exemple :
Nb_lu = fscanf(Pointeur_sur_fichier, "%s", Chaîne);

ENS – Rabat – Département d’Informatique 62


Les fichiers

Met dans Chaîne les caractères situés entre le début et la fin de fichier ou
le prochain espace blanc. Les espaces blancs initiaux sont
automatiquement sautés. Les formats de fscanf sont les mêmes que ceux
de scanf.

Dans un fichier texte


• fgetc : ce qui signifie "prend un caractère dans un fichier".
Exemple :
int caractere;
caractere = fgetc(Pointeur_sur_fichier);
• fgets : ce qui signifie "prend une chaîne dans un fichier". Lit un certain
nombre de caractères dans un fichier et les met dans une chaîne en ajoutant
le caractère nul à la fin.
Exemple :
fgets(Chaine, 10, Pointeur_sur_fichier);
Lit 10 caractères dans le fichier et les écrits dans Chaine. Un dernier
caractère nul est ajouté. Mais, si une fin de ligne (EOL) est rencontrée
avant le dixième caractère lu, seuls les caractères avant la fin de ligne
seront lus et ils seront suivis dans la chaîne par EOL et NULL.

Dans un fichier binaire

Syntaxe : Nb_lu = fread(pointeur_sur_tableau, taille_element, nb_elements,


fichier);

Nb_lu est égal à nb_elements si l'écriture s'est passée sans incident.


Exemple:
#include <stdio.h>
FILE *Pointeur_sur_fichier;
fopen("C:\IUT\essai.dta", "wb");
int tableau[5];
nb = fread(tableau, sizeof(int), 3, Pointeur_sur_fichier);
Lit dans le fichier binaire "essai.dta" des nombres entiers et les range dans les
trois premières cellules du tableau ; nb a pour valeur le nombre d'éléments écrits,
3 si tout s'est bien passé.

II.4 Déplacement dans un fichier

ENS – Rabat – Département d’Informatique 63


Les fichiers

• int fseek(FILE *flux,long noct,int org): place le pointeur du flux indiqué à


un endroit défini comme étant situé à noct octets de l’origine spécifiée par
org :
org = SEEK_SET correspond au début du fichier.
org = SEEK_CUR correspond à la position actuelle du pointeur.
org = SEEK_END correspond à la fin du fichier.
• long ftell (FILE *flux) : fournit la position courante du pointeur du
flux indiqué (exprimée en octets par rapport au début du fichier).

II.5 Fermeture du fichier


• int fclose(FILE *flux) : désalloue l’espace mémoire associé au flux
concerné et ferme le fichier correspondant. Fournit la valeur EOF en cas
d’erreur et la valeur 0 dans le cas contraire.

III- Enoncé des exercices


Exercice 99
Ecrire un programme qui permet de créer un fichier d’étudiants.

Exercice 100
Ecrire une procédure qui permet de modifier les informations d’un étudiant.

ENS – Rabat – Département d’Informatique 64


Solutions des exercices

SOLUTIONS DES EXERCICES

Pascal C
Exercice 1
Ecrire un programme qui permet d’afficher le message suivant : mon premier programme.
Program afficher ; #include<stdio.h>
Begin #include<conio.h>
Writeln(‘mon premier programme’) ; void main()
Readln ; {
End . printf("mon premier programme") ;
getch() ;
}
Exercice 2
Ecrire un programme qui demande à l'utilisateur les valeurs de 2 entiers x et y, qui permute leurs valeurs et qui
les affiche.
Program Echange; #include<stdio.h>
var x,y,tmp:integer; #include<conio.h>
begin void main()
write('donner deux entiers differents:'); {
readln(x,y); clrscr();
writeln('x=',x,' et y=' ,y); int x,y,tmp;
tmp:=x; printf("entrez deux nombres: ");

ENS – Rabat – Département d’Informatique 65


Solutions des exercices

x:=y; scanf("%d %d",&x,&y);


y:=tmp; printf("avant echange x=%d et y=%d\n",x,y);
writeln('x=',x,' et y=',y); tmp=x;
readln; x=y;
end. y=tmp;
printf("apres echange x=%d et y=%d",x,y);
getch();
}
Exercice 3
Ecrire un programme qui échange 3 entiers.
Program Echange; #include<stdio.h>
var x,y,tmp,z:integer; #include<conio.h>
begin void main()
write('donner trois entiers differents:'); {
readln(x,y,z); int x,y,z,tmp;
writeln('x=',x,' et y=' ,y,’et z=’,z); printf("entrez trois nombres: ");
tmp:=x; scanf("%d %d %d",&x,&y,&z);
x:=y; printf("avant echange x=%d , y=%d et z=%d
y :=z ; \n",x,y,z);
z:=tmp; tmp=x;
writeln('x=',x,' et y=',y,’ et z=’,z); x=y;
readln; y=z ;
end. z=tmp;
printf("apres echange x=%d , y=%d et z=%d
",x,y,z);
getch();

ENS – Rabat – Département d’Informatique 66


Solutions des exercices

}
Exercice 4
Ecrire un programme qui demande à l'utilisateur les coordonnées de 2 points distincts du plan et qui affiche les
coordonnées du point milieu.

program milieu ; #include<conio.h>


var x1, y1, x2, y2, xm, ym : real ; void main()
begin {
writeln ('Entrez les coordonnées du premier float x1, y1, x2, y2, xm, ym ;
point') ; readln ( x1 ) ; readln ( y1 ); printf ("Entrez les coordonnées du premier point") ;
writeln ('Entrez les coordonnées du deuxième scanf("%f %f ",&x1,&y1) ;
point') ; readln ( x2 ) ; readln ( y2 ); printf ("Entrez les coordonnées du second point") ;
xm := (x1 + x2) / 2 ; ym := (y1 + y2) / 2 ; scanf("%f %f ",&x2,&y2) ;
writeln ('Les coordonnées du point milieu xm =(float) (x1 + x2) / 2 ; ym = (float)(y1 + y2) / 2 ;
sont :', xm :5:2, ym:5:2) ; printf("Les coordonnées du point milieu sont : (%5.2f,
end. %5.2f) ", xm, ym);
getch() ;
}
Exercice 5
Ecrire un programme qui demande à l'utilisateur une valeur pour U0, r et n et qui affiche la nième valeur de la
suite arithmétique définie par U0 et Un+1 = Un + r. (On rappelle la propriété : Un = U0 + n.r ).
program suite ; #include<conio.h>
var U0, Un, r : real ; n : integer ; void main()
begin {
writeln ('Entrez les valeurs de U0, r et n') ; float U0,Un,r ;
readln ( U0,r, n ); int n ;

ENS – Rabat – Département d’Informatique 67


Solutions des exercices

Un := U0 + n*r; printf("Entrez les valeurs de U0, r et n") ;


writeln ('La ',n:3,'ième valeur de la suite est :', scanf("%f %f %d",&Uo,&r,&n) ;
Un :5:2) ; Un = U0 + n*r;
end. printf ("La %d ième valeur de la suite est :%5.2f"', Un)
;
getch() ;
}
Exercice 6
Ecrire un programme qui échange les contenus de 2 données si elles sont de signes contraires.
program signe_contraire; #include<stdio.h>
var tmp,x,y:integer; #include<conio.h>
begin void main()
write('donner deux entiers differents:'); {
readln(x,y); clrscr();
writeln('x=',x,' et y=' ,y); int x,y,tmp;
if x*y <0 then printf("entrez deux nombres: ");
begin scanf("%d %d",&x,&y);
tmp:=x; printf("avant echange x=%d et y=%d\n",x,y);
x:=y; if(x*y<0){
y:=tmp; tmp=x;
writeln('les deux entiers sont de signes x=y;
contraires donc apres echange'); y=tmp;
writeln('x=',x,' et y=',y); printf("les 2 nombres sont de signes contraires
end donc apres echange x=%d et y=%d",x,y);
else }
writeln('les deux entiers sont de meme signes else

ENS – Rabat – Département d’Informatique 68


Solutions des exercices

donc pas d''echange'); printf("les 2 nombres sont de meme signes donc


readln; pas de changement");
end. getch();
}
Exercice 7
Ecrire un programme qui échange les contenus de 2 données si elle sont de signes contraires, sinon, il met leur
produit dans le premier et la somme dans le deuxième
program somme_produit; #include<stdio.h>
var tmp,x,y:integer; #include<conio.h>
begin void main()
write('donner deux entiers:'); {
readln(x,y); clrscr();
writeln('x=',x,' et y=' ,y); int x,y,tmp;
if x*y<0 then printf("entrez deux nombres: ");
begin scanf("%d %d",&x,&y);
tmp:=x; printf("avant echange x=%d et y=%d\n",x,y);
x:=y; if(x*y<0){
y:=tmp; tmp=x;
end x=y;
else y=tmp;
begin printf("les 2 nombres sont de signes contraires
tmp:=x; donc apres echange x=%d et y=%d",x,y);
x:=y*x; }
y:=y+tmp; else{
end; tmp=x;
writeln('apres operation'); x=x*y;

ENS – Rabat – Département d’Informatique 69


Solutions des exercices

writeln('x=',x,' et y=',y); y=y+tmp;


readln; printf("les 2 nombres sont de meme signes donc
end. leur produit est x=%d \net leur somme est y=%d",x,y);
}
getch();
}
Exercice 8
Ecrire un programme qui étant donnée un mois et son premier jour, affiche le premier jour du mois suivant
program premier_jour; #include<stdio.h>
var nbj,annee,mois,premj:integer; #include<conio.h>
begin void main()
write('entrer une annee de votre choix:'); {
readln(annee); clrscr();
write('entrer un mois et son premier jour:'); int biss,nbj,premj,M,A;
readln(mois,premj); printf("donnez une annee de votre
case mois of choix:");scanf("%d",&A);
1,3,5,7,8,10,12: nbj:=31; printf("donnez un mois et son premier
4,6,9,11: nbj:=30; jours:");scanf("%d %d",&M,&premj);
2: begin if (A % 100==0) A=A/100;
if annee mod 100 = 0 then annee:=annee div if (A % 4==0) biss=0;
100; else biss=1;
if annee mod 4 = 0 then nbj:=29 switch (M){
else nbj :=28; case 1 :
end; case 3 :
end; case 5 :
premj:=(premj+nbj) mod 7; case 7 :

ENS – Rabat – Département d’Informatique 70


Solutions des exercices

writeln('le premier jour du mois suivant case 8 :


est:',premj); case 10:
case 12: nbj=31;
readln; break;
end. case 4 :
case 6 :
case 9 :
case 11: nbj=30;
break;
case 2 :
if (bissextile(A)) nbj=28;
else nbj=29;
break;
}

premj=(premj+nbj)%7;
printf("\nle premier jour du mois suivant est:
%d",premj) ;
getch();
}
Exercice 9
Ecrire un programme qui calcule la somme des N premiers termes positifs
program somme; #include<stdio.h>
var N,i,s:integer; #include<conio.h>
begin void main()
write('entrer un nombre positif:'); {

ENS – Rabat – Département d’Informatique 71


Solutions des exercices

readln(N); clrscr();
s:=0; int N,i,S;
if N>0 then printf("donnez un entier positif:
for i:=1 to N do ");scanf("%d",&N);
s:=s+i; S=0;
writeln('la somme de N premiers termes if(N>0) {
positifs:',N);; for(i=1 ;i<=N;i++)
readln S=S+i;
end. }
printf("la somme des %d premiers termes
positifs est:%d ",N,S);

getch();
}
Exercice 10
Ecrire un programme qui calcule la somme des N premiers termes positifs impaires
program som_impaire; include<stdio.h>
var N,i,s:integer; #include<conio.h>
begin void main()
write('entrer un entier positif:'); {
readln(N); clrscr();
i:=1;s:=0; int N,i,S;
while(i<2*N) do printf("donnez un entier positif:
begin ");scanf("%d",&N);
s:=s+i; S=0;
i:=i+2; i=1;

ENS – Rabat – Département d’Informatique 72


Solutions des exercices

end; while(i<=2*N-1){
writeln('somme de ',N,' premiers termes positifs S=S+i;
impaires est: ',s); i=i+2;
readln; }
end. printf("la somme des %d premiers termes
positifs impaires est:%d ",N,S);
getch();}
Exercice 11
Ecrire un programme qui calcule la somme des N premiers termes positifs pairs nom multiple de 3
program som_paires; #include<stdio.h>
var N,i,s,cp:integer; #include<conio.h>
begin void main()
write('entrer un entier positif:'); {
readln(N); clrscr();
i:=0;s:=0;cp:=0; int N,i,S,cp;
while(cp<N) do printf("donnez un entier positif:
begin ");scanf("%d",&N);
i:=i+2; S=0;
if (i mod 3 <> 0) then i=0;
begin cp=0;
s:=s+i; while(cp<N){
cp:=cp+1; i=i+2;
end; if(i%3!=0){
end; S=S+i;
writeln('somme de ',N,' premiers termes positifs cp=cp+1;
non multiples de 3 est: ',s); }

ENS – Rabat – Département d’Informatique 73


Solutions des exercices

readln; }
end. printf("la somme des %d premiers termes
positifs impaires non multiple de 3 est:%d ",N,S);
getch();
}
Exercice 12
Ecrire un programme qui calcule la somme 1/2 + 1/4 + 1/8 +…+1/2n (n Є N*)
program calcul; #include<stdio.h>
var n,i:integer; #include<conio.h>
s,u:real; #include<math.h>
begin #include<stdlib.h>
s:=0; void main()
u:=1/2; {
i:=1; clrscr();
write('donner un entier non nul: ');readln(n); float s,u;
while i<=n do int i,n;
begin s=0;
s:=s+u; u=(float)1/2;
u:=u/2; i=1;
i:=i+1; printf("donnez un entier positif non
end; nul:");scanf("%d",&n);
writeln('la somme est: ',s:10:5); while(i<=n){
readln; s=s+u;
end. u=u/2;
i=i+1;
}

ENS – Rabat – Département d’Informatique 74


Solutions des exercices

printf("la somme est: %f",s);


getch();
}
Exercice 13
Ecrire un programme qui calcule la somme 1+1/2-1/4+ 1/8-1/16+…±1/2n (n Є N*)
program calcul; #include<stdio.h>
var n,i:integer; #include<conio.h>
s,u:real; void main()
begin {
write('donner un entier non nul: ');readln(n); clrscr();
i:=1; float s,u;
S:=1; int i,n;
u:=1/2; s=1;
while i<=n do u=(float)1/2;
begin i=1;
if i mod 2=0 then printf("donnez un entier positif non
s:=s-u nul:");scanf("%d",&n);
else s:=s+u; while(i<=n){
u:=u/2; if(i%2==0) s=s-u;
i:=i+1; else s=s+u;
u=u/2;
end; i=i+1;
writeln('la somme est: ',s:10:5); }
readln; printf("la somme est: %f",s);
end. getch();
}

ENS – Rabat – Département d’Informatique 75


Solutions des exercices

Exercice 14
Ecrire un programme qui donne le nombre N tel que la série 1+1/2-1/3+1/4- 1/5+…±1/N donne un résultat égal
(à 1/100 près) à 1,33
program calcul; #include<stdio.h>
var S:real; #include<conio.h>
i:longint; #include<math.h>
begin void main()
S:=1; {
i:=1; clrscr();
while abs(S - 1.33) > 0.001 do float s,n;
begin long int i;
if (i mod 2=0) then S:=S-(1/(i+1)) s=1;
else S:=S+(1/(i+1)); i=1;
i:=i+1; while( fabs(s-1.33)>0.001)
end; {
write('le nombre tel que la serie donne un resultat = n=(float)1/(i+1);
1,33 est:',s:10:5) ; if (i%2==0) s=s-n;
readln; else s=s+n;
end. i=i+1;
}
printf("la valeur approche de 1,33 est : %f",s);
getch();
}
Exercice 15
Ecrire un programme qui donne la plus grande valeur inférieure à 1000 de la somme 1+2+4+8+…+2N
program calcul; #include<stdio.h>

ENS – Rabat – Département d’Informatique 76


Solutions des exercices

var u,s:integer; #include<conio.h>


begin void main()
u:=2; {
s:=1; clrscr();
while s<1000 do int s,u;
begin s=1;
s:=s+u; u=2;
u:=u*2; while(s<1000){
end; s=s+u;
s:=s-(u div 2); u=2*u;
writeln('la plus grande valeur inferieur a 1000 de la }
somme est: ',s); s=s-u/2;
readln; printf("la plus grande valeur inferieur a 1000 est:
end. %d",s);
getch();
}
Exercice 16
Ecrire un programme qui calcule la somme 1+x+x2+…+xn (x réel et n entier).
program calcul; #include<stdio.h>
var x,s,u:real; #include<conio.h>
n,i:integer; #include<math.h>
begin void main()
write('donner un reel et un entier:'); {
readln(x,n); clrscr();
i:=1; float s,x,u;
s:=1; int n,i;

ENS – Rabat – Département d’Informatique 77


Solutions des exercices

u:=x; printf("donnez un reel et un entier :");


while i<=n do scanf("%f %d",&x,&n);
begin s=1;
s:=s+u; u=x;
u:=u*x; for(i=1;i<=n;i++){
i:=i+1; s=s+u;
end; u=u*x;
writeln('la somme est: ',s:10:5); }
readln; printf("la Somme est:%f",s);
end. getch();
}
Exercice 17
Calcul approché de x
Soient les deux suites: An+1= (An+Gn)/2 et Gn+1=2AnGn/(An+Gn) avec A0=x et G0=1, on montre que lim An=lim
Gn= x
n∞ n∞
Ecrire un programme qui donne la valeur de x avec une précision relative Є=10-6, c’est à dire |An-Gn|/|Gn|<Є

program racine_carre; #include<stdio.h>


var x,A,G,B:real; #include<conio.h>
begin #include<math.h>
write('donner un nombre non nul: '); void main()
readln(x); {
A:=x; clrscr();
G:=1; float x,A,B,G;
while abs((A-G)/G)>0.000001 do printf("donner un nombre non nul:");

ENS – Rabat – Département d’Informatique 78


Solutions des exercices

begin scanf("%f",&x);
B:=A; A=x;
A:=(A+G)/2; G=1;
G:=2*B*G/(B+G); while(fabs((A-G)/G)>0.000001)
end; {
writeln('la racine de ',x:10:5,' est: ',A:10:5); B=A;
readln; A=(A+G)/2;
end. G=2*B*G/(B+G);
}
printf("la racine de %f est : %f",x,A);
getch();
}
Exercice 18
Sachant que la somme 1-1/3+1/5-1/7+1/9... tend vers ∏/4. écrire un programme donnant le nombre ∏ à 10-6 près
program pi; #include<stdio.h>
var s,t:real; #include<conio.h>
i:integer; void main()
begin {
s:=4; clrscr();
i:=1; float s,t;
t:=1/3; int i;
while t>0.000001 do s=4;
begin t=(float)1/3;
t:=4/(2*i+1); i=1;
if i mod 2=0 then while(t>0.000001){
s:=s+t t=(float)4/(2*i+1);

ENS – Rabat – Département d’Informatique 79


Solutions des exercices

else s:=s-t; if (i%2==0) s=s+t;


i:=i+1; else s=s-t;
end; i=i+1;
writeln('pi =',s:10:5); }
readln; printf("la valeur de pi est:%f",s);
end. getch();
}
Exercice 19
Le développement limité de la fonction sinus au voisinage de zéro est : sin x= x - x3/3! + x5/5! -…+(-1)p x2p+1/
(2p+1)!+…
Ecrire un programme qui calcule sin x à 10-6 près.
program sinx; #include<stdio.h>
var s,x,u,t:real; #include<conio.h>
v,i:integer; void main()
begin {
write('donner un nombre:');readln(x); clrscr();
s:=0; float s,u,x,v,t;
u:=x; int i,n;
v:=1; printf("donner un nombre:");scanf("%f",&x);
i:=1; s=0;
t:=u/v; u=x;
while t>0.000001 do v=1;
begin i=1;
if i mod 2=0 then s:=s-(u/v) t=(float)u/v;
else s:=s+(u/v); while (t>0.000001 ){
u:=u*x*x; if (i%2==0) s=s+u/v;

ENS – Rabat – Département d’Informatique 80


Solutions des exercices

v:=(2*i+1)*2*i*v; else s=s-u/v;


i:=i+1; u=u*x*x;
t:=u/v; v=(2*i+1)*2*i*v;
end; i++;
writeln('le sinus de ',x:10:5,'est: ',s:10:5); t=(float)u/v;
readln; }
end. printf("sinus de %f=%f",x,s);
getch();
}

Exercice 20
Ecrire un programme qui calcule la somme, le produit et la différence de deux données numériques.
program operation; #include <stdio.h>
var x,y:integer; #include<conio.h>
op:char; void main()
begin {
writeln('donner deux nombres x et y'); int x,y;
readln(x,y); char op;
writeln('donner un op‚rateur'); printf("donner le premier operande\n");
readln(op); scanf("%d",&x);
case(op) of printf("donner le deusieme operande\n");
'/': begin scanf("%d",&y);
if y<>0 then writeln('la division de x par y est ‚gale printf("donner l'operateur\n");
…:',x/y) op=getch();
else writeln(' division par z‚ro'); switch(op)
end; {

ENS – Rabat – Département d’Informatique 81


Solutions des exercices

'*':writeln('x*y=',x*y); case '+': printf("x+y=%d\n",x+y); break;


'+':writeln('x+y=',x+y); case '-': printf("x-y=%d\n",x-y); break;
'-':writeln('x-y=',x-y); case '*': printf("x*y=%d\n",x*y); break;
end; case '/': if( y!=0) printf("x/y=%f\n",x/y);
readln; else printf(" division par zero\n"); break;
end. }
getch();
}

Exercice 21
écrire un programme qui retourne le code d’une donnée de type CARACTERE.
program code_ASCII; #include <stdio.h>
var c:char; #include<conio.h>
asci:integer; void main()
begin {
writeln('donner un caractère:'); int asci;
readln(c); char c;
asci:=ord(c); printf("donner un caractere\n");
writeln('le code ASCII de ce caractère est:',asci); scanf("%c",&c);
readln; asci='A';
end. printf("%d\n",asci);

getch();
}
Exercice 22
Ecrire un programme qui calcule le salaire net d’un employé, sachant que celui-ci a assuré un certain nombres

ENS – Rabat – Département d’Informatique 82


Solutions des exercices

d’heures de travail à un prix fixe par heure, et que l’employeur doit réduire de son salaire des charges qui sont
calculées avec un coefficient donné.
program salaire_net_employe; #include <stdio.h>
var charges,sb,sn,coef,ph:real; #include<conio.h>
nh:integer; void main()
begin {
writeln('donner le nombre d''heures de travail de cet int NH;
employ‚:'); float NB,SN,SB,coef,PH,charges;
readln(nh);
writeln('donner le prix d''une heure:'); printf("donner le nombre d'heures de travail:\n");
readln(ph); scanf("%d",&NH);
writeln('donner le coefficient:'); printf("donner le prix de chaque heure:\n");
readln(coef); scanf("%f",&PH);
sb:=nh*ph; printf("donner le coefficient de reduction:\n");
charges:=sb*coef; scanf("%f",&coef);
sn:=sb-charges; SB=NH*PH;
writeln('le salaire net de cet employ‚ est:',sn); charges=SB*coef;
readln; SN=SB-charges;
end. printf("la salaire net de cet employe est egal a %f",SN);
getch();
}
Exercice 23
Ecrire un programme qui permet de reprendre l’exercice précédant en considérant que l’employé a assuré des
heures normales, des heures à 25% et des heures à 50%.
program salaire_net_supplements; include<stdio.h>
var charges,sb,sn,coef,ph:real; #include<conio.h>

ENS – Rabat – Département d’Informatique 83


Solutions des exercices

nh25,nh50,nhn:integer; void main()


begin {
writeln('donner le nombre d''heures … 25% et celui … int NHN,NH25,NH50;
50% ainsi que le nombre d''heure normales :'); float NB,SN,SB,coef,PH,charges;
readln(nh25,nh50,nhn);
writeln('donner le prix d''une heure:'); printf("donner le nombre d'heures normales:\n");
readln(ph); scanf("%d",&NHN);
writeln('donner le coefficient:'); printf("donner le nombre d'heures a 25%:\n");
readln(coef); scanf("%d",&NH25);
sb:=nhn*ph+nh25*ph*125/100+nh50*150/100*ph; printf("donner le nombre d'heures a 50%:\n");
charges:=sb*coef; scanf("%d",&NH50);
sn:=sb-charges; printf("donner le prix d'une heure:\n");
writeln('le salaire net de cet employ‚ est:',sn); scanf("%f",&PH);
readln; printf("donner le coefficient de reduction:\n");
end. scanf("%f",&coef);
SB=(NHN+NH25*(125/100)+NH50+(150/100))*PH;
charges=SB*coef;
SN=SB-charges;
printf("la salaire net de cet employe est egal a %f",SN);
getch();
}
Exercice 24
Ecrire un programme qui retourne si une donnée numérique est paire ou impaire (utiliser le reste de la division
par 2).
program est_pair; #include<stdio.h>
var n:integer; #include<conio.h>

ENS – Rabat – Département d’Informatique 84


Solutions des exercices

bp:boolean; void main()


begin {
writeln('donner un entier positif:'); int n;
readln(n); printf("donner un entier positif :\n");
bp:=(n mod 2)=0; scanf("%d",&n);
if bp then writeln('cet entier est pair') if( n % 2 == 0)
else writeln('cet entier n''est pas pair'); printf("cet entier est pair.\n");
readln; else
end. printf("cet entier n'est pas pair.\n");
getch();
}
Exercice 25
Ecrire un programme qui permet de lire trois données numériques et retourne si la troisième donnée est la
somme des deux autres ou pas.
program est_somme; #include<stdio.h>
var x,y,z:integer; #include<conio.h>
bs:boolean; void main()
begin {int x,y,z;
writeln('donner trois nombres:'); printf("donner trois nombres:\n");
readln(x,y,z); scanf("%d%d%d",&x,&y,&z);
bs:=(x+y)=z; if(z==x+y)
if bs then writeln('la trosième donnée est égale à la printf("la trosieme donnée est egale a la somme des
somme des autres ') autres.\n");
else else printf("la trosieme donnée n'est pas egalea la
writeln('la trosième donnée n'' est pas égale à la somme des autres.\n");
somme des autres '); getch();

ENS – Rabat – Département d’Informatique 85


Solutions des exercices

readln; }
end.
Exercice 26
Ecrire un programme qui, à partir du salaire brut d’un employé, détermine l’impôt à payer sachant que les règles
de calcul des impôts sont comme suit :

salaire brut(SB) l’impôt à payer


SB<1500 0%
1500<=SB<3000 10% du SB
3000<=SB<5000 450+30%(SB-3000)
SB>=5000 750+40%(SB-
5000)
program impots; #include<stdio.h>
var sb,impot:real; #include<conio.h>
begin void main()
writeln('donner le salaire brut de cet employé:'); {float sb;
readln(sb); printf("donner le salaire brut de cet employe:\n");
if sb<1500 then writeln('l''impot à payer est de 0%') scanf("%f",&sb);
else if (sb<1500)
begin printf("l'impot a payer est de 0%.\n");
if sb<3000 then writeln('l''impot à payer est else
de:',sb*0,1) { if (sb<3000) printf("l'impot a payer est de:
else %f\n",sb*0.1);
begin else
if sb<5000 then writeln('l''impot à payer est {
de:',450+30/100*(sb-3000)) if (sb<5000) printf("l'impot a payer est de:

ENS – Rabat – Département d’Informatique 86


Solutions des exercices

else %f\n",450+0.3*(sb-3000));
writeln('l''impot à payer est de:',750+40/100*(sb- else printf("l'impot a payer est de:
5000)); %f\n",750+0.4*(sb-5000));
end; }
end; }
readln getch();
end. }
Exercice 27
Ecrire un programme qui fournit les racines de l’équation Ax2+Bx+C=0.
program eqation ; #include<stdio.h>
var a,b,c:integer; #include<conio.h>
delta:real; #include<math.h>
begin void main()
writeln('donner a, b et c'); { int a,b,c;
readln(a,b,c); float delta;
if a=0 then printf("donner a, b et c:\n");
begin scanf("%d%d%d",&a,&b,&c);
if b=0 then begin if (a==0)
if c=0 then writeln('S=R') { if(b=0)
else writeln('S=VIDE'); { if (c=0) printf("S=R");
end else printf("S=VIDE");
else writeln('la solution est:',-c/b); }
end else printf("la solution est:%f",-c/b);
else begin }
delta:=b*b-4*a*c; else
if delta>=0 then writeln('les racines de cette {

ENS – Rabat – Département d’Informatique 87


Solutions des exercices

équation sont: x1=',(-b-sqrt(delta))/(2*a),'x2=', (- delta=b*b-4*a*c;


b+sqrt(delta))/(2*a)) if (delta>=0)
else writeln('pas de solution'); printf("les racines de cette équation sont: x1=%f et x2=
end; %f",(-b-sqrt(delta))/(2*a),(-b+sqrt(delta))/(2*a));
readln; else printf("pas de solution");
end. getch();
}
}
Exercice 28
Ecrire un programme qui, étant donnée une date (jour, mois, année), affiche la date du jour suivant.
program jour_suivant; #include<stdio.h>
var j,m,a,ms,js,as:integer; #include<conio.h>
biss,dj:boolean; void main()
begin {
writeln('donner la date d''aujourd''hui:'); clrscr();
readln(j,m,a); int j,m,a,js,ms,as,dj,biss;
if( a mod 100)=0 then biss:=(a mod 400)=0 printf("donnez la date d'aujourd'hui: ");scanf("%d %d
else biss:=(a mod 4)=0; %d",&j,&m,&a);
case m of if (a % 100==0) a=a/100;
1,3,7,8,10,12:dj:=(j=31); if (a % 4==0) biss=0;
4,6,9,11:dj:=(j=30); else biss=1;
2:if biss then dj:=(j=29) switch (m){
else dj:=(j=28); case 1 :
end; case 3 :
if dj then begin case 5 :
js:=1; case 7 :

ENS – Rabat – Département d’Informatique 88


Solutions des exercices

if m=12 then begin case 8 :


ms:=1; case 10:
as:=a+1; case 12: dj=(j==31);
end break;
else begin case 4 :
ms:=m+1; case 6 :
as:=a; case 9 :
end; case 11: dj=(j==30);
end break;
else begin case 2 :
js:=j+1; if(biss) dj=(j==28);
ms:=m; else dj=(j==29);
as:=a; break;
end; }
writeln('le jour suivant est :',js,'/',ms,'/',as); if (dj) {
readln; js=1;
end. if(m==12){
ms=1;
as=a+1;
}
else{
ms=m+1;
as=a;
}
}
else{

ENS – Rabat – Département d’Informatique 89


Solutions des exercices

js=j+1;
ms=m;
as=a;
}
printf("\nle jour suivant est:%d/%d/
%d",js,ms,as) ;
getch();
}
Exercice 29
Ecrire un programme qui, étant donnée une date (jour, mois, année), affiche la date du jour précédant.
program jour_precedant; #include<stdio.h>
var nj,j,m,a,mp,jp,ap:integer; #include<conio.h>
biss:boolean; void main()
begin { int nj,j,m,a,mp,jp,biss,a,p;
writeln('donner la date d''aujourd''hui:'); printf("donner la date d'aujourd'hui:\n");
readln(j,m,a); scanf("%d%d%d",j,m,a);
if( a mod 100)=0 then biss:=(a mod 400)=0 if(( a % 100)==0))
else biss:=(a mod 4)=0; biss=(a % 400)==0;
if m=1 then m:=13; else biss=(a % 4)==0;
case m-1 of if m==1 m=13;
1,3,7,8,10,12:nj:=31; switch(m-1)
4,6,9,11:nj:=30; { case 1:
2:if biss then nj:=29 case 3:
else nj:=28; case 5:
end; case 7:
if j=1 then begin case 8:

ENS – Rabat – Département d’Informatique 90


Solutions des exercices

if m=1 then begin case 10:


ap:=a-1; case 12: nj=31;
jp:=nj; case 4:
mp:=12; case 6:
case 9:
end case 11:nj=30;
else begin case 2: if (biss) nj=29;
mp:=m-1; else nb=28;
ap:=a; }
jp:=nj; if (j==1)
end; { if (m==1)
end { ap=a-1;
else begin jp=nj;
jp:=j-1; mp=12;
mp:=m; }
ap:=a; else
end; { mp=m-1;
writeln('le jour précédant est :',jp,'/',mp,'/',ap); ap=a;
readln; jp=nj;
end. }
else
{ jp=j-1;
mp=m;
ap=a;
}
printf("le jour precedant est :%d/%d/%d",jp,mp,ap);

ENS – Rabat – Département d’Informatique 91


Solutions des exercices

getch();
}
}
Exercice 30
Ecrire un programme qui calcule la somme 5+6+7+….+N (N>=5).
Program Somme_entiers; #include<stdio.h>
var N,i,S:integer; #include<conio.h>
begin void main()
writeln('donner un entier >=5:'); { int N,i,S;
readln(N); printf("donner un entier >=5:\n");
S:=0;i:=5; scanf("%d",&N);
while i<=N do S=0;
begin i=4;
S:=S+i; while(i<N)
i:=i+1; { i=i+1;
end; S=S+i;
writeln('la somme est égale à’,S); }
readln; printf("la somme est egale a :%d" ,S);
end. getch();
}
Exercice 31
Ecrire un programme qui calcule le produit des N (N>0) premiers entiers positifs.
program Produit_Entiers; #include<stdio.h>
var P,i,N:integer; #include<conio.h>
begin void main()
writeln('donner un entier >0:'); {

ENS – Rabat – Département d’Informatique 92


Solutions des exercices

readln(N); int p,i,n;


if N<=0 then writeln('il faut donner un entier > 0!') printf("Donner un entier >0:");
else scanf("%d",&n);
P:=1; if(n<=0) printf("Il faut donner un entier >0!!");
for i:=1 to N do else{
P:=P*i; p=1;
writeln('le produit des N premiers entiers est :',P); for(i=1;i<=n;i++) p=p*i;
end. printf("le produit des %d premiers entiers
est:%d",n,p);
}
getch();
}
Exercice 32
Ecrire un programme qui calcule la somme 1+1/2+1/4+1/6+…1/2N (N>0).
program Serie_Fraction; #include<stdio.h>
var i,N:integer; #include<conio.h>
S:real; void main()
begin {
writeln('donner un entier N>0'); int i,n;
readln(N); float s;
S:=1; printf("Donner un entier >0:");
i:=1; scanf("%d",&n);
repeat s=1;i=1;
begin do{
S:=S+(1/(2*i)); s=s+(float)1/(2*i);
i:=i+1; i=i+1;

ENS – Rabat – Département d’Informatique 93


Solutions des exercices

end; }while(i<=n);
until i=N+1; printf("la somme est: %f",s);
writeln('S=,'S); getch();
readln; }
end.
Exercice 33
Ecrire un programme qui échange les contenus de trois données numériques si leur somme est paire, sinon il met
la somme des trois dans la première donnée, leur produit dans la seconde et la valeur zéro dans la troisième.
program echange_cond_trois; void main()
uses crt; {
var s,tmp,x,y,z:integer; clrscr();
begin int x,y,z,tmp,s;
clrscr; printf("Donnez trois entiers:");
writeln('donner trois entiers:'); scanf("%d %d %d",&x,&y,&z);
readln(x,y,z); s=x+y+z;
s:=x+y+z; if(s%2==0){
if(s mod 2)=0 then begin tmp=x;
tmp:=x; x=y;
x:=y; y=z;
y:=z; z=tmp;
z:=tmp; printf("x=%d,y=%d,z=%d",x,y,z);
writeln('x=',x,' ','y=',y,' ','z=',z); }
end else{
tmp=x;
else begin x=x+y+z;
tmp:=x; y=y*tmp*z;

ENS – Rabat – Département d’Informatique 94


Solutions des exercices

x:=x+y+z; z=0;
y:=y*tmp*z; printf("x=%d,y=%d,z=%d",x,y,z);
z:=0; }
writeln('x=',x,' ','y=',y,' ','z=',z); getch();
end; }
readln;
end.
Exercice 34
Ecrire un programme qui calcule la somme :1-1/2+1/3-1/4+…+/-1/N
program Serie_Alternative; include<stdio.h>
var i,N:integer; #include<conio.h>
S:real; void main()
b:boolean; {
begin int i,n,b;
writeln('donner un entier >0'); float s;
readln(N); printf("Donner un entier >0:");
S:=1; scanf("%d",&n);
for i:=2 to N do s=1;
begin for(i=2;i<=n;i++){
b:=(i mod 2)=0; b=(i%2==0);
if b then S:=S-1/i if(b) s=s-(float)1/i;
else S:=S+1/i; else s=s+(float)1/i;
end; }
writeln('S=',S); printf("la somme est: %f",s);
readln;
end. getch(); }

ENS – Rabat – Département d’Informatique 95


Solutions des exercices

Les fonctions
Exercice 35
Ecrire une fonction paramétrée qui retourne si un nombre donné est premier ou non.
function est_premier(N:integer):boolean; #include<stdio.h>
var i,nb:integer; #include<math.h>
begin int premier(int N)
nb:=0; {
for i:=1 to N do int i=2;
if N mod i =o then nb:=nb+1; int termine=0;
est_premier:=(nb=2); while(i<=sqrt(N)&&(!termine)){
end; termine=(N%i==0);
i=i+1;
}
return(!termine);
}
Exercice 36
Ecrire une fonction paramétrée qui rend si un nombre donné est parfait ou non.
function est_parfait(N:integer):boolean; #include<stdio.h>
var S,i:integer; int parfait(int A)
begin {
S:=0; int s=0;
for i:=1 to N-1 do for(int i=1;i<A;i++)
if N mod i = 0 then S:=S+i if(A%i==0) s+=i;
est_parfait:=(N=S); return(A==s);
end; }
Exercice 37

ENS – Rabat – Département d’Informatique 96


Solutions des exercices

Ecrire une fonction paramétré qui rend si deux nombres données sont amis ou non.
function Amis(N:integer;M:integer):boolean; #include<stdio.h>
var S,R,i,j:integer; int amis(int N,int M)
begin {
S:=0;R:=0; int s,r,i,j;
for i:=1 to N-1 do r=0;
if N mod i = 0 then S:=S+i; s=0;
for j:=1 toM-1 do for(i=1;i<N;i++)
if M mod j = 0 then R:=R+j; if(N%i==0) s+=i;
Amis:=((M=S) and (N=R)); for(j=1;j<M;j++)
end; if(M%j==0) r+=j;
return((M==s)&&(N==r));
}
Exercice 38
Ecrire une fonction paramétrée qui retourne l’inverse d’un nombre entier donné

function inverse(n:longint):longint; #include<stdio.h>


var r,inv:longint; #include<conio.h>
begin long inverse(long n)
inv:=0; {
while n mod 10 =0 do n:=n div 10; long r,inv;
while n mod 10 <>0 do inv=0;
begin while(n%10==0) n=n/10;
r:=n mod 10; while(n%10!=0){
inv:=(inv*10)+r; r=n%10;
n:=n div 10; inv=(inv*10)+r;

ENS – Rabat – Département d’Informatique 97


Solutions des exercices

end; n=n/10;
inverse:=inv; }
end; return(inv);
}

Exercice 39
Ecrire une fonction récursive permettant de calculer le PGDC de deux nombres entiers positifs A et B.
function pgdc(a,b:integer):integer; #include<stdio.h>
begin int pgdc(int A,int B)
if a>b then pgdc:=pgdc(a-b,b) {
else if a<b then pgdc:=pgdc(a,b-a) if(A>B) return(pgdc(A-B,B));
else pgdc:=a; else if(A<B) return(pgdc(A,B-A));
end; else return A;
}
Exercice 40
Ecrire une fonction récursive permettant de calculer le PPMC de deux nombres entiers positifs A et B.
function calcul_ppmc(A:integer,B:integer):integer; #include<stdio.h>
var multiple,k:integer; int ppmc(int A,int B)
begin {
if A<B then ppmc:=ppmc(B,A) int multiple,k;
else if(A<B) return(ppmc(B,A));
begin else{
multiple:=A; multiple=A;
k:=2; k=2;
end while(multiple%B!=0){
while multiple mod B<> 0 do multiple=A*k;

ENS – Rabat – Département d’Informatique 98


Solutions des exercices

begin k++;
multiple:= A*k; }
k:=k+1; return(multiple);
end; }
}
ppmc:=multiple;
end;
end;
Exercice 41
Ecrire une fonction récursive qui permet de calculer le factoriel d’un nombre donné.
function Factoriel(N:integer):integer; include<stdio.h>
begin long fact(int n)
if N=0 then factoriel:=1 {
else if(n>1) return(fact(n-1)*n);
factoriel:= N*factoriel(N-1); else return 1;
end; }

Exercice 42
Ecrire une fonction récursive qui permet de calculer la puissance d’un entier donné.
function puissance(N:integer,k:integer):longint; #include<stdio.h>
begin long puiss(int n,int k)
if k=0 then puissance:=1 {
else if(k==0) return 1;
puissance:=N*puissance(N,k-1); else return (puiss(n,k-1)*n);
end; }

ENS – Rabat – Département d’Informatique 99


Solutions des exercices

Exercice 43
Ecrire une fonction récursive qui calcule la valeur de la fonction d’Ackermann « A » définie pour m>0 et n>0
par :

A(m, n)=A((m-1),A(m,n-1)) pour n>0, m>0 ;


A(0,n)=n+1 pour n>0;
A(m,0)=A(m-1,1) pour m>0 ;
function acker(n,m:integer):integer; #include<stdio.h>
begin #include<conio.h>
if (m<0) or (n<0) then acker:=0 int acker(int n,int m)
else if n=0 then acker:=m+1 {
else if m=0 then acker:= acker(n-1,1) if((m<0)||(n<0)) return 0;
else acker:=acker(n-1,acker(n,m-1)) else if(n==0) return (m+1);
end; else if(m==0) return(acker(n-1,1));
else return(acker(n-1,acker(n,m-1)));
}
Exercice 44
Ecrire une fonction qui fournit le nombre de chiffres d’un entier donné.
function NCHIFFRES (N:longint):integer; int NCHIFFRES(long N)
var I:integer; {
begin int I;
If N<0 then N:=N*(-1); if (N<0)
I:=1; N *= -1;
while N>10 do for (I=1; N>10; I++)
begin N /= 10;
N:=N div 10; return I;

ENS – Rabat – Département d’Informatique 100


Solutions des exercices

I:=I+1; }
end;
NCHIFFRES:=I;
End;
Les procédures
Exercice 45
Ecrire une procédure qui permet de dessiner la lettre X, à l'aide d'espaces et d'une "lettre" fournie par
l'utilisateur, auquel on demande aussi la "hauteur" du dessin qu'il désire obtenir. Avec les réponses : a et 5, elle
donnera :
a a
a a
a
a a
a a
procedure DessX(hauteur:integer;lettre:char); void DessX(int hauteur,char lettre)
{ int no_ligne,i;
var no_ligne,i:integer; for(no_ligne=1;no_ligne<((hauteur+1)/2);no_ligne++)
begin {
for no_ligne:=1 to ((hauteur+1) div 2)-1 do for (i=1;i<no_ligne;i++)
begin printf("%c",' ');
for i:=1 to no_ligne-1 do printf("%c",lettre);
write(' '); for(i=0;i<hauteur-2*no_ligne;i++)
write(lettre); printf("%c",' ');
for i:=0 to (hauteur-2*no_ligne)-1 do printf("%c",lettre);
write(' '); printf("\n");
write(lettre); }

ENS – Rabat – Département d’Informatique 101


Solutions des exercices

writeln; for(i=1;i<(hauteur+1)/2;i++)
end; printf("%c",' ');
for i:=1 to ((hauteur+1) div 2)-1 do printf("%c",lettre);
write(' '); printf("\n");
write(lettre); for(no_ligne=1;no_ligne<((hauteur+1)/2);no_ligne++)
writeln; {
for no_ligne:=1 to ((hauteur+1) div 2)-1 do for (i=0;i<(hauteur-2*no_ligne-1)/2;i++)
begin printf("%c",' ');
for i:=0 to ((hauteur-2*no_ligne-1) div 2)-1 do printf("%c",lettre);
write(' '); for(i=0;i<2*no_ligne-1;i++)
write(lettre); printf("%c",' ');
for i:=0 to (2*no_ligne-1)-1 do printf("%c",lettre);
write(' '); printf("\n");
write(lettre); }
writeln; }
end;
end;
Exercice 46
Soit un programme qui visualise un menu composé de trois rubriques : Hors d’œuvre, plat chaud et dessert.
Ecrire une procédure qui permet d’effectuer, à chaque fois, un choix exclusif.
program menu; #include<stdio.h>
uses crt; #include<conio.h>
procedure Plat(choix1,choix2,choix3:string); void plat(char choix1[10],char choix2[10],char
var choix:char; choix3[10])
begin {
choix:=readkey; char choix;

ENS – Rabat – Département d’Informatique 102


Solutions des exercices

writeln; choix=getch();
write('-',choix,'-'); printf("-%c-",choix);
if choix=choix1[1] then writeln(choix1) if(choix==choix1[0]) printf("%s",choix1);
else if choix=choix2[1] then writeln(choix2) if(choix==choix2[0]) printf("%s",choix2);
else if choix=choix3[1] then writeln(choix3); if(choix==choix3[0]) printf("%s",choix3);
end; }
begin
clrscr;
plat('soupe','crudit','oeuf Dur');
plat('steak','poulet','hamburger');
plat('gateau','poire','fromage');
readln;
end.
Exercice 47
Ecrire une procedure paramétrée, qui permet l’échange des contenus de deux paramètres formels par valeur A et
B. Appeler cette procédure dans un programme principal.On écrira les résultats dans le corps de la procédure, et
dans le programme principal.
program exchange; include<stdio.h>
var A:real; #include<conio.h>
B: real; void echange(float x,float y)
procedure echange(x,y:real); {
var temp:real; float temp;
begin printf("Echange:%10.2f %10.2f",x,y);
writeln('Ecange:',x:10:2,y:10:2); temp=x;
temp:=x; x=y;
x:=y; y=temp;

ENS – Rabat – Département d’Informatique 103


Solutions des exercices

y:=temp; printf("\nEchange:%10.2f %10.2f",x,y);


writeln('Echange:',x:10:2,y:10:2); }
end; void main()
begin {
readln(A,B); clrscr();
echange(A,B); float A,B;
writeln('Echange:',x:10:2,y:10:2); scanf("%f %f",&A,&B);
readln; echange(A,B);
end. printf("\nEchange:%10.2f %10.2f",A,B);
getch();
}
Exercice 48
Ecrire une procedure paramétrée, qui permet l’échange des contenus de deux paramètres formels par adresse A
et B. Appeler cette procédure dans un programme principal.On écrira les résultats dans le corps de la procédure,
et dans le programme principal.
program exchange; #include<stdio.h>
var A:real; #include<conio.h>
B:real; void echange(float&x,float&y)
procedure echange(var x,y:real); {
var temp:real; float temp;
begin printf("Echange:%10.2f %10.2f",x,y);
writeln('Ecange:',x:10:2,y:10:2); temp=x;
temp:=x; x=y;
x:=y; y=temp;
y:=temp; printf("\nEchange:%10.2f %10.2f",x,y);
writeln('Echange:',x:10:2,y:10:2); }

ENS – Rabat – Département d’Informatique 104


Solutions des exercices

end; void main()


begin {
readln(A,B); clrscr();
echange(A,B); float A,B;
writeln('Echange:',x:10:2,y:10:2); scanf("%f %f",&A,&B);
readln; echange(A,B);
end. printf("\nEchange:%10.2f %10.2f",A,B);
getch();
}
Exercice 49
Ecrire une procédure qui affiche tous les nombres premiers qui sont compris entre 1 et 200.
procedure Nombres_premiers; Void Nombres_premiers (void)
var i,j,nb:integer; {
begin int i,j,nb ;
for j:=1 to 200 do for(j=1; i<=200;i++)
begin {
nb:=0; for(nb=0,i=1;i<=j/2;i++)
for i:=1 to (j div 2) do if (!(j %i) nb++;
if( j mod i =0) then nb:=nb+1; if( nb==1 ) printf(“%d\n”,j);
if nb=1 then writeln(j); }
end; }
end;
Exercice 50
Ecrire une procédure qui affiche tous les nombres parfaits qui sont compris entre 1 et 200.
procedure Nombres_parfaits; Void Nombres_parfaits()
var i,j,nb,S:integer; { int i,j,S ;

ENS – Rabat – Département d’Informatique 105


Solutions des exercices

begin for(j=1;j<=200;j++)
for j:=1 to 200 do {
begin for (S=0,i=1;i<=j-1;i++)
S:=0; {
for i:=1 to j-1 do if (!(j%i)) s+=i;
if (s==j ) printf(“%d\n”,j);
if( j mod i =0) then S:=S+I; }
if S=j then writeln(j); }
end;
end;
Exercice 51
Ecrire une procédure qui permet d’afficher tous les diviseurs d’un entier N ainsi que leur nombre.
procedure Diviseurs(N :integer) ; void Diviseurs(int N)
var i,nb:integer; { int nb=0 ;
begin printf(“les diviseurs de % sont \n”,N);
nb:=0; for( int i=1 ;i<=N ;i++)
writeln(‘Les diviseurs de ‘,N,’sont :’) ; if (!(N%i )){
for i:=1 to N do printf(‘’ %d\n”,i);
if N mod i =0 then nb+=1;}
begin printf(“le nombre de diviseurs de %d est%d”,N,nb);
writeln(i); }
nb:=nb+1;
end;
writeln(‘Le nombre de diviseurs de ‘,N,’est :’,nb);
end ;
Exercice 52

ENS – Rabat – Département d’Informatique 106


Solutions des exercices

Affichez un triangle isocèle formé d'étoiles de N lignes (N est fourni au clavier):


Nombre de lignes : 8
*
***
*****
*******
*********
***********
*************
***************
procedure DessinerTri(L:integer); void DessinerTri(int L)
var { int i; /* compteur des lignes */
k:integer; {compteur des lignes} int j; /* compteur des caractères */
ESP,I,j:integer; int e; /* nombre d'espaces */
begin for (i=0;i<L;i++)
for k:=1 to L do {
begin e = L-i-1;
ESP := L-k; for (j=0 ; j<e ; j++)
for I:=1 to ESP do putchar(' ');
write(' '); for (j=0 ; j<2*i+1 ; j++)
for j:=1 to 2*k-1 do putchar('*');
write('*'); putchar('\n');
writeln; }
end; getchar() ;
readln; }
end ;

ENS – Rabat – Département d’Informatique 107


Solutions des exercices

Exercice 53
Calculer pour une valeur X donnée du type float la valeur numérique d'un polynôme de degré n:
P(X) = AnXn + An-1Xn-1 + ... + A1X + A0
Les valeurs de n, des coefficients An, ..., A0 et de X seront entrées au clavier.
Utiliser le schéma de Horner qui évite les opérations d'exponentiation lors du calcul:

procedure polynome(N:integer;X:real); void polynome(int N, float X)


var I:integer; {
A,B:real; float A; /* coefficients successifs du polynôme */
begin float P; /* coefficient courant du terme Horner */
for I:=1 to N+1 do for(P=0.0 ; N>=0 ; N--)
begin {
writeln('donner le ',I,'eme coefficient'); printf("Entrer le coefficient A%d : ", N);
readln(B); scanf("%f", &A);
A:=A*X+B; P = P*X + A;
end; }
writeln(‘Valeur du polynôme pour X = ‘,X,’est :’,A); printf("Valeur du polynôme pour X = %.2f : %.2f\n",
readln; end; X, P);
}
Exercice 54

ENS – Rabat – Département d’Informatique 108


Solutions des exercices

Ecrire une procédure qui affiche la table des produits pour N variant de 1 à 10 :
X*Y I 0 1 2 3 4 5 6 7 8 9 10
--------------------------------------------------
0 I 0 0 0 0 0 0 0 0 0 0 0
1 I 0 1 2 3 4 5 6 7 8 9 10
2 I 0 2 4 6 8 10 12 14 16 18 20
3 I 0 3 6 9 12 15 18 21 24 27 30
4 I 0 4 8 12 16 20 24 28 32 36 40
5 I 0 5 10 15 20 25 30 35 40 45 50
6 I 0 6 12 18 24 30 36 42 48 54 60
7 I 0 7 14 21 28 35 42 49 56 63 70
8 I 0 8 16 24 32 40 48 56 64 72 80
9 I 0 9 18 27 36 45 54 63 72 81 90
10 I 0 10 20 30 40 50 60 70 80 90 100

program tabMul; void tabMul(void)


CONST MAX= 10; {
var I,J:integer; const int MAX = 10; /* nombre de lignes et de
begin colonnes */
write(' X*Y I'); int I; /* compteur des lignes */
for I:=0 to MAX do int J; /* compteur des colonnes */
write(I:4);
writeln; /* Affichage de l'en-tête */
writeln('-----------------------------------------------’); printf(" X*Y I");
for J:=0 to max do for (J=0 ; J<=MAX ; J++)
begin printf("%4d", J);

ENS – Rabat – Département d’Informatique 109


Solutions des exercices

write(J:7,’ I’); printf("\n");


for I:=0 to Max do printf("------");
write(I*J:4); for (J=0 ; J<=MAX ; J++)
writeln; printf("----");
end; printf("\n");
readln;
end. /* Affichage du tableau */
for (I=0 ; I<=MAX ; I++)
{
printf("%3d I", I);
for (J=0 ; J<=MAX ; J++)
printf("%4d", I*J);
printf("\n");
}
}
Les Tableaux
Exercice 55
Ecrire une procédure qui affiche les nombres négatifs d’une liste réelle
Type tab=array[0..50] of real ; void nbre_negatif(float a[],int n)
Procedure nbre_negatif(a:tab;n:integer); {int i;
Var i:integer; for(i=0;i<n;i++)
Begin if(a[i]<0) printf("%f\t",a[i]);
for i:=0 to n-1 do }
if a[i]<0 then writeln(a[i]);
End;
Exercice 56

ENS – Rabat – Département d’Informatique 110


Solutions des exercices

Ecrire une procédure qui met à zéro la diagonale d’une matrice carrée.
type matrice=array[1..50,1..50] of integer; typedef int ligne[50];
procedure mise_zero(var a:matrice;n:integer); typedef ligne matrice[50];
var i:integer; void mise_zero(matrice A,int n)
begin {int I;
for i:=1 to n do for (I=0; I<n; I++)
a[i,i]:=0; A[I][I]=0;
end; }
Exercice 57
Ecrire une procédure qui affiche l’occurrence d’existence d’un nombre réel dans une liste de nombres réels
Type tab=array[0..50] of real ; void occurrence(float a[],int n,float nbre)
Procedure occurrence(a:tab;n:integer;nbre:real); {int i,cpt;
Var i,cpt:integer; for(i=0,cpt=0;i<n;i++)
Begin if(a[i]==nbre) cpt++;
cpt:=0; printf("L'occurrence d'existence du nombre %f est
for i:=0 to n-1 do %d",nbre,cpt);
if a[i]=nbre then cpt:=cpt+1; }
writeln(‘L’’occurrence d’’existence du nombre
‘,nbre,’ est ’,cpt) ;
End;
Exercice 58
Ecrire une procédure qui met le plus petit élément d’une liste au début de celle-ci
type tab=Array[0..50] of real; void min_debut(float a[],int n)
procedure min_debut(var a:tab;n:integer); {int i,ind;
var i,ind:integer; float tmp;
tmp: real; for(i=1,ind=0;i<n;i++)

ENS – Rabat – Département d’Informatique 111


Solutions des exercices

begin if(a[i]<a[ind]) ind=i;


ind:=0; tmp=a[0];
for i:=0 to n-1 do a[0]=a[ind];
if a[i]<a[ind] then ind:=i; a[ind]=tmp;
tmp:=a[0]; }
a[0]:=a[ind];
a[ind]:=tmp;
end;
Exercice 59
Ecrire une procédure qui met les éléments négatifs d’une liste à gauche et les éléments positifs à droite de la liste
type tab=Array[0..50] of real; void negatif_gauche(float a[],int n)
procedure negatif_gauche(var a:tab;n:integer); {int i,j;
var i,j:integer; float tmp;
tmp: real; for(i=0,j=0;i<n;i++)
begin if(a[i]<0)
j:=0; { tmp=a[j];
for i:=0 to n-1 do a[j]=a[i];
if a[i]<0 then a[i]=tmp;
begin j++;
tmp:=a[j]; }
a[j]:=a[i]; }
a[i]:=tmp;
j:=j+1;
end;
end;
Exercice 60

ENS – Rabat – Département d’Informatique 112


Solutions des exercices

Ecrire une procédure qui classe une liste de notes de la plus petite à plus grande
type tab=Array[0..50] of real; void tri(float note[],int n)
procedure tri(var note:tab;n:integer); {int i,j,min;
var i,j,min:integer; float tmp;
tmp:real; for(i=0;i<n-1;i++)
begin {
for i:=0 to n-2 do for(min=i,j=i+1;j<n;j++)
begin if(note[j]<note[min]) min=j;
min:=i; if (min!=i)
for j:=i+1 to n-1 do { tmp=note[i];
if note[j]<note[min] then min:=j; note[i]=note[min];
if min<>i then note[min]=tmp;
begin }
tmp:=note[i]; }
note[i]:=note[min]; }
note[min]:=tmp;
end;
end;
end;
Exercice 61
Etant donné N étudiants, leurs notes correspondantes à M matières et leur moyenne. Ecrire une procédure qui
affiche à côté de chaque étudiant son classement.
type matrice=array[1..50,1..50]of real; void moyenne(float m[50][50],int tl,int tc)
procedure moyenne(var m:matrice;tl,tc:integer); {float s;
var i,j:integer; int i,j;
s:real; for (i=0;i<tl;i++)

ENS – Rabat – Département d’Informatique 113


Solutions des exercices

begin {s=0;
for i:=1 to tl do for(j=0;j<tc-2;j++)
begin s+=m[i][j];
s:=0; m[i][tc-2]=s/(tc-2);
for j:=1 to tc-2 do }
s:=s+m[i,j]; }
m[i,tc-1]:=s/(tc-2);
end; void classement(float m[50][50],int tl,int tc)
end; {int te,i,cl=1,j,p[50],arret=0;
for(i=0;i<tl;i++)
procedure classement(var m:matrice;tl,tc:integer); m[i][tc-1]=0;
var te,i,j,cl:integer; do
p:array[1..50] of integer; {j=0;te=0;
arret:boolean; while(m[j][tc-1]!=0 && j<tl) j++;
begin if (m[j][tc-1]!=0) arret=1;
for i:=1 to tl do else
m[i,tc]:=0; {p[te++]=j;
arret:=false; for (j=p[te-1]+1;j<tl;j++)
cl:=1; if(m[j][tc-1]==0)
repeat {if(m[j][tc-2]>m[p[te-1]][tc-2])
begin {te=0;
j:=1; p[te++]=j;
te:=0; }
while (m[j,tc]<>0) and (j<=tl) do j:=j+1; else
if m[j,tc]<>0 then arret:=true if (m[j][tc-2]==m[p[te-1]][tc-2]) p[te++]=j; }
else for(i=0;i<te;i++)

ENS – Rabat – Département d’Informatique 114


Solutions des exercices

begin m[p[i]][tc-1]=cl;
te:=te+1; cl+=te;
p[te]:=j; }
for j:= p[te]+1 to tl do }
if m[j,tc]=0 then while(!arret);
if m[j,tc-1]>m[p[te],tc-1] then }
begin
te:=1;
p[te]:=j;
end
else
if m[j,tc-1] = m[p[te],tc-1] then
begin
te:=te+1;
p[te]:=j;
end;
for i:=1 to te do
m[p[i],tc]:=cl;
cl:=cl+te;
end;
end;
until arret;
end;
Exercice 62
Le tri par bulles est un tri par échange. Le principe de base est de réordonner les couples non classés tant qu’ils
en existent. La méthode de tri par bulles consiste à parcourir la liste en comparant deux éléments successifs en

ENS – Rabat – Département d’Informatique 115


Solutions des exercices

les permutant s’il y a lieu. Ecrire une procédure qui réalise ce tri.
Type tab=array[0..50] of integer ; void echanger(int t[],int i, int j)
Procedure echanger(var t:tab;i,j: integer); {int tmp=t[i];
Var tmp:integer; t[i]=t[j];
Begin t[j]=tmp;
tmp :=t[i]; }
t[i] :=t[j]; void tri_bulles (int t[], int n)
t[j] :=tmp; {int k,p;
End; for(k=0;k<=n-2;k++)
Procedure tri_bulles(var t: tab; n: integer); for(p=n-2;p>=k;p--)
Var p,k:integer; if(t[p+1]<t[p])
Begin echanger(t,p+1,p);
for k:=0 to n-2 do }
for p:=n-2 downto k do
if t[p+1]<t[p] then
echanger(t,p+1,p);
End;
Les chaînes de caractères :
Exercice 63
Un palindrome est un mot, ou une phrase, lisible indifféremment de la gauche vers la droite ou inversement.
Ecrire une fonction qui rend si une chaîne de caractères est un palindrome ou non.
Function palindrome(s:string):boolean; int palindrome (char s[])
Var i,taille :integer; {int i,taille;
miroir:string; char miroir[255];
begin taille=strlen(s);
taille :=length(s) ; for(i=0;i<taille;i++)

ENS – Rabat – Département d’Informatique 116


Solutions des exercices

miroir:=’’; miroir[i]=s[taille-i-1];
for i:= 1 to taille do return(!strncmp(miroir,s,taille));
miroir:=miroir+s[taille-i+1]; }
palindrome :=(s=miroir) ; Remarque :
end ; Vous devez ajouter la ligne suivante au début de votre
programme : #include <string.h>, pour pouvoir utiliser
les fonctions strlen et strncmp.
Exercice 64
Ecrire une fonction qui retourne la fréquence de présence d’un mot dans une phrase.
Function frequence(phrase,mot:string):integer; int frequence (char phrase[],char mot[])
var cpt,debut:integer; {int cpt=0;
begin while (phrase=strstr(phrase,mot))
cpt:=0; {cpt++;
while pos(mot,phrase)<>0 do phrase=phrase+strlen(mot);
begin }
cpt:=cpt+1; return(cpt);
debut:=pos(mot,phrase); }
delete(phrase,1,length(mot)+debut); Remarque :
end; Vous devez ajouter la ligne suivante au début de votre
frequence:=cpt; programme : #include <string.h>, pour pouvoir utiliser
end; les fonctions strlen et strstr.
Exercice 65
Ecrire une procédure qui enlève tous les blancs au début d’une phrase et laisse un seul blanc entre les différents
mots de la phrase
procedure blanc(var s:string); void blanc (char s[ ])
var ind:integer; {

ENS – Rabat – Département d’Informatique 117


Solutions des exercices

tmp:string; while(s[0]==' ') strcpy(s,s+1);


begin while(s=strchr(s,' '))
while s[1]=' ' do delete(s,1,1); { while(*(s+1)==' ') strcpy(s,s+1);
ind:=0; s=s+1;
tmp:=s; }
while pos(' ',tmp)<>0 do }
begin Remarque :
ind:=pos(' ',tmp)+ind; Vous devez ajouter la ligne suivante au début de votre
while s[ind+1]=' ' do delete(s,ind+1,1); programme : #include <string.h>, pour pouvoir utiliser
tmp:=copy(s,ind+1,length(s)); les fonctions strcpy et strchr.
end;
end;
Exercice 66
Soit un nombre entier positif N. Ecrire une fonction qui donne son équivalent dans une base donnée B
(2≤ B≤ 16)
Function car(n :word) :char ; char car(int n)
Begin {if (n<=9) return('0'+n);
If n<=9 then car:=chr(n+ord(‘0’)) else return(n+'A'-10);
Else }
car:=chr(n+ord(‘A’)-10);
End; char* dix_b(int n,int b)
{char *s,t[40];
Function dix_b(n,b:word):string; strcpy(s,"");
Var s:string; while(n!=0)
Begin {
s:=’’; t[0]=car(n%b);

ENS – Rabat – Département d’Informatique 118


Solutions des exercices

While n<>0 do strcpy(t+1,"");


Begin strcat(t,s);
s:=car(n mod b)+s; strcpy(s,t);
n:=n div b; n=n/b;
End; }
dix_b:=s; return(s);
End; }

Exercice 67
Soit N un nombre donné en base B1 (B ≠ 10). Ecrire une fonction qui donne son équivalent en base 10.
Function valeur (c :char) :word ; int valeur(char c)
Begin { if((c<='9') && (c>='0'))
If c IN [‘0’..’9’] then return(c-'0');
valeur:=ord(c)-ord(‘0’) else
Else if ((toupper(c) >='A') && (toupper(c)<='F'))
If upcase(c) IN [‘A’..’F’] then return(toupper(c)-'A'+10);
valeur:=ord(upcase(c))-ord(‘A’)+10; }
End;
int b_dix(char n[],int b)
Function b_dix(n:string;b:word):word; {int i,res=0;
Var i:integer; for(i=0;i<strlen(n);i++)
res:word; res=res*b+valeur(n[i]);
Begin return(res);
res:=0; }
For i:=1 to length(n) do Remarque :

ENS – Rabat – Département d’Informatique 119


Solutions des exercices

res:=res*b+valeur(n[i]) ; Vous devez ajouter les lignes suivantes au début de


b_dix :=res ; votre programme : #include <string.h> et #include
End ; <ctype.h>, pour pouvoir utiliser les fonctions strlen et
toupper.
Exercice 68
Soit N un nombre donné en base B1. Ecrire une fonction qui donne son équivalent en base B2.
procedure baseB(n:string;b1,b2:integer;var r:string); void baseB(char n[],int b1,int b2,char r[])
var re:integer; {
begin return(dix_b(b_dix(n,b1),b2));
baseB:=dix_b(b_dix(n,b1),b2); }
end;
Exercice 69
Si on est amené à réaliser des opérations sur des nombres entiers très grands, on peut utiliser les chaînes de
caractères pour représenter ces nombres et ensuite faire l’opération par bloc.
Ecrire une procédure pour réaliser l’opération d’addition sur de tels nombres.
Function calcul(N1,N2:String):String; char* calcul(char n1[],char n2[])
var Code,R,V,V1,V2:Integer; {char s1[100],s2[100],s[100],n[100],t[2];
N,S,S1,S2:string; int r,v;
begin r=0;
N:=''; strcpy(s1,"");strcpy(s2,"");strcpy(s,"");strcpy(n,"");strc
R:=0; py(t,"");
While ( N1<>'') or (N2<>'') Do while((strlen(n1)!=0) || (strlen(n2)!=0))
Begin {
If Length(N1)>4 Then if(strlen(n1)>=4)
Begin {
S1:=Copy(N1,Length(N1)-3,4); strcpy(s1,n1+strlen(n1)-4);

ENS – Rabat – Département d’Informatique 120


Solutions des exercices

Delete(N1,Length(N1)-3,4); strcpy(n1+strlen(n1)-4,"");
End }
Else else
Begin {
S1:=N1; strcpy(s1,n1);
N1:=''; strcpy(n1,"");
End ; }
If Length(N2)>4 Then if(strlen(n2)>=4)
Begin {
S2:=Copy(N2,Length(N2)-3,4); strcpy(s2,n2+strlen(n2)-4);
Delete(N2,Length(N2)-3,4); strcpy(n2+strlen(n2)-4,"");
End }
Else else
Begin {
S2:=N2; strcpy(s2,n2);
N2:=''; strcpy(n2,"");
End ; }
Val(S1,V1,Code); v=atoi(s1)+atoi(s2)+r;
Val(S2,V2,Code); strcpy(s1,"");strcpy(s2,"");itoa(v,s,10);
V:=V1+V2+R; if(strlen(s)>4)
Str(V,S); {
If Length(S)>4 Then strncpy(t,s,1);
Begin r=atoi(t);
Val(Copy(S,1,1),R,Code); strcpy(s,s+1);
S:=Copy(S,2,Length(S)-1); }
End else

ENS – Rabat – Département d’Informatique 121


Solutions des exercices

Else R:=0; r=0;


N:=S+N; strcat(s,n);strcpy(n,s);
End; }
Calcul:=N return(n);
end; }
Remarque :
Vous devez ajouter les lignes suivantes au début de
votre programme : #include <string.h> et #include
<stdlib.h>pour pouvoir utiliser les fonctions strlen,
strcat, strcpy, atoi, itoa et strncpy.
Exercice 70
Ecrire une procédure qui permet de passer de la représentation d’un nombre en chiffres romains à sa
représentation décimale.
function ConvDec1(c:char):integer; int ConvDec1(char c)
begin {
case upcase(c) of switch (toupper(c)) {
'I':ConvDec1:=1; case 'I': return 1;
'V':ConvDec1:=5; case 'V': return 5;
'X':ConvDec1:=10; case 'X': return 10;
'L':ConvDec1:=50; case 'L': return 50;
'C':ConvDec1:=100; case 'C': return 100;
'D':ConvDec1:=500; case 'D': return 500;
'M':ConvDec1:=1000; case 'M': return 1000;
end; }
end; }
procedure ConvDec(rom:string;var dec:integer);

ENS – Rabat – Département d’Informatique 122


Solutions des exercices

var i,d,dn:integer; void ConvDec(char rom[],int *dec)


begin {
dec:=0; int i, d, dn;
d:=ConvDec1(rom[1]);
for i:=1 to length(rom)-1 do *dec = 0;
begin d = ConvDec1(rom[0]);
dn:=ConvDec1(rom[i+1]); for (i = 0; rom[i+1] != '\0'; i++) {
if(d<dn) then dn = ConvDec1(rom[i+1]);
dec:=dec-d if (d < dn) *dec -= d;
else else *dec += d;
dec:=dec+d; d = dn;
d:=dn; }
end; *dec += d;
dec:=dec+d; }
end; Remarque :
Vous devez ajouter la ligne suivante au début de votre
programme : #include <ctype.h> pour pouvoir utiliser
la fonction toupper.
Exercice 71
Ecrire une procédure qui permet de passer de la représentation décimale d’un nombre à sa représentation en
chiffres romains.
procedure ConvRom(var rom:string;dec:integer); void ConvRom(char rom[], int dec)
const ntok=13; {
var tok:integer; int tok;
const romval:array[1..13]of const int ntok = 13;
string[2]=(‘I’,’IV’,’V’,’IX’,’X’,’XL’,’L’,’XC’,’C’,’C const char

ENS – Rabat – Département d’Informatique 123


Solutions des exercices

D’,’D’,’CM’,’M’); *romval[13]={"I","IV","V","IX","X","XL","L","XC","
const decval:array[1..13]of C",
integer=(1,4,5,9,10,40,50,90,100,400,500,900,1000); "CD","D", "CM", "M"};
begin const int decval[13]
rom:=''; ={1,4,5,9,10,40,50,90,100,400,500,900,1000};
for tok:=ntok downto 2 do rom[0] = '\0';
begin for (tok = ntok-1; tok >= 0; tok--) {
while dec>=decval[tok] do while (dec >= decval[tok]) {
begin strcat(rom, romval[tok]);
rom:=rom+romval[tok]; dec -= decval[tok];
dec:=dec-decval[tok]; }
end; }
end; }
end; Remarque :
Vous devez ajouter la ligne suivante au début de votre
programme : #include <string.h> pour pouvoir utiliser
la fonction strcat.
Exercice 72
Ecrire une fonction qui retourne le déterminant d’une matrice carrée.
const DIM=10; #define DIM 10
type matrice=array[0..DIM-1,0..DIM-1] of real; typedef float ligne[DIM];
procedure det_aux(ma:matrice;var typedef ligne matrice[DIM];
mb:matrice;l,c:integer;n:integer); float expo(int n)
var i,j,d,e:integer; {
begin if(!(n%2)){return (1);}
e:=0; return (-1);

ENS – Rabat – Département d’Informatique 124


Solutions des exercices

for i:=0 to n-1 do }


begin
d:=0; void det_aux(matrice ma,matrice mb,int l,int c,int n)
if i<>l then {int i,j,d,e=0;
begin for(i=0;i<n;i++)
for j:=0 to n-1 do {
if j<>c then d=0;
begin if(i!=l)
mb[e][d]:=ma[i][j]; {
d:=d+1; for(j=0;j<n;j++)
end; if(j!=c)
e:=e+1; {mb[e][d]=ma[i][j];
end; d++;
end; }
end; e++;
}
function expo(n:integer):real; }
begin }
if n mod 2=0 then expo:=1
else expo:=-1; float determinant(matrice m,int l)
end; {
int i;
function determinant(m:matrice;l:integer):real; matrice m2;
var float x=0;
i:integer; if(l==1)return (m[0][0]);
m2:matrice; for(i=0;i<l;i++)

ENS – Rabat – Département d’Informatique 125


Solutions des exercices

x:real; {
begin det_aux(m,m2,i,0,l);
x:=0; x=x+(expo(i)*m[i][0]*determinant(m2,(l-1)));
if l=1 then determinant:= m[0][0] }
else return (x);
begin }
for i:=0 to l-1 do
begin
det_aux(m,m2,i,0,l);
x:=x+(expo(i)*m[i][0]*determinant(m2,(l-1)));
end;
determinant:=x;
end;
end;
Exercice 73
Ecrire une procédure qui calcule l’inverse d’une matrice carrée.
procedure transp_mat(ma:matrice;var void transp_mat(matrice ma,matrice mb,int n)
mb:matrice;n:integer); {
var i,j:integer; int i,j;
begin for (i=0;i<n;i++)
for i:=0 to n-1 do for (j=0;j<n;j++)
for j:=0 to n-1 do mb[j][i]=ma[i][j];
mb[j][i]:=ma[i][j]; }
end;
void multi_R(float a,matrice ma,matrice mb,int n)
procedure multi_R(a:real;ma:matrice;var {

ENS – Rabat – Département d’Informatique 126


Solutions des exercices

mb:matrice;n:integer); int i,j;


var i,j:integer; for(i=0;i<n;i++)
begin for(j=0;j<n;j++)
for i:=0 to n-1 do mb[i][j]=ma[i][j]*a;
for j:=0 to n-1 do }
mb[i][j]:=ma[i][j]*a;
end; void coffacteur(matrice ma,matrice mb,int l)
{
procedure coffacteur(ma:matrice;var int i,j;
mb:matrice;l:integer); matrice m2;
var i,j:integer; if (l==1)
m2:matrice; mb[0][0]=1;
begin else
if l=1 then {
mb[0][0]:=1 for (i=0;i<l;i++)
else for (j=0;j<l;j++)
begin {
for i:=0 to l-1 do det_aux(ma,m2,i,j,l);
for j:=0 to l-1 do mb[i][j]=expo(i+j)*determinant(m2,(l - 1));
begin }
det_aux(ma,m2,i,j,l);
mb[i][j]:=expo(i+j)*determinant(m2,(l - 1)); }
end; }
end;
end; void inverse(matrice ma,matrice mb,int l)
{

ENS – Rabat – Département d’Informatique 127


Solutions des exercices

procedure inverse(ma:matrice;var matrice m1,m2;


mb:matrice;l:integer); float d;
var d=(1/determinant(ma,l));
m1,m2:matrice; coffacteur(ma,m1,l);
d:real; transp_mat(m1,m2,l);
begin multi_R(d,m2,mb,l);
d:=(1/determinant(ma,l)); }
coffacteur(ma,m1,l);
transp_mat(m1,m2,l);
multi_R(d,m2,mb,l);
end;
Exercice 74
Un carré magique est un carré divisé en cellules dans lesquelles les nombres entiers, à partir de 1 sont disposés
de telle sorte que les sommes de chaque ligne, de chaque colonne et de chaque diagonale soient égales.
Exemple :
6 1 8
7 5 3
2 9 4
Ecrire une procédure qui permet de réaliser le carré magique.
const k=11; #define k 11
type magique=array[1..k,1..k]of integer; typedef int ligne[k+1];
procedure CaMag(var carre:magique;n:integer); typedef ligne magique[k+1];
var fin,nombre,l,c:integer; void CaMag(magique carre,int n)
begin {
nombre:=1; int fin,nombre=1,l=1,c;
l:=1; fin=n*n;

ENS – Rabat – Département d’Informatique 128


Solutions des exercices

fin:=n*n; c=(n+1)/2;
c:=(n+1) div 2; carre[l][c]=nombre;
carre[l,c]:=nombre; while(nombre!=fin)
while nombre<>fin do {
begin if(nombre%n==0) l++;
if nombre mod n =0 then inc(l) else
else {
begin if(l==1) l=n; else l--;
if l=1 then l:=n if(c==1) c=n; else c--;
else dec(l); }
if c=1 then c:=n nombre++;
else dec(c); carre[l][c]=nombre;
end; }
inc(nombre); }
carre[l,c]:=nombre;
end;
end;

Les enregistrements
Exercice 75
Ecrire un programme qui permet de saisir et d’afficher les informations d’une liste d’étudiants.
Program gest; #include <stdio.h>
#include <conio.h>
uses crt; typedef struct{
Type Date=record int j;
J,M,A:Integer; int m;

ENS – Rabat – Département d’Informatique 129


Solutions des exercices

end; int a;
etud=record }date;
Nom,Prn:string[20]; typedef struct{
CIN:string[10]; char nom[21];
Date_Nais:Date; char prn[21];
End; char cin[11];
Var TEtud:Array[1..100] of etud; date date_naiss;
Te:Integer; }etud;
etud tetud[10];
Procedure Affich_formul(Titre:String); int te=0;
Begin
TextBackground(Blue); void affich_formul(char titre[])
ClrScr; {
TextColor(Yellow); textbackground(BLUE);
Gotoxy(35,4); clrscr();
Write(Titre); textcolor(YELLOW);
Gotoxy(20,7); gotoxy(35,4);
Write('Nom :'); cprintf("%s",titre);
Gotoxy(20,9); gotoxy(20,7);
Write('Pr‚nom :'); cprintf("Nom:");
Gotoxy(20,11); gotoxy(20,9);
Write('C.I.N :'); cprintf("Prenom");
Gotoxy(20,13); gotoxy(20,11);
Write('Date de Naissance :'); cprintf("C.I.N");
End; gotoxy(20,13);
cprintf("Date de naissance");

ENS – Rabat – Département d’Informatique 130


Solutions des exercices

Procedure saisie(Var E:Etud); }


Begin void saisie(etud *e)
TextColor(White); {
With E, Date_Nais Do textcolor(WHITE);
Begin gotoxy(26,7);
Gotoxy(26,7); clreol();
Clreol; scanf("%s",e->nom);
Readln(Nom); gotoxy(29,9);
Gotoxy(29,9); clreol();
Clreol; scanf("%s",e->prn);
Readln(Prn); gotoxy(28,11);
Gotoxy(28,11); clreol();
Clreol; scanf("%s",e->cin);
Readln(CIN); gotoxy(40,13);
Gotoxy(40,13); clreol();
Clreol; scanf("%d",&e->date_naiss.j);
Readln(J); gotoxy(42,13);
Gotoxy(42,13); printf("/");
Write('/'); scanf("%d",&e->date_naiss.m);
Readln(M); gotoxy(45,13);
Gotoxy(45,13); printf("/");
Write('/'); scanf("%d",&e->date_naiss.a);
Readln(A); }
End; void affich(etud e)
End; {
textcolor(WHITE);

ENS – Rabat – Département d’Informatique 131


Solutions des exercices

Procedure Saisietout; gotoxy(26,7);clreol();cprintf(e.nom);


Var E:Etud; gotoxy(29,9);clreol();cprintf(e.prn);
Rep:Char; gotoxy(28,11);clreol();cprintf(e.cin);
Begin gotoxy(40,13);clreol();cprintf("%d/%d/
Te:=0; %d",e.date_naiss.j,e.date_naiss.m,e.date_naiss.a);
Affich_formul('S A I S I E'); }
Repeat void saisietout()
Saisie(E); { char rep;
Te:=Te+1; affich_formul("S A I S I E");
TEtud[Te]:=E; do
TextColor(Yellow); {
Gotoxy(45,17); saisie(&tetud[te++]);
Write('Voulez-vous continuez (O/N)?'); textcolor(YELLOW);
Rep:=readkey; gotoxy(45,17);
Gotoxy(45,17); cprintf("Voulez-vous continuez (O/N)?");
Clreol; fflush(stdin);
Until Rep In ['N', 'n']; rep=getchar();
End; gotoxy(45,17);
clreol();
Procedure Affich(Var E:Etud); }
Begin while((rep!='n') && (rep!='N'));
TextColor(White); }
With E, Date_Nais Do void affichtout()
Begin {
Gotoxy(26,7); char rep;
Clreol; int i;

ENS – Rabat – Département d’Informatique 132


Solutions des exercices

Write(Nom); affich_formul("C O N S U L T A T I O N");


Gotoxy(29,9); for(i=0;i<te;i++)
Clreol; {
Write(Prn); fflush(stdin);
Gotoxy(28,11); affich(tetud[i]);
Clreol; textcolor(YELLOW);
Write(CIN); gotoxy(45,17);
Gotoxy(40,13); cprintf("Taper une touche pour continuer");
Clreol; rep=getchar();
fflush(stdin);
Write(J,'/',M,'/',A); gotoxy(45,17);
End; clreol();
End; }
}
Procedure Affichtout;
Var E:Etud; main()
Rep:Char; {etud e;
I:Integer; saisietout();
Begin affichtout();
Affich_formul('C O N S U L T A T I O N'); clrscr();
For i:=1 To Te Do getch();
Begin }
Affich(TEtud[I]);
TextColor(Yellow);
Gotoxy(45,17);
Write('Taper une touche pour continuer');

ENS – Rabat – Département d’Informatique 133


Solutions des exercices

Rep:=readkey;
Gotoxy(45,17);
Clreol;
End;
End;
BEGIN
saisietout;
Affichtout;
ClrScr;
Readln;
END.
Exercice 76
Ecrire les procédures qui donnent le calcul sur les nombres complexes au moyen d’un type enregistrement.
type complexe=Record typedef struct{
a,b:real; float a;
end; float b;
}complexe;
procedure zsomme(z1,z2:complexe;var z : complexe);
begin void Zsomme(complexe z1,complexe z2,complexe *z)
z.a:=z1.a+z2.a; {z->a=z1.a+z2.a;
z.b:=z1.b+z2.b; z->b=z1.b+z2.b;
end; }

procedure zmoins(z1,z2:complexe;var z : complexe); void Zmoins(complexe z1,complexe z2,complexe *z)


begin {z->a=z1.a-z2.a;
z.a:=z1.a-z2.a; z->b=z1.b-z2.b;

ENS – Rabat – Département d’Informatique 134


Solutions des exercices

z.b:=z1.b-z2.b; }
end;
void Zmul(complexe z1,complexe z2,complexe *z)
procedure zmul(z1,z2 : complexe; var z:complexe); {z->a=z1.b*z2.b-z1.a*z2.a;
begin z->b=z1.a*z2.b+z2.b*z2.a;
z.a:=z1.b*z2.b-z1.a*z2.a; }
z.b:=z1.a*z2.b+z2.b*z2.a;
end;

Les listes chaînées


1. Les listes simples:
type liste=^element; typedef struct str{
element=record int info;
info:integer; str*suivant;
suivant:liste; }*liste;
end;
Exercice 77
Ecrire une procédure qui permet la création en file d’une liste chaînée
procedure creation_file(var tete:liste); void creer_file(liste &L)
var p,q:liste; {
x:integer; int x;
begin printf("entrer des entiers (0 pour terminer):");
new(p); scanf("%d",&x);
write('donner des entiers (0 pour terminer) : '); while(x!=0){
readln(x); liste p=(liste)malloc (sizeof(str));
tete:=nil; p->info=x;

ENS – Rabat – Département d’Informatique 135


Solutions des exercices

while x<>0 do p->suivant=NULL;


begin if(L==NULL) L=p;
p^.info:=x; else{
p^.suivant:=nil; liste q=L;
if tete=nil then while(q->suivant!=NULL) q=q->suivant;
tete:=p q->suivant=p;
else }
begin scanf("%d",&x);
q:=tete; }
while q^.suivant<>nil do }
q:=q^.suivant;
q^.suivant:=p;
end;
new(p);
readln(x);
end;
end;
Exercice 78
Ecrire une procédure qui permet la création en pile d’une liste chaînée
procedure creation_pile(var tete:liste); void creer_pile(liste &L)
var p:liste; {
x:integer; int x;
begin printf("entrer des entiers (0 pour terminer):");
new(p); scanf("%d",&x);
write('donner des entiers (0 pour terminer) : '); while(x!=0){
readln(x); liste p=(liste)malloc (sizeof(str));

ENS – Rabat – Département d’Informatique 136


Solutions des exercices

tete:=nil; p->info=x;
while x<>0 do p->suivant=NULL;
begin if(L==NULL) L=p;
p^.info:=x; else{
p^.suivant:=tete; p->suivant=L; L=p;
tete:=p; }
new(p); scanf("%d",&x);
readln(x); }
end; }
end;
Exercice 79
Ecrire une procédure qui recherche un élément dans une liste chaînée
function rechercher (tete:liste;x:integer) :liste; liste rechercher(liste L,int x)
var p:liste; {
begin if(L!=NULL){
if tete=nil then recherche:=nil if(L->info==x) return L;
else if tete^.info=x then recherche:=tete else return(rechercher(L->suivant,x));
else recherche:=recherche(tete^.suivant,x); }
end; else return NULL;
}
procedure rech_elt (tete:liste;x:integer; var
pred:liste;var pos:liste); void recherch_elt(liste L,int x,liste &pos,liste &pred)
begin {
if tete=nil then if(L!=NULL){
begin if(L->info==x){
pos:=nil; pos=L;

ENS – Rabat – Département d’Informatique 137


Solutions des exercices

pred:=nil; pred=NULL;
end }
else if tete^.info=x then else{
begin liste p=L;
pos:=tete; while((p->suivant! = NULL)&&(p->info!=x))
pred:=nil; {
end pred=p;
else p=p->suivant;
begin }
p:=tete; if(p->info==x) pos=p;
while (p^.suivant<>nil) and (p^.info<>x) do else pos=NULL;
begin }
pred:=p; }
p:=p^.suivant; }
end;
if p^.info=x then pos:=p
else pos:=nil;
end;
end;
Exercice 80
Ecrire une procédure qui insert un élément dans une liste chaînée
procedure inserer(var tete:liste;x:integer;position:liste); void inserer(liste &L,liste pos,int x)
var p,q:liste; {
begin liste p;
new(q); p=(liste)malloc(sizeof(str));
q^.info:=x; p->info=x;

ENS – Rabat – Département d’Informatique 138


Solutions des exercices

q^.suivant:=nil; p->suivant=NULL;
if position=tete then if(L!=NULL){
begin if(pos==L){
q^.suivant:=tete; p->suivant=L;
tete:=q; L=p;
end }
else else{
begin liste q=L;
q^.suivant:=position; while(q->suivant!=pos)
p:=tete; q=q->suivant;
while p^.suivant<>position do p->suivant=pos;
p:=p^.suivant; q->suivant=p;
}
p^.suivant:=q; }
end; }
end;

procedure insere(var
tete:liste;x:integer;position:liste;pred:liste);
var q:liste;
begin void insere(liste &L,liste pos,liste pred,int x)
new(q); {
q^.info:=x; liste p;
q^.suivant:=nil; p=(liste)malloc(sizeof(str));
if position=tete then p->info=x;
begin p->suivant=NULL;

ENS – Rabat – Département d’Informatique 139


Solutions des exercices

q^.suivant:=tete; if(L!=NULL){
tete:=q; if(pos==L){
end p->suivant=L;
else L=p;
begin }
q^.suivant:=position; else{
pred^.suivant:=q; p->suivant=pos;
end; pred->suivant=p;
end; }
}
}
Exercice 81
Ecrire une procédure qui élimine un élément d’une liste chaînée
procedure eliminer(var tete:liste;x:integer); void supprimer(liste &L,int x)
var trouve:boolean; {
q,p:liste; int trouve =1;
begin liste p,q;
p:=tete; p=L;
trouve:=false; q=L;
while(not trouve)and(p<>nil) do while((trouve)&&(p!=NULL)){
begin if(p->info==x) trouve=0;
if p^.info=x then trouve:=true else {
else q=p;
begin p=p->suivant;
q:=p; }
p:=p^.suivant; }

ENS – Rabat – Département d’Informatique 140


Solutions des exercices

end; if(trouve==0){
end; if(p==L) L=p->suivant;
if trouve then q->suivant=p->suivant;
if p=tete then tete:=p^.suivant free(p);
else q^.suivant:=p^.suivant; }
dispose(p); }
end;
void supprime(liste &L,liste pos,liste pred)
{
procedure elimine(var tete:liste;pos:liste;pred:liste); if(pos==L) L=pos->suivant;
begin else pred->suivant =pos->suivant;
if pos=tete then tete:=pos^.suivant free(pos);
else pred^.suivant:=pos^.suivant; }
dispose(pos);
end;
void afficher(liste L)
procedure afficher_liste(tete:liste); {
var p:liste; liste p=L;
begin printf("\n la liste est:\n");
p:=tete; while(p!=NULL){
while p<>nil do printf("\n%d",p->info);
begin p=p->suivant;
writeln('- ',p^.info); }
p:=p^.suivant; }
end;
end;

ENS – Rabat – Département d’Informatique 141


Solutions des exercices

Exercice 82
Ecrire une procédure qui empile un élément dans une pile représentée par une liste chaînée
procedure empiler(var tete:liste;x:integer); void empiler(liste &L,int x)
var p:liste; {
begin new(p); liste p=(liste)malloc(sizeof(str));
p^.info:=x; p->info=x;
p^.suivant:=tete; p->suivant=L;
tete:=p; L=p;
end; }

Exercice 83
Ecrire une procédure qui désempile un élément dans une pile représentée par une liste chaînée
procedure desempiler(var tete:liste); void desempiler(liste &L)
begin {
if tete<>nil then liste p;
begin p=L;
p:=tete; L=p->suivant;
tete:=tete^.suivant; free(p);
dispose(p); }
end;
end;
2. les listes doublement chainées
type liste=^element; typedef struct str{
element=record int info;
info:integer; str*suivant;
suivant,precedent:liste; str*pred;

ENS – Rabat – Département d’Informatique 142


Solutions des exercices

end; }*liste;

Exercice 84
Ecrire une procédure qui permet la création d’une liste doublement chaînée
procedure creation(var tete:liste;var Queue:liste); void creation(liste &L,liste &Qu)
var p,q:liste; {
x:integer; int x;
begin printf("entrer des entiers (0 pour terminer):");
new(p); scanf("%d",&x);
write('donner des entiers (0 pour terminer) : '); while(x!=0){
readln(x); liste p=(liste)malloc (sizeof(str));
tete:=nil; p->info=x;
while x<>0 do p->suivant=NULL;
begin Qu=p;
p^.info:=x; if(L==NULL){
p^.suivant:=nil; p->pred=NULL;
Queue:=p; L=p;
if tete=nil then }
begin else{
p^.precedent:=nil; liste q=L;
tete:=p while(q->suivant!=NULL) q=q-
end >suivant;
else q->suivant=p;
begin p->pred=q;
q:=tete; }
while q^.suivant<>nil do scanf("%d",&x);

ENS – Rabat – Département d’Informatique 143


Solutions des exercices

q:=q^.suivant; }
q^.suivant:=p; }
p^.precedent:=q;
end;
new(p);
readln(x);
end;
end;
Exercice 85
Ecrire une procédure qui recherche un élément dans une liste doublement chaînée
function rechercher(tete:liste;x:integer) :liste; liste rechercher(liste L,int x)
var p:liste; {
begin if(L!=NULL){
if tete=nil then recherche:=nil if(L->info==x) return L;
else if tete^.info=x then recherche:=tete else return(rechercher(L->suivant,x));
else recherche:=recherche(tete^.suivant,x); }
end; else return NULL;
}
function rechercher (tete:liste;
Queue:liste;x:integer):liste;
begin liste rechercher(liste L,liste Qu,int x)
if tete=nil then rech:=nil {
else if tete^.info=x then rech:=tete if(L->pred!=Qu){
else if Queue^.info=x then rech:=Queue if(L->info==x) return L;
else rech:=rech(tete^.suivant,Queue^.precedent,x); else if(Qu->info==x) return Qu;
end; else return(rechercher(L->suivant , Qu-

ENS – Rabat – Département d’Informatique 144


Solutions des exercices

>pred,x));

}
else return NULL;
}

Exercice 86
Ecrire une procédure qui insert un élément dans une liste doublement chaînée
procedure inserer(var tete:liste;x:integer;position:liste); void inserer(liste&L,int x,liste pos)
var p,q:liste; {
begin liste p=(liste)malloc(sizeof(str));
new(q); p->info=x;
q^.info:=x; if(L!=NULL){
q^.suivant:=nil; if(pos==L){
if position=tete then
begin p->pred=NULL;
q^.precedent:=tete^.precedent; p->suivant=L;
q^.suivant:=tete; L->pred=p;
position^.precedent:=p; L=p;
tete:=q; }
end else{
else if position=nil then p->suivant=pos;
begin p->pred=pos->pred;
p:=tete; pos->pred->suivant=p;
while p^.suivant<>nil do pos->pred=p;
p:=p^.suivant; }

ENS – Rabat – Département d’Informatique 145


Solutions des exercices

p^.suivant:=q; }
q^.precedent:=p; }
end
else
begin
q^.suivant:=position;
q^.precedent:=position^.precedent;
position^.precedent^.suivant:=q;
position^.precedent:=q;
end;
end;

Exercice 87
Ecrire une procédure qui élimine un élément d’une liste doublement chaînée
procedure eliminer(var tete:liste;position:liste); void supprimer(liste &L,liste pos)
var q,p:liste; {
begin if(L!=NULL){
if position=tete then if(pos==L){
begin pos->suivant->pred=NULL;
position^.suivant^.precedent:=nil; L=pos->suivant;
tete:=position^.suivant; free(pos);
end }
else if position^.suivant=nil then else if(pos->suivant==NULL){
position^.precedent^.suivant:=nil pos->pred->suivant=NULL;
else free(pos);
begin }

ENS – Rabat – Département d’Informatique 146


Solutions des exercices

position^.precedent^.suivant:=position^.sui else{
vant; pos->pred->suivant=pos->suivant;
position^.suivant^.precedent:=position^.pre pos->suivant->pred=pos->pred;
cedent; free(pos);
end; }
dispose(position); }
end; }

2. Les listes circulaires:


type liste=^element; typedef struct str{
element=record int info;
info:integer; str*suivant;
suivant:liste; }*liste;
end;
var l,p:liste;
Exercice 88
Ecrire une procédure qui permet la création d’une liste chaînée circulaire
procedure creation(var tete:liste); void creer(liste &L)
var p,q:liste; {
x:integer; int x;
begin printf("entrer des entiers (0 pour terminer):");
new(p); scanf("%d",&x);
write('donner des entiers (0 pour terminer) : '); while(x!=0){
readln(x); liste p=(liste)malloc (sizeof(str));
tete:=nil; p->info=x;
while x<>0 do if(L==NULL) L=p;

ENS – Rabat – Département d’Informatique 147


Solutions des exercices

begin else{
p^.info:=x; liste q=L;
if tete=nil then while(q->suivant!=L) q=q->suivant;
tete:=p q->suivant=p;
else }
begin p->suivant=L;
q:=tete; scanf("%d",&x);
while q^.suivant<>tete do }
q:=q^.suivant; }
q^.suivant:=p;
end;
p^.suivant:=tete;
new(p);
readln(x);
end;
end;

Exercice 89
Ecrire une fonction qui recherche un élément dans une liste chaînée circulaire
function recherche(tete:liste; x:integer) :liste; liste rechercher(liste L,int x)
var p:liste; {
begin if(L!=NULL){
if tete<>nil then liste p=L;
begin do{
p:=tete; if(p->info==x) return p;
while (p^.suivant<>tete) and (p^.info<>x) do p=p->suivant;

ENS – Rabat – Département d’Informatique 148


Solutions des exercices

p:=p^.suivant; }while(p!=L);
if p^.info=x then recherche:=p return NULL;
else recherche:=nil; }
end; return NULL;
end; }

Exercice 90
Ecrire une procédure qui insert un élément dans une liste chaînée circulaire
procedure inserer(var tete:liste;x:integer;position:liste); void inserer(liste &L,liste pos,int x)
var p,q:liste; {
begin liste q;
if tete<>nil then liste p=(liste)malloc(sizeof(str));
begin p->info=x;
new(q); if(L!=NULL){
q^.info:=x; if(pos==L){
if position=tete then q=L;
begin p->suivant=L;
p:=tete;
while p^.suivant<>tete do while(q->suivant!=L) q=q->suivant;
p:=p^.suivant; q->suivant=p;
p^.suivant:=q; L=p;
q^.suivant:=tete; }
tete:=q; else if(pos==NULL){
end q=L;
else if position=nil then while(q->suivant!=L) q=q->suivant;
begin q->suivant=p;

ENS – Rabat – Département d’Informatique 149


Solutions des exercices

p:=tete; p->suivant=L;
while p^.suivant<>tete do }
p:=p^.suivant; else{
p^.suivant:=q; q=L;
q^.suivant:=tete; while(q->suivant!=pos) q=q-
end >suivant;
else q->suivant=p;
begin p->suivant=pos;
q^.suivant:=position; }
p:=tete; }
while p^.suivant<>position do }
p:=p^.suivant;
p^.suivant:=q;
end;
end; end;
Exercice 91
Ecrire une procédure qui élimine un élément d’une liste chaînée circulaire
procedure eliminer(var tete:liste;position:liste); void supprimer(liste &L,liste pos)
var q,p:liste; {
begin liste p;
if tete<>nil then if(L!=NULL){
begin if(pos==L){
if position=tete then p=L;
begin while(p->suivant!=L) p=p->suivant;
p:=tete; p->suivant=pos->suivant;
while p^.suivant<>tete do p:=p^.suivant; L=pos->suivant;

ENS – Rabat – Département d’Informatique 150


Solutions des exercices

p^.suivant:=tete^.suivant; free(pos);
tete:=tete^.suivant; }
dispose(position); else{
end p=L;
else while(p->suivant!=pos) p=p-
begin >suivant;
p:=tete; p->suivant=pos->suivant;
while p<>position do free(pos);
begin }
q:=p; }
p:=p^.suivant; }
end;
q^.suivant:=position^.suivant;
dispose(position);
end;
end;
end;
Exercice 92
Un paragraphe est une suite de phrases. Une phrase est une suite de mots qui se termine par un point(‘.’). deux
mots sont séparés par un blanc(‘ ’).
Dans cet exercice on représentera un paragraphe par une liste chainée, et aussi une phrase par une liste chainnée.
1- Ecrire une procédure qui permet la création d’une telle représentation.
2- Ecrire une procédure qui permet la recherche de la première occurrence d’un mot dans le paragraphe. Le
résultat de la recherche donne la position de ce mot.
3- Ecrire une procédure qui permet l’insertion d’un mot M1 après un mot M2 donnée. Si le mot ne se trouve
pas dans le paragraphe, on ne fait pas d’insertion.

ENS – Rabat – Département d’Informatique 151


Solutions des exercices

4- Ecrire une procédure qui permet l’élimination d’un mot M1 du paragraphe.


5- Ecrire une fonction qui permet la recherche d’une phrase, donnée par son premier mot, dans le
paragraphe le résultat de la recherche donne la position de cette phrase dans le paragraphe.
6- Ecrire une procédure qui permet l’insertion d’une phrase ph1 après une phrase ph2 donnée. Si la phrase
ph2 ne se trouve pas dans le paragraphe, on insert ph1 à la findu paragraphe.
7- Ecrire une procédure qui permet l’élimination d’une phrase ph1 du paragraphe.
PROGRAM paragraphe; #include<stdio.h>
#include<conio.h>
type ligne=^element; #include<alloc.h>
element=record #include<string.h>
info:string; typedef struct str1{
suivant:ligne; char info[20];
end; str1*suivant;
type para=^str; }*ligne;
str=record typedef struct str2{
line:ligne; ligne line;
suivant:para; str2*suivant;
end; }*para;
var L,q:ligne;
Pa,p:para; void creer_ligne(ligne &L)
{
procedure creation_ligne(var L:ligne); char mot[20];
var p,q:ligne; printf("Entrer une suite de mots ('.' pour
mot:string; terminer):");
begin scanf("%s",mot);
new(p); while(strcmp(mot,".")){

ENS – Rabat – Département d’Informatique 152


Solutions des exercices

writeln('entrer une suite de mots (point"." pour int n=strlen(mot) ;


terminer):'); //printf("__%d",n);
readln(mot); ligne p=(ligne)malloc(sizeof(str1));
while mot<>'.' do //p->info=(char*)malloc(sizeof(char)*n);
begin strcpy(p->info,mot);
p^.info:=mot; p->info[n]='\0';
p^.suivant:=nil; p->suivant=NULL;
if L=nil then L:=p if(L==NULL) L=p;
else else{
begin ligne q=L;
q:=L; while(q->suivant!=NULL) q=q-
while q^.suivant<>nil do >suivant;
q:=q^.suivant; q->suivant=p;
q^.suivant:=p; }
end; //free(p->info);
readln(mot); scanf("%s",mot);
new(p); }
end; }
end;
void afficher_ligne(ligne L)
procedure afficher_ligne(L:ligne); {
var p:ligne; ligne p=L;
begin while(p->suivant!=NULL){
if L<>nil then // strcat(p->info," ");
begin printf("%s ",p->info);
p:=L; p=p->suivant;

ENS – Rabat – Département d’Informatique 153


Solutions des exercices

while p^.suivant<>nil do }
begin printf("%s.",p->info);
write(p^.info,' ' ); }
p:=p^.suivant;
end; void creer_paragraphe(para&Pa)
write(p^.info,'.'); {
end; para p,q;
end; ligne L;
char rep;
procedure creation_paragraphe(var Pa:para); do{
var p,q:para; L=NULL;
L:ligne; creer_ligne(L);
rep:string; p=(para)malloc(sizeof(str1));
begin p->line=L;
repeat p->suivant=NULL;
L:=nil; if (Pa==NULL) Pa=p;
creation_ligne(L); else{
new(p); q=Pa;
p^.line:=L; while(q->suivant!=NULL) q=q-
p^.suivant:=nil; >suivant;
if Pa=nil then Pa:=p q->suivant=p;
else }
begin getchar();
q:=Pa; printf("voulez vous continuer(o/n)? ");
while q^.suivant<>nil do q:=q^.suivant; scanf("%c",&rep);
q^.suivant:=p; }while(rep=='o');

ENS – Rabat – Département d’Informatique 154


Solutions des exercices

end; }
write('voulez vous continuer?(oui/non)
');readln(rep); void afficher_paragraphe(para Pa)
until (rep='non'); {
end; para p=Pa;
while(p!=NULL){
procedure afficher_paragraphe(Pa:para); afficher_ligne(p->line);
var p:para; p=p->suivant;
begin }
if Pa<>nil then }
begin
p:=Pa; void chercher(para Pa,char*mot,para&P, ligne &L)
{
while p<>nil do int trouve=0;
begin para q=Pa;
afficher_ligne(p^.line); while((q!=NULL)&&(!trouve)){
writeln; P=q ;
p:=p^.suivant; ligne l=q->line;
end; while((l!=NULL)&&(!trouve)){
end; if(!strcmp(l->info,mot)) {
end; trouve=1;
L=l;
procedure rechercher(Pa:para;mot:string;var p:para;var }
l:ligne); l=l->suivant;
var q:para; }
r:ligne; q=q->suivant;

ENS – Rabat – Département d’Informatique 155


Solutions des exercices

trouve:boolean; }
begin }
trouve:=false;
if Pa<>nil then void inserer(para Pa,char*M1,char*M2)
begin {
q:=Pa; ligne q,r,l;
while (q<>nil)and(not trouve) do para p;
begin if(p!=NULL){
r:=q^.line; r=(ligne)malloc(sizeof(str1));
while(r<>nil)and(not trouve) do strcpy(r->info,M2);
begin r->suivant=NULL;
if r^.info = mot then chercher(Pa,M1,p,q);
begin l=p->line;
l:=r; l=q;
p:=q; r->suivant=l->suivant;
trouve:=true; l->suivant=r;
end }
else }
r:=r^.suivant;
end; void supprimer(para &Pa,char*mot)
q:=q^.suivant; {
end; ligne l,q;
end; para p;
end; if(Pa!=NULL){
chercher(Pa,mot,p,q);
procedure inserer(Pa:para;M1,M2:string); if(q==p->line){

ENS – Rabat – Département d’Informatique 156


Solutions des exercices

var q,r,l:ligne;
p:para; p->line=q->suivant;
begin free(q);
if p<>nil then }
begin else{
new(r); l=p->line;
r^.info:=M2; while(l->suivant!=q) l=l->suivant;
r^.suivant:=nil; l->suivant=q->suivant;
rechercher(Pa,M1,p,q); free(q);
l:=p^.line; }
l:=q; }
r^.suivant:=l^.suivant; }
l^.suivant:=r;
end; para rechercher_phrase(para Pa,char*M1)
end; {
para p;
procedure supprimer(var Pa:para;M1:string); ligne q;
var p:para; p=Pa;
q,l:ligne; if(Pa!=NULL){
begin while(p!=NULL){
if Pa<>nil then q=p->line;
begin if(!strcmp(q->info,M1))
rechercher(Pa,M1,p,q); return(p);
if q=p^.line then p=p->suivant;
p^.line:=q^.suivant }
else return NULL;

ENS – Rabat – Département d’Informatique 157


Solutions des exercices

begin }
l:=p^.line; return NULL;
while l^.suivant<>q do }
l:=l^.suivant;
l^.suivant:=q^.suivant; void inserer_phrase(para Pa,ligne l,char*M1)
end; {
dispose(q); para p,q,r;
end; if(Pa!=NULL){
end; q=(para)malloc(sizeof(str2));
q->line=l;
function rechercher_phrase(Pa:para;M1:string):para; q->suivant=NULL;
var p:para; p=rechercher_phrase(Pa,M1);
q:ligne; if(p!=NULL){
trouve:boolean; q->suivant=p->suivant;
begin p->suivant=q;
p:=Pa; }
trouve:=false; else{
if p<>nil then r=Pa;
begin while(r->suivant!=NULL) r=r-
while(p<>nil) and (not trouve)do >suivant;
begin r->suivant=q;
if(p^.line^.info=M1) then }
begin }
rechercher_phrase:=p; }
trouve:=true;
end void supprimer_phrase(para&Pa,ligne l)

ENS – Rabat – Département d’Informatique 158


Solutions des exercices

else {
p:=p^.suivant;
end; para p,q,m;
end; ligne r;
end; p=rechercher_phrase(Pa,l->info);
if(p==Pa){
procedure inserer_phrase ( Pa:para ; l:ligne ; Pa=p->suivant;
M1:string); free(p);
var p,q,r:para; }
begin else{
if Pa<>nil then q=Pa;
begin while((q!=NULL)&&(q->line!=p->line)){
new(q); m=q;
q^.line:=l; q=q->suivant;
q^.suivant:=nil; }
p:=rechercher_phrase(Pa,M1); if(q!=NULL){
if p<>nil then m->suivant=q->suivant;
begin free(p);
q^.suivant:=p^.suivant; }
p^.suivant:=q; }
end }
else
begin
r:=Pa;
while r^.suivant<>nil do r:=r^.suivant;
r^.suivant:=q;

ENS – Rabat – Département d’Informatique 159


Solutions des exercices

end;
end;
end;

procedure supprimer_phrase(var Pa:para;l:ligne);


var p,q,m:para;
begin
p:=rechercher_phrase(Pa,l^.info);
if p=Pa then Pa:=p^.suivant
else
begin
q:=Pa;
while(q<>nil)and(q^.line<>p^.line) do
begin
m:=q;
q:=q^.suivant;
end;
if q<>nil then
m^.suivant:=q^.suivant;
end;
dispose(p); end;
Les Arbres Binaires
type Noeud=^element; typedef struct str{
element=record int cle;
cle:integer; str*g,*d;
g:Noeud; }*Noeud;

ENS – Rabat – Département d’Informatique 160


Solutions des exercices

d:Noeud;
end;
Exercice 93
Ecrire la procédure du parcours d’un arbre binaire en préordre.
procedure preordre(A:Noeud); void preordre(Noeud A)
begin {
if A<>nil then if(A!=NULL){
begin printf("%d ",A->cle);
write(A^.cle,' '); preordre(A->g);
preordre(A^.g); preordre(A->d);
preordre(A^.d); }
end; }
end;
Exercice 94
Ecrire la procédure du parcours d’un arbre binaire en postordre.
procedure postordre(A:Noeud); void postordre(Noeud A)
begin {
if A<>nil then if(A!=NULL){
begin postordre(A->g);
postordre(A^.g); postordre(A->d);
postordre(A^.d); printf("%d ",A->cle);
write(A^.cle,' '); }
end; }
end;
Exercice 95
Ecrire la procédure du parcours d’un arbre binaire en ordre.

ENS – Rabat – Département d’Informatique 161


Solutions des exercices

procedure ordre(A:Noeud); void ordre(Noeud A)


begin {
if A<>nil then if(A!=NULL){
begin ordre(A->g);
ordre(A^.g); printf("%d ",A->cle);
write(A^.cle,' '); ordre(A->d);
ordre(A^.d); }
end; }
end;
Exercice 96
Ecrire une fonction qui recherche un élément dans un arbre ordonné horizontalement
function recherche(A:Noeud;x:integer):Noeud; Noeud recherche(Noeud A,int x)
begin {
if A<>nil then if(A!=NULL){
begin if(A->cle==x) return A;
if A^.cle=x then recherche:=A else{
else if A^.cle>x then if(A->cle>x) return(recherche(A-
recherche:=recherche(A^.g,x) >g,x));
else recherche:=recherche(A^.d,x); else return(recherche(A->d,x));
end }
else recherche:=nil; }
end; else return NULL;
}

Exercice 97

ENS – Rabat – Département d’Informatique 162


Solutions des exercices

Ecrire une procédure qui insert un élément dans un arbre ordonné horizontalement
procedure insertion(var A:Noeud;x:integer); void insertion(Noeud &A,int x)
var N:Noeud; {
begin Noeud p=(Noeud)malloc(sizeof(str));
new(N); p->cle=x;
N^.cle:=x; p->g=NULL;
N^.g:=nil; p->d=NULL;
N^.d:=nil; if (A==NULL) A=p;
if A=nil then A:=N else{
else if(A->cle>x) insertion(A->g,x);
begin else insertion(A->d,x);
if x<A^.cle then insertion(A^.g,x) }
else insertion(A^.d,x); }
end;
end;

Exercice 98
Ecrire une procédure qui supprime un élément dans un arbre ordonné horizontalement
procedure suppression(var A:Noeud;x:integer); void suppression(Noeud &A,int x)
var pt,pd,pg:Noeud; {
begin Noeud pt,pg,pd;
if A<>NIL then if(A!=NULL){
begin if(A->cle==x){
if A^.cle=x then pt=A->d;
begin if (pt!=NULL){
pt:=A^.d; while(pt!=NULL){

ENS – Rabat – Département d’Informatique 163


Solutions des exercices

if pt<>nil then pg=pt;


begin pt=pt->g;
while pt<>nil do }
begin pg->g=A->g;
pg:=pt; A=A->d;
pt:=pt^.g; }
end; else A=A->g;
pg^.g:=A^.g; }
A:=A^.d; else if(x==A->g->cle){
end pt=A->g->d;
else A:=A^.g; if(pt!=NULL){
end while(pt!=NULL){
else pg=pt;
if x=A^.g^.cle then pt=pt->g;
begin }
pt:=A^.g^.d; pg->g=A->g->d;
if pt<>nil then A->g=A->g->d;
begin }
while pt<>nil do else A->g=A->g->g;
begin }
pg:=pt; else if(x==A->d->cle){
pt:=pt^.g; pt=A->d->g;
end; if(pt!=NULL){
pg^.g:=A^.g^.d; while(pt!=NULL){
A^.g:=A^.g^.d; pd=pt;
end pt=pt->d;

ENS – Rabat – Département d’Informatique 164


Solutions des exercices

else A^.g:=A^.g^.g; }
end pd->d=A->d->d;
else A->d=A->d->g;
if x=A^.d^.cle then }
begin else A->d=A->d->d;
pt:=A^.d^.g; }
if pt<>nil then else{
begin if(x<A->cle) suppression(A->g,x);
while pt<>nil do else suppression(A->d,x);
begin }
pd:=pt; }
pd:=pt^.d; }
end;
pd^.d:=A^.d^.d;
A^.d:=A^.d^.g;
end
else A^.d:=A^.d^.d;
end
else
if x<A^.cle then suppression(A^.g,x)
else suppression(A^.d,x);
end;
end;
Les Fichiers
Exercice 99
Ecrire un programme qui permet de créer un fichier d’étudiants.

ENS – Rabat – Département d’Informatique 165


Solutions des exercices

Program gest_fich; #include<stdio.h>


uses crt; #include<conio.h>
Type Date=record #include<alloc.h>
J,M,A:Integer; #include<string.h>
end; typedef struct{
etud=record int J,M,A;
Nom,Prn:string[20]; }date;
CIN:string[10]; typedef struct{
Date_Nais:Date; char nom[20];
End; char prn[20];
Var FEtud:File of etud; char cin[10];
date date_nais;
Procedure Affich_formul(Titre:String); }etudiant;
Begin
TextBackground(Blue); void affich_formul(char *titre)
ClrScr; {
TextColor(Yellow); textbackground(BLUE);
Gotoxy(35,4); clrscr();
Write(Titre); textcolor(YELLOW);
Gotoxy(20,7); gotoxy(35,4);
Write('Nom :'); cprintf("%s",titre);
Gotoxy(20,9); gotoxy(20,7);
Write('Pr‚nom :'); cprintf("Nom :");
Gotoxy(20,11); gotoxy(20,9);
Write('C.I.N :'); cprintf("Prenom :");
Gotoxy(20,13); gotoxy(20,11);

ENS – Rabat – Département d’Informatique 166


Solutions des exercices

Write('Date de Naissance :'); cprintf("C.I.N :");


End; gotoxy(20,13);
cprintf("Date de naissance :");
Procedure saisie(Var E:Etud); }
Begin
TextColor(White); void saisie(etudiant &E)
With E, Date_Nais Do {
Begin textcolor(WHITE);
Gotoxy(26,7); gotoxy(26,7);
Clreol; clreol();
Readln(Nom); scanf("%s",E.nom);
Gotoxy(29,9); gotoxy(29,9);
Clreol; clreol();
Readln(Prn); scanf("%s",E.prn);
Gotoxy(28,11); gotoxy(28,11);
Clreol; clreol();
Readln(CIN); scanf("%s",E.cin);
Gotoxy(40,13); gotoxy(40,13);
Clreol; clreol();
Readln(J); scanf("%d",&E.date_nais.J);
Gotoxy(42,13); gotoxy(42,13);
Write('/'); clreol();
Readln(M); cprintf("/");
Gotoxy(45,13); scanf("%d",&E.date_nais.M);
Write('/'); gotoxy(45,13);
Readln(A); cprintf("/");

ENS – Rabat – Département d’Informatique 167


Solutions des exercices

End; clreol();
End; scanf("%d",&E.date_nais.A);
}
Procedure Ajout;
Var E:Etud; void ajout()
Rep:Char; {
Begin etudiant E;
Assign(Fetud,'C:\Gestion'); int rep;
{$I-} FILE*Fetud=fopen("Gestion","ab");
Reset(Fetud); affich_formul("SAISIE");
{$I+} do{
If IOResult<>0 Then Rewrite(Fetud) saisie(E);
Else Seek(Fetud,FileSize(Fetud)); fwrite(&E,sizeof(etudiant),1,Fetud);
Affich_formul('S A I S I E'); textcolor(YELLOW);
Repeat gotoxy(45,17);
Saisie(E); cprintf("voulez_vous continuez(o/n)?");
Write(Fetud,E); clreol();
TextColor(Yellow); flushall();
Gotoxy(45,17); rep=getchar();
Write('Voulez-vous continuez (O/N)?'); }while(rep=='o' || rep=='O');
Rep:=readkey; fclose(Fetud);
Gotoxy(45,17); }
Clreol; void affich(etudiant &E)
Until Rep In ['N', 'n']; {
Close(Fetud); textcolor(WHITE);
End; gotoxy(26,7);

ENS – Rabat – Département d’Informatique 168


Solutions des exercices

clreol();
Procedure Affich(Var E:Etud); cprintf("%s",E.nom);
Begin gotoxy(29,9);
TextColor(White); clreol();
With E, Date_Nais Do cprintf("%s",E.prn);
Begin gotoxy(28,11);
Gotoxy(26,7); clreol();
Clreol; cprintf("%s",E.cin);
Write(Nom); gotoxy(40,13);
Gotoxy(29,9); clreol();
Clreol; cprintf("%d/%d/%d",E.date_nais.J,
Write(Prn); E.date_nais.M,E.date_nais.A);
Gotoxy(28,11); }
Clreol;
Write(CIN); void affichtout()
Gotoxy(40,13); {
Clreol; etudiant E;
Write(J,'/',M,'/',A); FILE*Fetud=fopen("Gestion","rb");
End; if (Fetud==NULL) return;
End; affich_formul("CONSULTATION");
do{
Procedure Affichtout; fread(&E,sizeof(etudiant),1,Fetud);
Var E:Etud; affich(E);
Rep:Char; textcolor(YELLOW);
I:Integer; gotoxy(45,17);
Begin cprintf("Tapez une Entree pour

ENS – Rabat – Département d’Informatique 169


Solutions des exercices

Assign(Fetud,'C:\Gestion'); continuer");
{$I-} getch();
Reset(Fetud); gotoxy(45,17);
{$I+} }while(!feof(Fetud));
If IOResult<>0 Then write('Probleme de lecture !!!!') fclose(Fetud);
Else }
Begin
Affich_formul('C O N S U L T A T I O N'); void main()
Repeat {
Read(Fetud,E); ajout() ;
Affich(E); affichtout() ;
TextColor(Yellow); clrscr() ;
Gotoxy(45,17); getch() ;
Write('Taper une touche pour continuer'); }
Rep:=readkey;
Gotoxy(45,17);
Clreol;
Until EOF(Fetud);
Close(Fetud);
End;
End;
BEGIN
Ajout;
Affichtout;
ClrScr;
Readln;

ENS – Rabat – Département d’Informatique 170


Solutions des exercices

END.
Exercice 100
Ecrire une procedure qui permet de modifier les informations d’un etudiant
Procedure Modif; void modif()
Var N: Integer; {
E:Etud; int i;
Begin char*CIN;
Assign(Fetud,'C:\Gestion'); char nom[20],prn[20],cin[10];
{$I-} int J,M,A;
Reset(Fetud); etudiant E;
{$I+} etudiant *Et;
If IOResult<>0 Then write('Probleme de lecture !!!!') FILE*Fetud=fopen("Gestion","rb");
Else FILE*f=fopen("tmptmp.$$","wb");
Begin textcolor(YELLOW);
ClrScr; textbackground(BLUE);
Write('Donner le numero d''ordre de l''etudiant a clrscr();
modifier'); if(Fetud==NULL) return;
readln(N); cprintf("Donnez le C.I.N de l'etudiant a modifier:
Seek(Fetud,N-1); ");
Read(Fetud,E); scanf("%s",CIN);
With E do getch();
Begin i=fread(&E,sizeof(etudiant),1,Fetud);
Write('Nom : ',Nom); while((strcmp(E.cin,CIN))&&(i!=0)){
Readln(Nom); fwrite(&E,sizeof(etudiant),1,f);
Write('Pr‚nom : ',Prn); i=fread(&E,sizeof(etudiant),1,Fetud);
Readln(Prn); }

ENS – Rabat – Département d’Informatique 171


Solutions des exercices

Write('C.I.N : ',CIN); if(!strcmp(E.cin,CIN)){


Readln(CIN); etudiant
End; *Et=(etudiant*)malloc(sizeof(etudiant));
Seek(Fetud,N-1); cprintf("Nom : %s ",E.nom);
Write(Fetud,E); scanf("%s",nom);
Close(Fetud) strcpy(Et->nom,nom);
End; cprintf("Prenom : %s ",E.prn);
End; scanf("%s",prn);
strcpy(Et->prn,prn);
cprintf("C.I.N : %s ",E.cin);
scanf("%s",cin);
strcpy(Et->cin,cin);
getch();
cprintf("Date de naissance :%d/%d/%d
",E.date_nais.J,E.date_nais.M,E.date_nais.A);
scanf("%d",&J);printf("/");Et-
>date_nais.J=J;
scanf("%d",&M);printf("/");Et-
>date_nais.M=M;
scanf("%d",&A);Et->date_nais.A=A;
fwrite(Et,sizeof(etudiant),1,f);
}
i=fread(&E,sizeof(etudiant),1,Fetud);
while(i!=0){
fwrite(&E,sizeof(etudiant),1,f);

ENS – Rabat – Département d’Informatique 172


Solutions des exercices

i=fread(&E,sizeof(etudiant),1,Fetud);
}
fclose(f);
fclose(Fetud);
remove("Gestion");
rename("tmptmp.$$","Gestion");
}

ENS – Rabat – Département d’Informatique 173


Annexe

GESTION DE L’ÉCRAN

Les fonctions de gestion de l’écran sont les mêmes en C et en Pascal. Vous


aurez, en ce qui suit, une brève description des instructions les plus
courantes.
Remarque :
En C, toutes ces fonctions se trouvent dans la bibliothèque conio.h

I. Notion de fenêtre
On peut définir une fenêtre dans un écran. L’écran actif sera réduit à cette
fenêtre.
WINDOW(x1,y1,x2,y2) où :
• x1 et y1 représentent les coordonnées du coin supérieur gauche de la
fenêtre.
• x2 et y2 représentent les coordonnées du coin inférieur droit de la
fenêtre.

II. Gestion du curseur


• L’instruction Gotoxy(x,y) positionne le curseur sur le point de
coordonnées (x,y) de la fenêtre active.
• La fonction WhereX retourne la colonne où se trouve le curseur.
• La fonction WhereY retourne la ligne où se trouve le curseur.

III. Instructions de gestion de l’écran


• ClrScr : efface la fenêtre active et positionne le curseur au point de
coordonnées (1,1).
• ClrEol : efface les caractères se trouvant après la position du curseur
jusqu’à la fin de la ligne.
• DelLine : élimine la ligne pointée par le curseur et déplace toutes les
lignes suivantes vers le haut. La dernière ligne devient vide.
• InsLine : insère une ligne vide à la place du curseur et décale les
lignes suivantes vers le bas. La dernière ligne sera perdue.

ENS – Rabat – Département d’Informatique 174


Annexe

IV. Instructions de gestion des couleurs


• TextColor(couleur) : définit la couleur du texte (16 couleurs codées de
0 à 15).
• TextBackGround(couleur) : défint la couleur du fond du texte (8
couleurs codées de 0 à 7).
Le tableau suivant présente les 16 couleurs existantes pour l’écriture du
texte :

Couleu
N° N° Couleur N° Couleur N° Couleur
r
0 Noir 4 Rouge 8 Gris foncé 12 Rouge clair
1 Bleu 5 Magenta 9 Bleu clair 13 Magenta
2 Vert 6 Brun 10 Vert clair 14 Jaune
3 Cyan 7 Gris clair 11 Cyan clair 15 Blanc

ENS – Rabat – Département d’Informatique 175


Conclusion

CONCLUSION

En conclusion, le langage Pascal reste le plus adapté à l’enseignement


d’algorithmique pour les élèves de l’enseignement secondaire ou pour les
débutants en algorithmique.

Malgré sa performance parfois supérieure à celle de Pascal, C est plutôt


destiné à des utilisateurs avertis (école d’ingénieurs, etc.).

Malgré le nombre très important d’exercices et leur diversité, on pourrait


prévoir quelques problèmes de synthèse tels que les Tours de Hanoi,
problèmes complets de système (gestion de stock, etc.), gestion très poussée
de l’écran avec par exemple un menu déroulant, etc.

On pourrait aussi suggérer pour les promotions à venir de compléter les


solutions proposées par une analyse du problème consistant à mettre en
évidence les données du problème et leurs types, ainsi les principales actions
à réaliser pour calculer les données de sortie (résultats) en partant des
données d’entrée.

ENS – Rabat – Département d’Informatique 176


Références

RÉFÉRENCES

 Programmer en langage C Claude Delanoy .

 Turbo Pascal manuel de l’utilisateur version 5.0 .

 Algorithmique : cours et exercices méthodologiques corrigés Guy


CHATY & Jean VICARD.

 Turbo Pascal et ses fichiers (version 3) : Jacques BOISGONTIER &


Christophe DNAY.

 Manuel d’Algorithmique réalisé par Mr LAMHARCHI Brahim.

ENS – Rabat – Département d’Informatique 177