Types définis en Pascal

Un article de Mangue.org, l'encyclopéde libre.


Nous allons ici présenter les types prédéfinis en Pascal, c'est à dire integer et real que nous avons déjà vus, mais aussi char, boolean et enfin string.


Sommaire

Les entiers

C'ets l'équivalent des entiers relatifs en maths mais malheuresement nous travaillons encore sur des ordinateurs dont la mémoire est limitée, il en résulte que l'étendue du type integer est limitée elle aussi !!! Vous pourrez donc atteindre seulement les entiers situés entre -32768 et +32767 avec ce type.
L'utilisation du type integer est courante et vous l'avez même déjà vu apparaître dans les exemples élémentaires des cours précédents, c'est pourquoi je ne la détaillerai pas trop, en revanche étudiez bien cet exemple :

program Depassement_de_Capacite;
(*
 Demontre ce qui se passe lorsque
 l'on depasse la limite des entiers
*)

(* uses WinCrt; *)

(* defintion des variables *)
var Entier1, Entier2 : integer;

begin
(* initialisation *)
  Entier1 := 20000;
  Entier2 := -13674;

  write   ( 'Valeur du premier entier :  ');
  writeln ( Entier1);
  write   ( 'Valeur du second entier  : ');
  writeln ( Entier2);

(* ligne vide *)
  writeln;

  write   ( 'Somme des deux entiers :  ');
  writeln ( Entier1 + Entier2);

(* depassement de capacite *)
  write   ( 'Difference des deux entiers :  ');
  writeln ( Entier1 - Entier2);
(* 33674 > 32767 d'ou l'erreur ! *)
end.

Compilez puis exécutez ce programme et regardez ce qu'il se passe. Pour l'addition pas de problèmes puisque nous restons dans la limite des entiers. En revanche le résultat n'est pas correct pour la différence!
Le résultat affiché ne correcpond pas à nos attentes puisque la différence de ces deux nombres est au delà de la limite des entiers de type integer

Lisez un cours sur le codage pour mieux comprendre. Nous savons que les nombres sont codés sur un nombre fini de bits. Lorsqu'une opération provoque un dépassement de capacité (overflow), le compilateur génère généralement une erreur que l'on peut lire (nous verrons ça plus tard!) mais n'arrêt pas les calculs, il se contente seulement de garder les bits de poids faible.

Il existe d'autre types d'entiers, mais ceux-cis ne sont pas supportés par tous les compilateurs (ils le sont par le Turbo Pascal et le FreePascal, c'est pourquoi je les présente ici).
Nom du typeValeur minimaleValeur maximaleNombre de bitsoccupés en mémoire
shortint-1281278
byte02558
integer-32768+3276716
word06553516
longint-2147483648214748364732
Pour les entiers, il est possible d'utiliser des fonctions d'ordre. Chaque élément a un élément précédent et un élément suivant ainsi qu'un ordre au sein du type lui-même.
Essayez donc d'utiliser ces fonctions dans vos programmes, elles pourront vous être utiles et vous les verrez apparaître dans les exemple des cours suivants. Si quelque chose vous échappe, n'oubliez pas notre forum.
  • ord : fournit l'ordre de son argument à l'intérieur du type
  • pred : fournit l'élément précédent l'argument
  • succ : fournit l'élément suivant l'argument
Astuce
Ces focntions sont aussi applicables sur les types caractère (char) et booléen (boolean) bien que leur usage soit plus rare.

Les différents opérateurs que l'on peut utiliser sur tous ces types sont simples, et vous vous en doutez certainement déjà ;)
les opérations arithmétiques simples (+ - * /) ainsi que la division entière et le modulo ( div mod)


Les caractères

Les caractères sont codés suivant une table de caractère que vous trouverez également sur le site. Pour le Pascal standard il existe 255 catractères, ils seront donc codés sur un octet exactement comme le type entier byte.
En Pascal les caractères (de type char) sont délimités par ' et '.

program Premiers_caracteres;

(* uses WinCrt; *)

(* definition de constantes *)
const LeBonCaractere = '3';

(* declaration de variables *)
var  VotreChoix : char;

begin
  (* pas d'initialisation *)

  (* entrees *)
  write  ('Entrez un caractere : ');
  readln ( VotreChoix);

  writeln; (* ligne vide *)

  (* sorties *)
  writeln ('Votre choix est    : ', VotreChoix);
  writeln ('Le bon choix etait : ', LeBonCaractere);

  readln; (* attend une pression sur entree *)
end.

J'en profite pour introduire la procédure readln, vous aurez tous les détails sur les procédures write, writeln, read et readln dans le [./cours5.htm cours suivant], à l'heure actuelle vous devez simplement savoir qu'elle nous permet de lire une valeur que l'utilisateur fournit au clavier.

En dehors de ça le programme n'est pas très complexe, il se contente de fixer un caractère puis d'en demander un à l'utilisateur. Ensuite il affiche un bilan ; rien de plus ;-)

Nous l'avons dit les caractères sont codés sur une table de caractère de 0 à 255... Chacun correspond donc à une valeur entière, ce qui explique pourquoi les procédures ord, pred et succ fonctionnent également sur ce type.
Cependant dans la table de caractère ASCII qui est généralement utilisée, tous les caractères ne sont pas imprimables à l'écran et on ne peut pas tous les former avec le clavier. Pourtant vous pouvez tous les utiliser en Pascal justement grace à cette correspondance entre les entiers et les caractères eux mêmes. Nous utiliserons pour ça la fonction chr (on peut aussi utiliser char) pour passer d'un entier à son équivalent en tant que caractère. Observez l'exemple suivant dans lequel on essai d'imprimer le caractère ASCII d'ordre 7 (qui correspond au BIP sonore) :

program Bip_sonore;
(* produit un BIP avec le haut-parleur *)

(* ne marche pas pour Windows *)

(* definition de constantes *)
cont Beep = chr (7);

begin
  write ('Un bip !!!', Beep);
  readln;
end.

Si vous êtes en mode console vous entendez le bip provoqué par une instruction write! Nous verrons dans le cours sur les [./cours9.htm types] qu'il est possible de remplacer chr(7) par char(7) voire même par #7 si vous utilisez le Turbo Pascal.

Nous avons vu qu'il est possible d'associer un entier représentant son ordre à chaque caractère. Il en résulté que les opérateurs de comparaisons fonctionnent aussi sur les chaînes de caractères. L'ordre établi est tout simplement celui de la table des caractères ASCII.


Les booléens

Il s'agit d'un type un peu spécial puisqu'il ne comprends que deux valeurs, le faux (false) et le vrai (true). Pourtant ils sont très utilisés, surtout avec les [./cours7.htm' structures conditionnelles] et les [./cours8.htm structures itératives].
Mais voyons plutôt un exemple, ça vaut mieux qu'un discours :

program OrdreCroissant;
(*
 verifie que deux entiers sont
 bien classes dans l'ordre croissant
*)

(* uses WinCrt; *)

(* declaration de variables *)
var X, Y      : integer; (* entiers *)
    Croissant : boolean; (* booleen *)

(* debut du programme *)
begin
  (* entrees *)
  write ('Donnez un entier : ');
  readln ( X);
  write ('Donnez un autre entier : ');
  readln ( Y);

  (* teste l'ordre *)
  Croissant := X <= Y;

  (* sorties *)
  writeln; (* saute une ligne *)

  if ( Croissant) then
    writeln('Ordre croissant')
  else
    writeln('Ordre non-croissant');

  (* pause *)
  readln;
end.

Ceci est un exemple d'école, l'utilisation d'une variable booléenne (de type boolean) n'est pas nécessaire, et encore moins souhaitable ici !
Pourtant vous voyez que Croissant reçoit comme valeur le résultat d'une comparaison entre deux valeurs entières. La structure conditionnelle que nous détaillerons dans le [./cours7.htm septième cours] se charge d'exploiter cette valeur ; essayez donc d'exécuter le programme avec plusieurs valeurs de test. Voilà vous avez certainement déjà compris comment ça fonctionne ;)

Il existe aussi des opérateurs et fonctions s'appliquant aux booléens. Vous avez déjà vu ord, pred et succ ; enfin les opérateurs de comparaison (< <= = >= > <>) qui appliqués aux variables d'autres types (ou aux booléens eux-mêmes) renvoient un résultat booléen.
Et enfin les opérateurs dits logiques, regardez plutôt la table suivante en supposant que A et B sont des valeurs booléennes :
ABnot (A)A or BA and BA xor B
falsefalsetruefalsefalsefalse
falsetruetruetruefalsetrue
truefalsefalsetruefalsetrue
truetruefalsetruetruefalse


Les réels

Les nombres réels (de type real) sont codés sur 6 octets. Sur ces 24 bits, 11 sont réservés pour la mantisse... Ainsi nos nombres réels seront compris dans l'intervalle 2.9*10-39 et 1.7*1028 et de même du coté négatif.
Lisez un cours traitant du codage des nombres en mémoire pour plus de détails.

Vous vous souvenez du phénomène d'overflow avec les nombres entiers ? Et bien ceci existe aussi avec les réels. Mais ce n'est pas tout puisque vous allez également être confronté à l'underflow, c'est à dire une perte de précision dans les données. Etudiez donc l'exemple suivant (exécutez le) :

program Aie_aie_aie;

(* uses WinCrt; *)

(* definition de constantes *)
const x = 1e27; (* notation exponentielle *)
      y = 1.0; (* notation classique *)

(* definition de variables *)
var Reel1, Reel2 : real;

(* programme *)
begin
 (* initilalisation *)
 Reel1 := ( x - x + y) / y;
 Reel2 := ( x + y - x) / y;

 (* sorties ecran *)
 writeln ( Reel1, Reel2);
end.

Pourtant d'un point de vue mathématique c'est exactement la même chose. Le problème vient encore une fois du fait que nos ordinateurs ont une mémoire limitée pour effectuer leurs calculs, ils sont donc incapables de manipuler en même temps des nombres très grands et des nombres très petits !

Danger
Attention : Ces nombres sont des réels pour le Pascal : 1.0, 0.5, 2.5, 1E-27, -1.5e-13
Mais ceux-ci n'en sont pas : 1, .5, 2., - 1.2, 1.E5<.code>, <code>-1e0.5

Les opérateurs agissant sur les réels en Pascal sont + - * /, en revanche contrairement à d'autres langages comme le C/C++ il n'existe pas d'opérateur pour l'élévation à une puissance, vous devrez écrire vos propres fonctions.

Il existe d'autres types de réels en Pascal standrad que voici :
TypeDomainePrécisionTaille en octets
real10-38 à 1038116
single1.5*10-45 à 3.4*103874
double5*10-324 à 1.7*10308158
extended1.9*10-4951 à 1.1*1049321910

De plus si vous travaillez en Delphi il existe de nombreux autres types avec une étendue bien plus large !


Les chaînes de caractères

Le type chaîne de caractère (string) est bien reconnu par le FreePascal et le Turbo Pascal, c'est pourquoi nous l'utiliserons. En revanche ceci n'existe pas en Pascal GNU.

En Pascal les chaînes de caractères sont délimitées par les symboles ' ' comme les caractères. Voyons un premier exemple de leur utilisation :

program ChaineDeCaracteres;

(* uses WinCrt; *)

const LMax = 27; (* longeur maximale *)

var Chaine1 : string; (* pas de taille maximale precisee *)
    Chaine2 : string[LMax]; (* limite de taille *)
    Lettre  : char;
    
begin
  Chaine1 := 'Une chaine de caracteres';
  writeln ( Chaine1);
  
  Chaine1 := 'l''utilisation du type string';
  writeln ( Chaine1);
  
  write ('Entrez une chaine de moins de 27 caracteres : ');
  readln ( Chaine2);
  (* essayez de depasser cette longueur *)
  
  Chaine1 := 'chaine entree : ' + Chaine2;
  Lettre  := '.';
  
  writeln ( Chaine1);
  
  Chaine1 := Chaine1 + Lettre;
  Chaine1[1] := 'C';
  
  writeln ( 'Chaine1 : ', Chaine1);
  writeln ( 'longueur de Chaine1 : ', length ( Chaine1));
end.

Vous voyez qu'il est possible de déclarer une variable de type string de deux manières différentes. Si on utilise string comme type pour la chaîne de caractères, la longueur maximale de celle-ci est fixée par le compilateur. En revanche si on précise la longueur comme dans string[Lmax] alors celle-ci est connue avec certitude par le programmeur et de plus il sera impossible d'affecter à la variable en question une chaîne de caractère dépassant cette longueur. Il existe des moyens de contourner cette limite de taille dans un programme même si elle est fixée explicitement mais nous ne verrons pas comment faire ici.
Si ce n'est pas clair pour vous posez vos questions sur le forum.
La séquence au sein d'une chaîne de caractères provoque l'écriture d'un ' à l'écran.

Vous voyez également dans cet exemple l'utilisation de l'opérateur de concaténation + (on pourraît aussi utiliser la procédure concat), qui permet de mettre bout à bout des chaînes de caractères entre elles, mais aussi avec de simples caractères.

Remarque
En revanche j'espère que vous vous doutez qu'il est impossible d'affecter une chaîne de caractère à un simple caractère.

Nous pouvons aussi affecter un caractère à une position précise dans une chaîne de caractère, c'ets ce que nous faisons avec Chaine[1] := 'C' où nous remplaçons le 'c' par un 'C'.

Il est aussi possible de comparer des chaînes de caractères entre elles. La comparaison découle de ce que nous avons vu pour les caractères.
Le compilateur compare tous les caractères de la chaîne les uns après les autres (en commençant par le premier biensûr) et renvoie leur ordre si il ce ne sont pas les mêmes... Si on est arrivé à la fin de l'une des chaînes de caractères et qu'aucun ordre n'a encore été établi alors la chaîne la p^lus courte est déclarée "inférieure" à l'autre.

Il y a plusieurs fonctions agissant sur les chaînes de caractères, lisez l'aide pour plus de détails :
  • concat : permet de concaténer ses arguments séparés par des virgules au sein d'une seule chaîne de caractère, ex: Chaine := concat ('test', ' n°1');
  • length : renvoie la longueur d'une chaîne de caractère passée en argument. ex : Longueur := length(Chaine);
  • copy : renvoie une partie d'une chaîne de caractères. ex : SousChaine := copy(Chaine,1,6);
  • pos : permet de savoir si une chaîne de caractères est inclue dans une autre, si c'est le cas renvoie le rang de son premier caractère. ex : Rang := pos(Chaine,'n°1');
  • insert : permet d'insérer une chaîne de caractère dans une autre. ex : insert(Chaine,'Ceci est un ',1);
  • delete : supprimer une partie de chaîne de caractère. ex : delete(Chaine,1,9);
Remarque
Attention, contrairement à bien d'autres langages (C/C++, Java, Caml...) en Pascal l'indexation des chaînes de caractères commence à 1 et non pas à 0.
C'est à dire que Chaine[1] désigne le premier caractère de Chaine et non pas le deuxième.

Cependant Chaine[0] désigne bien quelque chose ! Il s'agit tout simplement de la longueur courante de la chaîne de caractère. Pour des programmes avancés vous pourrez avoir besoin de consulter cette valeur mais surtout veillez à ne pas la modifier, ça pourrait avoir des conséquences désastreuses sur votre programme.
Nous n'utiliserons jamais ceci dans les exemples de ce cours car le risque est quand même élevé. Pensez à vous documenter sur les directives de compilation afin de rendre vos programmes plus robustes.

Outils personels