2010-08-19 19 views
21

Cuando la gente habla sobre el uso de "números mágicos" en la programación de computadoras, ¿qué significan?¿Qué son los "números mágicos" en la programación de computadoras?

+15

Un número mágico es 42 :) –

+0

No, no hay nada mágico en realidad 42. 42 _es_ 6 por 9 (si está usando de base 13). ¡DeepThought y Earth tenían razón! – paxdiablo

+4

@Victor: Eso debería ser 'THE_ANSWER_TO_THE_UNIVERSE_THE_WORLD_AND_EVERYTHING = 42' – mpen

Respuesta

37

Los números mágicos son cualquier número en su código que no sea inmediatamente obvio para alguien con muy poco conocimiento.

Por ejemplo, el siguiente fragmento de código:

sz = sz + 729; 

tiene un número mágico en ella y sería mucho mejor escribir como:

sz = sz + CAPACITY_INCREMENT; 

Algunos afirman puntos de vista extremos que nunca se debe tener cualquier número en su código excepto -1, 0 y 1, pero prefiero una visión algo menos dogmática, ya que reconocería instantáneamente 24, 1440, 86400, 3.1415, 2.71828 y 1.414 - todo depende de su conocimiento.

Sin embargo, a pesar de que sé hay 1440 minutos en un día, probablemente todavía uso un identificador MINS_PER_DAY ya que hace que la búsqueda de ellos mucho más fácil. ¿De quién decir que el incremento de capacidad mencionado anteriormente no sería también 1440 y terminaría cambiando el valor equivocado? Esto es especialmente cierto para los números bajos: la posibilidad de uso dual de 37197 es relativamente baja, la probabilidad de usar 5 para múltiples cosas es bastante alta.

El uso de un identificador significa que no tendría que pasar por todos sus 700 archivos fuente y cambiar 729 a 730 cuando el incremento de la capacidad haya cambiado. Se podía cambiar la una sola línea:

#define CAPACITY_INCREMENT 729 

a:

#define CAPACITY_INCREMENT 730 

y recompilar el lote.


Contraste esto con constantes mágicas que son el resultado de los ingenuos pensar que sólo porque eliminan las cifras reales de su código, que pueden cambiar:

x = x + 4; 

a:

#define FOUR 4 
x = x + FOUR; 

Eso agrega absolutamente cero información adicional a su código y es una pérdida de tiempo total.

+3

+1 como un buen ejemplo de cómo no hacerlo (thedailywtf tenía una gran colección de los que acaba de ayer: http://thedailywtf.com/Articles/Avoiding-Magic-Constants).aspx) – delnan

+0

Sí, lo leí yo mismo. Especialmente me encantó el '#define STR1" 1 "', '#define STR9" 1 "' al final (parafraseando). – paxdiablo

+0

Los números mágicos en lugar de las constantes con nombre son propensos a la rotura cuando se cambian. Si el mismo número se utiliza para múltiples propósitos, es probable que se modifique para todos los fines y/o solo en algunos casos. Las constantes nombradas reducen significativamente esta rotura. – BillThor

5

"números mágicos" son números que aparecen en los estados como

if days == 365 

Suponiendo que no sabía que había 365 días en un año, que iba a encontrar esta declaración sin sentido. Por lo tanto, es una buena práctica para asignar todos los números "mágicos" (números que tienen algún tipo de importancia en su programa) a una constante,

DAYS_IN_A_YEAR = 365 

Y a partir de entonces, comparar a ese lugar. Es más fácil de leer, y si la Tierra se desalinea y ganamos un día más ... puedes cambiarla fácilmente (es probable que otros números cambien).

+1

"si la tierra alguna vez queda fuera de alineación, y ganamos un día extra" - Extraño, eso parece suceder cada cuatro años. :) –

+1

La pieza más divertida de código que he visto: '#define PI 3.14159/* make define en caso de que PI cambie alguna vez * /' :-) – paxdiablo

+0

¡¿La tierra se desalinea cada cuatro años ?! ¡Guauu! – Nick

1

El término número mágico se utiliza generalmente para describir algunas constantes numéricas en el código. El número aparece sin más descripción y, por lo tanto, su significado es esotérico.

El uso de números mágicos se puede evitar mediante el uso de constantes con nombre.

2

Cualquier cosa que no tenga un significado aparente para nadie más que la propia aplicación.

if (foo == 3) { 
    // do something 
} else if (foo == 4) { 
    // delete all users 
} 
0

Uso de los números en los cálculos distintos de 0 o 1 que no están definidos por algún identificador o variable (que no sólo hace que el número fácil de cambiar en varios lugares cambiándolo en un lugar, sino que también hace claro para el lector para qué es el número).

2

Los números mágicos son un valor especial de ciertas variables que hace que el programa se comporte de una manera especial.

Por ejemplo, una biblioteca de comunicación puede tomar un parámetro Timeout y puede definir el número mágico "-1" para indicar el tiempo de espera infinito.

4

Wikipedia es su amigo (Magic Number artículo)

+4

+1, por enseñar el OP a pescar (con suerte), y no solo por entregarle el pescado. – Thanatos

+11

Dale fuego a un hombre, estará caliente por la noche. Enciende a un hombre, él estará caliente por el resto de su vida: Terry Pratchett (creo). Sin embargo, SO debería poder mantenerse solo, ¡incluso si el resto de Internet desaparece! Por supuesto, enlace a otra fuente, pero prefiero poner algo de carne en la respuesta también. – paxdiablo

+1

+1 para Pratchett! – Paddyslacker

3

La mayoría de las respuestas hasta el momento han descrito un número mágico como una constante que no es auto describir. Siendo un poco un programador de la "vieja escuela", en el pasado describíamos los números mágicos como cualquier constante a la que se le asigna algún propósito especial que influye en el comportamiento del código. Por ejemplo, el número 999999 o MAX_INT o algo completamente arbitrario.

El gran problema con los números mágicos es que su propósito puede ser fácilmente olvidado, o el valor utilizado en otro contexto perfectamente razonable.

Como un ejemplo crudo y terriblemente artificial:

while (int i != 99999) 
{ 
    DoSomeCleverCalculationBasedOnTheValueOf(i);  

    if (escapeConditionReached) 
    { 
    i = 99999; 
    } 
} 

El hecho de que una constante se utiliza o no el nombre no es realmente el problema. En el caso de mi terrible ejemplo, el valor influye en el comportamiento, pero ¿qué sucede si tenemos que cambiar el valor de "i" mientras bucleamos?

Claramente en el ejemplo anterior, NO NECESITA un número mágico para salir del ciclo. Podría reemplazarlo con una declaración de interrupción, y ese es el verdadero problema con los números mágicos, que son un enfoque perezoso para la codificación, y sin falta siempre pueden ser reemplazados por algo menos propenso a la falla o a perder significado con el tiempo.

+0

Prefiero llamarlo un valor de centinela, pero veo de dónde vienes. – paxdiablo

+1

Para mí, un valor centinela vive en una estructura de datos, generalmente una clave que es demasiado grande (o pequeña) para ser una clave válida. Sin embargo, para esta terminación de bucle, he visto que se describe (demasiadas veces) como inherentemente preferible a 'break' porque" break es un goto oculto ". ¿Qué logra lograr? - 'PC = target_address;'. Para mí, estos números mágicos especiales son versiones encubiertas e indirectas de la misma cosa (asignaciones que llevan a la ejecución a un punto particular del código) y, como tales, a menudo notablemente menos legibles y mantenibles que el simple uso de 'break'. – Steve314

+0

Es difícil de creer que escribir 'break' sea * menos * vago que configurar esa salida basada en el número mágico. – Steve314

4

Hay más de un significado. La dada por la mayoría ya respuestas (un número no identificado arbitraria) es muy común, y lo único que voy a decir sobre eso es que algunas personas se van al extremo de definir ...

#define ZERO 0 
#define ONE 1 

Si Si haces esto, te perseguiré y no mostraré misericordia.

Otro tipo de número mágico, sin embargo, se utiliza en formatos de archivo. Es solo un valor incluido como típicamente lo primero en el archivo que ayuda a identificar el formato de archivo, la versión del formato de archivo y/o la endianidad del archivo en particular.

Por ejemplo, puede tener un número mágico de 0x12345678. Si ve ese número mágico, es probable que esté viendo un archivo del formato correcto. Si ve, por otro lado, 0x78563412, es probable que vea una versión endian-swap del mismo formato de archivo.

El término "número mágico" se abusa un poco, sin embargo, en referencia a casi cualquier cosa que identifique un formato de archivo, incluidas cadenas ASCII bastante largas en el encabezado.

http://en.wikipedia.org/wiki/File_format#Magic_number

+1

Yo diría que el segundo tipo de número mágico (es decir, los que están en formatos de archivo) es en realidad el tipo más común/relevante. – hbw

+0

Eso puede ser cierto; después de todo, cualquier buen programador sabrá mejor que usar un número mágico para especificar su número mágico. – Steve314

+1

la "magia" de los números mágicos es su falta de semántica inherente evidente ... ya sea identificadores como mencionas o factores fudge. –

0

En palabras sencillas y verdaderas, un número mágico es un número de tres dígitos, cuya suma de los cuadrados de los dos primeros dígitos es igual a la tercera. Ex-202, as, 2 * 2 + 0 * 0 = 2 * 2. Ahora, WAP en java para aceptar un número entero e imprimir si es un número mágico o no.

+2

Ciertamente no se ajusta a la descripción de "números mágicos desde el punto de vista de la programación". – BoltClock

0

Puede parecer un poco banal, pero HAY al menos un número mágico real en cada lenguaje de programación.

que argumentan que es la varita mágica para gobernarlos a todos prácticamente en la aljaba de todos los programadores de varitas mágicas.

FALSO es inevitablemente 0 TRUE no es (FALSO), pero no necesariamente 1! Podría ser -1 (0xFFFF)

NULL es inevitable 0 (el puntero) Y la mayoría de los compiladores que permiten a menos que su verificación de tipos es absolutamente rabioso.

0 es el índice base de los elementos del conjunto, excepto en los idiomas que son tan anticuados que el índice base es '1'. Uno puede entonces codificar convenientemente (i = 0; i < 32; i ++), y esperar que 'i' comience en la base (0), e incremente a, y se detenga en 32-1 ... el 32 ° miembro de una matriz, o lo que sea.

0 es el final de muchas cadenas de lenguaje de programación. El valor de "parar aquí".
0 también está integrado en las instrucciones de X86 para "mover cadenas de manera eficiente". Ahorra muchos microsegundos.

0 a menudo es utilizado por los programadores para indicar que "nada salió mal" en la ejecución de una rutina. Es el valor de código "no-excepción". Uno puede usarlo para indicar la falta de excepciones lanzadas.

Cero es la respuesta más a menudo dada por los programadores para la cantidad de trabajo que se necesitaría para hacer algo completamente trivial, como cambiar el color de la celda activa a rosa púrpura en lugar de brillante. "¡Cero, hombre, como cero!"

0 es el recuento de errores en un programa que aspiramos a lograr. 0 excepciones no contabilizadas, 0 ciclos sin terminar, 0 vías de recursión que no se pueden tomar realmente. 0 es la asíntota que estamos tratando de lograr en la programación laboral, los "problemas" de novia, novio, malas experiencias en restaurantes e idiosincrasias generales del automóvil de uno.

Sí, 0 es un número mágico de hecho. MUCHA más magia que cualquier otro valor. Nada ... ejem, se acerca.

[email protected]

Cuestiones relacionadas