Il y a un Nico de service qui a demandé qq chose au sujet des passages d'arguments par valeur et pointeur.
Le sujet et un peu plus vaste que ce qui est montré ici, mais j'ai pris le temps de rédiger un truc mignon pour les débutants et les autres. Je pense que cela permet de bien comprendre pour le cas où vous avez encore qq soucis à saisir le sujet.
Je propose de faire par la suite, moi où qui voudra ou purra bien, et sous une forme à peu près identique, des compléments à ce premier chapitre.
On ne sait jamais, des fois qu'il en sorte un bouquin et qu'on le publie !
Code : Tout sélectionner
;
; Factorielle1 reçoit la valeur n en argument et renvoit le résultat dans Resultat
; La valeur Resultat peut être récupérée en appelant la fonction affectée à une variable :
; x = Factorielle1(12) stockera le résultat dans x
;
Procedure.l Factorielle1(n.l)
Resultat.l = 1
For i = n To 2 Step -1
Resultat = Resultat * i
Next
ProcedureReturn Resultat
EndProcedure
;
; Factorielle2 reçoit non pas une valeur, mais un pointeur
; De ce fait il faut récupérer la valeur de manière indirecte
; Cette adressage indirect permet de connaître l'emplacement mémore
; de la variable, et par conséquent de placer le résutlat de la fonction
; à cet emplacement.
;
; On ne peut pas utiliser cette fonction sous la forme x = Factorielle(8), mais
; uniquement sous la forme x = 8 : Factorielle(x) : ...
;
Procedure Factorielle2(*Pointeur.l)
Valeur.l = PeekL(*Pointeur)
Resultat.l = 1
For i = Valeur To 2 Step -1
Resultat = Resultat * i
Next
PokeL(*Pointeur, Resultat)
EndProcedure
;
; Factorielle3 permet d'avoir le résultat placé dans la variable et en valeur de retour de la fonction
; Il arrive que certaines fonctions disposent de ux modes de retour de valeur, facilitant ainsi l'accès
; pour les programmeurs.
;
; On peut utiliser cette fonction indifférement sous la forme : x = Factoriel(n) ou bien x = 8 : Factorielle(x) : ...
; Mais attention x prend la valeur résultat dans les deux cas et ne peut pas être récupéré à sa valeur initiale sans
; stockage dans une autre variable !
;
Procedure Factorielle3(*Pointeur.l)
Valeur.l = PeekL(*Pointeur)
Resultat.l = 1
For i = Valeur To 2 Step -1
Resultat = Resultat * i
Next
PokeL(*Pointeur, Resultat)
ProcedureReturn Resultat
EndProcedure
Structure ENTIERLONG
EntierLong.l
EndStructure
;
; Factorielle4 dispose des même propriétés que Factorielle3 mais utilise une structure pour permettre
; d'avoir une équivalence pointeur / valeur. La structure est constituée d'un seul membre : un entier long.
; Ce procédé permet de faire l'économie des fonctions PeekL et PokeL et fait gagner un peu de temps.
;
Procedure Factorielle4(*Pointeur.ENTIERLONG)
Resultat.l = 1
For i = *Pointeur\EntierLong To 2 Step - 1
Resultat = Resultat * i
Next
*Pointeur\EntierLong = Resultat
EndProcedure
;
; Pour vous permettre de réaliser des tests de performances corrects, vous devez fermer l'option Débogueur.
; A défaut le temps d'exécution peut s'avérer plus long.
;
OpenConsole()
PrintN("Test des procédures")
PrintN("")
n = 10 : PrintN("Factorielle1 : " + Str(Factorielle1(n)) + " " + Str(n))
n = 10 : PrintN("Factorielle2 : " + Str(Factorielle2(@n)) + " " + Str(n))
n = 10 : PrintN("Factorielle3 : " + Str(Factorielle3(@n)) + " " + Str(n))
n = 10 : PrintN("Factorielle4 : " + Str(Factorielle3(@n)) + " " + Str(n))
PrintN("Test de performance")
PrintN("")
Count = 10000000
tz = ElapsedMilliseconds() : For i = 1 To Count : n = 10 : o = Factorielle1(n) : Next : PrintN(Str(ElapsedMilliseconds() - tz))
tz = ElapsedMilliseconds() : For i = 1 To Count : n = 10 : o = Factorielle2(@n) : Next : PrintN(Str(ElapsedMilliseconds() - tz))
tz = ElapsedMilliseconds() : For i = 1 To Count : n = 10 : o = n : o = Factorielle3(@o) : Next : PrintN(Str(ElapsedMilliseconds() - tz))
tz = ElapsedMilliseconds() : For i = 1 To Count : n = 10 : o = n : o = Factorielle4(@o) : Next : PrintN(Str(ElapsedMilliseconds() - tz))
;
; Les tests de performances montrent rapidement une chose, c'est le coût en terme de temps, de l'appel par pointeur, qui est plus
; important que l'appel par valeur.
;
; Ce surcoût est tout simplement du au fait qu'il faut transférer la valeur de manière indirecte pour Factorielle2 et Factorielle3.
;
; Tout est question de forme !
;
While Inkey() = "" : Wend
CloseConsole()