*** HANDLEIDING VAN MDL-LIB ***

- COPYRIGHT 1990 BY MDL-SOFT -

Als  u  dit  nog  niet  gedaan  heeft,  lees  dan  eerst  de
inleiding, in het bestand INLEIDNG.TXT!

Het bestand DATA bevat twee zeer krachtige  procedures:  n
waarmee u variabelen van elk type bliksemsnel kunt  wisselen
zonder tussenvariabele (in machinetaal geschreven, dus  ECHT
snel), en een procedure waarmee  u  letterlijk  ALLE  sorten
arrays, van ELK type, al of  niet  zelf  gedefinierd,  kunt
sorteren. De  sorteermethode  is  een  bliksemsnelle  Shell-
Metzner sort: uit een test in het programma  MDLTEST  blijkt
dat  het  sorteren  van  100  reals,  random  case,  slechts
ongeveer n seconde duurt... (In  BASIC  zou  het  met  een
Shell-Metzner sort een halve minuut duren!)

----

Naam      : VarSwap
Actie     : Wisselt variabelen
Soort     : Procedure
Declaratie: Procedure   VarSwap(var   var1;   var    var2;
            size:integer);

Deze  procedure  wisselt twee variabelen, die van  elk  type
mogen zijn, van inhoud. 'var1' en 'var2' zijn twee type-loze
VAR-parameters  (als u niet weet wat dat zijn, kijk dat  dan
na in uw PASCAL handboek). 'size' is de grootte in bytes van
de  twee  variabelen, die voor iedere  variabele  natuurlijk
gelijk  moet  zijn.  Het beste kunt u de  grootte  niet  als
constante  opgeven,  maar de functie SIZEOF  gebruiken.  Een
voorbeeld:

var a,b:real;
VarSwap(a,b,sizeof(real));

Zo  hoeft  u  zich niet druk te maken over  de  grootte  van
types:  Pascal rekent die zelf wel uit. (Overigens: het type
mag  natuurlijk  zelf-gedefinierd zijn, en  alle  mogelijke
combinaties van arrays, records etc. bevatten).

----

Naam      : Sort
Actie     : Sorteert alle soorten arrays
Soort     : (bijzondere) Procedure
Declaratie: Procedure Sort(var data;
                      nrOfElements, size, funcaddr:integer);

Deze  procedure  is zo ongeveer de krachtigste uit  de  hele
bibliotheek:   hij  kan  letterlijk  ALLE   soorten   arrays
sorteren, van IEDER type, al of niet zelf gedefinierd.
Laat  ik  beginnen  met een bespreking  van  de  parameters,
daarna volgen nog wat tips.

'data'  is  een typeloze VAR-parameter, die het  array  moet
bevatten dat gesorteerd gaat worden.

'nrOfElements'  is  een integer, die het aantal te  sorteren
elementen  in  het array bevat. Let op dat u  niet  te  veel
elementen  opgeeft, dan zou uw systeem kunnen gaan  crashen.
En anders worden er wel gegevens overhoop gegooid.

'size' is de grootte van n element in het array. Aangezien
het  array  als een typeloze VAR-parameter wordt  opgegeven,
moet de grootte per element er expliciet worden  bijgenoemd.
De grootte kunt u het beste door Pascal laten berekenen, met
SizeOf(<uw  type>).  Dit werkt  ook  voor  zelfgedefinierde
typen en het bespaart een hoop rekenwerk en risico's.

'funcaddr' tenslotte is het  bijzondere  van  deze  functie.
Deze integer bevat namelijk het absolute adres van een  zelf
te  schrijven  BOOLEAN-functie,  dat   met   ADDR(<functie>)
berekend moet worden. Waarom is dat nu z geregeld,  zult  u
zich afvragen? Welnu, voor het sorteren  is  het  nodig  dat
vergelijkingen worden gemaakt,  of  een  element  groter  of
kleiner  is.  Aangezien  de  procedure  ALLES  moet   kunnen
sorteren, is voor ieder type een andere vergelijking  nodig.
Die moet u bij ieder type zelf schrijven, in de vorm van een
BOOLEAN-functie,  waarvan  het  adres  d.m.v.  ADDR  aan  de
Sort-procedure geleverd wordt.
De functie dient de waarde TRUE af te leveren als het eerste
gegeven element groter of gelijk (>=)  is  aan  het  tweede,
anders FALSE. De functie dient er dus zo uit te zien:

Function Vergelijk(var var1,var2:<uw type>):boolean;
Begin
  Vergelijk := (var1 >= var2)
end;

Als u afdalend i.p.v. opklimmend wilt sorteren, verandert  u
de  '>='  in een '<'. Let op: 'var1' en 'var2'  MOETEN  VAR-
parameters zijn, anders crasht uw systeem!!

Er  zal vast nog veel onduidelijk zijn, daarom hier nog twee
voorbeeldjes:

Het sorteren van 100 real-getallen (zie ook MDLTEST):


Var tabel:array[1..100] of real;
....
Function Vergelijk_real(var var1,var2:real):boolean;
Begin
  vergelijk_real := (var1 >= var2)
end;
....
  Sort(tabel,100,sizeof(real),addr(vergelijk_real));


Het  sorteren  van  een  adressenbestand.  Als  de  boolean-
variabele  TRUE  is,  wordt  opklimmend  gesorteerd,  anders
afdalend. 'adres_rec' is een zelfgedefinierd record.


Var opklimmend:boolean;
    tabel:array[1..200] of adres_rec; { zelf gedefinieerd }
....
Function Vgl_adres(var var1,var2:adres_rec);
Begin
  If opklimmend then
    vgl_adres := (var1.naam >= var2.naam)
  else
    vgl_adres := (var1.naam <  var2.naam)
end;
....
  Sort(tabel,200,sizeof(adres_rec),addr(vgl_adres));


Zoals  u ziet, wordt hierboven op naam gesorteerd. Door  een
ander  element van het record op te geven kunt u b.v. ook op
adres sorteren.

Dit voorbeeld  toont  ook  nog  een  voordeel  van  zelf  de
vergelijkings-functie schrijven: u  kunt  het  sorteren  van
allerlei extra voorwaarden laten afhangen.

Wat  ik nog niet behandeld heb, is het sorteren van  meerdi-
mensionale  arrays.  U  moet  dan  per  dimensie   sorteren.
Voorbeeldje (een twee-dimensionaal array van strings):


Type string20 = string[20];
Var tabel : array[0..50,0..5] of string20;
    i     : integer;
....
Function Vgl_string(var var1,var2:string20);
Begin
  vgl_string := (var1 >= var2)
end;
....
  { sorteer het array per dimensie }
  For i:=0 to 50 do { 51 keer }
    Sort(tabel[i],6,sizeof(string20),addr(vgl_string));


Net  zo  gaat het met drie- en meer-dimensionale  arrays,  u
krijgt dan per dimensie n FOR-lus meer.

Merk  op,  dat  b.v.  een  ARRAY[0..10]  OF  <een  type>  11
elementen  bevat: de nul telt in dat geval ook mee.  Vandaar
dat de tweede parameter van de 'sort' hierboven 6 is en GEEN
5.  Dit  probleem doet zich niet voor met arrays die  met  1
beginnen. Nog een voorbeeldje: ARRAY[5..18] OF INTEGER heeft
14 elementen, er moet dus geen 18 maar 14 opgegeven worden.

Voor  meer voorbeelden, zie het programma MDLTEST, onderdeel
DIVERSEN (in de include-file DIVERSEN.PAS). Daarin wordt een
string  gesorteerd, een array willekeurige REAL-getallen  en
een disk-directory.
                                                  