Partie I : 6) Les fonctions et les Sub
L'ordinateur va commencer d'exécuter notre programme au début du corps et va terminer l'exécution à la fin du corps.
Mais il existe aussi des parties de notre code qui ne feront pas partie du corps. Il y a deux types distingues pour ces portions de code : les Fonctions et les Sub.
Nous allons commencer par apprendre à s'en servir puis, dans un second temps, à les créées.
Étant donné que les fonctions et les Sub se ressemblent énormément, je vais expliquer profondément les Fonctions puis je vous expliquerais les Sub.
L'indentation
Maintenant, vous allez commencer à faire des programmes de plus en plus complexes. C'est pourquoi il va falloir respecter certaines règles au niveau de la présentation de votre code.
Mais la règle la plus importante est l'indentation.
En fait, l'indentation est une manière de taper votre code pour beaucoup plus de lisibilité. Chaque bloc de code spécifique sera indenté c'est à dire qu'il faudra rajouter une tabulation devant pour le décaler vers la droite.
Et là vous allez me demander :
A quoi cela peut bien servir ?
Et bien un exemple concret vous le montrera mieux que n'importe quel discours.
Voici un code qui ne sert à rien mais qui contient une erreur :
Code VB :
a=50 if a=1 then goto [fin] else while a>1 a=a-2 if a=30 or a=20 or a=10 then print "A="; print a wend end if end if
Dites moi comme ça du premier coups d'œil où est l'erreur ?
C'est dure hein?

Maintenant, chaque fois que vous tombez sur une condition ou une boucle, vous rajoutez une tabulation à l'intérieur de la boucle ou de la condition.
Comme ceci :
Code VB :
if a=1 then ' [ Ici on a une condition donc on indente tous ce qu'il y a dedans for i=0 to 50 ' | [ Ici le début d'une boucle donc rebelote, on indente print "Bonjour" ' | | next ' | ] else ' ] i=0 while i<>50 i=i+1 print "Au Revoir" wend end if
Comme ceci on voit très bien chaque bloc de code.
Maintenant, essayez d'indenter le code erroné pour trouver l'erreur.
Caché:
Code VB :
a=50 if a=1 then goto [fin] else while a>1 a=a-2 if a=30 or a=20 or a=10 then print "A="; print a wend ' notre probleme vient de là, on ferme le While avant de fermer le If end if end if
Et donc le code sans erreur :
Code VB :
a=50 if a=1 then goto [fin] else while a>1 a=a-2 if a=30 or a=20 or a=10 then print "A="; print a end if wend end if
Comme vous pouvez l'avoir vu il est beaucoup plus simple d'indenter son code en même temps qu'on l'écrit plutôt qu'après.
Voila maintenant que vous connaissez l'indentation on va pouvoir passer aux fonctions

Théorie
Je vous ai dit que les Fonctions et les Sub sont des portions de code qui ne sont pas dans le corps du programme. Or je vous ai aussi dit que l'ordinateur n'exécutait que ce qu'il y avait dans le corps, donc, logiquement, les Fonctions et les Sub ne sont pas exécutées.
Et c'est vrai, mais on peut dire à l'ordinateur de les exécuter, autrement elles ne serviraient pas à grand-chose ^^ .
On appelle cette action appeler une Fonction ou une Sub.
Et devinez où on va appeler une Fonction ou une Sub ?
Euh, je ne sais pas ... dans le corps ?
Exactement.
L'ordinateur arrive à la ligne où l'on appelle la Fonction ou la Sub, il va donc exécuter le code de cette Fonction ou de cette Sub.
Une fois le code de la Fonction ou de la Sub exécuté, l'ordinateur retourne dans le corps du programme et continu son exécution après l'appelle.
De plus, chaque Fonction et chaque Sub possède des noms distingues, ainsi, lors de l'appelle de la Fonction SQR l'ordinateur saura où aller (cette fonction est un exemple que nous étudierons plus en détaille tout le long de ce chapitre).
Voici, de façon schématisé, comment ça se passe :

Mais le mieux et le plus utile c'est que l'on peut appeler une Fonction ou une Sub plusieurs fois. Un autre schéma :

Voila pour ce qui est de la théorie, maintenant passons à la pratique.
Utiliser une Fonction
On va prendre pour exemple une Fonction dite innée, c'est-à-dire que vous n'aurez pas besoin d'avoir un bout de code supplémentaire à coté du corps principal de votre programme, ce code est rajouté automatiquement lors de la compilation.
Je vous présente donc la fonction innée SQR. En général, on note le nom d'un fonction avec des parenthèses, comme ceci : sqr(). Ca fait comprendre que SQR est une fonction. On peut donc dire simplement : "Je vous présente donc sqr()"
Vous avez peut-être remarqué que j'utilise indifféremment les majuscules et les minuscules pour le nom de cette fonction. En faite, normalement le nom des Fonction et des Sub est sensible à la case (un "a" minuscule est considéré différent d'un "A" majuscule) donc une fonction qui s'appelle racine() ne pourra pas être appelée avec le nom RaCiNe() par exemple.
Mais dans le cas présent on a le droit car c'est une fonction innée, donc son nom est insensible à la case (un "a" minuscule est considéré comme similaire à un "A" majuscule).
Bon, revenons à notre fonction, comme je vous l'ai dit plus haut, elle sert à obtenir la racine carrée d'un nombre ...
C'est bien beau de savoir qu'elle sert à obtenir une racine carrée mais comment fait-on pour lui demander la racine carrée de 625 ?!
Pour cela on utilise ce que l'on nomme les paramètres.
Voici comment on fait pour appeler une fonction avec des paramètres :
Code VB :
sqr(625)
Ici, il n'y a qu'un seul paramètre, c'est le nombre dont on veut la racine carrée.
On place le/les paramètre(s) entre les parenthèses.
Et juste avant la parenthèse ouvrante, on écrit le nom de la fonction.
On peut donc traduire cette ligne par : appel la fonction sqr() avec le paramètre 625.
Allez-y, cliquer sur Run pour voir le résultat.
Ça ne marche pas, il y a une erreur !!
En effet, et c'est tout à fait normal. Bah oui, on demande la racine carrée de 625 mais on en fait rien. On pourrait l'afficher, non ?
Et bien c'est tout bête :
Code VB :
print sqr(625)
Et là normalement il n'y a pas de problème et vous voyez s'afficher devant vos yeux le nombre 25, qui est bien la racine carrée de 625.
Le retour
En faite, on dit qu'un fonction retourne quelque chose, là, sqr() retourne la racine carrée de 625.
Une fonction en LB retourne toujours quelque chose, mais on n'est pas obligé d'afficher ce qu'elle renvoi, par exemple on peu stocker le résultat dans une variable :
Code VB :
racineCarre = sqr(625)
Attention, une fonction renvoie toujours quelque chose mais ce n'est pas forcément un nombre. Elle peut aussi renvoyer un texte. Pour savoir si une fonction renvoie un nombre ou un texte, il faut regarder sont nom. Si il finit par un dollar $ ça veux dire qu'elle renvoie un texte, sinon c'est un nombre. Par exemple la fonction NBR ne finit pas par un $ donc elle renvoie un nombre. Autre exemple, la fonction TXT$, qui quant à elle renvoie un texte (ces deux fonctions ne sont pas innées).
Il faut donc faire attention au type de retour et ne pas faire des choses du genre :
Code VB :
unText$ = nbr(15)
Ou encore :
Code VB :
unNombre = txt$(15)
Les paramètres
Au niveau des paramètres, on est aussi très libre. On peu mettre sous n'importe quelle forme le paramètre, une valeur, une variable et même une autre fonction et encore mieux : une opération. Par exemple pour sqr() :
- Pour la valeur :
Code VB :print sqr(625)
- Pour la variable :
Code VB :nombre=625 print sqr(nombre)
- Pour la fonction :
Code VB :print sqr(sqr(625))
Ce qui revient à faire :
Code VB :racineCarree = sqr(625) print sqr(racineCarree)
- Et pour l'opération :
Code VB :nombre = 7 print sqrt(nombre + 9)
Mais attention (oui encore), il faut envoyer le bon type et le bon nombre de paramètre.
Pour le bon type, c'est simple, n'essayer pas de chercher la racine carrée de "Salut" ça marche pas

Code VB :
texte$= "Salut" print sqr(texte$)
Pour le nombre de paramètre, c'est un peu plus compliqué. En effet nous n'avons vu jusqu'ici que sqr() qui n'a besoin que d'un seul paramètre numérique (un nombre).
Prenons mid$() à titre d'exemple. mid$() est, à l'instar de sqr(), une fonction innée. Comme vous pouvez l'avoir constaté, cette fonction renvoie du texte. Mais pour faire son travail correctement, elle a besoin de trois paramètres, un texte et deux nombres.
Lors de l'appelle d'une fonction, chaque paramètre doit être séparé par une virgule. Donc, pour mid$(), il faudra faire :
Code VB :
print mid$("Texte",2,3)
Et on trouvera affiché dans la console : "ext". En effet, mid$() permet d'extraire une partie d'un texte.
Il faut aussi savoir que l'ordre des paramètres est important. Par exemple, pour mid$(), le premier paramètre est le texte où l'on va extraire quelque chose, le second est à partir de quelle position on extrait et le troisième et dernier paramètre est le nombre de caractère que l'on prend. Dans l'exemple ci-dessus, dans le texte "Texte" on a commencé à extraire à partir du second caractère et en prendre trois, ça nous donne bien "ext".
Voici, pour finir, un appel de fonction qui montre bien ce que l'on peut faire :
Code VB :
nombre = 9 print mid$("Un truc qui ne veux rien dire",nombre,nombre-6)
Créer un Fonction
Maintenant que l'on a vu comme utiliser des fonctions, nous allons les créer nous même.
Il va donc falloir que l'on écrive un bout de code et que l'on dise qu'il n'appartient pas au corps principal de notre programme.
Pour cela, on va encadrer notre code entre ces deux lignes :
Code VB :
function end function
Mais ça ne suffit pas, en effet, là on a juste dit qu'il s'agissait d'une fonction. Il faudrait peut-être penser à la nommer, non ?
Mais bon, pour lui donner un nom, il faudrait déjà savoir ce qu'elle fait !
Pour les besoins de ce tutoriel, nous allons créer une fonction qui permet d'avoir la racine carrée d'un nombre.
Mais c'est nul !! SQR() le fait très bien, non ?!
Et bien non en faite.
En effet, SQR() a un problème.
Essayez ce code :
Code VB :
print sqr(-25)
Et là, c'est le drame !
Bin oui, depuis quand peut-on faire la racine carrée d'un nombre négatif ? (En restant dans les Réels bien sûr).
Vous ne pensez pas qu'il serait tout de même plus sympa que SQR() nous prévienne au lieu de faire planter notre programme ?
Mais bien sûr, SQR() ne sait pas le faire, alors on va créer notre fonction.
On va l'appeler racine(), pour être original

Pour information, il y a deux règles à respecter lorsque vous choisissez le nom de votre fonction :
- Que des chiffres et des lettres, sans accent et commençant par un lettre.
- Doit se finir par $ si le retour est un texte, sinon, le retour sera un nombre.
Bien, maintenant on a le nom, reste plus qu'à le rajouter à notre code :
Code VB :
function racine end function
C'est bien mais il manque toujours des choses, comme les paramètres par exemple.
On n'en a besoin que d'un seul : le nombre à partir du quel on extraira la racine carrée.
Pour faire dans l'original, on va l'appeler nombre. Ce qui nous donne :
Code VB :
function racine(nombre) end function
Donc, dans notre fonction, nombre est une variable numérique.
Maintenant il faudrait penser à la remplir, cette fonction ...
Elle doit tester si nombre est positif. Si il l'est, on renvoi sa racine carrée, sinon, on renvoi -1.
Donc une condition :
Code VB :
function racine(nombre) if nombre >= 0 then 'On renvoi la racine carrée else 'On renvoi -1, synonyme d'erreur end if end function
C'est bon, vous suivez toujours ?
Bien, continuons.
Je ne vous ais toujours pas expliqué comment renvoyer quelque chose.
C'est très simple, il faut utiliser une variable spéciale qui a le même nom que la fonction.
Donc pour nous, cette variable sera racine.
Nous obtenons donc finalement :
Code VB :
function racine(nombre) if nombre >= 0 then racine = sqr(nombre) 'On renvoi la racine carrée else racine = -1 'On renvoi -1, synonyme d'erreur end if end function
Voila, c'est finit, notre fonction fonctionne

Mais faudrait-il encore savoir où la mettre.
En faite, on peut la mettre à peu près n'importe.
De toute façon, si vous avez mis votre fonction où il ne fallait pas, JB vous le signalera lorsque vous lancerez votre programme.
Mais pour faire les choses proprement, je vous conseille de suivre un plan bien défini.
En ce que me concerne, je met mes fonctions à la fin de mon programme, en les décrivant succinctement.
Voici un exemple avec notre fonction racine :
Code VB :
input "Entrer un nombre : "; unNombre print "La racine carrée de ";unNombre;" est ";racine(unNombre) end '-----------------------------------------------' '------------------ FONCTIONS ------------------' '-----------------------------------------------' 'Fonction permettant d'obtenir la racine carrée d'un nombre function racine(nombre) if nombre >= 0 then racine = sqr(nombre) 'On renvoi la racine carrée else racine = -1 'On renvoi -1, synonyme d'erreur end if end function
Ce code est assez simple.
D'abord, on demande un nombre à l'utilisateur.
Puis on luis affiche ce nombre ainsi que ça racine carrée.
Pour la racine carrée, nous utilisons notre fonction, comme ça, si l'utilisateur entre un nombre négatif, le programme ne plantera pas.
Le seul point où vous pouvez avoir accroché est la ligne 4, avec le end.
En faite, cette instruction permet de terminer le programme, comme ça, d'un coups, sans prévenir.
Avant, on ne la mettait pas, mais lorsque l'ordinateur arrivait à la fin de notre code et qu'il ne trouvait plus rien, il s'arrêtait tout seul.
En faite, là aussi l'instruction end est facultative mais ça fait plus propre de la mettre et ça empêchera d'avoir des problèmes assez ennuyeux plus tard dans la suite du cours.
Voila, maintenant vous savez créer vos propres fonctions

Comparaison avec les Sub
Pour tout dire, les fonctions et les Sub c'est presque la même chose.
La seule différence de taille, c'est qu'une Sub ne renvoi pas de résultat.
Création
Voila comment créer un Sub :
Code VB :
sub ecrire texte1$, texte2$ print texte1$;" ";texte2$ end sub
Nous avons tout d'abord la première ligne qui sert à décrire notre Sub.
On la commence par sub, pour signaler que ce qui suit n'appartient pas au corps principale de notre programme et que c'est une Sub.
Ensuite, nous la nommons, celle-ci s'appelle ecrire (pas d'accent, pas d'espace, ...)
Autre changement avec les fonctions, ce n'est plus une parenthèse qu'il faut mettre pour séparer le nom et les paramètres mais un espace.
Puis on met les paramètres séparés par des virgules.
Voila pour la première ligne.
Je ne vais pas vous faire l'affront de vous expliquer la seconde ligne

Enfin, la dernière ligne permet de dire que notre Sub s'arrête là.
Utilisation
Pour appeler une Sub, il suffit de faire ça :
Code VB :
call ecrire "Lala", "Lili" end '-----------------------------------------' '------------------ SUB ------------------' '-----------------------------------------' ' Permet d'écrire deux textes en même temps sub ecrire texte1$, texte2$ print texte1$;" ";texte2$ end sub
Voici les quelques explications.
D'abords, on écrit call, ça dit à l'ordinateur que nous allons appeler une Sub.
Ensuite vient le nom de la Sub, ici c'est ecrire.
Pour finir, on met les paramètres en les séparant par des virgules.
Voila, les Sub c'est pas bien dur si vous avez compris les fonctions.
Quelques infos
La portée des variables
Il existe deux portées pour les variables.
La portée définit où on pourra accéder à la variable :
Les variables locales
Toutes les variables sont locales de base.
Donc actuellement, nous n'avons utilisé que des variables locales.
Ces variables ne sont accessibles qu'à partir de la partie où elles sont.
Par exemple, prenons une variable qui s'appelle nombre dans le programme principale, et une autre variable qui s'appelle aussi nombre dans une des fonctions/Sub.
Et bien ces deux variables sont complètement différentes.
Voici un code concret :
Code VB :
nombre = 15 call uneSub print nombre end '-----------------------------------------' '------------------ SUB ------------------' '-----------------------------------------' sub uneSub nombre = 8 print nombre end sub
Ceci nous donnera cela :
Console:
8
15
15
En effet, notre programme commence par mettre 15 dans nombre.
Puis il saute dans la Sub où il met 8 dans nombre.
Mais ce ne sont pas les deux mêmes variables, chaque une pointent sur une case différente dans la mémoire RAM.
Ensuite, toujours dans la Sub, on affiche la variable nombre (celle de la Sub)
Puis on retourne au corps principal et on affiche la variable nombre (celle du corps principal)
C'est juste pour vous faire comprendre que ce ne sont pas les deux mêmes variables, même si elle ont le même nom.
Les variables globales
Ce sont des variables (non

C'est-à-dire qu'elles sont accessibles depuis tout le programme. Quand je dis tout c'est tout, c'est-à-dire qu'elles sont aussi accessibles depuis les fonctions et les Sub.
Un petit exemple :
Code VB :
global text$ text$ = "Bonjours" call ecrire text$ = "Cher Zéro" call ecrire text$ = "Comment allez vous ?" call ecrire end sub ecrire print text$ end sub
Si on enlève le global text$, plus rien ne s'affiche dans la console (si, 3 retours à la ligne).
Les sauts dans les fonctions et les Sub
On a déjà parlé des sauts dans le chapitre précédent. Je vous avais dit qu'il ne pouvait pas y avoir deux étiquettes identiques dans un programme.
Et bien c'est faux. Mais pas totalement puisqu'il ne peut pas y avoir deux étiquettes identiques dans le programme principale et qu'il ne peut y en avoir deux identiques dans la même fonction ou Sub.
Je vais un peu expliquer. Si nous avons une étiquette dans le programme principale, c'est-à-dire en dehors des fonctions et des Sub, qui se nomme [mon_etiquette] et bien tout goto [mon_etiquette] qui se trouve dans le programme principale ira à cette étiquette. Pour continuer l'exemple on va faire un petit code :
Code VB :
[mon_etiquette] if a=1 then [mon_etiquette] 'saut vers la ligne 1 call rien 1 end sub rien nbr [mon_etiquette] if nbr = 1 then print nbr nbr = 0 print nbr goto [mon_etiquette] 'saut vers la ligne 11 end if end sub
Le goto va rechercher l'étiquette là où il est, c'est-à-dire soit il est appelé dans le programme principal et il va chercher l'étiquette dans le programme principal ou soit il est appelé dans une fonction ou une Sub, alors il la cherche dans cette fonction ou Sub et pas dans le programme principal.
Vous avez peut-être remarqué une ligne bizarre :
if a=1 then [mon_etiquette].
En fait, c'est une compression de la condition suivante:
if a=1 then goto [mon_etiquette]
On enlève le goto pour avoir moins de chose à écrire mais ça revient exactement au même.
Que choisir
Maintenant vient une question vitale importante :
Je prends quoi entre les fonctions et les Sub ?
Et bien ça dépend de ce que vous voulez faire. Si vous voulez faire un sous-programme (les fonctions et les Sub sont des sous-programmes) qui renvoi un résultat, il faut utiliser une fonction. Si vous voulez faire un sous-programme qui ne renvoie rien, dans ce cas là vous pouvez utiliser soit les fonctions, soit les Sub.
Il est conseillé d'utiliser les Sub qui sont fait pour ça mais personnellement je ne les utilise pas trop. Je préfère les fonctions. Après c'est à vous de choisir!
Voila un chapitre plein de nouvelles choses que nous venons de finir.
Vous pouvez allez vous reposer/faire un tour car maintenant à sonné l'heure du TP
