Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Pascal - Les blocs, la portée
(Article écrit par Olivier Garrigues et extrait d'Amiga News Tech - février 1992)
|
|
De nouveau du Pascal ! Ceux qui ont cru que le simple article du mois dernier
expliquait tout du Pascal se trompaient lourdement.
L'article d'aujourd'hui se décompose en deux parties : la première sera essentiellement théorique et portera sur
l'architecture des blocs. La seconde continuera l'exploration du compilateur PCQ et sera beaucoup plus pratique.
Les blocs
Le Pascal est un langage structuré : tout ce qui le compose obéit à une forme syntaxique. L'architecture
principale d'un programme est basée sur le bloc (nous en avons vu un le mois dernier). Il existe différentes
sortes de blocs qui disposent chacune de propriétés propres.
La forme générale d'un bloc est un en-tête, suivie d'une zone de déclarations locales et d'un segment
d'instructions. L'en-tête se divise lui-même en un mot introductif qui indique le type du bloc (à ne
pas confondre avec les types de variables), suivi d'un identificateur qui sera le nom donné au bloc pour
de futures utilisations et, éventuellement, d'autres informations comme les passages de paramètres (ordre
et sens). Il se termine par un point-virgule.
La déclaration locale est la zone qui permet de définir de nouveaux objets (par l'intermédiaire d'autre blocs)
connus exclusivement du bloc courant. Le segment d'instructions, lui, est toujours le couple "BEGIN... END."
Tous les blocs ont nécessairement un en-tête. Le premier mot d'un bloc (et de son en-tête) est celui qui
définira son type.
PROGRAM indique, je l'ai déjà expliqué, le bloc programme. Il ne doit apparaître qu'une seule fois
dans tout le listing. Dans le fichier qui le contient, il doit être le plus grand bloc, c'est-à-dire que tous les
autres blocs doivent se trouver dans sa zone de déclarations locales.
EXTERNAL définit un bloc externe qui permet de ne pas associer des procédures et des fonctions à un
programme sans créer d'erreur de compilation. Le fichier objet obtenu est nommé une "bibliothèque", qu'il ne faut
pas confondre avec les ".library" d'Exec qui, elles, doivent être ouvertes pour pouvoir être utilisées. Celles
construites à l'aide d'un bloc externe sont utilisées avec l'éditeur de liens évitant la compilation répétée d'une
partie d'un programme. Je ne cite ici ce bloc que pour des raisons d'exhaustivité, nous l'étudierons en détails
dans un autre article.
Les points communs de ces deux blocs, sont qu'ils sont uniques dans un fichier, qu'ils ne peuvent se contenir
mutuellement, et qu'ils contiennent tous les autres blocs dans leur zone de déclarations locales (j'insite car
ceci est très important). A l'opposé d'un bloc programme, le bloc externe ne possède pas de nom, et n'a pas de segment
d'instructions.
VAR (que nous avons déjà vu), permet de déclarer un bloc (ou plusieurs blocs) de déclarations de variables.
CONST déclare des constantes (qui ne changent pas de valeur tout le long du programme) mais aussi, des variables
qui possèdent une valeur par défaut. Pourquoi avoir mis ce type de variables dans "constantes" ? Afin de respecter
une décision de Borland dans le Turbo Pascal (ils en sont à la version 6) tenant de la syntaxe de la déclaration.
Nous y reviendrons, alors patience.
TYPE permet de construire des types nouveaux avec les quelques types de bases et des constructeurs de
types tels que ARRAY, RECORD (voir plus loin). Le point commun de ces trois blocs est qu'ils ne sont composés
que d'un en-tête ; ils n'ont ni zone de déclarations locales, ni segment d'instructions.
PROCEDURE et FUNCTION sont les déclarateurs de blocs procéduraux. Le premier déclare une procédure
et l'autre une fonction (avouez que vous ne l'aviez pas trouvé). Une fonction est simplement une procédure qui
renvoie un objet. Il faut donc préciser son type. Nous verrons comment il faut s'y prendre. Ce type de blocs
possède les trois zones : un en-tête (pour définir son nom, l'ordre des arguments et leur type pour l'appel),
une zone de déclarations locales, et un segment d'instructions.
En fait, nous avons six en-têtes différents pour cinq types de blocs. Ce qu'il faut bien comprendre est que
cette structuration permet de créer des blocs dans d'autres blocs, comme des boîtes qui contiendraient d'autres
boîtes plus petites. Ainsi, certaines de ces boîtes nous seraient cachées ou accessibles suivant l'endroit où
l'on travaille (effet de localité).
Un exemple, toujours très formel (ce n'est pas la partie théorique pour rien), pour ceux qui seraient perdus :
Remarquez que dans cet exemple, j'utilise le terme interne pour bien différencier la zone de déclarations locales
du programme et les zones de déclarations locales de chaque bloc procédural.
La portée
Tout objet qui a un nom possède une portée qui lui est associée, c'est-à-dire qu'à un certain moment, on ne pourra
plus l'utiliser. Pour qu'un objet (variable, type, procédure ou fonction) soit défini dans la zone où l'on veut le
référencer (en général, dans un segment d'instruction), il faut non seulement que sa déclaration soit située plus
haut dans le texte, mais aussi dans un bloc qui contient (par emboîtements successifs) le bloc où l'on travaille.
Un petit exemple, commenté au-delà du raisonnable, ne fera pas de mal.
Nouvelles procédures
Bon, finie la théorie, passons à la pratique. Je vous avais laissé un petit devoir (tiens, plus personne ne me regarde...).
La spécification était : "saisie de l'âge d'une personne, ainsi que l'année de sa naissance sur l'entrée standard pour
calculer approximativement l'année actuelle, le tout très familièrement". Le but de ce programme était de vous présenter
mister READLN, dont voici la fiche signalétique :
READLN()
- Syntaxe : READLN (var1, var2, ..., varN)
- Type : procédure multiparamètres
- Spécification : identique à celle de READ, mais avec un retour-chariot après saisie de toutes les variables paramètres
Pour comprendre READLN, il faut connaître READ.
READ()
- Syntaxe : READ (var1, var2, ..., varN)
- Type : procédure multiparamètres
- Paramètres : variables du type integer, real, string ou array of char.
- Spécification : lit sur l'entrée standard (généralement le clavier) ou, si var1
est du type file, dans le fichier désigné par var1, une séquence de caractères, puis fait
la conversion suivant le type de la variable en cours de saisie. L'ordre de saisie est de la gauche vers la
droite, et il faut séparer les entrées par des espaces. Enfin, un écho à l'écran est fait si la saisie
passe par le clavier.
Vous pouvez observer que d'autres types de variables peuvent être utilisés avec READ() ou READLN().
Ceux-ci seront expliqués plus tard.
L'implémentation fournie par PCQ pour READ() n'est pas tout à fait standard. READ() demande toujours que
tous ses arguments soient séparés par un blanc, d'où certains effets indésirables, que montre l'exemple suivant.
Pour pouvoir saisir les deux nombres, il faut les taper l'un derrière l'autre, séparés par un blanc. Par
contre, l'implémentation de READLN() est respectée, comme le montre ce petit programme :
Alors, READ() ou READLN() ? Pour ne pas avoir de surprises, je vous conseille READLN() quand vous utilisez
PCQ. Pour ceux qui utilisent d'autres compilateurs Pascal, testez-les avec le programme ci-dessus et faites-vous une idée.
Pour mémoire, voici la fiche signalétique des procédures WRITE() et WRITELN() :
WRITE()
- Syntaxe : WRITE (exp1, exp2, ..., expN)
- Type : procédure multiparamètres
- Paramètre : expX peut être une expression du type array of char, string, integer, booléen, réel
mais aussi des constantes string (par exemple "Hello boy") ou array of char (comme 'hello boy')
- Spécification : envoie sur la sortie standard (ou si var1 est du type "file of" dans le fichier désigné
par var1), les valeurs sous forme de chaînes de caractères, des paramètres restants.
WRITELN()
- Syntaxe : WRITELN (exp1, exp2, ..., expN)
- Type : procédure multiparamètres
- Paramètres : identiques à ceux de WRITE()
- Spécification : identique à WRITE(), mais avec ajout d'un retour-chariot après tous les paramètres.
Vous vous demandez peut-être à quoi correspond une variable de type "file of...".
En Pascal, on désigne un fichier par un nombre qui lui est propre (au même moment, un nombre ne désigne qu'un
et un seul fichier). L'entrée et la sortie standard sont aussi considérés comme des fichiers par Pascal
(et par AmigaDOS). Une variable de type "file of" peut recevoir ce nombre. Les procédures WRITE() et READ()
sont des procédures d'entrées-sorties générales qui ne se bornent pas au clavier et aux fenêtres (CLI ou Shell) ;
elles permettent des "accès disques" à travers les fichiers que l'on aura préalablement ouverts. Mais ceci est
une autre histoire.
Le mois prochain, si tout va bien, nous aborderons, pour la partie théorique, les mystérieux types prédéfinis
ainsi que les effets de bord et, dans la partie pratique, l'implémentation des chaînes de caractères (y a du boulot !).
|