1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Semana 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 [Esta es CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> Muy bien, esto es CS50, y este es el comienzo de la semana 4, 5 00:00:12,000 --> 00:00:16,000 y este es uno de los algoritmos de ordenación más lenta posible. 6 00:00:16,000 --> 00:00:19,000 ¿Cuál era lo que acabo de ver allí? 7 00:00:19,000 --> 00:00:24,000 Eso era una especie de burbuja, para gran O (n ^ 2) + resumen, 8 00:00:24,000 --> 00:00:28,000 y de hecho no somos los únicos en este mundo parece saber 9 00:00:28,000 --> 00:00:30,000 qué tipo burbuja o es su tiempo de ejecución. 10 00:00:30,000 --> 00:00:33,000 En efecto, se trataba de una entrevista con Eric Schmidt de Google 11 00:00:33,000 --> 00:00:45,000 y el ex senador Barack Obama sólo unos pocos años atrás. 12 00:00:45,000 --> 00:00:48,000 >> Ahora, el senador, que está aquí en Google, 13 00:00:48,000 --> 00:00:54,000 y me gusta pensar en la presidencia como una entrevista de trabajo. 14 00:00:54,000 --> 00:00:58,000 Ahora, es difícil conseguir un trabajo como presidente, y usted va a través de los rigores ahora. 15 00:00:58,000 --> 00:01:00,000 También es difícil conseguir un trabajo en Google. 16 00:01:00,000 --> 00:01:05,000 Tenemos preguntas, y le pedimos a nuestras preguntas candidatos, 17 00:01:05,000 --> 00:01:10,000 y éste es el de Larry Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Ustedes piensan que estoy bromeando? Está justo aquí. 19 00:01:14,000 --> 00:01:18,000 ¿Cuál es la forma más eficiente para ordenar un millón de enteros de 32 bits? 20 00:01:18,000 --> 00:01:21,000 [Risas] 21 00:01:21,000 --> 00:01:24,000 Well- 22 00:01:24,000 --> 00:01:26,000 Lo siento. >> No, no, no, no. 23 00:01:26,000 --> 00:01:34,000 Creo que el ordenamiento de burbuja sería el camino equivocado. 24 00:01:34,000 --> 00:01:39,000 >> Vamos, ¿quién le dijo eso? 25 00:01:39,000 --> 00:01:43,000 La semana pasada recordar que tomamos un descanso de código, al menos por un día, 26 00:01:43,000 --> 00:01:46,000 y comenzó a concentrarse en algunas ideas de alto nivel y resolución de problemas de manera más general 27 00:01:46,000 --> 00:01:49,000 en el contexto de búsqueda y clasificación, 28 00:01:49,000 --> 00:01:53,000 y hemos introducido algo que no teníamos una palmada este nombre en la semana pasada, 29 00:01:53,000 --> 00:01:56,000 pero notación asintótica, el Big O, el Omega Big, 30 00:01:56,000 --> 00:02:00,000 ya veces la notación grande Theta, y estos eran simplemente formas 31 00:02:00,000 --> 00:02:02,000 de describir el tiempo de ejecución de algoritmos, 32 00:02:02,000 --> 00:02:05,000 la cantidad de tiempo que le toma a un algoritmo para ejecutar. 33 00:02:05,000 --> 00:02:08,000 >> Y usted puede recordar que usted habló sobre el tiempo de ejecución en función del tamaño 34 00:02:08,000 --> 00:02:11,000 de la entrada, que generalmente llamamos n, sea cual sea el problema que sea, 35 00:02:11,000 --> 00:02:13,000 donde n es el número de personas en la habitación, 36 00:02:13,000 --> 00:02:17,000 el número de páginas de un libro de teléfono, y nos pusimos a escribir las cosas 37 00:02:17,000 --> 00:02:21,000 como O (n ^ 2) u O (n) o O (n log n), 38 00:02:21,000 --> 00:02:24,000 e incluso cuando las matemáticas no tuvo los resultados esperados con tanta perfección 39 00:02:24,000 --> 00:02:28,000 y fue n ² - n / 2 o algo por el estilo 40 00:02:28,000 --> 00:02:31,000 que en cambio sólo tirar algunos de los términos de orden inferior, 41 00:02:31,000 --> 00:02:34,000 y la motivación no es que de verdad queremos un 42 00:02:34,000 --> 00:02:37,000 especie de manera objetiva de evaluar 43 00:02:37,000 --> 00:02:39,000 el desempeño de los programas o el rendimiento de los algoritmos 44 00:02:39,000 --> 00:02:42,000 que al final del día no tiene nada que hacer, por ejemplo, 45 00:02:42,000 --> 00:02:45,000 con la velocidad de su equipo hoy. 46 00:02:45,000 --> 00:02:47,000 >> Por ejemplo, si implementa la ordenación de burbuja, 47 00:02:47,000 --> 00:02:50,000 o implementar fusionar sort sort o selección en el ordenador de hoy, 48 00:02:50,000 --> 00:02:53,000 un equipo de 2 GHz, y que lo ejecute, 49 00:02:53,000 --> 00:02:56,000 y se necesita un cierto número de segundos, el año que viene hay un 3 GHz 50 00:02:56,000 --> 00:02:59,000 o un ordenador de 4 GHz, y usted puede entonces afirmar que "Wow, mi algoritmo 51 00:02:59,000 --> 00:03:03,000 Ahora es el doble de rápido ", cuando en realidad eso no es obviamente el caso. 52 00:03:03,000 --> 00:03:06,000 Es sólo el hardware se ha vuelto más rápido, pero el equipo 53 00:03:06,000 --> 00:03:10,000 no tiene, y lo que realmente quieren deshacerse de cosas como 54 00:03:10,000 --> 00:03:13,000 múltiplos de 2 o múltiplos de 3, cuando se trata de describir 55 00:03:13,000 --> 00:03:17,000 qué tan rápido o lento como un algoritmo es justo y realmente se centran 56 00:03:17,000 --> 00:03:20,000 en n o algún factor del mismo, 57 00:03:20,000 --> 00:03:24,000 algo de energía de los mismos como en el caso de las clases de la semana pasada. 58 00:03:24,000 --> 00:03:27,000 Y recordar que, con la ayuda de la especie de mezcla 59 00:03:27,000 --> 00:03:31,000 hemos sido capaces de hacerlo mucho mejor que la ordenación de burbuja y ordenamiento por selección 60 00:03:31,000 --> 00:03:33,000 e incluso la inserción de clasificación. 61 00:03:33,000 --> 00:03:36,000 >> Nos pusimos manos a la n log n, y otra vez, 62 00:03:36,000 --> 00:03:39,000 Recordemos que log n generalmente se refiere a algo que crece 63 00:03:39,000 --> 00:03:43,000 más lentamente n, por lo que n log n hasta el momento era bueno 64 00:03:43,000 --> 00:03:45,000 porque era menos de ² n. 65 00:03:45,000 --> 00:03:47,000 Pero para lograr n log n con una especie de mezcla 66 00:03:47,000 --> 00:03:51,000 lo que fue el germen de una idea básica de que teníamos que aprovechar 67 00:03:51,000 --> 00:03:54,000 que también aprovechó de nuevo en la semana 0? 68 00:03:54,000 --> 00:03:58,000 ¿Cómo abordamos el problema de clasificación inteligente con una especie de mezcla? 69 00:03:58,000 --> 00:04:04,000 ¿Cuál fue la idea clave, tal vez? 70 00:04:04,000 --> 00:04:07,000 Cualquier persona en absoluto. 71 00:04:07,000 --> 00:04:09,000 Bueno, vamos a dar un paso atrás. 72 00:04:09,000 --> 00:04:11,000 Describir merge sort en sus propias palabras. 73 00:04:11,000 --> 00:04:15,000 ¿Cómo funciona? 74 00:04:15,000 --> 00:04:17,000 Bueno, vamos a remar de nuevo a 0 la semana. 75 00:04:17,000 --> 00:04:19,000 Bueno, sí. 76 00:04:19,000 --> 00:04:22,000 [Inaudible-alumno] 77 00:04:22,000 --> 00:04:26,000 Bueno, bueno, así que divide el conjunto de los números en 2 piezas. 78 00:04:26,000 --> 00:04:29,000 Hemos clasificado cada una de esas piezas, y luego los fusionaron, 79 00:04:29,000 --> 00:04:33,000 y hemos visto esta idea antes de tomar un problema que es tan grande 80 00:04:33,000 --> 00:04:36,000 y picando para arriba en un problema que es tan grande o grande esto. 81 00:04:36,000 --> 00:04:38,000 >> Recordemos el ejemplo guía telefónica. 82 00:04:38,000 --> 00:04:42,000 Recordemos el algoritmo de auto-conteo de semanas atrás, 83 00:04:42,000 --> 00:04:45,000 especie para fusionar fue resumido por este pseudocódigo aquí. 84 00:04:45,000 --> 00:04:48,000 Cuando te dan n elementos, primero fue comprobación de validez. 85 00:04:48,000 --> 00:04:51,000 Si n <2, entonces no hago nada en absoluto 86 00:04:51,000 --> 00:04:55,000 porque si n <2 entonces n es 0 o 1, obviamente, 87 00:04:55,000 --> 00:04:57,000 y lo que si es 0 o 1, no hay nada que ordenar. 88 00:04:57,000 --> 00:04:59,000 Eso es todo. 89 00:04:59,000 --> 00:05:01,000 La lista ya está trivialmente ordenado. 90 00:05:01,000 --> 00:05:04,000 Pero por lo demás, si tienes dos o más elementos que adelante y dividirlos 91 00:05:04,000 --> 00:05:06,000 en 2 mitades, izquierda y derecha. 92 00:05:06,000 --> 00:05:09,000 Clasifique cada una de esas mitades, y luego fusionar las dos mitades ordenadas. 93 00:05:09,000 --> 00:05:13,000 Pero el problema aquí es que a primera vista esto parece que estamos batea. 94 00:05:13,000 --> 00:05:17,000 Esta es una definición circular en que si yo he pedido que ordenar estos n elementos 95 00:05:17,000 --> 00:05:22,000 y que me estás diciendo "Está bien, está bien, vamos a ordenar los elementos n / 2 yn aquellos / 2" 96 00:05:22,000 --> 00:05:27,000 entonces mi pregunta viene va a ser "bien, ¿cómo clasificar el n / 2 elementos?" 97 00:05:27,000 --> 00:05:30,000 >> Pero debido a la estructura de este programa, 98 00:05:30,000 --> 00:05:33,000 porque no es este el caso base, por así decirlo, 99 00:05:33,000 --> 00:05:39,000 este caso especial que dice que si n es 00:05:42,000 No responda con esa respuesta circular mismo. 101 00:05:42,000 --> 00:05:46,000 Este proceso, esta ciclicidad finalmente terminará. 102 00:05:46,000 --> 00:05:50,000 Si te pregunto "Sort estos n elementos," y usted dice: "Está bien, ordenar estos n / 2" 103 00:05:50,000 --> 00:05:53,000 entonces dices, "una especie bien, estos n / 4, n / 8, N/16," 104 00:05:53,000 --> 00:05:56,000 eventualmente podrás dividir por un número suficientemente grande 105 00:05:56,000 --> 00:05:59,000 que tendrá sólo un elemento de la izquierda, momento en que se puede decir, 106 00:05:59,000 --> 00:06:02,000 "Aquí, aquí hay un elemento ordenados simple". 107 00:06:02,000 --> 00:06:06,000 A continuación, la brillantez de este algoritmo aquí es derivar del hecho 108 00:06:06,000 --> 00:06:09,000 que una vez que tenga todas estas listas individualmente ordenados, 109 00:06:09,000 --> 00:06:12,000 todos los cuales son de tamaño 1, que parece ser inútil, 110 00:06:12,000 --> 00:06:15,000 una vez que inicie su fusión y la fusión 111 00:06:15,000 --> 00:06:19,000 construir el edificio finalmente como Rob hizo en el video finalmente una lista ordenada. 112 00:06:19,000 --> 00:06:22,000 >> Pero esta idea se extiende mucho más allá de la clasificación. 113 00:06:22,000 --> 00:06:26,000 Existe esta idea incrustada en este programa se conoce como recursión, 114 00:06:26,000 --> 00:06:29,000 por lo que la idea es un programa, 115 00:06:29,000 --> 00:06:32,000 y para resolver algún problema que te llame, 116 00:06:32,000 --> 00:06:36,000 o poner en el contexto de los lenguajes de programación que están en función, 117 00:06:36,000 --> 00:06:39,000 y con el fin de resolver un problema, la función llama a sí mismo 118 00:06:39,000 --> 00:06:42,000 una y otra vez y otra vez, pero la función 119 00:06:42,000 --> 00:06:44,000 no puede llamarse a sí mismo infinitas veces. 120 00:06:44,000 --> 00:06:47,000 Finalmente, tiene hasta llegar al fondo, por así decirlo, 121 00:06:47,000 --> 00:06:49,000 y tienen alguna condición de base rígida que dice 122 00:06:49,000 --> 00:06:53,000 en este punto, dejar de llamar a ti mismo para que todo el proceso 123 00:06:53,000 --> 00:06:56,000 Por último es de hecho detener. 124 00:06:56,000 --> 00:06:58,000 ¿Qué significa esto en realidad, a recurse? 125 00:06:58,000 --> 00:07:01,000 >> Vamos a ver si podemos hacer un ejemplo simple, trivial con, digamos, 126 00:07:01,000 --> 00:07:03,000 3 personas conmigo hasta aquí en el escenario, si alguien se sienta cómodo. 127 00:07:03,000 --> 00:07:06,000 1, vamos arriba, 2 y 3. 128 00:07:06,000 --> 00:07:09,000 3 Si quieren venir aquí. 129 00:07:09,000 --> 00:07:12,000 Si quieres estar a mi lado aquí en una línea, supongamos que el problema en cuestión 130 00:07:12,000 --> 00:07:15,000 es muy trivial contar el número de personas que están aquí. 131 00:07:15,000 --> 00:07:18,000 Pero, francamente, estoy cansado de todos estos ejemplos de conteo. 132 00:07:18,000 --> 00:07:21,000 Esto va a tomar algún tiempo, 1, 2, y punto, punto, punto. 133 00:07:21,000 --> 00:07:23,000 Esto va a tardar una eternidad. 134 00:07:23,000 --> 00:07:25,000 Prefiero punt este problema en conjunto con la ayuda de cual es tu nombre? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, está bien. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly y? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly, y Willy. 138 00:07:31,000 --> 00:07:34,000 Ahora mismo me he hecho la pregunta por alguien 139 00:07:34,000 --> 00:07:37,000 número de personas que estén en esta etapa, y no tengo ni idea. 140 00:07:37,000 --> 00:07:40,000 Esta es una lista muy larga, por lo que en lugar de eso voy a hacer este truco. 141 00:07:40,000 --> 00:07:43,000 Voy a pedir a la persona a mi lado para hacer la mayor parte de la obra, 142 00:07:43,000 --> 00:07:46,000 y una vez que se lleva a cabo haciendo la mayoría del trabajo 143 00:07:46,000 --> 00:07:49,000 Voy a hacer la menor cantidad de trabajo posible y sólo tiene que añadir un 144 00:07:49,000 --> 00:07:51,000 a lo que su respuesta es, así que aquí vamos. 145 00:07:51,000 --> 00:07:54,000 Me han preguntado cuántas personas hay en el escenario. 146 00:07:54,000 --> 00:07:57,000 ¿Cuántas personas hay en el escenario a la izquierda de usted? 147 00:07:57,000 --> 00:08:00,000 La izquierda de mí? >> Está bien, pero no hagas trampa. 148 00:08:00,000 --> 00:08:04,000 Eso es bueno, eso es correcto, pero si queremos seguir esta lógica 149 00:08:04,000 --> 00:08:08,000 vamos a suponer que usted desea de manera similar a despejar este problema a la izquierda de usted, 150 00:08:08,000 --> 00:08:11,000 así que en lugar de contestar directamente adelante, sólo tiene que pasar la pelota. 151 00:08:11,000 --> 00:08:14,000 Oh, cuántas personas hay a la izquierda de mí? 152 00:08:14,000 --> 00:08:16,000 ¿Cuántas personas hay a la izquierda? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Risas] 155 00:08:27,000 --> 00:08:30,000 Bien, 0, así que lo que ha hecho ahora Willy 156 00:08:30,000 --> 00:08:33,000 se ha vuelto su respuesta diciendo esta dirección 0. 157 00:08:33,000 --> 00:08:36,000 Ahora, ¿qué debe hacer? >> 1. 158 00:08:36,000 --> 00:08:39,000 Bien, así que usted es el 1, por lo que dicen: "Está bien, voy a añadir un 159 00:08:39,000 --> 00:08:41,000 a cualquier número de Willy era, "así 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Usted es ahora 1 por lo que su respuesta a la derecha es ahora 161 00:08:43,000 --> 00:08:45,000 1. >> Y el mío sería 2. 162 00:08:45,000 --> 00:08:48,000 Bueno, por lo que está tomando la respuesta anterior de 1, 163 00:08:48,000 --> 00:08:51,000 la adición de la cantidad mínima de trabajo que quiere hacer, que es +1. 164 00:08:51,000 --> 00:08:55,000 Ahora tiene 2, y luego la mano que me valor? 165 00:08:55,000 --> 00:08:57,000 3, es decir, lo siento, 2. 166 00:08:57,000 --> 00:08:59,000 Bueno. 167 00:08:59,000 --> 00:09:02,000 >> Bueno, tuvimos 0 a la izquierda. 168 00:09:02,000 --> 00:09:05,000 Luego tuvimos una, y luego añadimos 2, 169 00:09:05,000 --> 00:09:07,000 y ahora me estás dando el número 2, 170 00:09:07,000 --> 00:09:10,000 y por lo que estoy diciendo, bueno, +1, 3. 171 00:09:10,000 --> 00:09:13,000 Hay en realidad tres personas de pie junto a mí en esta etapa, 172 00:09:13,000 --> 00:09:16,000 así que podría haber hecho esto, obviamente, muy lineal, 173 00:09:16,000 --> 00:09:19,000 en gran medida de la manera obvia, pero ¿qué hacemos realmente? 174 00:09:19,000 --> 00:09:21,000 Tomamos un problema de tamaño 3 inicialmente. 175 00:09:21,000 --> 00:09:24,000 A continuación, se rompió en un problema de tamaño 2, 176 00:09:24,000 --> 00:09:27,000 entonces un problema de tamaño 1 y, a continuación, finalmente, el caso base 177 00:09:27,000 --> 00:09:29,000 Fue muy, oh, no hay nadie allí, 178 00:09:29,000 --> 00:09:33,000 momento en el que Willy volvió efectivamente una respuesta codificada de un par de veces, 179 00:09:33,000 --> 00:09:36,000 y el segundo se hizo burbujear luego hacia arriba, brotaba, burbujeaba, 180 00:09:36,000 --> 00:09:39,000 y luego añadiendo en éste adicional 1 181 00:09:39,000 --> 00:09:41,000 hemos implementado esta idea básica de la recursividad. 182 00:09:41,000 --> 00:09:44,000 >> Ahora, en este caso, realmente no resolver un problema 183 00:09:44,000 --> 00:09:46,000 cualquier forma más eficaz entonces que hemos visto hasta el momento. 184 00:09:46,000 --> 00:09:48,000 Pero piensa en los algoritmos que hemos hecho en el escenario hasta el momento. 185 00:09:48,000 --> 00:09:51,000 Tuvimos a 8 hojas de papel en la pizarra, 186 00:09:51,000 --> 00:09:55,000 En el vídeo cuando Sean estaba buscando el número 7, y ¿qué hizo realmente? 187 00:09:55,000 --> 00:09:58,000 Bueno, él no hizo ningún tipo de divide y vencerás. 188 00:09:58,000 --> 00:10:01,000 Él no hizo ningún tipo de recursión. 189 00:10:01,000 --> 00:10:03,000 Más bien, él acaba de hacer este algoritmo lineal. 190 00:10:03,000 --> 00:10:07,000 Sin embargo, cuando se introdujo la idea de números ordenados en el escenario en vivo la semana pasada 191 00:10:07,000 --> 00:10:09,000 luego tuvimos ese instinto de ir hacia el centro, 192 00:10:09,000 --> 00:10:13,000 momento en el que teníamos una lista más pequeña de tamaño 4 o otra lista de tamaño 4, 193 00:10:13,000 --> 00:10:17,000 y luego tuvimos el mismo problema, por lo que repite, repite, repite. 194 00:10:17,000 --> 00:10:19,000 En otras palabras, recursed. 195 00:10:19,000 --> 00:10:24,000 Muchas gracias a nuestros 3 voluntarios aquí para demostrar la recursividad con nosotros. 196 00:10:24,000 --> 00:10:28,000 >> Vamos a ver si podemos hacer esto ahora concretar un poco más, 197 00:10:28,000 --> 00:10:30,000 la solución de un problema que una vez más podemos hacer con bastante facilidad, 198 00:10:30,000 --> 00:10:34,000 pero vamos a utilizar como punto de partida para la aplicación de esta idea básica. 199 00:10:34,000 --> 00:10:37,000 Si desea calcular la suma de un montón de números, 200 00:10:37,000 --> 00:10:39,000 por ejemplo, si se pasa en el número 3, 201 00:10:39,000 --> 00:10:42,000 Quiero darle el valor de sigma 3, 202 00:10:42,000 --> 00:10:46,000 por lo que la suma de 3 + 2 + 1 + 0. 203 00:10:46,000 --> 00:10:48,000 Quiero volver a la respuesta 6, 204 00:10:48,000 --> 00:10:51,000 así que vamos a implementar esta función sigma, esta función suma 205 00:10:51,000 --> 00:10:54,000 que, de nuevo, toma en entrada y, a continuación devuelve la suma 206 00:10:54,000 --> 00:10:57,000 de ese número todo el camino hacia abajo a 0. 207 00:10:57,000 --> 00:10:59,000 Podríamos hacer esto bastante simple, ¿no? 208 00:10:59,000 --> 00:11:01,000 Podemos hacer esto con algún tipo de estructura de bucle, 209 00:11:01,000 --> 00:11:04,000 así que voy a seguir adelante y que esto empiece. 210 00:11:04,000 --> 00:11:07,000 >> Incluir stdio.h. 211 00:11:07,000 --> 00:11:09,000 Déjame entrar en principal para trabajar aquí. 212 00:11:09,000 --> 00:11:12,000 Vamos a guardar esto como sigma.c. 213 00:11:12,000 --> 00:11:14,000 Entonces me voy a ir de aquí, y voy a declarar un int n, 214 00:11:14,000 --> 00:11:18,000 y yo voy a hacer lo siguiente mientras el usuario no cooperar. 215 00:11:18,000 --> 00:11:22,000 Mientras el usuario no me ha dado un número positivo 216 00:11:22,000 --> 00:11:26,000 déjame ir delante y le pedirá que para n = getInt, 217 00:11:26,000 --> 00:11:28,000 y déjame darles algunas instrucciones en cuanto a qué hacer, 218 00:11:28,000 --> 00:11:33,000 así printf ("entero positivo por favor"). 219 00:11:33,000 --> 00:11:39,000 Sólo es algo relativamente sencillo como éste, así que para cuando llegamos a la línea 14 220 00:11:39,000 --> 00:11:42,000 ahora tenemos un número entero positivo, presumiblemente en el n. 221 00:11:42,000 --> 00:11:44,000 >> Ahora vamos a hacer algo con él. 222 00:11:44,000 --> 00:11:50,000 Déjame ir por delante y calcular la suma, por lo que int suma = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma es sólo la suma, así que estoy escribiendo en la forma más elegante. 224 00:11:54,000 --> 00:11:56,000 Vamos a llamarlo sigma allí. 225 00:11:56,000 --> 00:11:58,000 Esa es la suma, y ​​ahora me voy a imprimir el resultado, 226 00:11:58,000 --> 00:12:08,000 printf ("La suma es% d \ n", suma). 227 00:12:08,000 --> 00:12:11,000 Y luego voy a devolver 0 para una buena medida. 228 00:12:11,000 --> 00:12:15,000 Hemos hecho todo lo que este programa requiere excepto la parte interesante, 229 00:12:15,000 --> 00:12:18,000 que es para aplicar en la práctica la función de sigma. 230 00:12:18,000 --> 00:12:22,000 >> Déjame aquí abajo a la parte inferior, y déjame declarar función sigma. 231 00:12:22,000 --> 00:12:26,000 Tiene que tomar una variable es de tipo entero, 232 00:12:26,000 --> 00:12:30,000 y qué tipo de datos es lo que quiero volver presumiblemente de sigma? 233 00:12:30,000 --> 00:12:34,000 Int, porque quiero que mis expectativas en la línea 15. 234 00:12:34,000 --> 00:12:37,000 En aquí déjame seguir adelante y poner en práctica este 235 00:12:37,000 --> 00:12:41,000 de una manera bastante sencilla. 236 00:12:41,000 --> 00:12:45,000 >> Vamos a seguir adelante y decir: int suma = 0, 237 00:12:45,000 --> 00:12:47,000 y ahora me voy a ir a tomar un poco de bucle aquí 238 00:12:47,000 --> 00:12:50,000 que va a decir algo como esto, 239 00:12:50,000 --> 00:13:01,000 for (int i = 0; I <= número, i + +) suma + = i. 240 00:13:01,000 --> 00:13:05,000 Y luego me voy a volver suma. 241 00:13:05,000 --> 00:13:07,000 Que podría haber implementado este en cualquier número de maneras. 242 00:13:07,000 --> 00:13:09,000 Podría haber usado un bucle while. 243 00:13:09,000 --> 00:13:11,000 Podría haber omitido usando la variable suma si realmente quería, 244 00:13:11,000 --> 00:13:15,000 pero en fin, solo tenemos una función que si no lo hacía bobo declara suma es 0. 245 00:13:15,000 --> 00:13:18,000 Entonces se repite desde 0 a arriba a través del número, 246 00:13:18,000 --> 00:13:23,000 y en cada iteración se añade que el valor actual de suma y luego devuelve suma. 247 00:13:23,000 --> 00:13:25,000 >> Ahora, hay una ligera optimización de aquí. 248 00:13:25,000 --> 00:13:29,000 Esto es probablemente un paso perdido, pero que así sea. Eso está bien por ahora. 249 00:13:29,000 --> 00:13:32,000 Estamos por lo menos ser exhaustivo y va todo el camino de 0 en adelante. 250 00:13:32,000 --> 00:13:34,000 No es muy duro y directo bonito, 251 00:13:34,000 --> 00:13:37,000 pero resulta que con la función sigma tenemos la misma oportunidad 252 00:13:37,000 --> 00:13:39,000 como lo hicimos aquí en el escenario. 253 00:13:39,000 --> 00:13:42,000 En el escenario que acabamos de contar cuántas personas estaban a mi lado, 254 00:13:42,000 --> 00:13:47,000 pero en cambio si queremos contar el número 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 hacia abajo a 0 pudimos similar punt a una función 256 00:13:51,000 --> 00:13:55,000 que en lugar describiremos como recursivo. 257 00:13:55,000 --> 00:13:57,000 Aquí vamos a hacer un juicio rápido comprobar y asegurarse de que no me bobo. 258 00:13:57,000 --> 00:14:00,000 >> Sé que hay al menos una cosa en este programa que me hizo mal. 259 00:14:00,000 --> 00:14:04,000 Cuando llegué a entrar voy a conseguir cualquier tipo de gritarme? 260 00:14:04,000 --> 00:14:06,000 ¿Qué voy a gritar en esto? 261 00:14:06,000 --> 00:14:11,000 Sí, se me olvidó el prototipo, así que estoy usando una función llamada sigma en la línea 15, 262 00:14:11,000 --> 00:14:16,000 pero no se declaró hasta la línea 22, así que mejor manera proactiva subir aquí 263 00:14:16,000 --> 00:14:22,000 y declarar un prototipo, y voy a decir sigma int (int numero), y eso es todo. 264 00:14:22,000 --> 00:14:24,000 Se implementa en la parte inferior. 265 00:14:24,000 --> 00:14:27,000 >> U otra manera de que pudiera resolver esto, 266 00:14:27,000 --> 00:14:30,000 Podía mover la función hasta allí, lo cual no es malo, 267 00:14:30,000 --> 00:14:32,000 pero por lo menos cuando los programas comienzan a hacer larga, francamente, 268 00:14:32,000 --> 00:14:35,000 Creo que hay algo de valor en tener siempre principal en la parte superior 269 00:14:35,000 --> 00:14:38,000 para que en el lector puede abrir el archivo y ver inmediatamente 270 00:14:38,000 --> 00:14:40,000 lo que está haciendo el programa sin tener que buscar a través de ella 271 00:14:40,000 --> 00:14:42,000 buscando que la función principal. 272 00:14:42,000 --> 00:14:49,000 Vamos a ir a mi ventana de terminal aquí, trate de hacer sigma sigma hacer, 273 00:14:49,000 --> 00:14:51,000 y metí la pata aquí también. 274 00:14:51,000 --> 00:14:55,000 Declaración implícita de la función getInt significa que me haya olvidado de hacer lo otro? 275 00:14:55,000 --> 00:14:57,000 [Inaudible-alumno] 276 00:14:57,000 --> 00:15:00,000 Bueno, por lo que al parecer un error muy común, así que vamos a poner esto aquí, 277 00:15:00,000 --> 00:15:04,000 cs50.h, y ahora vamos a volver a mi ventana de terminal. 278 00:15:04,000 --> 00:15:08,000 >> Voy a borrar la pantalla, y voy a hacer volver a ejecutar sigma. 279 00:15:08,000 --> 00:15:11,000 Parece que se ha compilado. Permítanme ahora se ejecutan sigma. 280 00:15:11,000 --> 00:15:15,000 Voy a escribir el número 3, y me dieron 6, así que no es un cheque riguroso, 281 00:15:15,000 --> 00:15:18,000 pero al menos parece estar funcionando a primera vista, pero ahora vamos a destrozar, 282 00:15:18,000 --> 00:15:21,000 y vamos a aprovechar realmente la idea de la repetición, de nuevo, 283 00:15:21,000 --> 00:15:24,000 en un contexto muy simple, así que dentro de unas semanas 284 00:15:24,000 --> 00:15:27,000 cuando empezamos a explorar más elegantes estructuras de datos de arrays 285 00:15:27,000 --> 00:15:30,000 tenemos otra herramienta en la caja de herramientas con las que 286 00:15:30,000 --> 00:15:33,000 manipular las estructuras de datos, como veremos. 287 00:15:33,000 --> 00:15:36,000 Este es el enfoque iterativo, el enfoque basado en bucle. 288 00:15:36,000 --> 00:15:39,000 >> Permítanme ahora hacer esta vez. 289 00:15:39,000 --> 00:15:44,000 Permítanme decir que en lugar de la suma del número de 290 00:15:44,000 --> 00:15:48,000 abajo a 0 es realmente la misma cosa que 291 00:15:48,000 --> 00:15:53,000 número + sigma (número - 1). 292 00:15:53,000 --> 00:15:57,000 En otras palabras, al igual que en el escenario me pateó a cada una de las personas junto a mí, 293 00:15:57,000 --> 00:16:00,000 y ellos a su vez mantiene patear hasta que finalmente tocó fondo en Willy, 294 00:16:00,000 --> 00:16:03,000 quien tuvo que regresar una respuesta codificada como 0. 295 00:16:03,000 --> 00:16:07,000 Aquí ahora estamos igualmente batea para sigma 296 00:16:07,000 --> 00:16:10,000 la misma función que fue llamado originalmente, pero aquí la idea clave 297 00:16:10,000 --> 00:16:12,000 es que no estamos llamando sigma idéntica. 298 00:16:12,000 --> 00:16:14,000 No estamos de paso en el n. 299 00:16:14,000 --> 00:16:17,000 Estamos pasando claramente en número - 1, 300 00:16:17,000 --> 00:16:20,000 por lo que un problema un poco más pequeño, ligeramente más pequeño problema. 301 00:16:20,000 --> 00:16:23,000 >> Desafortunadamente, esto no es del todo una solución, sin embargo, y antes de fijar 302 00:16:23,000 --> 00:16:26,000 lo que podría saltar tan evidente en algunos de ustedes 303 00:16:26,000 --> 00:16:28,000 déjame seguir adelante y volver a ejecutar hacer. 304 00:16:28,000 --> 00:16:30,000 Parece que compile bien. 305 00:16:30,000 --> 00:16:32,000 Permítanme volver a ejecutar sigma con 6. 306 00:16:32,000 --> 00:16:37,000 ¡Vaya, déjame volver a ejecutar sigma con 6. 307 00:16:37,000 --> 00:16:42,000 Hemos visto esto antes, aunque sea accidentalmente tiempo pasado también. 308 00:16:42,000 --> 00:16:48,000 ¿Por qué me sale este error de segmentación críptico? Si. 309 00:16:48,000 --> 00:16:50,000 [Inaudible-alumno] 310 00:16:50,000 --> 00:16:53,000 No hay caso base, y más específicamente, lo que probablemente sucedió? 311 00:16:53,000 --> 00:16:58,000 Este es un síntoma de lo que el comportamiento? 312 00:16:58,000 --> 00:17:00,000 Digamos que un poco más fuerte. 313 00:17:00,000 --> 00:17:02,000 [Inaudible-alumno] 314 00:17:02,000 --> 00:17:05,000 Es un bucle infinito eficazmente, y el problema con los bucles infinitos 315 00:17:05,000 --> 00:17:08,000 cuando implican recursión en este caso, una función que se hace llamar, 316 00:17:08,000 --> 00:17:10,000 lo que ocurre cada vez que se llama a una función? 317 00:17:10,000 --> 00:17:13,000 Bueno, piense en la forma en que expuso la memoria en una computadora. 318 00:17:13,000 --> 00:17:16,000 Hemos dicho que hay esta cantidad de memoria llamado la pila que está en el fondo, 319 00:17:16,000 --> 00:17:19,000 y cada vez que se llama a una función de memoria un poco más se puso 320 00:17:19,000 --> 00:17:24,000 en esta pila de llamada que contiene las variables locales de dicha función o parámetros, 321 00:17:24,000 --> 00:17:27,000 por lo que si sigma sigma sigma Las llamadas llama sigma 322 00:17:27,000 --> 00:17:29,000  llama sigma donde termina esta historia? 323 00:17:29,000 --> 00:17:31,000 >> Bueno, con el tiempo los excesos de la cantidad total 324 00:17:31,000 --> 00:17:33,000 de memoria que tiene disponible en su ordenador. 325 00:17:33,000 --> 00:17:37,000 Usted invadir el segmento que se supone que debes permanecer en el interior, 326 00:17:37,000 --> 00:17:40,000 y se obtiene este error de segmentación, el núcleo de dumping, 327 00:17:40,000 --> 00:17:43,000 y qué core dumped significa es que ahora tengo un archivo llamado núcleo 328 00:17:43,000 --> 00:17:46,000 que es un archivo que contiene ceros y unos 329 00:17:46,000 --> 00:17:49,000 que en realidad en el futuro será útil para el diagnóstico. 330 00:17:49,000 --> 00:17:52,000 Si no te resulta obvio que su error es 331 00:17:52,000 --> 00:17:54,000 en realidad se puede hacer un poco de análisis forense, por así decirlo, 332 00:17:54,000 --> 00:17:58,000 en el archivo volcado de memoria, que, de nuevo, es sólo un montón de ceros y unos 333 00:17:58,000 --> 00:18:02,000 que en esencia representa el estado de su programa en la memoria 334 00:18:02,000 --> 00:18:05,000 el momento en que cayó de esta manera. 335 00:18:05,000 --> 00:18:11,000 >> La solución aquí es que no podemos volver a ciegas sigma, 336 00:18:11,000 --> 00:18:14,000 el número sigma + de un problema un poco más pequeño. 337 00:18:14,000 --> 00:18:16,000 Tenemos que tener algún tipo de caso base aquí, 338 00:18:16,000 --> 00:18:19,000 y lo que el caso base probablemente ser? 339 00:18:19,000 --> 00:18:22,000 [Inaudible-alumno] 340 00:18:22,000 --> 00:18:25,000 Está bien, siempre y cuando el número es positivo que en realidad debería devolver esto, 341 00:18:25,000 --> 00:18:29,000 o dicho de otra manera, si el número es, por ejemplo, <= a 0 342 00:18:29,000 --> 00:18:32,000 Sabes qué, voy a seguir adelante y devolver 0, 343 00:18:32,000 --> 00:18:36,000 al igual que Willy lo hizo, y otra cosa, yo voy a seguir adelante 344 00:18:36,000 --> 00:18:41,000 y devolver este, por lo que no es mucho más corto 345 00:18:41,000 --> 00:18:44,000 que la versión iterativa que fustigó primero usando un bucle for, 346 00:18:44,000 --> 00:18:48,000 notar que hay este tipo de elegancia a la misma. 347 00:18:48,000 --> 00:18:51,000 En lugar de devolver un número y realizar toda esta matemática 348 00:18:51,000 --> 00:18:54,000 y la adición de las cosas con las variables locales 349 00:18:54,000 --> 00:18:57,000 vez que estés diciendo: "Bueno, si esto es un problema fácil de super, 350 00:18:57,000 --> 00:19:01,000 al igual que el número es <0, déjame inmediatamente devolverá 0. " 351 00:19:01,000 --> 00:19:03,000 >> No vamos a molestar apoyo números negativos, 352 00:19:03,000 --> 00:19:05,000 así que voy a codificar el valor de 0. 353 00:19:05,000 --> 00:19:08,000 Pero por lo demás, para poner en práctica esta idea de sumar 354 00:19:08,000 --> 00:19:11,000 todos estos números juntos que efectivamente puede tomar un bocado pequeño 355 00:19:11,000 --> 00:19:14,000 para salir del problema, al igual que lo hicimos aquí en el escenario, 356 00:19:14,000 --> 00:19:18,000 entonces batea el resto del problema a la siguiente persona, 357 00:19:18,000 --> 00:19:20,000 pero en este caso la siguiente persona es uno mismo. 358 00:19:20,000 --> 00:19:22,000 Se trata de una función con el mismo nombre. 359 00:19:22,000 --> 00:19:25,000 Sólo tienes que pasar un problema cada vez más pequeños y más pequeños cada vez, 360 00:19:25,000 --> 00:19:28,000 ya pesar de que no tienen las cosas muy formalizados en el código aquí 361 00:19:28,000 --> 00:19:33,000 esto es exactamente lo que estaba pasando en la semana 0 con la guía telefónica. 362 00:19:33,000 --> 00:19:36,000 Esto es exactamente lo que estaba sucediendo en las últimas semanas con Sean 363 00:19:36,000 --> 00:19:39,000 y con nuestras demostraciones de la búsqueda de números. 364 00:19:39,000 --> 00:19:42,000 Se trata de tomar un problema y dividiéndolo una y otra vez. 365 00:19:42,000 --> 00:19:44,000 >> En otras palabras, hay una manera de traducir ahora 366 00:19:44,000 --> 00:19:47,000 esta construcción del mundo real, esta construcción de alto nivel 367 00:19:47,000 --> 00:19:51,000 de dividir y conquistar y hacer algo una y otra vez 368 00:19:51,000 --> 00:19:56,000 en el código, así que esto es algo que vamos a ver una vez más con el tiempo. 369 00:19:56,000 --> 00:20:00,000 Ahora, en un aparte, si eres nuevo en la recursividad al menos debe entender ahora 370 00:20:00,000 --> 00:20:02,000 por qué esto es divertido. 371 00:20:02,000 --> 00:20:05,000 Voy a ir a google.com, 372 00:20:05,000 --> 00:20:17,000 y yo voy a buscar algunos consejos y trucos sobre la recursividad, introduzca. 373 00:20:17,000 --> 00:20:21,000 Dile a la persona a tu lado si no estuvieran riendo ahora. 374 00:20:21,000 --> 00:20:23,000 ¿Te refieres a la recursividad? 375 00:20:23,000 --> 00:20:25,000 Quizás quiso decir-ah, ahí vamos. 376 00:20:25,000 --> 00:20:28,000 Bien, ahora que está el resto de todo el mundo. 377 00:20:28,000 --> 00:20:30,000 Un poco huevo de Pascua incrustado en algún lugar en Google. 378 00:20:30,000 --> 00:20:33,000 Como acotación al margen, uno de los enlaces que ponemos en la página web del curso 379 00:20:33,000 --> 00:20:36,000 de hoy es precisamente esta red de varios algoritmos de ordenación, 380 00:20:36,000 --> 00:20:39,000 algunas de las cuales vimos la semana pasada, pero lo bueno de esta visualización 381 00:20:39,000 --> 00:20:43,000 a medida que tratan de envolver su mente alrededor de varias cosas relacionadas con algoritmos 382 00:20:43,000 --> 00:20:46,000 Sabía que puede muy fácilmente ahora comenzar con diferentes tipos de entradas. 383 00:20:46,000 --> 00:20:50,000 Las entradas de todos invertida, sobre todo las entradas ordenadas, las entradas al azar y así sucesivamente. 384 00:20:50,000 --> 00:20:53,000 Al intentar, una vez más, distinguir estas cosas en tu mente 385 00:20:53,000 --> 00:20:57,000 darse cuenta de que esta dirección URL en la página web de la asignatura en la página de Conferencias 386 00:20:57,000 --> 00:21:00,000 podría ayudarle a razonar a través de algunos de ellos. 387 00:21:00,000 --> 00:21:05,000 >> Hoy finalmente podemos resolver este problema desde hace un tiempo, 388 00:21:05,000 --> 00:21:08,000 que era que esta función de intercambio no funcionó, 389 00:21:08,000 --> 00:21:12,000 y cuál fue el problema fundamental con este canje función, 390 00:21:12,000 --> 00:21:15,000 cuyo objetivo fue, de nuevo, para intercambiar un valor aquí y aquí 391 00:21:15,000 --> 00:21:17,000 de tal manera que esto sucede? 392 00:21:17,000 --> 00:21:20,000 Esto en realidad no funciona. ¿Por qué? 393 00:21:20,000 --> 00:21:22,000 Si. 394 00:21:22,000 --> 00:21:28,000 [Inaudible-alumno] 395 00:21:28,000 --> 00:21:31,000 Exactamente, la explicación de este bugginess 396 00:21:31,000 --> 00:21:34,000 simplemente porque cuando se llama a funciones en C 397 00:21:34,000 --> 00:21:38,000 y esas funciones tomar argumentos, como ayb aquí, 398 00:21:38,000 --> 00:21:42,000 está de paso en las copias de cualquier valor que estamos ofreciendo a esa función. 399 00:21:42,000 --> 00:21:46,000 Usted no está proporcionando los valores originales ellos mismos, 400 00:21:46,000 --> 00:21:49,000 así que vimos esto en el contexto de buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, que parecía un poco algo como esto. 402 00:21:52,000 --> 00:21:57,000 >> Recordemos que teníamos x e y inicializa a 1 y 2, respectivamente. 403 00:21:57,000 --> 00:21:59,000 A continuación, imprime lo que eran. 404 00:21:59,000 --> 00:22:03,000 Entonces me dijo que yo los estaba llamando intercambio swap de x, y. 405 00:22:03,000 --> 00:22:06,000 Pero el problema era que el intercambio de trabajo, 406 00:22:06,000 --> 00:22:10,000 pero sólo en el ámbito de aplicación de la propia permuta funcionar. 407 00:22:10,000 --> 00:22:13,000 Tan pronto como llegamos a la línea 40 los valores intercambiados 408 00:22:13,000 --> 00:22:16,000 fueron desechados, y por lo tanto nada 409 00:22:16,000 --> 00:22:21,000 en la función original fue cambiado realmente en absoluto, 410 00:22:21,000 --> 00:22:26,000 entonces si le parece entonces que el aspecto que tiene en términos de nuestra memoria 411 00:22:26,000 --> 00:22:29,000 si esta parte izquierda de la placa representa- 412 00:22:29,000 --> 00:22:33,000 y voy a hacer mi mejor esfuerzo para que todos la vean esto: si esta parte izquierda de la tabla 413 00:22:33,000 --> 00:22:37,000 representa, por ejemplo, la memoria RAM, y la pila se va a crecer en esta forma, 414 00:22:37,000 --> 00:22:43,000 y llamamos a una función como principal y principal tiene 2 variables locales, x e y, 415 00:22:43,000 --> 00:22:48,000 vamos a describir a aquellos que x aquí, y vamos a describirlos como y aquí, 416 00:22:48,000 --> 00:22:55,000 y vamos a poner en los valores 1 y 2, por lo que esta aquí es principal, 417 00:22:55,000 --> 00:22:58,000 y cuando se llama a la función principal de intercambio del sistema operativo 418 00:22:58,000 --> 00:23:02,000 da la función de intercambio en su propia franja de memoria en la pila, 419 00:23:02,000 --> 00:23:04,000 su propio marco en la pila, por así decirlo. 420 00:23:04,000 --> 00:23:08,000 También asigna 32 bits para estos enteros. 421 00:23:08,000 --> 00:23:11,000 Le pasa a llamarlos a y b, pero eso es totalmente arbitraria. 422 00:23:11,000 --> 00:23:13,000 Podría haber llamado lo que quiera, pero lo que sucede cuando principal 423 00:23:13,000 --> 00:23:19,000 intercambio de llamadas es que toma este 1, pone una copia allí, pone una copia allí. 424 00:23:19,000 --> 00:23:23,000 >> Hay una otra variable local en swap, sin embargo, llama qué? Tmp. >> 425 00:23:23,000 --> 00:23:27,000 Tmp, así que me doy otros 32 bits de aquí, 426 00:23:27,000 --> 00:23:29,000 ¿y qué hago en esta función? 427 00:23:29,000 --> 00:23:34,000 Dije int tmp recibe una, por lo que tiene 1, así que lo hice la última vez que jugó con este ejemplo. 428 00:23:34,000 --> 00:23:39,000 A continuación, se pone a b, entonces b es 2, por lo que ahora esto se convierte en 2, 429 00:23:39,000 --> 00:23:42,000 y ahora llega b temp, temp así es 1, 430 00:23:42,000 --> 00:23:44,000 por lo que ahora se convierte en este b. 431 00:23:44,000 --> 00:23:46,000 Eso es genial. Funcionó. 432 00:23:46,000 --> 00:23:49,000 Pero tan pronto como la función devuelve 433 00:23:49,000 --> 00:23:52,000 de intercambio de memoria de forma eficaz desaparece para que pueda ser reutilizado 434 00:23:52,000 --> 00:23:58,000 por alguna otra función en el futuro, y principal es obviamente completamente inalterado. 435 00:23:58,000 --> 00:24:00,000 Necesitamos una manera de resolver este problema fundamental, 436 00:24:00,000 --> 00:24:03,000 y hoy por fin voy a tener una manera de hacer esto mediante el cual 437 00:24:03,000 --> 00:24:06,000 podemos introducir algo que se llama un puntero. 438 00:24:06,000 --> 00:24:09,000 Resulta que podemos resolver este problema 439 00:24:09,000 --> 00:24:12,000 no pasando en copias de x e y 440 00:24:12,000 --> 00:24:18,000 pero no por lo que pasa en, ¿crees que, a la función de intercambio? 441 00:24:18,000 --> 00:24:20,000 Sí, ¿qué pasa con la dirección? 442 00:24:20,000 --> 00:24:22,000 Realmente no hemos hablado acerca de las direcciones en mucho detalle, 443 00:24:22,000 --> 00:24:25,000 pero si esto pizarra representa la memoria de mi computadora 444 00:24:25,000 --> 00:24:28,000 sin duda podríamos empezar a numerar los bytes de RAM en mi 445 00:24:28,000 --> 00:24:31,000 y decir que este es el byte # 1, este es el byte # 2, # 3 byte, 446 00:24:31,000 --> 00:24:35,000 byte # 4, # byte ... 2 millones de dólares si tengo 2 GB de RAM, 447 00:24:35,000 --> 00:24:38,000 por lo que sin duda podría llegar a algún esquema de numeración arbitrario 448 00:24:38,000 --> 00:24:41,000 para todos los bytes individuales en la memoria de mi ordenador. 449 00:24:41,000 --> 00:24:43,000 >> ¿Qué pasa si en lugar cuando llamo intercambio 450 00:24:43,000 --> 00:24:47,000 en lugar de pasar copias de x e y 451 00:24:47,000 --> 00:24:51,000 ¿por qué no en lugar de pasar la dirección de x aquí, 452 00:24:51,000 --> 00:24:55,000 la dirección de y aquí, esencialmente la dirección postal 453 00:24:55,000 --> 00:24:59,000 de x e y porque luego de intercambio, si está informado 454 00:24:59,000 --> 00:25:01,000 de la dirección en la memoria de x e y, 455 00:25:01,000 --> 00:25:04,000 luego de intercambio, si lo entrenó un poco, 456 00:25:04,000 --> 00:25:07,000 que potencialmente podría conducir a esa dirección, por así decirlo, 457 00:25:07,000 --> 00:25:11,000 x, y cambiar el número allí, luego en coche a la dirección de y, 458 00:25:11,000 --> 00:25:16,000 cambiar el número allí, aunque en realidad no obtener copias de él mismo esos valores, 459 00:25:16,000 --> 00:25:19,000 así que, aunque ya hablamos de esto como memoria principal 460 00:25:19,000 --> 00:25:23,000 y este swap como la memoria de los poderosos y la parte peligrosa de C 461 00:25:23,000 --> 00:25:28,000 es que cualquier función puede tocar cualquier parte de la memoria del ordenador, 462 00:25:28,000 --> 00:25:32,000 y esto es de gran alcance en la que se pueden hacer cosas muy elegantes con programas de computadora en C. 463 00:25:32,000 --> 00:25:36,000 Esto es peligroso porque también se puede meter la pata muy fácilmente. 464 00:25:36,000 --> 00:25:39,000 De hecho, una de las formas más comunes para los programas de estos días para ser explotados 465 00:25:39,000 --> 00:25:42,000 todavía no es para un programador para realizar 466 00:25:42,000 --> 00:25:45,000 que él o ella está permitiendo un dato 467 00:25:45,000 --> 00:25:49,000 para ser escrita en una ubicación de memoria que no se pretendía. 468 00:25:49,000 --> 00:25:51,000 >> Por ejemplo, él o ella declara una matriz de tamaño 10 469 00:25:51,000 --> 00:25:56,000 pero, accidentalmente, trata de poner 11 bytes en la matriz de la memoria, 470 00:25:56,000 --> 00:25:59,000 y empiezas a tocar partes de la memoria que ya no son válidos. 471 00:25:59,000 --> 00:26:02,000 Sólo para este contexto, algunos de ustedes sabrán que 472 00:26:02,000 --> 00:26:06,000 software a menudo le pide los números de serie o claves de registro, 473 00:26:06,000 --> 00:26:08,000 Photoshop y Word y programas como este. 474 00:26:08,000 --> 00:26:12,000 Existen grietas, como algunos de ustedes saben, en línea donde usted puede ejecutar un pequeño programa, 475 00:26:12,000 --> 00:26:14,000 y listo, no pedir más de un número de serie. 476 00:26:14,000 --> 00:26:16,000 ¿Cómo es que funciona? 477 00:26:16,000 --> 00:26:21,000 En muchos casos, estas cosas son simplemente encontrar en los ordenadores 478 00:26:21,000 --> 00:26:24,000 segmentos de texto en ceros reales de la computadora y seres 479 00:26:24,000 --> 00:26:28,000 ¿dónde está esa función en la que se solicita el número de serie, 480 00:26:28,000 --> 00:26:31,000 y sobrescribir ese espacio, o mientras el programa se está ejecutando 481 00:26:31,000 --> 00:26:33,000 usted puede averiguar donde la clave se almacena 482 00:26:33,000 --> 00:26:37,000 usando algo llamado un depurador, y se puede agrietar software de esa manera. 483 00:26:37,000 --> 00:26:40,000 Esto no quiere decir que este es nuestro objetivo para el próximo par de días, 484 00:26:40,000 --> 00:26:42,000 pero tiene muy reales ramificaciones. 485 00:26:42,000 --> 00:26:45,000 Que uno le sucede a implicar el robo de software, 486 00:26:45,000 --> 00:26:47,000 pero también hay compromiso de las máquinas enteras. 487 00:26:47,000 --> 00:26:50,000 >> De hecho, cuando estos sitios web día son explotados 488 00:26:50,000 --> 00:26:53,000 y comprometida y los datos se filtraron y contraseñas robadas se 489 00:26:53,000 --> 00:26:58,000 muy a menudo se relaciona con la mala gestión de la memoria, 490 00:26:58,000 --> 00:27:01,000 o, en el caso de bases de datos, falta de anticipación 491 00:27:01,000 --> 00:27:03,000 entrada contradicción, por lo que más en que en las próximas semanas, 492 00:27:03,000 --> 00:27:07,000 pero por ahora sólo un adelanto de la clase de daño que se puede hacer 493 00:27:07,000 --> 00:27:11,000 por no bastante entender cómo funcionan las cosas debajo de la capucha. 494 00:27:11,000 --> 00:27:14,000 Vamos a ir sobre la comprensión de por qué esto está roto 495 00:27:14,000 --> 00:27:17,000 con una herramienta que se hará más y más útil 496 00:27:17,000 --> 00:27:19,000 ya que nuestros programas se vuelven más complejos. 497 00:27:19,000 --> 00:27:21,000 Hasta ahora cuando se ha tenido un error en su programa 498 00:27:21,000 --> 00:27:23,000 ¿cómo ha ido depurando sobre él? 499 00:27:23,000 --> 00:27:25,000 ¿Cuáles han sido tus técnicas hasta el momento, ya sea impartido por el TF 500 00:27:25,000 --> 00:27:27,000 o simplemente autodidacta? 501 00:27:27,000 --> 00:27:29,000 [Estudiante] printf. 502 00:27:29,000 --> 00:27:31,000 Printf, así printf probablemente ha sido su amigo en que si usted quiere ver 503 00:27:31,000 --> 00:27:33,000 lo que está sucediendo dentro de su programa de 504 00:27:33,000 --> 00:27:36,000 usted acaba de poner printf aquí, printf aquí, printf aquí. 505 00:27:36,000 --> 00:27:38,000 A continuación, ejecutarlo, y te dan un montón de cosas en la pantalla 506 00:27:38,000 --> 00:27:43,000 que se puede utilizar para deducir entonces lo que realmente está pasando mal en su programa. 507 00:27:43,000 --> 00:27:45,000 >> Printf tiende a ser algo muy poderoso, 508 00:27:45,000 --> 00:27:47,000 pero es un proceso muy manual. 509 00:27:47,000 --> 00:27:49,000 Tienes que poner un printf aquí, un printf aquí, 510 00:27:49,000 --> 00:27:51,000 y si lo pones dentro de un bucle podría obtener 100 líneas 511 00:27:51,000 --> 00:27:53,000 de salida que usted entonces tiene que tamizar a través. 512 00:27:53,000 --> 00:27:58,000 No es un mecanismo muy fácil de usar o interactivos para los programas de depuración, 513 00:27:58,000 --> 00:28:00,000 pero por suerte existe alternativas. 514 00:28:00,000 --> 00:28:03,000 Hay un programa, por ejemplo, llama GDB, el depurador de GNU, 515 00:28:03,000 --> 00:28:06,000 que es un arcano muy poco en cómo lo usa. 516 00:28:06,000 --> 00:28:08,000 Es un poco complejo, pero, francamente, 517 00:28:08,000 --> 00:28:11,000 esta es una de esas cosas que si usted pone en esta semana y la próxima 518 00:28:11,000 --> 00:28:14,000 la hora extra a entender algo como GDB 519 00:28:14,000 --> 00:28:18,000 que le ahorrará probablemente decenas de horas en el largo plazo, 520 00:28:18,000 --> 00:28:21,000 Así que con eso, te voy a dar un adelanto de cómo funciona esto. 521 00:28:21,000 --> 00:28:23,000 >> Estoy en mi ventana de terminal. 522 00:28:23,000 --> 00:28:26,000 Déjenme seguir adelante y compilar este programa, buggy3. 523 00:28:26,000 --> 00:28:28,000 Ya está actualizado. 524 00:28:28,000 --> 00:28:31,000 Déjame correr tal como lo hicimos hace un tiempo, y de hecho, está rota. 525 00:28:31,000 --> 00:28:34,000 Pero ¿por qué es esto? Tal vez lo arruiné la función de intercambio. 526 00:28:34,000 --> 00:28:37,000 Tal vez es a y b. No estoy muy a moverse correctamente. 527 00:28:37,000 --> 00:28:39,000 Déjame ir adelante y hacerlo. 528 00:28:39,000 --> 00:28:43,000 En lugar de simplemente correr buggy3 déjame en lugar de ejecutar este programa de GDB, 529 00:28:43,000 --> 00:28:48,000 y yo lo voy a decir a ejecutar buggy3, 530 00:28:48,000 --> 00:28:52,000 y voy a incluir un parámetro de línea de comandos,-tui, 531 00:28:52,000 --> 00:28:55,000 y vamos a poner esto en futuros problemas de especificación para recordar. 532 00:28:55,000 --> 00:28:57,000 Y ahora esta interfaz en blanco y negro que apareció, de nuevo, 533 00:28:57,000 --> 00:28:59,000 Es un poco abrumador al principio, porque hay toda esta 534 00:28:59,000 --> 00:29:02,000 información sobre la garantía aquí, pero al menos hay algo familiar. 535 00:29:02,000 --> 00:29:04,000 En la parte superior de la ventana es mi código actual, 536 00:29:04,000 --> 00:29:08,000 y si me desplazo hasta aquí permítanme desplazarse a la parte superior de mi archivo, 537 00:29:08,000 --> 00:29:11,000 y, de hecho, hay buggy3.c y observe en la parte inferior de esta ventana 538 00:29:11,000 --> 00:29:13,000 Tengo este mensaje GDB. 539 00:29:13,000 --> 00:29:16,000 >> Este no es el mismo que mi normal del sistema John Harvard. 540 00:29:16,000 --> 00:29:19,000 Este es un mensaje que va a permitir que controle GDB. 541 00:29:19,000 --> 00:29:21,000 GDB es un depurador. 542 00:29:21,000 --> 00:29:24,000 Un depurador es un programa que le permite caminar a través de 543 00:29:24,000 --> 00:29:27,000 ejecución de su programa de línea a línea por línea, 544 00:29:27,000 --> 00:29:30,000 en el camino haciendo lo que quieras con el programa, 545 00:29:30,000 --> 00:29:33,000 incluso llamar a funciones, o en busca, sobre todo, 546 00:29:33,000 --> 00:29:35,000 en valores de las variables de diversos. 547 00:29:35,000 --> 00:29:37,000 Vamos a seguir adelante y hacer esto. 548 00:29:37,000 --> 00:29:40,000 Voy a seguir adelante y escribir en carrera en el símbolo del BGF, 549 00:29:40,000 --> 00:29:43,000 por lo notará en la parte inferior izquierda de la pantalla que he escrito correr, 550 00:29:43,000 --> 00:29:45,000 y he pulsa enter, y qué hizo eso? 551 00:29:45,000 --> 00:29:50,000 Es, literalmente, corriendo mi programa, pero que en realidad no veo mucho ir de aquí 552 00:29:50,000 --> 00:29:55,000 porque yo no lo he dicho el depurador 553 00:29:55,000 --> 00:29:57,000 para hacer una pausa en un momento particular en el tiempo. 554 00:29:57,000 --> 00:29:59,000 Simplemente escribiendo run ejecuta el programa. 555 00:29:59,000 --> 00:30:01,000 Yo en realidad no veo nada. No lo puedo manipular. 556 00:30:01,000 --> 00:30:03,000 >> En su lugar vamos a hacer esto. 557 00:30:03,000 --> 00:30:08,000 En este mensaje GDB déjame en vez escriba break, entrar. 558 00:30:08,000 --> 00:30:10,000 Eso no es lo que quise escribir. 559 00:30:10,000 --> 00:30:13,000 En lugar de eso escribir ruptura principal. 560 00:30:13,000 --> 00:30:15,000 En otras palabras, quiero hablar de algo que se llama un punto de interrupción, 561 00:30:15,000 --> 00:30:18,000 que se nombra conveniente porque va a romper o hacer una pausa 562 00:30:18,000 --> 00:30:21,000 ejecución de su programa en ese lugar en particular. 563 00:30:21,000 --> 00:30:23,000 Principal es el nombre de mi función. 564 00:30:23,000 --> 00:30:25,000 Tenga en cuenta que GDB es muy inteligente. 565 00:30:25,000 --> 00:30:28,000 Se descubrió que la principal pasa a comenzar aproximadamente en la línea 18 566 00:30:28,000 --> 00:30:32,000 de buggy3.c y observe aquí, en la parte superior izquierda 567 00:30:32,000 --> 00:30:34,000 + b es justo al lado de la línea 18. 568 00:30:34,000 --> 00:30:38,000 Eso me recuerda que he puesto un punto de interrupción en la línea 18. 569 00:30:38,000 --> 00:30:42,000 Esta vez, cuando yo escriba run, me voy a correr mi programa 570 00:30:42,000 --> 00:30:45,000 hasta que llegue a ese punto de ruptura, 571 00:30:45,000 --> 00:30:48,000 por lo que el programa hará una pausa para mí en la línea 18. 572 00:30:48,000 --> 00:30:50,000 Aquí vamos, corre. 573 00:30:50,000 --> 00:30:53,000 Nada parece haber pasado, pero dejó aviso en la parte inferior 574 00:30:53,000 --> 00:30:58,000 programa de inicio, buggy3, 1 en punto de interrupción en la línea principal buggy3.c 18. 575 00:30:58,000 --> 00:31:00,000 ¿Qué puedo hacer ahora? 576 00:31:00,000 --> 00:31:03,000 >> Note que puede empezar a escribir cosas como la impresión, 577 00:31:03,000 --> 00:31:08,000 No printf, print x, y eso sí que es raro. 578 00:31:08,000 --> 00:31:11,000 Los $ 1 es sólo una curiosidad, como veremos 579 00:31:11,000 --> 00:31:14,000 cada vez que imprima algo que se obtiene un nuevo valor $. 580 00:31:14,000 --> 00:31:18,000 Eso es lo que se puede hacer referencia a los valores anteriores por si acaso, 581 00:31:18,000 --> 00:31:21,000 pero por ahora lo que me está diciendo impresión es que el valor de x en este punto de la historia 582 00:31:21,000 --> 00:31:26,000 es aparentemente 134514032. 583 00:31:26,000 --> 00:31:29,000 ¿Qué? ¿De dónde vino que incluso viene? 584 00:31:29,000 --> 00:31:31,000 [Inaudible-alumno] 585 00:31:31,000 --> 00:31:34,000 De hecho, esto es lo que vamos a llamar a un valor basura, y nosotros no hemos hablado de esto, sin embargo, 586 00:31:34,000 --> 00:31:37,000 pero la razón por la que inicializar las variables 587 00:31:37,000 --> 00:31:40,000 obviamente para que tengan algún valor que desea que tengan. 588 00:31:40,000 --> 00:31:44,000 Pero el problema es recordar que usted puede declarar variables 589 00:31:44,000 --> 00:31:46,000 como lo hice hace un momento en mi ejemplo sigma 590 00:31:46,000 --> 00:31:48,000 sin llegar a dar un valor. 591 00:31:48,000 --> 00:31:50,000 Recordemos lo que hice aquí en sigma. 592 00:31:50,000 --> 00:31:52,000 Declaré n, pero ¿qué valor tenía lo doy? 593 00:31:52,000 --> 00:31:56,000 Ninguna, porque sabía que en las próximas líneas 594 00:31:56,000 --> 00:31:59,000 GetInt se ocuparía del problema de poner un valor dentro de n. 595 00:31:59,000 --> 00:32:02,000 >> Pero en este punto de la historia de la línea 11 596 00:32:02,000 --> 00:32:05,000 y la línea 12 y la línea 13 y la línea 14 597 00:32:05,000 --> 00:32:08,000 a lo largo de esas líneas de varios cuál es el valor de n? 598 00:32:08,000 --> 00:32:10,000 En C simplemente no lo sé. 599 00:32:10,000 --> 00:32:14,000 Por lo general es un valor basura, un número completamente al azar 600 00:32:14,000 --> 00:32:17,000 que sobra esencialmente de alguna función anterior 601 00:32:17,000 --> 00:32:21,000 después de haber sido ejecutado, así como su programa se ejecuta 602 00:32:21,000 --> 00:32:24,000 Recordemos que la función tiene función, la función, la función. 603 00:32:24,000 --> 00:32:27,000 Todos estos marcos de conseguir poner en la memoria y luego los devuelven las funciones, 604 00:32:27,000 --> 00:32:31,000 y al igual que sugerí con la goma de borrar su memoria es eventualmente reutilizados. 605 00:32:31,000 --> 00:32:37,000 Bueno, lo que pasa es que esta variable x en este programa 606 00:32:37,000 --> 00:32:41,000 parece haber contenido algún valor como basura 134514032 607 00:32:41,000 --> 00:32:44,000 de alguna función anterior, no uno que yo escribí. 608 00:32:44,000 --> 00:32:47,000 Podría ser algo que viene efectivamente con el sistema operativo, 609 00:32:47,000 --> 00:32:49,000 alguna función debajo de la capucha. 610 00:32:49,000 --> 00:32:52,000 >> Está bien, está bien, pero ahora vamos a pasar a la siguiente línea. 611 00:32:52,000 --> 00:32:55,000 Si escribo "siguiente" en mi GDB rápido y llegué a entrar, 612 00:32:55,000 --> 00:32:58,000 cuenta de que el selector se desplaza hasta la línea 19, 613 00:32:58,000 --> 00:33:01,000 sino la consecuencia lógica es que la línea 18 614 00:33:01,000 --> 00:33:06,000 ha terminado de ejecutarse, por lo que si vuelvo a escribir "print x" 615 00:33:06,000 --> 00:33:10,000 Ahora deberá ver 1, y de hecho, así es. 616 00:33:10,000 --> 00:33:14,000 Una vez más, las cosas $ es una forma de GDB le recuerda 617 00:33:14,000 --> 00:33:17,000 lo que la historia de las impresiones son que usted ha hecho. 618 00:33:17,000 --> 00:33:21,000 Ahora voy a seguir adelante e imprimir y, de hecho, y es un valor loco también, 619 00:33:21,000 --> 00:33:24,000 pero no es gran cosa ya que en la línea 19 estamos a punto de ceder 620 00:33:24,000 --> 00:33:27,000 el valor 2, así que voy a escribir "Siguiente" de nuevo. 621 00:33:27,000 --> 00:33:29,000 Y ahora estamos en la línea printf. 622 00:33:29,000 --> 00:33:31,000 Permítanme hacer x impresión. 623 00:33:31,000 --> 00:33:34,000 Déjame hacer y de impresión. Francamente, estoy un poco cansado de la impresión de este. 624 00:33:34,000 --> 00:33:38,000 Déjame en vez escribir "x pantalla" y "y la pantalla", 625 00:33:38,000 --> 00:33:41,000 y ahora cada vez que escriba un comando en el futuro 626 00:33:41,000 --> 00:33:45,000 Voy a recordar lo que es x e y, lo que es x e y, lo que es x e y. 627 00:33:45,000 --> 00:33:48,000 >> También puedo, en un aparte, escriba "locales de información." 628 00:33:48,000 --> 00:33:50,000 Info es una orden especial. 629 00:33:50,000 --> 00:33:52,000 Los locales significa que me muestra las variables locales. 630 00:33:52,000 --> 00:33:55,000 Sólo en caso de olvido o se trata de una función loco y complicado 631 00:33:55,000 --> 00:33:57,000 que yo o alguien más escribió lugareños información le dirá 632 00:33:57,000 --> 00:34:00,000 ¿cuáles son las variables locales dentro de esta función local 633 00:34:00,000 --> 00:34:03,000 que es posible que se preocupan por si quieres curiosear. 634 00:34:03,000 --> 00:34:07,000 Ahora, printf está a punto de ejecutar, así que voy a seguir adelante y sólo tienes que escribir "siguiente". 635 00:34:07,000 --> 00:34:10,000 Porque estamos en este entorno no estamos realmente viendo 636 00:34:10,000 --> 00:34:14,000 ejecutar hasta aquí, pero note que está haciendo un poco destrozado aquí. 637 00:34:14,000 --> 00:34:17,000 Pero note que está anulando la pantalla hay, 638 00:34:17,000 --> 00:34:21,000 así que no es un programa perfecto aquí, pero eso está bien, porque siempre puedo hurgar 639 00:34:21,000 --> 00:34:23,000 mediante impresión si quiero. 640 00:34:23,000 --> 00:34:26,000 >> Déjame escribir al lado de nuevo, y ahora viene la parte interesante. 641 00:34:26,000 --> 00:34:29,000 En este punto de la historia y es 2, y x es 1, 642 00:34:29,000 --> 00:34:32,000 como se sugiere aquí, y de nuevo, 643 00:34:32,000 --> 00:34:35,000 la razón de esto es automáticamente mostrando ahora es porque he utilizado el comando 644 00:34:35,000 --> 00:34:40,000 display x e y visualización, por lo que el momento de tipo I siguiente 645 00:34:40,000 --> 00:34:43,000 en teoría x e y deben convertirse intercambian. 646 00:34:43,000 --> 00:34:45,000 Ahora, ya sabemos que no va a ser el caso, 647 00:34:45,000 --> 00:34:49,000 pero ya veremos dentro de un momento cómo podemos profundizar más para entender por qué eso es cierto. 648 00:34:49,000 --> 00:34:54,000 A continuación, y por desgracia, y es todavía 2 yx sigue siendo 1, y puedo confirmar lo mismo. 649 00:34:54,000 --> 00:34:56,000 Imprimir x, imprimir y. 650 00:34:56,000 --> 00:34:59,000 De hecho, ningún intercambio que realmente ha sucedido, así que vamos a empezar esta vez. 651 00:34:59,000 --> 00:35:01,000 Claramente intercambio está roto. 652 00:35:01,000 --> 00:35:04,000 En lugar de eso escribe "Ejecutar" de nuevo. 653 00:35:04,000 --> 00:35:07,000 Permítanme decir que sí, quiero que reiniciar desde el principio, entrar. 654 00:35:07,000 --> 00:35:09,000 >> Ahora estoy de vuelta para arriba en la línea 18. 655 00:35:09,000 --> 00:35:11,000 Ahora note x e y son valores de basura de nuevo. 656 00:35:11,000 --> 00:35:15,000 Siguiente, siguiente, siguiente, siguiente. 657 00:35:15,000 --> 00:35:17,000 Si me aburro yo también puedo simplemente escriba n para el próximo. 658 00:35:17,000 --> 00:35:21,000 Se puede abreviar con la secuencia más corta posible de caracteres. 659 00:35:21,000 --> 00:35:23,000 Intercambiar está roto. 660 00:35:23,000 --> 00:35:25,000 Vamos a bucear, así que en vez de teclear siguiente, 661 00:35:25,000 --> 00:35:30,000 ahora voy a escribir lo que paso Estoy caminando dentro de esta función 662 00:35:30,000 --> 00:35:33,000 para que yo pueda caminar a través de él, así que me golpeó paso y luego entra. 663 00:35:33,000 --> 00:35:37,000 Tenga en cuenta que los saltos que destacan más abajo en mi programa a la línea 36. 664 00:35:37,000 --> 00:35:39,000 Ahora, ¿cuáles son las variables locales? 665 00:35:39,000 --> 00:35:41,000 Información de los locales. 666 00:35:41,000 --> 00:35:43,000 No hay nada todavía porque no hemos llegado a esa línea, 667 00:35:43,000 --> 00:35:47,000 así que vamos a seguir adelante y decir "siguiente". 668 00:35:47,000 --> 00:35:50,000 Ahora parece que tenemos tmp tmp impresión. 669 00:35:50,000 --> 00:35:52,000 Valor basura, ¿no? Creo que sí. 670 00:35:52,000 --> 00:35:55,000 ¿Qué tal una impresión, impresión b, 1 y 2? 671 00:35:55,000 --> 00:35:58,000 En un momento, en cuanto me escriba de nuevo al lado 672 00:35:58,000 --> 00:36:02,000 tmp va a tener un valor de 1, con suerte, 673 00:36:02,000 --> 00:36:05,000 tmp porque va a ser asignado el valor de a. 674 00:36:05,000 --> 00:36:08,000 >> Ahora vamos a hacer imprimir a, b, impresión, 675 00:36:08,000 --> 00:36:11,000 pero ahora imprimir tmp, y es de hecho 1. 676 00:36:11,000 --> 00:36:14,000 Déjame hacer a continuación. Déjame hacer a continuación. 677 00:36:14,000 --> 00:36:16,000 He terminado la función de intercambio. 678 00:36:16,000 --> 00:36:19,000 Estoy aún dentro de la misma en la línea 40, así que me imprima una, 679 00:36:19,000 --> 00:36:22,000 print b, y no me importa lo que tmp es. 680 00:36:22,000 --> 00:36:27,000 Parece intercambio es correcto cuando se trata de intercambio de a y b. 681 00:36:27,000 --> 00:36:31,000 Pero si ahora introducido a continuación, salto de nuevo a la línea 25, 682 00:36:31,000 --> 00:36:34,000 y por supuesto, si escribo en x e y de impresión 683 00:36:34,000 --> 00:36:38,000 siguen siendo sin cambios, por lo que no han solucionado el problema. 684 00:36:38,000 --> 00:36:41,000 Sin embargo, el diagnóstico ahora tal vez con este programa GDB 685 00:36:41,000 --> 00:36:44,000 hemos conseguido al menos un paso más cerca de entender 686 00:36:44,000 --> 00:36:47,000 lo que va mal sin necesidad de basura nuestro código por poner un printf aquí, 687 00:36:47,000 --> 00:36:50,000 printf aquí, printf aquí y luego se ejecuta una y otra vez 688 00:36:50,000 --> 00:36:52,000 tratando de averiguar lo que va mal. 689 00:36:52,000 --> 00:36:55,000 >> Voy a seguir adelante y dejar fuera de este conjunto con dejar de fumar. 690 00:36:55,000 --> 00:36:57,000 Esto va a decir a continuación, "Salir de todos modos?" Sí. 691 00:36:57,000 --> 00:37:00,000 Ahora estoy de vuelta en mi sistema normal, y he terminado con GDB. 692 00:37:00,000 --> 00:37:03,000 Como acotación al margen, no es necesario utilizar esta bandera-tui. 693 00:37:03,000 --> 00:37:07,000 De hecho, si lo omite obtener esencialmente la mitad inferior de la pantalla. 694 00:37:07,000 --> 00:37:11,000 Si a continuación, escriba ruptura principal y ejecute 695 00:37:11,000 --> 00:37:15,000 Todavía puedo ejecutar mi programa, pero lo que hará es más textual 696 00:37:15,000 --> 00:37:18,000 sólo me muestra la línea actual a la vez. 697 00:37:18,000 --> 00:37:21,000 El tui-, la interfaz de usuario textual, 698 00:37:21,000 --> 00:37:25,000 sólo le muestra más del programa a la vez, que es probablemente un poco conceptualmente más fácil. 699 00:37:25,000 --> 00:37:27,000 Pero, en realidad, sólo se puede hacer siguiente, siguiente, siguiente, 700 00:37:27,000 --> 00:37:30,000 y voy a ver una línea a la vez, y si realmente quieres ver lo que está pasando 701 00:37:30,000 --> 00:37:35,000 Me puede escribir la lista y ver un montón de líneas vecinas. 702 00:37:35,000 --> 00:37:39,000 >> Hay un video que le hemos pedido que usted mira para boletines de problemas 3 703 00:37:39,000 --> 00:37:43,000 en la que Nate se tratan algunas de las complejidades de GDB, 704 00:37:43,000 --> 00:37:46,000 y esta es una de esas cosas, de verdad, donde un porcentaje no trivial de que 705 00:37:46,000 --> 00:37:49,000 nunca tocará GDB, y eso será algo malo 706 00:37:49,000 --> 00:37:53,000 porque, literalmente, usted terminará gastando más tiempo a finales de este semestre 707 00:37:53,000 --> 00:37:56,000 persiguiendo a los bichos entonces usted tendría si usted pone en esa media hora / hora 708 00:37:56,000 --> 00:38:00,000 esta semana y el aprendizaje junto a sentirse cómodo con GDB. 709 00:38:00,000 --> 00:38:02,000 Printf era su amigo. 710 00:38:02,000 --> 00:38:05,000 GDB ahora debe ser su amigo. 711 00:38:05,000 --> 00:38:08,000 >> ¿Tiene preguntas sobre GDB? 712 00:38:08,000 --> 00:38:12,000 Y aquí está una lista rápida de algunos de los comandos más poderosos y útiles. 713 00:38:12,000 --> 00:38:15,000 Si. >> ¿Puede imprimir una cadena? 714 00:38:15,000 --> 00:38:17,000 ¿Puede imprimir una cadena? Por supuesto. 715 00:38:17,000 --> 00:38:19,000 No tiene por qué ser sólo números enteros. 716 00:38:19,000 --> 00:38:22,000 Si una variable s es una cadena que sólo tiene que escribir s de impresión. 717 00:38:22,000 --> 00:38:24,000 Se le mostrará lo que es variable de cadena. 718 00:38:24,000 --> 00:38:26,000 [Inaudible-alumno] 719 00:38:26,000 --> 00:38:28,000 Se le dará la dirección y la propia cadena. 720 00:38:28,000 --> 00:38:32,000 Se mostrará a los dos. 721 00:38:32,000 --> 00:38:34,000 Y una última cosa, sólo porque se trata de un buen saber demasiado. 722 00:38:34,000 --> 00:38:37,000 Backtrace y el marco, déjame sumergirse en esta última vez, 723 00:38:37,000 --> 00:38:39,000 mismo programa con GDB. 724 00:38:39,000 --> 00:38:44,000 Déjenme seguir adelante y ejecutar la versión de la interfaz de usuario textual, 725 00:38:44,000 --> 00:38:46,000 romper principal. 726 00:38:46,000 --> 00:38:49,000 Déjenme seguir adelante y correr de nuevo. Aquí estoy. 727 00:38:49,000 --> 00:38:55,000 Ahora voy a ir a siguiente, siguiente, siguiente, siguiente, siguiente, paso, entrar. 728 00:38:55,000 --> 00:39:00,000 >> Y ahora supongo que ahora estoy en intercambio deliberadamente, pero yo soy como "Maldita sea, ¿cuál era el valor de x?" 729 00:39:00,000 --> 00:39:02,000 No puedo hacer x más. 730 00:39:02,000 --> 00:39:05,000 No puedo hacerlo y porque no están en su alcance. 731 00:39:05,000 --> 00:39:07,000 No están en su contexto, pero no hay problema. 732 00:39:07,000 --> 00:39:09,000 Puedo escribir backtrace. 733 00:39:09,000 --> 00:39:13,000 Esto me muestra todas las funciones que se han realizado hasta este punto en el tiempo. 734 00:39:13,000 --> 00:39:16,000 Observe que la una en la parte inferior, la principal, se alinea con principal 735 00:39:16,000 --> 00:39:18,000 estar en el fondo de nuestra imagen aquí. 736 00:39:18,000 --> 00:39:22,000 El hecho de que está por encima de canje que se alinee con el canje de estar por encima de ella en la memoria aquí, 737 00:39:22,000 --> 00:39:26,000 y si quiero volver a principal temporalmente lo que puedo decir "marco". 738 00:39:26,000 --> 00:39:30,000 ¿Qué número? Principal es el cuadro n º 1. 739 00:39:30,000 --> 00:39:32,000 Voy a seguir adelante y decir "cuadro 1". 740 00:39:32,000 --> 00:39:36,000 >> Ahora estoy de vuelta en main, y puedo imprimir x, y puedo imprimir y, 741 00:39:36,000 --> 00:39:40,000 pero no puedo imprimir a o b. 742 00:39:40,000 --> 00:39:43,000 Pero puedo si digo: "Bueno, espere un minuto. ¿Dónde estaba el canje?" 743 00:39:43,000 --> 00:39:46,000 Déjenme seguir adelante y decir "0 marco". 744 00:39:46,000 --> 00:39:48,000 Ahora estoy de vuelta donde quiero estar, y en un aparte, 745 00:39:48,000 --> 00:39:52,000 hay otros comandos también, como si realmente estás consiguiendo mecanografiar aburrido siguiente, siguiente, siguiente, siguiente, 746 00:39:52,000 --> 00:39:56,000 por lo general, se puede decir cosas como "el próximo 10", y que pasará por los siguientes 10 líneas. 747 00:39:56,000 --> 00:39:59,000 También puede escribir "continuar" cuando realmente harto de caminar a través de ella. 748 00:39:59,000 --> 00:40:05,000 Continuar se ejecutará el programa sin interrupción hasta que llega a otro punto de interrupción, 749 00:40:05,000 --> 00:40:07,000 ya sea en un bucle o más abajo en su programa. 750 00:40:07,000 --> 00:40:11,000 >> En este caso se continuó hasta el final, y el programa sale normalmente. 751 00:40:11,000 --> 00:40:13,000 Esta es una forma elegante, proceso inferior. 752 00:40:13,000 --> 00:40:16,000 Sólo su programa terminó normalmente. 753 00:40:16,000 --> 00:40:24,000 Más sobre esto en el video y en la depuración de las sesiones por venir. 754 00:40:24,000 --> 00:40:26,000 Eso era mucho. 755 00:40:26,000 --> 00:40:35,000 Vamos a tomar nuestro hijo de 5 minutos de descanso aquí, y vamos a volver con las estructuras y los archivos. 756 00:40:35,000 --> 00:40:38,000 >> Si ha buceado en conjunto de procesadores de esta semana ya 757 00:40:38,000 --> 00:40:41,000 usted sabrá que utilizamos en el código de distribución, 758 00:40:41,000 --> 00:40:45,000 la fuente de código que le proporcionamos a usted como un punto de partida, algunas técnicas nuevas. 759 00:40:45,000 --> 00:40:50,000 En particular, hemos introducido esta nueva palabra clave se llama estructura, la estructura, 760 00:40:50,000 --> 00:40:53,000 de manera que podamos crear variables personalizadas de todo tipo. 761 00:40:53,000 --> 00:40:57,000 También introdujo la noción de archivo del archivo de entrada de E / S y de salida, 762 00:40:57,000 --> 00:41:00,000 y esto es lo que podemos guardar el estado 763 00:41:00,000 --> 00:41:03,000 de su tablero Scramble en un archivo en disco 764 00:41:03,000 --> 00:41:06,000 para que los compañeros docentes y comprendo 765 00:41:06,000 --> 00:41:09,000 lo que está sucediendo dentro de su programa sin tener que jugar de forma manual 766 00:41:09,000 --> 00:41:11,000 decenas de juegos de pelea. 767 00:41:11,000 --> 00:41:13,000 Podemos hacer esto más automatizadamente. 768 00:41:13,000 --> 00:41:18,000 >> Esta idea de una estructura resuelve un problema bastante convincente. 769 00:41:18,000 --> 00:41:21,000 Supongamos que queremos implementar algún programa 770 00:41:21,000 --> 00:41:25,000 que de alguna manera hace un seguimiento de la información sobre los estudiantes, 771 00:41:25,000 --> 00:41:28,000 y los estudiantes podrían tener, por ejemplo, una identificación, un nombre 772 00:41:28,000 --> 00:41:31,000 y una casa en un lugar como Harvard, así que estos son tres piezas de información 773 00:41:31,000 --> 00:41:34,000 queremos mantener a su alrededor, así que déjame seguir adelante y empezar a escribir un pequeño programa aquí, 774 00:41:34,000 --> 00:41:38,000 incluir stdio.h. 775 00:41:38,000 --> 00:41:42,000 Déjame hacer incluir cs50.h. 776 00:41:42,000 --> 00:41:44,000 Y luego empezar mi función principal. 777 00:41:44,000 --> 00:41:46,000 No me molestaré con los argumentos de línea de comandos, 778 00:41:46,000 --> 00:41:49,000 y aquí quiero tener un estudiante, así que voy a decir 779 00:41:49,000 --> 00:41:54,000 un estudiante tiene un nombre, así que voy a decir "nombre de cadena." 780 00:41:54,000 --> 00:41:59,000 Entonces yo voy a decir un estudiante también tiene un ID, id int así, 781 00:41:59,000 --> 00:42:03,000 y un estudiante tiene una casa, así que también voy a decir "casa de cuerda". 782 00:42:03,000 --> 00:42:06,000 Entonces voy a pedir este un poco más limpia de esta manera. 783 00:42:06,000 --> 00:42:11,000 Bien, ahora tengo 3 variables con las que representan a un estudiante, por lo que "un estudiante". 784 00:42:11,000 --> 00:42:15,000 >> Y ahora quiero llenar estos valores, así que voy a seguir adelante y decir algo como 785 00:42:15,000 --> 00:42:18,000 "Id = 123". 786 00:42:18,000 --> 00:42:21,000 Nombre se va a poner a David. 787 00:42:21,000 --> 00:42:24,000 Digamos que la casa se va a poner Mather, 788 00:42:24,000 --> 00:42:31,000 y luego me voy a hacer algo arbitrariamente como printf ("% s, 789 00:42:31,000 --> 00:42:37,000 cuyo identificador es% d, vive en% s. 790 00:42:37,000 --> 00:42:41,000 Y ahora, ¿qué es lo que quiero conectar aquí, una después de la otra? 791 00:42:41,000 --> 00:42:47,000 Nombre, id, casa, devuelve 0. 792 00:42:47,000 --> 00:42:50,000 Bueno, a menos que metí la pata en alguna parte aquí 793 00:42:50,000 --> 00:42:54,000 Creo que tenemos un programa muy bueno que almacena un estudiante. 794 00:42:54,000 --> 00:42:57,000 Por supuesto, esto no es tan interesante. ¿Y si quiero tener 2 estudiantes? 795 00:42:57,000 --> 00:42:59,000 Eso no es gran cosa. Puedo soportar 2 personas. 796 00:42:59,000 --> 00:43:03,000 Déjenme seguir adelante y poner de relieve este y bajar aquí, 797 00:43:03,000 --> 00:43:09,000 y lo que puedo decir "id = 456" para alguien como Rob que vive en Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Bueno, espera, pero no puedo llamar a estos lo mismo, 799 00:43:12,000 --> 00:43:15,000 y parece que voy a tener que copiar esto, 800 00:43:15,000 --> 00:43:19,000 así que permítanme decir que estos serán variables de David, 801 00:43:19,000 --> 00:43:23,000 y me dejas algunas copias de estos para Rob. 802 00:43:23,000 --> 00:43:27,000 Llamaremos a estos Rob, pero esto no va a funcionar ahora 803 00:43:27,000 --> 00:43:33,000 porque he-espera, vamos a cambiar a id1, nombre1 y house1. 804 00:43:33,000 --> 00:43:35,000 Rob será 2, 2. 805 00:43:35,000 --> 00:43:42,000 Tengo que cambiar esto aquí, aquí, aquí, aquí, aquí, aquí. 806 00:43:42,000 --> 00:43:45,000 Espera, ¿qué pasa con Tommy? Vamos a hacer esto de nuevo. 807 00:43:45,000 --> 00:43:49,000 Obviamente, si usted todavía piensa que esto es una buena manera de hacer esto, no lo es, 808 00:43:49,000 --> 00:43:52,000 así copiar / pegar mal. 809 00:43:52,000 --> 00:43:55,000 Pero hemos resuelto este hace una semana. 810 00:43:55,000 --> 00:43:59,000 >> ¿Cuál era nuestra solución cuando queríamos tener varias instancias del mismo tipo de datos? 811 00:43:59,000 --> 00:44:01,000 [Los estudiantes] Matriz. 812 00:44:01,000 --> 00:44:03,000 Una matriz, así que vamos a tratar de limpiar esto. 813 00:44:03,000 --> 00:44:07,000 Quiero dejar algo de espacio para mí mismo en la parte superior, y déjame hacer esto en lugar aquí. 814 00:44:07,000 --> 00:44:12,000 Llamaremos a estas personas, y en su lugar voy a decir "ids int" 815 00:44:12,000 --> 00:44:14,000 y yo voy a apoyar a 3 de nosotros por ahora. 816 00:44:14,000 --> 00:44:18,000 Voy a decir "nombres de cadena," y voy a apoyar a 3 de nosotros, 817 00:44:18,000 --> 00:44:22,000 y luego voy a decir "casas de cuerda", y yo voy a apoyar a tres de nosotros. 818 00:44:22,000 --> 00:44:26,000 Ahora aquí en lugar de David obtener sus propias variables locales 819 00:44:26,000 --> 00:44:28,000 podemos deshacernos de ellos. 820 00:44:28,000 --> 00:44:30,000 Eso se siente bien que estamos limpiando esto. 821 00:44:30,000 --> 00:44:35,000 Entonces puedo decir que David va a ser [0] y nombres [0] 822 00:44:35,000 --> 00:44:38,000 y casas [0]. 823 00:44:38,000 --> 00:44:41,000 Y luego tenemos a Rob similar puede ahorrar en esto. 824 00:44:41,000 --> 00:44:46,000 Vamos a poner esto aquí, así que va a ser arbitrariamente ids [1]. 825 00:44:46,000 --> 00:44:50,000 Él va a ser nombres [1], 826 00:44:50,000 --> 00:44:53,000 y luego, por último, las casas [1]. 827 00:44:53,000 --> 00:44:57,000 >> Todavía un poco tedioso, y ahora tengo que resolver esto, 828 00:44:57,000 --> 00:45:03,000 así que vamos a decir "nombres [0], id [0], casas [0], 829 00:45:03,000 --> 00:45:06,000 y vamos a pluralizar esto. 830 00:45:06,000 --> 00:45:09,000 Ids, IDS, IDS. 831 00:45:09,000 --> 00:45:12,000 Y de nuevo, lo estoy haciendo, así que de nuevo, ya estoy recurriendo a copiar / pegar de nuevo, 832 00:45:12,000 --> 00:45:14,000 lo más probable es que hay otra solución aquí. 833 00:45:14,000 --> 00:45:18,000 Es probable que pueda limpiar esto más lejos con un bucle o algo así, 834 00:45:18,000 --> 00:45:21,000 Así que en resumen, es un poco mejor, pero todavía se siente como 835 00:45:21,000 --> 00:45:24,000 Estoy recurriendo a copiar / pegar, pero incluso esto, sostengo, 836 00:45:24,000 --> 00:45:27,000 es realmente no es fundamentalmente la solución adecuada porque 837 00:45:27,000 --> 00:45:29,000 ¿Y si en algún momento decidimos que usted sabe qué? 838 00:45:29,000 --> 00:45:32,000 En realidad, deberíamos haber estado almacenando las direcciones de email de David y Rob 839 00:45:32,000 --> 00:45:34,000 y todos los demás en este programa. 840 00:45:34,000 --> 00:45:36,000 También hay que guardar los números de teléfono. 841 00:45:36,000 --> 00:45:39,000 También hay que guardar los números de contacto de emergencia. 842 00:45:39,000 --> 00:45:41,000 Tenemos todas estas piezas de datos que desea almacenar, 843 00:45:41,000 --> 00:45:43,000 Entonces, ¿cómo hace usted para hacer eso? 844 00:45:43,000 --> 00:45:46,000 >> Usted declara otra matriz en la parte superior, a continuación, agregar manualmente 845 00:45:46,000 --> 00:45:49,000 una dirección de correo electrónico [0], la dirección de correo electrónico [1] 846 00:45:49,000 --> 00:45:51,000 para David y Rob y así sucesivamente. 847 00:45:51,000 --> 00:45:56,000 Pero no hay realmente sólo una suposición subyacente en este diseño 848 00:45:56,000 --> 00:45:59,000 que estoy usando el sistema de honor saber que 849 00:45:59,000 --> 00:46:03,000 [I] en cada uno de los varios arrays 850 00:46:03,000 --> 00:46:06,000 que pasa es que se refieren a la misma persona, 851 00:46:06,000 --> 00:46:10,000 por lo que [0] en ids es el número 123, 852 00:46:10,000 --> 00:46:13,000 y voy a asumir que los nombres [0] 853 00:46:13,000 --> 00:46:16,000 es la misma persona el nombre y casas [0] 854 00:46:16,000 --> 00:46:21,000 es la casa de la misma persona y así sucesivamente para todos los arrays diferentes que crean. 855 00:46:21,000 --> 00:46:24,000 Pero nótese que no hay vínculo fundamental 856 00:46:24,000 --> 00:46:27,000 entre los 3 pedazos de información, id, nombre y la casa, 857 00:46:27,000 --> 00:46:32,000 a pesar de que la entidad que estamos tratando de modelar en este programa no es arrays. 858 00:46:32,000 --> 00:46:35,000 Las matrices son precisamente de esta manera programática de hacerlo. 859 00:46:35,000 --> 00:46:38,000 Lo que realmente queremos para modelar en nuestro programa es una persona 860 00:46:38,000 --> 00:46:41,000 al igual que David, una persona como Rob dentro de los cuales 861 00:46:41,000 --> 00:46:46,000 o encapsulación es un nombre y una ID y una casa. 862 00:46:46,000 --> 00:46:49,000 >> ¿Podemos de alguna manera expresar esta idea de la encapsulación 863 00:46:49,000 --> 00:46:52,000 mediante el cual una persona tiene una identidad, un nombre y una casa 864 00:46:52,000 --> 00:46:55,000 y no recurrir a este truco por el que realmente nos 865 00:46:55,000 --> 00:46:58,000 Confiamos en que algo soporte 866 00:46:58,000 --> 00:47:02,000 se refiere a la misma entidad humana en cada uno de estos conjuntos dispares? 867 00:47:02,000 --> 00:47:04,000 De hecho, podemos hacer esto. 868 00:47:04,000 --> 00:47:08,000 Déjame ir más importante por ahora, y me deja crear mi propio tipo de datos 869 00:47:08,000 --> 00:47:10,000 realmente por primera vez. 870 00:47:10,000 --> 00:47:14,000 Se utilizó esta técnica en Scramble, 871 00:47:14,000 --> 00:47:17,000 pero aquí voy a seguir adelante y crear un tipo de datos, 872 00:47:17,000 --> 00:47:19,000 y sabes qué, yo voy a llamarlo estudiante o persona, 873 00:47:19,000 --> 00:47:23,000 y yo voy a usar typedef para definir un tipo. 874 00:47:23,000 --> 00:47:25,000 Voy a decir que se trata de una estructura, 875 00:47:25,000 --> 00:47:29,000 y luego esta estructura va a ser de estudiante tipo, vamos a decir, 876 00:47:29,000 --> 00:47:31,000 aunque es un poco anticuado ahora para mí. 877 00:47:31,000 --> 00:47:33,000 Diremos "int id." 878 00:47:33,000 --> 00:47:35,000 Vamos a decir "nombre de cadena." 879 00:47:35,000 --> 00:47:37,000 Entonces vamos a decir "casa de Cuerdas", 880 00:47:37,000 --> 00:47:40,000 por lo que ahora el final de estas líneas de código 881 00:47:40,000 --> 00:47:45,000 Acabo enseñado sonido metálico que existe 882 00:47:45,000 --> 00:47:49,000 además de un tipo de datos enteros, además de cuerdas, además de dobles, además de carrozas. 883 00:47:49,000 --> 00:47:54,000 >> A partir de este momento en la línea de tiempo de 11, ahora hay un nuevo tipo de datos llamado a los estudiantes, 884 00:47:54,000 --> 00:47:58,000 y ahora puedo declarar una variable de estudiante en cualquier lugar que desee, 885 00:47:58,000 --> 00:48:01,000 así que me baje aquí a la gente. 886 00:48:01,000 --> 00:48:05,000 Ahora puedo deshacerme de esto, y puedo ir de nuevo a David aquí, 887 00:48:05,000 --> 00:48:10,000 y David realmente puedo decir que David, 888 00:48:10,000 --> 00:48:13,000 literalmente podemos nombrar la variable de mí mismo, 889 00:48:13,000 --> 00:48:16,000 va a ser de tipo estudiantil. 890 00:48:16,000 --> 00:48:18,000 Esto puede parecer un poco extraño, pero esto no es tan diferente 891 00:48:18,000 --> 00:48:22,000 de declarar algo como un entero o una cadena o un flotador. 892 00:48:22,000 --> 00:48:24,000 Lo que pasa a llamarse estudiante ahora, 893 00:48:24,000 --> 00:48:28,000 y si quiero poner algo dentro de esta estructura 894 00:48:28,000 --> 00:48:31,000 Ahora tengo que usar una nueva pieza de sintaxis, pero es bastante sencillo, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" en la capital de D, 896 00:48:39,000 --> 00:48:42,000 y david.house = "Mather," 897 00:48:42,000 --> 00:48:46,000 y ahora puedo deshacerme de esta cosa aquí. 898 00:48:46,000 --> 00:48:51,000 Notificación ahora hemos rediseñado nuestro programa en realidad una forma mucho mejor 899 00:48:51,000 --> 00:48:54,000 en que ahora nuestro programa refleja el mundo real. 900 00:48:54,000 --> 00:48:57,000 >> Hay una noción real de una persona o un estudiante. 901 00:48:57,000 --> 00:49:02,000 Aquí tenemos ahora una versión C de una persona o más específicamente un estudiante. 902 00:49:02,000 --> 00:49:05,000 En el interior de esa persona son estas características pertinentes, 903 00:49:05,000 --> 00:49:10,000 ID, nombre y casa, así que Rob se convierte esencialmente la misma cosa aquí abajo, 904 00:49:10,000 --> 00:49:14,000 estudiante para robar, y ahora rob.id = 456, 905 00:49:14,000 --> 00:49:17,000 rob.name = "Rob". 906 00:49:17,000 --> 00:49:20,000 El hecho de que la variable se llama Rob es una especie de sentido. 907 00:49:20,000 --> 00:49:22,000 Podríamos haberlo llamado x o y o z. 908 00:49:22,000 --> 00:49:25,000 Nos llamó a Rob a ser semánticamente consistente, 909 00:49:25,000 --> 00:49:28,000 pero en realidad el nombre es dentro de ese mismo campo, 910 00:49:28,000 --> 00:49:30,000 así que ahora tengo esto. 911 00:49:30,000 --> 00:49:33,000 Esto también no se siente como el mejor diseño que he codificado David. 912 00:49:33,000 --> 00:49:35,000 He codificado Rob. 913 00:49:35,000 --> 00:49:39,000 Y todavía tengo que recurrir a alguna copia y pega cada vez que quiero nuevas variables. 914 00:49:39,000 --> 00:49:43,000 Por otra parte, tengo que darle al parecer cada una de estas variables un nombre, 915 00:49:43,000 --> 00:49:46,000 aunque yo preferiría describir estas variables 916 00:49:46,000 --> 00:49:48,000  estudiantes más genéricamente. 917 00:49:48,000 --> 00:49:52,000 >> Ahora podemos combinar las ideas que han estado trabajando bien para nosotros 918 00:49:52,000 --> 00:49:56,000 y en lugar de decir: "¿Sabes qué, dame unos estudiantes llamados variables, 919 00:49:56,000 --> 00:50:01,000 y vamos a tener que ser de tamaño 3 ", por lo que ahora puede refinar más a fondo, 920 00:50:01,000 --> 00:50:04,000 deshacerse del manual declaró David, 921 00:50:04,000 --> 00:50:08,000 y que en su lugar puede decir algo así como estudiantes [0] aquí. 922 00:50:08,000 --> 00:50:11,000 Entonces puedo decir que los estudiantes [0] aquí, 923 00:50:11,000 --> 00:50:14,000 estudiantes [0] aquí, y así sucesivamente, y me puede dar la vuelta 924 00:50:14,000 --> 00:50:16,000 y limpiar eso para Rob. 925 00:50:16,000 --> 00:50:19,000 Yo también podría ir Y ahora tal vez añadiendo un bucle 926 00:50:19,000 --> 00:50:23,000 y el uso de GetString y getInt para conseguir realmente estos valores por parte del usuario. 927 00:50:23,000 --> 00:50:27,000 Podría seguir acerca de cómo agregar una constante porque esto es generalmente una mala práctica 928 00:50:27,000 --> 00:50:29,000 para codificar un número arbitrario como 3 aquí 929 00:50:29,000 --> 00:50:33,000 y entonces sólo recuerda que debes elegir un máximo de 3 alumnos en el mismo. 930 00:50:33,000 --> 00:50:36,000 Probablemente sería mejor usar # define en la parte superior de mi archivo 931 00:50:36,000 --> 00:50:40,000 y el factor de que fuera, así que en realidad, déjame seguir adelante y generalizar esto. 932 00:50:40,000 --> 00:50:43,000 >> Permítanme abrir un ejemplo que se encuentra entre la actual 933 00:50:43,000 --> 00:50:46,000 ejemplos de antelación, structs1. 934 00:50:46,000 --> 00:50:49,000 Se trata de un programa más completo que utiliza # define aquí 935 00:50:49,000 --> 00:50:51,000 y dice que vamos a tener 3 estudiantes por defecto. 936 00:50:51,000 --> 00:50:54,000 Aquí estoy declarando un valor de clase de los estudiantes, 937 00:50:54,000 --> 00:50:57,000 por lo que un salón de clases de los estudiantes, y ahora estoy usando un bucle 938 00:50:57,000 --> 00:51:00,000 sólo para hacer el código un poco más elegante, popular la clase 939 00:51:00,000 --> 00:51:05,000 con la entrada del usuario, de modo iterar desde i = 0 en hasta estudiantes, que es 3. 940 00:51:05,000 --> 00:51:07,000 Y entonces pedir al usuario en esta versión 941 00:51:07,000 --> 00:51:10,000  ¿cuál es el ID del estudiante, y lo consigue con getInt. 942 00:51:10,000 --> 00:51:13,000 ¿Cuál es el nombre del estudiante, y luego me pongo con GetString. 943 00:51:13,000 --> 00:51:15,000 ¿Qué es la casa del estudiante? Lo entiendo con GetString. 944 00:51:15,000 --> 00:51:19,000 Y luego al final aquí me decidí a cambiar 945 00:51:19,000 --> 00:51:22,000 cómo estoy imprimiendo estos y utilizar realmente un bucle, 946 00:51:22,000 --> 00:51:24,000 ¿Y quién soy yo imprimir? 947 00:51:24,000 --> 00:51:27,000 De acuerdo con el comentario que estoy imprimiendo a nadie en Mather, 948 00:51:27,000 --> 00:51:30,000 y eso es todo lo que Rob y Tommy y así sucesivamente en realidad-de Tommy en Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy y David se imprimiría en este caso, pero, ¿cómo funciona esto? 950 00:51:34,000 --> 00:51:40,000 No hemos visto a esta función antes, pero tomar una conjetura en cuanto a lo que hace. 951 00:51:40,000 --> 00:51:42,000 Compara cadenas. 952 00:51:42,000 --> 00:51:45,000 >> Es un poco no es evidente cómo se compara cadenas porque resulta 953 00:51:45,000 --> 00:51:49,000 si devuelve 0, que significa que las cadenas son iguales. 954 00:51:49,000 --> 00:51:53,000 Si devuelve un -1 significa que uno viene alfabéticamente antes que el otro, 955 00:51:53,000 --> 00:51:57,000 y si devuelve una palabra que significa el otro viene alfabéticamente 956 00:51:57,000 --> 00:52:00,000 antes que el otro, y se puede ver en línea o en la página de manual 957 00:52:00,000 --> 00:52:04,000 para ver exactamente dónde está el que, pero todo esto está haciendo ahora es lo que está diciendo 958 00:52:04,000 --> 00:52:09,000 si el [i]. casa es igual a "Mather" 959 00:52:09,000 --> 00:52:13,000 a continuación, seguir adelante e imprimir esto y lo otro está en Mather. 960 00:52:13,000 --> 00:52:16,000 Pero esto es algo que no hemos visto antes, y volveremos a ello. 961 00:52:16,000 --> 00:52:21,000 Yo no recuerdo haber tenido que hacer esto en cualquiera de mis programas. 962 00:52:21,000 --> 00:52:24,000 Gratuito aparentemente en referencia a la memoria, liberando la memoria, 963 00:52:24,000 --> 00:52:31,000 pero lo que la memoria me estoy liberando al parecer en este bucle en la parte inferior de este programa? 964 00:52:31,000 --> 00:52:34,000 Parece que me estoy liberando a nombre de una persona 965 00:52:34,000 --> 00:52:37,000 y la casa de una persona, pero ¿por qué es eso? 966 00:52:37,000 --> 00:52:41,000 >> Resulta que todas estas semanas que he estado usando GetString 967 00:52:41,000 --> 00:52:45,000 hemos ido introduciendo tipo de un error en cada uno de sus programas. 968 00:52:45,000 --> 00:52:51,000 GetString por diseño asigna memoria para que pueda volver a que una cadena, 969 00:52:51,000 --> 00:52:55,000 como David, o Rob, y entonces puede hacer lo que quieras 970 00:52:55,000 --> 00:52:59,000 con esa cadena en su programa, ya que hemos reservado la memoria para usted. 971 00:52:59,000 --> 00:53:02,000 El problema es que todo este tiempo cada vez que llame GetString 972 00:53:02,000 --> 00:53:05,000 Nosotros, los autores de GetString, han estado solicitando al sistema operativo 973 00:53:05,000 --> 00:53:07,000 para darnos un poco de RAM para esta cadena. 974 00:53:07,000 --> 00:53:09,000 Danos un poco de RAM para esta cadena siguiente. 975 00:53:09,000 --> 00:53:11,000 Danos un poco más RAM para esta cadena siguiente. 976 00:53:11,000 --> 00:53:13,000 Lo que usted, el programador, nunca han estado haciendo 977 00:53:13,000 --> 00:53:15,000 que nos está dando de nuevo la memoria, 978 00:53:15,000 --> 00:53:17,000 por lo que para estas semanas todos los programas que has escrito 979 00:53:17,000 --> 00:53:20,000 han tenido lo que se llama un salto memoria por el que seguir usando 980 00:53:20,000 --> 00:53:24,000 más memoria y más cada vez que llame GetString, y eso está bien. 981 00:53:24,000 --> 00:53:27,000 Nos deliberadamente hacer que en las primeras semanas, porque no es tan interesante 982 00:53:27,000 --> 00:53:29,000 tener que preocuparse de donde la cadena está viniendo. 983 00:53:29,000 --> 00:53:34,000 Todo lo que quiero es la palabra Rob volver cuando el usuario lo tipos pulg 984 00:53:34,000 --> 00:53:38,000 >> Pero avanzar ahora tenemos que comenzar a conseguir más sofisticado acerca de esto. 985 00:53:38,000 --> 00:53:42,000 Cada vez que asignar memoria será mejor que eventualmente devolver. 986 00:53:42,000 --> 00:53:45,000 De lo contrario, en el mundo real en tu Mac o PC que pueda tener de vez en cuando con experiencia 987 00:53:45,000 --> 00:53:50,000 síntomas de que su equipo está a punto de paralizarse eventualmente 988 00:53:50,000 --> 00:53:54,000 o la pelota de playa estúpido giro se acaba de ocupar la computadora de 989 00:53:54,000 --> 00:53:56,000 atención entera y no puedes hacer las cosas. 990 00:53:56,000 --> 00:54:00,000 Eso puede ser explicado por cualquier número de bugs, pero entre los posibles errores 991 00:54:00,000 --> 00:54:03,000 son cosas que se llaman pérdidas de memoria mediante el cual una persona que escribió ese pedazo de software 992 00:54:03,000 --> 00:54:07,000 que está utilizando no recordaba para liberar memoria 993 00:54:07,000 --> 00:54:10,000 que él o ella le pidió al sistema operativo para, 994 00:54:10,000 --> 00:54:14,000 no usar GetString, porque eso es una cosa CS50, pero utilizando funciones similares 995 00:54:14,000 --> 00:54:16,000 que piden que el sistema operativo para la memoria. 996 00:54:16,000 --> 00:54:19,000 Si usted o meten la pata y que en realidad nunca regresar memoria 997 00:54:19,000 --> 00:54:24,000 un síntoma de que puede ser que un programa se ralentiza y retarda y reduce la velocidad 998 00:54:24,000 --> 00:54:26,000 a menos que usted recuerde llamar gratis. 999 00:54:26,000 --> 00:54:28,000 >> Volveremos a cuándo y por qué se llama libre, 1000 00:54:28,000 --> 00:54:32,000 pero vamos a seguir adelante sólo por si acaso y tratar de ejecutar este programa en particular. 1001 00:54:32,000 --> 00:54:35,000 Esto fue llamado structs1, introduzca. 1002 00:54:35,000 --> 00:54:40,000 Déjenme seguir adelante y ejecutar structs1, 123, David Mather, 1003 00:54:40,000 --> 00:54:47,000 456, Rob Kirkland, 789, 1004 00:54:47,000 --> 00:54:50,000 Tommy Mather, y vemos a David en Mather, de Tommy en Mather. 1005 00:54:50,000 --> 00:54:53,000 Esto es sólo una prueba de cordura poco que el programa está funcionando. 1006 00:54:53,000 --> 00:54:56,000 Ahora, por desgracia, este programa es un poco frustrante que 1007 00:54:56,000 --> 00:55:00,000 Hice todo ese trabajo, escribí en 9 diferentes cuerdas, pulsa enter, 1008 00:55:00,000 --> 00:55:04,000 se le dijo que estaba en Mather, pero obviamente yo sabía que estaba en Mather ya porque lo escribió. 1009 00:55:04,000 --> 00:55:07,000 Sería bueno si al menos este programa se parece más a una base de datos 1010 00:55:07,000 --> 00:55:10,000 y que en realidad recuerda lo que he escrito en 1011 00:55:10,000 --> 00:55:12,000 así que nunca más tenga que introducir estos registros estudiantiles. 1012 00:55:12,000 --> 00:55:15,000 Tal vez es como un sistema registrarial. 1013 00:55:15,000 --> 00:55:21,000 >> Podemos hacer esto usando esta técnica conocida como entrada de archivo del archivo de E / S y de salida, 1014 00:55:21,000 --> 00:55:24,000 una manera muy genérica de decir en cualquier momento que desee leer o escribir archivos de los archivos 1015 00:55:24,000 --> 00:55:26,000 usted puede hacer esto con un cierto conjunto de funciones. 1016 00:55:26,000 --> 00:55:29,000 Déjenme seguir adelante y abrir este structs2.c ejemplo, 1017 00:55:29,000 --> 00:55:33,000 que es casi idéntico, pero vamos a ver lo que hace ahora. 1018 00:55:33,000 --> 00:55:36,000 En la parte superior del archivo que declarar una clase de estudiantes. 1019 00:55:36,000 --> 00:55:38,000 I a continuación, rellenar la clase con la entrada del usuario, 1020 00:55:38,000 --> 00:55:41,000 por lo que esas líneas de código son exactamente como antes. 1021 00:55:41,000 --> 00:55:45,000 Entonces, si me desplazo hasta aquí puedo imprimir todos los que están en Mather arbitrariamente como antes, 1022 00:55:45,000 --> 00:55:47,000 pero esta es una nueva característica interesante. 1023 00:55:47,000 --> 00:55:51,000 Estas líneas de código son nuevos, e introducen algo aquí, 1024 00:55:51,000 --> 00:55:55,000 De archivos, todo en mayúsculas, y tiene * aquí también. 1025 00:55:55,000 --> 00:55:58,000 Permítanme pasar esto aquí, a * por aquí también. 1026 00:55:58,000 --> 00:56:00,000 >> Esta función no hemos visto antes, fopen, 1027 00:56:00,000 --> 00:56:03,000 pero significa abrir el archivo, así que vamos a leerlo a través de ellos, 1028 00:56:03,000 --> 00:56:05,000 y esto es algo que vamos a volver en conjuntos de procesadores futuros, 1029 00:56:05,000 --> 00:56:10,000 pero esta línea aquí esencialmente abre un archivo llamado base de datos, 1030 00:56:10,000 --> 00:56:13,000 y, específicamente, se abre de tal manera que puede hacer lo que a él? 1031 00:56:13,000 --> 00:56:15,000 [Inaudible-alumno] 1032 00:56:15,000 --> 00:56:19,000 Bien, entonces "w" sólo significa que está diciendo al sistema operativo 1033 00:56:19,000 --> 00:56:21,000 abrir este archivo de tal manera que yo pueda escribir en él. 1034 00:56:21,000 --> 00:56:23,000 No quiero que lo lea. Yo no quiero mirar sólo a él. 1035 00:56:23,000 --> 00:56:26,000 Quiero cambiar y agregar cosas potencialmente a la misma, 1036 00:56:26,000 --> 00:56:28,000 y el archivo se va a llamar base de datos. 1037 00:56:28,000 --> 00:56:30,000 Esto podría llamarse cualquier cosa. 1038 00:56:30,000 --> 00:56:32,000 Esto podría ser database.txt. Esto podría ser. Db. 1039 00:56:32,000 --> 00:56:37,000 Esto podría ser una palabra como foo, pero arbitrariamente escogió el nombre de la base de datos de archivo. 1040 00:56:37,000 --> 00:56:42,000 Esta es una prueba de cordura poco que volveremos en detalle en el tiempo, 1041 00:56:42,000 --> 00:56:47,000 si da, para el puntero de archivo, no significa NULL igual que todo está bien. 1042 00:56:47,000 --> 00:56:51,000 >> Larga historia corta, funciona como fopen veces fallan. 1043 00:56:51,000 --> 00:56:53,000 Tal vez el archivo no existe. Tal vez te has quedado sin espacio de disco. 1044 00:56:53,000 --> 00:56:55,000 Tal vez usted no tiene permiso para esa carpeta, 1045 00:56:55,000 --> 00:56:58,000 por lo que si fopen devuelve algo nulo malo ha pasado. 1046 00:56:58,000 --> 00:57:02,000 Por el contrario, si no devuelve fopen nulo todo está bien 1047 00:57:02,000 --> 00:57:04,000 y puedo empezar a escribir en este archivo. 1048 00:57:04,000 --> 00:57:06,000 He aquí un truco nuevo. 1049 00:57:06,000 --> 00:57:08,000 Se trata de un bucle para que se itera sobre cada uno de mis estudiantes, 1050 00:57:08,000 --> 00:57:10,000 y esto se ve muy similar a lo que hemos hecho antes, 1051 00:57:10,000 --> 00:57:15,000 pero esta función es un primo de la llamada printf printf fprintf para archivo, 1052 00:57:15,000 --> 00:57:18,000 y nota que es diferente en tan sólo 2 maneras. 1053 00:57:18,000 --> 00:57:20,000 Uno de ellos, que comienza con F en lugar de p, 1054 00:57:20,000 --> 00:57:23,000 pero luego su primer argumento es aparentemente lo que? 1055 00:57:23,000 --> 00:57:25,000 [Los estudiantes] del archivo. >> Se trata de un archivo. 1056 00:57:25,000 --> 00:57:30,000 Esta cosa llamada fp, que finalmente va a separar lo que es un apuntador de archivo, 1057 00:57:30,000 --> 00:57:35,000 pero por ahora simplemente fp representa el archivo que he abierto, 1058 00:57:35,000 --> 00:57:41,000 fprintf aquí para imprimir esta diciendo ID del usuario en el archivo, no a la pantalla. 1059 00:57:41,000 --> 00:57:44,000 Imprimir el nombre del usuario en el fichero, no a la pantalla, 1060 00:57:44,000 --> 00:57:47,000 la casa en el archivo, no a la pantalla, y luego aquí, obviamente, 1061 00:57:47,000 --> 00:57:50,000 cerrar el archivo, y luego hacia abajo aquí libremente la memoria. 1062 00:57:50,000 --> 00:57:53,000 >> La única diferencia entre esta versión y la versión 2 1 1063 00:57:53,000 --> 00:57:58,000 es la introducción de fopen y este archivo como * 1064 00:57:58,000 --> 00:58:01,000 y esta noción de fprintf, así que vamos a ver lo que el resultado final es. 1065 00:58:01,000 --> 00:58:03,000 Déjame ir a mi ventana de terminal. 1066 00:58:03,000 --> 00:58:06,000 Déjame correr structs2, introduzca. 1067 00:58:06,000 --> 00:58:09,000 Parece que todo está bien. Vamos a volver a ejecutar structs2. 1068 00:58:09,000 --> 00:58:15,000 123, David Mather, 456, Rob Kirkland, 1069 00:58:15,000 --> 00:58:19,000 789, Tommy Mather, introduzca. 1070 00:58:19,000 --> 00:58:23,000 Parece que se comportaban de la misma, pero si ahora hago ls 1071 00:58:23,000 --> 00:58:28,000 cuenta de lo que está en el archivo aquí entre toda mi código, base de datos, 1072 00:58:28,000 --> 00:58:32,000 así que vamos a abrir esa, gedit de base de datos, y ver eso. 1073 00:58:32,000 --> 00:58:34,000 No es la más sexy de formatos de archivo. 1074 00:58:34,000 --> 00:58:38,000 Realmente es un pedazo de línea de datos por línea por línea, 1075 00:58:38,000 --> 00:58:42,000 pero aquellos de ustedes que usan archivos de Excel o CSV, valores separados por comas, 1076 00:58:42,000 --> 00:58:47,000 Ciertamente podría haber utilizado fprintf hacer en su lugar tal vez algo como esto 1077 00:58:47,000 --> 00:58:50,000 por lo que yo podía crear el equivalente de un archivo de Excel 1078 00:58:50,000 --> 00:58:53,000 al separar con comas cosas, no sólo las nuevas líneas. 1079 00:58:53,000 --> 00:58:56,000 >> En este caso, si hubiera utilizado en lugar comas en lugar de líneas nuevas 1080 00:58:56,000 --> 00:59:01,000 Yo, literalmente, podría abrir el archivo de base de datos en Excel si en cambio lo hizo ver como esto. 1081 00:59:01,000 --> 00:59:03,000 En resumen, ahora que tenemos el poder para escribir en archivos 1082 00:59:03,000 --> 00:59:07,000 ahora podemos empezar a datos persistentes, manteniéndolo alrededor del disco 1083 00:59:07,000 --> 00:59:10,000 para que podamos mantener la información en torno a una y otra vez. 1084 00:59:10,000 --> 00:59:14,000 Tenga en cuenta un par de cosas más que ahora son un poco más familiar. 1085 00:59:14,000 --> 00:59:16,000 En la parte superior de este archivo C tenemos un typedef 1086 00:59:16,000 --> 00:59:21,000 porque queríamos crear un tipo de datos que representa una palabra, 1087 00:59:21,000 --> 00:59:25,000 por lo que este tipo se denomina palabra, y en el interior de esta estructura 1088 00:59:25,000 --> 00:59:27,000 que es un poco más de lujo ahora. 1089 00:59:27,000 --> 00:59:30,000 ¿Por qué es una palabra compuesta de parecer una matriz? 1090 00:59:30,000 --> 00:59:33,000 ¿Qué es una palabra que sólo intuitivamente? 1091 00:59:33,000 --> 00:59:35,000 >> Es una serie de caracteres. 1092 00:59:35,000 --> 00:59:37,000 Es una secuencia de caracteres espalda con espalda con espalda. 1093 00:59:37,000 --> 00:59:41,000 Letras en mayúsculas resulta ser arbitrariamente decir la longitud máxima 1094 00:59:41,000 --> 00:59:44,000 de cualquier palabra en el diccionario que está utilizando para Scramble. 1095 00:59:44,000 --> 00:59:46,000 ¿Por qué tengo un +1? 1096 00:59:46,000 --> 00:59:48,000 El carácter nulo. 1097 00:59:48,000 --> 00:59:51,000 Recordemos cuando hicimos el ejemplo Bananagrams necesitábamos un valor especial 1098 00:59:51,000 --> 00:59:55,000 al final de la palabra con el fin de seguir la pista 1099 00:59:55,000 --> 00:59:59,000 de donde las palabras en realidad terminó, y como la especificación del conjunto de problema, dice 1100 00:59:59,000 --> 01:00:03,000 aquí estamos asociando con una palabra dada un valor boolean, 1101 01:00:03,000 --> 01:00:05,000 una bandera, por así decirlo, cierta o falsa. 1102 01:00:05,000 --> 01:00:09,000 ¿Has encontrado ya esta palabra, porque nos damos cuenta de 1103 01:00:09,000 --> 01:00:13,000 Realmente necesitamos una manera de recordar no sólo lo que una palabra está en Scramble 1104 01:00:13,000 --> 01:00:15,000 pero si no es así, lo humano, lo he encontrado 1105 01:00:15,000 --> 01:00:20,000 así que si usted encuentra la palabra "the" No se puede escribir el, entrar, el, entrar, la, introduzca 1106 01:00:20,000 --> 01:00:23,000 y obtener 3 puntos, 3 puntos, 3 puntos, 3 puntos. 1107 01:00:23,000 --> 01:00:26,000 Queremos ser capaces de poner en lista negra la palabra mediante el establecimiento de un bool 1108 01:00:26,000 --> 01:00:29,000 en true si ya lo has encontrado, y por eso nos 1109 01:00:29,000 --> 01:00:31,000 encapsulada en esta estructura. 1110 01:00:31,000 --> 01:00:35,000 >> Ahora, aquí en Scramble hay esta otra estructura llamada diccionario. 1111 01:00:35,000 --> 01:00:39,000 En ausencia de aquí es la palabra typedef porque en este caso 1112 01:00:39,000 --> 01:00:43,000 necesitábamos para encapsular la idea de un diccionario, 1113 01:00:43,000 --> 01:00:46,000 y un diccionario contiene un montón de palabras, 1114 01:00:46,000 --> 01:00:49,000 como se deduce de esta matriz, y cuántas de esas palabras hay? 1115 01:00:49,000 --> 01:00:51,000 Bueno, sea este tamaño variable llamada dice. 1116 01:00:51,000 --> 01:00:53,000 Pero sólo tenemos un diccionario. 1117 01:00:53,000 --> 01:00:55,000 No necesitamos un tipo de datos llamado diccionario. 1118 01:00:55,000 --> 01:00:58,000 Sólo tenemos uno de ellos, por lo que resulta en C 1119 01:00:58,000 --> 01:01:03,000 que si no dices typedef, que acaba de decir struct, a continuación, dentro de las llaves 1120 01:01:03,000 --> 01:01:05,000 usted pone sus variables, a continuación, poner el nombre. 1121 01:01:05,000 --> 01:01:09,000 Esto se declara una variable denominada diccionario 1122 01:01:09,000 --> 01:01:11,000 que se parece a esto. 1123 01:01:11,000 --> 01:01:16,000 Por el contrario, estas líneas están creando una estructura de datos reutilizable llamado palabra 1124 01:01:16,000 --> 01:01:19,000 que se pueden crear múltiples copias de, al igual que hemos creado 1125 01:01:19,000 --> 01:01:22,000 varias copias de los estudiantes. 1126 01:01:22,000 --> 01:01:24,000 >> ¿Qué significa este último término nos permite hacer? 1127 01:01:24,000 --> 01:01:30,000 Déjame volver en, digamos, un ejemplo más simple de tiempos más sencillos, 1128 01:01:30,000 --> 01:01:34,000 y me dejó abrir, digamos, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 El problema en cuestión es en realidad pelar 1130 01:01:38,000 --> 01:01:41,000 la capa de una cadena y empezar a despegar estas ruedas de entrenamiento 1131 01:01:41,000 --> 01:01:44,000 porque resulta que una cadena todo este tiempo 1132 01:01:44,000 --> 01:01:47,000 es como prometimos en la semana 1 realmente sólo un apodo, 1133 01:01:47,000 --> 01:01:51,000 un sinónimo de la biblioteca CS50 para algo que se parece un poco más críptico, 1134 01:01:51,000 --> 01:01:53,000 char *, y hemos visto esta estrella antes. 1135 01:01:53,000 --> 01:01:55,000 Lo vimos en el contexto de los archivos. 1136 01:01:55,000 --> 01:01:59,000 >> Ahora vamos a ver por qué hemos estado ocultando este detalle desde hace algún tiempo. 1137 01:01:59,000 --> 01:02:02,000 Aquí hay un archivo llamado compare1.c, 1138 01:02:02,000 --> 01:02:07,000 y, al parecer, le pide al usuario 2 cadenas, s y t, 1139 01:02:07,000 --> 01:02:11,000 y luego se trata de comparar esas cadenas para la igualdad en la línea 26, 1140 01:02:11,000 --> 01:02:14,000 y si son iguales se dice, "Usted escribió la misma cosa" 1141 01:02:14,000 --> 01:02:17,000 y si no somos iguales dice: "Ha escrito cosas diferentes". 1142 01:02:17,000 --> 01:02:19,000 Déjenme seguir adelante y ejecutar este programa. 1143 01:02:19,000 --> 01:02:23,000 Déjame ir a mi directorio de origen, haga una compare1. Se compila bien. 1144 01:02:23,000 --> 01:02:25,000 Déjame correr compare1. 1145 01:02:25,000 --> 01:02:27,000 Voy a acercar, introducir. 1146 01:02:27,000 --> 01:02:29,000 Diga algo. HELLO. 1147 01:02:29,000 --> 01:02:32,000 Voy a decir algo nuevo. HELLO. 1148 01:02:32,000 --> 01:02:34,000 Sin duda alguna no escriba cosas diferentes. 1149 01:02:34,000 --> 01:02:37,000 >> Déjame intentarlo de nuevo. BYE BYE. 1150 01:02:37,000 --> 01:02:40,000 Definitivamente no es diferente, así que lo que está pasando aquí? 1151 01:02:40,000 --> 01:02:44,000 Bueno, lo que realmente se comparan en la línea 26? 1152 01:02:44,000 --> 01:02:46,000 [Inaudible-alumno] 1153 01:02:46,000 --> 01:02:49,000 Sí, por lo que resulta que una cadena, tipo de datos, es una especie de mentira piadosa. 1154 01:02:49,000 --> 01:02:53,000 Una cadena es un char *, pero lo que es un char *? 1155 01:02:53,000 --> 01:02:56,000 Un char *, como se dice, es un puntero, 1156 01:02:56,000 --> 01:03:00,000 y un puntero es una dirección efectiva, 1157 01:03:00,000 --> 01:03:05,000 suma una ubicación en la memoria, y, si por casualidad usted ha escrito en una palabra como HOLA 1158 01:03:05,000 --> 01:03:08,000 Recuerdo las discusiones anteriores de cadenas 1159 01:03:08,000 --> 01:03:16,000 esto es como la palabra HOLA. 1160 01:03:16,000 --> 01:03:19,000 Recuerde que una palabra como HOLA se puede representar 1161 01:03:19,000 --> 01:03:22,000 como una serie de personajes como este 1162 01:03:22,000 --> 01:03:25,000 y luego con un carácter especial en el extremo llamado el carácter nulo, 1163 01:03:25,000 --> 01:03:27,000 como la denota \. 1164 01:03:27,000 --> 01:03:29,000 ¿Qué es en realidad una cadena? 1165 01:03:29,000 --> 01:03:32,000 Observe que este es varios fragmentos de memoria, 1166 01:03:32,000 --> 01:03:36,000 y, de hecho, al final de ella sólo se conoce una vez que mirar a través de toda la cadena 1167 01:03:36,000 --> 01:03:38,000 buscando el carácter nulo especial. 1168 01:03:38,000 --> 01:03:41,000 Pero si esto es un trozo de memoria de la memoria de mi ordenador, 1169 01:03:41,000 --> 01:03:44,000 vamos a decir arbitrariamente que esta cadena sólo tuvimos suerte, 1170 01:03:44,000 --> 01:03:47,000 y se quedó colocado en el comienzo mismo de la RAM de mi ordenador. 1171 01:03:47,000 --> 01:03:54,000 Este byte es 0, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> Cuando digo algo como GetString y hago string s = GetString 1173 01:04:02,000 --> 01:04:04,000 lo que realmente se devuelve? 1174 01:04:04,000 --> 01:04:08,000 Para estas últimas semanas, lo que realmente está siendo almacenado en s 1175 01:04:08,000 --> 01:04:13,000 no es esta cadena per se, pero en este caso es lo que se está almacenado 1176 01:04:13,000 --> 01:04:18,000 el número 0, porque lo que en realidad hace GetString 1177 01:04:18,000 --> 01:04:20,000 es que no físicamente devolver una cadena. 1178 01:04:20,000 --> 01:04:22,000 Eso no tiene mucho sentido conceptual. 1179 01:04:22,000 --> 01:04:24,000 Lo que hace de retorno es un número. 1180 01:04:24,000 --> 01:04:28,000 Ese número es la dirección de HOLA en la memoria, 1181 01:04:28,000 --> 01:04:32,000 y la cadena de s entonces, si pelar esta capa, la cadena no existe realmente. 1182 01:04:32,000 --> 01:04:35,000 No es más que una simplificación en la biblioteca CS50. 1183 01:04:35,000 --> 01:04:38,000 >> Esto realmente es algo que se llama char *. 1184 01:04:38,000 --> 01:04:41,000 Char tiene sentido porque ¿qué es una palabra, como HOLA? 1185 01:04:41,000 --> 01:04:44,000 Bueno, es una serie de caracteres, una serie de caracteres. 1186 01:04:44,000 --> 01:04:47,000 Char * significa que la dirección de un personaje, 1187 01:04:47,000 --> 01:04:50,000 así que, ¿qué significa para devolver una cadena? 1188 01:04:50,000 --> 01:04:53,000 Una manera agradable y sencilla de devolver una cadena 1189 01:04:53,000 --> 01:04:57,000 es más bien que tratar de averiguar cómo vuelvo a 5 o 6 bytes diferentes 1190 01:04:57,000 --> 01:05:01,000 permítanme volver a la dirección de la cual byte? 1191 01:05:01,000 --> 01:05:03,000 La primera de ellas. 1192 01:05:03,000 --> 01:05:06,000 En otras palabras, te voy a dar la dirección de un personaje en la memoria. 1193 01:05:06,000 --> 01:05:10,000 Eso es lo que representa char *, la dirección de un único carácter en la memoria. 1194 01:05:10,000 --> 01:05:12,000 Llame a esa variable s. 1195 01:05:12,000 --> 01:05:15,000 Conservar en esa dirección particular s, lo que me dijo es arbitrariamente 0, 1196 01:05:15,000 --> 01:05:19,000 sólo para mantener las cosas simples, pero en realidad es por lo general un número más grande. 1197 01:05:19,000 --> 01:05:21,000 >> Espera un minuto. 1198 01:05:21,000 --> 01:05:23,000 Si sólo me da la dirección del primer carácter, ¿cómo puedo saber cuál es la dirección es 1199 01:05:23,000 --> 01:05:25,000 el segundo carácter, la tercera, la cuarta y quinta de la? 1200 01:05:25,000 --> 01:05:27,000 [Inaudible-alumno] 1201 01:05:27,000 --> 01:05:31,000 Sólo se sabe dónde está el final de la cadena es por medio de este truco muy útil, 1202 01:05:31,000 --> 01:05:35,000 así que cuando usted usa algo como printf, lo que printf, literalmente, toma como argumento, 1203 01:05:35,000 --> 01:05:39,000 Recordamos que usamos este marcador de posición% s, y luego se pasa en 1204 01:05:39,000 --> 01:05:41,000 la variable que se almacena una cadena. 1205 01:05:41,000 --> 01:05:47,000 Lo que en realidad pasa es la dirección del primer carácter de la cadena. 1206 01:05:47,000 --> 01:05:50,000 Printf continuación, utiliza un bucle for o un bucle while como reciba la citada dirección, 1207 01:05:50,000 --> 01:05:53,000 por ejemplo, 0, así que voy a hacer esto ahora, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n", s); 1209 01:06:02,000 --> 01:06:07,000 Cuando llamo printf ("% s \ n", s); lo que realmente estoy proporcionando con printf 1210 01:06:07,000 --> 01:06:13,000 es la dirección del primer carácter en s, que en este caso es arbitrario H. 1211 01:06:13,000 --> 01:06:16,000 >> ¿Cómo printf saber qué es exactamente lo que se mostrará en la pantalla? 1212 01:06:16,000 --> 01:06:19,000 La persona que implementó printf implementado un bucle while o un bucle for 1213 01:06:19,000 --> 01:06:23,000 que dice que este personaje es igual al carácter nulo especial? 1214 01:06:23,000 --> 01:06:25,000 Si no, lo imprima. ¿Qué tal este? 1215 01:06:25,000 --> 01:06:28,000 Si no se imprime, imprimir, imprimir, imprimirla. 1216 01:06:28,000 --> 01:06:32,000 Oh, éste es especial. La impresión se detiene y devuelve al usuario. 1217 01:06:32,000 --> 01:06:35,000 Y eso es literalmente todo lo que ha estado sucediendo por debajo de la campana, 1218 01:06:35,000 --> 01:06:38,000 y eso es mucho para digerir en el primer día de clase, 1219 01:06:38,000 --> 01:06:43,000 pero por ahora es realmente la piedra angular de todo entendimiento 1220 01:06:43,000 --> 01:06:46,000 que ha estado sucediendo dentro de la memoria de nuestro ordenador, 1221 01:06:46,000 --> 01:06:49,000 y, finalmente, vamos a molestar a este aparte con un poco de ayuda 1222 01:06:49,000 --> 01:06:51,000 de uno de nuestros amigos de Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> El profesor Nick Parlante de Stanford ha hecho esta secuencia maravilloso video 1224 01:06:56,000 --> 01:06:58,000 de todo tipo de lenguas diferentes que introdujeron 1225 01:06:58,000 --> 01:07:00,000 este Claymation poco Binky carácter. 1226 01:07:00,000 --> 01:07:03,000 La voz que usted está a punto de escuchar un adelanto en apenas pocos segundos sneak 1227 01:07:03,000 --> 01:07:05,000 es el de un profesor de Stanford, y usted está recibiendo 1228 01:07:05,000 --> 01:07:07,000 sólo 5 o 6 segundos de esto ahora mismo, 1229 01:07:07,000 --> 01:07:09,000 pero esta es la nota en la que vamos a celebrar hoy 1230 01:07:09,000 --> 01:07:11,000 y comenzará el miércoles. 1231 01:07:11,000 --> 01:07:15,000 Te doy Fun puntero con Binky, la vista previa. 1232 01:07:15,000 --> 01:07:18,000 [♪ ♪ Music] [Profesor Parlante] Hey, Binky. 1233 01:07:18,000 --> 01:07:21,000 Despierta. Es tiempo para la diversión puntero. 1234 01:07:21,000 --> 01:07:24,000 [Binky] ¿Qué es eso? Aprenda acerca de los punteros? 1235 01:07:24,000 --> 01:07:26,000 Oh, qué bien! 1236 01:07:26,000 --> 01:07:29,000 >> Nos vemos el miércoles. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]