1 00:00:00,000 --> 00:00:11,200 2 00:00:11,200 --> 00:00:12,580 >> DAVID MALAN: Muy bien, bienvenida de nuevo. 3 00:00:12,580 --> 00:00:13,290 Este es CS50. 4 00:00:13,290 --> 00:00:15,130 Este es el comienzo de la séptima semana. 5 00:00:15,130 --> 00:00:18,890 Así que ha sido un tiempo, así que pensamos que sería mejor tomar un viaje relámpago de dónde estamos 6 00:00:18,890 --> 00:00:20,760 dejamos y donde ahora vamos. 7 00:00:20,760 --> 00:00:23,310 >> Así que esta cosa aquí podría tener causado cierta angustia al principio. 8 00:00:23,310 --> 00:00:27,680 Pero es de esperar, que está empezando a aclimatarse a lo que esto denota aquí - 9 00:00:27,680 --> 00:00:32,670 estrella que representa un puntero, que es justo lo que, en términos más sencillos? 10 00:00:32,670 --> 00:00:33,400 Así que es una dirección. 11 00:00:33,400 --> 00:00:35,490 >> Así que es la dirección de algo en la memoria. 12 00:00:35,490 --> 00:00:38,260 Y empezamos a pelar las capas Hace un par de semanas, las cosas como 13 00:00:38,260 --> 00:00:41,800 GetString y otras funciones similares todo este tiempo han estado volviendo 14 00:00:41,800 --> 00:00:46,010 direcciones de las cosas en la memoria, como el dirección del primer carácter en 15 00:00:46,010 --> 00:00:46,990 alguna secuencia. 16 00:00:46,990 --> 00:00:50,360 >> Así también introdujimos valgrind, que usted comenzará a utilizar para este problema 17 00:00:50,360 --> 00:00:53,380 establecer, en particular para la próxima problema configurado así. 18 00:00:53,380 --> 00:00:54,980 Y valgrind hace lo que para nosotros? 19 00:00:54,980 --> 00:00:57,520 20 00:00:57,520 --> 00:01:01,020 Comprueba si hay fugas de memoria, y También comprueba que hay abuso de la memoria. 21 00:01:01,020 --> 00:01:05,890 >> Se puede, con cierta probabilidad, detectar si su código va a tocar de memoria 22 00:01:05,890 --> 00:01:07,100 que simplemente no debería. 23 00:01:07,100 --> 00:01:10,410 Así que no es necesariamente una fuga, pero si ir más allá de las fronteras de algunos 24 00:01:10,410 --> 00:01:14,730 matriz, y en realidad se ejecuta valgrind e inducir a que el comportamiento, mientras que 25 00:01:14,730 --> 00:01:17,870 valgrind se está ejecutando en su programa es se ejecuta dentro de la misma, obtendrá 26 00:01:17,870 --> 00:01:21,460 mensajes como este - "escritura no válido de tamaño 4 ", el cual, recordar un par de 27 00:01:21,460 --> 00:01:25,880 Hace semanas significaba que tenía accidentalmente como en un int demasiado 28 00:01:25,880 --> 00:01:27,250 más allá de los límites de una matriz. 29 00:01:27,250 --> 00:01:30,790 Y lo que el tamaño 4 significa que aquí el tamaño de que int en particular. 30 00:01:30,790 --> 00:01:35,260 >> Así que toma consuelo en el hecho de que de salida de valgrind, el formato de la misma, 31 00:01:35,260 --> 00:01:36,170 es simplemente atroz. 32 00:01:36,170 --> 00:01:40,180 Es muy difícil ver a través del desorden para la información interesante. 33 00:01:40,180 --> 00:01:42,910 Así que lo que hemos hecho aquí es sólo extracto algunos de la pareja de más 34 00:01:42,910 --> 00:01:43,850 líneas interesantes. 35 00:01:43,850 --> 00:01:46,760 Pero darse cuenta de que el 80% de los de valgrind salida va a ser un poco de un 36 00:01:46,760 --> 00:01:47,650 distracción. 37 00:01:47,650 --> 00:01:52,820 >> Sólo tienes que buscar patrones como estos - derecho válido, no válido de lectura, 40 bytes 38 00:01:52,820 --> 00:01:56,690 y un número de bloques son definitivamente perdidos, palabras clave así. 39 00:01:56,690 --> 00:02:01,920 ¿Y qué te esperamos ver algo de tipo de rastro de lo que funcionará el 40 00:02:01,920 --> 00:02:03,340 error es en realidad pulg 41 00:02:03,340 --> 00:02:07,195 En este caso aquí, en qué línea de mi código fue el error aparentemente? 42 00:02:07,195 --> 00:02:09,729 43 00:02:09,729 --> 00:02:14,130 >> 26 en un archivo llamado memory.c, que era el ejemplo que estábamos jugando con 44 00:02:14,130 --> 00:02:14,890 en el momento. 45 00:02:14,890 --> 00:02:16,460 Así que probablemente no está en malloc. 46 00:02:16,460 --> 00:02:18,630 Probablemente fue en mi código en su lugar. 47 00:02:18,630 --> 00:02:20,910 Así que vamos a ver esto de nuevo y de nuevo en poco tiempo. 48 00:02:20,910 --> 00:02:24,080 >> Así scanf, esto ocurrió en un par de formas hasta ahora. 49 00:02:24,080 --> 00:02:26,410 Vimos brevemente sscanf. 50 00:02:26,410 --> 00:02:28,330 Fue algo un número de que se zambulló en en su 51 00:02:28,330 --> 00:02:29,535 los preparativos para el concurso. 52 00:02:29,535 --> 00:02:33,130 Y scanf es en realidad lo que el CS50 biblioteca ha estado usando por debajo de la 53 00:02:33,130 --> 00:02:36,560 campana desde hace bastante tiempo con el fin para obtener la entrada del usuario. 54 00:02:36,560 --> 00:02:40,420 >> Por ejemplo, si me mudo a la CS50 Appliance aquí, déjame abrir una 55 00:02:40,420 --> 00:02:45,315 ejemplo hoy que se llama scanf-0.C Y es super simple. 56 00:02:45,315 --> 00:02:46,590 Son sólo unas pocas líneas de código. 57 00:02:46,590 --> 00:02:50,880 Pero demuestra realmente cómo getInt ha estado trabajando todo este tiempo. 58 00:02:50,880 --> 00:02:54,710 >> En este programa aquí, en la línea 16 , Noto que me declaro un int. 59 00:02:54,710 --> 00:02:57,270 Así que no hay punteros, nada mágico allí, sólo un int. 60 00:02:57,270 --> 00:03:00,330 Luego, en la línea 17, que incitan la usuario un número, por favor. 61 00:03:00,330 --> 00:03:02,930 Luego a finales de 18, yo uso scanf aquí. 62 00:03:02,930 --> 00:03:06,910 Y he especificado, algo así como printf, que estoy esperando la cita 63 00:03:06,910 --> 00:03:08,110 ciento unquote i. 64 00:03:08,110 --> 00:03:10,920 >> Así ciento i, por supuesto, denota un int. 65 00:03:10,920 --> 00:03:14,580 Pero note lo que el segundo argumento para scanf es. 66 00:03:14,580 --> 00:03:17,350 ¿Cómo describiría el segundo argumento después de la coma? 67 00:03:17,350 --> 00:03:19,450 ¿Qué es eso? 68 00:03:19,450 --> 00:03:20,670 >> Es la dirección de x. 69 00:03:20,670 --> 00:03:25,490 Así que esto es útil porque al proporcionar scanf con la dirección de x, lo que hace 70 00:03:25,490 --> 00:03:29,560 que permiten a esa función a hacer? 71 00:03:29,560 --> 00:03:33,010 No sólo tiene que ir allí, sino también hacer que? 72 00:03:33,010 --> 00:03:34,060 >> Realizar un cambio en él. 73 00:03:34,060 --> 00:03:38,080 Debido a que usted puede ir allí, es una especie de como un mapa a una ubicación en la memoria. 74 00:03:38,080 --> 00:03:41,900 Y así, siempre y cuando proporcione scanf, o cualquier función con dicho mapa, que 75 00:03:41,900 --> 00:03:45,840 función puede ir allí, y no sólo mirar el valor, sino que también puede 76 00:03:45,840 --> 00:03:49,670 cambiar ese valor, lo cual es útil si el propósito en la vida de scanf es 77 00:03:49,670 --> 00:03:53,060 escanear la entrada del usuario, en concreto desde el teclado. 78 00:03:53,060 --> 00:03:57,830 Y el f denota formato, al igual que printf, el f denota una formateada 79 00:03:57,830 --> 00:03:58,930 cadena que desea imprimir. 80 00:03:58,930 --> 00:04:04,430 >> Así que en resumen, esta línea 18 simplemente dice: tratar de leer un int del usuario 81 00:04:04,430 --> 00:04:10,420 teclado y guardarlo dentro de x, en cualquiera que sea la dirección x pasa a vivir en. 82 00:04:10,420 --> 00:04:14,860 Y luego, por último, la línea 19 se limita a decir, gracias por el int, en este caso. 83 00:04:14,860 --> 00:04:15,940 >> Así que permítanme seguir adelante y hacer esto. 84 00:04:15,940 --> 00:04:18,570 Así que scanf 0. 85 00:04:18,570 --> 00:04:20,130 Déjame ir adelante y agrandar 86 00:04:20,130 --> 00:04:22,960 Voy a correr con este puntos slash scanf 0. 87 00:04:22,960 --> 00:04:24,020 Número, por favor? 88 00:04:24,020 --> 00:04:24,720 50. 89 00:04:24,720 --> 00:04:25,730 Gracias por el 50. 90 00:04:25,730 --> 00:04:27,270 Así que es bastante simple. 91 00:04:27,270 --> 00:04:28,160 >> Ahora ¿qué es lo que no hace? 92 00:04:28,160 --> 00:04:29,940 No está haciendo un montón de comprobación de errores. 93 00:04:29,940 --> 00:04:33,000 Por ejemplo, si yo no coopero, y yo no escribo en un número, pero 94 00:04:33,000 --> 00:04:37,860 vez que escribo algo así como "hola" eso es sólo un poco extraño. 95 00:04:37,860 --> 00:04:41,130 Y lo que una de las cosas que el CS50 biblioteca ha estado haciendo por nosotros durante algún 96 00:04:41,130 --> 00:04:43,440 tiempo es que reprompting y reprompting. 97 00:04:43,440 --> 00:04:49,320 >> La frase recordatorio reintento estaba en cs50.c, y esa es la razón por la que en getInt 98 00:04:49,320 --> 00:04:51,670 la biblioteca CS50 es en realidad un conjunto montón de líneas largas, porque estamos 99 00:04:51,670 --> 00:04:53,190 la comprobación de cosas estúpidas como esta. 100 00:04:53,190 --> 00:04:55,730 ¿El usuario no da nosotros, de hecho, un int? 101 00:04:55,730 --> 00:04:57,910 ¿Él o ella nos da algo como una letra del alfabeto? 102 00:04:57,910 --> 00:05:01,410 Si es así, queremos detectar eso y les gritan. 103 00:05:01,410 --> 00:05:03,915 >> Pero las cosas se ponen más interesantes en el siguiente ejemplo. 104 00:05:03,915 --> 00:05:09,840 Si voy a scanf-1.c, lo que es un Lo que ha cambiado fundamentalmente en 105 00:05:09,840 --> 00:05:11,135 el siguiente ejemplo? 106 00:05:11,135 --> 00:05:13,690 107 00:05:13,690 --> 00:05:16,010 Estoy utilizando char *, por supuesto, en lugar de int. 108 00:05:16,010 --> 00:05:19,210 >> Así que esto es interesante, porque char *, recuerdo, en realidad es sólo la 109 00:05:19,210 --> 00:05:20,190 lo mismo que la cadena. 110 00:05:20,190 --> 00:05:23,840 Así que se siente como tal vez este es un super implementación simple de GetString. 111 00:05:23,840 --> 00:05:26,010 Pero he desprendió la capa de la biblioteca CS50, así que estoy 112 00:05:26,010 --> 00:05:27,550 llamar a este char * ahora. 113 00:05:27,550 --> 00:05:30,070 Así que vamos a ver a dónde, si en cualquier lugar, nos equivocamos. 114 00:05:30,070 --> 00:05:30,840 >> Línea 17 - 115 00:05:30,840 --> 00:05:33,950 Otra vez digo, por favor, dame algo, en este caso, una cadena. 116 00:05:33,950 --> 00:05:37,940 Y luego, en la línea siguiente, que yo llamo scanf, de nuevo, dándole un código de formato, 117 00:05:37,940 --> 00:05:39,310 pero esta vez por ciento s. 118 00:05:39,310 --> 00:05:41,900 Y después de este tiempo, yo soy dándole a amortiguar. 119 00:05:41,900 --> 00:05:43,550 >> Ahora noto, no estoy usando la y comercial. 120 00:05:43,550 --> 00:05:47,120 Pero ¿por qué es que probablemente está bien aquí? 121 00:05:47,120 --> 00:05:49,760 Porque lo que la barrera es ya? 122 00:05:49,760 --> 00:05:50,770 Ya es un puntero. 123 00:05:50,770 --> 00:05:51,650 Ya es una dirección. 124 00:05:51,650 --> 00:05:54,510 >> Y vamos a esta palabra "confundir", hágamelo simplemente llame que s, por ejemplo, para 125 00:05:54,510 --> 00:05:55,050 simplicidad. 126 00:05:55,050 --> 00:05:58,250 Pero yo he llamado a amortiguar porque en en general, en la programación, si usted tiene un 127 00:05:58,250 --> 00:06:02,130 trozo de memoria, que una cadena realmente justo es decir, que se podría llamar un buffer. 128 00:06:02,130 --> 00:06:04,460 Es un lugar para almacenar información. 129 00:06:04,460 --> 00:06:07,400 >> Al igual que en cosas como YouTube, cuando que están amortiguando, por así decirlo, que 130 00:06:07,400 --> 00:06:10,270 simplemente significa que es la descarga de los bits de Internet y guardarlos en un 131 00:06:10,270 --> 00:06:14,160 matriz local, una parte local de la memoria, de modo que se puede ver más adelante sin 132 00:06:14,160 --> 00:06:16,830 que saltar o colgar en que durante la reproducción. 133 00:06:16,830 --> 00:06:20,930 >> Así que hay un problema aquí, sin embargo, porque yo lo digo scanf, le espera una 134 00:06:20,930 --> 00:06:22,320 cadena del usuario. 135 00:06:22,320 --> 00:06:24,410 Aquí está la dirección de un trozo de memoria. 136 00:06:24,410 --> 00:06:26,180 Ponga esa cadena allí. 137 00:06:26,180 --> 00:06:31,230 ¿Por qué es que dan cota nos problemas, sin embargo? 138 00:06:31,230 --> 00:06:33,490 >> ¿Qué es eso? 139 00:06:33,490 --> 00:06:35,510 ¿Se me permite el acceso que parte de la memoria? 140 00:06:35,510 --> 00:06:36,250 Usted sabe, yo no lo sé. 141 00:06:36,250 --> 00:06:39,210 Debido a que se ha inicializado búfer a algo? 142 00:06:39,210 --> 00:06:39,820 En realidad no. 143 00:06:39,820 --> 00:06:43,090 Y lo que es lo que hemos estado llamando un valor basura, que 144 00:06:43,090 --> 00:06:44,040 no es una palabra formal. 145 00:06:44,040 --> 00:06:49,200 Simplemente significa que no tenemos idea de lo que los bits se encuentran dentro de los cuatro bytes que 146 00:06:49,200 --> 00:06:51,240 He asignado como tampón. 147 00:06:51,240 --> 00:06:52,450 >> No he llamado a malloc. 148 00:06:52,450 --> 00:06:53,940 Definitivamente no he llamado GetString. 149 00:06:53,940 --> 00:06:56,380 Entonces, ¿quién sabe lo que es en realidad dentro de tampón? 150 00:06:56,380 --> 00:07:00,550 Y sin embargo, diciendo scanf ciegamente, ir allí y poner lo que el usuario escribe. 151 00:07:00,550 --> 00:07:04,460 >> Entonces, ¿qué es probable que la causa en nuestro código si lo ejecutamos? 152 00:07:04,460 --> 00:07:05,700 Probablemente una violación de segmento. 153 00:07:05,700 --> 00:07:07,970 Tal vez no, pero probablemente un error de segmentación. 154 00:07:07,970 --> 00:07:10,620 Y digo tal vez no, porque a veces usted lo hace, a veces 155 00:07:10,620 --> 00:07:11,380 usted no recibe una violación de segmento. 156 00:07:11,380 --> 00:07:14,280 A veces sólo tener suerte, pero que es, sin embargo, va a ser 157 00:07:14,280 --> 00:07:15,340 un error en nuestro programa. 158 00:07:15,340 --> 00:07:17,060 >> Así que permítanme seguir adelante y compilar esto. 159 00:07:17,060 --> 00:07:18,280 Voy a hacerlo de la manera de la vieja escuela. 160 00:07:18,280 --> 00:07:23,825 Tablero Así clang 0, scanf-1, scanf-1.c, Intro. 161 00:07:23,825 --> 00:07:24,720 Vaya, demasiado vieja escuela. 162 00:07:24,720 --> 00:07:26,550 Vamos a ver. 163 00:07:26,550 --> 00:07:28,440 ¿Qué hice? 164 00:07:28,440 --> 00:07:29,700 Oh, char * buffer. 165 00:07:29,700 --> 00:07:33,595 166 00:07:33,595 --> 00:07:35,130 Oh, gracias - 167 00:07:35,130 --> 00:07:36,930 Guardar, OK - 168 00:07:36,930 --> 00:07:37,690 muy vieja escuela. 169 00:07:37,690 --> 00:07:38,900 Muy bien, ha pasado un tiempo. 170 00:07:38,900 --> 00:07:41,720 >> Así que he acabo de salvar el archivo después de haciendo que temporal 171 00:07:41,720 --> 00:07:42,700 cambiar hace un momento. 172 00:07:42,700 --> 00:07:46,090 Y ahora que he compilado manualmente con Clang. 173 00:07:46,090 --> 00:07:49,500 Y ahora me voy a ir por delante y ejecutar scanf-1, Enter. 174 00:07:49,500 --> 00:07:50,290 Cadena por favor. 175 00:07:50,290 --> 00:07:51,600 Voy a escribir "hola." 176 00:07:51,600 --> 00:07:54,070 >> Y ahora, aquí es donde, francamente, printf CAN es un poco molesto. 177 00:07:54,070 --> 00:07:56,020 No es en realidad va a segfault en este caso. 178 00:07:56,020 --> 00:07:59,860 Printf es un poco especial porque se usa de manera muy comúnmente que 179 00:07:59,860 --> 00:08:03,570 esencialmente printf está haciendo Haznos un favor y hacer realidad, 180 00:08:03,570 --> 00:08:04,830 eso no es un puntero válido. 181 00:08:04,830 --> 00:08:09,080 Permítanme tomar sobre mí sólo de impresión en paréntesis nulo, incluso 182 00:08:09,080 --> 00:08:13,340 aunque no es necesariamente lo que nosotros mismos nos esperábamos. 183 00:08:13,340 --> 00:08:16,940 >> Así que no podemos inducir muy fácilmente un segfault con esto, pero está claro que 184 00:08:16,940 --> 00:08:18,600 no es el comportamiento que yo quería. 185 00:08:18,600 --> 00:08:19,800 ¿Y cuál es la solución simple? 186 00:08:19,800 --> 00:08:25,650 Pues bien, en scanf-2, permítanme proponer que en lugar de en realidad sólo la asignación de una 187 00:08:25,650 --> 00:08:30,100 char *, quiero ser un poco más inteligente sobre esto, y déjame asignar el búfer 188 00:08:30,100 --> 00:08:32,940 como una secuencia de 16 caracteres. 189 00:08:32,940 --> 00:08:34,200 >> Así que puedo hacer esto en un par de maneras. 190 00:08:34,200 --> 00:08:35,610 Absolutamente me vendría malloc. 191 00:08:35,610 --> 00:08:38,980 Pero yo puedo volver a la semana dos, cuando Sólo necesitaba un montón de 192 00:08:38,980 --> 00:08:39,620 personajes. 193 00:08:39,620 --> 00:08:40,860 Eso es sólo una matriz. 194 00:08:40,860 --> 00:08:44,870 Así que déjame en lugar redefino búfer a ser una matriz de 16 caracteres. 195 00:08:44,870 --> 00:08:47,340 >> Y ahora, cuando paso de búfer en - 196 00:08:47,340 --> 00:08:49,940 y esto es algo que no hicimos hablar en la segunda semana - 197 00:08:49,940 --> 00:08:53,730 pero se puede tratar a un array como aunque es una dirección. 198 00:08:53,730 --> 00:08:56,390 Técnicamente, como hemos visto, son un poco diferente. 199 00:08:56,390 --> 00:09:01,290 Pero scanf no le importará si se le pasa el nombre de un arreglo, ya que lo que 200 00:09:01,290 --> 00:09:05,030 Clang hará por nosotros es esencialmente tratar el nombre de esa matriz como la 201 00:09:05,030 --> 00:09:08,280 dirección de la porción de 16 bytes. 202 00:09:08,280 --> 00:09:09,550 >> Así que esto es mejor. 203 00:09:09,550 --> 00:09:12,110 Esto significa que ahora que puedo espero haga lo siguiente. 204 00:09:12,110 --> 00:09:16,800 Permítanme Alejar por un momento y no hacer scanf-2, compilado en Aceptar. 205 00:09:16,800 --> 00:09:19,390 Ahora déjame hacer conseguí slash scanf-2. 206 00:09:19,390 --> 00:09:22,430 Cadena por favor. "Hola." Y parecía funcionar esta vez. 207 00:09:22,430 --> 00:09:26,020 >> Pero alguien puede proponer un escenario en el que todavía no podría funcionar? 208 00:09:26,020 --> 00:09:28,550 ¿Sí? 209 00:09:28,550 --> 00:09:30,640 Algo más de 16 caracteres. 210 00:09:30,640 --> 00:09:32,020 Y, de hecho, podemos estar un poco más precisa. 211 00:09:32,020 --> 00:09:36,540 Algo más largo que 15 caracteres, porque realmente tenemos que tener en cuenta 212 00:09:36,540 --> 00:09:39,920 que necesitamos que el cero barra invertida implícitamente en el extremo de la cadena, 213 00:09:39,920 --> 00:09:42,950 que es un aparte scanf típicamente cuidar para nosotros. 214 00:09:42,950 --> 00:09:46,210 >> Así que déjame hacer algo así - 215 00:09:46,210 --> 00:09:48,040 A veces podemos simplemente dejarlo así. 216 00:09:48,040 --> 00:09:50,630 OK, así que ahora hemos inducidos nuestro fallo de segmentación. 217 00:09:50,630 --> 00:09:51,000 ¿Por qué? 218 00:09:51,000 --> 00:09:54,940 Debido a que he escrito más de 15 personajes, y por lo que hemos hecho 219 00:09:54,940 --> 00:09:58,280 memoria tocado que en realidad No debería haberlo hecho. 220 00:09:58,280 --> 00:10:00,180 >> Entonces, ¿qué es realmente la solución aquí? 221 00:10:00,180 --> 00:10:02,210 Bueno, ¿y si necesitamos una cadena más larga? 222 00:10:02,210 --> 00:10:03,960 Bueno, tal vez lo dejamos 32 bytes. 223 00:10:03,960 --> 00:10:05,160 Bueno, ¿y si eso no es suficiente? 224 00:10:05,160 --> 00:10:06,040 ¿Qué hay de 64 bytes? 225 00:10:06,040 --> 00:10:07,080 ¿Y si eso no es suficiente? 226 00:10:07,080 --> 00:10:09,640 ¿Qué hay de 128 o 200 bytes? 227 00:10:09,640 --> 00:10:12,660 Lo que realmente es la solución a este problema en el caso general, si no sabemos en 228 00:10:12,660 --> 00:10:14,460 avanzar en lo que el usuario va a escribir? 229 00:10:14,460 --> 00:10:20,000 230 00:10:20,000 --> 00:10:23,050 >> Es sólo una especie de gran dolor en el culo, para ser honesto, que es la razón por la 231 00:10:23,050 --> 00:10:29,050 Biblioteca CS50 tiene unas pocas docenas de líneas de código que colectivamente implementar 232 00:10:29,050 --> 00:10:32,390 GetString cadena de una manera que no lo hacemos tiene que saber de antemano lo que el 233 00:10:32,390 --> 00:10:33,430 usuario va a escribir. 234 00:10:33,430 --> 00:10:37,370 En particular, si uno mira hacia atrás en cs50.c desde hace dos semanas, usted verá 235 00:10:37,370 --> 00:10:40,480 que GetString hace realidad No utilice scanf de esta manera. 236 00:10:40,480 --> 00:10:43,720 Más bien, se lee un carácter a la vez. 237 00:10:43,720 --> 00:10:46,010 >> Porque la única cosa buena acerca de la lectura de un personaje es lo que podemos 238 00:10:46,010 --> 00:10:48,490 garantizar nosotros mismos para siempre tener al menos un carbón de leña. 239 00:10:48,490 --> 00:10:51,740 Yo sólo puedo declarar un char y, a continuación, tomar estos pasos verdaderamente bebé a poco 240 00:10:51,740 --> 00:10:54,380 leer un carácter en a una tiempo desde el teclado. 241 00:10:54,380 --> 00:10:58,240 Y entonces, lo que verás GetString hace es cada vez que se queda sin, 242 00:10:58,240 --> 00:11:02,280 por ejemplo, 16 bytes de memoria, se utiliza malloc, o un primo de la misma, 243 00:11:02,280 --> 00:11:06,810 asignar más memoria, copia de la vieja memoria en la nueva, y luego arrastrándose 244 00:11:06,810 --> 00:11:09,900 junto, consiguiendo un carácter a la vez, y cuando se queda sin que 245 00:11:09,900 --> 00:11:13,370 trozo de memoria, lo tira, agarra un pedazo más grande de la memoria, copias de edad 246 00:11:13,370 --> 00:11:14,750 en nuevas y repeticiones. 247 00:11:14,750 --> 00:11:18,480 Y es realmente un dolor de realidad aplicar algo tan simple como 248 00:11:18,480 --> 00:11:19,710 obtener información de un usuario. 249 00:11:19,710 --> 00:11:21,090 >> Así que usted puede usar scanf. 250 00:11:21,090 --> 00:11:22,430 Puede utilizar otras funciones similares. 251 00:11:22,430 --> 00:11:25,420 Y un montón de libros de texto y en línea ejemplos hacen, pero son todos 252 00:11:25,420 --> 00:11:27,210 vulnerables a problemas como éste. 253 00:11:27,210 --> 00:11:29,550 Y en última instancia, conseguir un error de segmentación es un poco molesto. 254 00:11:29,550 --> 00:11:30,680 No es bueno para el usuario. 255 00:11:30,680 --> 00:11:33,560 >> Pero en el peor de los casos, lo que hace es fundamental poner su 256 00:11:33,560 --> 00:11:37,160 código en riesgo de? 257 00:11:37,160 --> 00:11:39,250 Algún tipo de ataque, potencialmente. 258 00:11:39,250 --> 00:11:41,680 Hablamos de uno de estos ataques - Desbordamiento de la pila. 259 00:11:41,680 --> 00:11:44,660 Pero en general, si se le permite desbordar un buffer, como lo hicimos una 260 00:11:44,660 --> 00:11:48,070 par de semanas atrás, con sólo escribir más que "hola" en la pila, 261 00:11:48,070 --> 00:11:52,330 tampoco puede asumir el control, potencialmente, un computadora, o por lo menos llegar a los datos que 262 00:11:52,330 --> 00:11:53,510 no pertenece a usted. 263 00:11:53,510 --> 00:11:55,970 >> Así que en resumen, es por eso que tenemos esas ruedas de entrenamiento. 264 00:11:55,970 --> 00:11:59,090 Pero ahora, empezamos a quitárselos, como nuestros programas ya no necesitan, 265 00:11:59,090 --> 00:12:00,610 necesariamente, la entrada del usuario. 266 00:12:00,610 --> 00:12:03,960 Pero en el caso del problema planteado seis, su aporte provendrá de una enorme 267 00:12:03,960 --> 00:12:07,520 archivo de diccionario con 150 algunos impares mil palabras. 268 00:12:07,520 --> 00:12:10,330 >> Así que usted no tendrá que preocuparse por entrada arbitraria del usuario. 269 00:12:10,330 --> 00:12:13,720 Le daremos algunos supuestos sobre ese archivo. 270 00:12:13,720 --> 00:12:20,340 ¿Tiene preguntas sobre punteros o scanf o la entrada del usuario en general? 271 00:12:20,340 --> 00:12:24,450 >> Muy bien, por lo que un rápido vistazo a continuación, en un arrastrando tema desde hace dos semanas. 272 00:12:24,450 --> 00:12:28,590 Y esa fue la idea de una estructura. 273 00:12:28,590 --> 00:12:34,180 No es que - esta noción de un estructura, que era lo que? 274 00:12:34,180 --> 00:12:35,430 Lo que sí struct hacer por nosotros? 275 00:12:35,430 --> 00:12:39,280 276 00:12:39,280 --> 00:12:39,860 >> Definir - 277 00:12:39,860 --> 00:12:41,710 ¿Cómo? 278 00:12:41,710 --> 00:12:42,820 Definir un tipo variable. 279 00:12:42,820 --> 00:12:44,410 Así que en cierto modo. 280 00:12:44,410 --> 00:12:46,180 De hecho, estamos combinando dos temas. 281 00:12:46,180 --> 00:12:49,510 Así que con typedef, recordar que podemos declarar un tipo de los nuestros, como un 282 00:12:49,510 --> 00:12:51,500 sinónimo, como cadena para char *. 283 00:12:51,500 --> 00:12:56,200 Pero el uso de typedef struct y, podemos crear verdaderamente nuestras propias estructuras de datos. 284 00:12:56,200 --> 00:12:59,600 >> Por ejemplo, si voy de nuevo en gedit aquí sólo por un momento, y sigo adelante 285 00:12:59,600 --> 00:13:08,230 y hacer algo como, permítanme guardar esto como, digamos, STRUCTS.C 286 00:13:08,230 --> 00:13:10,840 temporalmente, sólo voy seguir adelante e incluir 287 00:13:10,840 --> 00:13:14,360 standardio.h, void main int. 288 00:13:14,360 --> 00:13:18,960 Y luego aquí, supongo que quiero para escribir un programa que almacena 289 00:13:18,960 --> 00:13:21,840 varios estudiantes de múltiples casas, por ejemplo. 290 00:13:21,840 --> 00:13:24,430 Así que es como un registrarial base de datos de algún tipo. 291 00:13:24,430 --> 00:13:29,550 >> Así que si necesito el nombre de un estudiante, podría hacer algo como carbón nombre *, 292 00:13:29,550 --> 00:13:31,570 y voy a hacer algo así - 293 00:13:31,570 --> 00:13:34,410 En realidad, vamos a usar la biblioteca CS50 por sólo un momento para hacer de esto una 294 00:13:34,410 --> 00:13:38,380 poco más simple, por lo que podemos pedir prestado esas decenas de líneas de código. 295 00:13:38,380 --> 00:13:39,340 Y vamos a hacerlo simple. 296 00:13:39,340 --> 00:13:42,610 Lo mantendremos en cadena, y ahora GetString. 297 00:13:42,610 --> 00:13:47,420 >> Así que yo pretendo ahora que he almacenado el nombre de algún estudiante, y la casa de 298 00:13:47,420 --> 00:13:50,240 algún estudiante, el simple uso de las variables como lo hicimos y en la primera semana. 299 00:13:50,240 --> 00:13:52,370 Pero supongo que ahora quiero apoyar varios estudiantes. 300 00:13:52,370 --> 00:13:58,460 Muy bien, así que mis instintos son hacer nombre2 cadena, se pone GetString, string 301 00:13:58,460 --> 00:14:01,370 house2 consigue GetString. 302 00:14:01,370 --> 00:14:05,850 Y entonces nuestro tercer estudiante, hagámoslo GetString nombre3. 303 00:14:05,850 --> 00:14:09,170 >> Muy bien, así que esto es de esperar sorprendente usted como un poco estúpido, 304 00:14:09,170 --> 00:14:11,580 porque este proceso es realmente nunca va a terminar, y que sólo va a 305 00:14:11,580 --> 00:14:13,130 hace que mi código se vea peor y peor y peor. 306 00:14:13,130 --> 00:14:14,810 Pero resolvimos esto también en la segunda semana. 307 00:14:14,810 --> 00:14:19,450 ¿Cuál era nuestra solución relativamente limpio cuando tuvimos múltiples variables de la 308 00:14:19,450 --> 00:14:23,580 mismo tipo de datos que están relacionados, pero que no queríamos este lío atroz 309 00:14:23,580 --> 00:14:26,870 de llamada de manera similar las variables? 310 00:14:26,870 --> 00:14:30,060 ¿Qué hemos hecho en su lugar? 311 00:14:30,060 --> 00:14:31,260 >> Así que creo que he oído un par de lugares. 312 00:14:31,260 --> 00:14:32,590 Tuvimos una matriz. 313 00:14:32,590 --> 00:14:37,110 Si desea varias copias de algo, ¿por qué no limpiamos todo esto 314 00:14:37,110 --> 00:14:39,540 y simplemente decir, dame array llamado nombres? 315 00:14:39,540 --> 00:14:41,640 >> Y por ahora, vamos a codificar 3. 316 00:14:41,640 --> 00:14:44,450 Y luego me dan otra matriz llamado casas, y me dejó para 317 00:14:44,450 --> 00:14:45,800 ahora codificar 3. 318 00:14:45,800 --> 00:14:49,220 Y yo he limpiado masivamente la desastre que acabo de crear. 319 00:14:49,220 --> 00:14:52,400 Ahora, he todavía no modificable 3, pero aún el 3 podría venir de la dinámica 320 00:14:52,400 --> 00:14:54,350 usuario, o argv, o similares. 321 00:14:54,350 --> 00:14:55,720 Así que esto ya es más limpio. 322 00:14:55,720 --> 00:15:00,100 >> Pero lo que es molesto sobre esto es que Ahora, a pesar de que el nombre es de alguna manera 323 00:15:00,100 --> 00:15:02,280 fundamentalmente vinculados a la casa de un estudiante - 324 00:15:02,280 --> 00:15:04,720 es un estudiante que realmente quiere representar - 325 00:15:04,720 --> 00:15:08,080 Ahora tengo dos matrices que son paralelas en el sentido de que son la 326 00:15:08,080 --> 00:15:13,930 soporte de mismo tamaño y nombre 0 presumiblemente mapas para casas soporte 0, 327 00:15:13,930 --> 00:15:16,600 y los nombres de Soporte 1 mapas a las casas de soporte 1. 328 00:15:16,600 --> 00:15:19,280 En otras palabras, el estudiante vive en esa casa, y que otro estudiante 329 00:15:19,280 --> 00:15:20,530 vive en la otra casa. 330 00:15:20,530 --> 00:15:23,720 Pero seguro que esto podría ser hecho aún más limpiamente. 331 00:15:23,720 --> 00:15:24,990 >> Bueno, es posible, de hecho. 332 00:15:24,990 --> 00:15:28,730 Y déjame seguir adelante y abrir hasta structs.h, y usted 333 00:15:28,730 --> 00:15:31,130 ver esta idea aquí. 334 00:15:31,130 --> 00:15:34,905 Fíjate que he usado typedef, a medida que aludido hace un momento para declarar nuestra 335 00:15:34,905 --> 00:15:35,570 propio tipo de datos. 336 00:15:35,570 --> 00:15:39,660 Pero también estoy usando esta otra palabra clave llamada struct que me da una nueva 337 00:15:39,660 --> 00:15:40,790 estructura de datos. 338 00:15:40,790 --> 00:15:43,980 >> Y esta estructura de datos Reclamo va tener dos cosas en el interior de 339 00:15:43,980 --> 00:15:47,060 - una cadena llamado nombre, y una cadena llama casa. 340 00:15:47,060 --> 00:15:49,820 Y el nombre que voy a dar a esta estructura de datos se va 341 00:15:49,820 --> 00:15:51,005 para ser llamado de los estudiantes. 342 00:15:51,005 --> 00:15:54,030 Yo podría llamarlo lo que quiera, pero esto semánticamente hacer 343 00:15:54,030 --> 00:15:55,810 sentido para mí en mi mente. 344 00:15:55,810 --> 00:15:59,160 >> Así que ahora, si abro una versión mejor del programa que empecé a escribir 345 00:15:59,160 --> 00:16:00,390 allí, déjame Desplácese hasta la parte superior. 346 00:16:00,390 --> 00:16:03,190 Y hay algunos más líneas de código aquí, pero permítanme centrarme para 347 00:16:03,190 --> 00:16:04,160 el momento en uno. 348 00:16:04,160 --> 00:16:07,790 He declarado una constante llamada a los estudiantes y no modificable 3 por ahora. 349 00:16:07,790 --> 00:16:11,110 Pero ahora, observe lo limpio mi código comienza a conseguir. 350 00:16:11,110 --> 00:16:15,030 >> En la línea 22, declaro gama de estudiantes. 351 00:16:15,030 --> 00:16:18,760 Y note que el estudiante es aparentemente ahora un tipo de datos. 352 00:16:18,760 --> 00:16:23,360 Debido a que en la parte superior de este archivo, notificación He incluido el archivo de cabecera 353 00:16:23,360 --> 00:16:24,820 que llegué hace un momento. 354 00:16:24,820 --> 00:16:28,820 Y ese archivo de cabecera simplemente tenía esta definición de un estudiante. 355 00:16:28,820 --> 00:16:32,470 >> Así que ahora, he creado mi propia datos personalizados escribe que los autores de C año 356 00:16:32,470 --> 00:16:33,890 Hace no pensar de antemano. 357 00:16:33,890 --> 00:16:34,570 Pero no hay problema. 358 00:16:34,570 --> 00:16:35,870 Puedo hacerlo yo mismo. 359 00:16:35,870 --> 00:16:39,050 Así que esto es un arreglo llamado estudiantes, cada uno de cuyos miembros 360 00:16:39,050 --> 00:16:41,100 es una estructura estudiantil. 361 00:16:41,100 --> 00:16:44,270 Y quiero tres de los en la matriz. 362 00:16:44,270 --> 00:16:46,030 >> Y ahora, ¿qué hace el resto de este programa hacer? 363 00:16:46,030 --> 00:16:47,550 Yo necesitaba algo un poco arbitraria. 364 00:16:47,550 --> 00:16:51,450 Así que desde línea 24 en adelante, Iterar de 0 a 3. 365 00:16:51,450 --> 00:16:54,000 Entonces le pido al usuario para el nombre del estudiante. 366 00:16:54,000 --> 00:16:56,110 Y entonces yo uso GetString como antes. 367 00:16:56,110 --> 00:16:59,410 Entonces me pregunto por la casa del estudiante, y utilizo GetString como antes. 368 00:16:59,410 --> 00:17:01,780 >> Pero note - Ligeramente nueva pedazo de sintaxis - 369 00:17:01,780 --> 00:17:07,010 Todavía puede indexar para el estudiante i, pero ¿cómo puedo conseguir a los datos específicos 370 00:17:07,010 --> 00:17:08,354 campo dentro de la estructura? 371 00:17:08,354 --> 00:17:11,770 Bueno, lo que es aparentemente el nueva pieza de la sintaxis? 372 00:17:11,770 --> 00:17:13,339 Es sólo el operador punto. 373 00:17:13,339 --> 00:17:14,510 >> No hemos realmente visto esto antes. 374 00:17:14,510 --> 00:17:17,819 Usted lo ha visto en el conjunto de procesadores cinco si usted tiene buceado en ya con los archivos de mapa de bits. 375 00:17:17,819 --> 00:17:22,372 Pero el punto sólo significa dentro de este campos de struct o múltiples, dan puntos 376 00:17:22,372 --> 00:17:24,510 nombre, o me da la casa de puntos. 377 00:17:24,510 --> 00:17:28,690 Eso significa que van dentro de la estructura y obtener los campos particulares. 378 00:17:28,690 --> 00:17:30,200 >> ¿Qué hace el resto de este programa haga? 379 00:17:30,200 --> 00:17:31,190 No todo es tan sexy. 380 00:17:31,190 --> 00:17:34,640 Nótese que iterar 0-3 otra vez, y simplemente creo una Inglés 381 00:17:34,640 --> 00:17:40,500 frase como fulano de tal está en tal o tal casa, pasando el nombre del punto de 382 00:17:40,500 --> 00:17:43,320 el estudiante y el i-ésimo su casa también. 383 00:17:43,320 --> 00:17:47,560 >> Y luego, por último, ahora vamos a empezar a obtener anal sobre esto, ahora que estamos 384 00:17:47,560 --> 00:17:49,580 familiarizado con lo que malloc y otras funciones han sido 385 00:17:49,580 --> 00:17:50,570 haciendo todo este tiempo. 386 00:17:50,570 --> 00:17:54,220 ¿Por qué tengo que liberar tanto el nombre y de la casa, a pesar de que 387 00:17:54,220 --> 00:17:56,960 no llamar a malloc? 388 00:17:56,960 --> 00:17:58,020 >> GetString hizo. 389 00:17:58,020 --> 00:18:00,930 Y ese fue el pequeño y sucio secreto de varias semanas, pero GetString tiene 390 00:18:00,930 --> 00:18:03,530 estado filtrando la memoria de todo el colocar todo el semestre hasta el momento. 391 00:18:03,530 --> 00:18:05,990 Y Valgrand finalmente revelar esto a nosotros. 392 00:18:05,990 --> 00:18:10,730 >> Pero no es un gran problema, porque sé que simplemente puedo liberar el nombre 393 00:18:10,730 --> 00:18:15,750 y la casa, aunque técnicamente, a ser súper, súper seguro, yo debería ser 394 00:18:15,750 --> 00:18:17,890 haciendo un poco de comprobación de errores aquí. 395 00:18:17,890 --> 00:18:19,040 ¿Cuáles son tus instintos te dicen? 396 00:18:19,040 --> 00:18:22,480 ¿Qué debería ser la comprobación de antes de que yo ¿Qué es un 397 00:18:22,480 --> 00:18:25,470 cadena, también conocido como el que un char *? 398 00:18:25,470 --> 00:18:33,460 >> Realmente debe comprobar si los estudiantes soporte i DOT Nombre no 399 00:18:33,460 --> 00:18:34,840 igual nulo. 400 00:18:34,840 --> 00:18:40,400 Entonces va a estar bien para seguir adelante y libre ese puntero, y el mismo u otro 401 00:18:40,400 --> 00:18:41,160 uno así. 402 00:18:41,160 --> 00:18:46,860 Si los estudiantes ménsula de punteo casa no es igual a null, esto ahora va a proteger 403 00:18:46,860 --> 00:18:52,520 contra la caja de esquina en la que GetString vuelve algo así como nulo. 404 00:18:52,520 --> 00:18:57,310 Y vimos hace un momento, la voluntad printf protegernos aquí con sólo decir 405 00:18:57,310 --> 00:18:58,990 null, lo que se va a parecer raro. 406 00:18:58,990 --> 00:19:02,340 Pero por lo menos no va a segfault, como hemos visto. 407 00:19:02,340 --> 00:19:05,990 >> Bueno, déjame hacer una cosa aquí. estructuras-0 es una especie de un programa estúpido 408 00:19:05,990 --> 00:19:09,700 porque entro todos estos datos, y luego se pierde una vez que termine el programa. 409 00:19:09,700 --> 00:19:10,940 Pero déjame ir adelante y hacer esto. 410 00:19:10,940 --> 00:19:12,830 Quiero dejar el terminal ventana un poco más grande. 411 00:19:12,830 --> 00:19:17,000 Permítanme hacer estructuras-1, que es una nueva versión de éste. 412 00:19:17,000 --> 00:19:18,520 >> Voy a acercar un un poco. 413 00:19:18,520 --> 00:19:21,620 Y ahora déjame correr dot slash estructuras-1. 414 00:19:21,620 --> 00:19:22,590 Nombre del estudiante - 415 00:19:22,590 --> 00:19:31,500 David Mather, hagámoslo Rob Kirkland, hagámoslo Lauren Leverett. 416 00:19:31,500 --> 00:19:33,650 Lo interesante ahora es aviso - 417 00:19:33,650 --> 00:19:35,540 y sólo yo sé porque Yo escribí el programa - 418 00:19:35,540 --> 00:19:38,930 hay un archivo de ahora mi actual directorio llamado students.csv. 419 00:19:38,930 --> 00:19:40,420 Algunos de ustedes se han visto éstos en el mundo real. 420 00:19:40,420 --> 00:19:42,980 >> ¿Qué es un archivo CSV? 421 00:19:42,980 --> 00:19:44,170 Valores separados por comas. 422 00:19:44,170 --> 00:19:46,670 Es algo así como la de un hombre pobre versión de un archivo de Excel. 423 00:19:46,670 --> 00:19:50,580 Es una tabla de filas y columnas que puede abrir en un programa como Excel, 424 00:19:50,580 --> 00:19:51,800 o números en un MAC. 425 00:19:51,800 --> 00:19:55,180 >> Y si abro el archivo aquí en gedit, aviso - y los números no están allí. 426 00:19:55,180 --> 00:19:57,360 Eso es sólo contar gedit me Números de líneas. 427 00:19:57,360 --> 00:19:59,740 Note que en la primera línea de esta archivo es David y Mather. 428 00:19:59,740 --> 00:20:01,450 La siguiente línea es Rob coma Kirkland. 429 00:20:01,450 --> 00:20:04,170 Y la tercera línea es Lauren coma Leverett. 430 00:20:04,170 --> 00:20:05,480 >> Así que lo que he creado? 431 00:20:05,480 --> 00:20:09,580 Ahora que he escrito un programa en C que efectivamente puede generar hojas de cálculo 432 00:20:09,580 --> 00:20:11,840 que se puede abrir en un programa como Excel. 433 00:20:11,840 --> 00:20:15,520 No todo lo que obligar a un conjunto de datos, pero si tiene trozos mucho más grandes de 434 00:20:15,520 --> 00:20:18,440 datos que en realidad quieres manipular y hacer gráficas de y 435 00:20:18,440 --> 00:20:21,260 como, esto es quizás una manera de crear esos datos. 436 00:20:21,260 --> 00:20:25,370 Por otra parte, CSV son en realidad muy común sólo para el almacenamiento de datos simple - 437 00:20:25,370 --> 00:20:28,940 Yahoo Finance, por ejemplo, si usted recibe cotizaciones de bolsa a través de su llamada- 438 00:20:28,940 --> 00:20:33,180 API, el servicio gratuito que le permite conseguir las existencias actuales hasta a la fecha 439 00:20:33,180 --> 00:20:35,650 Presupuestos para empresas, que dar a la parte posterior de datos en el 440 00:20:35,650 --> 00:20:37,800 formato CSV super simple. 441 00:20:37,800 --> 00:20:39,380 >> Entonces, ¿cómo lo hacemos? 442 00:20:39,380 --> 00:20:42,530 Bueno notar, la mayor parte de este programa de casi la misma. 443 00:20:42,530 --> 00:20:46,870 Pero nótese aquí abajo, en lugar de imprimir los estudiantes de fuera, en la línea 35 444 00:20:46,870 --> 00:20:51,040 en adelante, afirmo que estoy ahorrando el estudiantes en el disco, por lo que se guarda un archivo. 445 00:20:51,040 --> 00:20:53,630 >> Entonces noto que estoy declarando un FILE * - 446 00:20:53,630 --> 00:20:57,260 Ahora, esto es una especie de anomalía en C. Por alguna razón, FILE es todo en mayúsculas, 447 00:20:57,260 --> 00:21:00,690 que no es como la mayoría de otros tipos de datos en C. Pero esto es un built-in 448 00:21:00,690 --> 00:21:02,320 tipo de datos, FILE *. 449 00:21:02,320 --> 00:21:05,900 Y estoy declarando un puntero a un archivo, es cómo se puede pensar en eso. 450 00:21:05,900 --> 00:21:08,070 >> fopen significa abrir el archivo. 451 00:21:08,070 --> 00:21:09,470 ¿Qué archivo que desea abrir? 452 00:21:09,470 --> 00:21:12,620 Quiero abrir un archivo que yo quiero arbitrariamente llamar students.csv. 453 00:21:12,620 --> 00:21:14,480 Podría llamar a que cualquier cosa que yo quiera. 454 00:21:14,480 --> 00:21:15,200 >> Y luego tomar una conjetura. 455 00:21:15,200 --> 00:21:18,960 ¿Qué hace el segundo argumento a fopen probablemente significa? 456 00:21:18,960 --> 00:21:21,480 Derecha, w para escritura, podría ser r para lectura. 457 00:21:21,480 --> 00:21:24,120 Hay una para append si desee agregar filas y no 458 00:21:24,120 --> 00:21:25,200 sobrescribir todo el asunto. 459 00:21:25,200 --> 00:21:28,005 >> Pero yo sólo quiero crear este archivo una vez, así que utilizaré comillas w. 460 00:21:28,005 --> 00:21:31,880 Y sé que sólo a partir de haber leído la documentación, o de la página de manual. 461 00:21:31,880 --> 00:21:35,100 Si el archivo no es nulo - en otras palabras, si nada salió mal allí - 462 00:21:35,100 --> 00:21:37,820 permítanme repetir las estudiantes de 0 a 3. 463 00:21:37,820 --> 00:21:40,410 >> Y ahora note que hay algo muy ligeramente diferente 464 00:21:40,410 --> 00:21:42,110 acerca de la línea 41 aquí. 465 00:21:42,110 --> 00:21:42,960 No es printf. 466 00:21:42,960 --> 00:21:46,530 Es fprintf para el archivo de printf. 467 00:21:46,530 --> 00:21:47,790 Así que va a escribir al archivo. 468 00:21:47,790 --> 00:21:48,860 ¿Qué archivo? 469 00:21:48,860 --> 00:21:53,630 Aquel cuyo puntero se especifica como primer argumento. 470 00:21:53,630 --> 00:21:55,940 >> A continuación especificamos una cadena de formato. 471 00:21:55,940 --> 00:21:59,660 A continuación especificamos qué cadena que queremos conecte por primera ciento s, y 472 00:21:59,660 --> 00:22:04,320 a continuación, otra variable o la segunda por ciento s. 473 00:22:04,320 --> 00:22:06,760 Luego cerramos el archivo con fclose. 474 00:22:06,760 --> 00:22:09,380 De lo que liberar la memoria como antes, aunque Debo volver y agregar 475 00:22:09,380 --> 00:22:10,540 algunas comprobaciones para null. 476 00:22:10,540 --> 00:22:12,090 >> Y eso es todo. 477 00:22:12,090 --> 00:22:16,960 fopen, fprintf, fclose me da la capacidad de crear archivos de texto. 478 00:22:16,960 --> 00:22:19,640 Ahora, usted verá en el problema establecido cinco, que consiste en imágenes, que va a utilizar 479 00:22:19,640 --> 00:22:20,990 archivos binarios en lugar. 480 00:22:20,990 --> 00:22:24,200 Pero fundamentalmente, la idea es la misma, a pesar de que las funciones que usted lo va a hacer 481 00:22:24,200 --> 00:22:28,710 ver son un poco diferentes. 482 00:22:28,710 --> 00:22:32,580 >> Así gira torbellino, pero usted recibirá demasiado familiar con el archivo I/O-- 483 00:22:32,580 --> 00:22:34,960 entrada y salida - con el conjunto de procesadores cinco. 484 00:22:34,960 --> 00:22:38,607 Y cualquier pregunta acerca de la fundamentos iniciales aquí? 485 00:22:38,607 --> 00:22:39,857 ¿Sí? 486 00:22:39,857 --> 00:22:41,880 487 00:22:41,880 --> 00:22:43,710 >> ¿Qué pasa si usted trata de liberar a un valor nulo? 488 00:22:43,710 --> 00:22:48,880 Creo que, a no ser libre ha conseguido un poco más fácil de usar, se puede 489 00:22:48,880 --> 00:22:49,890 potencialmente segfault. 490 00:22:49,890 --> 00:22:54,160 Pasando nulo es malo porque no lo hago creer molestias gratuitas para comprobar por ti, 491 00:22:54,160 --> 00:22:57,330 porque sería potencialmente una pérdida de tiempo para que lo haga por sí mismo 492 00:22:57,330 --> 00:22:59,022 todos en el mundo. 493 00:22:59,022 --> 00:23:00,590 Buena pregunta, sin embargo. 494 00:23:00,590 --> 00:23:04,300 >> Muy bien, por lo que este tipo de se nosotros para un tema interesante. 495 00:23:04,300 --> 00:23:07,010 El tema del problema establece cinco es la medicina forense. 496 00:23:07,010 --> 00:23:08,420 Al menos esa es una parte del conjunto de problemas. 497 00:23:08,420 --> 00:23:12,030 Los forenses generalmente se refiere a la recuperación de la información que puede o 498 00:23:12,030 --> 00:23:14,110 No puede haber sido borrado deliberadamente. 499 00:23:14,110 --> 00:23:18,680 Y así que pensé que le daría una rápida muestra de lo que realmente está pasando en todo 500 00:23:18,680 --> 00:23:21,230 esta vez por debajo de la capó de su ordenador. 501 00:23:21,230 --> 00:23:23,960 >> Por ejemplo, si usted tiene dentro de su ordenador portátil o el ordenador de sobremesa un 502 00:23:23,960 --> 00:23:28,040 disco duro, que es ya sea un mecánico dispositivo que en realidad hace girar - 503 00:23:28,040 --> 00:23:31,650 hay cosas circulares llamados platos que se ven muy parecido a lo que 504 00:23:31,650 --> 00:23:34,540 sólo tenía en la pantalla aquí, aunque esto es cada vez más de la vieja escuela. 505 00:23:34,540 --> 00:23:37,370 Se trata de una-y-uno-mitad-pulgada tres disco duro. 506 00:23:37,370 --> 00:23:40,070 Y tres y media pulgadas refiere de con de la cosa cuando lo instale 507 00:23:40,070 --> 00:23:40,890 en un ordenador. 508 00:23:40,890 --> 00:23:44,890 >> Muchos de ustedes en sus ordenadores portátiles ahora tienen unidades de estado sólido, o SSD, 509 00:23:44,890 --> 00:23:46,260 que no tienen partes móviles. 510 00:23:46,260 --> 00:23:49,170 Son más como RAM y menos como estos dispositivos mecánicos. 511 00:23:49,170 --> 00:23:51,450 Pero las ideas siguen siendo las mismas, sin duda en lo que respecta 512 00:23:51,450 --> 00:23:52,790 al problema planteado cinco. 513 00:23:52,790 --> 00:23:57,400 >> Y si lo piensas ahora de un disco duro representa ser un círculo, el cual 514 00:23:57,400 --> 00:23:58,930 Voy a dibujar como esto aquí. 515 00:23:58,930 --> 00:24:02,290 Cuando se crea un archivo en su computadora, si se trata de un SSD, o en 516 00:24:02,290 --> 00:24:06,610 este caso, un viejo disco duro de la escuela, ese archivo comprende múltiples bits. 517 00:24:06,610 --> 00:24:10,510 Digamos que es esto 0 y 1, un montón de 0s y 1s. 518 00:24:10,510 --> 00:24:11,660 Así que este es mi disco duro entero. 519 00:24:11,660 --> 00:24:13,225 Esto es al parecer un archivo bastante grande. 520 00:24:13,225 --> 00:24:18,080 Y está consumiendo el 0 y 1 en ese porción de la fuente física. 521 00:24:18,080 --> 00:24:19,750 >> Bueno, ¿qué es esa parte física? 522 00:24:19,750 --> 00:24:25,310 Bueno, resulta que en un disco duro, al menos de este tipo, hay 523 00:24:25,310 --> 00:24:27,340 estas diminutas partículas magnéticas. 524 00:24:27,340 --> 00:24:32,630 Y ellos tienen esencialmente el norte y sur para ellos, por lo que si usted 525 00:24:32,630 --> 00:24:35,710 convertir una de esas partículas magnéticas de esta manera, se podría decir que se trata de 526 00:24:35,710 --> 00:24:36,720 que representa un 1. 527 00:24:36,720 --> 00:24:39,340 Y si es al revés hacia el sur hasta norte, se podría decir que es 528 00:24:39,340 --> 00:24:40,390 que representa un 0. 529 00:24:40,390 --> 00:24:43,660 >> Así que en el mundo físico real, eso es cómo se puede representar algo en 530 00:24:43,660 --> 00:24:45,670 estado binario del 0 y el 1. 531 00:24:45,670 --> 00:24:46,720 Así que eso es todo un archivo es. 532 00:24:46,720 --> 00:24:49,300 Hay un montón de magnética partículas que son de esta manera o su 533 00:24:49,300 --> 00:24:51,920 De esta forma, los patrones que crean de 0 y 1. 534 00:24:51,920 --> 00:24:56,760 >> Pero resulta que cuando se guarda un archivo, alguna información se guarda por separado. 535 00:24:56,760 --> 00:25:00,000 Así que esta es una pequeña mesa, un directorio, por así decirlo. 536 00:25:00,000 --> 00:25:05,810 Y voy a llamar a este nombre de columna y Voy a llamar a esta ubicación de la columna. 537 00:25:05,810 --> 00:25:08,850 >> Y yo voy a decir, supongamos esta es mi hoja de vida. 538 00:25:08,850 --> 00:25:14,050 Mi resume.doc se almacena a ubicación, digamos 123. 539 00:25:14,050 --> 00:25:15,390 Siempre voy por ese número. 540 00:25:15,390 --> 00:25:18,810 Pero baste decir que al igual que en la memoria RAM, se puede tomar una unidad de disco duro 541 00:25:18,810 --> 00:25:22,350 eso es un gigabyte o 200 gigabytes o de un terabyte, y se puede 542 00:25:22,350 --> 00:25:23,750 numerar todos los bytes. 543 00:25:23,750 --> 00:25:26,480 Puede numerar todos los trozos de 8 bits. 544 00:25:26,480 --> 00:25:29,030 >> Así que vamos a decir que esta es la ubicación 123. 545 00:25:29,030 --> 00:25:32,070 Así que este directorio dentro de mi operación sistema recuerda que mi 546 00:25:32,070 --> 00:25:34,250 hoja de vida es en la ubicación 123. 547 00:25:34,250 --> 00:25:36,850 Pero se pone interesante cuando se elimina un archivo. 548 00:25:36,850 --> 00:25:37,820 >> Así, por ejemplo - 549 00:25:37,820 --> 00:25:40,790 y por suerte, la mayor parte del mundo ha atrapado en esto - ¿qué pasa cuando 550 00:25:40,790 --> 00:25:45,040 arrastra un archivo a la Papelera de Mac OS o su Windows Papelera de reciclaje? 551 00:25:45,040 --> 00:25:48,290 552 00:25:48,290 --> 00:25:50,510 ¿Cuál es el propósito de hacer eso? 553 00:25:50,510 --> 00:25:53,860 Es obvio que es deshacerse de el archivo, pero lo que hace el acto de arrastrar y 554 00:25:53,860 --> 00:25:57,550 caer en la papelera o en su Papelera de reciclaje hacer en un ordenador? 555 00:25:57,550 --> 00:25:59,230 >> Absolutamente nada, de verdad. 556 00:25:59,230 --> 00:26:00,320 Es como una carpeta. 557 00:26:00,320 --> 00:26:01,800 Es una carpeta especial, para estar seguro. 558 00:26:01,800 --> 00:26:04,460 ¿Pero realmente borrar el archivo? 559 00:26:04,460 --> 00:26:06,780 >> Bueno, no, porque algunos de ustedes probablemente han sido, oh maldita sea, no lo hiciste 560 00:26:06,780 --> 00:26:07,420 quise hacer eso. 561 00:26:07,420 --> 00:26:09,130 Así se hace doble clic en el Papelera o la Papelera de reciclaje. 562 00:26:09,130 --> 00:26:11,630 Usted ha hurgó y que se haya recuperado el archivo simplemente arrastrándolo 563 00:26:11,630 --> 00:26:12,110 de ahí. 564 00:26:12,110 --> 00:26:14,420 Así que, claramente, no es necesariamente eliminarlo. 565 00:26:14,420 --> 00:26:15,990 >> Bien, que eres más inteligente que eso. 566 00:26:15,990 --> 00:26:18,860 Usted sabe que sólo arrastrándola a la Trash o Papelera de reciclaje no significa 567 00:26:18,860 --> 00:26:19,930 estás vaciar la papelera. 568 00:26:19,930 --> 00:26:24,110 Así que ir hasta el menú, y usted dice Vaciar papelera o Vaciar Papelera de reciclaje. 569 00:26:24,110 --> 00:26:25,360 Entonces, ¿qué sucede? 570 00:26:25,360 --> 00:26:29,070 571 00:26:29,070 --> 00:26:32,530 >> Sí, por lo que se elimina más. 572 00:26:32,530 --> 00:26:37,660 Pero todo lo que sucede es esto. 573 00:26:37,660 --> 00:26:45,350 El ordenador olvida donde resume.doc era. 574 00:26:45,350 --> 00:26:47,400 >> Pero lo que no ha cambiado aparentemente en la foto? 575 00:26:47,400 --> 00:26:51,390 576 00:26:51,390 --> 00:26:55,570 Los bits, el 0 y 1 que reclamo son en el sitio de algún aspecto físico del 577 00:26:55,570 --> 00:26:56,280 el hardware. 578 00:26:56,280 --> 00:26:57,110 Ellos todavía están allí. 579 00:26:57,110 --> 00:26:58,930 Es sólo el equipo tiene olvidan lo que son. 580 00:26:58,930 --> 00:27:03,160 >> Por lo que es esencialmente liberado del archivo bits de modo que puedan ser reutilizados. 581 00:27:03,160 --> 00:27:06,940 Pero no hasta que se cree más archivos, y más archivos y más archivos se 582 00:27:06,940 --> 00:27:12,150 probabilísticamente, los 0s y 1s, esas partículas magnéticas, se reutilizan, 583 00:27:12,150 --> 00:27:16,220 al revés o boca arriba, para otros archivos, 0s y 1s. 584 00:27:16,220 --> 00:27:17,980 >> Por lo que tiene esta ventana de tiempo. 585 00:27:17,980 --> 00:27:19,860 Y no es de predecible longitud, de verdad. 586 00:27:19,860 --> 00:27:22,240 Depende del tamaño de su disco conducir y la cantidad de archivos que tiene y 587 00:27:22,240 --> 00:27:23,490 la rapidez con que hagas otras nuevas. 588 00:27:23,490 --> 00:27:27,050 Pero hay esta ventana de tiempo durante el que ese archivo es todavía perfectamente 589 00:27:27,050 --> 00:27:27,770 recuperable. 590 00:27:27,770 --> 00:27:31,050 >> Así que si alguna vez utiliza programas como McAfee o Norton para tratar de recuperar 591 00:27:31,050 --> 00:27:35,680 datos, lo único que están haciendo es tratar de recuperar este directorio llamado a 592 00:27:35,680 --> 00:27:37,340 averiguar dónde estaba su archivo. 593 00:27:37,340 --> 00:27:40,605 Y a veces Norton y dirá: archivo es el 93% de reembolso. 594 00:27:40,605 --> 00:27:42,020 Bueno, ¿qué significa eso? 595 00:27:42,020 --> 00:27:45,690 Eso sólo significa que algún otro archivo casualmente terminó usando, por ejemplo, 596 00:27:45,690 --> 00:27:48,920 los bits de su archivo original. 597 00:27:48,920 --> 00:27:51,950 >> Entonces, ¿qué es en realidad involucrados en la recuperación de datos? 598 00:27:51,950 --> 00:27:55,720 Bueno, si usted no tiene algo como Norton preinstalado en el equipo, 599 00:27:55,720 --> 00:27:59,510 el mejor a veces se puede hacer es mirar en todo el disco duro en busca de 600 00:27:59,510 --> 00:28:00,510 los patrones de bits. 601 00:28:00,510 --> 00:28:05,350 Y uno de los temas de la Serie de problemas cinco es que va a buscar el 602 00:28:05,350 --> 00:28:09,570 equivalente a un disco duro, un forense imagen de una tarjeta compact flash de una 603 00:28:09,570 --> 00:28:13,660 cámara digital, la búsqueda de los 0s y 1s que normalmente, con alta 604 00:28:13,660 --> 00:28:16,720 probabilidad, representar a la comenzar de una imagen JPEG. 605 00:28:16,720 --> 00:28:21,120 >> Y ustedes pueden recuperar esas imágenes por asumiendo, si veo a este patrón de 606 00:28:21,120 --> 00:28:24,380 bits en la imagen forense, con alta probabilidad, que las marcas 607 00:28:24,380 --> 00:28:25,650 el inicio de un JPEG. 608 00:28:25,650 --> 00:28:29,520 Y si veo el mismo patrón de nuevo, que probablemente marca el inicio de 609 00:28:29,520 --> 00:28:32,440 otra JPEG, y otro JPEG, JPEG y otro. 610 00:28:32,440 --> 00:28:34,970 Y esto es por lo general la forma de recuperación de datos funcionará. 611 00:28:34,970 --> 00:28:37,870 Lo bueno de los archivos JPEG es a pesar de que el formato de archivo en sí es algo 612 00:28:37,870 --> 00:28:44,400 complejo, el comienzo de cada uno de tales archivo es en realidad bastante identificable 613 00:28:44,400 --> 00:28:47,370 y simple, como se verá, si no tienes ya. 614 00:28:47,370 --> 00:28:50,270 >> Así que vamos a echar un vistazo más de cerca por debajo la capucha en cuanto a exactamente lo que ha sido 615 00:28:50,270 --> 00:28:53,360 pasando, y lo que estos 0s y 1s son, para darle un poco más de un 616 00:28:53,360 --> 00:28:55,330 contexto para este desafío particular. 617 00:28:55,330 --> 00:28:55,510 >> [REPRODUCCIÓN DE VÍDEO] 618 00:28:55,510 --> 00:28:58,700 >> -Cuando sus tiendas de PC más de sus datos permanentes. 619 00:28:58,700 --> 00:29:03,390 Para ello, los datos viajan desde la RAM junto con las señales de software que le dicen 620 00:29:03,390 --> 00:29:06,110 El disco duro de la forma de almacenar los datos. 621 00:29:06,110 --> 00:29:09,410 Los circuitos de disco duro se traducen esas señales en tensión 622 00:29:09,410 --> 00:29:10,870 fluctuaciones. 623 00:29:10,870 --> 00:29:14,970 Estos, a su vez, controlan la unidad de disco partes móviles, algunos de los pocos 624 00:29:14,970 --> 00:29:17,910 partes móviles que quedan en el computadora moderna. 625 00:29:17,910 --> 00:29:22,130 >> Algunas de las señales de control de un motor que gira bandejas recubiertas de metal. 626 00:29:22,130 --> 00:29:25,470 Sus datos se almacenan en realidad en estos platos. 627 00:29:25,470 --> 00:29:28,610 Otras señales se mueven la lectura / escritura cabezas para leer o 628 00:29:28,610 --> 00:29:30,710 escribir datos en los discos. 629 00:29:30,710 --> 00:29:35,450 Esta maquinaria tan precisa que un ser humano pelo ni siquiera podía pasar entre el 630 00:29:35,450 --> 00:29:37,280 cabezas y platos giratorios. 631 00:29:37,280 --> 00:29:40,316 Sin embargo, todo funciona a velocidades fenomenales. 632 00:29:40,316 --> 00:29:40,660 >> [VIDEO PLAYBACK FIN] 633 00:29:40,660 --> 00:29:42,190 >> DAVID MALAN: Zoom en una pequeña profundizar ahora en lo que es 634 00:29:42,190 --> 00:29:44,360 en realidad en los platos. 635 00:29:44,360 --> 00:29:44,720 >> [REPRODUCCIÓN DE VÍDEO] 636 00:29:44,720 --> 00:29:47,660 >> -Echemos un vistazo a lo que acabamos de vio en cámara lenta. 637 00:29:47,660 --> 00:29:51,710 Cuando un breve pulso de electricidad es enviado a la cabeza de lectura / escritura, si volteretas 638 00:29:51,710 --> 00:29:54,650 en una pequeña electromagnética para de una fracción de segundo. 639 00:29:54,650 --> 00:29:58,970 El imán crea un campo, el cual cambia la polaridad de una pequeña, pequeña 640 00:29:58,970 --> 00:30:02,850 parte de las partículas de metal que abrigo de cada superficie del disco. 641 00:30:02,850 --> 00:30:05,940 >> Una serie patrón de estos pequeños, áreas cargada-up en el disco 642 00:30:05,940 --> 00:30:08,470 representa un solo bit de los datos en el número binario 643 00:30:08,470 --> 00:30:10,530 sistema utilizado por las computadoras. 644 00:30:10,530 --> 00:30:13,775 Ahora, si la corriente se envía de una manera a través de la cabeza de lectura / escritura, el área 645 00:30:13,775 --> 00:30:15,970 se polariza en una dirección. 646 00:30:15,970 --> 00:30:17,950 Si la corriente se envía en el dirección opuesta, la 647 00:30:17,950 --> 00:30:19,930 polarización se invierte. 648 00:30:19,930 --> 00:30:22,370 >> La manera de obtener los datos desde el disco duro? 649 00:30:22,370 --> 00:30:24,090 Simplemente revertir el proceso. 650 00:30:24,090 --> 00:30:26,550 Así que es que las partículas en el disco que obtener la corriente en el 651 00:30:26,550 --> 00:30:27,960 lectura / escritura de la cabeza en movimiento. 652 00:30:27,960 --> 00:30:30,700 Armar millones de éstos segmentos magnetizados, y 653 00:30:30,700 --> 00:30:32,160 usted tiene un archivo. 654 00:30:32,160 --> 00:30:36,060 >> Ahora, las piezas de un solo archivo puede estar dispersos por toda una unidad de 655 00:30:36,060 --> 00:30:39,970 platos, algo así como el desorden de papeles en su escritorio. 656 00:30:39,970 --> 00:30:43,500 Así que un archivo muy especial hace un seguimiento de dónde está todo. 657 00:30:43,500 --> 00:30:45,985 ¿No te gustaría tener algo así? 658 00:30:45,985 --> 00:30:46,470 >> [VIDEO PLAYBACK FIN] 659 00:30:46,470 --> 00:30:47,820 >> DAVID MALAN: OK, probablemente no. 660 00:30:47,820 --> 00:30:52,070 Entonces, ¿cuántos de ustedes crecí con estos? 661 00:30:52,070 --> 00:30:53,970 Aceptar, por lo que es cada vez menos manos cada año. 662 00:30:53,970 --> 00:30:56,550 Pero me alegro de que esté por lo menos familiarizados con ellos, porque esta y nuestra propia 663 00:30:56,550 --> 00:31:00,520 libro de demostración, por desgracia, se están muriendo muy retardar la muerte aquí de familiaridad. 664 00:31:00,520 --> 00:31:04,010 >> Pero esto es lo que, al menos, de vuelta en la escuela secundaria, el uso se utiliza para copias de seguridad. 665 00:31:04,010 --> 00:31:08,110 Y fue increíble, porque podía almacenar 1,4 megabytes en 666 00:31:08,110 --> 00:31:08,930 Este disco en particular. 667 00:31:08,930 --> 00:31:12,260 Y esta fue la versión de alta densidad, como se indica por la HD, que tiene 668 00:31:12,260 --> 00:31:14,240 es decir antes de los vídeos HD de hoy en día. 669 00:31:14,240 --> 00:31:16,400 >> Densidad estándar fue de 800 kilobytes. 670 00:31:16,400 --> 00:31:18,640 Y antes de eso, había Discos de 400 kilobytes. 671 00:31:18,640 --> 00:31:23,120 Y antes de eso, había 5 y 1/4 discos pulgadas, que eran verdaderas disquete, 672 00:31:23,120 --> 00:31:25,680 y un poco más ancho y más alto que estas cosas aquí. 673 00:31:25,680 --> 00:31:29,150 Pero en realidad se puede ver la llamada aspecto disquete de estos discos. 674 00:31:29,150 --> 00:31:32,630 >> Y funcionalmente, en realidad son bastante similar a los discos duros de al 675 00:31:32,630 --> 00:31:33,570 menos de este tipo. 676 00:31:33,570 --> 00:31:37,270 Una vez más, los SSD en los equipos más nuevos trabajar un poco diferente. 677 00:31:37,270 --> 00:31:41,530 Pero si traslada la pestaña pequeña de metal, en realidad se puede ver un poco de galleta, 678 00:31:41,530 --> 00:31:42,560 o bandejas. 679 00:31:42,560 --> 00:31:43,830 >> No es de metal como éste. 680 00:31:43,830 --> 00:31:46,000 Éste es en realidad algunos más baratos material plástico. 681 00:31:46,000 --> 00:31:46,750 Y usted puede tipo de moverla. 682 00:31:46,750 --> 00:31:50,310 Y has apunté simplemente borrado algunos número de bits o partículas magnéticos 683 00:31:50,310 --> 00:31:51,220 desde este disco. 684 00:31:51,220 --> 00:31:52,710 >> Así que gracias a Dios, no hay nada en él. 685 00:31:52,710 --> 00:31:55,790 Si esa cosa está en el camino - y la tapa sus ojos y los de su vecino - 686 00:31:55,790 --> 00:31:58,865 usted puede clase de sacar esto adelante toda la vaina fuera así. 687 00:31:58,865 --> 00:32:01,900 Pero hay un poco de primavera, así que ten consciente de que con sus ojos. 688 00:32:01,900 --> 00:32:03,620 Así que ahora usted tiene realmente un disquete. 689 00:32:03,620 --> 00:32:07,090 >> Y lo que es notable acerca de este es que en la medida en que este es un 690 00:32:07,090 --> 00:32:10,830 representación a pequeña escala de un mayor disco duro, estas cosas son super, 691 00:32:10,830 --> 00:32:11,590 super simple. 692 00:32:11,590 --> 00:32:15,170 Si se pellizca la parte inferior de la misma, ahora que fuera de esa cosa de metal, y la cáscara 693 00:32:15,170 --> 00:32:20,990 ellos abren, todo lo que hay es dos piezas de fieltro y la llamada disquete 694 00:32:20,990 --> 00:32:22,930 con una pieza de metal en el interior. 695 00:32:22,930 --> 00:32:25,990 >> Y ahí va la mitad de el contenido de mi disco. 696 00:32:25,990 --> 00:32:27,540 Ahí va otro medio de ellos. 697 00:32:27,540 --> 00:32:31,375 Pero eso es todo lo que daba vueltas en el interior de su equipo en antaño. 698 00:32:31,375 --> 00:32:35,220 699 00:32:35,220 --> 00:32:38,310 >> Y además, a poner esto en perspectiva, lo grande que es la mayor parte de su 700 00:32:38,310 --> 00:32:39,560 duros estos días? 701 00:32:39,560 --> 00:32:41,960 702 00:32:41,960 --> 00:32:46,230 500 gigabytes, un terabyte, tal vez en una computadora de escritorio, 2 terabytes, 3 703 00:32:46,230 --> 00:32:47,630 terabytes, 4 terabytes, ¿verdad? 704 00:32:47,630 --> 00:32:52,480 Se trata de un megabyte, más o menos, que ni siquiera puede caber un típico MP3 705 00:32:52,480 --> 00:32:55,310 más en estos días, o algunos archivo de música similar. 706 00:32:55,310 --> 00:32:59,500 >> Así que un pequeño recuerdo para ti hoy, y también para ayudar a contextualizar lo que 707 00:32:59,500 --> 00:33:03,570 vamos a tomar por sentado ahora en el problema planteado cinco. 708 00:33:03,570 --> 00:33:04,820 Así que estos son tuyos para siempre. 709 00:33:04,820 --> 00:33:07,340 710 00:33:07,340 --> 00:33:13,370 Así que permítanme transición a donde será pasar al siguiente conjunto de procesadores también. 711 00:33:13,370 --> 00:33:18,470 Así que ahora hemos establecido esta página para - oh, un par de anuncios de forma rápida. 712 00:33:18,470 --> 00:33:21,730 >> Este viernes, si usted desea unirse CS50 para el almuerzo, ir al lugar de costumbre, 713 00:33:21,730 --> 00:33:23,610 cs50.net/rsvp. 714 00:33:23,610 --> 00:33:25,100 Y proyecto final - 715 00:33:25,100 --> 00:33:28,520 así que por el plan de estudios, hemos publicado la especificación de proyecto fin de carrera ya. 716 00:33:28,520 --> 00:33:31,410 Darse cuenta de que eso no significa que es debido sobre todo pronto. 717 00:33:31,410 --> 00:33:33,990 Ha publicado, en realidad, sólo para obtener Ustedes que piensan al respecto. 718 00:33:33,990 --> 00:33:37,620 Y, en efecto, un super significativa porcentaje de que se aborda 719 00:33:37,620 --> 00:33:40,780 proyectos finales sobre el material que ni siquiera han llegado a la clase, 720 00:33:40,780 --> 00:33:42,730 pero será tan pronto como la próxima semana. 721 00:33:42,730 --> 00:33:45,530 >> Nótese, sin embargo, que la especificación exige un par de componentes diferentes de la 722 00:33:45,530 --> 00:33:46,190 proyecto final. 723 00:33:46,190 --> 00:33:49,590 El primero, en unas pocas semanas, es una pre-propuesta, un correo electrónico bastante informal para 724 00:33:49,590 --> 00:33:52,760 el TF para decirle o qué eres pensando para su proyecto, con 725 00:33:52,760 --> 00:33:53,650 ningún compromiso. 726 00:33:53,650 --> 00:33:56,710 Propuesta será su especial compromiso, diciendo: aquí, esto es lo que 727 00:33:56,710 --> 00:33:57,770 Me gustaría hacer para mi proyecto. 728 00:33:57,770 --> 00:33:58,250 ¿Qué piensa usted? 729 00:33:58,250 --> 00:33:58,650 Demasiado grande? 730 00:33:58,650 --> 00:33:59,145 Demasiado pequeño? 731 00:33:59,145 --> 00:34:00,330 ¿Es manejable? 732 00:34:00,330 --> 00:34:02,230 Y ves las especificaciones para más detalles. 733 00:34:02,230 --> 00:34:05,060 >> Un par de semanas después de que es el estado informar, que es una forma similar 734 00:34:05,060 --> 00:34:08,260 email informal a tu TF decir cuán muy por detrás de usted está en su final, 735 00:34:08,260 --> 00:34:12,360 aplicación de proyecto, seguido por el CS50 Hackathon a la que todos 736 00:34:12,360 --> 00:34:17,520 es invitado, que será un evento de 20:00 en una noche hasta las 7:00 737 00:34:17,520 --> 00:34:19,150 AM de la mañana siguiente. 738 00:34:19,150 --> 00:34:22,560 Pizza, como yo lo he dicho en semanas cero, wil ser servido a las 9:00 PM, 739 00:34:22,560 --> 00:34:24,120 Comida china a las 1:00 PM. 740 00:34:24,120 --> 00:34:27,929 Y si usted todavía está despierto a las 5:00 de la mañana, lo llevaremos a IHOP para el desayuno. 741 00:34:27,929 --> 00:34:31,310 >> Así que la Hackathón es uno de los más experiencias memorables en la clase. 742 00:34:31,310 --> 00:34:35,290 A continuación, la aplicación se debe, y entonces el clímax Feria CS50. 743 00:34:35,290 --> 00:34:38,070 Más detalles sobre todas estas en las semanas venideras. 744 00:34:38,070 --> 00:34:40,739 >> Pero volvamos a algo vieja escuela - 745 00:34:40,739 --> 00:34:41,920 de nuevo, una matriz. 746 00:34:41,920 --> 00:34:45,040 Así que una serie estaba muy bien, ya que resuelve problemas como vimos sólo un 747 00:34:45,040 --> 00:34:49,290 Hace momento con estructuras estudiantiles poniendo un poco fuera de control si 748 00:34:49,290 --> 00:34:52,405 quiero tener un estudiante, estudiante dos, estudiante tres, dot dot dot estudiante, 749 00:34:52,405 --> 00:34:54,400 un número arbitrario de los estudiantes. 750 00:34:54,400 --> 00:34:58,850 >> Así matrices, hace unas semanas, se abalanzaron y resuelto todos nuestros problemas de la no 751 00:34:58,850 --> 00:35:03,340 sabiendo de antemano la cantidad de cosas de algún tipo puede ser que deseemos. 752 00:35:03,340 --> 00:35:07,390 Y hemos visto que las estructuras pueden ayudarnos organizar mejor nuestro código y mantener 753 00:35:07,390 --> 00:35:11,660 las variables conceptualmente similares, como un nombre y una casa, juntos, por lo que 754 00:35:11,660 --> 00:35:15,570 puede tratar como una sola entidad, en el interior de los cuales hay piezas más pequeñas. 755 00:35:15,570 --> 00:35:17,810 >> Pero matrices tienen algunas desventajas. 756 00:35:17,810 --> 00:35:19,780 ¿Cuáles son algunas de las desventajas nos hemos encontrado 757 00:35:19,780 --> 00:35:22,320 con matrices hasta el momento? 758 00:35:22,320 --> 00:35:23,450 ¿Qué es eso? 759 00:35:23,450 --> 00:35:28,130 Tamaño fijo - por lo que a pesar de que usted puede ser ser capaz de asignar memoria para una 760 00:35:28,130 --> 00:35:32,310 matriz, una vez que sabes cómo muchos estudiantes que tiene, cuántos caracteres tiene 761 00:35:32,310 --> 00:35:35,460 desde el usuario, una vez que ha asignado la matriz, has clase de pintadas 762 00:35:35,460 --> 00:35:36,740 a ti mismo en una esquina. 763 00:35:36,740 --> 00:35:40,600 >> Porque no se puede insertar nuevos elementos en el centro de una matriz. 764 00:35:40,600 --> 00:35:43,660 No se puede insertar más elementos al final de una matriz. 765 00:35:43,660 --> 00:35:47,750 Realmente, usted tiene que recurrir a la creación de un nueva gama, como hemos comentado, 766 00:35:47,750 --> 00:35:49,320 copiando lo viejo a lo nuevo. 767 00:35:49,320 --> 00:35:52,610 Y de nuevo, que es el dolor de cabeza que GetString ofertas por usted. 768 00:35:52,610 --> 00:35:56,170 >> Pero, de nuevo, ni siquiera se puede insertar algo en el centro de la matriz 769 00:35:56,170 --> 00:35:58,200 si la tasa no está totalmente llena. 770 00:35:58,200 --> 00:36:03,010 Por ejemplo, si esta matriz aquí de tamaño seis sólo tiene cinco cosas en ella, 771 00:36:03,010 --> 00:36:06,080 así, usted podría virar algo en el extremo. 772 00:36:06,080 --> 00:36:08,200 Pero lo que si desea insertar algo en el medio de la 773 00:36:08,200 --> 00:36:11,280 matriz, a pesar de que podría tener cinco de los seis que hay en él? 774 00:36:11,280 --> 00:36:14,250 >> Bueno, ¿qué podemos hacer cuando teníamos todo de nuestros voluntarios humanos en el escenario 775 00:36:14,250 --> 00:36:15,110 semana pasado? 776 00:36:15,110 --> 00:36:18,710 Si quisiéramos poner a alguien aquí, tampoco estas personas cómo mover este 777 00:36:18,710 --> 00:36:22,540 manera, o esta gente cómo mover este manera, y que se convirtieron caro. 778 00:36:22,540 --> 00:36:26,950 El desplazamiento de personas en el interior de un array terminó sumando y costeo 779 00:36:26,950 --> 00:36:31,240 nosotros tiempo, por lo tanto, gran parte de nuestro n al cuadrado veces corriendo como la ordenación por inserción, por 780 00:36:31,240 --> 00:36:32,550 ejemplo, en el peor de los casos. 781 00:36:32,550 --> 00:36:36,520 Así que las matrices son grandes, pero hay que sabe de antemano el tamaño que desee. 782 00:36:36,520 --> 00:36:38,030 >> Así que bien, aquí está la solución. 783 00:36:38,030 --> 00:36:43,860 Si no sé de antemano cuántos estudiantes que puedan tener, y sé una vez 784 00:36:43,860 --> 00:36:47,870 Yo decido, sin embargo, me tengo que quedar con esa muchos estudiantes, ¿por qué no acabo de siempre 785 00:36:47,870 --> 00:36:51,740 asignar el doble de espacio como yo podría pensar que necesito? 786 00:36:51,740 --> 00:36:54,450 ¿No es una solución razonable? 787 00:36:54,450 --> 00:36:58,240 >> Siendo realistas, no creo que estemos Va a necesitar más de 50 ranuras 788 00:36:58,240 --> 00:37:02,190 en un arreglo para una clase de tamaño mediano, así que vamos a redondear hacia arriba. 789 00:37:02,190 --> 00:37:07,040 Voy a hacer 100 slots en mi matriz, sólo por lo que definitivamente podemos obtener la 790 00:37:07,040 --> 00:37:10,330 número de estudiantes que espero estar en alguna clase de mediano tamaño. 791 00:37:10,330 --> 00:37:14,320 Así que ¿por qué no reunir y asignar más memoria, por lo general, para una matriz 792 00:37:14,320 --> 00:37:16,290 de lo que cree que incluso podría necesitar? 793 00:37:16,290 --> 00:37:20,190 ¿Cuál es esta simple retroceso a esa idea? 794 00:37:20,190 --> 00:37:21,440 >> Estás perdiendo la memoria. 795 00:37:21,440 --> 00:37:25,350 Literalmente, cada programa se escribe a continuación es tal vez el uso del doble de memoria que 796 00:37:25,350 --> 00:37:26,680 que realmente necesita. 797 00:37:26,680 --> 00:37:28,990 Y eso simplemente no se siente como un solución particularmente elegante. 798 00:37:28,990 --> 00:37:31,990 Por otra parte, sólo disminuye la probabilidad de que un problema. 799 00:37:31,990 --> 00:37:35,300 Si le sucede que tiene un curso muy popular un semestre y tiene 101 800 00:37:35,300 --> 00:37:39,610 estudiantes, el programa sigue siendo enfrenta fundamentalmente el mismo problema. 801 00:37:39,610 --> 00:37:44,280 >> Así que por suerte, hay una solución a anuncio a todos nuestros problemas en la forma 802 00:37:44,280 --> 00:37:46,790 de estructuras de datos que están más complejos que los 803 00:37:46,790 --> 00:37:47,970 que hemos visto hasta el momento. 804 00:37:47,970 --> 00:37:50,530 Esto, afirmo, es una lista enlazada. 805 00:37:50,530 --> 00:37:51,920 Esta es una lista de los números - 806 00:37:51,920 --> 00:37:54,970 9, 17, 22, 26, y 34 - 807 00:37:54,970 --> 00:38:00,120 que han sido unidas entre sí por medio de lo que he dibujado como flechas. 808 00:38:00,120 --> 00:38:03,580 >> En otras palabras, si yo quería representar una matriz, que podría hacer 809 00:38:03,580 --> 00:38:04,910 algo como esto. 810 00:38:04,910 --> 00:38:07,310 Y voy a poner esto en la cabeza en un momento. 811 00:38:07,310 --> 00:38:09,970 Que podía hacer - 812 00:38:09,970 --> 00:38:12,520 hola, muy bien. 813 00:38:12,520 --> 00:38:14,470 En espera. 814 00:38:14,470 --> 00:38:17,360 Equipo nuevo aquí, claro - 815 00:38:17,360 --> 00:38:18,090 Está bien. 816 00:38:18,090 --> 00:38:21,730 >> Así que si tengo estos números en orden de batalla - 817 00:38:21,730 --> 00:38:28,880 9, 17, 22, 26, 24 - 818 00:38:28,880 --> 00:38:30,530 no necesariamente a escala. 819 00:38:30,530 --> 00:38:33,730 Muy bien, así que aquí está mi serie - 820 00:38:33,730 --> 00:38:34,980 Oh, Dios mío. 821 00:38:34,980 --> 00:38:38,700 822 00:38:38,700 --> 00:38:40,395 Muy bien, así que aquí está mi matriz. 823 00:38:40,395 --> 00:38:44,110 824 00:38:44,110 --> 00:38:45,050 Oh, Dios mío. 825 00:38:45,050 --> 00:38:48,820 >> [Risas] 826 00:38:48,820 --> 00:38:49,440 >> DAVID MALAN: Pretend. 827 00:38:49,440 --> 00:38:52,330 Es demasiado esfuerzo para volver y arreglar eso, por lo que - 828 00:38:52,330 --> 00:38:54,290 26. 829 00:38:54,290 --> 00:38:57,650 Así que tenemos este conjunto de 9, 17, 22, 26 y 34. 830 00:38:57,650 --> 00:39:00,260 Para aquellos de ustedes puede ver el error vergonzoso que acabo de hacer, 831 00:39:00,260 --> 00:39:00,830 ahí está. 832 00:39:00,830 --> 00:39:04,490 >> Así que yo sostengo que este es un solución muy eficiente. 833 00:39:04,490 --> 00:39:07,310 He asignan tantos enteros como Necesito - uno, dos, tres, 834 00:39:07,310 --> 00:39:09,100 cuatro, cinco, o seis - 835 00:39:09,100 --> 00:39:11,660 y luego me he guardado los números dentro de esta matriz. 836 00:39:11,660 --> 00:39:15,220 Pero supongamos que, entonces, quiero insertar un valor como el número 8? 837 00:39:15,220 --> 00:39:16,100 Bueno, ¿a dónde va? 838 00:39:16,100 --> 00:39:18,530 Supongamos que quiero insertar un número como 20. 839 00:39:18,530 --> 00:39:19,790 Bueno, ¿a dónde va? 840 00:39:19,790 --> 00:39:23,160 En algún lugar en el medio, o el número 35 tiene que ir 841 00:39:23,160 --> 00:39:24,010 en algún lugar en el extremo. 842 00:39:24,010 --> 00:39:25,320 Pero me he quedado sin espacio. 843 00:39:25,320 --> 00:39:29,120 >> Y así, este es un reto fundamental de matrices que no son la solución. 844 00:39:29,120 --> 00:39:32,280 Afirmé hace un momento, GetString soluciona este problema. 845 00:39:32,280 --> 00:39:37,380 Si desea insertar un sexto número en esta matriz, lo que es al menos un 846 00:39:37,380 --> 00:39:40,090 solución que usted puede recurrir a ciencia cierta, al igual que hacemos con GetString? 847 00:39:40,090 --> 00:39:44,340 848 00:39:44,340 --> 00:39:46,030 ¿Qué es eso? 849 00:39:46,030 --> 00:39:48,190 >> Bueno, hacerlo más grande se más fácil de decir que de hacer. 850 00:39:48,190 --> 00:39:52,810 No podemos necesariamente que la matriz más grande, pero ¿qué podemos hacer? 851 00:39:52,810 --> 00:39:56,570 Hacer una nueva matriz que es más grande, de tamaño 6, o tal vez el tamaño de 10, si queremos 852 00:39:56,570 --> 00:40:00,490 para adelantarse a las cosas, y luego copiar la antigua matriz en la nueva, y luego 853 00:40:00,490 --> 00:40:01,680 liberar la matriz de edad. 854 00:40:01,680 --> 00:40:05,770 >> Pero ¿cuál es el tiempo de ejecución ahora de ese proceso? 855 00:40:05,770 --> 00:40:09,870 Es gran O de n, debido a que la copia va a costar algunas unidades de 856 00:40:09,870 --> 00:40:13,480 tiempo, así que no es tan ideal si tenemos que asignar una nueva variedad, que va 857 00:40:13,480 --> 00:40:15,610 para consumir el doble de memoria temporalmente. 858 00:40:15,610 --> 00:40:16,660 Copie viejo en nuevo - 859 00:40:16,660 --> 00:40:18,800 Quiero decir, es sólo un dolor de cabeza, que es, de nuevo, ¿por qué escribimos 860 00:40:18,800 --> 00:40:19,920 GetString para usted. 861 00:40:19,920 --> 00:40:21,380 >> Así que ¿qué podemos hacer en su lugar? 862 00:40:21,380 --> 00:40:25,000 Bueno, ¿y si nuestra estructura de datos en realidad tiene lagunas en ella? 863 00:40:25,000 --> 00:40:30,790 Supongamos que me relajo mi meta de tener trozos contiguos de memoria, donde 9 864 00:40:30,790 --> 00:40:34,500 está justo al lado de 17, que es justo al lado 22, y así sucesivamente. 865 00:40:34,500 --> 00:40:39,570 >> Y supongamos que el 9 puede ser aquí en RAM, y 17 pueden ser aquí en la memoria RAM, 866 00:40:39,570 --> 00:40:40,990 y 22 pueden estar aquí en la RAM. 867 00:40:40,990 --> 00:40:43,610 En otras palabras, yo no los necesito incluso espalda con espalda más. 868 00:40:43,610 --> 00:40:47,850 Sólo tengo que enhebrar una aguja de alguna manera a través de cada uno de estos números, o cada uno 869 00:40:47,850 --> 00:40:51,010 de estos nodos, ya que vamos a llamar la rectángulos como yo los he dibujado, a 870 00:40:51,010 --> 00:40:55,670 recordar cómo llegar a la última tales nodo de la primera. 871 00:40:55,670 --> 00:40:59,940 >> Entonces, ¿cuál es la construcción de programación que hemos visto hace poco tiempo con el que 872 00:40:59,940 --> 00:41:03,030 puede implementar ese hilo, o dibujado aquí, con la que puedo 873 00:41:03,030 --> 00:41:05,430 aplicar esas flechas? 874 00:41:05,430 --> 00:41:06,500 Así punteros, ¿verdad? 875 00:41:06,500 --> 00:41:09,560 Si asigno no sólo una int, pero un nodo - y por 876 00:41:09,560 --> 00:41:10,810 nodo, me refiero sólo a contenedor. 877 00:41:10,810 --> 00:41:12,900 Y visualmente, me refiero a un rectángulo. 878 00:41:12,900 --> 00:41:16,420 Por lo tanto un nodo aparentemente necesita para contener dos valores - 879 00:41:16,420 --> 00:41:21,490 el int sí mismo, y luego, como se deduce de la mitad inferior del rectángulo, 880 00:41:21,490 --> 00:41:23,010 espacio suficiente para un int. 881 00:41:23,010 --> 00:41:26,130 >> Así que pensar en el futuro aquí, lo grande que es este nodo, este 882 00:41:26,130 --> 00:41:27,170 contenedor de que se trate? 883 00:41:27,170 --> 00:41:29,250 ¿Cuántos bytes para la int? 884 00:41:29,250 --> 00:41:31,310 Presumiblemente 4, si es la misma, como de costumbre. 885 00:41:31,310 --> 00:41:33,270 Y entonces la cantidad de bytes para el puntero? 886 00:41:33,270 --> 00:41:33,650 4. 887 00:41:33,650 --> 00:41:37,940 Así que este contenedor o este nodo, es va a ser una estructura de 8 bytes. 888 00:41:37,940 --> 00:41:41,760 Ah, y eso es una feliz coincidencia que hemos introducido esta noción de 889 00:41:41,760 --> 00:41:44,400 una estructura o una estructura de C. 890 00:41:44,400 --> 00:41:48,890 >> Así que yo sostengo que quiero dar un paso hacia este más sofisticado 891 00:41:48,890 --> 00:41:52,560 aplicación de una lista de números, una lista de números vinculados, tengo que hacer una 892 00:41:52,560 --> 00:41:56,920 poco más pensando en la delantera y declarar no sólo un int, pero una estructura 893 00:41:56,920 --> 00:41:58,620 que voy a llamar, convencionalmente aquí, el nodo. 894 00:41:58,620 --> 00:42:01,630 Podríamos llamarlo lo que queramos, pero nodo va a ser temática en un montón 895 00:42:01,630 --> 00:42:03,560 de las cosas que empezamos a mirar ahora. 896 00:42:03,560 --> 00:42:06,480 >> Dentro de ese nodo es un entero n. 897 00:42:06,480 --> 00:42:09,350 Y luego esta sintaxis, un poco extraño a primera vista - 898 00:42:09,350 --> 00:42:12,960 struct nodo * siguiente. 899 00:42:12,960 --> 00:42:16,900 Bueno pictóricamente, ¿qué es eso? 900 00:42:16,900 --> 00:42:21,000 Esa es la mitad inferior de el rectángulo que vimos 901 00:42:21,000 --> 00:42:22,730 hace un momento. 902 00:42:22,730 --> 00:42:27,600 >> Pero ¿por qué estoy diciendo struct nodo * en contraposición a nodo sólo *? 903 00:42:27,600 --> 00:42:31,370 Porque si ese puntero apunte en otro nodo, es sólo la 904 00:42:31,370 --> 00:42:32,760 dirección de un nodo. 905 00:42:32,760 --> 00:42:35,630 Eso es coherente con lo que hemos discutido acerca de los punteros hasta el momento. 906 00:42:35,630 --> 00:42:39,690 ¿Pero por qué, si puedo reclamar esta estructura es llamado nodo, ¿tengo que decir struct 907 00:42:39,690 --> 00:42:42,660 nodo aquí dentro? 908 00:42:42,660 --> 00:42:43,190 >> Exactamente. 909 00:42:43,190 --> 00:42:46,490 Es una especie de una realidad estúpida de C. La definición de tipos, por así decirlo, no tiene 910 00:42:46,490 --> 00:42:47,220 sucedido todavía. 911 00:42:47,220 --> 00:42:48,510 C es muy literal. 912 00:42:48,510 --> 00:42:51,050 Se lee el código en la parte superior abajo, de izquierda a derecha. 913 00:42:51,050 --> 00:42:54,930 Y hasta que llegue a ese punto y coma en la línea de fondo, supongo que lo que no funciona 914 00:42:54,930 --> 00:42:57,590 existir como un tipo de datos? 915 00:42:57,590 --> 00:42:59,060 Nodo, nodo, entre comillas. 916 00:42:59,060 --> 00:43:03,050 >> Pero debido a la más detallado declaración que hice en la primera línea - 917 00:43:03,050 --> 00:43:05,340 typedef struct node - 918 00:43:05,340 --> 00:43:08,790 porque eso fue primero, antes de que el llaves, eso es algo así como 919 00:43:08,790 --> 00:43:11,800 pre-educar Clang eso, saber qué, dame una estructura 920 00:43:11,800 --> 00:43:13,570 llamado nodo de estructura. 921 00:43:13,570 --> 00:43:16,270 Francamente, no me gusta llamar a las cosas struct nodo, struct nodo todo 922 00:43:16,270 --> 00:43:17,090 a través de mi código. 923 00:43:17,090 --> 00:43:20,660 Pero yo sólo voy a usar una vez, justo en el interior, para que yo pueda efectivamente 924 00:43:20,660 --> 00:43:25,010 crear una especie de referencia circular, no un puntero a mí mismo por sí mismo, sino un 925 00:43:25,010 --> 00:43:29,400 puntero a otro de un tipo idéntico. 926 00:43:29,400 --> 00:43:32,330 >> Así resulta que en una estructura de datos así, hay unos cuantos 927 00:43:32,330 --> 00:43:34,470 operaciones que podrían ser de interés para nosotros. 928 00:43:34,470 --> 00:43:37,460 Podríamos querer insertar en una lista como esta. 929 00:43:37,460 --> 00:43:39,850 Podríamos querer eliminar a partir de una lista como esta. 930 00:43:39,850 --> 00:43:43,490 Podríamos querer buscar en la lista de valor, o más generalmente, de la poligonal. 931 00:43:43,490 --> 00:43:46,410 Y travesía es sólo una forma elegante de diciendo comienzo a la izquierda y seguir todo 932 00:43:46,410 --> 00:43:47,650 el camino a la derecha. 933 00:43:47,650 --> 00:43:52,640 >> Y noten, incluso con este un poco más estructura de datos sofisticada, y mucho 934 00:43:52,640 --> 00:43:56,510 yo propongo que podamos pedir prestado un poco de las ideas de las últimas dos semanas y 935 00:43:56,510 --> 00:43:58,410 implementar una función llamada buscar así. 936 00:43:58,410 --> 00:44:01,360 Se va a devolver true o falsa, lo que indica, sí o 937 00:44:01,360 --> 00:44:03,390 No, n está en la lista. 938 00:44:03,390 --> 00:44:05,960 Su segundo argumento es un puntero a la propia lista, por lo que un 939 00:44:05,960 --> 00:44:07,920 puntero a un nodo. 940 00:44:07,920 --> 00:44:10,350 >> Todo lo que voy a hacer es declarar a continuación, una variable temporal. 941 00:44:10,350 --> 00:44:12,730 Lo llamaremos ptr por convención, para el puntero. 942 00:44:12,730 --> 00:44:15,220 Y yo asigno igual a la principio de la lista. 943 00:44:15,220 --> 00:44:16,680 >> Y ahora fíjense el bucle while. 944 00:44:16,680 --> 00:44:20,640 Mientras puntero no es igual null, voy a comprobar. 945 00:44:20,640 --> 00:44:24,520 Es puntero de flecha n igual a la n que fue aprobada en? 946 00:44:24,520 --> 00:44:26,410 Y espera un minuto - nuevo pedazo de sintaxis. 947 00:44:26,410 --> 00:44:29,324 ¿Cuál es la flecha, de repente? 948 00:44:29,324 --> 00:44:30,574 ¿Sí? 949 00:44:30,574 --> 00:44:34,200 950 00:44:34,200 --> 00:44:34,810 >> Exactamente. 951 00:44:34,810 --> 00:44:38,860 Así, mientras hace unos minutos, se utilizó la notación de puntos para acceder a algo 952 00:44:38,860 --> 00:44:43,080 en el interior de un la estructura, si la variable que tienen no es la estructura 953 00:44:43,080 --> 00:44:47,420 en sí, sino un puntero a una estructura, por suerte, un pedazo de sintaxis que 954 00:44:47,420 --> 00:44:48,620 finalmente tiene sentido intuitivo. 955 00:44:48,620 --> 00:44:52,360 La flecha significa seguir el puntero, como nuestras flechas normalmente significan 956 00:44:52,360 --> 00:44:56,570 gráficamente, e ir a campo de datos en el interior. 957 00:44:56,570 --> 00:44:59,700 Así que la flecha es la misma cosa que punto, pero lo usa cuando se tiene un puntero. 958 00:44:59,700 --> 00:45:05,270 >> Así que para resumir a continuación, si el campo n interior de la estructura llamada puntero 959 00:45:05,270 --> 00:45:07,760 es igual a es igual a n, devolver true. 960 00:45:07,760 --> 00:45:11,970 De lo contrario, esta línea aquí - puntero es igual a puntero siguiente. 961 00:45:11,970 --> 00:45:17,540 Entonces, ¿qué está haciendo esto, aviso, es que si yo actualmente estoy apuntando a la estructura 962 00:45:17,540 --> 00:45:21,430 que contiene 9, y 9 no es el número Busco - Supongo que estoy buscando 963 00:45:21,430 --> 00:45:22,830 para n igual a 50 - 964 00:45:22,830 --> 00:45:25,930 Voy a actualizar mi puntero temporal al no señalar en este nodo 965 00:45:25,930 --> 00:45:31,190 más, pero puntero de flecha al lado, que se va a poner yo aquí. 966 00:45:31,190 --> 00:45:34,270 >> Ahora, me di cuenta es un torbellino introducción. 967 00:45:34,270 --> 00:45:37,380 El miércoles, en realidad vamos a hacer esto con algunos seres humanos y con un poco más 968 00:45:37,380 --> 00:45:38,900 código a un ritmo más lento. 969 00:45:38,900 --> 00:45:42,990 Pero damos cuenta, ahora estamos haciendo nuestros datos estructuras más complejas para que nuestro 970 00:45:42,990 --> 00:45:45,780 Los algoritmos pueden ser más eficientes, lo que va a ser requisito para 971 00:45:45,780 --> 00:45:50,500 pset seis, cuando cargamos en, de nuevo, los 150.000 palabras, pero deberá hacerlo 972 00:45:50,500 --> 00:45:55,650 de manera eficiente, y lo ideal es crear un programa que se ejecuta para nuestros usuarios que no están en 973 00:45:55,650 --> 00:46:00,460 lineal, no en n al cuadrado, pero en constante de tiempo, en el ideal. 974 00:46:00,460 --> 00:46:02,300 >> Nos vemos el miércoles. 975 00:46:02,300 --> 00:46:07,240 >> ALTAVOZ: En la próxima CS50, David olvida su caso base. 976 00:46:07,240 --> 00:46:12,770 >> DAVID MALAN: Y esa es la forma de enviar mensajes de texto con C. Lo que el - 977 00:46:12,770 --> 00:46:14,020 >> [MENSAJE DE TEXTO VARIOS NOTIFICACIÓN SOUNDS] 978 00:46:14,020 --> 00:46:19,734