
                           --------------------
                           - Le pascal facile -
                           --------------------


        Ce  volet  de  la  série  est  consacré  aux  types  structurés  de
      données. Pour exemple est joint le programme 'Operation_Embouteillage'
      et le source correspondant.


         Enoncé du probléme 'Opération Embouteillage'
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

         Une ville decide de munir une de ses grandes avenues d'une onde
      verte (une voiture roulant à la vitesse maximum autorisée en ville n'est
      jamais arrêtée par un feu rouge). Cette grande avenue a 4 rues transver-
      sales. Le second feu est distant du premier de 500 mètres, le troisième
      du second de 800 mètres et 1000 mètres entre le quatrième et le troisi-
      ème. La vitesse maximum en ville est de 50 km/h. Faire le programme qui
      représente les feux de l'onde verte et les feux des rues transversales.
      Rappel : une onde verte est à sens unique.


      1 Que sont les types structurés
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        Les variables structurées sont les tableaux, les enregistrements, et
      les fichiers. Elles n'existent que pour simplifier la vie du programmeur
      quand il doit jongler avec un nombre conséquent de variables (tableau).
      Il est beaucoup plus simple d'avoir un tableau de 100 cases que 100
      variables de nom différents. Dans cet article sont expliqués les
      enregistrements et les tableaux. Dans le prochain article, nous
      aborderons en détails les fichiers, dont vous avez deja eu un aperçu
      dans le premier article.

      2 Les tableaux
      ~~~~~~~~~~~~~~

        2.1 Définition

          Les tableaux son composés d'un nombre fixe d'éléments d'un même
      type. Ils sont définis par un indice et un type. Il existe deux sortes de
      tableaux, les simples et les multidimensionnels, ceux-ci étant
      considérés comme des tableaux de tableaux.

        2.2 Déclaration

          La syntaxe de déclaration d'un tableau est :
                
                  var nom : array[ind1,...,indn] of type;

          où 'nom' est le nom du tableau, 'ind1' et 'indn' sont des types
      d'indices et 'type' le type de données que contient le tableau.

        2.3 Exemple

          L'exemple est tiré du source 'operation_embouteillage'.

                  t : array[1..4,1..3] of feu;

          où 'feu' est un enregistrement (voir section 3).
          Cet exemple déclare un tableau de 12 éléments, pouvant être
      représenté ainsi :

		t[1,1] 		t[2,1] 		t[3,1] 		t[4,1]

		t[1,2] 		t[2,2] 		t[3,2] 		t[4,2]

		t[1,3] 		t[2,3] 		t[3,3] 		t[4,3]

        2.4 A noter

          Les chaînes de caractères sont des tableaux unidimensionnels dont la
      taille est déclarée par 'allocstring'. Voir le source 'Multi_exemples'
      joint au précédent article.

        2.5 Utilisation

          Un petit source pour voir un peu ce que l'on peut faire avec les
      tableaux.

                    program tableau;

                    var i,j : integer;
                        t : array[1..2,1..2] of real;

                    begin
                     for i := 1 to 2 do
                      for j := 1 to 2 do
                      begin
                       write('entrez le nombre de la colonne ',i,' et de la ligne ',j,' : ');
                       readln(t[i,j]);
                      end;

                     {
                      Réalisation d'un produit en croix. Sont connus : t[1,1],
                      t[2,1] et t[2,2]. Pour ceux qui ne savent pas ce qu'est
                      un produit en croix, un exemple :
                       Un institut de sondage sonde 1234 Amigaïstes. Sur 1234,
                      962 déclarent posséder au minimum 3 Amiga 4000 (quel bel
                      exemple!). 962 pour 1234, mais conbien pour 100? Cela
                      donne schématiquement 
                                              962 --> 1234
                                               ?  -->  100

                                           962x100
                      Le résultat, c'est   ------- = 77,95 donc 77,95%
                                            1234
                      
                     }

                     t[2,1] := (t[1,1]*t[2,2])/t[2,1];
                     writeln('le resultat est : ',t[2,1]);
                    end.


      3 Les enregistrements
      ~~~~~~~~~~~~~~~~~~~~~

        3.1 Definition

          Un enregistrement est un ensemble de données d'un même type ou de
      types différents. Chaque donnée est un champ de l'enregistrement. Le
      nombre de données dans un enregistrement est invariable au cours du
      programme qui en utilise. Un champ peut être un enregistrement et ainsi
      de suite. La doc ne mentionne pas de restriction sur ce fait (voir par
      exemple la structure (enregistrement) 'window' dans 'intuition.i' qui
      pointe sur une structure Rastport qui pointe sur une structure AreaInfo).

        3.2 Déclaration

          La syntaxe de la délaration d'un enregistrement est :

                    type
                           nom_enr = record
                                   champs_1 : type_champs_1;
                                   champs_2 : type_champs_2;
                                   .
                                   .
                                   champs_n : type_champs_n;
                           end;

                    var
                           variable : nom_enr;


          où 'nom_enr' est le nom de l'enregistrement, 'variable' est une
      variable de type 'nom_enr'.

        3.3 Exemple

          Cet exemple est tiré du source 'operation_embouteillage'.

                    type
                        feu = record
                           x     : integer;
                           y     : integer;
                           temps : byte;
                           etat  : byte;
                           texte : string;
                        end;

                    var
                        t : array[1..4,1..3] of feu;

                    .
                    .
                    .
                     t[1,1].temps := 15;
                     t[1,1].etat  := rouge;
                     t[1,1].texte := rouge1_tx;
                     t[1,1].x     := 12;
                     t[1,1].y     := 15;

          Nous pouvons voir comment assigner une valeur à un champ :

                    variable . champ := valeur;
                             ~

        3.4 L'instruction 'with'

          With est une instruction spécialement dédiée aux enregistrements. On
      l'utilise quand on a plusieurs opérations succéssives à faire sur un
      enregistrement. Sa syntaxe est :

                    with nom_enr do
                    begin

                     .
                     .
                     .

                    end;

          où 'nom_enr' est le nom d'un enregistrement.

        3.5 Exemple

          Toujours tirés du source 'Operation_embouteillage'.

                    procedure affiche(fire:feu);
                    begin
                     with fire do
                     begin
                      gotoxy(a,x,y);
                      textcolor(a,etat);
                      writestring(a,texte);
                     end;
                    end;

          Explication : avec l'enregistrement 'fire', va en x,y, ecrit en
      couleur 'etat' et ecrit 'texte'. x, y, etat et texte sont des champs de
      l'enregistrement feu (voir plus haut).

        3.6 Les pointeurs

          Un pointeur contient l'adresse d'une variable de n'importe quel type
      (des entiers aux enregistrements). Lors de l'utilisation des pointeurs
      avec des enregistrements, leur intérêt est flagrant : dans la procédure
      prise en exemple au-dessus, je passe comme argument à la procédure un
      enregistrement complet, alors qu'avec l'utilisation d'un pointeur, je
      transfère seulement l'adresse. J'espère que l'association 'moins de
      données = moins de temps' s'est faite immédiatement chez vous.

          On trouve deux sortes de pointeurs. Les pointeurs 'déclarés' et les
      pointeurs 'pirates'.
          Les pointeurs 'pirates' sont des pointeurs qui ne sont pas déclarés
      au début du programme par un 'var' et qui sont désignés pointeur par le
      signe '@' (Alt-Shift-3) que l'on place devant le nom de la variable
      pointée. Exemple :

                    @t[1,1]

          est un pointeur contenant l'adresse de l'élement 1,1 du
      tableau t.
          Les pointeurs 'déclarés' sont déclarés par un var. Par exemple le
      pointeur w sur l'enregistrement window correspondant (dans le source
      'operation_embouteillage').

          Comment définir un pointeur. Pour la déclaration d'un pointeur pour
      un enregistrement, il faut, après le 'end;' de l'enregistrement, placer
      une ligne ayant cette syntaxe :

                    nom_enrptr = ^nom_enr;

          où 'nom_enr' est le nom de l'enregistrement defini auparavant.

                Exemple :
                
                         window = record
                         }
                         }
                         }
                         end;
                         
                         windowptr = ^window

          Il est aussi possible de définir un pointeur sur n'importe quel type
      de donnée : integer, byte, short, ...

          Lors de l'utilisation de pointeurs avec des enregistrements, il faut
      insérer un '^' entre le nom de l'enregistrement et le nom du champ,
      avant le point les séparant. Exemple :

                    @t[1,1]^.texte       ou        w^.rport

          L'utilisation des pointeurs avec 'with' est aussi possible mais au
      lieu de

                    with fire do

          il faut mettre

                    with fire^ do

                A noter : un pointeur 'pirate' : pirate n'est peu être pas
                          le mot approprié mais je n'ai trouvé que celui-là.
                          Leur utilisation est très courante, surtout avec
                          intuition (prochains articles). Alors utilisez les
                          sans crainte.

        3.7 Modification

          Modification à apporter au source pour une utilisation avec des
      pointeurs :

                    * après la déclaration de l'enregistrement, ajouter
                      'feuptr = ^feu'
                    * dans la procédure 'change_etat', 'affiche(t[i,j]);'
                      devient 'affiche(@t[i,j]);, ainsi que dans la procédure
                      'graphique'.
                    * le début de la procédure 'affiche' devient :

                               procedure affiche(fire : feuptr);
                               begin
                                with fire^ do
                                begin


          D'autres explications sont dans le source joint.

          Pour toutes les questions que vous vous posez sur la programmation
      en PCQ, contactez moi.

                              Michel TOURNAY
                             27 rue Felix Pres
                             08600 FROMELENNES
                                 (France)

          Petit message pour Christophe LARATTE : Le MiniP4, c'est très bien!
      mais c'est trooooop duuuuuuuuur!!!!!!!!!!!! Il pense trop bien, l'Amiga!