48 votes

Nombres nommés en tant que variables

Je l'ai déjà vu à quelques reprises récemment dans le code de profil élevé , où les valeurs constantes sont définies comme des variables, nommées d'après la valeur, puis utilisées une seule fois. Je me demandais pourquoi cela se faisait?

Par exemple, Linux Source (resize.c)

 unsigned five = 5;
unsigned seven = 7;
 

Par exemple, C # .NET Source (Quaternion.cs)

 double zero = 0;
double one = 1;
 

83voto

MrZebra Points 6508

Nommer les nombres est terrible pratique, un jour, quelque chose devra changer, et vous vous retrouverez avec unsigned five = 7.

Si elle a un sens, lui donner un nom significatif. Le "nombre magique" five absence d'amélioration au cours de la magie nombre 5, c'est pire parce qu'il ne pourrait pas en fait égal 5.

Ce genre de chose se pose généralement à partir de quelques-cargo culte de programmation des lignes directrices de style où quelqu'un a entendu dire que les "nombres magiques sont mauvais" et interdit leur utilisation sans bien comprendre pourquoi.

48voto

Richard Tingle Points 8054

Bien nommé variables

Donner les noms de variables peuvent considérablement clarifier le code, tels que

constant int MAXIMUM_PRESSURE_VALUE=2;

Cela donne deux avantages:

  • La valeur MAXIMUM_PRESSURE_VALUE peut être utilisé dans de nombreux endroits différents, si, pour quelque raison que ce soit que les changements de la valeur que vous devez le changer en un seul lieu.

  • Lorsqu'il montre immédiatement que la fonction est en train de faire, par exemple, le code suivant évidemment vérifie si la pression est trop haute:

    if (pressure>MAXIMUM_PRESSURE_VALUE){
        //without me telling you you can guess there'll be some safety protection in here
    }
    

Mal nommée variables

Cependant, tout a un contre-argument et ce que vous avez montré ressemble beaucoup à une bonne idée de prendre la mesure où il n'a pas de sens. La définition d' TWO 2 ne pas ajouter de la valeur

constant int TWO=2;
  • La valeur TWO peut être utilisé dans de nombreux endroits différents, peut-être à double les choses, peut-être d'accéder à un index. Si dans l'avenir, vous avez besoin de changer l'indice que vous ne peut tout simplement changer d' int TWO=3; parce que cela aurait une incidence sur tous les autres (complètement indépendants) des moyens que vous avez utilisés DEUX, maintenant vous seriez en triplant au lieu de doubler etc
  • Lorsqu'il est utilisé, il vous donne pas plus d'informations que si vous venez d'utiliser "2". Comparer les deux morceaux de code:

    if (pressure>2){
        //2 might be good, I have no idea what happens here
    }
    

    ou

    if (pressure>TWO){
        //TWO means 2, 2 might be good, I still have no idea what happens here
    }
    
  • Pire encore (comme cela semble être le cas ici) TWO peut pas égal à 2, si c'est une forme de dissimulation où l'intention est de rendre le code moins claire: évidemment, il réalise que.

La raison habituelle pour ce est une norme de codage qui interdit à des numéros de magie, mais ne compte pas TWO comme un nombre magique; ce qui bien sûr il est! 99% du temps, vous souhaitez utiliser un véritable nom de la variable, mais dans la que 1% du temps à l'aide d' TWO au lieu de 2 des gains que vous rien (Désolé, je veux dire ZERO).

ce code est inspiré par Java, mais est destiné à être la langue agnostique

30voto

Alex P Points 688

Version courte:

  • Une constante five qui tient juste le nombre cinq est assez inutile. Ne pas aller autour de la prise de ces pour aucune raison (parfois, vous avez à cause de la syntaxe ou en tapant les règles, bien que).
  • Le nom des variables dans les Quaternions.cs ne sont pas strictement nécessaire, mais vous pouvez faire le cas pour le code beaucoup plus lisible avec que sans.
  • Les variables nommées en ext4/redimensionner.c ne sont pas constantes. Ils sont clairement nommées par les compteurs. Leurs noms obscurs de leur fonction un peu, mais ce code n'a suivre correctement le projet spécialisé des normes de codage.

Ce qui se passe avec les Quaternions.cs?

Celui-là est vraiment facile.

Juste après ceci:

double zero = 0;
double one = 1;

Pour cela, le code:

return zero.GetHashCode() ^ one.GetHashCode();

Sans les variables locales, quelle est l'alternative?

return 0.0.GetHashCode() ^ 1.0.GetHashCode(); // doubles, not ints!

Quel gâchis! La lisibilité est certainement sur le côté de la création de la habitants de. Par ailleurs, je pense que nommer explicitement les variables indique "Nous avons pensé avec soin" beaucoup plus clairement que le simple fait d'écrire une seule source de confusion retour de déclaration.

Ce qui se passe avec les redimensionner.c?

Dans le cas de ext4/redimensionner.c, ces chiffres ne sont pas constantes. Si vous suivez le code, vous verrez qu'ils sont des compteurs et leurs valeurs en fait le changement sur plusieurs itérations d'une boucle while.

Notez comment ils sont initialisés:

unsigned three = 1;
unsigned five = 5;
unsigned seven = 7;

Trois est égal à un, hein? Qu'est-ce que?

Voir, ce qui se passe réellement est que l' update_backups passe ces variables par référence à la fonction ext4_list_backups:

/*
 * Iterate through the groups which hold BACKUP superblock/GDT copies in an
 * ext4 filesystem.  The counters should be initialized to 1, 5, and 7 before
 * calling this for the first time.  In a sparse filesystem it will be the
 * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
 * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
 */
static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
                                  unsigned *five, unsigned *seven)

Ils sont des compteurs qui sont conservés au cours de plusieurs appels. Si vous regardez le corps de la fonction, vous allez voir que c'est de jongler avec les compteurs pour trouver la prochaine puissance de 3, 5, ou 7, de la création de la séquence de vous voir dans le commentaire: 1, 3, 5, 7, 9, 25, 27, &c.

Maintenant, pour le plus cocasse, c'partie: la variable three est initialisé à 1 car 30 = 1. La puissance 0 est un cas spécial, car c'est la seule fois 3x = 5x = 7x. Essayez votre main à la réécriture ext4_list_backups de travailler avec tous les trois compteurs initialisé à 1 (30, 50, 70), et vous verrez comment beaucoup plus lourde le code devient. Parfois il est plus facile de dire à l'appelant de faire quelque chose de funky (initialiser la liste à 1, 5, 7) dans les commentaires.

Alors, est - five = 5 bon style de codage?

Est "cinq" est un bon nom pour la chose que la variable five représente à redimensionner.c? À mon avis, ce n'est pas un style que vous devez reproduire dans n'importe aléatoire de projet, vous prenez sur. Le simple nom five ne communique pas beaucoup sur le but de la variable. Si vous travaillez sur une application web ou rapidement des prototypes d'une vidéo de chat du client ou de quelque chose et décider de nommer une variable five, vous allez probablement créer des maux de tête et de gêne pour la personne qui doit gérer et modifier votre code.

Cependant, c'est un exemple où les généralités sur la programmation ne peignez pas l'image complète. Regardez le noyau du style de codage du document, en particulier le chapitre sur l'appellation.

Les variables GLOBALES (à utiliser uniquement si vous avez vraiment besoin d'eux) doivent ont des noms descriptifs, comme le font les fonctions globales. Si vous avez une fonction ce qui compte le nombre d'utilisateurs actifs, vous devez appeler que "count_active_users()" ou similaire, vous devriez ne pas l'appeler "cntusr()".

...

LOCAL noms de variable doit être court et au point. Si vous avez certaines entier aléatoire compteur de boucle, il doit probablement être appelé "je". En l'appelant "loop_counter" est non-productif, si il n'y a aucune chance de d'être mal compris. De même, "tmp" peut être à peu près n'importe quel type de variable qui est utilisée pour contenir une valeur temporaire.

Si vous avez peur de mélanger vos locaux noms de variables, vous avez un autre problème, qui est appelée la fonction de l'hormone de croissance-le déséquilibre du syndrome. Voir le chapitre 6 (Fonctions).

C'est en partie C-style de codage de la tradition. Elle est en partie déterminé par ingénierie sociale. Beaucoup de code du noyau est sensible choses, et il a été révisé et testé de nombreuses fois. Étant donné que Linux est un gros projet open-source, c'est vraiment pas mal pour les contributions — dans la plupart des cas, le plus grand défi est de la vérification de ces contributions pour la qualité.

L'appel de cette variable five au lieu de quelque chose comme nextPowerOfFive est un moyen de décourager les contributeurs de l'ingérence dans le code qu'ils ne comprennent pas. C'est une tentative pour vous forcer à vraiment lire le code que vous modifiez dans le détail, ligne par ligne, avant que vous essayez de faire des changements.

Ne mainteneurs du noyau de prendre la bonne décision? Je ne peux pas dire. Mais c'est clairement une pratique délibérée déplacer.

11voto

Joshpbarron Points 323

Mon organisation a certaines directives de programmation, parmi lesquelles l’utilisation de nombres magiques ...

par exemple:

 if (input == 3) //3 what? Elephants?....3 really is the magic number here...
 

Ceci serait changé en:

 #define INPUT_1_VOLTAGE_THRESHOLD 3u 
if (input == INPUT_1_VOLTAGE_THRESHOLD) //Not elephants :(
 

Nous avons également un fichier source avec -200 000 -> 200 000 #defined dans le format:

 #define MINUS_TWO_ZERO_ZERO_ZERO_ZERO_ZERO -200000
 

qui peuvent être utilisés à la place des nombres magiques, par exemple pour référencer un index spécifique d'un tableau.

J'imagine que cela a été fait pour "Lisibilité".

7voto

Dieter Lücking Points 10938

Les nombres 0, 1, ... sont des nombres entiers. Ici, les 'variables nommées' donnent à l'entier un type différent. Il serait peut-être plus raisonnable de spécifier ces constantes (const unsignedigned five = 5;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X