COBOL/Sous-programmes
L'utilisation de sous-programme permet de réutiliser du code : plutôt que de réécrire plusieurs fois le même traitement (le même code), faites plusieurs appels à un même sous-programme. C'est de la programmation procédurale. Un sous-programme permet d'effectuer un traitement particulier (défini par les instructions COBOL qui le composent), vous pouvez lui passer plusieurs arguments en paramètre : lors de son appel, précisez les variables que votre sous-programme pourra utiliser, elles constitueront l'environnement d'exécution du programme et permettront de modifier le résultat de son exécution (il en est de même pour les fonctions mathématiques).
Les sous-programmes, aussi appelés fonctions-utilisateur ou procédures-utilisateur (voire méthodes-utilisateur) sont des programmes que vous écrivez et auxquels vous faites vous-mêmes appel dans d'autres programmes. Un programme peut appeler plusieurs sous-programmes (autres que lui-même).
Appel d'un sous-programme
modifierConsidérons un programme principal (appelant) a et un programme secondaire (appelé) b. Le programme a fait appel au programme b en utilisant l'instruction CALL
:
où prg est le nom du programme appelé, par exemple dans notre cas, nous mettrons "b".
La clause USING
nous permet de spécifier la liste des arguments à passer au sous-programme, vous pouvez en passer autant que vous voulez.
Les variables passées en paramètre doivent être de niveau 01 ou 77.
Vous pouvez précéder chacun de ces arguments (ou chaque groupe d'arguments) de REFERENCE
ou CONTENT
. Le premier est un passage par référence : la variable que vous passez pourra être modifiée par le sous-programme, vous devez donc l’utiliser avec prudence. Le second est un passage par valeur : c’est une copie de l'argument qui est passée au sous-programme et ainsi si celui-ci la modifie, cela n'a pas d'incidence sur la variable d'origine.
- Si aucun mode de passage n'est précisé, c’est le passage par référence qui sera utilisé.
- Si vous n'avez pas besoin de modifier la valeur d'un argument, passez-le par valeur.
Concernant le programme appelé
modifierLes variables passées en paramètre doivent être définies dans la LINKAGE SECTION
de la DATA DIVISION
(juste après la WORKING-STORAGE SECTION
) du sous-programme appelé. Ces définitions doivent être identiques à celles des variables originales (définies dans le programme appelant), à ceci près que la clause VALUE
ne peut être utilisée.
Vous devez également préciser dans la PROCEDURE DIVISION
du programme appelé une clause USING
permettant d'énumérer ces variables : leur ordre d'apparition est important, il doit correspondre à l’ordre utilisé lors de l'appel du sous-programme (l'instruction CALL
).
Il n’est pas nécessaire que les variables aient le même nom dans le programme appelant et le programme appelé. La correspondance des arguments entre les 2 programmes ne se fait pas sur leur nom mais sur leur ordre d'apparition.
Structure des sous-programmes
modifierIl y a deux manières de découper un programme en plusieurs sous-programmes.
Code séparé
modifierLa première façon de faire est de définir les sous-programmes l'un après l'autre. Voici par exemple la définition d'un programme a puis la définition d'un programme b.
000001 IDENTIFICATION DIVISION.
000002 PROGRAM-ID. a.
000003 PROCEDURE DIVISION.
000004 prog.
000005 DISPLAY "Vous êtes dans A".
000006 CALL "b".
000007 DISPLAY "Vous êtes de retour dans A".
000008 STOP RUN.
000009 END PROGRAM a.
000010****************************
000011 IDENTIFICATION DIVISION.
000012 PROGRAM-ID. b.
000013 PROCEDURE DIVISION.
000014 prog.
000015 DISPLAY "Vous êtes dans B".
000016 EXIT PROGRAM.
000017 END PROGRAM b.
b est appelé par a, l'instruction STOP RUN
(qui met fin à l'exécution) est remplacée par EXIT PROGRAM
qui marque la fin du sous-programme.
Code imbriqué
modifierLa seconde façon de faire est d'imbriquer la définition du sous-programme appelé dans celle du sous-programme appelant :
000001 IDENTIFICATION DIVISION.
000002 PROGRAM-ID. a.
000003 PROCEDURE DIVISION.
000004 prog-a.
000005 CALL "b".
000006 STOP RUN.
000007***********************
000008 IDENTIFICATION DIVISION.
000009 PROGRAM-ID. b.
000010 PROCEDURE DIVISION.
000011 prog-b.
000012 EXIT PROGRAM.
000013 END PROGRAM b.
000014***********************
000015 END PROGRAM a.
Ici, la définition du sous-programme b est imbriquée dans celle du sous-programme a : elle est placée entre le STOP RUN
qui marque la fin de l'exécution (en clair : après la dernière instruction) et le END PROGRAM
qui marque la fin du programme.
Cette façon de faire est utile si l'usage du sous-programme b se limite au programme a.
Exemple : MAX de deux entiers
modifierVoici un programme dans lequel nous définissons un sous-programme max (lignes 15 à 29), appelé à partir du programme principal a (lignes 1 à 13).
000001 IDENTIFICATION DIVISION.
000002 PROGRAM-ID. a.
000003 DATA DIVISION.
000004 WORKING-STORAGE SECTION.
000005 77 x PIC 999 VALUE 34.
000006 77 y PIC 999 VALUE 77.
000007 77 max PIC 999.
000008 PROCEDURE DIVISION.
000009 main.
000010 CALL "max" USING CONTENT x y REFERENCE max.
000011 DISPLAY "max (" x "," y ") = " max.
000012 STOP RUN.
000013 END PROGRAM a.
000014****************************
000015 IDENTIFICATION DIVISION.
000016 PROGRAM-ID. max.
000017 DATA DIVISION.
000018 LINKAGE SECTION.
000019 77 a PIC 999.
000020 77 b PIC 999.
000021 77 max PIC 999.
000022 PROCEDURE DIVISION USING a b max.
000023 prog.
000024 IF a > b
000025 THEN MOVE a TO max
000026 ELSE MOVE b TO max
000027 END-IF.
000028 EXIT PROGRAM.
000029 END PROGRAM max.
Nous passons 3 variables à notre sous-programme : 2 que nous ne modifierons pas et que nous passerons donc par valeur, et une dernière qui prendra la valeur du maximum des deux autres que nous passerons par référence.
L'ordre de passage des arguments nous indique que les variables a, b, max du programme appelé correspondent aux variables x, y, max du programme appelant.