[REPRODUCCIÓN DE MÚSICA] DAVID J. MALAN: Muy bien. [Risas] Bienvenido de nuevo. Este es CS50. Y este el final de la quinta semana. Y hasta ahora, tenemos más o menos estado tomando por sentado que hay existe este compilador, Clang, que has se invoca a través de esta otra herramienta llamada Haga que de alguna manera mágicamente convierte el código fuente en código objeto, los ceros y unos que los equipos de la CPU, centrales unidad de procesamiento, en realidad entiende. Pero resulta que hay un número que es pasando por debajo de la campana en entre entrada y salida. Y me gustaría proponer que la carne que en un poco más detalle en estos cuatro pasos, tienen algo llamado pre-procesamiento, algo Llamamos la compilación, lo que hemos visto, algo que se llama el montaje, y algo que se llama de enlace. Así, hasta ahora, en algunos de nuestra programas, hemos tenido incluye agudo. Más recientemente hemos tenido algunos fuerte define para las constantes. Así resulta que las cosas que llevan el prefijo con el símbolo de hash o el símbolo de la libra son pre-procesador directivas. Eso es sólo una forma elegante de decir que es una línea de código que en realidad es convertido en algo más antes de que el ordenador, incluso tratar de convertir su programar en ceros y unos. Por ejemplo, agudo incluye estándar E / S. H, prácticamente sólo significa ir por delante, agarra el contenido de los archivos stdio.h y pegarlas allí mismo. Así que no hay ceros y unos en ese punto todavía. No deja de ser una sustitución. Y eso se hace durante la llamada etapa de pre-procesamiento, cuando se En realidad correr Clang o específicamente Hacer en la mayoría de los casos. Así que todo esto ha estado sucediendo primero de forma automática hasta el momento. Luego viene el paso de compilación. Pero hemos estado muy simplificada compilación. Compilar un programa realmente significa tomarlo de algo así como C, el código fuente que hemos estado escribiendo, abajo a algo llamado montaje. El lenguaje ensamblador es un nivel más bajo lenguaje que, por suerte, no lo haremos tienen muchas ocasiones de escribir este semestre. Pero es en el nivel más bajo de la sentido de que, literalmente, empezar a escribir sumar y restar y multiplicar y cargar de la memoria y guardar en la memoria, el instrucciones muy básicas que un ordenador, debajo de la capucha, realmente entiende. Por último, el montaje tiene ese idioma a los ceros y unos que hemos estado que describe hasta ahora. Y en verdad, por último, hay el llamado fase de vinculación, que vamos a ver en un momento, que combina los ceros y los unos con los ceros y queridos otras personas antes que ha creado. Así que considere esto super simple programa. Fue a partir de la semana 1. Simplemente dijo, Hello World, en la pantalla. Corrimos a través de este Clang. ¿O nos encontramos a través de Make que se desarrolló Clang. Y emitida en el momento donde algunos ceros y unos. Pero resulta que hay un paso intermedio. Si me voy de aquí - ¡Uy, no lo hice quiero verlo todavía. Si voy por aquí a mi aparato y abro hello.c, aquí es ese mismo programa. Y lo que voy a hacer en mi terminal ventana de aquí es que voy a ejecutar Clang en lugar de hacer, lo que automatiza los cuatro los pasos a seguir para nosotros. Y yo voy a hacer ruido metálico-S y entonces hola.c y luego entrar. Y tengo un mensaje parpadeante nuevo, lo que es bueno. Y ahora en una ventana un poco más grande, Voy a abrir gedit aquí. Y voy a abrir un archivo que, Resulta, se llama hello.s este contiene ese lenguaje ensamblador Me he referido antes. Y esto es lo que se llama el montaje idioma, nivel bastante bajo instrucciones que el CPU Intel o lo que sea que hay dentro entiende. Y es para mov movimiento. llamado es para llamando, una función muy bajo nivel. sub es para restar. Así que cuando usted tiene una CPU en particular dentro de su equipo, lo que lo hace distintas, frente a las CPUs de la mercado, es que las instrucciones que entiende y muchas veces lo eficiente que es, lo rápido que es en la ejecución de algunos de esas instrucciones. Ahora para obtener más información, puede tomar siguiente CS61 Otoño en el colegio. Pero aquí tenemos, por ejemplo, unos pocos identificadores que pudieran parecer familiar. hola.c es el nombre del programa. . Texto - no hay mucho de interés no en este momento, recordar que el texto segmento, a partir del lunes, es donde en la memoria de su programa de realidad termina. Así que eso es lo menos vagamente familiarizado allí. Aquí, por supuesto, es una mención de nuestra función principal. Desplazamiento hacia abajo, estos se refieren a las cosas llamados registros, muy pequeños trozos de memoria dentro de la CPU real. Y si me desplazo hacia abajo hasta aún más, veo una especie mención indirecta de ASCII. Y allí, en efecto, es que la cadena, hola, coma, mundo. Así que cuento largo, esto ha sido pasando por usted, de forma automática, debajo de la capucha de todo este tiempo. Y lo que está sucediendo realmente es, una vez se le han acabado Clang, o por medio de Asegúrese, de que está recibiendo en primer lugar, a partir del código fuente, la llamado lenguaje ensamblador. Entonces Clang es convertir esta asamblea idioma a ceros y unos. Y esta es la diapositiva que empezamos nuestra discusión en la semana 0 a - y luego Semana 1 en. Y, finalmente, esos ceros y unos se combinan con los ceros y unos de aquellas bibliotecas que hemos estado tomando por sentado, como E / S estándar o el Biblioteca de cuerdas o incluso la biblioteca CS50. Así que para pintar este cuadro más visualmente, tenemos hello.c. Y, por supuesto, utiliza el printf funcionar decir hola mundo. El paso de compilación toma hacia abajo para ese archivo que acaba de ver hello.s, incluso aunque eso es eliminada normalmente automáticamente. Pero ese es el código de la asamblea en el paso intermedio. Y luego, cuando nos reunimos la asamblea lenguaje, por así decirlo, que es cuando se conseguir esos ceros y unos. Así que hemos has en forma efectiva hoy en lo que hemos estado dando por sentado, significa ir código fuente código objeto. Pero en fin, ahora esa misma imagen - vamos a meterlo a el lado izquierdo. Y tenga en cuenta que en la parte superior hay Mencioné stdio.h. Eso es un archivo que hemos incluido en casi todo el programas que hemos escrito. Y eso es el archivo cuyo contenido obtener copia pegada, efectivamente lo alto de su código. Pero resulta que, en un ordenador sistema en alguna parte, hay probablemente un archivo stdio.c que alguien escribió años Hace que implementa toda la funciones que fueron declaradas en stdio.h. Ahora, en realidad, probablemente no sea el su Mac o su PC o incluso en el Aparato CS50 es un código C cruda. Alguien ya lo recopiló e incluyó . Archivo o de código objeto o. Un archivo, el cual se refiere a una biblioteca compartida eso ha sido pre-instalado y pre-compilado para usted. Pero supongamos que existe de hecho en nuestro stdio.c ordenador en paralelo con Clang. Siendo compilado de su código y montados. Código stdio.c 's se está recopilando y montado, de manera que este último paso, aquí abajo, tenemos que de alguna manera vincular, por así decirlo, sus ceros y unos con sus ceros y unos en una sola sencillo programa que en última instancia es llamado simplemente Hola. Así que eso es todo lo de la magia que es venido sucediendo hasta ahora. Y va a seguir tomando estos procesos por sentado, pero se dan cuenta hay un montón de detalles jugosos pasando por debajo de allí en. Y esto es lo que hace que su ordenador con Intel inside particularmente distinto. Así que en esa nota, si usted desea únete a nosotros para el almuerzo de este viernes, no vaya al lugar cs50.net/rsvp habitual, 13:15 de este viernes. Y ahora algunos anuncios. Así que tenemos buenas noticias. Y tenemos una mala noticia. Comience con una buena noticia aquí. [GEMIDO] Está bien. Bueno, es técnicamente un día de fiesta, por lo que no es tanto un regalo de nosotros. Pero la mala noticia, por supuesto. [GEMIDO] Me pasé un montón de tiempo en las animaciones. [Risas] Habrá una sesión de revisión el próximo lunes. Va a ser a las 5:30 AM. Le recuerdan a todos estos detalles a través de correo electrónico en el curso de sitio web en tan sólo un par de días. Será filmado y puesto a disposición poco después. Así que si usted no puede hacer que el lunes ranura para la noche, no te preocupes. Secciones esta semana que viene será también centrarse en la revisión del cuestionario. Si su sección es el lunes, que es vacaciones de hecho la universidad, lo haremos sin dejar de cumplir en la sección. Si usted simplemente no puede hacer que sección porque vas lejos, eso está bien. Asistir a una sección de domingo o martes o puesta a punto en la sección de Jason, que es disponible en línea. Por lo tanto, más malas noticias. Así que de acuerdo con el plan de estudios, tenemos conferencia el próximo viernes. Pero la buena noticia - claramente, he pasado demasiado tiempo en esto. [Risas] Nosotros cancelaremos las conferencias del próximo Viernes. Así que va a ser un regalo para nosotros, por lo que realmente puede tener un agradable respiro en entre esta semana y dos semanas, por lo tanto. Así que no hay conferencias de la próxima semana, sólo una pequeña pequeño cuestionario, para lo cual debe ser consiguiendo cada vez más excitado. Así que ahora vamos a centrar nuestra atención en algo que es de hecho más visual y más emocionante y para sentar las bases para lo que va a ser en el horizonte en sólo un par de semanas. Después de la primera prueba, vamos a convertir el foco de nuestro problema pone a otro dominio específico problema, que de forenses o de la seguridad de manera más general. De hecho, la tradición con este problema juego es para mí uno de los compañero de enseñanza o entidades emisoras de caminar a través de campus de tomar algunas fotografías de identificables, pero no personas obvias, lugares o cosas, a continuación, cada año me de alguna manera logran borrar accidentalmente o corruptos tarjeta de los medios de comunicación digitales eso es dentro de nuestra cámara. Pero no es gran cosa. Puedo seguir adelante y conectar que en mi computadora. Yo puedo hacer una imagen forense de la misma, por lo que a hablar, copiando los ceros y en bajar de esa tarjeta de memoria, ya sea es una tarjeta SD o tarjeta de memoria flash compacta o lo que sea que está familiarizado. Y luego podemos entregar eso. Y así, el reto por delante, entre otros cosas para ti, serán para escribir Código C que se recupera de un montón de JPEG para mí y revelado serán esas personas, lugares o cosas. Y también hablaremos, en este problema establecido y en los días por venir, sobre gráficos en general. Nosotros los hemos utilizado, un curso, para estallar. Pero has especie de darse por sentado existe estas nociones de alto nivel de rectángulos y óvalos. Pero debajo de la capucha hay píxeles. Y usted ha tenido que comenzar pensando en ellos. O usted para p-set 4 tener que pensar sobre la brecha entre sus ladrillos, cómo rápido eres pelota se mueve a través de la pantalla para salir. Así que hay esta noción de la puntos en la pantalla es entran en juego ya. Ahora lo que se ve, sin embargo, es lo que se obtiene en una pantalla de ordenador. Si alguna vez has visto algún bien o mala televisión, las probabilidades son que prácticamente tratar al público como tecnófobos que en realidad no saber mucho de computación. Y lo que es muy fácil para la policía detective de decir, ¿verdad limpiar eso para mí? O mejorar, ¿no? Mejorar es como la palabra de moda en la mayoría de cualquier programa de los delitos relacionados. Y la realidad es que si usted toma una muy imagen borrosa de un sospechoso de hacer algo malo, no se puede simplemente mejorarla. No se puede hacer un zoom infinito. No se puede ver en el reflejo de alguien ojo que cometió que particular la delincuencia, a pesar de la prevalencia de esta en la televisión. Y así, con que vamos a motivar a que próximo conjunto de problemas con una visión a algunos programas con el que podría ser familiar. [REPRODUCCIÓN DE VÍDEO] -OK. Ahora, vamos a tener una buena mirada a ti. -Un momento. Ejecute lo dicho. -Espera un minuto. Ir a la derecha. -No. Congele eso. -Full pantalla. -OK. Congele eso. -Apretar hasta en eso, ¿quieres? -Vector en el que ese tipo por la rueda trasera. -Acercar aquí en este lugar. -Con el equipo adecuado, el fotografiado puede ser ampliado y agudizado. ¿Qué es eso? -Se trata de un programa de mejora. -Puede que claro que cualquier? -No lo sé. Vamos a mejorarlo. -Mejorar la sección A-6. -Aumenté el detalle y - -Creo que hay suficiente para mejorar. Suelte a mi pantalla. -Potenciar la reflexión en su ojo. -Vamos a correr esto a través de mejora de vídeo. -Edgar, ¿puedes mejorar esto? -Espera. -He estado trabajando en esta reflexión. -Alguien de reflexión. -Reflexión. -Hay una reflexión de la cara del hombre. -La reflexión. -Hay una reflexión. -Acérquese al espejo. -Se puede ver un reflejo. -Puede usted mejorar la imagen de aquí? -Puede usted mejorar aquí? -Puedes mejorarla? -Puedes mejorarla? -Podemos mejorar esto? -Puedes mejorarla? -Espera un segundo, voy a mejorar. -Zoom en la puerta. -X10. -Zoom. [Risas] -Entrar a vivir -Espera, detente. -Stop. -Pausa ella. -Gire a 75 grados alrededor la vertical, por favor. [Risas] -Stop, y de nuevo a la parte sobre la puerta de nuevo. -Tienes una mejora de imagen que puede mapa de bits? -Tal vez podamos usar la Pradeep Sen método de ver en las ventanas. -Este software es el estado actual de la técnica. -El valor de icono está apagado. -Con la combinación correcta de algoritmos. -Ha tomado algoritmos de iluminación para al siguiente nivel y que pueden utilizarlas para mejorar esta fotografía. -Bloqueo en y ampliar el eje z. -Mejorar. -Mejorar. -Mejorar. -Congelar y mejorar. [VIDEO PLAYBACK FIN] DAVID J. MALAN: Así que de problemas 5 es lo que nos espera allí. Así que pronto vamos a tener una mejor comprensión de cuándo y por qué puede y nuestra no se puede mejorar de ese modo. Pero primero, vamos a volver nuestra atención a algunos de los componentes básicos que vamos a necesitan poder contar esa historia. Así recordamos que elaboramos esta imagen en Lunes y un poco la semana pasada. Y esto describe la disposición de las cosas en la memoria de su computadora cuando la ejecución de algunos programas. El segmento de alto tech, memoria, se refiere a los ceros reales y los que componen el programa. Hay, por debajo de eso, algunos inicializado o datos sin inicializar, que normalmente se refiere a cosas como constantes o cadenas o variables globales que tienen sido declarado de antemano. Ahí está el montón, pero vamos a venir atrás para que en un rato. Y luego está la pila. Al igual que una pila de bandejas en el cafetería, aquí es donde se pone la memoria capas y capas cada vez haces lo que en un programa? ¿Cuál es el uso de la pila para? ¿Sí? Llamada de función. Cada vez que se llama a una función, es dado a astilla de memoria para su las variables locales o de sus parámetros. Y gráficamente, vemos que con cada función de llamada sucesiva, cuando A Llamadas B C llama D, que conseguir capas en la pila. Y dentro de cada una de esas porciones de memoria es esencialmente un alcance único para esa función, que, por supuesto, es problemático si se quiere entregar de una función a otra pieza Un de datos que desea que para mutar o cambiar. Entonces, ¿qué fue de nuestra solución para permitir Una función representada por una pila enmarcar cambiar la memoria en el interior de otro marco de pila? ¿Cómo lo hacen los dos hablan el uno al otro? Así que a través de punteros o direcciones, que, de nuevo, simplemente describir el lugar donde en la memoria, por medio de una específica morder número, lo particular valor puede ser encontrado. Así que recordar la última vez también hemos continuado la historia y miró a un programa bastante buggy. Y este programa está libre de errores para unos pocos razones, pero la más preocupante es porque no puede comprobar qué? Sí, no logra comprobar la entrada. ¿Lo sientes? Si se trata de más de 12 caracteres. Así que muy inteligentemente, al llamar memcopy, que, como su nombre indica, sólo copias de la memoria a partir de su segundo argumento en su primer argumento. El tercer argumento, muy inteligentemente, es revisado para asegurarse de que usted no lo hace copiar más de, en este caso, la longitud de barras, número de caracteres, en el destino, que es este array C. Pero el problema es que lo que si sí C no es lo suficientemente grande a manejar eso? Usted va a copiar el número de bytes que se te ha dado. Pero, ¿qué es lo que realmente tiene más bytes que tienes espacio para el? Pues bien, este programa muy tontamente justo procede ciegamente a tomar lo que es da, hola barra invertida es 0 genial si cadena es corta suficiente, como cinco caracteres. Pero si en realidad es 12 caracteres o 1.200 caracteres, vimos la última vez que sólo vas a por completo sobrescribir memoria que no pertenece a usted. Y peor de los casos, si sobrescribe que porción roja hay que llamamos a la remite - esto es sólo el que el ordenador de forma automática, para ti, detrás de la escenas, se pliega un valor de 32 bits que le recuerda a lo que hacer frente a lo que debería Volveré cuando foo, esta otra función, está hecho de ejecución. Es una miga de pan de tipo a la que devuelve. Si sobrescribe que, potencialmente, si usted es el malo de la película, se pudo potencialmente hacerse cargo hay alguien del equipo. Y lo más seguro estrellarlo en la mayoría de los casos. Ahora bien, este problema sólo se agravó como empezamos a hablar de la memoria gestión en general. Y malloc, para la asignación de memoria, es un función que se puede utilizar para asignar memoria cuando no sabemos de antemano que podríamos necesitar algo. Así, por ejemplo, si regreso al aparato aquí. Y abro desde hello2.c última vez, recordar este programa aquí, que parecía un poco de algo como esto, sólo tres líneas - Diga su nombre, entonces el nombre de cadena, a la izquierda, es igual a getString. Y luego imprimirlo, el nombre del usuario. Así que este era un programa muy simple. Para que quede claro, déjame ir por delante y hacer hola-2. Yo voy a hacer slash dot hola-2. Diga su nombre - David. Intro. Hola David. Parece que funciona bien. Pero lo que realmente está pasando debajo de la campana en esta lista? Primero vamos a pelar algunas capas. String es simplemente un sinónimo que hemos se dio cuenta de qué? Estrella de Char. Así que vamos a hacerlo un poco más arcano pero técnicamente más correcta que esta es una estrella char, lo que significa que nombre, sí, es una variable. Pero, ¿qué nombre de las tiendas es la dirección de un char, que se siente un poco extraño porque me estoy volviendo una cadena. Estoy volviendo múltiple no chars un char. Pero, por supuesto, usted necesita solamente la primera Dirección de char a recordar dónde la toda cadena es porque ¿por qué? ¿Cómo se puede averiguar dónde está el final de la cadena es saber el principio? El cero barra invertida. Así que con esos dos pistas que averiguar antes del comienzo y el final de cualquier cadena son, siempre y cuando estén adecuadamente formado con que nulo terminador, que el cero barra invertida. Pero esto está llamando getString. Y resulta que getString todo este tiempo ha sido una especie de trampa para nosotros. Lo ha estado haciendo este trabajo, para estar seguro, Obtención de una cadena desde el usuario. Pero ¿dónde está la memoria se viene? Si nos remontamos a la imagen aquí y aplicar la definición de sólo un Hace momento, de que la pila es donde memoria va cuando se llama a funciones, por esa lógica, cuando se llama a getString, y luego escribo en D-A-V-I-D Enter, donde es D-A-V-I-D barra invertida cero almacenado, sobre la base de la historia que nos hemos dicho a la fecha? Parece estar en la pila, ¿no? Cuando se llama cadena get obtiene un pedacito de la memoria en la pila. Así que es lógico pensar que la D-A-V-I-D se almacena cero barra invertida hay en la pila. Pero espere un minuto, getString retornos esa cadena, por así decirlo, lo que significa que es la bandeja de la cafetería se toma de la pila. Y dijimos la última vez que tan pronto como función devuelve, y que te lleve la bandeja, por así decirlo, de la pila, lo que puede asumir sobre los restos de que la memoria? Que tipo de ellos volvió a dibujar como signos de interrogación porque se vuelven efectivamente valores desconocidos. Ellos pueden ser reutilizados cuando algunos siguiente función es llamada. En otras palabras, si nos toca a almacenar - Voy a dibujar una imagen rápida aquí de la pila. Si llegamos a ser el dibujo de la parte inferior de mi segmento de memoria, y lo diremos que este es el lugar de memoria ocupada por C y principal y tal vez arg arg v y cualquier otra cosa en el programa, cuando GetString se llama, presumiblemente getString obtiene un trozo de memoria aquí. Y entonces D-A-V-I-D de alguna manera termina en esta función. Y yo voy a simplificar en exceso. Pero vamos a suponer que su D-A-V-I-D barra invertida cero. Así que esta cantidad de bytes se utilizan en el marco para getString. Pero tan pronto como getString vueltas, dijo la última vez que esta memoria sobre aquí todo se hace - woops - todo queda borrado con eficacia. Y podemos pensar en esto ahora como cuestión marca porque quién sabe lo que va a pasar con ese recuerdo. De hecho, muy a menudo llaman a funciones que no sea getString. Y tan pronto como lo llamo alguna otra función que getString, tal vez no en este programa en particular que acabamos de ver a, pero algunos otros, sin duda alguna otra función podría llegar a ser dado este próximo punto en la pila. Así que no puede ser que las tiendas GetString D-A-V-I-D en la pila, ya que lo haría perderá inmediatamente el acceso a la misma. Pero sabemos que getString sólo devuelve lo que? No es volver a Me seis caracteres. ¿Qué es lo verdaderamente regresando hizo llegamos a la conclusión última vez? La dirección de la primera. Así que de alguna manera, cuando llamaste getString, que es la asignación de una parte de la memoria para la cadena que los usuarios escriben y a continuación, la dirección de vuelta del mismo. Y resulta que cuando se quiere función para asignar memoria en este camino y vuelta a la persona que llama esa función, la dirección de que parte de la memoria, a pesar de todo no puede ponerlo en la pila en la inferior, ya que funcionalmente es sólo no va a ser suyo muy rápidamente, por lo que probablemente puede adivinar dónde probablemente vamos a tirar en cambio, el llamado montón. Así que entre el fondo de la memoria de diseño y la parte superior de la memoria de diseño son un montón de segmentos. Una de ellas es la pila, y la derecha anteriormente, es el montón. Y el montón es sólo un pedazo diferente de memoria que no se utiliza para las funciones de cuando se les llama. Se utiliza para la memoria a largo plazo, cuando que desea una función que consigan unas memoria y ser capaz de aferrarse a ella sin perder el control del mismo. Ahora usted podría tal vez inmediatamente ver que esto no es necesariamente un diseño perfecto. A medida que su programa asigna memoria en la pila, o como se llama cada vez más funciones, o como asignar memoria en el montón con malloc apagado como getString está haciendo, lo que claramente parece ser inevitable problema? Derecha. Al igual que el hecho de que estas flechas están apuntando el uno al otro no presagia nada bueno. Y, de hecho, podríamos fallar muy rápidamente un programa en cualquier número de maneras. De hecho, creo que podríamos tener una vez hecho esto accidentalmente. O si no, vamos a hacerlo deliberadamente ahora. Déjenme seguir adelante y escribir muy rápidamente un programa llamado dontdothis.c. Y ahora voy a ir aquí y Qué agudo incluyen stdio.h. Vamos a declarar la función foo toma Sin argumentos, que es denotado así por vacío. Y lo único foo va a hacer es llamar a foo, que probablemente no es el muy inteligente, pero que así sea. Ent void main. Ahora la única cosa principal va que hacer es llamar foo también. Y, sólo por diversión, me voy a ir por delante y decir printf "Hola desde foo ". Aceptar. Así que si yo no he cometido ningún error, Hacer dontdothis slash dot. Y vamos a hacerlo en una ventana más grande - dot slash, dontdothis. Vamos. Uh oh. Al parecer, usted puede hacer esto. Maldita sea. Aceptar. Espere. En espera. ¿Hemos - Hicimos uso con Marca. [Suspira] Lo sé, pero creo que acaba de eliminar eso. Uh, sí. Maldita sea. Resuelva este Rob. ¿Qué? Es muy simple. Sí, nos volvimos optimización off. Aceptar, stand bye. Ahora me siento mejor. Aceptar. Está bien. Así que vamos a volver a compilar este - Hacerte dontdothis. Puede que tenga que cambiar el nombre de este a dothis.c en un momento. Eso es. Gracias. Aceptar. Así que el hecho de que yo era la impresión algo era en realidad sólo ralentizar el proceso por el cual habría llegado a ese punto. Aceptar. ¡Uf! Entonces, ¿qué está pasando en realidad? La razón allí, tal como un aparte, es hacer nada en términos de entrada y salida tiende a ser más lenta porque que escribir caracteres a la pantalla, tiene que desplazarse. Así que cuento largo, me había hecho sucedido tan impaciente, tendríamos visto este resultado final también. Ahora que tengo paseo de los impresos-ups, lo vemos de inmediato. ¿Entonces por qué está pasando esto. Bueno, la explicación simple, por supuesto, es que foo probablemente no debería se hace llamar. Ahora, en términos generales, esta es la recursión. Y pensamos que un par de semanas recursivo hace es bueno. La recursividad es la forma mágica de expresarse muy sucinta. Y simplemente funciona. Pero hay una característica clave de todos los programas recursivos que hemos hablado y mirando al hasta ahora, lo que era que no tenían qué? Un caso base, que fue un poco difícil codificado caso de que dicho en algunas situaciones no llame foo, que es claramente no es el caso aquí. Entonces, ¿qué está sucediendo realmente en términos de esta imagen? Bueno, cuando las llamadas principales foo, se consigue un trozo de memoria. Cuando llama a foo foo, se pone una rebanada de memoria. Cuando llama a foo foo, se pone una rebanada. Se pone una rebanada. Se pone una rebanada. Debido foo nunca regresa. Nunca vamos borrando uno de los marcos de la pila. Así que estamos soplando a través de la pila, no hablar de quién sabe qué más, y estamos sobrepasando los límites de nuestra llamado segmento de la memoria. Go Error falsa segmentación. Así que la solución no es claramente, no lo hagas. Pero la implicación más grande es que, sí, no hay absolutamente cierto límite, incluso si no está bien definida, en cuanto a cómo muchas de las funciones que puede llamar en un programa, ¿cuántas veces una función puede llamar a sí mismo. Así que a pesar de que hicimos la recursividad predican como esta cosa mágica potencialmente un Hace un par de semanas para que el sigma función, y cuando tengamos los datos estructuras y CS50, verás otra aplicaciones para él, no es necesariamente lo mejor. Porque si una función se llama a sí mismo, llama a sí mismo, incluso si no hay una base de caso, si usted no golpea que el caso base para 1000 las llamadas o 10.000 llamadas, por ese momento es posible que haya quedado sin espacio en su llamada pila y exitosa algunos otros segmentos de la memoria. Por lo tanto, también es un diseño de trade-off entre la elegancia y entre robustez de su especial aplicación. Así que no hay otro inconveniente o otra de gotcha a lo que hemos estado haciendo hasta ahora. Cuando llamé a getString - déjame ir nuevamente dentro de Hello-2. Observe que estoy llamando getString, que está devolviendo una dirección. Y decimos hoy que la dirección es del montón. Y ahora estoy imprimiendo el cadena en esa dirección. Pero nunca hemos llamado la opuesto de getString. Nunca hemos tenido a calll una función como ungetstring, donde usted da vuelta ese recuerdo. Pero, francamente, es probable que debería haber sido. Porque si seguimos pidiendo al ordenador para la memoria, a través de alguien como getString pero nunca darle la espalda, seguramente que también está obligado a llevar a problemas con lo que nos quedamos sin memoria. Y, de hecho, podemos buscar estos problemas con la nueva herramienta cuyo uso es un poco críptico al tipo. Pero déjame ir adelante y salpico arriba en la pantalla en un momento. Voy a seguir adelante y ejecutar Valgrind con parámetro cuyo primer comando argumento de la línea es el nombre de ese programa hola-2. Y lamentablemente es salida es atrozmente compleja sin una buena razón. Vemos, pues, todo ese lío. David es el estado de mi nombre. Así que ese es el programa actualmente en funcionamiento. Y ahora tenemos esta salida. Así Valgrind es similar en espíritu a GDB. No es un depurador per se. Pero es un comprobador de memoria. Es un programa que ejecutará el programa y le dirá si le preguntas a un equipo para la memoria y nunca se lo entregó de nuevo, el sentido de lo que usted tiene una pérdida de memoria. Y las pérdidas de memoria tienden a ser malo. Y es que los usuarios de computadoras tienen Probablemente sintió esto, si usted tiene un Mac o un PC. ¿Alguna vez ha utilizado el ordenador para tiempo y no reiniciado en varios día, o sólo tienes una gran cantidad de programas en ejecución, y la maldita cosa disminuye a un punto muerto, o al menos es super molesto de usar, porque todo acaba super lento. Ahora que puede haber cualquier número de razones. Podría ser un bucle infinito, un error en de alguien de código, o, más simplemente, que podría significar que usted está usando más memoria, o tratando, de su equipo en realidad tiene. Y tal vez hay un error en algún programa que seguir preguntando por la memoria. Navegadores de años eran conocidos por esto, pidiendo más y más memoria pero nunca lo devolvió. Seguramente, si sólo tiene un número finito cantidad de memoria, no se puede pedir infinitamente muchas veces para algo de esa memoria. Y así, lo que se ve aquí, a pesar de que de nuevo la salida de Valgrind es innecesariamente complejo para mirar a en primer lugar, esta es la parte interesante. Heap - en uso en la salida. Así que aquí está cómo era la cantidad de memoria en uso en el montón en el vez que mi programa salió - aparentemente seis bytes en un bloque. Así que voy a agitar mis manos a lo que un bloque es. Piense en ello es sólo una parte, una mayor palabra técnica para trozo. Pero seis bytes - ¿cuáles son los seis bytes que todavía estaban en uso? Exactamente. D-A-V-I-D barra invertida cero, cinco letras nombrar más el terminador nulo. Así que este programa Valgrind cuenta de que yo pidió seis bytes, al parecer, por modo de getString, pero nunca les dio la espalda. Y de hecho, esto podría no ser tan obvio si mi programa no es de tres líneas, pero es 300 líneas. Así que en realidad podemos dar otro comando argumento de la línea de Valgrind para hacerlo más detallado. Es un poco molesto para recordar. Pero si lo hago - veamos. Leak - ¿Fue fugas - aunque no me acuerdo lo que está fuera de la mano. - Fugas cheque equivale completo. Sí, gracias. - Fugas cheque equivale completo. Intro. El mismo programa se está ejecutando. Escriba David de nuevo. Ahora veo un poco más de detalle. Pero a continuación el resumen montón, la cual es idéntica a la de cuatro - ah, esto es un poco agradable. Ahora Valgrind está buscando realmente un poco más difícil en mi código. Y está diciendo que, al parecer, malloc en línea - nos alejamos. En la línea - no vemos qué línea es. Pero malloc es el primer culpable. Hay un blog en malloc. ¿De acuerdo? Bueno, no. ¿Cierto? Llamé getString. getString llama aparentemente malloc. Entonces, ¿qué línea de código es aparentemente la culpa por haber asignado esta memoria? Vamos a suponer que quien escribió malloc ha existido el tiempo suficiente como para que sea no es su culpa. Así que es probable que sea la mía. getString en cs50.c - así que es un presentar en algún lugar en el equipo - en línea 286 parece ser el culpable. Ahora vamos a suponer que CS50 ha sido alrededor por cantidad decente de tiempo, por lo que nosotros también somos infalibles. Y por lo que probablemente no está en getString de que el error se encuentra, sino más bien en hola-2.c línea 18. Así que echemos un vistazo a lo que era que la línea 18. Oh. De alguna manera, esta línea no es necesariamente con errores, per se, sino que es la razón detrás de esa pérdida de memoria. Así que muy sencilla, lo que haría de manera intuitiva ser la solución a este problema? Si estamos pidiendo memoria, nunca fueron dándole la espalda, y que parece ser un problema, ya que con el tiempo mi equipo podría quedarse sin memoria, se reducirá la velocidad abajo, las cosas malas pueden pasar, así, ¿cuál es la solución simple e intuitiva? Sólo tienes que darle la espalda. ¿Cómo se puede liberar esa memoria? Bueno, por suerte es muy sencillo sólo decir el nombre de forma gratuita. Y nosotros nunca hemos hecho esto antes. Pero usted puede pensar esencialmente en libre como el opuesto de malloc. libre es lo opuesto a la la asignación de memoria. Así que ahora déjame a compilar esto. Hacer hola-2. Déjame correr de nuevo. hola-2 David. Así que parece que funciona en exactamente de la misma manera. Pero si vuelvo a Valgrind y repetición ese mismo comando en mi recién compilado programa, mecanografía en mi nombre como antes - agradable. Resumen Heap - en uso en la salida - cero bytes en cero bloques. Y esto es muy agradable, todo bloques montón fueron liberados. Sin fugas son posibles. Así que viene, no con problemas n 4, pero con problemas 5, los forenses y en adelante, esto también se convertirá en un medida de la exactitud de su programa, si usted tiene o no o no tienen pérdidas de memoria. Pero, por suerte, no sólo se puede razonar a través de ellos de forma intuitiva, que es, sin duda, más fácil para pequeños programas pero es más difícil para los programas más grandes, Valgrind, para aquellos programas de mayor envergadura, puede ayudarle a identificar el problema particular. Pero hay otro problema que puedan surgir. Permítanme abrir este archivo aquí, que es, de nuevo, un ejemplo algo simple. Pero vamos a centrarnos en lo que este programa lo hace. Esto se llama memory.c. Vamos a publicar esta tarde hoy en el zip del código fuente de la actualidad. Y note que tengo una función llamada f que no toma argumentos y no devuelve nada. En la línea 20, que estoy al parecer se declara una puntero a un int y decir que es x. Estoy asignando es el retorno valor de malloc. Y para que quede claro, ¿cuántos bytes am Probablemente volver de malloc en esta situación? Probablemente 40. ¿De dónde sacaste eso? Bueno, si usted recuerda que un int es a menudo 4 bytes, por lo menos es en el aparato, 10 veces 4 es, obviamente, 40. Así malloc devuelve una dirección de un trozo de memoria y almacenamiento que abordar en última instancia en x. Así que para ser claros, lo que entonces está sucediendo? Bueno, déjame cambia de nuevo a nuestra imagen aquí. No me dejes solo trazo la parte inferior de mi la memoria del ordenador, deja que me vaya por delante y dibujar todo el rectángulo que representa toda mi RAM. Vamos a decir que la pila está en la parte inferior. Y hay un segmento de texto en los datos sin inicializar. Pero yo sólo voy a los abstracta otras cosas de distancia como punto, punto, punto. Yo sólo voy a hacer referencia a este como la pila en la parte superior. Y luego en la parte inferior de esta imagen, para representar principal, me voy para darle una memoria rebanadas en la pila. Para f, voy a darle una rebanada de memoria en la pila. Ahora, tengo que consultar con mi código fuente de nuevo. ¿Cuáles son las variables locales para el principal? Aparentemente nada, así que corte es efectivamente vacío o ni siquiera tan grande como he dibujado él. Pero en f, tengo una variable local, que se llama x. Así que voy a seguir adelante y dar f un trozo de memoria, que calificó de x. Y ahora malloc de 10 veces 4, Así malloc 40, ¿dónde está ese memoria viene? Nosotros no hemos dibujado una imagen como esto antes. Pero vamos a suponer que es efectivamente que viene de aquí, por lo que uno, dos, tres, cuatro, cinco. Y ahora necesito 40 de estos. Así que voy a hacer punto, punto, punto de sugerir que incluso hay más memoria al volver de la pila. Ahora, ¿qué es la dirección? Elijamos nuestro arbitraria abordar como siempre - Ox123, a pesar de que probablemente va ser algo completamente diferente. Esa es la dirección del primer byte en memoria que lo que estoy pidiendo para malloc. Así que en resumen, una vez que la línea 20 se ejecuta, lo que es, literalmente, almacenado en el interior de x aquí? Ox123. Ox123. Y el buey es poco interesante. Sólo significa que aquí hay un número hexadecimal. Pero lo fundamental es que lo que he store en x, que es una variable local. Pero su tipo de datos, una vez más, es una dirección de un int. Bueno, me voy a guardar Ox123. Pero, de nuevo, si eso es un poco demasiado complicado innecesariamente, si me desplazo hacia atrás, podemos abstraer esta distancia bastante razonable y justo decir que x es un puntero a ese trozo de memoria. Aceptar. Ahora la pregunta que nos ocupa es la siguiente - la línea 21, que resulta, está libre de errores. ¿Por qué? ¿Lo sientes? No tiene por qué - decir que una vez más. Bueno, no lo hace de forma gratuita. Así que ese es el segundo, pero. Así que hay otra, pero específicamente en la línea 21. Exactamente. Esta simple línea de código es sólo una desbordamiento de búfer, una saturación del búfer. Un buffer sólo significa un trozo de memoria. Pero ese trozo de memoria es de tamaño 10, 10 enteros, lo que significa que si índice en ella utilizando el azúcar sintáctico de la notación de matriz, la plaza soportes, usted tiene acceso a x soporte de 0 x 1 soporte de x, dot soporte, punto, punto. x soporte 9 es el más grande. Así que si lo hago x soporte 10, donde De hecho voy en la memoria? Bueno, si tengo 10 int - vamos realmente atraer a todos de ellos aquí. Así que esa fue la primera de cinco. Aquí están los otros cinco ints. Así x soporte 0 está aquí. x soporte 1 es aquí. x soporte 9 está aquí. x soporte 10 está aquí, lo que significa que estoy diciendo, en la línea 21, el equipo para poner el número donde? El número 0 donde? Bueno, es 0, sí. Pero sólo el hecho de que su 0 es una especie de coincidencia. Podría ser el número 50, a todos nos importa. Pero estamos tratando de ponerlo en x soporte 10, que es donde este signo de interrogación se dibuja, que no es una buena cosa. Este programa podría muy bien estrellarse como resultado. Ahora, vamos a seguir adelante y ver si esto es, de hecho, lo que sucede. Hacer memoria, ya que el archivo se llama memory.c. Vamos a seguir adelante y ejecutar la memoria de programa. Así que tuvimos suerte, en realidad, lo que parece. Tuvimos suerte. Pero vamos a ver si ahora corremos Valgrind. A primera vista, mi programa podría parecen ser perfectamente correcta. Pero déjame correr Valgrind con el - Fuga de verificación es igual completa en la memoria. Y ahora cuando ejecuto esto - interesante. Escritura no válido de tamaño 4 en línea 21 de memory.c. Línea 21 de memory.c es cuál? Ah, interesante. Pero espere. Tamaño 4, ¿cuál es el que se refiere a? Sólo hice una escritura, pero es de tamaño 4. ¿Por qué es 4? Es porque es un int, que es, de nuevo, cuatro bytes. Así Valgrind encontró un error que yo, echar un vistazo a mi código, no lo hizo. Y tal vez su TF sería o no sería. ¿Qué Pero Valgrind con seguridad encontró que que hemos cometido un error allí, incluso aunque tuvimos suerte, y el ordenador decidió, eh, yo no voy a chocar sólo porque usted tocó un byte, una el valor de la memoria que no lo hiciste de int en realidad poseer. Bueno, ¿qué más hay errores aquí. Dirección - esta es una dirección de mirada loco en hexadecimal. Eso sólo significa que en algún lugar de la pila es cero bytes después de un bloque de tamaño 40 se asigna. Permítanme Alejar aquí y ver si esto es un poco más útil. Interesante. 40 bytes están definitivamente perdidos en el registro de la pérdida de 1 de 1. Una vez más, más palabras que es útil en este caso. Pero en base a las líneas resaltadas, donde debería probablemente centrar mi atención para otro bug? Se parece a una línea 20 de memory.c. Así que si nos remontamos a la línea 20, que es la uno que ha identificado previamente. Y no es necesariamente erróneo. Pero hemos invertido esta sus efectos. Entonces, ¿cómo puedo corregir, al menos, uno de esos errores? ¿Qué podía hacer después de la línea 21? Que podía hacer libre de x, por lo que es de devolver esa memoria. Y ¿cómo puedo solucionar este error? Definitivamente debería ir a no más de 0. Así que voy a tratar y volver a hacer éste. Lo sentimos, pero sin duda alguna a no más de 9. Hacer memoria. Permítanme volver a ejecutar Valgrind en una ventana más grande. Y ahora mira. Niza. Todos los bloques de almacenamiento dinámico fueron liberados. Sin fugas son posibles. Y por encima de aquí, no hay mención como tampoco del derecho válido. Sólo para obtener codiciosos, y vamos a ver si otra demostración no va según lo previsto - Yo tuve la suerte hace un momento. Y el hecho de que esto es 0 es quizás innecesariamente engañosa. Vamos a hacer 50 años, un tanto arbitraria número, marca de memoria slash dot memoria - todavía tenga suerte. Nada ha estrellarse. Supongamos que yo acabo de hacer algo realmente tonto, y lo hago 100. Deja rehacerme memoria, dot slash memoria - tuvimos suerte de nuevo. ¿Qué hay de 1000? ints allá, más o menos, donde debería estar? Hacer memoria - maldita sea. [Risas] Aceptar. No vamos a perder el tiempo ya. Vuelva a ejecutar la memoria. Eso es. Está bien. Así que al parecer se indexa 100.000 ints más allá de donde debería haber estado en la memoria, las cosas malas suceden. Así que esto no es, obviamente, una regla fija duro. Yo estaba un poco usando el juicio y error para llegar allí. Pero esto se debe a que, cuento largo, la memoria del equipo también se divide en estas cosas denominadas segmentos. Y a veces, la computadora en realidad te ha dado un poco más de memoria de lo que pides. Sin embargo, para la eficiencia, es simplemente más fácil obtener más memoria, pero sólo le dirá que usted está recibiendo una parte de ella. Y si tienes suerte a veces, Por lo tanto, usted podría ser capaz de tocar memoria que no le pertenece a usted. Usted no tiene ninguna garantía de que lo que el valor que puso en su lugar se quedará allí, porque el equipo aún piensa que no es la suya, pero no es necesariamente va para golpear otro segmento de la memoria en la equipo e inducir un error como este de aquí. Está bien. Cualquier pregunta entonces sobre la memoria? Está bien. Vamos a echar un vistazo aquí, entonces, en algo que hemos estado dando por concedida desde hace bastante tiempo, que está en este archivo llamado cs50.h. Así que este es un archivo. Estos son sólo un montón de los comentarios arriba. Y usted puede ser que haya mirado a esto si que hurgó en el aparato. Pero resulta que todo el tiempo, cuando solíamos usar cadena como una sinónimo, el medio por el cual nos declaramos que era sinónimo con esta typedef palabra clave, para el tipo de definición. Y estamos diciendo esencialmente, hacer cadena sinónimo de estrellas caracteres. Que los medios por los cuales la pila creado estas ruedas de entrenamiento conocidos como la cadena. Ahora aquí es sólo un prototipo para getchar. Puede ser que hayamos visto antes, pero eso es de hecho lo que hace. getchar no toma ningún argumento, devuelve un char. GetDouble no toma ningún argumento, devuelve un doble. getFloat no tiene argumentos, declaraciones un flotador, y así sucesivamente. getint está aquí. getlonglong hay aquí. Y getString está aquí. Y eso es todo. Esta línea morada es otro preprocesador directiva, debido a la hashtag en el comienzo de la misma. Está bien. Así que ahora me dejes ir en cs50.c. Y no vamos a hablar demasiado tiempo en esto. Pero para darle una idea de lo que es estado sucediendo todo esto tiempo, déjame ir a - hagámoslo getchar. Así getchar es en su mayoría comentarios. Pero parece que esto. Así que esta es la función real getchar que hemos sido dando por sentado que existe. Y a pesar de que no hemos utilizar éste que muchas veces, o nunca, que es por lo menos relativamente simple. Así que vale la pena tomar un rápido vistazo aquí. Así getchar tiene un bucle infinito, deliberadamente para parecer. A continuación, llama - y esto es una especie de agradable reutilización de código que nos escribió. Llama getString. Porque lo que lo hace significar para obtener un char? Bueno, puede ser que también tratar de conseguir un toda la línea de texto del usuario y a continuación, sólo tiene que buscar en un de esos personajes. En la línea 60, aquí hay un poco de poco de una comprobación de validez. Si getString volvió nulo, no vamos a proceder. Algo salió mal. Ahora bien, esto es algo molesto, pero convencional en C. caracteres máx probablemente representa lo que acaba basándose en su nombre? Es una constante. Es como el valor numérico de la mayor carbón puede representar con un bocado, que es probablemente el número 255, que es el mayor número que representar a ocho bits, a partir de cero. Así que he uso este, en esta función, escribir este código, sólo porque si algo va mal en getchar pero su propósito en la vida es volver a char, usted necesita ser capaz de alguna manera para indicar al usuario que algo salió mal. No podemos devolver null. Resulta que es un puntero nulo. Y de nuevo, getchar tiene para devolver un char. Así que la convención, si algo sale mal, es usted, el programador, o en este caso, yo con la biblioteca, que tenía un solo decidir arbitrariamente, si algo va mal, voy a devolver el número 255, que es verdaderamente significa que podemos no ser así, el usuario no puede escribir el carácter representado por la número 255, porque teníamos un robarlo como un valor llamado centinela para representar un problema. Ahora resulta que el carácter 255 no es algo que se pueda escribir con el teclado, por lo que no es gran cosa. El usuario no se da cuenta de que Yo he robado este personaje. Pero si alguna vez se ve en las páginas de manual en un sistema informático alguna referencia a una todas las tapas de constantes como este que dice, en los casos de error que esto podría constante ser devuelto, es todo un humano hizo Hace años se decidió arbitrariamente devolver este valor especial y llamarlo una constante en el caso algo va mal. Ahora, la magia sucede aquí abajo. En primer lugar, estoy declarando en la línea 67 dos personajes, C1 y C2. Y luego, en la línea 68, hay realmente una línea de código que es una reminiscencia de nuestra printf amigo, dado que se tiene ciento Cs entre comillas. Pero darse cuenta de lo que está pasando aquí. sscanf significa escaneo cadena - medios escanear una formateada cadena, sscanf ergo. ¿Qué significa eso? Esto significa que se pasa a sscanf una cadena. Y la línea es lo el usuario escribe pulg Se pasa a sscanf una cadena de formato como esto que dice scanf cuáles son usted esperando que el usuario ha escrito pulg A continuación, pasa en las direcciones de los dos trozos de la memoria, en este caso, porque tengo dos marcadores de posición. Así que voy a dar la dirección de C1 y C2 de la dirección. Y recuerdan que usted da en función de la dirección de una variable, lo que es la implicación? ¿Qué puede hacer esa función como resultado de darle la dirección de un variable, frente a la propia variable? Se puede cambiar, ¿verdad? Si tuvieras a alguien un mapa a un físico dirección, pueden ir allí y hacer lo que quieran en esa dirección. La misma idea aquí. Si pasamos a sscanf, la dirección de dos fragmentos de memoria, incluso estos pequeños pequeños trozos de memoria, C1 y C2, pero les decimos que la dirección de ellos, sscanf puede cambiarlo. Así que el propósito de sscanf en la vida, si leemos la página de manual, es leer lo que el usuario escribió en la esperanza de que el usuario tenga escrito en un personaje y tal vez otro personaje, y lo que el usuario escrito, el primer personaje pasa aquí, el segundo personaje va aquí. Ahora, en un aparte, esto y lo haría Sólo sé esto de la documentación, el hecho de que me puse un espacio en blanco que hay Sólo quiere decir que no me importa si el usuario pulsa la barra espaciadora algunos veces antes de que él o ella toma un carácter, voy a ignorar cualquier espacio en blanco. Así que, sé por la documentación. El hecho de que hay un segundo% c seguido de un espacio en blanco es en realidad deliberada. Quiero ser capaz de detectar si el usuario estropeado o no cooperar. Así que espero que el usuario sólo escribe en uno de los personajes, por lo tanto, estoy esperando sscanf que sólo se va a devolver el valor 1, ya que, de nuevo, si leo la documentación, el propósito de sscanf en la vida es para volver a la número de las variables que se llenaron con la entrada del usuario. Pasé con dos variables direcciones, C1 y C2. Espero, sin embargo, que sólo uno de ellos es asesinado porque si sscanf devuelve 2, ¿cuál es, presumiblemente, la implicación lógica? Que el usuario no sólo me dan una personaje como yo le dije. Probablemente escriben en menos dos caracteres. Así que si yo no tuviera lugar la segunda % C, acabo de tener una, que francamente sería más intuitivo enfoque, creo que un primer vistazo, usted no va a ser capaz de detectar si el usuario le ha estado dando más entrada de lo que realmente quería. Así que esta es una forma implícita de comprobación de errores. Pero noto lo que hago aquí. Una vez que esté seguro de que el usuario me dio una carácter, libero a la línea, haciendo lo contrario de getString, que a su vez utiliza malloc, y luego vuelva C1, el personaje que esperaba el proporcionado por el usuario y sólo se dispensará. Así que una rápida vislumbrado sólo, pero cualquier pregunta sobre getchar? Volveremos a algunos de los otros. Bueno, déjame seguir adelante y hacer esto - Supongamos ahora, sólo para motivar a nuestra discusión en una semana, más tiempo, este es un archivo llamado structs.h. Y de nuevo, esto es sólo una muestra de algo que está por venir. Pero nótese que muchos de esto es comentarios. Así que permítanme destacar sólo el parte interesante por ahora. typedef - hay esa misma palabra clave de nuevo. typedef se utiliza para declarar cadena como un tipo especial de datos. Puede usar typedef para crear nuevo tipos de datos que no existían cuando C fue inventado. Por ejemplo, int viene con C. caracteres viene con C. doble viene con C. Pero no hay ninguna noción de un estudiante. Y, sin embargo, sería muy útil tener la capaz de escribir un programa que almacena en una variable, el número de identificación del estudiante, su nombre, y su casa. En otras palabras, tres piezas de los datos, como un int y un cuerda y otra cadena. Con typedef, lo que es bastante potente sobre esto y la palabra clave para sturct estructura, usted, el programador en el año 2013, realmente puede definir su propio el los tipos de datos que no existían años hace pero que se adapte a sus propósitos. Y aquí, en las líneas 13 a 19, estamos declarando un nuevo tipo de datos, como un int, pero llamándolo estudiante. Y dentro de esta variable va a tres cosas - un int, una cuerda, y una cadena. Así que usted puede pensar en lo que es realmente ha pasado aquí, a pesar de que este es un poco de una simplificación para hoy, un estudiante es esencialmente va a tener este aspecto. Su va a ser un pedazo de memoria con una identificación, un nombre campo, y un campo de casa. Y vamos a ser capaces de utilizar los trozos de memoria y acceder a ellos de la siguiente manera. Si entro en struct0.c, aquí hay una relativamente largo, pero después de un patrón, de código que utiliza este nuevo truco. Así que en primer lugar, permítanme llamar su atención a las partes interesantes hasta la parte superior. Afilado define a los estudiantes 3, declara una constantes llamados estudiantes y cesionarios arbitrariamente el número 3, justo así que tengo tres estudiantes que utilizan este programa por el momento. Aquí viene Principal. Y fíjense, ¿cómo me declaro una gran variedad de estudiantes? Bueno, acabo de utilizar la misma sintaxis. La palabra estudiante es obviamente nueva. Pero los estudiantes, la clase, los estudiantes del soporte. Así que por desgracia hay mucho de reutilización de los términos aquí. Esto es sólo un número. Así que esto es como decir tres. Class es justo lo que quiero llamar a la variable. Yo podría llamarlo estudiantes. Pero clase, esto no es una clase en un orientado a objetos Java tipo de vía. Es sólo una clase de estudiantes. Y el tipo de datos de cada elemento en esa matriz es estudiante. Así que esto es un poco diferente y de decir algo como éste, es sólo - Estoy diciendo dame tres estudiantes y llamar a esa clase de arreglo. Está bien. Ahora aquí está un bucle de cuatro. Este tipo familiar - iterate de cero en un máximo de tres. Y aquí está la nueva pieza de la sintaxis. El programa va a pedir confirmación, el ser humano, para darle un estudiante ID, que es un int. Y aquí está la sintaxis con la que se puede almacenar algo en el campo de identificación en ubicación del soporte de clase I. Así esta sintaxis no es nueva. Esto sólo significa dame la octava estudiante en la clase. Pero este símbolo es nueva. Hasta ahora, hemos utilizado no podemos punto, al menos en código como este. Esto significa ir a la estructura conocida como un estudiante y poner algo allí. Del mismo modo, en esta línea siguiente, el 31, vaya adelante y poner lo que el usuario escribe para un nombre aquí y lo que hacen para ganarse casa, lo mismo, seguir adelante y lo puso en. casa. Así que lo que hace este programa en última instancia, hacer? Se puede ver un poco bromista allí. Déjame ir por delante y no hago estructuras 0 dot slash struct 0, ID del estudiante 1, decir David Mather, identificación del estudiante 2. Rob Kirkland, carnet de estudiante 3. Lauren Leverit - y lo único que hizo este programa, que es algo completamente arbitrario, es Yo quería hacer algo con estos datos, ahora que nos he enseñado cómo utilizar estructuras, es que me acabo de tener este bucle adicional aquí. Iterar sobre el conjunto de los estudiantes. He utilizado nuestro, amigo quizás ahora familiar, string comparar stircomp a cheque es la casa octava del estudiante igual a Mather? Y si es así, simplemente imprimir algo arbitrariamente como, sí, lo es. Pero, de nuevo, me acaba de dar oportunidades de usar y reutilizar y reutilizar esta nueva notación de puntos. Así que a quién le importa, ¿verdad? El subir con un programa de estudiantes es algo arbitrario, pero resulta que podemos hacer cosas útiles con esta, por ejemplo, como sigue. Esta es una estructura mucho más complicado en C. Tiene una docena o más campos, de manera algo críptica llamada. Pero si alguna vez has oído hablar de una gráfica formato de archivo llamado mapa de bits, BMP, que Resulta que el formato de archivo de mapa de bits casi parece como que este. Es un poco estúpido rostro sonriente. Es una pequeña imagen que he acercaste en bastante grande para que yo pudiera ver cada de los puntos o píxeles individuales. Ahora, resulta que podemos representar un punto negro con, por ejemplo, el número 0. Y un punto blanco con el número 1. Así que en otras palabras, si desea dibujar un Cara sonriente y guardar esa imagen en un ordenador, basta con almacenar los ceros y los que se ven como este, donde, de nuevo, los son de color blanco y ceros son de color negro. Y juntos, si usted tiene efectivamente un ceñidor de unos y ceros, tiene una rejilla de píxeles, y si usted pone a cabo, que tienen una linda carita sonriente. Ahora, el formato de archivo de mapa de bits, BMP, es efectivamente que debajo del capó, pero con más píxeles sot que en realidad puede representar los colores. Pero cuando usted tiene más sofisticado formatos de archivo como BMP y JPEG y GIF con el cual usted puede estar familiarizado, los archivos en el disco típicamente no sólo tener ceros y unos de los píxeles, pero que tienen algunos metadatos, así - meta en el sentido de que no es realmente datos, pero es útil tener. Así que estos campos aquí están implicando y vamos a ver esto con más detalle en el P-set 5, que antes de los ceros y unos que representar los píxeles de una imagen, hay un montón de metadatos como el tamaño de la imagen y el ancho de la imagen. Y noto que estoy arrancando algunos cosas arbitrarias aquí - anchura y altura. Conteo de bits y algunas otras cosas. Así que hay algunos metadatos en un archivo. Pero para entender cómo se ponen los archivos de esta manera, en realidad se puede a continuación, manipular imágenes, recuperar imágenes desde el disco, cambiar el tamaño de imágenes. Pero no se puede necesariamente mejorarlos. Necesitaba una fotografía. Así que volví a RJ aquí, que te vio en la pantalla hace bastante tiempo. Y si abro Keynote aquí, esto es lo que sucede si se intenta acercar y mejorar RJ. Él no está mejorando realmente. Ahora Keynote es una especie de desdibujando un poco, sólo para pasar por alto el hecho de que RJ no consigue especialmente mejorado al hacer zoom in Y si hacerlo de esta manera, ver las plazas? Sí, definitivamente se puede ver los cuadrados de un proyector. Eso es lo que pasa cuando a mejorar. Pero en la comprensión de cómo nuestro RJ o el La cara sonriente es implementado nos permitirá realmente escribir código que manipula estas cosas. Y yo que pensaba que iba a terminar con esta nota, con 55 segundos de una realzan eso es, Me atrevo, digo algo engañoso. [REPRODUCCIÓN DE VÍDEO] -Está mintiendo. Acerca de qué, no lo sé. -Entonces, ¿qué sabemos? -Que a las 9:15 Ray Santoya estaba en el cajero automático. -Así que la pregunta es ¿qué estaba haciendo a las 9:16? -El rodaje de la nueve milímetros en algo. Tal vez vio al francotirador. -O estaba trabajando con él. -Espera. Retroceder un. -Qué es lo que ves? -Traiga su rostro hacia arriba, pantalla completa. -Sus gafas. -Hay una reflexión. -Ese es el equipo de béisbol Neuvitas. Esa es su logotipo. -Y él está hablando con quien sea que esté llevando esa chaqueta. [VIDEO PLAYBACK FIN] DAVID J. MALAN: Esta voluntad ser problemas 5. Nos vemos la semana que viene. Hombre: En la próxima CS50. [Grillos] [REPRODUCCIÓN DE MÚSICA]