Nombre magique (programmation) - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

Magics GUIDs

Il est possible de créer ou modifier des GUID pour qu'ils soient facilement mémorisables bien que cela puisse affecter leur efficacité et leur unicité. Les règles pour générer des GUID et des UUID sont complexes mais assurent d'avoir des numéros uniques si elles sont suivies scrupuleusement.

Plusieurs GUID java commencent par « CAFEEFAC ».

Constantes numériques non-nommées

Le terme de magic number peut également correspondre à l'utilisation de constantes numériques non-nommées dans le code source d'un programme. L'utilisation de ces constantes viole les anciennes règles de programmation issues de COBOL, de FORTRAN et de PL/1, ne rend pas plus claire le choix de cette valeur et provoque généralement des erreurs de programmation. Le nommage de tous les constantes rend le code plus lisible, plus compréhensible et plus facilement maintenable.

Le nom des constantes doit avoir un sens selon le contexte ; par exemple, il vaut mieux éviter les codes du genre SEIZE = 32 alors que NOMBRE_DE_BITS aurait été plus clair.

Les problèmes avec ces magic number ne se limitent pas au constantes numériques ; le terme est également utilisé pour d'autres types de données, la déclaration des constantes étant plus flexible et porteuse de sens. Ainsi, déclarer const string testNomUtilisateur = "Jean" est meilleur que d'utiliser le mot-clé "Jean" de manière disséminée dans le programme ; de plus, cela simplifie la phase de tests.

Par exemple, le pseudo-code suivant permet de mélanger aléatoirement les valeurs d'un tableau représentant un jeu de 52 cartes :

         for i from 1 to 52           j:= i + randomInt(53 - i) - 1           jeu.swapEntries(i, j)      

jeu est un objet de type tableau, la fonction randomInt(x) choisit un chiffre au hasard entre 1 et x compris et swapEntries(i, j) échange la position des données placées en i et j dans le tableau. Dans cet exemple, 52 est un magic number. Il est plutôt conseillé d'écrire :

        constant int nombreDeCarte:= 52        for i from 1 to nombreDeCarte           j:= i + randomInt(nombreDeCarte + 1 - i) - 1           jeu.swapEntries(i, j)      

Et ce pour plusieurs raisons :

  • Le second exemple est plus facile à lire et à comprendre. Un développeur lisant pour le premier exemple va se demander « Pourquoi 52 ? » bien qu'il serait certainement capable de comprendre en lisant attentivement l'ensemble du code. Les magic number deviennent déroutants lorsque la même valeur est utilisée pour désigner des choses complètement différentes dans une même partie de code.
  • Il est plus simple de modifier la valeur de la constante car celle-ci n'est pas dupliquée. Changer la valeur d'un magic number est source d'erreur car la même valeur est très souvent utilisée à plusieurs endroits dans le programme. Il se peut également que deux variables aux significations différentes aient la même valeur ; cela pose un problème pour les différencier. Pour adapter le premier exemple à un jeu de tarot de 78 cartes, le développeur pourrait naïvement remplacer toutes les occurrences de 52 par 78. Cela pourrait causer deux problèmes : premièrement, la valeur 53 de la seconde ligne de l'exemple ne sera pas modifiée et amènerait le programme à ne traiter qu'une partie du jeu de cartes ; deuxièmement, il se peut qu'il remplace la chaîne "52" dans tout le programme sans prêter attention à ce qu'elle signifie ce qui introduirait très certainement des bugs. Par comparaison, changer la valeur de nombreDeCarte dans le second exemple est une opération très simple et ne nécessite la modification que d'une seule ligne.
  • La déclaration des variables remplaçant les magic number sont placées au début des fonctions ou fichiers pour faciliter leur recherche et leur modification.
  • L'introduction de paramètres est plus facile. Par exemple, pour généraliser l'exemple et faire qu'il puisse mélanger n'importe quel tas de cartes, il faudrait passer nombreDeCarte en paramètre de la procédure :
        function melange(int nombreDeCarte )           for i from 1 to nombreDeCarte               j:= i + randomInt(nombreDeCarte + 1 - i) - 1              jeu.swapEntries(i, j)      
  • Il est plus facile de détecter les coquilles car une variable déclarée est vérifiée par le compilateur. Par exemple, saisir "62" au lieu de "52" ne sera pas détecté alors que « nombreDeCate » au lieu de « nombreDeCarte » lèvera un warning (ou une erreur) du compilateur informant que « nombreDeCate » n'est pas défini.
  • Cela permet également de minimiser les saisies au clavier dans les IDE permettant le complètement automatique : il suffit de saisir les premières lettres de la variable pour que l'IDE le complète automatiquement.

Il y a tout de même quelques défauts :

  • L'exécution de l'expression nombreDeCarte + 1 prend plus de temps que l'expression 53. Néanmoins, la plupart des compilateurs et des l'interpréteurs modernes sont capables de comprendre que la variable nombreDeCarte a été déclarée comme constante et de pré-calculer la valeur 53 dans le code compilé.
  • L'utilisation de grands noms de variables allonge les lignes de code, obligeant certaines lignes de code à s'étaler sur plusieurs lignes.
  • Le debbugage peut être plus difficile si le débuggeur ne fait pas la correspondance entre les noms de variable et leur valeur.

Usages acceptés comme constantes numériques non-nommées

Dans certains cas – dépendant des habitudes de codage –, l'utilisation de constantes numériques non-nommées est acceptée :

  • l'utilisation du 0 ou du 1 comme valeur initiale ou valeur d'incrémentation dans les boucle for : for (int i=0;i (en supposant que l'incrémentation i++ n'est pas supportée).
  • l'utilisation de 2 dans les expressions mathématiques : périmètre = rayon * Math.PI * 2.
  • l'utilisation de 2 pour vérifier qu'un nombre est pair ou impair : bool estPair = (x%2==0), où % est l' opérateur modulo.

Les constantes 1 et 0 sont parfois utilisées pour représenter les valeurs booléennes « Vraie » et « Faux » dans les langages de programmation qui n'ont pas ce type (comme les anciennes versions de C).

En C/C++, 0 est parfois utilisé pour représenter un pointer ou référence null. Comme pour les valeurs booléens, les librairies de C standards contiennent des macro-définition de NULL dont l'utilisation est fortement conseillée. D'autres langages proposent des valeurs null ou nil spécifiques.

Page générée en 0.104 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales
Version anglaise | Version allemande | Version espagnole | Version portugaise