Jusqu'à présent nous avons vu comment utiliser des sous-programmes (plus précisemment comment utiliser les fonctions prédéfinies) mais pas comment en définir de nouveaux.
Dans cette partie du cours, nous abordons le problème de la définition de nouveaux sous-programmes par le développeur.
Pour simplifier les explications, nous ne considérerons en un premier temps que les procédures.
Le cas des fonctions sera décrit ultérieurement.
Une procédure est un sous-programme qui ne retourne pas de valeur et qui agit nécessairement sur son environnement exterieur (modifie des variables globales, affiche des résultats, lit des données, fait des accès disque, etc ....). |
Prenons par un exemple la procédure AfficherNote dont nous verrons le code un peu plus loin.
Cette procédure possède deux paramètres (en mode de passage par valeur):
L'effet de cette procédure est d'afficher le nom et la note données dans une zone de liste.
L'appel d'une procédure est une instruction dont l'exécution provoque l'exécution de son code. |
Comme dans le cas des fonctions, si la procédure possède des paramètres (tous en mode de passage par valeur) , cette exécution se fera avec les valeurs d'appel qui seront affectés à ses paramètres dans l'ordre où elles apparaissent.
Par contre, un appel de procédure n'est pas une expression. Il ne pourra donc pas figurer à droite du signe = d'une affectation, ni à aucun emplacement de programme où pourrait figurer une expression.
Mais contrairement à une fonction, un appel de procédure peut figurer là où pourrait figurer une affectation. Donc en particulier, de manière isolé sur une ligne de code.
Voici par exemple un appel de la procédure AfficherNote:
AfficherNote "Thirion", 7 |
Lorsque l'interpréteur Visual Basic exécutera cette instruction, il va en fait exécuter le code de la procédure AfficherNote, en donnant au préalable la valeur "Thirion" au paramètre Nom et la valeur 7 au paramètre Note.
Après cet exécution, il reviendra automatiquement à l'instruction qui suit immédiatement l'instruction d'appel. Supposons par exemple que l'instruction d'appel précédente soit suivi de l'instruction i = 1:
Après avoir exécuté la procédure AfficherNote avec les valeur "Thirion" et 7, l'interpréteur revient automatiquement dans la procédure appelante (celle qui contient l'instruction d'appel) à l'instruction suivante. Dans notre cas, la prochaine instruction exécutée sera donc i = 1.
En Visual Basic, un appel de procédure s'écrit de la manière suivante :
Nom de la procédure V1, V2, ..., VN |
où V1, V2, ...,VN représentent les valeurs des N paramètres de la procédure. Dans le cas le plus simple, ce sont des littéraux. Dans le cas le plus général, ce sont des expressions.
Pour appeler une procédure sans paramètre, on écrira simplement son nom.
Remarquez qu'il n'y a pas de parenthèses autour des valeurs des paramètres (ceci est particulier à Visual Basic).
La déclaration d'une procédure sert à définir son nom, ses paramètres et son code. |
Dans le code d'une procédure figureront en général, des variables locales et des instructions utilisant les paramètres.
Ces instructions ne seront exécutés que si la procédure est appelée au moins une fois à un endroit quelconque du programme.
Rappelons que c'est à ce moment là et uniquement à ce moment là, que les paramètres prendrons une valeur (les valeurs d'appel) et que le code de la procédure sera exécuté avec ces valeurs de paramètres.
Voici par exemple comment est défini la procédure AfficherNote (cet exemple se trouve dans le projet Exemple/Notes.vbp:
La première ligne est l'entête de la procédure. Dans cet entête on trouve:
L'entête sert donc à définir les paramètres de la procédure.
Entre l'entête et End Sub se trouve le corps de la procédure. Il contient généralement des déclarations de variables locales (optionnel) et les instructions à exécuter lorsque la procédure sera appelée.
Dans cet exemple, nous avons déclarez une variable locale, Ligne de type String.
Cet déclaration est suivie de deux instructions à exécuter: une affectation et un affichage.
En Visual Basic, une procédure se déclare de la manière suivante :
Sub nom de la procédure ( Liste de paramètres ) [Déclaration des variables locales] Instructions End Sub |
La déclaration des variables locales est optionnelle.
La liste des paramètres (éventuellement vide ) peut s'écrire de différentes manières. Pour des raisons pédagogiques, nous ne verrons pour l'instant que celle-ci:
ByVal nom de variable As type, ... , ByVal nom de variable As type |
Le passage par valeur est l'affectation des valeurs aux paramètres d'une procédure lors de son appel.
Pour illustrer ce mécanisme, reprenons l'exemple de la procédure AfficherNote.
Dans notre exemple, la procédure AfficherNote est appelée deux fois dans Form_Load:
Rappelons que Form_Load est une procédure évènementielle qui est automatiquement exécutée au démarrage d'un programme Visual Basic.
Dès le démarrage du programme, la première instruction exécutée sera donc le premier appel de la procédure AfficherNote.
Dans ce premier appel, la procédure sera exécutée avec les valeurs "Thirion" pour le paramètre Nom et 7 pour le paramètre Note.
A ce moment là, la valeur "Thirion" sera affectée au paramètre Nom de la procédure et la valeur 7 au paramètre Note. Puis le code de la procédure sera exécuté avec ces valeurs de paramètres, ce qui aura pour effet d'afficher la chaine la chaine "Thirion:7" dans la zone de liste.
D'après le mécanisme de retour que nous avons expliqué à la section II (Appel d'une procédure), l'interpréteur reviendra ensuite dans la procédure Form_Load, juste après le premier appel de la procédure AfficherNote. Il exécutera donc le deuxième appel. La figure suivante illustre ces différentes opérations:
La valeur "Knuth" sera alors affectée au paramètre Nom de la procédure et la valeur 18 au paramètre Note. Puis le code de la procédure sera exécuté avec ces valeurs de paramètres, ce qui aura pour effet d'afficher la chaine "Knuth:18" dans la zone de liste.
Enfin, l'interpréteur retourne dans Form_Load, à l'instruction qui suit le deuxième appel. Comme il n'y en a pas. Il quitte la procédure Form_Load et se remet en état d'attente d'un évènement. La figure suivante illustre ces différentes opérations:
En fait, tout se passe comme si les instructions suivantes avaient figurées dans Form_Load (pour vous aidez, j'ai mis le code de la procédure AfficherNote à droite):
Private Sub Form_Load () Dim ligne As String ligne = "Thirion" + ":" + Str(7) Afficher ligne, ZoneListeNotes ligne = "Knuth" + ":" + Str(18) Afficher ligne, ZoneListeNotes End Sub |
Sub AfficherNote(ByVal Nom As String, ByVal Note As Integer) Dim ligne As String ligne = Nom + ":" + Str(Note) Afficher ligne, ZoneListeNotes End Sub |
Les instructions en rouge sont équivalentes à l'appel AfficherNote "Thirion", 7.
Les instructions en bleu ont équivalentes à l'appel AfficherNote "Knuth", 18.
On aurait donc pu faire la même chose sans appel de procédure, me direz vous. Oui, mais en écrivant plus de code !
Ici, nous n'avons pas gagné grand chose car la procédure AfficherNote ne contient que deux instructions. Mais imaginez qu'elle en contienne 100 !
Rappelez vous qu'une des raisons principales de l'existence des sous-programme est de pouvoir réutiliser du code.