Concu dans les annees 70, Pascal est un des premiers descendants d'Algol 60 a rencontrer un veritable succes, en particulier dans le domaine de l'Education. C'est ainsi que jusqu'au debut des annees 90, il sera le langage le plus utilise dans les universites. Un des avantages de Pascal est sa relative fiabilite, en particulier grace a un controle de types assez etendu. Il s'agit par ailleurs d'un langage imperatif classique avec la plupart des structures du genre, ce qui en fait un langage encore relativement utilise pour decrire des algorithmes, meme si, en pratique, l'avenement des langages orientes objets correspond au declin progressif du Pascal. Les eleves ayant deja utilise un langage imperatif n'auront en principe aucun probleme a comprendre la syntaxe du Pascal, ce cours est juste destine a exposer la formalisation.
1. Introduction
program nom_du_programme(input,output);
begin
________ ;
________ ;
________
end.
Les mots cles input et output designent les entrees et sorties standard (le clavier et l'ecran), c'est ici que l'on specifiera que l'on veut travailler sur des fichiers particuliers. Les mots reserves begin et end designent le debut et la fin d'un groupement logique (ici le corps du programme). Entre les deux, les lignes se terminent en principe par un point virgule sauf cas particuliers (comme la derniere ligne avant end). On signale au compilateur que l'on est arrive a la fin du programme par un point.
Les commentaires sont places entre les caracteres (* et *).
La declaration se fait avant le begin
signalant le debut du bloc logique, au debut du programme et de la facon suivante
:
var nom_de_la_variable : type_de_la_variable
;
Par exemple :
var i : integer ;
ou eventuellement une declaration multiple
:
var i,j : integer ;
x : real ;
On peut egalement declarer des constantes
au meme endroit dans le programme :
const PI=3.14159;
Cette fonctionnalite de Prolog rentre dans le cadre de l'accentuation du controle de types. La possibilite de definir ses propres types permet de limiter un certain nombre de bugs a la phase de compilation. La syntaxe est la suivante :4. Types enumeres
type mon_type = (type1,type2,type3,...);
(* cette ligne se place avant la declaration
des variables *)
Par exemple, on peut definir un type couleur :
type couleur = (rouge,jaune,bleu,vert,gris);
var col : couleur;
Les types enumeres permettent ensuite
de faire un certain nombre d'operations basees sur l'ordre de la declaration.
Dans notre exemple, le compilateur affecte un numero a chaque couleur. La
couleur 0 est rouge, la couleur 1 est bleu, ainsi de suite...
D'ou les resultats suivants :
- ord(col) donne son ordre dans l'enumeration
(si col = bleu, ord(col) = 2)
- pred(col) donne l'element precedent
dans l'enumeration (si col = bleu, pred(col) = jaune)
- succ(col) donee le successeur dans l'enumeration
(si col = bleu, succ(col) = vert)
Il est egalement possible de definir des sous-types :
type couleurs_froides = bleu..gris;
On declare les tableaux de la facon suivante :5. Tableaux et chaines de caracteres
type tableau = array[1..50] of integer;
pour un tableau de 50 entiers qu'il faudra ensuite instancier :
var mon_tableau : tableau;
On accede alors a son i-eme element de la facon suivante : cetab[i].
Les chaines de caracteres sont creees de la meme facon, en utilisant le mot reserve packed qui indique que les differents caracteres du tableau sont groupes :
type mot = packed array [1..10]
of char;
var mot1 = mot;
La declaration de matrices necessite juste l'ajout d'une dimension :
type matrice = array[1..10,1..10]
of integer; (* pour une matrice de 100 entiers. *)
Les structures sont realisees en utilisant une declaration de type avec le mot record. Imaginons une structure personne contenant le prenom et l'age d'un individu :6. Structures
type personne = record
prenom : mot;
age : integer;
end;
var jean : personne;
(* pour cet exemple, il faut bien
entendu avoir declare le type mot avant *)
On accede ensuite aux differents
champs de deux manieres differentes :
- par un point : jean.prenom =
'jean '; (* on rajoute des espaces pour arriver aux 10 caracteres requis
par la structure mot *)
jean.age
= 20;
- par le mot with :
with jean do
prenom = 'jean
';
age = 20;
end;
Elles sont declarees au debut du programme. Une procedure realise une partie d'un programme alors qu'une fonction est destinee a renvoyer une variable.7. Procedures et fonctions
program nom_du_programme(input,output);
var_______;
procedure proc(i:integer,lettre:char);
var _____;
begin
________ ;
________ ;
________
end;
function fonc(i,j:integer)
: integer; (* declare que la sortie de la fonction est un entier *)
var _____;
begin
________ ;
________ ;
fonc := ________
(* la derniere ligne indique la valeur a renvoyer en instanciant fonc
*)
end;
begin
(* on retrouve ici le bloc logique correspondant au programme
principal *)
________ ;
________ ;
________
end.
Les commandes de lecture et d'ecriture sont :8. Entrees/Sorties
Pour utiliser un fichier, il faut le declarer au debut du programme - il s'agit d'une variable a part entiere :
program nom_du_programme(input,fichier);
var fichier : file of char; (* On peut aussi utiliser le mot text
a la place de file of char *)
Par la suite, les commandes
sont differentes suivant que l'on veuille utiliser le fichier en lecture ou
en ecriture :
reset(fichier,nom_du_fichier); prepare la lecture.
rewrite(fichier,nom_du_fichier); prepare l'ecriture.
Ne pas confondre les deux arguments : le premier est de type file
et designe le fichier lui-meme, le second est de type string (ou
packed array of char) et designe juste le nom
du fichier. Enfin, on utilise write/writeln/read/readln comme precedemment,
en mentionnant simplement le fichier en premier argument :
writeln(fichier,'La valeur de l'entier
i est ',i);
Les caracteres speciaux EOLN (end of line) et EOF (end of file) sont souvent
utiles dans la lecture de fichiers. Enfin, pour fermer un fichier, on utilise
l'instruction :
close(fichier);
9. Boucles et branchements conditionnels
Les instructions decrites ici sont typiques des langages imperatifs. Elles ne presentent donc aucune difficulte de comprehension particuliere.
if cond then
(* Dans la condition cond, on peut utiliser les operateurs de comparaisons
standard : =, <> (different), >, <, >= et <= *)
begin
________ ;
________ ;
________
end
else
begin
________ ;
________ ;
________
end;
Pour eviter l'imbrication de multiples blocs logiques if, on utilise parfois l'instruction case (qui dirige en fonction de la valeur d'une variable, dans notre exemple, un entier i) :
case i of
1 : ________; (* Noter l'absence de begin *)
2 : ________;
3 : ________;
N : ________;
else (* Contrairement a ce que j'ai
dit en cours, la derniere condition est introduite par else dans la plupart
des *)
___________ (* versions de Pascal et non par otherwise
*)
end;
Enfin, on retrouve egalement les boucles classiques :
for i := 1 to N
do while cond do
begin
begin
________ ;
________ ;
________ ;
________ ;
________
________
end;
end;
Par rapport a la question qui m'a ete posee en cours, dans la boucle for, l'incrementation de i est automatique (et d'une unite) a chaque tour de boucle mais il est possible de faire des operations sur la variable i a l'interieur de la boucle. Ainsi, placer l'instruction i := i +1 juste avant le end aura pour effet de ne faire tourner la boucle que pour les i impairs, par exemple.
10. Pointeurs
Cette section est un complement par rapport a ce que j'ai dit en cours et une rapide introdution aux pointeurs. Comme en C, un pointeur designe une adresse qui indique ou dans la memoire trouver la variable. Ainsi, on declare de la facon suivante un pointeur sur un entier :
type pointeur = ^integer;
var ptr : pointeur;
Ensuite, on l'utilise dans le programme en l'initialisant par new et en le detruisant par dispose :
begin
new(ptr);
ptr^ := 10; (* Pour acceder a l'entier pointe *)
________;
________;
dispose(ptr)
end.
Le pointeur
nul s'ecrit nil.
Ces bases devraient vous suffire pour comprendre un programme simple ecrit
en Pascal.
Pour toutes questions ou remarques, n'hesitez pas :
rigouste@site.uottawa.ca
.