>> [REPRODUCCIÓN DE MÚSICA]
DOUG LLOYD: De acuerdo.
Tipo de un tema extraño, ¿no?
Números de magia.
Qué cierva quiere decir cuando es hablando de números mágicos?
Bueno, algunos de los programas que hemos escrito en CS50
hasta el momento han tenido alguna extraña números de tipo de arrojados en ellos.
Tal vez por razones no lo hacemos totalmente entender ahora.
Por ejemplo, en el problema Mario, nos cubiertas la altura de la pirámide de 23.
Le dijimos explícitamente no puede ir más alto que 23.
>> Pero, ¿qué quiere decir 23?
Bueno, si usted lee el spec cuidadosamente,
podría haber visto que el razón por la que coronó al 23
es debido a que la altura estándar de una ventana de terminal es 24.
Y por lo que si tenemos la pirámide ser más alto que eso,
que podría hacer esa cosa rara donde se ejecuta fuera de la pantalla.
Y ya sabes, lo que hace Eso significa que en el contexto, ¿no?
>> ¿Es el significado de 23 inmediatamente obvio a alguien que mira a su programa
y tal vez tiene una diferente ventana de terminal tamaño?
Probablemente no.
Parece que, en Aceptar.
Bueno, ¿por qué es un poco menos de 23?
En general, es una especie de un mal hábito en realidad
para escribir constantes en el código.
De este modo, cuando en realidad lo hace escribir una constante en su código,
se refiere a veces como el uso de números mágicos, que es algo
por lo general, queremos tratar de evitar.
>> Por ejemplo, vamos a echar un vistazo Esta sencilla función aquí.
Obviamente no hay datos tipo en C llamado tarjeta o cubierta.
Así que tengan paciencia conmigo.
Es un poco de pseudocódigo mezclado aquí.
Esta es una función llamada tratar tarjeta que aparentemente
toma una baraja como parámetro, y salida de voluntad para mí una sola tarjeta.
>> Y yo estoy haciendo algo aquí donde yo tener un bucle que va desde 0 a 52,
y me ocupo de una tarjeta.
Bueno, tenemos una magia número aquí, a la derecha.
¿Ves lo que el número mágico es?
O más importante aún, ¿verdad ver cuál es el problema aquí?
En particular, si esta es sólo una función
en su propio archivo en un carpeta que contiene
un montón de diferentes archivos, cada uno de los cuales
hace otra cosa que una baraja de cartas.
Tal vez ellos baraja, o se ocupa una mano de cinco cartas en lugar de una sola tarjeta.
>> ¿Ves lo que el problema podría estar aquí?
¿Ves el número mágico He inyecta en el código?
Es el 52, a la derecha.
>> Al igual que, intuitivamente usted probablemente sabe, en Aceptar.
Al igual que una baraja de tarjetas contiene 52 cartas.
Pero en nuestro programa, es sólo tipo de flotando por ahí.
Es como, de repente, hay un 52.
>> Una forma de resolver este problema es que hacer esto.
Estamos muy explícitamente ahora diciendo en voz alta el tamaño de la cubierta como 52.
Se le da un poco más intuitivo es decir, cuando en el bucle for
más adelante, pues, diremos, i es menor que el tamaño de la cubierta.
Simplemente parece mejor que decir 52.
Ahora bien, esto realmente solucionar el problema.
Se da alguna simbólica sentido a la constante.
Pero sí especie de realidad introducir otro problema
que podría no ser evidente de inmediato.
Incluso si esta variable se declara globally--
Qué recuerdas lo que significa que cuando declaramos
una variable a nivel mundial frente a nivel local?
Incluso si declaramos una variable a nivel mundial, lo que si hay
otra función en nuestro conjunto de funciones
que tienen que ver con la manipulación de tarjetas que inadvertidamente cambios de tamaño de la cubierta,
o la aumenta por 1 o disminuye por 1.
Eso podría significar un problema, ¿verdad?
Sobre todo si estamos tratando con un conjunto de cartas donde barajar la baraja completa
es requerido.
Si se disminuye el tamaño de la cubierta por 1, por ejemplo, a 51,
no estamos realmente barajando todas las cartas, posiblemente.
Nos vamos a uno de ellos.
Y ese valor podría quizá ser predicho o explotada por un mal actor.
>> C ofrece lo que se llama un directiva de preprocesador, que
también se llama una macro para creando constantes simbólicas.
Y, de hecho, ya ha visto una directiva de preprocesador,
incluso si usted no ha oído llamado así con #include.
Es otro ejemplo de una macro o directiva de preprocesador.
>> La forma de crear constantes simbólicas, o dar un nombre a una constante
de modo que tenga más lo que significa, es como sigue.
#define, nombre, reemplazo.
Realmente importante a un lado aquí realmente rápido.
No ponga un punto y coma al Al final de sus #defines.
Así que es #define, nombre, reemplazo.
>> Cuando se compila el programa, lo que realmente sucede
es el compilador si va que pasar por su código
y reemplazar todas las instancias de la palabra "nombre" con todo lo que
poner como reemplazo.
Análogamente, si #include es una especie de similar a copiar y pegar,
entonces #define es una especie de similar a buscar y reemplazar,
si alguna vez has usado esa característica en un procesador de textos, por ejemplo.
>> Así, por ejemplo, si #define PI como 3.14159265,
si eres mejor matemáticamente inclinada y de repente
ver 3.14159265 vuelo todo en su código,
usted probablemente sabe que está hablando de pi.
Pero tal vez podamos darle una poco significado más simbólico.
Y en vez podemos decir #define pi como la boca llena de números
que yo no voy a seguir leer una y otra.
>> ¿Y qué va a pasar después a tiempo de compilación es cuando el programa es
compilado, lo primero que va a pasar es que va a ir a través de
y se reemplazará cada vez que considera el capital P, capital I,
va literalmente sustituirla por 3.14 y así sucesivamente, de modo que usted
no tener que escribirla cada tiempo, mientras que su programa aún
tiene la funcionalidad que esperar, porque estás trabajando
con manipulación, multiplicar, dividiendo, lo que sea por pi.
>> Usted no está limitado a este sustitución de sólo números.
Por ejemplo, yo podría #define Por supuesto como el CS50 cadena.
En este caso, cuando el programa se compila,
#define pasarán por la código, reemplace cada vez
ve "claro" con el CS50 cadena.
>> Se dará cuenta aquí también que con frecuencia
#define toda mi definido simbólica constantes, por así decirlo,
están siempre en mayúsculas.
Es una convención.
No es necesario.
La razón por lo general la gente utilizará todas las capitales cuando están #defining
es sólo para que sea realmente claro que este elemento particular de mi código
es una constante definida.
Si era minúscula, es posible que que podría confundirse con una variable.
Y eso es, probablemente, no es una buena cosa que hacer.
>> Así que este particular, solución es mucho mejor
que cualquiera de los anteriores.
Si yo primero #define tamaño de la cubierta 52, a continuación, ahora mi uso de 52, o el tamaño de la cubierta aquí,
es mucho más intuitivo y mucho más seguro.
No se puede manipular una constante.
No se puede decir 52 plus plus.
Eso no va a convertirlo a 53.
No se puede cambiar 52 a algo.
>> Puede cambiar una variable cuyo valor es 52,
que fue la primera solución que teníamos antes.
Y usted puede aumentar esa variable a 53.
Pero no se puede decir 52 plus plus y tener que de repente a su vez 52 a 53.
52 es siempre 52.
Y lo que no puede cambiar inadvertidamente tamaño de la cubierta aquí mediante la manipulación de ella,
>> Otro lado bueno efecto de esto, sin embargo es
que son conscientes de que no todos los países de todo el mundo
utilizar un mazo de cartas de tamaño de 52?
Por ejemplo, es muy común en Alemania utilizar un tamaño de cubierta de 32,
donde tira algunos de las cartas de menor valor.
Y en este caso, querido puerto de mi suite
de las funciones que tienen que ver con cartomagia a Alemania.
Que pude en la primera instancia que mostró, tienen que ir y reemplazar
todas las instancias de 52 en mi código con 32.
>> Pero aquí, si me #define tamaño de la cubierta 32 en la parte superior de mi código,
si tengo que cambiar, no puedo sólo tiene que ir y cambiar esa cosa.
Vuelva a compilar mi código, y todos repente se propaga a través.
De hecho, podemos cambiar la cubierta tamaño a cualquier valor que queremos.
>> ¿Te puedo interesar en un juego de tamaño de la cubierta de recogida?
>> Soy Doug Lloyd.
Y esto es CS50.