Archive

Archives pour la catégorie ‘Turbo Pascal’

Turbo Pascal – Les pointeurs

This entry is part 22 of 24 in the series Turbo Pascal - Tutoriel

Un peu comme les langages C et C++, le Turbo Pascal permet d’acceder à la memoire et aux variables par le biais
de ce que l’on appelle les pointeurs.
Cependant, la syntaxe des pointeurs en Pascal reste rudimentaire et peu maniable.

Mais commençons par définir ce qu’est un pointeur. Un pointeur est une variable qui contient l’adresse memoire
d’une autre variable.
Et oui, parce qu’une variable n’est rien d’autre qu’un emplacement reservé dans la mémoire de l’ordinateur. Le
pointeur va alors pointer sur cet emplacement de mémoire.
En Pascal, les pointeurs sont typés selon le type de la variable qu’ils doivent pointer.
Par exemple, si ils doivent pointer sur une variable du type Integer, il seront du type Integer.

Pour déclarer une variable du type pointeur, on utilise l’opérateur ^ (accent circonflexe), suivi du
type de la variable.
Par exemple :

var Pointeur : ^Integer;{Un pointeur sur une variable Integer}

Il est egalement possible d’utiliser la syntaxe suivante, qui peut être un passage obligatoire dans certains
cas :

Type PInteger = ^Integer;

var Pointeur : PInteger;

Ensuite, on accede au contenu, c’est à dire à la variable pointée, en utilisant le même opérateur (^),
mais cette fois ci, en le placant derière le nom de la variable :

var Pointeur : ^Integer;

begin
writeln(Pointeur^);{Le contenu de la variable pointee}
end.

À ce stade là, la valeur renvoyée est arbitraire car elle dépend du contenu de la mémoire, vu que le pointeur
n’a pas été initialisé. En effet, il pointe sur un emplacement de la mémoire non-determiné.
Nous allons maintenant ajouter une nouvelle variable du type Integer (c’est à dire du type que
le pointeur doit pointer) que nous appelerons Entier et faire pointer notre variable Pointeur
sur celle-ci.
Pour ce faire, on utilise l’opérateur @ (aroba) pour affecter l’adresse mémoire de notre nouvelle variable
au pointeur.
Attention! Ici, nous n’accedons pas au contenu mais à l’adresse. Il ne faut donc pas
utiliser l’operateur ^.

varPointeur : ^Integer;
Entier : Integer;

begin
Pointeur := @Entier;{On fait pointer Pointeur sur Entier}
Entier := 45;{On affecte 45 à Entier}
writeln(Pointeur^);{Sortie -> 45}
end.

La dernière ligne affiche 45. C’est tout à fait normal, puisque nous avons modifier le contenu
pointé par Pointeur, c’est à dire la variable Entier.
Mais ce comportement ne nous est pas inconnu : rappellez vous des procedures capables de modifier le contenu
d’une variable passée en argument, pour peu que l’on utilise le mot-clef var. Et oui, il s’agit
aussi de pointeurs. Seulement, le Pascal, un peu comme le Basic mais dans de moindres mesures, tente de nous les
dissimuler pour simplifier au maximum le langage.
Bien sur, ça marche aussi en sens inverse :

varPointeur : ^Integer;
Entier : Integer;

begin
Pointeur := @Entier;{On fait pointer Pointeur sur Entier}
Pointeur^ := 45;{On affecte 45 à Pointeur^}
writeln(Entier);{Sortie -> 45}
end.

Simple question : que ce serait-il passé si au lieu du type Integer, on avait utiliser le type
Real pour Entier?
Le résultat aurait bien entendu pas été inattendu, vu que le codage des variables n’est pas le même. Si dans
la pratique, une variable du type Integer peut parfaitement être pointée par un pointeur du type
LongInt, il est preferable d’eviter ce genre de pratique. En effet, que faire d’une variable du type
String pointée par un Real?

Si on veut neutraliser un pointeur à un moment donné, il faut affecter la valeur NIL à son adresse :

Pointeur := NIL;{Neutralisation}

Ainsi, le pointeur ne pointe sur plus rien de précis, comme au départ.

Categories: Turbo Pascal Tags:

Turbo Pascal – Les objets

This entry is part 23 of 24 in the series Turbo Pascal - Tutoriel
  1. Le type OBJECT
  2. Heritage et genetique
  3. Constructeurs, destructeurs et méthodes virtuelles
  4. Methodes et propriétés privées

Dans ses premières versions, le Turbo Pascal était un langage dit traditionnel : les données étaient transmises
à un ensemble de fonctions et procédures, lesquelles se chargaient de les controler, et le cas écheant, de les modifier.
Puis au fil du temps, le langage a subit la même évolution que l’on pu observer du C au C++ : les
objets sont apparus.
En programmation orientée objet, ce sont les données qui possédent des procédures et des fonctions. Ces procédures
et fonctions (alors appelées methodes) operent sur l’objet dont elles dépendent.
Cependant, il ne faut pas croire que cela fait de Turbo Pascal un vrai langage orienté objet, comme peut l’être
Java. Il faut plutôt l’entendre dans le même sens que l’orientation objet de C++ (c’est à dire un peu, mais pas
completement).

Le type OBJECT

Comme pour une variable classique, un objet est toujours d’un type bien particulier. Dans le cas particuler
de la programmation orientée objet, on dit alors que le type est une classe, et que la variable est un
objet ou une instance de cette classe.

Pour créer une classe, il faut créer un Type du type OBJECT :

TypeTObjet = OBJECT
{propriétés}
{methodes}
end;

TObjet represente le nom de la classe. Les propriétés sont en fait des champs, comme pour les
types RECORD (voir page précedente).
Imaginons que nous voulions ecrire un programme ayant pour but de gerer un stock de velo. Chaque velo poura
être caractèrisé par plusieurs propriétés comme : la marque, le modéle, la taille, le prix.
On peut alors créer un type TVelo tel que celui-ci :

TypeTVelo = OBJECT
Marque : String;
Modele : String;
Taille : Byte;
Prix : Integer;
end;

Jusqu’ici, rien de nouveau par rapport au type RECORD.
Mais ce n’est pas tout : cette classe TVelo va aussi posseder un ensemble de méthodes. Nous allons
tous d’abord créer la méthode Bapteme qui va permetre d’initaliser les propriétés Marque, Modele,
Taille et Prix.
Pour ajouter une méthode à une classe, on déclare son prototype (c’est à dire la premiere ligne du bloc)
juste après la déclaration de ses propriétés :

TypeTVelo = OBJECT
Marque : String;
Modele : String;
Taille : Byte;
Prix : Integer;
procedure Bapteme(aMarque, aModele : String;
aTaille : Byte; aPrix : Integer);
end;

Ensuite, on va créer une procédure TVelo.Bapteme où l’on écrira le code. Les propriétés de l’objet
sont directement accessibles. On peut cependant utiliser le parametre self qui permet de faire reference
à l’objet (par exemple, ecrire self.Marque au lieu de Marque).

procedure TVelo.Bapteme(aMarque, aModele : String; aTaille : Byte; aPrix : Integer);
begin
Marque := aMarque;{Affectation des arguments aux propriétés}
Modele := aModele;
Taille := aTaille;
Prix := aPrix;
end;

Et voila, le tour est joué! Il ne reste plus qu’a créer une variable du type TVelo, et d’utiliser ces methodes
et propriétés.
Pour appeler une méthode d’un objet, il suffit d’écrire son nom à la suite de l’objet, en ayant bien pris soin
d’interposer l’opérateur . (le point).
Voici le code complet :

TypeTVelo = OBJECT
Marque : String;
Modele : String;
Taille : Byte;
Prix : Integer;
procedure Bapteme(aMarque, aModele : String;
aTaille : Byte; aPrix : Integer);
end;

procedure TVelo.Bapteme(aMarque, aModele : String; aTaille : Byte; aPrix : Integer);
begin
Marque := aMarque;{Affectation des arguments aux propriétés}
Modele := aModele;
Taille := aTaille;
Prix := aPrix;
end;

var MonVelo : TVelo;{Une instance de la classe TVelo}

begin
MonVelo.Bapteme('SUNN', 'Asphalt +', 52, 6500);{Appel de la methode
Bapteme}

writeln('Marque : ', MonVelo.Marque);{Affichage des}
writeln('Modele : ', MonVelo.Modele);{propriétés}
writeln('Taille : ', MonVelo.Taille);
writeln('Prix   : ', MonVelo.Prix);
end.

Les méthodes d’un objets ne sont pas limitées au seules procédures. Il est egalement possible qu’une méthode
puisse renvoyer une valeur : il y a juste à déclarer une fonction (function).
Voici une nouvelle méthode, ainsi que la nouvelle déclaration du type TVelo :

TypeTVelo = OBJECT
Marque : String;
Modele : String;
Taille : Byte;
Prix : Integer;
procedure Bapteme(aMarque, aModele : String;
aTaille : Byte; aPrix : Integer);
function EstAlaTaille(TEJ : Real) : Boolean;
end;

function TVelo.EstAlaTaille(TEJ : Real) : Boolean;
begin
{Cette methode renvoi TRUE si le velo est à la taille (avec
toutes fois une certaine tolérance) suivant la valeur de TEJ
qui represente la taille de l'entrejambe}

If (Taille > TEJ * 0.60) And (Taille < TEJ * 0.70) Then
EstAlaTaille := true
Else
EstAlaTaille := false;
end;

Heritage et genetique

Là où les objets deviennent encore plus interessants, c'est lorsqu'on commence à créer des objets "hybrides".
Créons par exemple une classe THomme, telle que celle ci :

Type THomme = OBJECT
Nom : String;
Prenom : String;
Age : Byte;
procedure Bapteme(aNom : String; aPrenom : String;
 aAge : Byte);
end;

procedure THomme.Bapteme(aNom : String; aPrenom : String; aAge : Byte);
begin
Nom := aNom;
Prenom := aPrenom;
Age := aAge;
end;

Maintenant, nous allons créer une autre classe qui descendra de cette même classe THomme. Par exemple,
une classe TPompier. Cette classe va heriter de toutes les propriétés et methodes de son ancetre
(dans notre cas Nom, Prenom, Age et Bapteme).
Pour réaliser cette manipulation genetique, il suffit de passer le nom de la classe parent (THomme)
entre parenthèses, après le mot-clef OBJECT de la déclaration de la classe enfant (TPompier) :

Type THomme = OBJECT
Nom : String;
Prenom : String;
Age : Byte;
procedure Bapteme(aNom : String; aPrenom : String;
 aAge : Byte);
end;

TPompier = OBJECT(THomme){Classe descendante de THomme}
(* Pour l'instant, aucune propriété *)
(* ni méthodes *)
end;

procedure THomme.Bapteme(aNom : String; aPrenom : String; aAge : Byte);
begin
Nom := aNom;
Prenom := aPrenom;
Age := aAge;
end;

var SoldatDuFeu : TPompier;
begin
With SoldatDuFeu Do
begin
Bapteme('FONEBONE', 'Stephano', 25);
writeln('Nom    : ', Nom);
writeln('Prenom : ', Prenom);
writeln('Age    : ', Age);
end;
end.

Comme prevu, toutes les propriétés et méthodes énoncées plus haut sont belles et biens disponibles.
Mais ce n'est pas tout : vu qu'un pompier est (beaucoup :-D ) plus qu'un homme, nous allons un petit peu le personaliser.
Ajoutons, pour commencer, la propriété Grade :

TPompier = OBJECT(THomme)
Grade : String;
d;

Cette propriété Grade ne sera accessible qu'avec les objets issus de la classe TPompier, et
non de la classe parente THomme.
Mais voila que maintenant, nous aimerions pouvoir initaliser cette même propriété lors de l'appel de la méthode
Bapteme. Or, cette méthode, telle qu'elle est en ce moment, ne permet pas une telle action.
Nous allons donc la redefinir dans l'objet TPompier :

Type THomme = OBJECT
Nom : String;
Prenom : String;
Age : Byte;
procedure Bapteme(aNom : String; aPrenom : String;
 aAge : Byte);
end;

 TPompier = OBJECT(THomme)
Grade : String;
procedure Bapteme(aNom : String; aPrenom : String;
 aAge : Byte; aGrade : String);
end;

procedure THomme.Bapteme(aNom : String; aPrenom : String; aAge : Byte);
begin
Nom := aNom;
Prenom := aPrenom;
Age := aAge;
end;

procedure TPompier.Bapteme(aNom : String; aPrenom : String;
aAge : Byte; aGrade : String);
begin
inherited Bapteme(aNom, aPrenom, aAge);
Grade := aGrade;
end;

var SoldatDuFeu : TPompier;
begin
With SoldatDuFeu Do
begin
Bapteme('FONEBONE', 'Stephano', 25, 'Sergent Chef');
writeln('Nom    : ', Nom);
writeln('Prenom : ', Prenom);
writeln('Age    : ', Age);
writeln('Grade  : ', Grade);
end;
end.

Et voici que nous faisons intervenir un element nouveau : inherited. inherited permet
d'appeler une méthode appartenant à l'objet parent. Ici, nous appelons la méthode Bapteme de l'objet
THomme, qui nous permet d'initialiser les trois premières propriétés. Ensuite, nous assignons
la valeur transmise à la propriété Grade. Ainsi, le travail devient plus facile.

Constructeurs, destructeurs et méthodes virtuelles

Comme pour les variables, on peut affecter la valeur d'un objet à un autre objet.
Prenons un exemple :

typeTPapa = OBJECT
Place : String;
procedure QuiSuisJe;
end;

TFils = OBJECT(TPapa)
Prop : String;
procedure QuiSuisJe;
end;

procedure TPapa.QuiSuisJe;
begin
writeln('Je suis le papa');
end;

procedure TFils.QuiSuisJe;
begin
writeln('Je suis le fils');
end;

varPapa : TPapa;
Fils : TFils;

begin
Papa.Place := 'Papa';
Fils.Place := 'Fils';
Fils.Prop := 'Propriété spécifique à Fils';
writeln(Papa.Place);{Sortie -> Papa}
Papa.QuiSuisJe;{Sortie -> Je suis le papa}
Papa := Fils;{Affectation de Fils à Papa}
writeln(Papa.Place);{Sortie -> Fils}
Papa.QuiSuisJe;{Sortie -> Je suis le papa}
end.

Comme on peut le remarquer dans cet exemple, seules les propriétés d'un objet sont affectées dans ce type d'opération. Les méthodes ne sont pas
"échangées", comme le prouve la ligne Papa.QuiSuisJe qui est donc toujours une méthode de la classe TPapa, et non de la
classe TFils (sinon, nous aurions eu comme résultat : Je suis le fils).

Vous remarquez que nous avons affecté l'objet descendant (Fils) à l'objet ascendant (Papa). L'inverse est impossible :
seules les classes descendantes peuvent être affectées à des classes parentes (pléonasme volontaire, afin de bien souligner la chose :-) ).

De plus, les precisions apportées à la classe heritière (ici, le champ Prop de la classe TFils) ne sont pas transmises.
Ainsi, si le code suivant provoque une erreur :

writeln(Papa.Prop);{ERREUR : Field Indentifer Excepted}

Mais alors comment faire si on veut pouvoir échanger les méthodes de deux objets lors d'une telle opération ?
Il faut utiliser des objets dynamiques, et des méthodes virtuelles. Pour cela, nous allons retrouver les pointeurs, que nous avons
déjà abordé dans des sections antérieures.

Nous allons tout d'abord rajouter le mot-clef virtual derrière la déclaration des procédures dans les classes, afin de rendre la méthode
QuiSuisJe virtuelle.
Une méthode virtuelle n'est liée à un objet qu'au moment de l'execution, et non lors de la compilation. On dit alors que la ligature est dynamique,
car non figée une fois pour toutes à un seul et unique objet. Et c'est precisement l'effet que nous recherchons dans notre cas.

Ensuite, nous allons devoir déclarer un constructeur. Un constructeur est tout simplement une méthode qui doit être appelée avant d'utiliser
l'objet auquel elle appartient. Même si cette méthode ne produit rien de particulier, elle doit tout de même exister.
Dans notre cas, elle initalisera la propriété Place avec Fils ou Papa dans le cas approprié.
Un constructeur se déclare avec le mot-clef constructor devant son identificateur. Il peut prendre des arguments si besoin est.

Puis enfin, pour créer un objet dynamiquement, il faut déclarer un pointeur vers cet objet, et utiliser la procedure New. New demande
2 arguments : le premier est le pointeur vers l'objet, et le deuxième est la méthode constructeur à appeler.
Notre exemple devient alors devient alors :

typeTPapa = OBJECT
Place : String;
constructor Init;
procedure QuiSuisJe; virtual;
end;

TFils = OBJECT(TPapa)
Prop : String;
constructor Init;
procedure QuiSuisJe; virtual;
end;

constructor TPapa.Init;
begin
Place := 'Papa';
end;

procedure TPapa.QuiSuisJe;
begin
writeln('Je suis le papa');
end;

constructor TFils.Init;
begin
Place := 'Fils';
Prop := 'Propriété spécifique à fils';
end;

procedure TFils.QuiSuisJe;
begin
writeln('Je suis le fils');
end;

varPapa : ^TPapa;
Fils : ^TFils;

begin
New(Papa, Init);
New(Fils, Init);
writeln(Papa^.Place);{Sortie -> Papa}
Papa^.QuiSuisJe;{Sortie -> Je suis le papa}
Papa := Fils;
writeln(Papa^.Place);{Sortie -> Fils}
Papa^.QuiSuisJe;{Sortie -> Je suis le fils}
Dispose(Papa);{Voir plus loin pour Dispose}
Dispose(Fils);{Idem}
end.

Et cette fois-ci, ça marche! Les méthodes ont bien été "échangées".
À l'opposé des constucteurs, on trouve les destructeurs. Les destructeurs sont chargés de détruire l'objet et de libérer la mémoire utilisée
par cet objet.
Les destructeurs sont déclarés à l'aide du mot-clef destructor. Ils doivent être appellés par la procédure Dispose qui possede une
syntaxe semblable à celle de New, à savoir le pointeur vers l'objet et la méthode destructrice.
Cependant, si la méthode ne possede pas de destructeurs, il est possible d'utiliser Dispose sans le deuxième argument, comme ce que
nous avons fait plus haut.

Methodes et propriétés privées

Au sein d'un module (c'est à dire au sein d'une unité ou d'un programme), il est possible de définir des méthodes et/ou des propriétés privées :-) .
Les méthodes et propriétés privées ne sont accessibles que par le module dans lequel la classe de l'objet est définie.
Ainsi, si on déclare une méthode privée MLambda dans une classe TLambda se trouvant dans l'unité ULambda, et
qu'on décide d'utiliser cette unité ULambda dans un programme PLambda, la méthode MLambda sera alors inaccessible.

Pour déclarer des élements privés, c'est simple : il suffit d'utiliser le mot-clef Private dans la déclaration de la classe.
Tout ce qui sera déclaré en dessous sera alos considéré comme privé :

TypeTLambda = OBJECT
Publique : String;{Elements dits publiques}
procedure PPublique;
PRIVATE
Prive : String;
procedure MLambda;{Elements privés}
end;
Categories: Turbo Pascal Tags:

Turbo Pascal – Les ensembles

This entry is part 24 of 24 in the series Turbo Pascal - Tutoriel

On a vu au départ que le langage Pascal a été conçu avant tout pour un usage scientifique et didactique. Il
permet, entre autres, une application directe de la theorie mathematique des ensembles.

Création d’un ensemble

Un ensemble peut être considéré comme un type à part entière de variable. On utilise les mots clefs Set Of,
suivi du type de variable qui sera contenu dans l’ensemble lors de la déclaration de la variable :

var Variable : Set Of type;

Le type doit être scalaire qui ne peut contenir que 256 valeurs et non signé, c’est à dire codé sur un octet
maximum. Les types valides peuvent donc être du type Char ou Byte, mais également
d’un type énuméré définit par le programmeur.
Voici des exemples de déclaration de type :

var ensA : Set Of Byte;

var ensB : Set Of Char;

type Jours = (Lun, Mar, Mer, Jeu, Ven, Sam, Dim);
var ensC : Set Of Jours;

Syntaxe

En math, les ensembles sont représentés graphiquement dans des sortes de cercles. Algebriquement, on les écrits
entre accolades :

A = {3, 7, 2, 5}

En Pascal, les accolades étant déjà utilisées pour les commentaires, ont utilise les crochets. L’ensemble
ci-dessus pourra s’écrire ainsi :

var A : Set Of Byte;

begin
A := [2, 3, 5, 7];
end.

Vous remarquez que l’ordre des elements de l’ensemble n’est pas le même. Cela n’a aucune importance car la
théorie des ensembles néglige cette ordre.
L’ensemble vide quand à lui s’écrit simplement :

vide := [];{ Ensemble vide }

Les opérations sur les ensembles sont les suivantes :

Operateur Nom
+ Union
- Difference (ou complement)
* Intersection
IN Inclus (elements)
= Equivalence
<> Different
<= Inclus (sous ensembles)
>= Contenu (sous ensembles)

Voici un exemple de programme :

program Ensembles;

var ensA, ensB, ensC : Set Of Byte;

begin
ensA := [1, 2, 3, 4, 5, 6, 7, 8, 9];{Nombres entiers naturels entre 1 et 9}
ensB := [1, 3, 5, 7, 9];{Nombres impairs}
ensC := [2, 4, 6, 8];{Nombres pairs}

If ensB + ensC = ensA Then
writeln('L''union de B et C equivaut à A');

If ensB * ensC = [] Then
writeln('Il n'' y a pas d''elements commun entre B et C');

If ensA - ensB = ensC Then
writeln('C est le complementaire de A');

If ensA - ensC = ensB Then
writeln('B est le complementaire de A');

If Not(10 IN ensA) Then
writeln('10 n''appartient pas à A');

If [] <= ensA Then
writeln('L''ensemble vide est sous ensemble de A');

If ensA >= ensB Then
writeln('A est sur-ensemble de B');
end.
Categories: Turbo Pascal Tags:

Turbo Pascal – Les maths

This entry is part 15 of 24 in the series Turbo Pascal - Tutoriel
  1. Opérateurs relationnels
  2. Méthodes de calcul
  3. Fonctions mathématiques
  4. La logique
    1. NOT
    2. AND
    3. OR
    4. XOR

Le Larousse definit ainsi le langage Pascal : Langage de programmation adapté au traitement
d’applications scientifiques
.

Cette afirmation fait du Pascal un langage riche en fonctions mathématiques.


Opérateurs relationnels


Les opérateurs relationnels permettent d’effectuer des comparaisons entre des variables, des
constantes…

































Opérateurs relationnels
Opérateur Fonction
= Egual
< Inférieur
> Supérieur
<= Inférieur ou égual
>= Supérieur ou égual
<> Différent


Méthodes de calcul


Des malheureses 4 opérations mathématiques que nous avons vu au départ, nous allons rajouter
c’est deux la :























Méthodes de calcul
Opérateur Fonction Exemple de code Résultat
MOD Modulo writeln(19 Mod 4); 3
DIV Division entière writeln(100 Div 3); 33


Fonctions mathématiques


Dans le tableau ci-dessous sont répertoriées les fonctions mathématiques du Turbo Pascal :





























































































































Fonctions mathématiques
Nom Fonction Exemple de code Résultat
Sin(x) Calcul du sinus (Radians) write(sin(0), sin(Pi)); 0 1
Cos(x) Calcul du cosinus (Radians) write(cos(0), cos(Pi)); 1 0
ArcTan(x) Renvoi la cotangente write(ArcTan(4)); .7853982
Sqr(x) Carré write(Sqr(5)); 25
Sqrt(x) Racine carré write(Sqrt(81)); 9
Exp(x) Eleve à une puissance népérienne write(Exp(0)); 1
Ln(x) Logarithme népérien write(Ln(1)); 0
Trunc(x) Tronque la partie entière write(Trunc(Pi)); 3
Int(x) Renvoi la partie entière write(Int(Pi)); 3,000…
Frac(x) Renvoi la partie fractionnaire (après la virgule) write(Frac(45.98765)); 0.98765
Round(x) Arrondi à l’entier le plus proche write(Round(28.7), Round(28.3)); 29 28
Pred(x) Renvoi le prédécesseur d’un nombre ordonné (entier) write(Pred(5)); 4
Succ(x) Renvoi le succésseur d’un nombre ordonné (entier) write(Succ(5)); 6
Odd(x) Renvoi true si le nombre est impair, false si pair write(Odd(3), Odd(2)); TRUE FALSE
Abs(x) Renvoi la valeur absolue write(Abs(-54)); 54
Pi Renvoi la constante Pi write(Pi); 3.14159265358…
Random(x) Renvoi un nombre aléatoire entre 0 et l’argument write(Random(10)); 5.7895415
Inc(x [, i]) Incrémente la variable de i si spécifié, ou de 1 par défaut Inc(MyVar); Inc(MyVar, 5);  
Dec(x, [, i]) Décrémente la variable de i si spécifié, ou de 1 par défaut Dec(MyVar); Dec(MyVar, 5);  


La logique


La logique est surtout utilisée dans les conditions, que se soit avec les boucles ou la structure
conditionnelle.

Le mieux, c’est de lire ceci : Maths appliquées

Il faut savoir que l’informatique ne reconnait que 2 états :

  • TRUE, quand c’est allumé

  • FALSE, lorsque c’est éteint


Lorsque l’on réalise une comparaison avec les opérateurs relationnels, l’ordinateur évalue en
fait l’expression à TRUE si elle se vérifie, et à FALSE dans les autres
cas.

Ainsi, on peut écrire des choses du style :

var blnVar : Boolean; {Une variable du type Boolean}

begin
blnVar := 78 > 35; {blnVar = TRUE}
blnVar := 78 < 35; {blnVar = FALSE}
write(5 = 5); {Affiche TRUE}
write(5 <> 5); {Affiche FALSE}
end.


Voici les opérateurs logiques du Turbo Pascal :

  • NOT : le NON logique. Il inverse le résultat : si FALSE devient TRUE
    et inversement.























    NON logique (NOT)
    Opérande Valeur renvoyée Exemple de code Résultat
    FALSE TRUE write(Not(False)); TRUE
    TRUE FALSE write(Not(True)); FALSE




  • AND : le ET logique. Il renvoi TRUE si et seulement si les deux
    opérandes sont TRUE.








































    ET logique (AND)
    Opérande1 Opérande2 Valeur renvoyée Exemple de code Résultat
    FALSE FALSE FALSE write(False And False); FALSE
    FALSE TRUE FALSE write(False And True); FALSE
    TRUE FALSE FALSE write(True And False); FALSE
    TRUE TRUE TRUE write(True And True); TRUE




  • OR : le OU logique. Il renvoi TRUE si au moins une des deux opérandes
    est à TRUE.








































    OU logique (OR)
    Opérande1 Opérande2 Valeur renvoyée Exemple de code Résultat
    FALSE FALSE FALSE write(False Or False); FALSE
    FALSE TRUE TRUE write(False Or True); TRUE
    TRUE FALSE TRUE write(True Or False); TRUE
    TRUE TRUE TRUE write(True Or True); TRUE




  • XOR : le OU exclusif logique. Il renvoi TRUE si une seule
    des deux opérandes est à TRUE.








































    OU exclusif logique (XOR)
    Opérande1 Opérande2 Valeur renvoyée Exemple de code Résultat
    FALSE FALSE FALSE write(False Xor False); FALSE
    FALSE TRUE TRUE write(False Xor True); TRUE
    TRUE FALSE TRUE write(True Xor False); TRUE
    TRUE TRUE FALSE write(True Xor True); FALSE




Categories: Turbo Pascal Tags:

Turbo Pascal – Le traitement du texte

This entry is part 16 of 24 in the series Turbo Pascal - Tutoriel
  1. Détail d’une chaîne de caractères
    1. Concat
    2. Copy
    3. Delete
    4. FillChar
    5. Insert
    6. Pos
    7. Str
    8. Val
  2. La table de caractères ASCII
  3. La casse
    1. StrUpper
    2. StrLower

On a vu comment afficher du texte avec write et writeln. Nous allons
maintenant voir comment formater ce texte.


Détail d’une chaîne de caractères


On a vu dans les variables qu’une chaîne de caractères est un tableau
du type char.

Ainsi, n’ayons pas peur d’écrire :

var MyTexte : array[1..5] Of Char; {Un tableau de Char}

begin
MyTexte[1] := ‘H’;
MyTexte[2] := ‘e’;
MyTexte[3] := ‘l’;
MyTexte[4] := ‘l’;
MyTexte[5] := ‘o’;
writeln(MyTexte); {Affichage du tableau comme si c’était une chaine}
end. {Sortie -> Hello}


Partant de ce principe, on peut facilement modifier n’importe quel caractère d’une chaîne, du
moment que l’on sait la longueur de la chaîne.

Car rappelons que l’on peut limiter la taille du chaîne de caractères à la déclaration. Si on
indique un index supérieur à sa longueur, une erreur se produit.

L’index 0 de la table correspond à la longueur de la chaîne de caractère. On peut ainsi écrire :

var MyTexte : String;

begin
MyTexte := ‘Bonjour le Web!’;
MyTexte[0] := Chr(7); {La chaîne ne fait plus que 7 caractères}
writeln(MyTexte); {Sortie -> Bonjour}
end.


Il existe une multitude de fonctions permettant de triturer du texte :


Concat


Cette fonction permet de concaténer plusieurs chaînes de caractères en une seule.

Elle est équivalente à ces même chaînes « additionnées » :

var MyTexte1 : String;
MyTexte2 : String;
strM1 : String;
strM2 : String;
strM3 : String;

begin
strM1 := ‘Salut! ‘;
strM2 := ‘Les copains! ‘;
strM3 := ‘C »est moi!’;

MyTexte1 := Concat(strM1, strM2, strM3);
MyTexte2 := strM1 + strM2 + strM3;

writeln(’MyTexte1=MyTexte2 : ‘, MyTexte1=MyTexte2); {Affiche TRUE
si les 2 sont identiques}
end.


Copy


Cette fonction retourne une partie bien précise d’une chaîne de caractères en fonction d’une position
specifiée. Voici la syntaxe :

Copy(Chaine : String, Debut : Integer, Long : Integer) : String;

Chaine représente la chaîne dans laquelle extraire les caractères, Debut
définit le caractère où commencer la copie et Long la longueur de la copie :

var MyTexte : String;

begin
MyTexte := ‘123456789′;
writeln(Copy(MyTexte, 3, 5)); {Sortie -> 34567}
writeln(Copy(MyTexte, 7, 3)); {Sortie -> 789}
end.


Delete


Cette procédure supprime des caractères d’une chaîne de caractères. Voici la syntaxe :

Delete(Chaine : String, Debut : Integer, Long : Integer);

Chaine représente la chaîne dans laquelle supprimer les caractères, Debut
définit le caractère où commencer la suppression et Long la longueur de la suppression :

var MyTexte : String;

begin
{123456789012345678901}
MyTexte := ‘Ceci est un gros trou’;
Delete(MyTexte, 13, 5); {Suppression de 5 caractères}
writeln(MyTexte); {Sortie -> Ceci est un trou}
end.


FillChar


FillChar permet d’inserer un caractère (type Char) ou un chiffre (type Byte)
un nombre de fois spécifiée dans une chaîne de caractères. Voici la syntaxe :

FillChar(Chaine : String, Nombre, Valeur);

FillChar correspond à la chaîne de caractères dans laquelle inserer Nombre
de fois Valeur :

var MyTexte : String[80];

begin
FillChar(MyTexte, 80, ‘$’);
writeln(MyTexte); {80 $}
end.


Insert


Cette procédure insere des caractères dans une chaîne de caractères. Voici la syntaxe :

Insert(Source : String, Destination : String, Debut : Integer);

Source représente la chaîne qui va être insérée dans la chaîne Destination
à partir du caractère Debut :

var MyTexte : String;
MyEnorme : String;

begin
MyTexte := ‘Ceci est un trou’;
MyEnorme := ‘enorme ‘;
Insert(MyEnorme, MyTexte, 13); {Insertion de la chaine MyEnorme dans MyTexte}
writeln(MyTexte); {Sortie -> Ceci est un enorme trou}
end.


Pos


Pos effectue la recherche d’une chaîne de caractère dans une autre. Voici sa syntaxe :

Pos(Recherche : String, Chaine : String) : Byte;

Recherche représente l’ocurence à rechercher dans la chaîne Chaine. La
valeur renvoyée correspond à la position de la chaine Recherche. En cas d’echec,
la valeur renvoyée est 0 :

var MyTexte : String;

begin
MyTexte := ‘Ceci est une phrase de sept mots’;
writeln(Pos(’phrase’, MyTexte)); {Sortie -> 14}
end.


Str


Cette procédure permet de convertir une variable numérique en une chaîne de caractères. Voici
la syntaxe :

Str(Nombre : Real, Chaine : String);

Nombre represente la variable numérique et Chaine, la chaîne de destination :

var MyNumber : Real;
MyTexte : String;

begin
MyNumber := Pi;
Str(MyNumber, MyTexte);
writeln(MyTexte);
end.


Val


Cette procédure effectue l’opération inverse à la procédure Str : elle convertit
une variable numérique en une chaîne de caractères. Voici la syntaxe :

Val(Chaine : String, Nombre : Real, Code : Integer);

Chaine represente la chaîne de caractère et Nombre, la variable de destination.
La variable Code renvoi un code d’erreur corespondant au caractère fautif de la chaîne
de caractères en cas d’erreur :

var MyNumber : Real;
MyTexte : String;
MyCode : Integer;

begin
MyTexte := ‘123456′;
Val(MyTexte, MyNumber, MyCode);
writeln(MyNumber);
end.


La table de caractères ASCII


La table de caractères ASCII est une table où sont regroupés les 256 caractères (numérotés de
0 à 255) pouvant être utilisés.

On peut afficher ces caractères en maintenant la touche Alt enfoncée et en tapant le code
du caractère désirés.

On peut aussi utiliser la fonction Chr. Cette fonction se charge d’afficher le caractère
ASCII correspondant au rang qui lui est transmis en argument.

Le programme suivant affiche les 256 caractères de la table :

var i : integer;

begin
for i := 0 To 255 Do
writeln(Chr(i));
end.


On peut aussi écrire le caractère en utilisant le caractère dièse (#) comme préfixe :

begin
writeln(#177);
end.

La fonction Ord effectue l’opération inverse et renvoi le code correspondant d’un caractère :

begin
writeln(Ord(’A')); {Renvoi 65}
end.


La casse


On peut modifier facilement la casse (MAJUSCULES/minuscules) d’une chaîne de caractères à l’aide
des fonctions suivantes :


StrUpper


Renvoi la chaîne de caractères transmise en argument en majuscules. Nécessite l’unité Strings :

uses strings;

begin
writeln(StrUpper(’bonjour’)); {Sortie -> BONJOUR}
end.


StrLower


Renvoi la chaîne de caractères transmise en argument en minuscules. Nécessite l’unité Strings :

uses strings;

begin
writeln(StrLower(’BONJOUR’)); {Sortie -> bonjour}
end.

Categories: Turbo Pascal Tags:

Turbo Pascal – Affichage du texte

This entry is part 17 of 24 in the series Turbo Pascal - Tutoriel
  1. ClrEol
  2. ClrScr
  3. DelLine
  4. GotoXY
  5. HighVideo
  6. InsLine
  7. LowVideo
  8. NormVideo
  9. TextBackground
  10. TextColor
  11. TextMode
  12. WhereX
  13. WhereY
  14. Window
  15. Les couleurs
  16. Les modes d’écran

On a vu à la page précédente comment traiter les chaînes de caractères avec Turbo Pascal. Nous
allons maintenant voir les différentes possibilités que nous offre ce langage pour les afficher
à l’écran.
Toutes ces procédures et fonctions nécessitent l’utilisation de l’unité crt. Vous
devez donc l’inclure en début de programme.

ClrEol

ClrEol efface la ligne où le curseur est placé, à partir de lui jusqu’à la fin de la ligne.
Exemple :

uses crt;

begin
writeln('Une ligne au dessus');
writeln('Une ligne au milieu');
writeln('Une ligne en dessous');
gotoXY(5, 2);{Voir ci-dessous pour gotoXY}
ClrEol; {On efface la ligne}
end.

ClrScr

ClrScr permet d’effacer l’écran.
Exemple :

uses crt;

begin
ClrScr;{On efface l'écran}
end.

DelLine

DelLine efface la totalité de la ligne du curseur, et décale toutes les lignes positionnées
en bas d’une ligne vers le haut
Exemple :

uses crt;

begin
writeln('1er ligne');
writeln('2ème ligne');
writeln('3ème ligne');
gotoXY(5, 2);{Voir ci-dessous pour gotoXY}
DelLine; {On efface la 2ème ligne}
end.

GotoXY

La syntaxe de GotoXY est la suivante :

GotoXY(X, Y : Byte);

GotoXY déplace le curseur à la Xème colonne et à la Yème
colonne.
Exemple :

uses crt;

begin
GotoXY(40, 12);{40ème colonnes et 12ème lignes}
write('*');
end.

HighVideo

HighVideo active la surbrillance, c’est à dire que le texte sera écrit avec une couleur
plus brillante que la normale.
Exemple :

uses crt;

begin
writeln('Texte ecrit normalement');
HighVideo;{On active la surbrillance}
writeln('Texte en surbrillance');
end.

InsLine

InsLine produit l’effet inverse de DelLine : InsLine insére une
ligne à partir de la ligne du curseur et décale toutes d’un cran vers le bas.
Exemple :

uses crt;

begin
writeln('1er ligne');
writeln('2ème ligne');
writeln('3ème ligne');
gotoXY(5, 2);
InsLine; {On insére une ligne}
end.

LowVideo

LowVideo produit l’effet contraire de HighVideo : au lieu d’activer la surbrillance,
LowVideo active une « sous-brillance ».
Exemple :

uses crt;

begin
writeln('Texte écrit normalement');
LowVideo;{On active la "sous brillance"}
writeln('Texte écrit moins fort');
end.

NormVideo

NormVideo permet de revenir au mode normal.
Exemple :

uses crt;

begin
HighVideo;
writeln('Texte écrit en surbrillance');
NormVideo;{Retour à la normale}
writeln('Texte normal');
end.

TextBackground

TextBackGround permet de définir la couleur de fond du texte. Voir ci-dessous pour le choix
des couleurs. Attention! Seul les 8 premières couleurs (0 à 7) sont possibles.
Exemple :

uses crt;

begin
TextBackground(Red);{Fond rouge}
writeln('Texte sur fond rouge');
end.

TextColor

TextColor définit la couleur du texte.
Exemple :

uses crt;

begin
TextColor(LightGreen);{Texte vert clair}
writeln('Ceci est un texte vert clair');
end.

TextMode

TextMode sélectionne un mode texte. Voir ci-dessous pour les différents modes disponibles.
Exemple :

uses crt;

begin
TextMode(CO40);{40 colonnes et 25 lignes}
writeln('Ceci est du texte');
end.

WhereX

WhereX renvoit la colonne où est placé le curseur.
Exemple :

uses crt;

begin
gotoXY(27, 1);
writeln('Le curseur est sur la ', WhereX, 'ème colonne');
{Renvoi 27}
end.

WhereY

WhereY est similaire à WhereY dans la mesure où celui-ci renvoi la ligne
où est placé le curseur et non pas la colonne.
Exemple :

uses crt;

begin
gotoXY(1, 12);
writeln('Le curseur est sur la ', WhereY, 'ème ligne');
{Renvoi 12}
end.

Window

Window crée une nouvelle fenêtre à l’écran. Voici la syntaxe :

Window(X1, Y1, X2, Y2 : Byte);

X1 et Y1 représentent les coordonnées du coin supérieur gauche, et
X2 et Y2 le coin inférieur droit.
Exemple :

uses crt;

begin
Window(10, 10, 25, 25);{Création d'une fenêtre}
Writeln('Ceci est du texte dans la fenêtre');
end.

Les couleurs

Si on ce limite à son utilisation classique, Turbo Pascal est limité à l’utilisation de 16 couleurs.
On peut alors utiliser son Index (son numéro), ou bien sa constante. Cette deuxième solution est
recommandée.
Voici les différentes couleurs :

Index Constante Aperçu
0 Black  
1 Blue  
2 Green  
3 Cyan  
4 Red  
5 Magenta  
6 Brown  
7 LightGray  
8 DarkGray  
9 LightBlue  
10 LightGreen  
11 LightCyan  
12 LightRed  
13 LightMagenta  
14 Yellow  
15 White  

À noter que l’on peut faire clignoter une couleur en ajoutant 128 à son index, ou bien la constante
Blink.
Exemple :

uses crt;

begin
TextColor(Red + Blink);{Texte rouge clignotant}
writeln('Ce texte est rouge et il clignote');
end.

Les modes d’écran

5 modes textes sont disponibles. Comme pour les couleurs, ils est possibles d’utiliser l’index
ou la constante.

Index Constante Description
0 BW40 Noir et blanc, 40×25
1 CO40 ou C40 Couleur, 40×25
2 BW80 Noir et blanc, 80×25
3 CO80 ou C80 Couleur, 80×25
7 Mono Monochrome, 80×25
Categories: Turbo Pascal Tags:

Turbo Pascal – Le son

This entry is part 18 of 24 in the series Turbo Pascal - Tutoriel
  1. Bip
  2. Sound

Il existe plusieurs façons de faire du son avec Turbo Pascal. Les méthodes qui vont suivrent permettent d’utiliser le haut-parleur interne du PC.
Pour la carte son, il faut employer des moyens détournés.

Bip

Pour faire un bip, une méthode bien connue est d’utiliser le caractère de controle de la table ASCII correpondant, qui est le 7.
On peut dont écrire :

begin
write(chr(7));{BIP!}
write(#7);{Re-BIP!}
end.

Sound

Une seconde possibilité plus souple est l’appel à Sound, qui demande l’emploi de l’unité crt.
Sound demande un argument qui représente la fréquence en Hertz du son à émmetre.
Voici un tableau qui permet de se retrouver entre les différentes vibrations :





























































NOTE Octaves
1 2 3 4
Do 131 262 523 1047
147 294 587 1175
Mi 165 330 659 1319
Fa 176 349 698 1397
Sol 196 392 784 1568
La 220 440 880 1720
Si 247 494 988 1976

Le La du diapason est, parait-il, situé sur la 2ème octave.
Donc, on peut écrire :

uses crt;

begin
Sound(440);{LAAAAAAAA}
end.

Oui, mais là (:-)), problème : le haut-parleur ne s’arrête plus!
Il faut alors recourir à une seconde instruction : NoSound.
NoSound arrete tout bêtement le haut-parleur :

uses crt;

begin
Sound(440);{LAAAAAAAA}
NoSound;{On arrete}
end.

Cette fois-ci, ça s’arrete. Mais ça se passe tellement vite que l’on a même plus le temps d’entendre.
Il existe alors plusieurs possibilité de temporiser : avec des boucles, avec un readln
On peut aussi utiliser Delay (qui est aussi compris dans l’unité crt). Delay suspend l’execution du programme pendant
le nombre de mili-secondes qui lui sont transmises en arguments.
Donc, pour faire un la de 1,5 s, on écrira :

uses crt;

begin
Sound(440);{LAAAAAAAA}
Delay(1500);{Pendant 1.5s}
NoSound;{On arrete}
end.
Categories: Turbo Pascal Tags:

Turbo Pascal – Graphismes

This entry is part 19 of 24 in the series Turbo Pascal - Tutoriel
  1. Initialisation
  2. Dessiner
  3. Styles de lignes
  4. Couleurs et remplissage
  5. Obtenir les états

Turbo Pascal n’est pas limité au seul affichage de texte. Il peut également utiliser des fonctions graphiques
qui lui permettent de réaliser des dessins plus ou moins sophistiqués.
La totalité de ces fonctions sont situées dans l’unité graph.

Initialisation

Avant toute utilisation des fonctions graphiques, il faut initaliser le système avec l’instruction InitGraph.
La syntaxe est la suivante :

InitGraph(Pilote, Mode, Chemin);
  • Pilote représente le pilote graphique de la machine
  • Mode correspond au mode graphique
  • Chemin est l’emplacement du répertoire BGI sur votre machine

Les 2 premiers arguments doivent être des variables. Les valeurs que peut prendre Pilote sont les suivantes :

Constantes Valeurs Constantes Valeurs
Detect 0 IBM8514 6
CGA 1 HercMono 7
MCGA 2 ATT400 8
EGA 3 VGA 9
EGA64 4 PC3270 10
EGAMono 5

Detect permet de réaliser une auto-détéction (voir plus loin).
Pour les modes graphique, ce peut être une des valeurs suivantes :

Constantes Valeurs Résolutions Constantes Valeurs Résolutions
CGAC0 0 320 x 200 EGALo 0 640 x 200
CGAC1 1 320 x 200 EGAHi 1 640 x 350
CGAC2 2 320 x 200      
CGAC3 3 320 x 200 EGA64Lo 0 640 x 200
CGAHi 4 640 x 200 EGA64Hi 1 640 x 350
           
MCGAC0 0 320 x 200 ATT400C0 0 320 x 200
MCGAC1 1 320 x 200 ATT400C1 1 320 x 200
MCGAC2 2 320 x 200 ATT400C2 2 320 x 200
MCGAC3 3 320 x 200 ATT400C3 3 320 x 200
MCGAMed 4 640 x 200 ATT400Med 4 640 x 200
MCGAHi 5 640 x 480 ATT400Hi 5 640 x 400
           
EGAMonoHi 3 640 x 350 IBM8514Lo 0 640 x 480
HercMonoHi 0 720 x 348 IBM8514Hi 1 1024 x 768
           
VGALo 0 640 x 200 PC3270Hi 0 720 x 350
VGAMed 1 640 x 350
VGAHi 2 640 x 480

Le mode utilisé doit correspondre au pilote utilisé (logique), sauf si vous utiliser l’auto-détéction (voir plus loin).
Voici un exemple :

Uses Graph;
VarPilote : Integer;{Variable pour le pilote}
Mode : Integer;{Variable pour le mode}
begin
Pilote := VGA;
Mode := VGAHi;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
CloseGraph;
end.

Vous remarquez que l’on a utiliser l’instruction CloseGraph. CloseGraph doit être appelé à chaque fois en fin de programme.
Il désactive le mode graphique et permet de libérer les divers secteur de mémoire occupés par les méthodes graphques.
Pour réaliser une auto-détection, il suffit d’utiliser Detect pour le pilote. La variable Mode n’a plus besoin d’être
initialisée :

Uses Graph;
VarPilote : Integer;
Mode : Integer;
begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
CloseGraph;
end.

Dessiner

Après avoir initialisé le système, il devient enfin possible d’utiliser les fonctions graphiques.
Les fonctions regroupées dans le tableau ci-dessous sont celles permettant de tracer des formes quelconques
à l’écran.

Fonctions de dessin
Fonction Description
Arc Dessine un arc de cercle à l’écran.
X et Y representent le centre de l’arc,
AngleDeb est l’angle de départ de l’arc, AngleFin
celui de fin et Rayon le rayon de l’arc.
Les angles sont exprimés en degrès.
Syntaxe :

Arc(X, Y: Integer; AngleDeb, AngleFin, Rayon: Word);
Bar Dessine un rectangle plein.
x1 et y1 represente le coin supérieur gauche et
x2 et y2 le coin inférieur droit.
La couleur et le style de remplissage est défini par SetFillStyle
ou SetFillPattern (voir plus loin).
Syntaxe :

Bar(x1, y1, x2, y2: Integer);
Bar3D Réalise la même chose que Bar, mais en 3D.
Profond represente la taille en pixel du contour.
Les valeurs possible pour Top sont les constantes TopOn (true)
et TopOff (false).
Si Top vaut TopOn, alors une face supérieure est dessinée.
Syntaxe :

Bar3D(x1, y1, x2, y2: Integer; Profond: Word; Top: Boolean);
Circle Dessine un cercle de centre X et Y, et de rayon Rayon.
Syntaxe :

Circle(X, Y: Integer; Rayon: Word);
DrawPoly Dessine un polygone vide de NbPoints sommets.
Les coordonnées de ces sommets sont définis dans la variable PolyPoints du type
PointType.
Syntaxe :

DrawPoly(NbPoints: Word; var PolyPoints);

Exemple :

Uses Graph;
ConstFrance : array[1..9] of PointType = ((X:0; Y:20),
(X:100; Y:0), (X:200; Y:20), (X:150; Y:150),
(X:200; Y:280), (X:100; Y:300),(X:0; Y:280),
(X:50; Y:50), (X:0; Y:20));
VarPilote : Integer;
Mode : Integer;
begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
DrawPoly(SizeOf(France) div SizeOf(PointType), France);
CloseGraph;
end.
Ellipse Dessine une ellipse de centre X et Y.
AngleDeb et AngleFin representent les angles de début et de fin, en degrès.
XRayon et YRayon representent la distance entre le centre et la tangente verticale
et la tangente horizontale.
Syntaxe :

Ellipse(X, Y: Integer; AngleDeb, AngleFin: Word; XRayon, YRayon: Word);
FillEllipse Réalise la même chose que Ellipse, mais remplit la forme.
Il n’y a donc pas d’angles de départ et de fin.
Syntaxe :

FillEllipse(X, Y: Integer; XRayon, YRayon: Word);
FillPoly Réalise la même chose que DrawPoly, mais remplit le polygone.
Syntaxe :

FillPoly(NbPoints: Word; var PointsPoly);
Line Trace une ligne du point x1 et y1 au point x2 et y2.
Syntaxe :

Line(x1, y1, x2, y2: Integer);
LineRel Trace à une ligne à partir de la position du curseur graphique (voir plus loin).
Dx et Dy represente la distance sur X et sur Y à parcourir à partir de la
position du curseur graphique.
Syntaxe :

LineRel(Dx, Dy: Integer);
LineTo Trace à une ligne à partir de la position du curseur graphique, jusqu’au point de
coordonnées X et Y.
Syntaxe :

LineTo(X, Y: Integer);
MoveRel Déplace le curseur graphique de Dx pixels sur l’axe des X et de Dy pixels
sur l’axe des Y.
Syntaxe :

MoveRel(Dx, Dy: Integer);
MoveTo Déplace le curseur graphique à la positon X et Y.
Syntaxe :

MoveTo(X, Y: Integer);
PieSlice Réalise la même chose que Arc, mais remplit la forme.
Syntaxe :

PieSlice(X, Y: Integer; AngleDeb, AngleFin, Rayon: Word);
PutPixel Dessine un point au coordonnées X et Y de couleur Pixel.
Syntaxe :

PutPixel(X, Y: Integer; Pixel: Word);
Rectangle Trace un rectangle du coin supérieur gauche de coordonnées x1 et y1, au
coin inférieur droit de coordonnées x2 et y2.
Syntaxe :

Rectangle(x1, y1, x2, y2: Integer);
Sector Réalise la même chose que Ellipse, mais remplit la forme. Contrairement à FillEllipse,
il est possible de spécifier un angle.
Syntaxe :

Sector(x, y: Integer; AngleDeb, AngleFin, XRayon, YRayon: Word);

Styles de lignes

Par défaut, les figures énoncées ci-dessus sont tracées avec des lignes pleines. Mais il est possible de modifier
ce comportement. Il faut pour cela utiliser SetLineStyle, dont voici la syntaxe :

SetLineStyle(Style, Motif, Epaisseur: Word);

Style represente le style de ligne à appliquer. Ce peut être une des valeurs suivantes :

Styles de lignes
Index Constante Description
0 SolidLn Trait plein
1 DottedLn Pointillés
2 CenterLn Trait mixte
3 DashedLn Trait tireté
4 UserBitLn Définit par l’utilisateur

Motif n’est utilisé que si le parametre Style est à UserBitLn.
Dans ce cas, il vous faudra fournir un entier codé sur 16 bits (Word). Chaque bit
de ce nombre représentera alors un pixel. Si le bit est à 1, le pixel sera affiché, si il est
à 0 il sera eteint.
Ainsi, si Motif vaut 61901, on aura :

1111000111001101

Ce qui pourai être symbolisé grossierement par :

____   ___  __ _

Epaisseur represente…l’épaisseur de la ligne. Ce peut être une des valeurs suivantes :

Constantes d’épaisseur
Index Constante Description
1 NormWidth Trait normal
3 ThickWidth Trait épais

Couleurs et remplissage

Toutes ces fonctions tracent des formes suivant les couleurs et le style de remplissage sélectionné. Pour séléctionner
une couleur, on utilise la procédure SetColor, associée à l’index de la couleur séléctionnée.
Voici un rappel des couleurs disponibles :

Index Constante Aperçu
0 Black  
1 Blue  
2 Green  
3 Cyan  
4 Red  
5 Magenta  
6 Brown  
7 LightGray  
8 DarkGray  
9 LightBlue  
10 LightGreen  
11 LightCyan  
12 LightRed  
13 LightMagenta  
14 Yellow  
15 White  

Par exemple, pour tracer un cercle rouge, on écrira :

Uses Graph;
VarPilote : Integer;
Mode : Integer;
begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
SetColor(Red);{Premier plan rouge}
Circle(50, 50, 50);
CloseGraph;
end.

Il est également possible de définir une couleur de fond avec SetBkColor :

Uses Graph;
VarPilote : Integer;
Mode : Integer;
begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
SetColor(Red);{Premier plan rouge}
SetBkColor(LightGreen);{Arrière plan vert-pale}
Circle(50, 50, 50);
CloseGraph;
end.

Comme vu dans le tableau plus haut, certaines fonctions autorisent le remplissage des figures, comme par
exemple FillPoly ou FillEllipse.
Avant de faire appel à l’une de ces fonctions, il faut d’abord définir le style de remplissage. On utilise
alors SetFillStyle.
Voici la syntaxe de SetFillStyle :

SetFillStyle(Pattern, Couleur: Word);

Couleur represente la couleur de remplissage et Pattern le motif, qui peut être une des valeurs
ci-dessous :

Motifs de remplissage
Index Constante Description
0 EmptyFill Couleur du fond (transparent)
1 SolidFill Couleur du tracé
2 LineFill Lignes horizontales
3 LtSlashFill Slashs
4 SlashFill Slashs épais
5 BkSlashFill Anti-Slashs épais
6 LtBkSlashFill Anti-Slashs
7 HatchFill Quadrillage
8 XHatchFill Quadrillage en diagonales
9 InterleaveFill Ecailles de poissons
10 WideDotFill Points espacés
11 CloseDotFill Points sérés
12 UserFill Motif définit par l’utilisateur (voir plus loin)

Par exemple, pour tracer un rectangle bleu clair en ecailles de poisson, on écrira :

Uses Graph;
VarPilote : Integer;
Mode : Integer;
begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
SetFillStyle(InterLeaveFill, LightBLue);
Bar(0, 0, 300, 100);
CloseGraph;
end.

Vous remarquez que le dernier motif UserFill peut-être personalisé. Pour créer un motif utilisateur,
il faut utiliser SetFillPattern dont la syntaxe est la suivante :

SetFillPattern(Pattern: FillPatternType; Couleur: Word);

Pour Couleur, pas de problèmes. Pour FillPatternType en revanche, ça se complique.
Le type FillPatternType est le suivant :

FillPatternType = ARRAY[1..8] OF BYTE;

On voit que c’est un tableau de 8 octets (BYTE).
Un motif est en fait un carré de 8×8 pixels. Selon le motif
sélectionné, on affiche ou non un pixel.
Chaque octet de FillPatternType represente une ligne de ce carré de 8×8. Et dans un octet, il y a
8 bits (voir la numération). Chaque bit de cet octet représente un pixel de la ligne :
quand il est à 1, on affiche le pixel, quand il est à 0, on l’éteint.
Par exemple, essayons de créer comme motif le symbole @ (ça va pas être si dur que ça :-) ). Tout
d’abord écrivons nos 8 octets :

0 0 1 1 1 1 0 0-> 60
0 1 0 0 0 0 1 0-> 66
1 0 1 1 1 1 0 1-> 189
1 0 1 0 0 1 0 1-> 165
1 0 1 0 0 1 1 0-> 166
1 0 1 1 1 1 0 0-> 188
0 1 0 0 0 0 1 0-> 66
0 0 1 1 1 1 0 0-> 60

Nous pouvons donc maintenant définir notre motif et le tester :

Uses Graph;
Const
Arob : FillPatternType = (60, 66, 189, 165, 166, 188, 66, 60);
VarPilote : Integer;
Mode : Integer;
begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
SetFillPattern(Arob, White);
Bar(0, 0, 300, 100);
CloseGraph;
end.

Ok, ce n’est pas très joli. Si vous en faites des plus beau, envoyez les moi.

En dehors des fonctions qui permettent un remplissage automatique, il est aussi possible de remplir des formes
fermées, un peu comme avec un logiciel d’infographie.
Pour cela, il faut utiliser FloodFill. FloodFill remplit une surface du point X et Y
jusqu’à ce que la couleur Bord soit rencontrée.
Voici la syntaxe :

FloodFill(X, Y: Integer; Bord: Word);

Obtenir les états

Pour programmer plus facilement, le Turbo Pascal dispose de plusieurs fonctions permettant au programmeur
de connaitre les états de plusieurs parametres. Voici ces fonctions :

Fonction Description
GetArcCoords Modifie la variable ArcCoords du type ArcCoordsType transmise en argument
avec les coordonnées transmises à Arc lors de son dernier appel.
Voici le type ArcCoordsType :

ArcCoordsType = RECORD
  X, Y,
  Xstart, Ystart,
  Xend, Yend : INTEGER;
END;
GetBkColor Renvoi l’index de la couleur de fond d’écran utilisée.
GetColor Renvoi l’index de la couleur de premier plan utilisée.
GetDriverName Renvoi une chaîne de caractères renvoyant le nom du pilote graphique utilisé.
GetFillPattern Modifie la variable FillPattern transmise en argument avec le motif de remplissage
defini par l’utilisateur avec SetFillPattern.
GetFillSettings Modifie la variable FillInfo transmise en argument avec les informations de remplissage
courant.
Voici le type FillSettingsType :

FillSettingsType = RECORD
  Pattern : WORD;
  Color   : WORD;
END;
GetGraphMode Renvoi l’index du mode graphique utilisé.
GetLineSettings Modifie la variable LineInfo transmise en arguments avec les informations de style de
ligne courant.
GetMaxColor Renvoi l’index de la couleur la plus haute pouvant être utilisé.
GetMaxMode Renvoi l’index du mode graphique le plus haut pouvant être utilisé avec le pilote courant.
GetMaxX Renvoi le numéro de la colonne le plus à droite (autrement dit, la largeur de l’écran).
GetMaxY Renvoi le numéro de la ligne la plus basse (autrement dit, la hauteur de l’écran).
GetModeName Renvoi une chaîne de caractère représentant le nom du mode graphique correspondant à l’index
transmis en argument.
GetModeRange Modifie les variables ModeInf et ModeSup transmises en argument avec respectivement
le plus petit et le plus grand index utilisables par le pilote spécifié comme mode graphique.
Syntaxe :

GetModeRange(PiloteGraph: Integer; var ModeInf, ModeSup:Integer);
GetPixel Renvoi la couleur du pixel situé aux coordonnées X et Y.
Syntaxe :

GetPixel(X, Y: Integer): Word;
GetX Renvoi la position X du curseur graphique
GetY Renvoi la position Y du curseur graphique
Categories: Turbo Pascal Tags:

Turbo Pascal – L’unité Graph et le texte

This entry is part 20 of 24 in the series Turbo Pascal - Tutoriel
  1. Ecrire
  2. Changement de style d’écriture
  3. Taille des caractères
  4. Justification
  5. Retrouver les parametres

Vous aurez certainement remarqué que le texte écrit par les méthodes standards comme write ou
writeln n’est pas des plus présentable.
L’unité Graph permet de remedier à ce détail de mise en forme et de pouvoir utiliser plusieurs
style de polices.

Pour utiliser ces fonctions et procédures, il faut initialiser le système pour le mode graphique, comme précisé
à la page précédente.
Petit rappel :

uses graph;

varPilote : Integer;
Mode : Integer;

begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
CloseGraph;
end.

Ecrire

Ensuite, pour écrire, on utilise la procédure OutText, qui ne prend qu’un seul argument : la chaîne
de caractères à afficher :

uses graph;

varPilote : Integer;
Mode : Integer;

begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
OutText('Hello! It''s me!');{Affiche Hello! It's me! à l'écran}
CloseGraph;
end.

Une alternative à OutText est OutTextXY. OutTextXY prend 2 arguments supplémentaires
qui sont les coordonnées X et Y de l’endroit où afficher la chaîne de caractères.
Ainsi :

uses graph;

varPilote : Integer;
Mode : Integer;

begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
OutTextXY(100, 200, 'Hello! It''s me!');{X = 100, Y = 200}
CloseGraph;
end.

Changement de style d’écriture

Pour changer de style d’écriture, c’est à dire changer de police, de taille de caractères, de direction d’écriture,
il faut utiliser la procédure SetTextStyle.
Voici la syntaxe :

SetTextStyle(Police, Direction, TailleCar : Word);

Police represente la police de caractère à utiliser. Ce peut être l’une des constantes suivantes :

Polices de caractères
Index Constante Description
0 DefaultFont La police par défaut
1 TriplexFont Triplex (style Impact)
2 SmallFont Petite police
3 SansSerifFont Sans serif
4 GothicFont Gothic

Il existe bien d’autres polices que celles citées plus haut. Les polices de caractères sont contenues dans des
fichiers dont l’extension est .chr. Il sont situés dans le repertoire bgi de Turbo
Pascal.
Pour les installer, il faut faire appel à la fonction InstallUserFont. InstallUserFont reçoit
un argument qui represente le nom de la police à installé et renvoi un Integer qui correspond à l’index
de la police. Vous pouvez ensuite utiliser cette index comme si vous utilisier une constante :

var Index : Integer;

begin
Index := InstallUserFont('euro');
end.

Direction caractèrise le sens d’affichage du texte. De gauche à droite ou de bas en haut. Les
valeurs possibles sont les suivantes :

Constantes de direction
Index Constante Description
0 HorizDir Sens horizontal, de gauche à droite
1 VertDir Sens vertical, de bas en haut

Et pour finir, l’argument TailleCar represente la taille du texte à afficher. Cette dimension
ne correspond à rien de précis, puisque la taille du texte affiché différe sensiblement d’une police à une
autre.
Si TailleCar vaut 0 (ou bien à la constante UserCharSize), la taille des caractères pourront
être définis par le programmeur (voir plus loin).
Voici un exemple d’utilisation de SetTextStyle :

uses graph;

varPilote : Integer;
Mode : Integer;

begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'c:\outils\tp\bgi');
SetTextStyle(GothicFont, VertDir, 4);{Police Gothic, vertical, taille 4}
OutTextXY(100, 200, 'Hello! It''s me!');
CloseGraph;
end.

Taille des caractères

Pour savoir quelles dimensions occupe une chaîne de caractères (par exemple, pour la centrer), on utilise
les fonctions TextWidth et TextHeight.
Ces deux fonctions renvoient respectivement la largeur et la hauteur en pixels de la chaîne de caractères qui leur
est passée en argument.
Donc, pour centrer un texte à l’écran, on écrira par exemple :

uses Graph;

varPilote : Integer;
Mode : Integer;
LeTexte : String;

begin
Write('Entrer le texte à afficher : ');
Read(LeTexte);

Pilote := Detect;
InitGraph(Pilote, Mode, 'C:\outils\Tp\BGI');
SetTextStyle(GothicFont, HorizDir, 4);

OutTextXY((GetMaxX - TextWidth(LeTexte)) div 2,
(GetMaxY - TextHeight(LeTexte)) div 2, LeTexte);

CloseGraph;
end.

Si vous avez donné la valeur UserCharSize à l’attribut TailleCar de la procédure
SetTextStyle, vous pouvez faire varier la taille des caractères des polices vectorielles à l’aide
de la procédure SetUserCharSize.
Voici la syntaxe de cette procédure :

SetUserCharSize(MultX, DivX, MultY, DivY : Word);

MultX et DivX represente le rapport à appliquer à la largeur de la police, et
MultY et DivY le rapport vertical.
En clair, il s’agit d’une échelle MultX/DivX comme pour les cartes IGN et le guide Michelin.
Pour doubler la largeur, on donnera la valeur de 2 à MultX et de 1 à DivX, ce qui dera 2/1.
À l’inverse, pour avoir la moitié, on inversera les valeur pour avoir un rapport de 1/2.
Voici un exemple :

uses Graph;

varPilote : Integer;
Mode : Integer;

begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'C:\outils\tp\bgi');
SetTextStyle(GothicFont, HorizDir, UserCharSize);
SetUserCharSize(2, 1, 1, 2);{Largeur * 2, Hauteur / 2}
OutText('Hello! It''s me !');
CloseGraph;
end.

Justification

Lorsque l’on spécifie des coordonnées à OutTextXY, le point transmis est considéré comme étant
le coin supérieur gauche où débuter le texte. Il est cependant possible de modifier ce comportement en faisant
appel à la procédure SetTextJustify. Cet procédure prend 2 arguments, le premier pour la justification
horizontale, et le deuxième pour la justification verticale. Les valeurs possibles sont les suivantes :

Constantes de justification
Index Constante Signification
0 LeftText Gauche, axe horizontal
1 CenterText Centre, axe horizontal
2 RightText Droite, axe horizontal
0 BottomText Bas, axe vertical
1 CenterText Centre, axe vertical
2 TopText Haut, axe vertical

Ainsi, pour écrire dans le coin inférieur droit sans difficultés, il suffira d’écrire :

uses graph;

varPilote : Integer;
Mode : Integer;

begin
Pilote := Detect;
InitGraph(Pilote, Mode, 'C:\outils\tp\bgi');
SetTextJustify(RightText, BottomText);{Coin inférieur droit}
OutTextXY(GetMaxX, GetMaxY, 'Ce coin est le coin inférieur droit');
CloseGraph;
end.

Retrouver les parametres

Il est possible de retrouver très facilement les valeurs des parametres transmis à SetTextStyle
et à SetTextJustify à l’aide de la procédure GetTextSettings. On passe à cette procédure une variable
du type TextSettingsType qui sera modifiée par référence.
Voici le type TextSettingsType :

TextSettingsType = RECORD
  Font      : WORD;
  Direction : WORD;
  CharSize  : WORD;
  Horiz     : WORD;
  Vert      : WORD;
END;
Categories: Turbo Pascal Tags:

Turbo Pascal – Les types personalisés

This entry is part 21 of 24 in the series Turbo Pascal - Tutoriel
  1. Types simples
  2. Intervalles
  3. Enregistrements
  4. Enumerations

Bien que le Turbo Pascal soit un langage où les types de variables sont sur-abondants, il est possible au
programmeur de créer ses propres types.
Les types doivent être déclarés avec le mot-clef Type avant la déclaration des variables (normal).

Types simples

Par défaut, une chaîne de caractères à une longueur maximale de 255 caractères. Il est possible de modifier
ce comportement et de spécifier un type de chaîne de carctères de 8 caractères maximum, pour contenir le nom
d’un fichier par exemple.
Si l’utilisateur futur du programme donne une chaîne de plus de 8 caractères à la variable, la chaîne sera alors
tronquée.
Pour définir le type, on écrira tout simplement :

Type NomFichier = String[8];

Ensuite, on peut déclarer une valeur du type NomFichier :

Type NomFichier = String[8];{Déclaration du type NomFichier}

var Fichier : NomFichier;{Utilisation du type NomFichier}

begin
writeln('Entrez le nom d''un fichier.');
write('Seuls les 8 premiers caractères sont pris en compte : ');
read(Fichier);
writeln('Vous avez écris : ', Fichier);
end.

Il est également possible de déclarer des nouveaux types de variables Integer, Byte
ou de n’importe quel type intégré, mais l’intéret est discutable :

Type Octet = Byte;
Type Mot = Integer;
type DMot = LongInt;

varUnOctet : Octet;
UnMot : Mot;
UnDMot : LongInt;

On peut aussi déclarer des nouveaux type du type Array. Par exemple, on peut imaginer un type Array qui aura seulement
une dimension de 3 :

Type Podium = array [1..3] of String;

varTourDeFrance : Podium;

begin
TourDeFrance[1] := 'Armstrong';
TourDeFrance[2] := 'Ullrich';
TourDeFrance[3] := 'Beloki';
TourDeFrance[4] := 'Kivilev';{Cette ligne provoque une erreur !!}
end.

Intervalles

Parfois, il est possible que l’on veuille qu’une variable ne puisse prendre une valeur qu’à l’intérieur d’une certaine fourchette (par exemple, entre
1 et 5).
Il est alors possible de définir un interval. Un interval ne peut être que du type entier ou du type caractère.
Pour définir un interval de 1 à 5, on écrira :

Type Arrivee = 1..5;

Pour définir un interval de la lettre I à N, on écrira :

Type Annuaire = 'I'..'N';

Ensuite, on utilise ce type comme n’importe quel autre type :

type TCuisson = 10..30;{De 10 à 30}

var Gateau : TCuisson;{Ne peut prendre que des valeurs de 10 à 30}

begin
write('Entrez le temps de cuisson du gateau : ');
readln(Gateau);
end.

Si on essaye tout de même de faire rentrer une valeur supérieur ou inférieur à l’interval, une erreur se produira.

Enregistrements

Nous avons déjà rencontré ce genre de type dans les sections antérieures. Pour prendre un exemple la procédure GetTextSettings de l’unité
Graph. Elle utilise un type de variable du type enregistrement se nommant TextSettingsType qui est le suivant :

TextSettingsType = RECORD
  Font      : WORD;
  Direction : WORD;
  CharSize  : WORD;
  Horiz     : WORD;
  Vert      : WORD;
END;

Si on déclare une variable su type TextSettingsType, on poura alors accéder à chacun de ces champs (Font, Direction,
CharSize, Horiz et Vert) à l’aide de l’opérateur point (.) :

uses Graph;

varMesReglages : TextSettingsType;

begin
MesReglages.Font := TriplexFont;
MesReglages.Direction := HorizDir;
MesReglages.CharSize := UserCharSize;
MesReglages.Horiz := RightText;
MesReglages.Vert := BottomText;
end.

Vous remarquez que dans le cas présent, nous n’avons pas eu à définir le type TextSettingsType puisque celui-ci l’est déjà au sein de
l’unité Grahp.
Le Turbo Pascal possede une instruction permettant d’établir une réference à la variable en cours, pour simplifier le boulot. Il s’agit de l’instruction
With..Do. Entre With et Do, on indique le nom de la variable. Ensuite, on déclare un bloc d’instruction (Begin...end)
et à l'intérieur de celui-ci, il n'est plus necaissaire d'indiquer le nom de la variable pour accéder à ces champs.
Ainsi :

uses Graph;

varMesReglages : TextSettingsType;

begin
With MesReglages Do
begin
Font := TriplexFont;
Direction := HorizDir;
CharSize := UserCharSize;
Horiz := RightText;
Vert := BottomText;
end;
end.

Donc, si pour un programme destiné à une entreprise, on avait par exemple à gérer les employés, on pourai créer un type TEmploye tel
que celui-ci :

Type TEmploye = RECORD
Nom : String[20];
Prenom : String[20];
Fonction : String[20];
Salaire : LongInt;
end;

Attention cependant! La taille maximal d'un type enregistrement est de 65520 octets. C'est pourquoi nous avons limité les champs du type String
à 20 caractères.
Ensuite, on l'utilisera comme n'importe quel type :

Type TEmploye = RECORD
Nom : String[20];
Prenom : String[20];
Fonction : String[20];
Salaire : LongInt;
end;

varPersonnel : Array[1..100] Of TEmploye;
i : integer;

begin
for i := 1 To 100 do
begin
with Personnel[i] do
begin
writeln('Employé n°', i);
write('Nom : ');
readln(Nom);
write('Prenom : ');
readln(Prenom);
write('Fonction : ');
readln(Fonction);
write('Salaire : ');
readln(Salaire);
end;
end;
end.

Il est aussi possible de définir des champs d'un type enregistement qui soit eux même du type enregistrement. Par exemple :

Type TEmploye = RECORD
Nom : String[20];
Prenom : String[20];
Fonction : String[20];
Salaire : LongInt;
Embauche : RECORD{Un enregistrement dans un enregistrement}
Jour : 1..31;
Mois : 1..12;
Annee : 1900..2000;
end;
end;

ou encore mieux :

Type TDate = RECORD
Jour : 1..31;
Mois : 1..12;
Annee : 1900..2000;
end;

Type TEmploye = RECORD
Nom : String[20];
Prenom : String[20];
Fonction : String[20];
Salaire : LongInt;
Embauche : TDate;{Type TDate défini ci-dessus}
DateNaissance : TDate;{Type TDate défini ci-dessus}
end;

Il est également possible d'utiliser une strucutre en Case...Of à l'intérieur d'un type RECORD.
On poura ainsi plus ou moins personaliser (en théorie) le type en fontion des parametres transmis.
Par exemple :

Type TPedalier = RECORD
Grand : Byte;
Petit : Byte;
Case Triple : Boolean Of
true : (Milieu : Byte);
false : ();
end;

Dans l'exemple ci-dessus, le champs Milieu est normalement créé QUE si le champs Triple est
à true.
L'exemple ci-dessous montre qu'il n'en est rien :

Type TPedalier = RECORD
Grand : Byte;
Petit : Byte;
Case Triple : Boolean Of
true : (Milieu : Byte);
false : ();
end;

varShimano : TPedalier;

begin
Shimano.Triple := false;{Donc le champs Milieu n'existe pas}
writeln(Shimano.Milieu);{et ben si!}
end.

Enumerations

Les enumerations ne sont pas à proprement parler un type de variable, mais plutôt une enumeration de constantes. Une variable déclarée ensuite de ce
type ne poura prendre pour valeur qu'une constante appartenant à cette énumeration.
D'autant plus que la valeur de ces constantes ne peut pas être définie.
Par exemple, prenons pour parametre le temps qu'il fait à l'exterieur. Nous considérerons qu'il peut faire Beau, Maussade ou Mitigé.
Nous pouvons ensuite créer un type regroupant ces trois constantes et une variable utilisant ce type :

Type Temps = (Beau, Maussade, Mitige);

var Lundi : Temps;

La variable Lundi ne peut prendre pour valeur que Beau, Maussade ou Mitige :

Type Temps = (Beau, Maussade, Mitige);

varLundi : Temps;
UnReel : Real;

begin
Lundi := Beau;{OK}
Lundi := Maussade;{OK}
Lundi := 10;{!!ERREUR!!)
Lundi := 1;{!!ERREUR!!}

UnReel := Mitige;{!!ERREUR!!}

writeln(Lundi);{!!ERREUR!!}
end.

On constate également que seules les variables du type Temps peuvent recevoir les constantes Beau, Maussade
et Mitige.
Mais à quoi sert donc ce genre de type? Il est utilisé dans les calculs sur les ensembles, ou bien dans des applications telles que celle-ci :

Type Temps = (Beau, Maussade, Mitige);

varLundi : Temps;

begin
if Lundi = Beau Then
writeln('Bonne journée')
else if Lundi = Maussade Then
writeln('Sortez vos bottes')
else if Lundi = Mitige Then
writeln('Prenez un parapluie, on ne sait jamais');
end.
Categories: Turbo Pascal Tags: