Developpez.com - Pascal
X

Choisissez d'abord la catégorieensuite la rubrique :

 

CHAPITRE XX : Types

Par Hugo ETIEVANT

Il est possible de créer de nouveaux types de variables sur Turbo Pascal 7.0. Il y a encore quelques décennies, un "bon" programmeur était celui qui savait optimiser la place en mémoire que prenait son programme, et donc la "lourdeur" des types de variables qu'il utilisait. Par conséquent, il cherchait toujours à n'utiliser que les types les moins gourmands en mémoire. Par exemple, au lieu d'utiliser un integer pour un champs de base de donnée destiné à l'âge, il utilisait un byte (1 octet contre 2). Voir chapitre 4 sur les types de variables. Il est donc intéressant de pouvoir manipuler, par exemple, des chaînes de caractères de seulement 20 signes : string[20] (au lieu de 255 pour string, ça tient moins de place). Les variables de types simples comme celles de type complexe peuvent être passées en paramètre à une procédure ou fonction que ce soit par l'identificateur principal ou par ses champs.

  1. Type simple
  2. Type structurés (enregistrement)
  3. Type intervalle
  4. Type énuméré
  5. Enregistrement conditionnel
 

1. Type simple

On déclare les nouveaux types simple de variable dans la partie déclarative du programme et avant la déclaration des variables utilisant ce nouveau type.
Syntaxe :

Type nom_du_type = nouveau_type ;

Exemples :

Type nom = string[20] ;

Type entier = integer ;

Type tableau = array [1..100] of byte ;

Program exemple24 ;
Type
chaine = string[20] ;
Var
nom : chaine ;
    
age : byte ;
BEGIN
Write('Entrez votre nom : ') ;
ReadLn(
nom) ;
Write('
Entrez votre âge : ') ;
ReadLn(
age) ;
WriteLn('
Votre nom est : ',nom,' et votre âge : ',age) ;
END.

Ce programme exemple 24 utilise un nouveau type appelé chaine qui sert à déclarer la variable nom.


 

2. Type structuré (encore appelé enregistrement)

On peut être amené à utiliser des types structurés car dans une seule variable on peut réussir à caser des sous-variables nommées champs. Comme nous l'avons vu dans le chapitre 16 avec le type datetime.
Syntaxe :

Type nom_du_type = Record
sous_type1 : nouveau_type1 ;
sous_type2 : nouveau_type2 ;
sous_type3 : nouveau_type3 ;
End ;

Note : les champs sont placés dans un bloc Record ... End ; et un sous-type peut lui-même être de type Record. Syntaxe :

Type nom_du_type = Record
sous_type1 : nouveau_type1 ;
sous_type2 = Record ;
sous_type2_1 : nouveau_type2 ;
sous_type2_2 : nouveau_type3 ;
sous_type2_3 : nouveau_type4 ;
End ;
End ;

Note : une constante ne peut pas être de type complexe (Array, Record...) mais seulement de type simple.

Note : on ne peut pas afficher le contenu d'une variable structurées sans passer par une syntaxe spécifiant le champs dont on veut connaître la valeur.

Note : les champs d'une variable de type structuré peuvent être de tout type (même tableau) sauf de type fichier (Text, File, File OF x).

Program exemple25a ;
Type
formulaire = Record
nom : string[20] ;
age : byte ;
sexe : char ;
nb_enfants : 0..15 ;
End ;
Var personne : formulaire ;
BEGIN
With
personne Do
Begin
nom := 'Etiévant' ;
age := 18 ;
sexe := 'M' ;
nb_enfants := 3 ;
End ;
END.

Program
exemple25b ;
Type
formulaire = Record
nom : string[20] ;
age : byte ;
sexe : char ;
nb_enfants : 0..15 ;
End ;
Var
personne : formulaire ;
BEGIN
personne.nom := 'Etiévant' ;
personne.age := 18 ;
personne.sexe := 'M' ;
personne.nb_enfants := 3 ;
END.

Ces programmes exemple25 (a et b) sont absoluement identiques. Ils utilisent tout deux une variable personne de type formulaire qui comprend trois champs : nom, age et sexe. L'utilisation de ces champs se fait ainsi : variable[point]champ (exemple25b). Lorsqu'on les utilise à la chaîne (exemple25a), on peut faire appel à With.

Program exemple25c ;
Type
date = Record
jour : 1..31 ;
mois : 1..12 ;
an : 1900..2000 ;
End ;
Type formulaire = Record
nom : string[20] ;
date_naissance : date ;
End ;
Var personne : formulaire ;
BEGIN
With
personne Do
Begin
nom := 'Etiévant' ;
With
date_naissance Do
Begin
jour := 21 ;
mois := 10 ;
an := 1980 ;
End ;
End ;
END.

Program exemple25d ;
Type
formulaire = Record

nom : string[20] ;
date_naissance : Record
jour : 1..31 ;
mois : 1..12 ;
an : 1900..2000 ;
End ;
End ;
Var personne : formulaire ;
BEGIN
With
personne Do
Begin
nom := 'Etiévant' ;
With
date_naissance Do
Begin
jour := 21 ;
mois := 10 ;
an := 1980 ;
End ;
End ;
END.

La aussi, les programmes exemple25 (c et d) sont absoluement identiques. Ils utilisent tout deux une variable personne de type formulaire qui comprend deux champs : nom, et date_naissance qui elle-même est de type structuré et comprenant les variables jour, mois et an.


 

3. Type intervalle

Les types intervalles très utilisés ici ont rigoureusement les mêmes propriétés que ceux dont ils sont tirés. Ils peuvent être de type nombre entier (Byte, Integer, ShortInt, LongInt, Long, Word) ou caractères (Char). Un type intervalle est forcément de type entier ou est compatible avec un type entier. Certaines fonctions sont réservées aux types intervalle, comme par exemple renvoyer le successeur dans l'intervalle considéré. Sachant qu'un intervalle est forcément ordonné et continu.

Syntaxe :

Type mon_type = borneinf..bornesup ;

On doit obligatoirement avoir :

  • borneinf et bornesup de type entier ou caractère
  • borneinf <= bornesup

Exemples :

Type bit = 0..1 ; Type alpha = 'A'..'Z' ; Type cent = 1..100 ;

Toutes ces instructions : Inc() (incrémentation de la variable passée en paramètre), Dec() (décrémentation de la variable passée en paramètre), Succ() (renvoit le successeur de la variable passée en paramètre), Pred() (renvoit le prédécesseur de la variable passée en paramètre), Ord() (renvoit l'index de la variable dans l'intervalle auquel elle appartient) s'appliquent aux seuls types intervalles qu'ils soient de type nombre entier ou caractère et énumérés. Par exemple, la boucle For et la condition Case Of n'acceptent que des variables de type intervalles (dont ont peut tiré un successeur pour l'itération...).

Program exemple31a ;
Const
Max=100 ;
Type
intervalle=1..Max ;
Var x :
intervalle ;
BEGIN
x:=1 ;
{...}
If Not(Succ(x)=
Max) Then Inc(x) ;
{...}
END.

Cet exemple31a utilise quelques fonctions spécifiques aux types intervalles. L'exemple suivant montre qu'on aurait pu se passer de déclarer un nouveau type en le spécifiant directement dans la syntaxe Var.

Program exemple31b ;
Const
Max=100 ;
Var x : 1..
Max ;
BEGIN
x:=1 ;
{...}
If Not(Succ(x)=
Max) Then Inc(x) ;
{...}
END.

 

4. Type énuméré

Un type énuméré est un type dont les variables associées n'auront qu'un nombre très limité de valeur (au maximum 256 différentes possibles). Un type énuméré sert de définition à un ensemble mathématique par l'intermédiaire de la syntaxe Set Of dont ce n'est pas le sujet ici, voir chapitre Ensemble. La définition d'un type énuméré conciste à déclarer une liste de valeurs possibles (256 au maximun) associées à un type, c'est-à-dire qu'une variable de type énuméré aura l'une et une seule de ces valeurs et pas une autre.

Program exemple32 ;
Type
jours=(dim, lun, mar, mer, jeu, ven, sam) ;
Var
today : jours ;
BEGIN
today := mar ;
today:=Succ(today) ;
Inc(
today,2) ;
Case
today Of
dim : WriteLn('Dimanche') ;
lun : WriteLn('Lundi') ;
mar : WriteLn('Mardi') ;
mer : WriteLn('Mercredi') ;
jeu : WriteLn('Jeudi') ;
ven : WriteLn('Vendredi') ;
sam : WriteLn('Samedi') ;
Else WriteLn('
autre, ',Ord(today)) ;
End;
END.

Les instructions propres au type intervalle sont valables également pour le type énuméré. Dans cet exemple32, il est déclaré un type jours de type énuméré composé de 7 éléments représentant les jours de la semaine. Remarquez que les éléments sont uniquement des identifiants qui n'on aucune valeur intrinsèque, on peut tout juste les repérer par leur index (l'odre dans lequel ils apparaîssent dans la déclaration, où le premier élément à le numéro 0 et le dernier : n-1). Tout d'abord une affectation à l'aide de l' opérateur habituel := vers la raviable today. Puis on lui affecte sont successeur dans la déclaration. Ensuite, on l'incémente de 2 c'est-à-dire qu'on le remplace par son sur-suivant. Et selon, sa valeur, on affiche à l'écran le jour de la semaine correspondant si sela est possible.

Remarque : La fonction Chr() réciproque de Ord() dans le cas de la table ASCII ne s'applique pas aux types intervalles et énumérés.

La partie déclarative de cet exemple32 :

Type jours=(dim, lun, mar, mer, jeu, ven, sam) ;
Var
today : jours ;

aurait très bien pu être racourcie en :

Var today : (dim, lun, mar, mer, jeu, ven, sam) ;

Note : Il est impossible d'utiliser les procédures Write(Ln) et Read(Ln) avec les variables de type énuméré.

Program exemple33 ;
Var
color:(red, yellow, green, black, blue) ;
BEGIN
For
color:=red To blue Do WriteLn('*') ;
END.

Cet exemple33 montre que l'instruction de boucle For marche aussi bien pour les types intervalles qu'énumérés.

Program exemple34 ;
Var
color:(red, yellow, green, black, blue) ;
BEGIN
color:=green ;
Case
color Of
red : WriteLn('Rouge') ;
yellow : WriteLn('Jaune') ;
green : WriteLn('Vert') ;
black : WriteLn('Noir') ;
blue : WriteLn('Bleu') ;
End ;
END.

Cet exemple34 montre que l'instruction de contrôle conditionnel Case Of fonctionne aussi avec le type énuméré, conformément à ce qui a été dit dans le chapitre sur les types intervalles.

Program exemple35 ;
Var
color:(red, yellow, green, black, blue) ;
BEGIN
color:=red ;
Repeat
Inc(
color) ;
Until
color>green ;
If
color=black Then WriteLn('Noir') ;
END.

Cet exemple35 montre que comme toute variable, color - qui est de type énuméré - peut être sujette à des tests booléens. Ici, sa valeur est incrémentée dans une boucle Repeat qui ne s'arrête que lorsque color atteint une valeur qui dans le type énuméré est supérieure à la valeur green. Ensuite un test If vient confirmer que la dernière valeur prise par color (à laquelle on s'attendait au vu de la définition du type énuméré appliqué à color) est black.


 

5. Enregistrement conditionnel

Lors de la création d'un enregistrement (type structuré), il est quelquesfois nécessaire de pouvoir en fonction d'un champs, décider de la création d'autres champs de tel ou tel type. Une telle programmation s'effectue grâce à la syntaxe Case Of que l'on connaissait déjà pour tester des variables de type intervalle. Cette fois-ci on va tester des champs dont les valeurs doivent être de type énuméré !

Syntaxe :

Type type_enumere=(élément1, élément2, ... élémentN) ;
mon_type=Record
champ1:type1;
Case
champ2:type_enumere Of
élément1:(champ3:type3);
élément2:(champ4:type4; champ5:type5; ... champM:typeM);
...
élémentN:( );
End;

Le principe c'est de créer un type énuméré dont les valeurs seront les valeurs-test de l'instruction Case Of. Ensuite, on créer le type enregistrement et on commence à créer les champs fixes, en ne mettant la structure conditionnelle qu'en dernier car son End; est confondu avec celui du Record. On écrit Case + un autre champ fixe dont la valeur conditionne la suite + : (deux points) + le type de ce champ qui est le type énuméré créé plus haut + Of. Ensuite à partir de la ligne suivante on procède comme pour un Case Of normal : on écrit les différentes valeurs possibles c'est-à-dire les éléments (par forcément tous...) du type énuméré + : (deux points) + entre parenthèses ( ) on met les champs que l'on veut suivant la valeur de l'élément sans oublier de spécifier leur type.

Donc suivant la valeur d'un champs fixe (de type énuméré), on va procéder à la création d'un champ, de plusieur champs ou même d'aucun champ (pour cette dernière option, il suffit de ne rien mettre entre les parenthèses).

Program exemple30a ;
Const
Nmax=1 ;

Type
materiaux=(metal, beton, verre) ;
produit=Record
nom : String[20] ;
Case
matiere : materiaux Of
metal : (conductivite : Real) ;
beton : (rugosite : Byte) ;
verre : (opacite : Byte; incassable : Boolean) ;
End ;
tab=Array[1..Nmax] Of produit ;

Procedure
affichage(prod : produit) ;
Begin
With
prod Do
Begin
WriteLn('
Produit ', nom) ;
Case
matiere Of
metal : WriteLn('Conductivité : ', conductivite) ;
beton : WriteLn('Rugosité : ', rugosite) ;
verre : Begin
WriteLn('Opacité : ', opacite) ;
If
incassable Then WriteLn('Incassable') ;
End ;
End ;
End ;
End ;

Var x :
tab ;
    i : Integer ;
BEGIN
With x[1] Do
Begin
nom:='Lampouille' ;
matiere:=verre ;
opacite:=98 ;
incassable:=true ;
End ;
For i:=1 To Nmax Do affichage(x[i]) ;
END.

Note : Il est absoluement nécessaire de remplire le champs qui conditionne le choix des autres champs avant de remplir les champs qui sont soumis à condition. Sinon, il est renvoyé des résultats absurdes.

Program exemple30b ;
Type
toto=Record
Case i:Integer Of
1:( ) ;
2:(
a:Real) ;
3:(
x, y:String) ;
End ;
Var x:toto ;
BEGIN
x.i:=2 ;
x.a:=2.23 ;
WriteLn(
x.a) ;
x.i:=3 ;
x.x:='Castor' ;
WriteLn(
x.x) ;
END.

Cet exmple30b montre que l'on peut utiliser des variables d'autres types que celui énuméré pour créer des enregistrements conditionnels. Ici c'est un Integer qui est utilisé et dont la valeur dans le programme conditionne l'existance d'autres champs.

Responsables bénévoles de la rubrique Pascal : Gilles Vasseur - Alcatîz -