Partie I : 6) Les fonctions et les Sub

 
Nous avons déjà vu comment faire des conditions, des boucles, des sauts ... etc. Mais tous ceci se passait dans le corps de notre programme.
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? :D
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 :p . Par exemple :
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 :p

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 :p
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


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 :p ) un peu spéciales: elles sont l'opposé des variables locales.
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 :top


 
Cette page a été consultée 7475 fois