Salut à tous,
Ce code n'est pas vraiment un code à proprement parlé, mais plutôt une ébauche de tutoriel visant à expliquer l'interêt d'utilisation des variables globales. Je poste ça sur PHPCS parce que c'est un peu le seul langage que je connaisse vraiment bien, mais ce tutoriel est en fait valable pour l'integralité des langages de programmation existant.
Les variables globales servent souvent pour enregistrer des variables d'environnement que des classes ou des fonctions pourront récuperer et utiliser, voire modifier. Mais il existe également une autre utilisation de ces variables.
Elles peuvent en effet servir à optimiser certaines fonctions basée sur des boucles. Pour exemple, je vais utiliser 3 fonctions qui permettent de calculer le factoriel d'un entier n (rappel : n! = 1 * 2 * 3 * ... (n - 1) * (n). Pour info, ça peut aussi bien servir dans les probabilités que dans l'approximation de Pi ou de l'exponentiel ...).
La première fonction (factoriel_1) est récursive : elle s'appelle elle-même. J'ai pas trop la pédagogie nécessaire pour expliquer, alors je vous laisse comprendre .... Désolé. Mais c'est pas compliqué à comprendre !
La seconde fonction (factoriel_2) est barbare (dans le sens de "barbare logiquement"). Elle va calculer le factoriel à l'aide d'une boucle for, en multipliant une variable par elle même, etc ... Pareil, pas très compliqué à comprendre, c'est une fonction intuitive puisqu'elle suit notre pensée.
Enfin, la troisième fonction (factoriel_3) utilise les variables globales ...
Source / Exemple :
<?php
// La fonction factorielle récursive ...
function factoriel_1($n)
{
if ($n == 0)
{
return(1);
}
else
{
return($n * factoriel_1($n - 1));
}
}
// La fonction factorielle itérative...
function factoriel_2($n)
{
$factoriel = 1;
for ($i = 1; $i <= $n; $i++)
{
$factoriel *= $i;
}
return($factoriel);
}
// La fonction factorielle optimisée ...
// On déclare d'abord le tableau qui va devenir global. Il contient en fait le résultat de 0! (factoriel de 0) = 1.
$_factoriel = array('input' => 0, 'output' => 1);
function factoriel_3($n)
{
// On rend le tableau global ...
global $_factoriel;
// On regarde pour voir si la demande est la même que celle du tableau.
if ($n == $_factoriel['input'])
{
// Si oui, on set la variable qui va être retournée avec la valeur du tableau global.
$factoriel = $_factoriel['output'];
}
// On regarde maintenant si on va gagner du temps en utilisant le tableau global.
elseif (abs($n - $_factoriel['input']) < $n)
{
// Si oui, les blocs suivants vont déterminés s'il faut décrémenter ou incrémenter pour acceder au factoriel voulu.
$factoriel = $_factoriel['output'];
if ($n - $_factoriel['input'] > 0)
{
for ($i = $_factoriel['input'] + 1; $i <= $n; $i++)
{
$factoriel = $factoriel * $i;
}
}
else
{
for ($i = $_factoriel['input']; $i >= $n + 1; $i--)
{
$factoriel = $factoriel / $i;
}
}
}
// Si ça ne vaut pas le coup, on calcule le factoriel de manière primaire.
else
{
$factoriel = 1;
for ($i = 1; $i <= $n; $i++)
{
$factoriel *= $i;
}
}
// On update les globales pour l'utilsation suivante de la fonction.
$_factoriel['input'] = $n;
$_factoriel['output'] = $factoriel;
return($factoriel);
}
?>
Conclusion :
Bon, comme les fonctions sont mal expliquées, j'explique l'idée. En fait, les variables globales sont utilisées comme point de départ. En effet, dans l'exemple, pour calculer un factoriel, il faut partir de 1, puis executer la boucle jusqu'à n. A l'aide des globales, on peut maintenant partir du de la dernière valeure calculée, c'est à dire de la valeure calculée depuis la dernière fois où la fonction a été appellée ... Pas clair ?
On va utiliser une première fois la fonction pour calculer le factoriel de 5.
La fonction va faire une boucle, de 1 à 5.
Après le calcul, le tableau global va changer, et contenir '5' comme input et '120' dans 'output' (le factoriel de 5 vaut 120). Imaginons ensuite que le script doit ensuite calculer le factoriel de 7. Et bien, grâce au tableau, il n'aura pas à partir de 1, mais de 5 ! D'où un gain de temps et une optimisation non négligeable ! Voilà, j'espère que c'est un peu plus clair ...
Pour prouver ce que j'avance, des petits tests. J'ai calculé le factoriel de 12 nombre à la suite, avec chacune des fonctions. Et voilà le resultat :
factoriel_1 : 6.853ms
factoriel_2 : 9.211ms
factoriel_3 : 5.152ms
Convaincu ?
Il est bien entendu interessant d'utiliser ces variables spéciales uniquement si une fonction est souvent appellée, sinon ... Bon ... On peut s'en passer.
@ la prochaine !
++ !
LocalStone.
18 oct. 2004 à 17:43
Je vois ce que tu veux dire pour la pile/file, c'est vrai qu'on peut le faire comme ça, et c'est en fait ce qu'on utilise pour des problèmes comme les N reines etc. J'y avais pas pensé, mais en fait on parcours bien un arbre virtuel, c'est bien vu ^^
18 oct. 2004 à 16:41
(à quand une équipe de Belgique pour les IOI ?)
Et pour parcourir un arbre binaire sans fonction récursive, on peut se faire sa propre pile (en gros ça revient à faire un appel) pour une moitié et utiliser un while pour l'autre moitié, c'est assez barbare :)
Comme l'a dit Kirua, il vaut mieux utiliser un tableau complet indicé pour la fonction factorielle mais la méthode que tu montres (ne garder qu'une valeur) peut être intéressant si on est très limité en place et si les valeurs demandées sont assez proches (sinon ça revient quasiment à tout calculer et en pratique ça prendra même plus de temps), comme par exemple une courbe continue.
18 oct. 2004 à 00:02
je vais me coucher à l'instant, bye bye ;)
17 oct. 2004 à 23:53
++ !
17 oct. 2004 à 18:35
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.