1 00:00:00,000 --> 00:00:02,350 >> [REPRODUCCIÓN DE MÚSICA] 2 00:00:02,350 --> 00:00:05,444 3 00:00:05,444 --> 00:00:06,360 DOUG LLOYD: De acuerdo. 4 00:00:06,360 --> 00:00:07,770 Tipo de un tema extraño, ¿no? 5 00:00:07,770 --> 00:00:09,050 Números de magia. 6 00:00:09,050 --> 00:00:12,012 Qué cierva quiere decir cuando es hablando de números mágicos? 7 00:00:12,012 --> 00:00:14,220 Bueno, algunos de los programas que hemos escrito en CS50 8 00:00:14,220 --> 00:00:16,660 hasta el momento han tenido alguna extraña números de tipo de arrojados en ellos. 9 00:00:16,660 --> 00:00:19,680 Tal vez por razones no lo hacemos totalmente entender ahora. 10 00:00:19,680 --> 00:00:23,950 Por ejemplo, en el problema Mario, nos cubiertas la altura de la pirámide de 23. 11 00:00:23,950 --> 00:00:26,880 Le dijimos explícitamente no puede ir más alto que 23. 12 00:00:26,880 --> 00:00:28,702 >> Pero, ¿qué quiere decir 23? 13 00:00:28,702 --> 00:00:30,410 Bueno, si usted lee el spec cuidadosamente, 14 00:00:30,410 --> 00:00:32,493 podría haber visto que el razón por la que coronó al 23 15 00:00:32,493 --> 00:00:36,160 es debido a que la altura estándar de una ventana de terminal es 24. 16 00:00:36,160 --> 00:00:38,860 Y por lo que si tenemos la pirámide ser más alto que eso, 17 00:00:38,860 --> 00:00:41,290 que podría hacer esa cosa rara donde se ejecuta fuera de la pantalla. 18 00:00:41,290 --> 00:00:45,140 Y ya sabes, lo que hace Eso significa que en el contexto, ¿no? 19 00:00:45,140 --> 00:00:48,880 >> ¿Es el significado de 23 inmediatamente obvio a alguien que mira a su programa 20 00:00:48,880 --> 00:00:51,550 y tal vez tiene una diferente ventana de terminal tamaño? 21 00:00:51,550 --> 00:00:52,330 Probablemente no. 22 00:00:52,330 --> 00:00:53,080 Parece que, en Aceptar. 23 00:00:53,080 --> 00:00:55,005 Bueno, ¿por qué es un poco menos de 23? 24 00:00:55,005 --> 00:00:56,880 En general, es una especie de un mal hábito en realidad 25 00:00:56,880 --> 00:00:58,940 para escribir constantes en el código. 26 00:00:58,940 --> 00:01:02,190 De este modo, cuando en realidad lo hace escribir una constante en su código, 27 00:01:02,190 --> 00:01:05,630 se refiere a veces como el uso de números mágicos, que es algo 28 00:01:05,630 --> 00:01:08,030 por lo general, queremos tratar de evitar. 29 00:01:08,030 --> 00:01:12,830 >> Por ejemplo, vamos a echar un vistazo Esta sencilla función aquí. 30 00:01:12,830 --> 00:01:15,726 Obviamente no hay datos tipo en C llamado tarjeta o cubierta. 31 00:01:15,726 --> 00:01:16,600 Así que tengan paciencia conmigo. 32 00:01:16,600 --> 00:01:18,910 Es un poco de pseudocódigo mezclado aquí. 33 00:01:18,910 --> 00:01:21,050 Esta es una función llamada tratar tarjeta que aparentemente 34 00:01:21,050 --> 00:01:26,570 toma una baraja como parámetro, y salida de voluntad para mí una sola tarjeta. 35 00:01:26,570 --> 00:01:30,990 >> Y yo estoy haciendo algo aquí donde yo tener un bucle que va desde 0 a 52, 36 00:01:30,990 --> 00:01:33,394 y me ocupo de una tarjeta. 37 00:01:33,394 --> 00:01:35,310 Bueno, tenemos una magia número aquí, a la derecha. 38 00:01:35,310 --> 00:01:38,790 ¿Ves lo que el número mágico es? 39 00:01:38,790 --> 00:01:42,280 O más importante aún, ¿verdad ver cuál es el problema aquí? 40 00:01:42,280 --> 00:01:44,310 En particular, si esta es sólo una función 41 00:01:44,310 --> 00:01:48,030 en su propio archivo en un carpeta que contiene 42 00:01:48,030 --> 00:01:49,970 un montón de diferentes archivos, cada uno de los cuales 43 00:01:49,970 --> 00:01:51,670 hace otra cosa que una baraja de cartas. 44 00:01:51,670 --> 00:01:57,310 Tal vez ellos baraja, o se ocupa una mano de cinco cartas en lugar de una sola tarjeta. 45 00:01:57,310 --> 00:01:59,420 >> ¿Ves lo que el problema podría estar aquí? 46 00:01:59,420 --> 00:02:03,220 ¿Ves el número mágico He inyecta en el código? 47 00:02:03,220 --> 00:02:04,390 Es el 52, a la derecha. 48 00:02:04,390 --> 00:02:06,440 >> Al igual que, intuitivamente usted probablemente sabe, en Aceptar. 49 00:02:06,440 --> 00:02:09,740 Al igual que una baraja de tarjetas contiene 52 cartas. 50 00:02:09,740 --> 00:02:12,570 Pero en nuestro programa, es sólo tipo de flotando por ahí. 51 00:02:12,570 --> 00:02:15,280 Es como, de repente, hay un 52. 52 00:02:15,280 --> 00:02:18,290 >> Una forma de resolver este problema es que hacer esto. 53 00:02:18,290 --> 00:02:22,724 Estamos muy explícitamente ahora diciendo en voz alta el tamaño de la cubierta como 52. 54 00:02:22,724 --> 00:02:25,390 Se le da un poco más intuitivo es decir, cuando en el bucle for 55 00:02:25,390 --> 00:02:28,650 más adelante, pues, diremos, i es menor que el tamaño de la cubierta. 56 00:02:28,650 --> 00:02:32,666 Simplemente parece mejor que decir 52. 57 00:02:32,666 --> 00:02:34,290 Ahora bien, esto realmente solucionar el problema. 58 00:02:34,290 --> 00:02:38,460 Se da alguna simbólica sentido a la constante. 59 00:02:38,460 --> 00:02:40,820 Pero sí especie de realidad introducir otro problema 60 00:02:40,820 --> 00:02:43,770 que podría no ser evidente de inmediato. 61 00:02:43,770 --> 00:02:45,859 Incluso si esta variable se declara globally-- 62 00:02:45,859 --> 00:02:47,650 Qué recuerdas lo que significa que cuando declaramos 63 00:02:47,650 --> 00:02:50,500 una variable a nivel mundial frente a nivel local? 64 00:02:50,500 --> 00:02:53,340 Incluso si declaramos una variable a nivel mundial, lo que si hay 65 00:02:53,340 --> 00:02:55,500 otra función en nuestro conjunto de funciones 66 00:02:55,500 --> 00:02:59,750 que tienen que ver con la manipulación de tarjetas que inadvertidamente cambios de tamaño de la cubierta, 67 00:02:59,750 --> 00:03:02,727 o la aumenta por 1 o disminuye por 1. 68 00:03:02,727 --> 00:03:04,060 Eso podría significar un problema, ¿verdad? 69 00:03:04,060 --> 00:03:08,261 Sobre todo si estamos tratando con un conjunto de cartas donde barajar la baraja completa 70 00:03:08,261 --> 00:03:08,760 es requerido. 71 00:03:08,760 --> 00:03:12,804 Si se disminuye el tamaño de la cubierta por 1, por ejemplo, a 51, 72 00:03:12,804 --> 00:03:14,970 no estamos realmente barajando todas las cartas, posiblemente. 73 00:03:14,970 --> 00:03:16,500 Nos vamos a uno de ellos. 74 00:03:16,500 --> 00:03:21,680 Y ese valor podría quizá ser predicho o explotada por un mal actor. 75 00:03:21,680 --> 00:03:24,920 >> C ofrece lo que se llama un directiva de preprocesador, que 76 00:03:24,920 --> 00:03:27,764 también se llama una macro para creando constantes simbólicas. 77 00:03:27,764 --> 00:03:30,180 Y, de hecho, ya ha visto una directiva de preprocesador, 78 00:03:30,180 --> 00:03:32,916 incluso si usted no ha oído llamado así con #include. 79 00:03:32,916 --> 00:03:37,150 Es otro ejemplo de una macro o directiva de preprocesador. 80 00:03:37,150 --> 00:03:41,290 >> La forma de crear constantes simbólicas, o dar un nombre a una constante 81 00:03:41,290 --> 00:03:43,740 de modo que tenga más lo que significa, es como sigue. 82 00:03:43,740 --> 00:03:47,030 #define, nombre, reemplazo. 83 00:03:47,030 --> 00:03:49,140 Realmente importante a un lado aquí realmente rápido. 84 00:03:49,140 --> 00:03:54,180 No ponga un punto y coma al Al final de sus #defines. 85 00:03:54,180 --> 00:03:57,310 Así que es #define, nombre, reemplazo. 86 00:03:57,310 --> 00:03:59,540 >> Cuando se compila el programa, lo que realmente sucede 87 00:03:59,540 --> 00:04:01,740 es el compilador si va que pasar por su código 88 00:04:01,740 --> 00:04:06,770 y reemplazar todas las instancias de la palabra "nombre" con todo lo que 89 00:04:06,770 --> 00:04:08,860 poner como reemplazo. 90 00:04:08,860 --> 00:04:13,060 Análogamente, si #include es una especie de similar a copiar y pegar, 91 00:04:13,060 --> 00:04:15,700 entonces #define es una especie de similar a buscar y reemplazar, 92 00:04:15,700 --> 00:04:19,180 si alguna vez has usado esa característica en un procesador de textos, por ejemplo. 93 00:04:19,180 --> 00:04:26,345 >> Así, por ejemplo, si #define PI como 3.14159265, 94 00:04:26,345 --> 00:04:28,720 si eres mejor matemáticamente inclinada y de repente 95 00:04:28,720 --> 00:04:31,640 ver 3.14159265 vuelo todo en su código, 96 00:04:31,640 --> 00:04:33,517 usted probablemente sabe que está hablando de pi. 97 00:04:33,517 --> 00:04:35,850 Pero tal vez podamos darle una poco significado más simbólico. 98 00:04:35,850 --> 00:04:39,850 Y en vez podemos decir #define pi como la boca llena de números 99 00:04:39,850 --> 00:04:42,110 que yo no voy a seguir leer una y otra. 100 00:04:42,110 --> 00:04:45,560 >> ¿Y qué va a pasar después a tiempo de compilación es cuando el programa es 101 00:04:45,560 --> 00:04:48,530 compilado, lo primero que va a pasar es que va a ir a través de 102 00:04:48,530 --> 00:04:51,520 y se reemplazará cada vez que considera el capital P, capital I, 103 00:04:51,520 --> 00:04:55,610 va literalmente sustituirla por 3.14 y así sucesivamente, de modo que usted 104 00:04:55,610 --> 00:04:58,090 no tener que escribirla cada tiempo, mientras que su programa aún 105 00:04:58,090 --> 00:05:00,631 tiene la funcionalidad que esperar, porque estás trabajando 106 00:05:00,631 --> 00:05:05,090 con manipulación, multiplicar, dividiendo, lo que sea por pi. 107 00:05:05,090 --> 00:05:08,230 >> Usted no está limitado a este sustitución de sólo números. 108 00:05:08,230 --> 00:05:12,279 Por ejemplo, yo podría #define Por supuesto como el CS50 cadena. 109 00:05:12,279 --> 00:05:14,070 En este caso, cuando el programa se compila, 110 00:05:14,070 --> 00:05:16,236 #define pasarán por la código, reemplace cada vez 111 00:05:16,236 --> 00:05:19,900 ve "claro" con el CS50 cadena. 112 00:05:19,900 --> 00:05:21,720 >> Se dará cuenta aquí también que con frecuencia 113 00:05:21,720 --> 00:05:26,090 #define toda mi definido simbólica constantes, por así decirlo, 114 00:05:26,090 --> 00:05:28,130 están siempre en mayúsculas. 115 00:05:28,130 --> 00:05:28,960 Es una convención. 116 00:05:28,960 --> 00:05:30,170 No es necesario. 117 00:05:30,170 --> 00:05:33,900 La razón por lo general la gente utilizará todas las capitales cuando están #defining 118 00:05:33,900 --> 00:05:37,590 es sólo para que sea realmente claro que este elemento particular de mi código 119 00:05:37,590 --> 00:05:38,820 es una constante definida. 120 00:05:38,820 --> 00:05:43,730 Si era minúscula, es posible que que podría confundirse con una variable. 121 00:05:43,730 --> 00:05:46,120 Y eso es, probablemente, no es una buena cosa que hacer. 122 00:05:46,120 --> 00:05:48,910 >> Así que este particular, solución es mucho mejor 123 00:05:48,910 --> 00:05:50,550 que cualquiera de los anteriores. 124 00:05:50,550 --> 00:05:59,950 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í, 125 00:05:59,950 --> 00:06:01,850 es mucho más intuitivo y mucho más seguro. 126 00:06:01,850 --> 00:06:03,280 No se puede manipular una constante. 127 00:06:03,280 --> 00:06:05,259 No se puede decir 52 plus plus. 128 00:06:05,259 --> 00:06:06,800 Eso no va a convertirlo a 53. 129 00:06:06,800 --> 00:06:09,390 No se puede cambiar 52 a algo. 130 00:06:09,390 --> 00:06:12,470 >> Puede cambiar una variable cuyo valor es 52, 131 00:06:12,470 --> 00:06:14,870 que fue la primera solución que teníamos antes. 132 00:06:14,870 --> 00:06:17,000 Y usted puede aumentar esa variable a 53. 133 00:06:17,000 --> 00:06:21,100 Pero no se puede decir 52 plus plus y tener que de repente a su vez 52 a 53. 134 00:06:21,100 --> 00:06:23,350 52 es siempre 52. 135 00:06:23,350 --> 00:06:28,860 Y lo que no puede cambiar inadvertidamente tamaño de la cubierta aquí mediante la manipulación de ella, 136 00:06:28,860 --> 00:06:29,940 137 00:06:29,940 --> 00:06:32,390 >> Otro lado bueno efecto de esto, sin embargo es 138 00:06:32,390 --> 00:06:38,310 que son conscientes de que no todos los países de todo el mundo 139 00:06:38,310 --> 00:06:40,690 utilizar un mazo de cartas de tamaño de 52? 140 00:06:40,690 --> 00:06:45,630 Por ejemplo, es muy común en Alemania utilizar un tamaño de cubierta de 32, 141 00:06:45,630 --> 00:06:48,020 donde tira algunos de las cartas de menor valor. 142 00:06:48,020 --> 00:06:50,960 Y en este caso, querido puerto de mi suite 143 00:06:50,960 --> 00:06:55,390 de las funciones que tienen que ver con cartomagia a Alemania. 144 00:06:55,390 --> 00:06:59,440 Que pude en la primera instancia que mostró, tienen que ir y reemplazar 145 00:06:59,440 --> 00:07:03,570 todas las instancias de 52 en mi código con 32. 146 00:07:03,570 --> 00:07:07,940 >> Pero aquí, si me #define tamaño de la cubierta 32 en la parte superior de mi código, 147 00:07:07,940 --> 00:07:11,730 si tengo que cambiar, no puedo sólo tiene que ir y cambiar esa cosa. 148 00:07:11,730 --> 00:07:15,010 Vuelva a compilar mi código, y todos repente se propaga a través. 149 00:07:15,010 --> 00:07:18,850 De hecho, podemos cambiar la cubierta tamaño a cualquier valor que queremos. 150 00:07:18,850 --> 00:07:22,500 >> ¿Te puedo interesar en un juego de tamaño de la cubierta de recogida? 151 00:07:22,500 --> 00:07:23,430 >> Soy Doug Lloyd. 152 00:07:23,430 --> 00:07:25,840 Y esto es CS50. 153 00:07:25,840 --> 00:07:27,772