Vous êtes sur la page 1sur 47

Chapitre 5 TYPES STRUCTURES

A la fin de cette partie, vous serez capable de:

Utiliser bon escient les types structurs ensemble, tableau, enregistrement;


Utiliser les composants Listbox, Memo et StringGrid dans des applications
Delphi;

5.1 Introduction

Les types de donnes que nous avons rencontrs jusqu'ici taient des types scalaires (ou non
structurs), c'est--dire lmentaires. Parmi ces types nous avons distingu les types prdfinis
de ceux que l'utilisateur peut lui-mme dfinir. Dans ce chapitre, nous allons tudier les types
structurs qui constituent une des richesses de la reprsentation des donnes en Pascal. Un type
est structur s'il est compos de plus d'un lment. C'est le cas des types suivants:
ensembles
tableaux
enregistrements
fichiers
Les fichiers font l'objet d'une tude spare dans la suite de ce cours, tant donn leur importance
et les notions qui leur sont attaches. Nous avons rserv une place en fin de chapitre aux
constantes dclares avec type et aux variables absolues.

5.2 Type ensemble (set)

En Pascal, les ensembles sont mis en oeuvre avec la mme signification qu'ils possdent en
mathmatique. On y retrouve d'ailleurs les mmes oprations. Pour mieux comprendre l'utilit du
type ensemble, considrons le problme suivant. Comment savoir si un caractre tap dans un
Edit par l'utilisateur est une voyelle majuscule ? Une structure slective permet de rsoudre
facilement ce problme. Elle doit tre place dans l'vnement OnKeyPress de l'Edit.:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);


begin
if (Key = 'A') or (Key = 'E') or (Key = 'I') or (Key = 'O')
or (Key = 'U') or (Key = 'Y') then
Label1.caption := 'C''est une voyelle';
end;

Ce genre de problme, consistant dterminer si le contenu d'une variable appartient un


ensemble de valeurs donnes, se rencontre souvent en programmation. Voici comment il est
possible de rsoudre ce problme l'aide d'un ensemble:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);


begin
if Key in ['A','E','I','O','U','Y'] then
Label1.caption := 'C''est une voyelle';
end;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-1


Ici, l'ensemble des voyelles est spcifi de manire explicite par une liste de constantes place
entre crochets, appele constructeur d'ensemble. Cette forme d'criture abrge est bien plus
lgante, plus claire et plus concise qu'une expression boolenne complexe. L'ensemble des
voyelles peut, dans cet exemple, tre considr comme une constante de type ensemble.
Un ensemble contient toujours des lments du mme type de base, scalaire (prdfini ou
numr) ou intervalle, l'exception du type rel. Le type ensemble se dclare de la manire
suivante:

SYNTAXE

type type_ensemble = set of type_de_base;

Une variable de type type_ensemble peut contenir des lments de type type_de_base,
qui doit tre un type scalaire ou intervalle, l'exception du type rel.

Le nombre maximum d'lments d'un ensemble est limit 256. De plus, deux ensembles sont
gaux s'ils contiennent les mmes lments, indpendamment de leur l'ordre.
La dfinition d'une variable de type ensemble comporte la spcification du type de base des
lments de cet ensemble. Seule une affectation permet de placer des valeurs dans une variable
de ce type. L'erreur consistant croire que la dclaration d'une telle variable suffit lui attribuer
des lments se rencontre frquemment.
L'affectation d'lments un ensemble s'effectue l'aide d'un constructeur d'ensemble qui n'est
autre qu'une liste d'lments du type de base, dlimite par des crochets. La notation d'intervalle
est possible lorsque plusieurs lments sont conscutifs. Le fragment de programme qui suit
montre quelques exemples de dclaration et d'utilisation de variables de type ensemble:

type alphabet = set of 'A'..'Z';


couleurs = (rouge, vert, bleu, jaune, blanc);
teinte = set of couleurs;
bizarre = set of 0..255;

var lettre, voyelle : alphabet;


c : char;
lumiere : teinte;
clair : set of jaune..blanc;
magique : bizarre;

...
begin
lettre := ['A'..'Z'];
voyelle := ['A','E','I','O','U','Y'];
lumiere := [blanc];
clair := [jaune, blanc];
magique := [0..8,12,19,22..38,99];
...
if c in voyelle then Edit1.Text := 'Voyelle';
end;
...
Le langage Pascal dispose d'oprateurs agissant sur les ensembles, de manire analogue aux
oprateurs de la thorie des ensembles en mathmatique. On trouve, d'un ct, les oprateurs
ensemblistes proprement dits (union, intersection et diffrence) et, de l'autre, des oprateurs
relationnels (appartenance, galit, altrit, inclusion). Comme pour les nombres, ces oprateurs
ont un degr de priorit et, en cas de mme degr de priorit, l'valuation des expressions se fait
de gauche droite. Mais voyons comment s'expriment ces oprateurs en Pascal. Les variables
utilises sont dclares comme suit:

var nombres, resultat, a, b : set of 0..10;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-2


reponse : char;
daccord : boolean;

intersection *
nombres := [1..10];
resultat := nombres * [2,4..6]; // resultat aura la valeur [2,4,5,6]
a := [1,2,4];
b := [3,5];
if a * b = [] then // [ ] reprsente l'ensemble vide.
Label1.Caption := 'a et b sont disjoints';

union +

resultat := a + b + [6,7,8,9]; // resultat aura la valeur


// [1,2,3,4,5,6,7,8,9]

diffrence -

resultat := nombres - [1,3..7]; // resultat aura la valeur [2,8,9]

galit =
if (nombres = [1..10]) then
resultat := nombres - [5..10];

altrit <>
if (nombres - [5..10]) <> [] then
Label1.Caption := 'Correct';

inclusion <=
if nombres <= [0,2,4,6,8] then
Label1.Caption := 'pair';
if (a <= b) and (a <> b) then
Label1.Caption := 'a inclus mais non gal b';

appartenance in
daccord := reponse in ['o','O'];
Il est important de ne pas confondre la notion d'ensemble avec la notion d'intervalle ou de type
numr. Si, par exemple, on dsire crire:

caractere := ['A'..'L'];
caractere peut, par exemple, tre dclar comme:

var caractere : set of 'A'..'L';


et non comme:

var caractere : 'A'..'L';

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-3


5.3 Type tableau (array)

Les tableaux, ou variables indices, sont ns du besoin de pouvoir traiter plusieurs variables du
mme type, groupes sous le mme identificateur et diffrentiables par la valeur d'un indice. Pour
mieux saisir la ncessit de disposer de tableaux, essayons de rsoudre le problme qui consiste
calculer la moyenne de dix nombres. Une solution serait d'crire le programme suivant:

var a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 : real;
a_moyen : real;

...
procedure TForm1.Button1Click(Sender: TObject);
{on suppose que l'on a affect un contenu aux variables a1 a10}
begin
a_moyen := (a1+a2+a3+a4+a5+a6+a7+a8+a9+a10) / 10;
Label1.Caption := FloatToStr (a_moyen);
end;

Il serait videmment aberrant de calculer la moyenne de 10'000 nombres avec une telle mthode.
Les variables a1 a10 contiennent des donnes de mme nature, il serait donc plus judicieux de
disposer d'une variable unique, mais structure en plusieurs composantes pouvant recevoir
chacune une donne de mme type. Cette ide est prcisment reprise dans la plupart des
langages de programmation qui disposent du type tableau. Voici ce que devient le programme de
calcul de moyenne avec l'utilisation d'une variable de type tableau:

const MAX = 10;


type tableau = array [1..MAX] of real;
var a : tableau;
i : 1..MAX;
somme : real;

begin
somme := 0;
for i := 1 to MAX do
somme := somme + a[i];
Label1.Caption := FloatToStr (somme / MAX);
end.

La distinction des valeurs contenues dans le tableau a se fait par la valeur de l'indice i, indiquant
le numro de l'lment considr. En effet, pour rfrencer un lment d'un tableau, il faut
spcifier l'identificateur de la variable suivi, entre crochets, de l'indice. De plus, notre programme
est devenu beaucoup plus gnral, puisqu'il suffit de changer la valeur de la constante MAX pour
qu'il calcule la moyenne de 100, 1000 ou 10'000 nombres. Cette forme de programme permet
notamment l'utilisation aise des structures itratives.

SYNTAXE

type type_tableau = array [intervalle] of type_element;

Type_tableau dcrit une collection d'lments de mme nature et de mme type,


type_element. Intervalle doit tre un intervalle de type simple: entier, boolen, caractre
ou numr, mais pas rel. L'indice du tableau prend ses valeurs dans intervalle. Le type
type_element peut tre un type simple ou structur, comme par exemple un tableau.

La taille d'une variable de type tableau est dtermine par la taille de ses lments et par leur
nombre.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-4


On utilise gnralement un tableau lorsque le nombre d'lments est connu l'avance. Une
dclaration telle que array [1..10] of integer interdit les valeurs de l'indice non comprises dans
l'intervalle 1..10.
Nous avons vu qu'il n'y a pas de restriction sur le type des lments d'un tableau. Ainsi on peut
dfinir des tableaux de tableaux, appels aussi tableaux multidimensionnels.
Comme premier exemple, considrons une grille de mots croiss de 30 lignes et 40 colonnes. Les
dclarations suivantes montrent comment transposer la nature d'une grille de mots croiss dans
une structure de donnes informatique quivalente. Chaque case de la grille est reprsente par
un lment d'un tableau bidimensionnel:

type ligne = array [1..40] of char;


tableau = array [1..30] of ligne;
var grille : tableau;
rangee : ligne;
Ces dclarations peuvent galement s'crire de la manire suivante:

const largeur = 40;


hauteur = 30;
type horizontal = 1..largeur;
vertical = 1..hauteur;
ligne = array [horizontal] of char;
tableau = array [vertical] of ligne;
var grille : tableau;
rangee : ligne;

On peut remarquer dans ces dclarations l'interdpendance des diffrents objets. La constante
largeur figure dans la dclaration de horizontal, le type horizontal dans celle de ligne, le type
ligne dans celle de tableau, enfin le type tableau dans celle de la variable grille. Les justifications
de cette faon de procder sont nombreuses et, parmi elles, celle de donner un nom chaque
objet. Cela permet de multiples rfrences, comme par exemple, dclarer plusieurs variables de
mme type. Une autre justification est illustre par la facilit d'adaptation du programme qui en
dcoule. Supposons que l'on veuille satisfaire une nouvelle requte ou situation, par exemple
adapter ce programme pour une nouvelle grille comportant 20 lignes et 35 colonnes. Il suffit alors
de modifier les constantes largeur et hauteur, puis de recompiler le programme. Les programmes
ainsi paramtrs sont plus gnraux.
Mais revenons aux dclarations, et en particulier aux deux suivantes:
ligne = array [horizontal] of char;
tableau = array [vertical] of ligne;
nous aurions pu les contracter de cette manire:

tableau = array [vertical] of array [horizontal] of char;


ou ainsi:

tableau = array [vertical, horizontal] of char;


Les trois formes sont quivalentes. Les instructions permettant de remplir la premire ligne de la
variable grille avec des astrisques seraient:

for i := 1 to largeur do
grille [1, i] := '*';

Mettre la grille de mots croiss blanc reviendrait crire:


for j := 1 to hauteur do
for i := 1 to largeur do
grille [j, i] := ' ';

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-5


Une fois encore, on constate que l'emploi de structures itratives convient tout fait au traitement
des donnes reprsentes sous forme de tableaux.
Voyons maintenant un exemple de programme utilisant un tableau dont l'indice est de type
caractre. Ce petit programme dtermine la frquence d'apparition de chaque lettre minuscule
dans un texte tap par l'utilisateur:

Pour ne pas compliquer l'exemple nous avons utilis l'vnement OnKeyPress du Memo dans
lequel l'utilisateur tape le texte. A chaque frappe, s'il s'agit d'une lettre minuscule, le tableau
contenant le nombre d'apparitions est mis jour et son contenu est affich dans le Listbox de
droite. Voici le code complet de ce programme:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
ListBox1: TListBox;
Memo1: TMemo;
Label1: TLabel;
procedure FormActivate(Sender: TObject);
procedure Memo1KeyPress(Sender: TObject; var Key: Char);
private
{ Dclarations prives }
public
{ Dclarations publiques }
table : array ['a'..'z'] of integer;
end;

var Form1: TForm1;

implementation

{$R *.DFM}

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-6


procedure TForm1.FormActivate(Sender: TObject);
{ initialisation du tableau }
var lettre : char;
begin
for lettre := 'a' to 'z' do
table[lettre] := 0;
end;

procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);


var lettre : char;
begin
if key in ['a'..'z'] then
table[key] := table[key] + 1;
listbox1.clear;
for lettre := 'a' to 'z' do
listbox1.items.add (lettre + ' ' + inttostr(table[lettre]));
end;

end.
L'intrt de ce programme est que chaque lment du tableau n'est pas repr par un nombre,
mais par un caractre. Le contenu d'un lment est un nombre entier correspondant la
frquence d'apparition du caractre dsignant ce mme lment. La variable table possde donc
26 lments, et il convient d'initialiser zro chacun des 26 lments au dbut du programme. La
condition if lettre in ['a'..'z'] ... permet de s'assurer que le caractre lu (indice du tableau) est bien
dans l'intervalle 'a'..'z'.
Dans le prochain exemple, l'indice du tableau est de type numr. Seules les dclarations et une
portion du programme sont prsentes. Un indice de type numr peut contribuer rendre les
programmes plus lisibles:

type rayons = (sport, menage, habillement, alimentation);


gain = array [rayons] of real;
var benefice : gain;
rayon : rayons;
total : real;
...
(* calcul du bnfice ralis dans tous les rayons du magasin *)
total := 0;
for rayon := sport to alimentation do
total := total + benefice[rayon];
Edit1.Text := 'Bnfice ralis: ', total:10:2, ' francs.';
...
Les oprations agissant sur les tableaux mettent en jeu les lments pris individuellement et non
le tableau de manire globale. Pour illustrer cette particularit, considrons les dclarations qui
suivent:

type lignes = array [1..10] of integer;


var a, b, c : lignes;
il n'est pas permis d'crire:
a := b + c;
Une addition composante par composante doit tre effectue, par exemple, l'aide de la
procdure suivante:

procedure somme (x, y: lignes; var z: lignes);


var i : integer;
begin
for i := 1 to max do
z[i] := x[i] + y[i];
end;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-7


L'affectation fait office d'exception. En effet, le transfert du contenu d'un tableau dans un autre est
possible de manire globale, pour autant que les deux soient du mme type. Dans ce cas,
l'instruction:
b := a;
est accepte et est quivalente :
for i := 1 to 10 do
b[i] := a[i];
Parfois, il est ncessaire de paramtrer une procdure avec des lments d'un tableau. Dans ce
cas, il est prfrable de passer tout le tableau comme paramtre, ce qui ne pose aucun problme,
mais amne une lgre contrainte. Le type des paramtres spcifis dans l'en-tte d'une
procdure doit tre un identificateur. Il n'est donc pas possible de spcifier une dclaration de ce
genre:
procedure tri (var liste: array[1..10] of real);
On la remplacera donc par:
type tableau = array [1..10] of real;
...
procedure tri (var liste: tableau);
L'en-tte de la procdure gagne en lisibilit, la contrainte n'est pas trop pesante.
Pour terminer, nous allons nous intresser un programme consistant effectuer un tri, dans
l'ordre croissant, des valeurs contenues dans un tableau de 10 lments. Le programme dispose
d'un bouton qui gnre 10 nombres entiers au hasard. Il les place dans un tableau et les affiche
dans un Listbox. Puis la procdure tri effectue un tri par change. Enfin, le contenu du tableau tri
est affich dans le second Listbox.
La mthode de tri par change consiste prendre chaque lment du tableau et le comparer
avec tous ses suivants. Chaque fois que les deux lments compars ne figurent pas dans le
tableau en ordre croissant, ils sont permuts. Cette mthode n'est de loin pas la plus efficace,
mais elle est facile comprendre et mettre en oeuvre. Voici comment se prsente notre
exemple:

Le code de ce programme se prsente de la manire suivante:

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-8


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

const MAX = 10;


type tableau = array [1..MAX] of integer;
type
TForm1 = class(TForm)
ListBox1: TListBox;
ListBox2: TListBox;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Dclarations prives }
public
{ Dclarations publiques }
table : tableau;
end;
var Form1: TForm1;

implementation
{$R *.DFM}

procedure tri (var liste: tableau);


var i, j : integer;
temp : integer;
begin
for i := 1 to MAX - 1 do
for j := i + 1 to MAX do
if liste[i] > liste[j] then begin
temp := liste[i];
liste[i] := liste[j];
liste[j] := temp;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);


var i : integer;
begin
listbox1.clear; // on vide le listbox
for i := 1 to MAX do begin
table[i] := random (100);
listbox1.items.add (inttostr(table[i]));
end;
end;

procedure TForm1.Button2Click(Sender: TObject);


var i : integer;
begin
tri (table); // tri proprement dit
listbox2.clear;
for i := 1 to MAX do
listbox2.items.add (inttostr(table[i]));
end;

end.
fig. 5.1

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-9


5.4 Utilisation de composants intgrant des tableaux

5.4.1 Introduction
Les tableaux apparaissent, implicitement ou explicitement, trs frquemment dans Delphi. Que ce
soit en tant que proprits de certains types de donnes, ou bien lorsque l'on utilise certains
composants de la VCL (Visual Component Library). Dans cette section nous allons nous attarder
essentiellement sur trois composants: les Listbox, les Memo et les StringGrid..

5.4.2 Listbox
Un Listbox, appel zone de liste en franais, est un ensemble ordonn de chanes de caractres
reprsent sous la forme suivante:

En fonction du nombre d'lments, un Listbox peut disposer d'une barre de dfilement. Chaque
lment d'un Listbox se trouve sur une et une seule ligne. De plus, il n'est pas possible d'crire
directement dans un Listbox. L'utilisateur peut ajouter, supprimer ou slectionner un ou plusieurs
lments de la liste. Une zone de liste dispose de plusieurs proprits et mthodes dont nous
allons dcrire ci-dessous les plus importantes:

Items property Items: TStrings;

Items contient l'ensemble des chanes de caractres de la liste.


Le type Tstrings reprsente une liste de chanes de caractres.

Exemple: Liste1.Items.Add ('Licorne');

Items possde lui-mme des proprits et des mthodes (voir plus loin).
Dans l'exemple ci-dessus, Add est une mthode de Items permettant
d'ajouter une chane de caractres dans la liste existante Items. Dans la
liste ci-contre, 'Vache', 'Cheval', sont les chanes de caractres
contenues dans Items:

Itemindex property ItemIndex: Integer;

La proprit ItemIndex indique le numro d'ordre de l'lment slectionn dans la liste.


ItemIndex est utilis aussi bien pour slectionner un lment de la liste, que pour connatre le
numro de l'lment slectionn au moment du fonctionnement du programme.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-10


Pour slectionner un lment de la liste, il faut attribuer la proprit ItemIndex la valeur dsire,
correspondant au numro d'ordre de l'lment dans la liste. La valeur ItemIndex pour le premier
lment est 0. Si aucun lment n'est slectionn, cette valeur est de -1.

Exemple: Liste2.Items.Add (liste1.Items[Liste1.ItemIndex]);

Dans la liste ci-contre, la chane 'Chat' est l'lment numro 3 de la liste.

Liste1.Itemindex vaut 3, et donc,


Liste1.Items[Liste1.Itemindex] vaut 'Chat'.

Lorsque la proprit MultiSelect (voir ci-dessous) est vraie, la valeur ItemIndex reprsente le
numro de l'lment qui a le "focus" parmi les lments slectionns. Si la proprit MultiSelect
est vraie la valeur par dfaut de ItemIndex est 0.

MultiSelect property MultiSelect: Boolean;


Lorsque cette proprit est vraie, il est possible de slectionner plusieurs lments de la liste en
mme temps.
Petit rappel: pour slectionner plusieurs lments d'une liste, il faut cliquer avec la souris sur
l'lment ou les lments choisis et appuyer en mme temps les touches shift ou contrle du
clavier.

SelCount property SelCount: Integer;


La proprit SelCount permet de connatre le nombre d'lments slectionns dans la liste, si la
proprit MultiSelect est vraie.
Cette proprit est consultable, mais n'est pas modifiable. Lorsque la proprit MultiSelect et
fausse, la proprit SelCount vaut toujours -1.

Exemple: Res.Text := 'Il y a ' + IntToStr(Liste1.SelCount) + ' lments slectionns.';

Dans la liste suivante, Selcount vaut 4.

Selected property Selected[Index: Integer]: Boolean;


La proprit Selected permet de dterminer ou de connatre quels lments de la liste sont
slectionns. Il s'agit en fait d'un tableau de valeurs boolennes.
Dans la liste prcdente, Liste1.Selected[1] vaut true, alors que Liste1.Selected[4] vaut false.
Cette proprit est trs utile lorsque, par exemple, un traitement doit tre appliqu uniquement aux
lments slectionns d'une liste.

Exemple: if Liste1.Selected[4] then

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-11


Sorted property Sorted: Boolean;
La proprit Sorted indique si la liste doit tre automatiquement trie alphabtiquement.

Exemple: Liste1.Sorted := true;

Clear procedure Clear;


Cette mthode permet de vider toute la liste en une seule fois.

ItemAtPos function ItemAtPos(Pos: TPoint; Existing: Boolean): Integer;


Cette mthode permet de connatre le numro de l'lment situ une coordonne spcifie.
Ceci peut tre utile pour retrouver un lment de la liste qui se trouve sous le curseur de la souris,
par exemple.
Si Pos se trouve aprs le dernier lment de la liste, la valeur du paramtre Existing dtermine la
valeur retourne par ItemAtPos:
Si Existing est true, ItemAtPos retourne 1
Si Existing est false, ItemAtPos retourne l'indice du dernier lment de la liste, plus 1.

Proprits et mthodes de Items

Count property Count: Integer;


La proprit Count indique le nombre d'lments actuellement contenus dans une liste.

Exemple: vide := (Liste1.Items.Count = 0);

Dans la liste suivante, Count vaut 5:

Strings property Strings[Index: Integer]: string;


Cette proprit permet de spcifier une chane de caractres d'une liste grce son indice.
Les deux lignes de l'exemple suivant sont quivalentes:

Exemple: Liste1.Items.Strings[0] := 'Ceci est la 1re chane';


Liste1.Items [0] := 'Ceci est la 1re chane';

Add function Add(const S: string): Integer; virtual;


Cette mthode permet d'ajouter un lment la fin d'une liste
Add retourne l'indice du nouvel lment plac dans la liste.

Exemple: Num := Liste1.Items.Add ('Ligne ajoute la liste');


Liste1.Items.Add ('Ligne aussi ajoute la liste');

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-12


AddStrings procedure AddStrings(Strings: TStrings); virtual;
Cette mthode permet d'ajouter une liste de chane de caractres dans la liste courante.
Dans l'exemple suivant, tous les lments de la liste Liste2 sont ajouts en une seule fois dans la
liste Liste1:

Exemple: Liste1.Items.AddStrings (Liste2.Items)

Append procedure Append(const S: string);


Cette mthode est quivalente la mthode Add, sauf qu'elle ne retourne pas l'indice du nouvel
lment ajout.

Exemple: Liste1.Items.Append ('Ligne ajoute la liste');

Delete procedure Delete(Index: Integer); virtual; abstract;


Cette mthode permet de supprimer une chane de caractres de la liste courante.

Exemple: Liste1.Items.Delete (2);

Voici le rsultat:

Exchange procedure Exchange(Index1, Index2: Integer); virtual;


Cette mthode permet de permuter deux lments d'une liste en indiquant leurs indices respectifs.

Exemple: Liste1.Items.Exchange (0, 3);

Voici le rsultat

Insert procedure Insert(Index: Integer; const S: string); virtual; abstract;


Cette mthode permet d'insrer un lment une position donne de la liste courante.

Exemple: Liste1.Items.Insert (3, 'Coq');

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-13


LoadFromFile procedure LoadFromFile(const FileName: string); virtual;
Cette mthode permet de placer dans la liste courante les lignes du fichier texte pass comme
paramtre.
L'exemple suivant permet d'afficher dans la liste Liste1 le contenu du fichier c:\config.sys.

Exemple: Liste1.Items.LoadFromFile ('c:\config.sys');

Move procedure Move(CurIndex, NewIndex: Integer); virtual;


Cette mthode permet de dplacer un lment dans la liste courante.

Exemple: Liste1.Items.Move (0,3);

Voici le rsultat:

SaveToFile procedure SaveToFile(const FileName: string); virtual;


Cette mthode permet d'enregistrer les lments de la liste courante dans le fichier texte pass
comme paramtre.

Exemple: Liste1.Items.SaveToFile ('c:\config.sys');

5.4.3 Memo
Un Memo est un composant permettant la saisie de texte multiligne. Il possde des similitudes
avec le Listbox:
La proprit Lines du Memo est quivalente et du mme type que la proprit Items du
Listbox. Les deux sont du type Tstrings; donc, toutes les proprits et mthodes dcrites
ci-dessus pour les Listbox sont galement valables pour les Memo
L'aspect est le mme que celui d'un Listbox.

Les principales diffrences sont:


Un Memo est essentiellement utilis pour saisir du texte gnralement de taille assez
importante. De ce point de vue, on peut dire qu'il remplit le mme rle qu'un Edit, avec
l'aspect multiligne en plus
L'utilisateur peut manipuler librement le texte: regrouper, ajouter, supprimer des lignes
Le contenu d'un Memo peut tre rfrenc et gr ligne par ligne, en faisant appel la
proprit (tableau) Lines, par exemple:
Memo.Lines.Add ('Dernire ligne');
Mais il peut aussi tre trait comme un tout, en faisant appel sa proprit Text, de la
mme manire qu'un Edit. La proprit Text n'est pas accessible depuis l'inspecteur
d'objet, mais on peut la grer depuis le code d'un programme.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-14


Pour illustrer le fonctionnement d'un Memo observons l'exemple suivant:

Le code du premier bouton est le suivant:

procedure TForm1.Ligne3Click(Sender: TObject);


begin
Edit1.text := Memo1.Lines[3];
end;
Ici on accde au contenu du Memo ligne par ligne. En l'occurrence on place la ligne 3 (attention!
La premire ligne porte le numro zro) dans le texte de l'Edit.

Le code du deuxime bouton est le suivant:

procedure TForm1.AjouterClick(Sender: TObject);


begin
Memo1.Lines.Add (Edit2.Text);
end;
Le contenu de l'Edit est ajout en tant que nouvelle ligne dans le Memo. On aurait pu crire:

procedure TForm1.AjouterClick(Sender: TObject);


begin
Memo1.Text := Memo1.text + Edit2.text;
end;
Dans ce cas le texte de l'Edit est simplement ajout au texte du Memo, sans insrer de saut de
ligne.

Enfin, le code du troisime bouton est le suivant:

procedure TForm1.SupprimerClick(Sender: TObject);


begin
Memo1.lines.Delete (1);
end;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-15


5.4.4 StringGrid
Un StringGrid est une grille constitue de cellules, un peu la manire d'un tableur. Chaque
cellule peut contenir une chane de caractres, d'o le nom de ce composant.
Les proprits et mthodes des StringGrid sont nombreuses. Vous trouverez ci-dessous une
description des principales. Pour avoir des informations concernant les autres vous pouvez faire
appel l'aide de Delphi.

Cells property Cells[ACol, ARow: Integer]: string;


On utilise la proprit Cells pour accder aux cellules de la grille, en fait aux chanes de
caractres qu'elles contiennent.
ACol indique la coordonne de la colonne et ARow celle de la ligne. La premire cellule en haut
et gauche a pour coordonnes (0,0).

Exemple: StringGrid1.Cells[2,3] := 'Capital initial';


Voici un exemple montrant comment sont numrotes les cellules d'une grille:

fig. 5.2

Cols property Cols[Index: Integer]: TStrings;


On utilise la proprit Cols pour accder aux chanes de caractres d'une colonne entire.
Index indique la coordonne de la colonne.

Exemple: Listbox1.items := StringGrig1.Cols[3];

Rows property Rows[Index: Integer]: TStrings;


On utilise la proprit Rows pour accder aux chanes de caractres d'une ligne entire.
Index indique la coordonne de la ligne.

Exemple: StringGrid1.Rows[2] := StringGrid1.Rows[3];


Dans cette exemple, le contenu de la colonne 3 est copi dans la colonne 2.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-16


Col property Col: Longint;
La proprit Col indique l'indice de la colonne contenant la cellule slectionne, autrement dit la
cellule courante.

Row property Row: Longint;


La proprit Row indique l'indice de la ligne contenant la cellule slectionne, autrement dit la
cellule courante.

Exemple: procedure TForm1.StringGrid1Click(Sender: TObject);


begin
Label1.Caption := 'Le curseur se trouve dans la colonne ' +
IntToStr(StringGrid1.Col + 1) + ', en ligne ' +
IntToStr(StringGrid1.Row + 1);
end;

ColCount property ColCount: Longint;


La proprit ColCount indique le nombre de colonnes de la grille.

RowCount property ColCount: Longint;


La proprit RowCount indique le nombre de lignes de la grille.

Exemple: for i := 0 to StringGrid1.ColCount - 1 do


for j := 0 to StringGrid1.RowCount - 1 do
StringGrid1.Cells[i, j] := '(' + inttostr(i) + ',' + inttostr(j) + ')';
Cet exemple a t utilis pour remplir la grille de la figure 5.2.

DefaultColWidth property DefaultColWidth: Integer;


La proprit DefaultColWidth indique, en pixels, la largeur de toutes les colonnes de la grille
n'ayant pas t explicitement redimensionnes.

DefaultRowHeight property DefaultRowHeight: Integer;


La proprit DefaultRowHeight indique, en pixels, la hauteur de toutes les lignes de la grille
n'ayant pas t explicitement redimensionnes.

ColWidths property ColWidths[Index: Longint]: Integer;


La proprit ColWidths indique la largeur, exprime en pixels, de chaque colonne de la grille.
Index permet de spcifier la colonne.

Exemple: StringGrid1.ColWidths[2] := 50;


Cet exemple fixe la largeur de la troisime colonne 50 pixels.

RowHeights property RowHeights[Index: Longint]: Integer;


La proprit RowHeights indique la hauteur, exprime en pixels, de chaque ligne de la grille.
Index permet de spcifier la ligne.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-17


FixedCols property FixedCols: Integer;
La proprit FixedCols indique le nombre de colonnes gauche de la grille qui ne dfilent pas.
Comme on peut le voir sur la figure 5.2, par dfaut, les cellules correspondantes sont de couleur
grise.

FixedRows property FixedCols: Integer;


La proprit FixedRows indique le nombre de lignes en haut de la grille qui ne dfilent pas.
Comme on peut le voir sur la figure 5.2, par dfaut, les cellules correspondantes sont de couleur
grise.

CellRect function CellRect(ACol, ARow: Longint): TRect;


La fonction CellRect renvoie les coordonnes cran d'une cellule de la grille.
ACol et ARow indiquent les coordonnes de la cellule. Le rsultat est fourni sous forme d'un
rectangle, correspondant l'emplacement de la cellule dans la grille.

MouseToCell procedure MouseToCell(X, Y: Integer; var ACol, ARow: Longint);


La procdure MouseToCell renvoie les indices de colonne et de ligne de la cellule occupant la
position de coordonnes cran (X,Y).
X et Y reprsentent des coordonnes cran, par exemple celles de la souris; ACol et ARow sont
les coordonnes de la cellule, exprimes en termes de numro de ligne et de colonne.

Afin d'illustrer ce qui prcde, nous allons examiner un exemple d'application faisant intervenir un
StringGrid.

Pour afficher les coordonnes de chaque cellule dans la grille nous avons utilis les instructions
suivantes, dclenches par l'vnement OnActivate de la fiche:

procedure TForm1.FormActivate(Sender: TObject);


var i, j : integer;
begin
for i := 0 to SG.ColCount - 1 do

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-18


for j := 0 to SG.RowCount - 1 do
SG.Cells[i, j] := '(' + inttostr(i) + ',' + inttostr(j) + ')';
end;
Le bouton "Cols[1]" excute l'instruction suivante:

listbox1.items := SG.Cols[1];
Il est important de comprendre que SG.Cols[1] ne reprsente pas une chane de caractres, mais
la liste des chanes de caractres de la colonne 1. Cette liste est de type Tstrings, tout comme
d'ailleurs la proprit Items d'un Listbox, d'o la possibilit d'affectation de l'un l'autre. Voici ce
qui apparat lorsque l'on clique sur ce bouton:

Le bouton "Rows[1]" effectue une opration quivalente, mais concerne la ligne 1. Voici le rsultat:

Puisque Cols[1] reprsente la liste des chanes de caractres de la colonne 1, comment obtenir le
contenu d'une cellule particulire de la colonne 1? Simplement en indiquant le numro de la ligne
dsire sous forme d'un indice de tableau:

Edit1.Text := SG.Cols[1][3];
Voici le rsultat de l'excution de cette instruction:

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-19


Le bouton " Rows[2] := Rows[3]" affecte la ligne 2 le contenu des cellules de la ligne 3. Le code
est le suivant:

SG.Rows[2] := SG.Rows[3];

Enfin, pour illustrer l'utilisation de la procdure MouseToCell nous avons fait appel l'vnement
OnMouseMove de la grille:

procedure TForm1.SGMouseMove(Sender: TObject; Shift: TShiftState;


X, Y: Integer);
var col, ligne : integer;
begin
SG.MouseToCell (x, y, col, ligne);
label1.caption := 'La souris se trouve sur la cellule (' +
inttostr(col) + ',' + inttostr(ligne) + ')';
end;
Rappelons que cette procdure vnementielle est appele chaque mouvement de la souris.
Voici le rsultat obtenu:

Une des plus grandes limitations de ce composant est que ses diverses proprits concernent
toutes les cellules. Il n'existe pas de proprit permettant de changer la police de caractres ou la
couleur de fond d'une cellule particulire.
Toutefois ce composant peut tre gr avec plus de souplesse en faisant appel l'vnement
OnDrawCell. Cet vnement est gnr autant de fois qu'il y a de cellules dans la grille. Pour
chaque cellule, chaque fois que la grille doit tre rafrachie ou redessine, Delphi nous fournit,
entre autres, les paramtres ACol et ARow contenant le numro de la colonne et de la ligne de la
cellule concerne, ainsi que le paramtre Rect reprsentant le rectangle sous-jacent la cellule:

procedure TForm1.SGDrawCell(Sender: TObject; ACol, ARow: Integer;


Rect: TRect; State: TGridDrawState);

C'est prcisment en rponse cet vnement que le programmeur peut appliquer un


comportement diffrenti aux cellules de la grille.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-20


Pour terminer, voici un exemple de programme faisant appel un StringGrid. Ce programme
ouvre un fichier graphique de type BMP, l'affiche en taille relle (en haut droite de la fentre) et
le transpose dans un StringGrid. Chaque pixel de l'image correspond une cellule du StringGrid.
L'utilisateur peut, entre autres, dessiner sur le StringGrid avec la couleur qu'il choisit l'aide de
trois curseurs (R, G et B). Le dessin sur le StringGrid est automatiquement rpercut sur l'image
en taille relle. Il peut aussi capturer une couleur de l'image et l'utiliser pour dessiner. Le
programme ne permet pas de sauvegarder une image, mais l'utilisateur peut recharger l'image
d'origine.

Le programme complet est tonnamment compact: il est constitu d'une trentaine de lignes de
code crites par le programmeur. Le voici au complet:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, StdCtrls;

type
TForm1 = class(TForm)
SG: TStringGrid;
IM: TImage;
Recharger: TButton;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-21


rouge: TScrollBar;
vert: TScrollBar;
bleu: TScrollBar;
ex: TPanel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
charger: TButton;
OD: TOpenDialog;
Label4: TLabel;
Label5: TLabel;
procedure SGDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
procedure rougeChange(Sender: TObject);
procedure SGMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormActivate(Sender: TObject);
procedure SGMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SGMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure RechargerClick(Sender: TObject);
procedure chargerClick(Sender: TObject);
private
{ Dclarations prives }
public
{ Dclarations publiques }
dessin : boolean;
nom : string;
end;

var Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.SGDrawCell(Sender: TObject; ACol, ARow: Integer;


Rect: TRect; State: TGridDrawState);
begin
SG.Canvas.Brush.color := im.canvas.pixels[Acol, Arow];
SG.canvas.fillrect (rect);
end;

procedure TForm1.rougeChange(Sender: TObject);


begin
ex.Color := rgb(rouge.position, vert.position, bleu.position);
end;

procedure TForm1.SGMouseDown(Sender: TObject; Button:


TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if ssleft in shift then begin
im.canvas.pixels[SG.Col, SG.row] := ex.color;
dessin := true;
end;
if ssright in shift then begin
rouge.position := GetRvalue (SG.canvas.pixels[x,y]);
vert.position := GetGvalue (SG.canvas.pixels[x,y]);
bleu.position := GetBvalue (SG.canvas.pixels[x,y]);
end;
end;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-22


procedure TForm1.FormActivate(Sender: TObject);
begin
dessin := false;
nom := '';
end;

procedure TForm1.SGMouseUp(Sender: TObject; Button: TMouseButton;


Shift: TShiftState; X, Y: Integer);
begin
dessin := false;
end;

procedure TForm1.SGMouseMove(Sender: TObject; Shift: TShiftState;


X, Y: Integer);
var r, c : integer;
begin
if dessin then begin
SG.MouseToCell (x, y, c, r);
im.canvas.pixels[c, r] := ex.color;
end;
end;

procedure TForm1. RechargerClick(Sender: TObject);


begin
if nom <> '' then begin
im.Picture.LoadFromFile (nom);
SG.refresh;
end;
end;

procedure TForm1.chargerClick(Sender: TObject);


begin
if OD.execute then begin
im.picture.loadfromfile (OD.filename);
nom := OD.FileName;
SG.refresh;
end;
end;

end.
Le principe de fonctionnement est assez simple pour tre expliqu en dtail. Voici tout d'abord les
noms des divers composants et leur signification:
Rouge, vert et bleu les trois barres de dfilement du choix de couleur
SG le StringGrid
im l'image
charger bouton pour le chargement de l'image
recharger bouton pour le rechargement de l'image
ex surface rectangulaire montrant la couleur actuelle
OD dialogue d'ouverture de fichier
La variable dessin indique si l'utilisateur est en train de dessiner. La variable nom contient le nom
du fichier image; le bouton recharger utilise ce nom pour recharger l'image.
L'vnement OnDrawCell est utilis pour remplir la cellule courante avec la couleur du pixel
correspondant sur l'image en taille relle:

SG.Canvas.Brush.color := im.canvas.pixels[Acol, Arow];


SG.canvas.fillrect (rect);

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-23


L'vnement OnChange des trois barres de dfilement contient l'instruction qui met jour la
couleur du panel:

ex.Color := rgb(rouge.position, vert.position, bleu.position);


L'vnement OnMouseDown du StringGrid gre les situations suivantes. Lorsque l'utilisateur
clique sur le bouton gauche de la souris, la couleur spcifie par les barres de dfilement est
place dans la cellule correspondante et dessin prend la valeur true, indiquant que l'utilisateur est
en train de dessiner. S'il s'agit du bouton droit, on met jour la couleur en positionnant les barres
de dfilement:
if ssleft in shift then begin
im.canvas.pixels[SG.Col, SG.row] := ex.color;
dessin := true;
end;
if ssright in shift then begin
rouge.position := GetRvalue (SG.canvas.pixels[x,y]);
vert.position := GetGvalue (SG.canvas.pixels[x,y]);
bleu.position := GetBvalue (SG.canvas.pixels[x,y]);
end;
Lorsque le bouton de la souris est relch, on change simplement la valeur de dessin.
Lorsque l'utilisateur dplace la souris en appuyant sur le bouton gauche, le programme convertit,
l'aide de la mthode MouseToCell, les coordonnes de la souris (x, y) en coordonnes de
cellule (c, r). L'image en taille relle est galement mise jour:
if dessin then begin
SG.MouseToCell (x, y, c, r);
im.canvas.pixels[c, r] := ex.color;
end;
Il ne reste plus que le code associ aux deux boutons, qui est d'une simplicit vidente.

5.5 Type enregistrement (record)

La plupart des langages de programmation de haut niveau incluent les tableaux. En revanche, les
enregistrements (record) sont une structure que l'on rencontre plus rarement. Ils permettent une
meilleure organisation et une gestion plus rationnelle des informations, et sont troitement lis
une autre structure fondamentale que sont les fichiers (voir plus loin).
Un enregistrement, comme un tableau, regroupe plusieurs informations. Alors que dans un
tableau tous les lments doivent tre du mme type, dans un enregistrement les diffrentes
composantes (ou champs) peuvent tre de nature ou de type diffrents. Enfin, on repre une
composante d'un enregistrement par le nom de la variable de type enregistrement et le nom du
champ auquel on veut accder.

SYNTAXE

type enreg_type = record


liste_id1 : type1;
liste_id2 : type2;
...
liste_idn : typen;
end;

La dclaration d'un enregistrement comprend le nom (enreg_type), puis entre les mots
rservs record et end, une liste d'identificateurs (les diffrents champs) suivis du type
correspondant; type1 ... typen peuvent tre des types quelconques.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-24


Pour mieux entrevoir les facilits associes au type enregistrement, envisageons une structure de
donnes qui pourrait figurer dans un programme de gestion de loyers. Les renseignements
dsirs concernant les locataires seraient:

nom
prnom
sexe
loyer
charges
numro d'appartement
La structure d'enregistrement se prte particulirement bien la reprsentation de ces
informations:

type str20 = string[20];


locataire = record
nom, prenom : str20;
sexe : (masculin, feminin);
loyer, charges : real;
no_appart : integer;
end;

var personne : locataire;


loyer_total : real;
fig. 5.3

L'accs un champ d'un enregistrement s'effectue en indiquant le nom de l'enregistrement et le


nom du champ, spars par un point (notation pointe). Par exemple, l'instruction d'entre
permettant la saisie du nom d'un locataire s'crit:

personne.nom := Edit1.Text;
De mme, le loyer total se calcule l'aide de l'instruction:

loyer_total := personne.loyer + personne.charges;


Dans certains passages de programmes o la manipulation des champs d'un enregistrement est
frquente, la notation pointe peut devenir lourde. Le langage Pascal a prvu un moyen de la
remplacer, grce l'instruction with ... do. Les instructions:

personne.nom := Edit1.Text;
loyer_total := personne.loyer + personne.charges;
peuvent tre transformes en:

with personne do begin


nom := Edit1.Text;
loyer_total := loyer + charges;
end;
ce qui allge considrablement l'criture des programmes. A l'intrieur d'une instruction with, on
utilise donc uniquement les noms des champs manipuler. D'apparence trs pratique, cette
instruction est utiliser avec parcimonie, tant donn la confusion qu'elle peut parfois provoquer
au niveau des identificateurs. Lorsque plusieurs variables de type enregistrement ayant des
champs de mme nom se trouvent dans une structure with ... do, il peut y avoir ambigut
apparente. En fait, le Pascal se rfre toujours la variable dont le nom d'enregistrement est le
plus proche. Considrons l'exemple suivant:
...
type pdg = record
nom : string[20];
age : integer;
societe : string[20];
end;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-25


emp = record
nom : string[20];
age : integer;
revenu : real;
end;
var employe : emp;
chef : pdg;
deductions : real;
...

with employe, chef do begin


nom := Edit1.Text;
revenu := revenu - deductions;
Edit2.Text := societe;
end;
...
nom et societe se rapportent la variable chef, alors que revenu concerne la variable employe.
Comme dans le cas des tableaux, les oprateurs arithmtiques ou logiques doivent se rapporter
aux champs d'un enregistrement et non l'enregistrement en tant qu'entit. L'exception en est
l'affectation. Il est donc possible aprs la dclaration:

var personne, gens : locataire;


d'crire l'instruction:

personne := gens;
Les deux variables doivent bien entendu possder exactement la mme structure, c'est--dire tre
de mme type.
Il est assez frquent, en programmation, de faire appel des paramtres de type enregistrement,
car un enregistrement constitue un groupe logique d'informations.
Aprs avoir tudi les tableaux et les enregistrements, il semble tout naturel de combiner ces deux
types de donnes. Une forme qui se rencontre souvent est le tableau d'enregistrements. Dans
beaucoup de cas, les objets traits par un programme ont une structure d'enregistrement, et ces
objets eux-mmes sont en grand nombre. Pour que l'exemple de la figure 5.3 soit un peu plus
raliste, il convient de transformer notre locataire unique en un ensemble de locataires:

const maxloc = 20;


type habitants = array [1..maxloc] of locataire;
var habitant : habitants;
Un indice est utilis pour reprer les diffrents locataires. Ainsi une augmentation de loyer du
troisime locataire s'crira comme suit:

habitant[3].loyer := habitant[3].loyer + 50.0;


On comprend peut-tre mieux prsent l'importance d'avoir disposition plusieurs types de
structures de donnes. Il est ainsi beaucoup plus facile de construire des programmes ayant un
rapport direct et naturel avec l'information traiter. Une des phases les plus importantes, si ce
n'est la plus importante, dans la rsolution d'un problme au moyen de la programmation est
l'analyse. C'est au cours de cette phase que s'effectue, entre autres, le choix des structures de
donnes les plus adquates. Une bonne analyse facilite grandement la phase de codification.
Nous allons examiner une structure de donnes plus complexe, construite l'aide de types de
donnes tudis au pralable:

const maxempl = 100;


type etat_civil = (marie, celibataire);
date = record
jour : 1..31;
mois : 1..12;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-26


annee : 1900..1999;
end;
adresse = record
rue : string[20];
no : integer;
code_postal : string[6];
ville : string[12];
end;
departements = (personnel, travaux, machines, maintenance);
employe = record
nom : string[15];
prenom : string[15];
age : integer;
etat : etat_civil;
maison : adresse;
salaire : real;
date_entree : date;
end;
division = array [1..maxempl] of employe;
var entreprise : array [departements] of division;
travailleur : employe;
section : division;

Dans le cadre de cette structure, le nom de l'employ reprsent par la variable travailleur est
donn par:

travailleur.nom
Le salaire du deuxime employ de la section s'exprime par:

section[2].salaire
Le jour d'entre dans l'entreprise du troisime employ de la division du personnel est repr par:

entreprise[personnel][3].date_entree.jour
Ces formes d'criture, bien que claires, peuvent devenir lourdes. En ralit, les informations sont
le plus souvent destines tre conserves dans un fichier qui n'est rien d'autre qu'une suite
d'enregistrements. Nous verrons plus loin que pour utiliser un fichier de manire optimale il vaut
mieux viter une structure d'enregistrement trop complexe. On prfre souvent utiliser deux ou
trois fichiers de structure simple plutt qu'un seul fichier trop dense et enchevtr.
Dans la plupart des implmentations de Pascal, une souplesse supplmentaire a t introduite au
niveau des enregistrements: les variantes. Les enregistrements avec variantes possdent un ou
plusieurs champs variables en contenu et en structure. L'exemple qui suit en prsente une
utilisation:

type forme = (triangle, carre, cercle);


teinte = (rouge, bleu, jaune);
figure = record
couleur : teinte;
case aspect : forme of
triangle : (base, hauteur : real);
carre : (cote : real);
cercle : (rayon : real);
end;

var dessin1, dessin2 : figure;


Les variantes sont spcifies dans un enregistrement l'aide d'une structure semblable celle de
l'instruction case ... of. La partie fixe d'un enregistrement doit toujours figurer au dbut de la
dclaration alors que les variantes viennent la fin. Si, pour une variante donne, il n'est pas
prvu de champ, on l'indiquera par ( ). Le champ qui slectionne les diffrentes variantes fait

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-27


galement partie de l'enregistrement. Enfin, la place mmoire occupe par une variable de type
figure correspond la somme de la taille des champs fixes et de la taille de la plus grande des
variantes.

dessin1.couleur := bleu;
dessin1.aspect := triangle;
dessin1.base := 10;
dessin1.hauteur := 5;
dessin2.couleur := rouge;
dessin2.aspect := cercle;
dessin2.rayon := 4;
Il revient au programmeur d'viter d'crire, par exemple:

dessin2.base
sans avoir test la valeur de la variable aspect.

5.6 Compatibilit de types

En Pascal, deux types peuvent tre identiques ou seulement compatibles. Certaines situations
exigent la premire proprit, alors que d'autres se satisfont de la seconde. De plus, la
compatibilit peut tre considre au niveau d'une affectation, d'un passage de paramtres ou
d'une expression. Le non-respect de certaines rgles de compatibilit peut conduire des erreurs
lors de l'excution d'un programme. C'est la raison pour laquelle il est bon d'avoir cette notion de
compatibilit l'esprit. En cas de doute il est conseill de se reporter l'aide de Delphi.

5.7 Constantes avec type

Nous avons vu, dans le chapitre 2, la diffrence existant entre une variable et une constante. En
Pascal standard, les constantes peuvent tre de type entier, rel, caractre, boolen ou chane de
caractres. Delphi permet, en plus, d'utiliser des constantes avec type, qu'il faut envisager plutt
comme des variables initialises. Ces constantes peuvent tre de type scalaire ou structur.

SYNTAXE

const identificateur : type = valeur;

Pour les constantes avec type non structur, chane de caractres ou ensemble.

const identificateur : type = (valeurs);

Pour les constantes avec type structur (tableau, enregistrement ou composite), sauf
ensemble.

Les exemples qui suivent constituent des dclarations de constantes types non structures:

const max_lignes : integer = 24;


rabais : real = 0.05;
demo : boolean = true;
message : string[5] = 'Merci';
arret : char = ^C;
code : byte = 2;

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-28


Une constante type, contrairement une constante habituelle, peut apparatre comme paramtre
transmis par rfrence d'une procdure ou d'une fonction. De plus, sa valeur peut galement tre
modifie par affectation. En revanche, elle ne peut pas intervenir dans la dclaration d'autres
constantes ou types. Pour illustrer cette dernire caractristique, voici une dclaration non
autorise:

const max : integer = 10;


type table = array [1..max] of integer;
Une constante de type ensemble contenant les lettres minuscules se dclare de la manire
suivante:

const minuscules : set of char = ['a'..'z'];


Une constante avec type peut galement appartenir l'un des types structurs tableau ou
enregistrement. L'intrt est alors une initialisation compacte, possible au moment de la
dclaration. Examinons, l'aide d'exemples, ces deux sortes de constantes types structures.
L'initialisation d'un tableau contenant le nombre de jours que compte chaque mois s'crit:

const jour_par_mois : array [1..12] of integer =


(31,28,31,30,31,30,31,31,30,31,30,31);
Pour des tableaux multidimensionnels, on procde de la manire suivante:

const grille : array [1..4,1..3] of integer =


((1,4,3),(3,1,4),(10,11,10),(1,0,0));
Les constantes de type enregistrement doivent tre prcdes de la dclaration de
l'enregistrement auquel elles se rfrent:

type simple = record


nom : string[20];
age : integer;
end;
const individu : simple = (nom : 'Dupont'; age : 56);

5.8 Variables absolues

Gnralement, l'adresse mmoire laquelle le compilateur place les variables d'un programme ne
peut pas tre choisie ou contrle par le programmeur. Toutefois, Delphi permet d'indiquer
explicitement dans la dclaration l'adresse mmoire o doit tre place une variable. L'adresse est
indique sous forme d'une adresse absolue ou sous forme de rfrence un autre objet du
programme. Ainsi la dclaration suivante permet de connatre le numro du mode vido en cours,
celui-ci tant stock l'adresse mmoire $0040.

var CrtMode: Byte absolute $0040;

Cette dclaration "superpose" l'emplacement de la variable CrtMode la position mmoire $0040.


Toutefois avec les nouveaux systmes d'exploitation, une protection de la machine, et de la
mmoire en particulier est mise en place. Dans notre cas, lors de l'excution du programme
utilisant la variable CrtMode, le systme affiche un message d'erreur concernant une violation
d'accs mmoire.
Voyons maintenant une autre utilisation des variables absolues sous la forme du petit exemple
suivant:

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-29


Au fur et mesure que l'utilisateur introduit des caractres dans la zone de texte, le programme
affiche le nombre de caractres contenus dans cette zone de texte. Pour cela nous avons
simplement utilis un Timer qui, toutes les 100 millisecondes, grce une variable absolue, extrait
et affiche le nombre de caractres de la zone de texte. Voici le code excut par le timer:

procedure TForm1.Timer1Timer(Sender: TObject);


var Str: shortstring;
StrL: Byte absolute Str;
begin
Str := Edit1.text;
Label2.caption := inttostr (StrL) + ' caractres';
end;
En effet, il faut se souvenir que les variables de type ShortString contiennent dans leur premier
octet (octet 0) la longueur effective de la chane de caractres. Comme on peut le constater le
contenu de la variable StrL change uniquement par le fait qu'elle est superpose, en mmoire,
la chane de caractres Str.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-30


EXERCICES

Exercice 5.1:

Ecrire un programme qui comporte un Edit et un ListBox. L'utilisateur tape un texte dans l'Edit.
Lorsqu'il tape <Return>, le texte est ajout dans le ListBox et l'Edit est vid.

Exercice 5.2:

Reprendre l'exercice 1 et ajouter un bouton qui vide compltement le ListBox, ainsi qu'un bouton
qui supprime du ListBox la ligne slectionne (en surbrillance).

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-31


Exercice 5.3:

Partir de l'exercice prcdent et ajouter une case cocher indiquant si le contenu du ListBox doit
tre tri ou non. De plus, trouver un moyen pour qu'aprs avoir cliqu sur un des deux boutons ou
sur la case cocher le "focus" (ici le curseur) se trouve sur l'Edit.

Exercice 5.4:

Ecrire un programme effectuant des tris selon 3 mthodes: tri par bulle, tri par comptage, tri par
change. Afin de visualiser les 250 nombres (compris entre 0 et 999) tirs au hasard en cliquant
sur le bouton "Remplir", ainsi que les rsultats obtenus avec les trois mthodes nous utilisons des
ListBox.

Mthode de tri par bulle:

On compare deux deux les lments adjacents en remontant la liste (le tableau); si
l'ordre n'est pas le bon, les deux lments compars sont permuts
On redescend dans la liste si le plus petit des lments permuts dans la phase
prcdente a encore des lments plus grands que lui. La descente s'arrte ds qu'il a
trouv sa place ou si l'on se trouve au dbut de la liste
On reprend la monte de la liste l o on l'avait laisse

Exemple: 6 7 3 8 5 1 monte
3 7 permutation
3 6 7 descente
7 8 5 1 monte
5 8 permutation
5 7 8 descente
3 5 6 7 8 1 descente, monte
1 8 permutation
1 7 8 descente
1 6 7 8 descente
1 5 6 7 8 descente
1 3 5 6 7 8 descente

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-32


Mthode de tri par comptage:

Pour trier un tableau A[1..n] on dtermine le rang de chaque lment en comptant le nombre des
lments qui lui sont infrieurs.
Dans ce but, on associe chaque A[i] un compteur. On compare successivement un lment du
tableau tous ses prdcesseurs; on rpte l'opration pour tous les lments et on obtient l'tat
du tableau en analysant le contenu des compteurs. Si le compteur C[i] indique la valeur k, la place
de l'lment A[i] est la k-ime position du tableau tri. Voici la suite des oprations effectuer:

Initialiser les compteur 1


On compare A[1] et A[2]:
o Si A[1] < A[2] alors on incrmente C[2] sinon on incrmente C[1]
On compare ensuite A[3] avec les lments A[1] et A[2]. En fonction des rsultats des
comparaisons, on incrmentera les compteurs correspondants, comme dans le point
prcdent. Lorsque tous les lments ont t traits, les compteurs indiquent le rang de
l'lment correspondant.

Mthode de tri par change:

Cette mthode consiste comparer chaque lment du tableau (en partant de l'indice le plus bas)
avec les lments suivants. Chaque fois que l'ordre n'est pas le bon, les deux lments sont
permuts. Il s'agit de l'une des mthodes de tri les moins efficaces.

Exercice 5.5:

Ecrire un programme comportant deux ListBox. Celui de droite est vide au dpart, alors que celui
de gauche doit contenir les nombres de 1 8 en toutes lettres (trouver comment faire cela). Deux
boutons permettent de copier l'lment slectionn dans le ListBox de gauche ou de droite. Les
boutons sont activs uniquement si la copie est possible.

Exercice 5.6:

Modifier le programme pour que les boutons dplacent et non plus copient les lments de
gauche droite et vice versa. De plus, ajouter l'indication du nombre d'lments sous chaque
ListBox (indication visible ds le lancement du programme).

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-33


Exercice 5.7:

Ajouter au programme deux boutons permettant de supprimer l'lment slectionn dans un


ListBox (aprs avoir cliqu sur ces boutons, l'affichage du nombre d'lments doit tre correct).

De plus, aprs avoir cliqu sur un des quatre boutons, le programme doit (s'il reste des lments
dans la liste) forcer la slection tre sur la 1re ligne de la liste.

Exercice 5.8:

Reprendre l'exercice prcdent et ajouter la possibilit de faire une multi-slection des lignes des
deux ListBox (slection de plusieurs lignes). Le programme doit effectuer toutes les oprations
comme prcdemment, mais sur toutes les lignes slectionnes.

Exercice 5.9:

Ecrire un programme qui comporte un StringGrid. Le StringGrid doit avoir une dimension de 8 x 8
et aucune colonne grise. En cliquant sur un bouton, le programme doit remplir la premire et la
dernire colonne avec la lettre 'X'.

Exercice 5.10:

Modifier le programme de l'exercice prcdent pour qu'il remplisse aussi la premire et la dernire
ligne avec la lettre 'X', ainsi que l'intrieur du carr dlimit par les 'X' avec la lettre 'O'.

Exercice 5.11:

Modifier le programme de l'exercice prcdent pour qu'il place des '1' dans les cases des deux
diagonales.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-34


Exercice 5.12:

Modifier le programme de l'exercice prcdent pour qu'il place des '8' dans les cases restes
vides, c'est--dire celles qui se trouvent entre les cts et les diagonales (quatre zones
triangulaires).

Exercice 5.13:

Reprendre la base de l'exercice 9 et faire en sorte qu'en cliquant sur le bouton le programme
inscrive, dans chaque case, la somme de son numro de ligne et de colonne. Par exemple, la
case (2,3) contiendra 5.

Exercice 5.14:

Reprendre l'exercice prcdent. Le programme doit laisser choisir la taille de la grille par
l'utilisateur (entre 2 x 2 et 8 x 8) l'aide d'un "TrackBar". A n'importe quelle position du TrackBar
l'utilisateur peut cliquer sur le bouton.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-35


Exercice 5.15:

Faire un programme bas sur un StringGrid de 8 x 8. On aimerait, en utilisant l'vnement


"OnDrawCell", que les cellules (1,4) et (5,5) soient rouges (les autres restent blanches) ds le
lancement du programme.

Exercice 5.16:

Modifier l'exercice prcdent pour qu'une case sur deux soit rouge.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-36


Exercice 5.17

Ecrire un programme se comportant comme suit:


Au dpart les nombres indiqu sur l'image doivent se trouver dans la grille
Un TrackBar permet de choisir le nombre de colonnes (entre 3 et 8)
Un "ColorGrid" permet de choisir la couleur avec laquelle les cases vides seront remplies
(pour rafrachir le StringGrid: StringGrid1.Refresh).

Exercice 5.18:

Ecrire un programme utilisant un StringGrid de 10 x 10. La couleur des lignes alterne entre jaune
et "acqua". Les cases slectionnes doivent apparatre avec un trait rouge sur leur diagonale:

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-37


Exercice 5.19:

Ecrire un programme qui comporte un StringGrid de 12 x 12 et un ListBox.


Placez quelques mots dans le ListBox. L'utilisateur doit pouvoir:
Cliquer sur une case de la grille
Choisir un mot du ListBox

Ensuite le programme place le mot, partir de la case choisie, de manire que le mot entre dans
la grille. Si la case choisie est en bas droite, le mot partira probablement vers le haut ou vers la
gauche. Indication: ne pas tenir compte des directions en diagonale.

Exercice 5.20:

Ecrire un programme utilisant un StringGrid et simulant le dplacement d'une tour ou d'un fou sur
un chiquier. L'utilisateur choisit la pice (tour ou fou), puis choisit une case. Le programme met
des 'X' ou des 'O' dans toutes les cases qui peuvent tre atteintes par cette pice.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-38


Exercice 5.21:

Ecrire un programme qui transforme les nombres arabes en nombres romains. Le nombre arabe
doit tre limit 4 chiffres. Pour mmoire voici les correspondances entre nombres romains et
arabes: I (1), V (5), X (10), L (50), C (100), D (500) et M (1000).

Exercice 5.22:

Ecrire un programme qui transforme les nombres romains en nombres arabes. Le programme
n'effectue aucun contrle de validit du nombre romain spcifi par l'utilisateur. Celui-ci ne doit
pas pouvoir entrer d'autres caractres que ceux correspondant aux nombres romains. De plus, au
fur et mesure que les caractres sont taps, le nombre romain est affich dans sa forme arabe.

Exercice 5.23:

Amliorer le programme de l'exercice prcdent en vrifiant la syntaxe du nombre romain spcifi


par l'utilisateur, notamment en ce qui concerne les points suivants:

Les squences suivantes ne doivent pas tre admises dans un nombre romain: DD,
CCCC, LL, XXXX, VV, IIII
Dans un nombre romain il peut y avoir deux lettres qui sont dans l'ordre croissant (par
exemple XC dans MXCI), mais pas trois (par exemple IXC dans MIXC). Il ne peut pas y
avoir non plus plus de deux lettres numriquement infrieures la lettre suivante (par
exemple 1109 s'crit MCIX et non MIXC)

Comme la vrification de "syntaxe" ne peut se faire en cours de frappe, prvoir un bouton pour la
transformation

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-39


Exercice 5.24:

Ecrire un programme qui, partant d'un chiffre de dpart donn (ci-dessous le chiffre 1), calcule et
affiche la suite que l'on peut voir dans l'exemple. Pour obtenir une nouvelle ligne, on se base sur
la ligne prcdente numrant son contenu:

Ligne 2: dans la ligne prcdente il y a 1 '1'


Ligne 3: dans la ligne prcdente il y a 2 '1'
Ligne 4: dans la ligne prcdente il y a 1 '2' et 1 '1'
Ligne 5: dans la ligne prcdente il y a 1 '1, 1 '2' et 2 '1''
etc

Comme vous pouvez le constater aucun chiffre plus grand que 3 n'apparat. Essayez de
comprendre pourquoi et de l'expliquer. Cette proprit est-elle valable en partant d'un autre chiffre
que 1 ?

Exercice 5.25:

Ecrire un programme de codage rudimentaire bas sur le principe du XOR. Une cl, choisie par
l'utilisateur, permet de coder et de dcoder un texte. Pour cela il faut appliquer l'oprateur xor
entre le premier caractre du texte coder et le premier caractre de la cl et ainsi de suite pour
les autres caractres. Lorsque l'on a puis les caractres de la cl, on se repositionne sur son
premier caractre. Le mme principe, appliqu au texte cod, permet de retrouver le texte en clair
(d'origine).

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-40


Exercice 5.26:

Ecrire un programme qui gnre le triangle de Pascal sous la forme suivante:

Comme on peut le voir chaque nombre (sauf les 1 des bords) est la somme des deux nombres qui
se situent au-dessus de lui.

Exercice 5.27:

Ecrire un programme de changement de base permettant de passer de la base 10 une base


quelconque comprise entre 2 et 36. Pour pouvez laisser entrer par l'utilisateur un nombre de 18
chiffres au maximum et utiliser le type entier int64 afin de travailler avec de plus grands nombres.
Une liste droulante permet de choisir la base d'arrive.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-41


Exercice 5.28:

Ecrire un programme de simulation de traverse d'une route plusieurs voies. L'utilisateur peut
choisir:
le nombre de voies de la route traverser: entre 1 et 6
la frquence d'apparition d'une voiture, c'est--dire la probabilit qu'il y ait une voiture au
moment de traverser
le nombre de traverses simuler

Le principe est le suivant:

on suppose qu'il faut 1 seconde pour traverser une voie


chaque tentative de traverse, si une voiture se prsente, il faut attendre 1 seconde
supplmentaire

En mmorisant, dans un tableau, le temps ncessaire chaque traverse, on peut savoir combien
il y a eu de traverses qui ont dur n secondes. Le programme doit ensuite reprsenter

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-42


graphiquement les rsultats. Horizontalement est reprsent le temps (on voit sur l'exemple que,
pour une route 3 voies, on met au minimum 3 secondes pour traverser) et verticalement le
nombre de traverses. Etant donn que le nombre de traverses peut varier considrablement,
vous devrez trouver un facteur correctif permettant d'avoir dans la plupart des cas un graphique
entirement visible. Le nombre de traverses admis doit tre compris entre 100 et 9999999.

Exercice 5.29:

Ecrire un programme permettant de gnrer des phrases alatoires, formant un discours. Chaque
phrase est construite partir de quatre fragments, pris dans quatre Listbox correspondants. Le
premier contient des dbuts de phrases, le dernier des fins de phrases et les deux autres des
parties intermdiaires. Chaque Listbox charge son contenu d'un fichier (LISTE1.TXT, LISTE2.TXT,
LISTE3.TXT, ou LISTE4.TXT) au moment du dmarrage du programme. Sous chaque Listbox
figure un Edit dans lequel l'utilisateur peut taper des fragments de phrases qui vont s'ajouter au
Listbox correspondant quand il tape sur <Return>. Pour supprimer un fragment de phrase d'un
Listbox il suffit de faire un double-clic sur la ligne dsire. Il est possible tout moment de
sauvegarder le contenu des quatre Listbox l'aide d'une option du menu Fichier. Enfin, l'utilisateur
peut choisir le nombre de phrases gnrer (le programme insre alatoirement des sauts de
ligne pour constituer des paragraphes) et peut imprimer le discours l'aide du bouton "Imprimer".

Exercice 5.30:

Ecrire un programme permettant de rsoudre les jeux du type mot secret ou mot cach. Une grille
(dans notre cas de 15 x 15) contient des lettres. On dispose galement d'une liste de mots.
Chacun des mots apparat dans la grille et peut tre crit dans les quatre directions
(horizontalement, verticalement et selon les deux diagonales) et dans les deux sens (par exemple

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-43


de haut en bas ou de bas en haut). Une fois que tous les mots de la liste ont t tracs dans la
grille, il est possible de former un mot avec les lettres restantes. Un rgulateur de vitesse
d'excution permet de voir voluer plus ou moins vite la rsolution du jeu.

Vous disposez de deux fichiers de type texte (GR1.GR2 et GR1.MO2), le premier contient les
lettres de la grille, le second la liste de mots.

Dans l'exemple prsent ci-dessous, chaque mot trouv est mis en minuscules et sur fond clair
dans la grille.

Diverses stratgies sont possibles, mais il est conseill de partir des mots de la liste et de les
trouver l'un aprs l'autre.

Exercice 5.31

Cet exercice consiste simuler des mesures de tension lectrique. Il comporte trois tapes
effectuer dans l'ordre.

1re tape:
Gnrer un fichier (MESURES.TXT) de 150 nombres rels compris entre 215 et 225; ces nombres
sont alatoirement distribus entre ces deux limites.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-44


2me tape:
Le bouton Calcul permet de compter combien il y a de mesures dans chaque intervalle de 1 [Volt].
Les rsultats sont placs dans un Listbox.

3me tape:
Le bouton Graphique permet de reprsenter sommairement de manire graphique les rsultats
calculs l'tape prcdente

Vous pouvez amliorer ce programme en indiquant des valeurs et des units sur les axes du
graphique.

Exercice 5.32

Cet exercice consiste simuler une course en ligne droite et en couloir entre 8 concurrents. Les
coureurs sont symboliss par 8 figures rondes (composants de type Tshape). En cliquant sur le
bouton "Dpart" on lance la course. L'avancement des coureurs est contrl par le tirage de
nombres alatoires entre 1 et 8. Le nombre tir permet de faire avancer le coureur du couloir
correspondant.

Le programme fait appel un Timer pour squencer la course.

Lorsqu'un coureur touche la ligne d'arrive, le jeu s'arrte. Le bouton "Nouv. Course" replace les
coureurs leur point de dpart, prts pour une nouvelle course.
Voici comment se prsente ce programme:

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-45


Exercice 5.33

Modifiez le programme de l'exercice prcdent comme suit:

l'utilisateur peut parier sur un coureur en choisissant un no. de couloir. Le coureur choisi
prend la couleur bleu turquoise
lorsque le premier coureur arrive un message indique si l'utilisateur a gagn ou perdu.
Le coureur qui gagne se met clignoter un fois la ligne d'arrive atteinte.
L'utilisateur peut rgler la vitesse des coureurs

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-46


Exercice 5.34

Modifiez le programme prcdent en remplaant l'utilisation d'un Timer par une boucle dont
l'excution est dclenche par le bouton "Dpart"

Exercice 5.35

Le jeu de la vie, invent par J. Conway en 1970, consiste simuler une population de bactries.
Sur un quadrillage (considr comme tant torodal) chaque case est soit vivante soit morte. L'tat
initial est choisi par l'utilisateur. On considre que chaque cellule a 8 voisins. Pour dterminer
l'tape (ou gnration) suivante on doit satisfaire certaines rgles:

une cellule vivante meurt par isolement si elle a 0 ou 1 voisin vivant


une cellule vivante meurt par touffement si elle a plus de 3 voisins vivants
dans les autres cas, la cellule reste vivante
une cellule morte (case vide) qui a exactement 3 voisins vivants devient vivante

Le programme utilise un StringGrid sur lequel l'utilisateur peut cliquer avec le bouton gauche (pour
noircir) ou droit (pour blanchir) une case. Les boutons "Dpart" et "Arrt" lancent et arrtent le jeu.

Delphi (J-C Armici janvier 2003 www.unvrai.com) page 5-47