====== Enumération et Set Of======
===== Enumération =====
Ressources sur les énumérations:
* [[https://wiki.lazarus.freepascal.org/Enumerated_types]]
==== Déclaration d'une énumération ====
type
MonthType = (January, February, March, April,
May, June, July, August, September,
October, November, December);
// exemple d'utilisation
var
Month : MonthType;
...
Month := January; // Equivalent a Month := TMonthType(0);
==== Ord ====
La function Ord permet de connaitre la valeur ordinale d'une valeur énumérée.
Exempe :
ord(January) = 0
ord(December) = 11
On peut modifier l'ordinale a la déclaration exemples :
type
TMonthType = (January=1, February, March, April,May, June, July, August, September, October, November, December);
type
TMonthType = (January=1, FirstMonth=1,February=2, SecondMonth=2...);
type
TMonthType = (January=1, February, May=5,June, July);
Dans le dernier cas ''ord(January)''=1, ''ord(February)''=2, ''ord(May)''=5,''ord(June)''=6, ''ord(July)''=7
==== Succ et Pred ====
succ(January) => February...
==== High et Low ====
Retourne respectivement la plus grande valeur (December) ou la plus petite valeur (January)
==== Exemples de codes ====
== Parcourir un ensemble ==
for i := Ord(Low(TMonthType)) to Ord(High(TMonthType)) do
begin
x:= GetEnumName(TypeInfo(TMonthType), Ord(i));
end;
var
vHandlerType: TDragManagerHandlerType;
begin
for vHandlerType := Low(TDragManagerHandlerTypee) to High(TDragManagerHandlerType) do
FreeThenNil(FDragManHandlers[vHandlerType]);
end;
== Passer d'un Type énuméré a un ordinale et réciproquement ==
var
vWS: integer;
begin
vWS := ord(wsFullScreen); //-> 4
WindowState:=TWindowState(vWS);
end;
===== Set Of =====
Ressources sur les Set Of:
* [[https://www.tutorialspoint.com/pascal/pascal_sets.htm]]
* [[https://pascal.developpez.com/cours/cyberzoide/?page=pg_Set]]
* [[https://wiki.freepascal.org/Set]]
==== Déclaration d'une énumération + Set Of ====
type
TMonth = (January, February, March, April,
May, June, July, August, September,
October, November, December);
TMonths = set of TMonth;
==== In ====
on peut tester si un membre fait parti d'un SetOf avec l'operateur IN.
Months: TMonths
...
if January in Months then...
==== Opérateur * pour verifier plusieurs membres du Set ====
if [csLoading,csDestroying,csDesigning]*ComponentState=[] then ...
==== Include / Exclude ====
Include (FComponentState,csUpdating);
...
Exclude(FComponentState,csUpdating);
==== Comprendre les sets ====
=== Comment sont ils stocké en mémoire ? ===
D’après ce que j'ai compris les Sets sont en fait un masque de bits dont la longueur est égal au nombre d’élément dans l'ensemble de base (voir l'exemple ci dessous)
Le Set serait représenté par un ''Longint'' pour les ensembles de moins de 32 éléments.\\
Et sur 32 Octets pour les ensembles de plus de 32 éléments.\\
Ce qui nous ferais un nombre de 256 éléments maximum (Set Of Byte = OK / Set Of Word = Error)...
Donc cela implique qu'il n'est pas possible de connaitre facilement le nombre d’éléments dans un Set, il n'existe pas de length(Set) ou autre.
Un ''high(Set)'' sera égale a un ''high(Elements)''
Exemple:\\
avec l'ensemble ''TTest = (b1,b2,b3,b4)'' soit 4 éléments\\
Le Set of ''TTests = set of TTest'' sera représenté par 4 bits d'un longint\\
Donc ''vTests :=[b1,b4]'' sera representé par ''1001''\\
Donc ''vTests :=[b2,b3]'' sera representé par ''0110''\\
Donc ''vTests :=[]'' sera representé par ''0000''\\
=== Démo ===
Petit programme de démo:
program project1;
uses
sysutils;
type
TBit = (b0, b1, b2, b3, b4, b5, b6, b7);
TBits = set of TBit;
var
vS: string;
vBits: TBits;
pI: pinteger;
begin
vBits := []; //(00000000...)
pI := @vBits; // on "convertit" le Set en Integer
writeln(IntToStr(pI^)); // -> 0
vBits := [b0]; //(10000000...)
writeln(IntToStr(pI^)); // -> 1
vBits := [b1]; //(01000000...)
writeln(IntToStr(pI^)); // -> 2
vBits := [b0, b1]; //(11000000...)
writeln(IntToStr(pI^)); // -> 3
vBits := [b0, b7]; //(10000001...)
writeln(IntToStr(pI^)); // -> 129
end.
=== Passer d'un Integer en Set of ===
Tout se passe dans la procedure ''IntAsSet'' ci-dessous...
program project2;
uses
sysutils;
type
TBit = (b0, b1, b2, b3, b4, b5, b6, b7);
TBits = set of TBit;
var
vS: string;
vBits: TBits;
pI: pinteger;
procedure test(ABits: TBits);
var
//vBit: TBit;
vI: integer;
begin
for vI := Ord(low(TBit)) to Ord(high(TBit)) do
begin
if TBit(vI) in ABits then
writeln(IntToStr(vI) + ' = 1')
else
writeln(IntToStr(vI) + ' = 0');
end;
end;
procedure IntAsSet(AInt: integer; PSet: pointer);
var
pI: pInteger;
begin
pI := PSet;
pI^ := Aint;
end;
begin
vBits := []; //(00000000...)
IntAsSet(255, @vBits);
test(vBits);
ReadLn(vS);
end.