Nous attaquons cette partie avec une autre notion : les tableaux. Ces derniers désignent une suite finie d’éléments du même type.
Déclaration
La déclaration d’un tableau se fait dans la DATA DIVISION
.
Pour préciser qu’une variable est un tableau, il faut utiliser le mot-clef OCCURS
suivi d’un nombre représentant la taille du tableau. Il contient obligatoirement un nombre fini d’éléments représentant la taille du tableau. Ces éléments peuvent être des entiers, des réels, des chaînes, etc.
Nous allons voir les différents tableaux possibles à travers quelques exemples.
Tableau unidimensionnel
Voici l’exemple le plus classique que vous allez trouver :
* En tête...
WORKING-STORAGE SECTION.
01 tableau.
02 entier PIC 9 OCCURS 10.
Résumons avec un schéma :
Tableau d’entiers à 1 dimension et 10 entrées
Vous voyez que sur le schéma, mes cellules sont numérotées de 1 à 10, et non de 0 à 9. Contrairement à la majorité des langages, en Cobol un tableau commence à l’indice 1 et non 0.
Tableau multidimensionnel
Voilà un exemple de tableau bidimensionnel :
01 tab.
02 ligne OCCURS 3. * Le nombre de lignes
03 cellule PIC 9 OCCURS 5.* Le nombre de colonnes
Vous pouvez créer jusqu’à 6 dimensions en imbriquant le mot clé OCCURS
à chaque ligne, mais au-delà de 3, gérer son tableau devient une tâche difficile. Voilà à quoi cela ressemble :
Tableau à 2 dimensions
Tableau de structure
01 tab.
02 ligne-carre OCCURS 3.
03 cellule OCCURS 5.
04 prenom PIC x(30).
04 nom PIC x(30).
Dans cet exemple, chaque cellule contient une structure à la place d’une simple variable ; pour faire simple, c’est comme si la cellule était divisée en plusieurs parties contenant chaque information. Encore une fois, rien ne vaut une bonne illustration :
Tableau de structure à 2 dimensions
Affectation
Bon, déclarer nos tableaux c’est bien, mais les utiliser c’est mieux !
On va prendre l’exemple le plus simple avec une dimension, nous allons demander à l’utilisateur jusqu’à combien il veut compter et nous remplirons le tableau selon ce qu’il désire.
IDENTIFICATION DIVISION.
PROGRAM-ID. Tableau.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 n PIC 99.
77 i PIC 99.
01 tab.
02 entier PIC 99 OCCURS 99.
SCREEN SECTION.
01 pls-n.
02 BLANK SCREEN.
02 LINE 5 COL 8 VALUE 'Valeur de n : '.
02 PIC 99 TO n REQUIRED.
01 pla-tab.
02 BLANK SCREEN.
02 LINE 2.
02 OCCURS 99.
03 LINE + 1 COL 5 PIC zz FROM entier.
PROCEDURE DIVISION.
INITIALIZE tab.
DISPLAY pls-n.
ACCEPT pls-n.
PERFORM TEST AFTER VARYING i FROM 1 BY 1 UNTIL i = n
MOVE i TO entier(i)
END-PERFORM.
DISPLAY pla-tab.
STOP RUN.
Sortez vos loupes !
On va analyser ce code de manière un peu plus approfondie.
Pour la partie située dans la WORKING-STORAGE SECTION
, les explications sont données dans la partie traitant la déclaration donc je ne vais pas y revenir, il vous suffit de lire le début du chapitre.
Voyons plutôt du côté de pla-tab
:
01 pla-tab.
02 BLANK SCREEN.
02 LINE 2.
02 OCCURS 99.
03 LINE + 1 COL 5 PIC zz FROM entier.
OCCURS permet de choisir le nombre de ligne que l’on veut afficher lors de l’affichage de notre tableau. Donc là, on va afficher le tableau complet, soit 99 lignes.
La ligne suivante, permet de récupérer ligne par ligne le contenu de la variable entier. Vous pouvez également constater la petite subtilité qui permet de sauter une ligne à chaque affichage avec LINE + 1
.
Passons au PROCEDURE
:
PROCEDURE DIVISION.
INITIALIZE tab.
DISPLAY pls-n.
ACCEPT pls-n.
PERFORM TEST AFTER VARYING i FROM 1 BY 1 UNTIL i = n
MOVE i TO entier(i)
END-PERFORM.
DISPLAY pla-tab.
STOP RUN.
Une fois que l’utilisateur a choisi le nombre qu’il veut, nous remplissons le tableau jusqu’à la valeur saisie. Nous faisons un TEST AFTER
afin d’arriver jusqu’à l’indice n, sans lui nous irions seulement jusqu’à l’indice n-1 (rappelez-vous le schéma dans le chapitre sur les boucles).
Ensuite, nous ajoutons le numéro de l’itération dans le tableau grâce à MOVE i TO entier(i)
.
J’ai utilisé MOVE
pour attribuer une valeur à entier(i)
, mais on peut aussi le faire avec COMPUTE
.
Je ne comprends pas très bien là… Pourquoi entier(i)
et pas pla-tab(i)
comme dans les autres langages ?
Voilà une autre particularité du Cobol : on accède au contenu d’un tableau via le nom de la cellule, et non celui du tableau ! Donc entier(1) vaut 1, entier(2) vaut 2, etc.
Ensuite DISPLAY pla-tab
pour afficher notre tableau, voici le résultat pour n = 10 :
1
2
3
4
5
6
7
8
9
10
Autre méthode
Jusqu’à maintenant nous avons afficher notre tableau d’un bloc, mais vous pouvez aussi le faire ligne par ligne comme ceci :
* En tete et déclaration...
01 pla-ligne.
02 LINE i.
02 COL 5 PIC zz FROM entier(i).
PROCEDURE DIVISION.
INITIALIZE tab.
DISPLAY pls-n.
ACCEPT pls-n.
PERFORM TEST AFTER VARYING i FROM 1 BY 1 UNTIL i = n
MOVE i TO entier(i)
DISPLAY pla-ligne
END-PERFORM.
STOP RUN.
Le résultat est exactement le même mais c’est simplement pour vous montrer une autre manière de procéder.
Taille des tableaux
Pour l’instant je vous ai uniquement montré comment faire des tableaux à taille fixe, mais il est également possible de faire des tableaux dont la taille varie.
01 tab.
02 default PIC 99.
02 val PIC 9 OCCURS 1 TO 50 DEPENDING default.
De manière plus globale, la syntaxe peut se représenter de la manière suivante : OCCURS x TO y DEPENDING z
. x symbolise la taille minimum du tableau, y la taille maximum et z la taille par défaut.
Donc z doit se situer entre x et y, sous forme plus mathématique cela se traduit par :
Je ne l’ai pas vraiment abordé de manière précise, mais pour les tableaux à plusieurs dimensions, l’accès à une cellule se fait comme ceci : cellule(i,j,k)
Opérations
Certaines fonctions permettent d’effectuer des opérations sur les tableaux, nous allons en voir deux.
Faisons le tri !
La première opération que nous allons voir c’est comment trier nos tableaux. Nous allons reprendre l’exemple de tout à l’heure en le modifiant un petit peu :
PROCEDURE DIVISION.
INITIALIZE tab.
MOVE 15 TO n.
PERFORM TEST AFTER VARYING i FROM 1 BY 1 UNTIL i = n
MOVE i TO entier(i)
END-PERFORM.
SORT entier DESCENDING.
DISPLAY pla-tab.
En exécutant notre programme, l’affichage sera :
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
Je pense que vous l’aurez compris, SORT entier DESCENDING
permet de trier les éléments de notre tableau par ordre décroissant. Ici nous utilisons DESCENDING
car nos éléments ont été ajoutés par ordre croissant.
Mais dans le cas où les entrées sont dans un ordre aléatoire et que l’on veut afficher notre tableau dans l’ordre, il suffit d’utiliser l’opération inverse, à savoir ASCENDING
.
La recherche
L’un des avantages des tableaux, c’est que l’on peut facilement rechercher l’élément qui nous intéresse grâce à une fonction toute faite.
Pour pouvoir faire une recherche il faut que notre tableau soit indexé, lors de sa déclaration nous allons ajouter ceci :
01 tab.
02 entier PIC 99 OCCURS 99 INDEXED BY indice.
Et notre recherche dans PROCEDURE DIVISION
se fait comme ceci :
SET indice TO 1.
SEARCH entier
AT END
DISPLAY "Element introuvable..."
WHEN entier(indice) = 5
DISPLAY "Element " entier(indice) " trouve ! ".
Pour pouvoir commencer notre recherche correctement, il faut initialiser l’indice de départ. Donc avec SET indice TO 1
nous positionnons notre curseur de recherche à la cellule 1. Ensuite il faut indiquer dans quelle cellule on veut chercher notre élément, ce qui correspond à SEARCH entier
.
La clause AT END
est optionnelle, mais je la mets ici, pour signaler à notre utilisateur si la recherche ne renvoie aucun résultat, ce qui affichera "Element introuvable…" à l’écran.
Ensuite, à la manière d’une condition multiple avec le mot WHEN
, nous allons énoncer nos conditions. Ici je cherche si 5 se trouve dans notre tableau entier. Si un élément est trouvé alors on affiche "Element 05 trouve !", sachant qu'indice joue le rôle de variable d’itération.
Nous avons fait le tour en ce qui concerne les tableaux en COBOL, comme d’habitude, on se retrouve au prochain chapitre.