Les Record complexes (Union en C)

Il est parfois nécessaire de manipuler une donnée de façon "variable", le bon exemple étant le type Variant, c'est une variable qui contient un peu n'importe quoi, un entier, une chaine de caractère...

l'union en Pascal se fait avec un CASE ... OF, ou un transtypage.

Le CASE...OF

Deux syntaxes sont possibles
Type

 Valeur=record
  flag:byte;
  case byte of // utilisation d'un type qui permet juste d'indiquer des valeurs "case"
   1 :(AsByte:byte);
   2 :(AsInteger:integer);
  end;
 // notez l'absence d'un second END qui terminerait le RECORD !

on pourrait dans ce cas utiliser un autre type comme par exemple
Type
 Valeur=record
  flag:byte;
  case boolean of // utilisation d'un type qui permet juste d'indiquer des valeurs "case"
   true :(AsByte:byte);
   false:(AsInteger:integer);
  end;
 // notez l'absence d'un second END qui terminerait le RECORD !

on déclare ici un record contenant un champ flag, un champ AsByte et un champ AsInteger c'est l'union de deux records :
Type
 Valeur1=record
  flag  :byte;
  AsByte:byte;
  // plus 3 octets bidon pour avoir la même taille que Valeur2 !
 end;
 Valeur2=record

  flag:byte;
  AsInt:integer; // qui fait 3 octets de plus que AsByte :)
 end;
deuxième syntaxe:
Type
 Valeur=record

  case flag:byte of // le case utilise une variable en plus du type
   1:(AsByte:byte);
   2:(AsInteger:byte);
  end;
 // pas de END pour le RECORD
on obtient exactement le même résultat ! mais la déclaration laisse supposée que "flag" contiendra 1 ou 2 selon l'usage du record... mais c'est pas obligé, Valeur.AsByte et Valeur.AsInteger sont tous les deux valides quelque soit la valeur de flag !

Le Transtypage

Type
 Valeur1=record
  flag  :byte;
  AsByte:byte;
  // plus 3 octets bidon pour avoir la même taille que Valeur2 !
 end;
 Valeur2=record

  flag:byte;
  AsInt:integer; // qui fait 3 octets de plus que AsByte :)
 end;

procedure Exemple(var v);
 begin
  case byte(v) of // accès au champ "flag" qui est le premier byte de v

   1 : with Valeur1(v) do begin ... end; // traiter v comme un "Valeur1"
   2 : with Valeur2(v) do begin ... end; // traiter v comme un "Valeur2"

  end;
 end;