[REPRODUCCIÓN DE MÚSICA] ROB BODEN: Muy bien. Así que, primero lo primero, de vídeo a partir de una cara conocida. [REPRODUCCIÓN DE VÍDEO] -Muy bien. Este es CS50, y esto es el inicio de la tercera semana. Lo siento yo no podía estar allí con ustedes hoy, pero permítame presentarle Propio Boden Rob CS50. [VIDEO PLAYBACK FIN] [Aplausos y vítores] ROB BODEN: La filmografía de que el video es fantástico. Está bien. Así que primero, hay otro almuerzo. Es mañana a las 1:15. No hay almuerzo este viernes. Es con Quora. Y Tommy aún no está aquí, pero uno de la gente de allí es ex jefe CF, Tommy McWilliam. Así que él es un tipo divertido. Usted debe venir. Está bien. Así que la semana pasada, empezamos romperse acerca de lo que una cadena es en realidad. Hemos sabido desde el principio que que es una secuencia de caracteres. Pero la semana pasada, hemos profundizado en el hecho de que lo que es en realidad una secuencia de personajes, bueno, ahora tenemos arreglos de caracteres. Y sabemos que una cadena, que es una matriz de personajes, al final, tenemos este byte nulo especial, este barra invertida 0, que indica el final de la cadena. Y así, una cadena es un arreglo de personajes, pero podemos tener más de sólo un conjunto de caracteres, podemos tener una matriz de cualquier tipo de cosas que queremos. Por lo tanto, si usted recuerda de la semana pasada, el Programa de Edad que David introdujo muy rápido. Así que lo primero que vamos a hacer es pedir al usuario un número entero, el número de personas en la habitación. Una vez que tengamos ese entero, estamos declarando una matriz. Observe esta sintaxis soporte. Usted va a acostumbrarse a eso. Así que estamos declarando una matriz de enteros llaman las edades, y hay n enteros en esta matriz. Así que este patrón aquí, este 4 int i es igual a 0, i es menor que n, i más además, que también va a ser un patrón que usted consigue muy acostumbrado. Porque eso es más o menos cómo eres siempre va a iterar sobre arrays. Así que recuerda que n es el longitud de nuestra matriz. Así que aquí, estamos pidiendo repetidamente para la edad de la persona i en la habitación. Después de esto, vamos hacia abajo, y por cualquier razón arbitraria, entonces imprima la edad que van a ser un año a partir de ahora. Y ejecutar ese programa, vamos a hacer edades, punto edades slash. Así que el número de personas en la habitación, digamos que hay tres. Y decir, la primera persona es de 13, siguiente es 26, y el último es 30. Así entonces va a iterar sobre los tres gente, imprimen 14, 27 y 31. Así que recuerde que cuando declaramos un matriz de tamaño n, los índices en que matriz, la matriz tiene valores y índices 0, 1, 2, todo el camino hasta n menos 1. Así que cuando nos dijo que había tres personas en el cuarto, y lo ponemos aquí la primera iteración a través de este bucle, i va a ser 0. Así que en el índice 0. Estamos asignando la primera Edad El usuario introduce. Luego, en el siguiente, estamos entrando en el segundo n el usuario entra, y en junto a dos, el último n. Así cuenta de que una matriz de tamaño tres no tiene nada en el índice de tres. Esto no es válida. Está bien. Así que, volviendo aquí. Así que ahora que hemos tratado con matrices, tenemos cierta familiaridad. Ahora vamos a pasar a comandos argumentos de la línea, que van a ser muy relevantes para este conjunto de problemas. Así que, hasta ahora, cada vez que usted tiene declaró que su función principal, que hemos dijo void main int. Así vacío sólo significa que no estamos pasando cualquier argumentos de esta función. Ahora vamos a ver que la principal puede tomar algunos argumentos. Aquí los llamamos int argc y los soportes argv cadena. Los soportes, una vez más, lo que indica que estamos tratando con matrices. Así que aquí, entre paréntesis argv cadena, estamos se trata de una matriz de cadenas. Así argc, eso va a indicar cuántos argumentos que hemos pasado a este programa. Y para ver lo que eso significa, vamos a cerrar esto. Aceptar. Así que, hasta ahora, nos hemos quedado todos programa como las edades de la raya vertical de puntos. Podemos también, en la línea de comandos, más allá pasar argumentos, de ahí el término, el comando argumentos de la línea. Así que el primer argumento, hola mundo. Así que aquí, argc sería tres. Es el recuento de los argumentos en la línea de comandos. Argc es siempre al menos 1, desde el punto recortar las edades, en sí, que cuenta como uno de los argumentos de la línea de comandos. Luego hola es la primera. Si edades slash dot es el cero, entonces hola es la primera, y el mundo es la segundo argumento de la línea de comandos. Así que la cadena argv, vamos a ver, contiene las cadenas, slash dot edades, hola, y en el mundo. Y, por la petición de David, vamos para reproducir un vídeo que introducir. [REPRODUCCIÓN DE VÍDEO] -Hasta ahora, en los programas que hemos por escrito, hemos declaramos principal void main como int. Y todo este tiempo, ese vacío tiene simplemente se especifica que el programa no toma ninguna argumentos de la línea de comandos. En otras palabras, cuando un usuario ejecuta una programa, él o ella puede proporcionar comando argumentos de la línea de la escritura adicional palabras o frases después del programa nombre en el indicador. Bueno, si usted no desea que su programa para tomar argumentos de línea de comandos, uno o más de tales palabras, tenemos que reemplazar anular con un par de argumentos. Así que vamos a hacer eso. Incluya CS50.h. Incluya io.h. estándar Int. principal. Y ahora, en lugar de vacío, me voy a especifique un entero llamado argc y una matriz de cadenas denominadas argv. Ahora, argc y argv son simplemente convenciones. Podríamos haber llamado a estos argumentos más lo que queramos. Pero lo importante es que argc es un int porque, por definición, es va a contener el número del argumento, la número de palabras en total que el usuario ha escrito en su solicitud. argv, por su parte, el argumento de vectores, es va a ser en realidad una matriz de almacenamiento todas las palabras que el usuario tiene escrito en su solicitud. Vamos a proceder a hacer algo ahora con uno o más de estos argumentos de la línea de comandos. En particular, vamos a seguir adelante e imprimir cualquier palabra que el usuario después del nombre del programa en el indicador. Soporte Abrir. Cerrar soporte. Ciento Printf s barra invertida y coma. Y ahora tengo que decirte printf qué valor para conectar a ese marcador de posición. Quiero que la primera palabra que el usuario tiene escrito después del nombre del programa, y por eso me voy a especificar argv soporte 1, cerca paréntesis, punto y coma. Ahora, ¿por qué el soporte 1 y que no soporte 0? Bueno, resulta que, almacenada automáticamente en argv 0 va a ser el nombre real del programa. Así que la primera palabra que el usuario después del nombre del programa es, por convención, va a ser almacenado en argv 1. Ahora vamos a compilar y ejecutar este programa. Hacer argv 0, slash argv punto 0. Y ahora una palabra como hola. Intro. Y ahí lo tenemos, hola. [VIDEO PLAYBACK FIN] ROB BODEN: Muy bien. Cierra esa. Así que echar un vistazo a ese programa que hemos introducido para nosotros, bueno, para mostrar, si imprimimos argv 0, marca, ahora ¿qué es, argv 0, slash argv punto 0. Así que, como se esperaba, se imprima la el nombre del programa, ya que es argv 0 siempre va a ser el el nombre del programa. Pero vamos a hacer algo un poco más interesante. Así, en el conjunto de problemas, usted será introducido a esta función, atoi. Entonces, ¿qué es lo que utilizamos para atoi? Eso va a convertir una cadena a un entero. Así que si paso la cadena, uno, dos, tres, a atoi, que va a convertirlos en que al entero, uno, dos, tres. Así que vamos a convertir la primera línea de comandos argumento en un entero, y luego simplemente imprimir ese entero. Así que, básicamente, estamos un poco reimplementar getint, sólo el entero se introduce en el comando línea en lugar de en el programa interactiva. Así pues, haciendo argv 0, vamos a hacer que aquí, y cerrar esa. Entonces, ejecutar argv 0, y vamos a entrar en el número entero, un dos tres cuatro uno dos. Así que va a imprimir el número entero, una dos tres cuatro uno dos. Hay algunas sutilezas que atoi que que va a dejar de preocuparse por nada más allá de un carácter numérico válido, pero eso no importa. Entonces, ¿qué crees que sucede si hago esto? Fallo de segmentación. Entonces ¿por qué es eso? Si uno mira hacia atrás en nuestro programa, estamos convertir argv 1, el primer argumento después de que el nombre del programa, a un entero. Pero no hay un argumento que se pasa después de que el nombre del programa. Así que aquí, vemos que se trata de un buggy programa, ya que, si tratamos de ejecutarlo sin ningún argumento, simplemente se colgará. Así que otro patrón común verás es algo así como, si argc es menos de dos, lo que indica que no había por lo menos el nombre del programa y una primer argumento, entonces haremos algo como printf, no es suficiente argumentos de la línea de comandos. Esto probablemente no es una buena para imprimir, es probable que sea algo, como deberá ingresar un número entero en la línea de comandos. Voy a terminar allí. Y luego volver 1. Así que recuerde que al final de nuestra programa, si volvemos 0, ese tipo de indica el éxito. Y principal también automáticamente devuelve 0 si no lo hace. Así que aquí, estamos resintonizar 1 para indicar que ese no es el éxito. Y usted puede devolver lo que quieras, simplemente, 0 indica el éxito, y nada indica fracaso. Así que vamos a ejecutar esta versión de las cosas. Así que ahora, si no entramos en una línea de comandos argumento, te dirá correctamente nosotros, no la línea de comandos suficiente. No terminó la frase. Si no, si realmente pasamos una, puede completar el programa. Así que esto es como se puede utilizar argc en fin de validar el número de Argumentos de línea de comandos que repercusión efectiva. Así que vamos a hacer de este programa un poco más complicado, y mirar a la segunda iteración de las cosas. Así mismo, estamos no sólo imprimir el primer argumento de la línea de comandos. Aquí, estamos iterando de iguales i int 0, i es menor que argc, i más plus, y argv impresión, el índice i. Así que este patrón, de nuevo, esta es la misma patrón como antes, excepto que en lugar de llamar a la variable n, estamos usando argc. Así que esta es la iteración en cada índice en la matriz, y la impresión de cada elemento de la matriz. Y por eso, cuando nos encontramos este programa, bueno, No entré en cualquier línea de comandos argumentos, por lo que sólo imprime el nombre del programa. Si entro en un montón de cosas, que va a imprimir uno, cada uno en su propia línea. Aceptar. Así que vamos a echar un paso más allá. Y en lugar de imprimir cada argumento en su propia línea, vamos a imprimir cada carácter de cada argumento en su propia línea. Así que recuerde que argv es una matriz de cadenas. Entonces, ¿qué es una cadena, pero una matriz de caracteres? Así que eso significa que argv es realmente una conjunto de una matriz de caracteres. Así que aprovechando que, vamos a ignorar esto por ahora. Vamos a considerar la cadena argv 0. Así que si queremos llevar a cada carácter de argv 0 en su propia línea, entonces quiero para hacer el patrón de lo que estamos acostumbrados, i es menos de la longitud de la matriz, que en este caso, es de strlen, eso es no lo que yo quiero hacer, cadena s es igual a argv 0. Así que i es menor que la longitud de nuestro matriz, que en este caso es una matriz de personajes, i plus plus. Y así, como vimos la semana pasada, es ideal si nos movemos que strlen fuera de la condición, puesto que n será la adición de el strlen de s cada vez que vamos a través del bucle, y es No va a estar cambiando. Así que vamos a establecer es igual a n por aquí. Aceptar. Así mismo, estamos interactuando sobre cada índice de la matriz. Y por eso, si queremos imprimir cada carácter en dicha matriz, por ciento c es la bandera que queremos usar para los caracteres. Y ahora una i soporte va a ser el cadena, carácter de índice i, por lo que si el cuerdas eran hola. Entonces S 0 va a ser H, S soporte 1 habrá de correo, y así sucesivamente. Así que ahora queremos combinar estas dos cosas. Queremos imprimir cada carácter de cada argumento de la línea de comandos. Así que vamos a tener un bucle For anidado. Y convencionalmente, el primer contador Soy yo, el próximo va a ser j, n será el strlen de argv i, i es menor que n, i plus plus. Y ahora en lugar de imprimir argv i, por lo que argv soporte i va a la lista - que va a ser la línea de comandos-i th argumento argv i, j se va a ser el carácter j-ésimo de el argumento-i. Me desharé de esto aquí y ahora ya que nos ponemos en ese bucle. Así que es equivalente a los iguales de cuerda s argv i, y luego s soporte de j. Bueno, nosotros no tenemos que declarar este s variable. En lugar de ello, sólo tendremos que combinar estos dos en lo que teníamos, argv i, j. ALTAVOZ 1: [inaudible]. ROB BODEN: Bien dicho. Así que esto está roto. Si yo en realidad corrió, lo haríamos han dado cuenta de esto. Así que el contador que me importa en este particular para bucle es j, el iterador. Así que habría que tenga problemas, probablemente un bucle infinito, si nos no había fijado que. Es por eso que también estamos hablando sobre la depuración de hoy. Aceptar. Así que vamos a ejecutar este programa. Y seamos realmente agregar un printf separada aquí que se acaba de imprimir otra línea, ya que esto significa cuando ejecutar el programa, habrá un espacio en blanco línea entre cada carácter de cada argumento de la línea de comandos. Bueno, vamos a ver lo que eso significa. Oop. ¿Tienes algún bug. Error implícitamente declarando función de biblioteca strlen. Volviendo a nuestro programa, que se olvidó de incluir el hash string.h. Así string.h va a ser el archivo de encabezado que declara la función strlen. Bien, que compila. Ahora, vamos a ejecutarlo. Así que eso. Se va a imprimir nuestro nombre del programa, hola mundo. Se va a imprimir cada cosa, cada carácter, en su propia línea. Aceptar. Así que vamos a aprovechar esta realidad un paso más allá. Y en lugar de utilizar string.h, vamos a pensar en cómo nos gustaría implementar nuestra propia función strlen. Así que me voy a dar de inmediato una firma de función. Así que vamos a llamar en my_strlen, y es Va a tomar una cadena como argumento, y esperamos volver el longitud de esa cadena. Así que, ¿dónde está ese tipo? Sí. Aceptar. Así que recuerde de la diapositiva anterior de que También fue de la semana pasada, que un arreglo de caracteres, así, una cadena, así que digamos que esta es nuestra cadena s. Así que si s es la cadena, hola, a continuación, H-E-L-L-O, en la memoria, que va a ser, y a continuación, esta barra invertida 0 carácter. Entonces, ¿cómo hacemos para que la longitud de s? Bueno, el truco está en busca de este 0 contragolpe carácter, esta nula terminador. De modo que el algoritmo se va a ser algo así como unos pocos suficientes caracteres que - vamos a echar esta mano representan algunos mostrador, vamos a llamar a esta longitud int. Así, a partir de aquí, estamos va a iterar sobre nuestra cadena. Así que el primer carácter, es H, y no es de nuevo slash 0, por lo que la longitud es 1. Iterar hasta el siguiente carácter, E, y no es la barra invertida 0. La longitud es de 2. L, 3. L, 4. O, 5. Y, por último, llegamos a la barra invertida 0, por lo que eso significa, así, esta cadena ha terminado. Así que vamos a volver 5. Así que en realidad la aplicación que, en primer lugar, mi longitud n es igual a 0, la mano derecha. Y vamos a repetir - ALTAVOZ 1: [inaudible] ROB BODEN: Oh, disparar. Buena decisión. Boom. Así longitud n es igual a 0. Así que ahora, la duración, pero s no igual y luego, la barra invertida 0. Así que recuerde, esta barra invertida 0, se trata de una carácter real, e indica el final de la cadena. Al igual que, también, la barra invertida n es un personaje real. Backslash 0 va a indicar Al final de nuestra cadena. No quiero poner eso ahí. Y mientras que s indexados por la longitud no es igual al terminador nulo, sólo vamos a incrementar la longitud. Así pues, al final de nuestro programa, longitud finalmente se va a ser 5 en este caso. Y acabamos volveremos longitud. Aceptar. Así que ahora aquí, no lo sé hacer my_strlen. Vamos a compilar para asegurarse todo funciona sin problemas. Estaba haciendo en 2? ¿O era que 1? Eso debería bastar. Está bien. Así que esto es argv 2. Funciona como se esperaba, a pesar de era que el que yo hacía en? Sí. Aceptar. Esta versión de lo que no tenía la línea nueva después de printf, pero no hace ninguna diferencia. Aceptar. Así trabajó como se esperaba. Ahora incluso podemos combinar esta un paso Además, cuando resulte aviso aquí, bueno, primero, estamos agarrando el strlen de argv i, y entonces estamos interactuando sobre cada carácter en la cadena. Así que en vez de hacer eso, ¿y si nos simplemente combinar esta lógica de la espera hasta que llegamos a la barra invertida 0 derecho en este bucle? Así iterar mientras argv i, j hace es igual a 0 barra invertida. Así que vamos a ejecutar en primer lugar. Está bien. Así que aquí, esta condición está diciendo - vamos a aclarar eso. Así que ahora, que esto sea nuestra argv. Así que cuando me acaba de ejecutar ese programa antes, argv es un array de cadenas. Y así, si lo ejecuto con argv slash dot 2, hola mundo, entonces el argv sí es la longitud 3, por argv cero, hola, y en el mundo. Y dentro de cada uno de estos índices, es decir, en sí una matriz, donde esto va a ser punto, esto será slash, no sé si esa era la dirección correcta, me no creo que era. A-R-V tablero, necesita más espacio. Vamos a cortar en el array. Tablero 0, y luego barra invertida 0 A-R-V. Y entonces en el caos será hola. Digamos, H-E barra invertida 0. Y, por último, W-O barra invertida 0. De modo que el algoritmo que sólo escribimos, el anidado bucles, lo que están haciendo es, en primer lugar tenemos la contador i y j a continuación. Esto sería más fácil con código en el pantalla, Volvamos a esto. Aceptar. Entonces noto que i es el iterador que es iterar sobre cada comando argumento de la línea. Y j es la iteración iterador sobre cada carácter en que argumento de la línea de comandos. Así que lo que esto printf más interna está haciendo Es decir, tenemos printf argv 0 0, printf argv 0 1, printf argv 0 2 0 3 0 4, 0 5, 6 0, pero ahora, argv 0 7 va a igualdad de barra invertida 0. Así que salimos de ese bucle, y ahora itera a 1. Y ahora vamos a imprimir argv 1 0, argv 1 1 - bueno, ahora, desde que me corté hola corta, argv 1 2 El nuevo va a ser barra invertida 0. Y así, se incrementa i y continuar, y así sucesivamente, hasta que nos imprimimos todos mundo, y los tres son de línea de comandos argumentos, y vamos a salir del el bucle más externa, y terminar nuestro programa. Aceptar. Así que vamos a llegar hasta aquí. Así obtendrá una cierta familiaridad con argumentos de la línea de comandos en este conjunto determinado problema. Ahora, la depuración. Así que es probable que ya haya tenido que hacer cierta depuración con su anterior establece problema. Y una manera muy fácil de depuración, en primer lugar, echemos un vistazo a un programa de buggy. Bueno, caminar a través de este programa, vamos a pedir al usuario para una entero, agarra ese entero, y luego, arbitrariamente, tenemos un bucle while que sólo va a disminuir i hasta que sea igual a 10. Vamos a suponer que estoy introduciendo un número entero mayor que 10. Así DECREMENT i hasta que sea igual a 10. Y luego tenemos otro bucle while que, si bien i no es igual a 0, estamos va a disminuir en un 3 i. Así que si ves la intención del error aquí, es que esto va a decrementar i para ser 10, y entonces esta voluntad bucle while i decremento del 10, a 7, a 4, a 1, a negativo 2, 5 a negativo, y así sucesivamente, hasta el infinito negativo, ya que voy a En realidad nunca ser igual a 0. Y luego, al final de este programa, tenemos la función foo que es pasando impresión que yo. Así que este es un programa corto y trivial, y el error es obvio, sobre todo después de que acabo de dijo cuál era el error. Sin embargo, la intención aquí es, bien, esto podría realmente se ven como parte de su soluciones de codiciosos de la última conjunto de problemas, y tal vez usted no tenga algunos bucle infinito en su programa, y no tienes ni idea ¿qué está causando. Así que una técnica de depuración muy útil es añadir sólo printfs todo su código. Así que aquí quiero un printf fuera primer bucle while. Y yo quiero un printf, y yo sólo voy a imprimir i. Incluso me voy a hacer primero while, i. En el exterior, mientras que el segundo bucle. Una vez más, imprima el interior de aquí, el valor de i. Y vamos a correr esto. Debug slash Así punto. Introduzca un número entero. Vamos a hacer 13. Y de golpe. Vemos que estamos bucle infinito dentro del segundo bucle while. Así que ahora que sabemos lo que el error es. Pero la depuración printf es perfectamente bien, pero una vez que sus programas obtienen más largo y complicado, hay soluciones más sofisticadas a hacer las cosas de trabajo. Así que vamos a eliminar todos estos printfs. Y vamos a asegurarnos de que no lo hice romper nada. Aceptar. Así que el programa que vamos introducir se llama GDB, para GNU depurador. Bueno, en realidad, vamos a eliminar de depuración para una segunda, y hacer de depuración de nuevo. Bueno, en realidad en primer lugar, una buena lección en los argumentos de línea de comandos. Tenga en cuenta que este comando Clang es compilar todo se está pasando en la línea de comandos, estos valores argumentos de la línea de comandos. Entonces, ¿cómo se va a utilizar argumentos de la línea de comandos, como se lo hizo antes, y lo que quieras en PSET 2, así es como Clang los está usando. Así que darse cuenta de que esta primera bandera, guión ggdb3, lo que está diciendo es: Clang, usted debe compilar este archivo con el intención de que con el tiempo se necesario para depurarlo. Así que, mientras usted tiene esa bandera, entonces podemos GDB depuración. Y va a abrir el depurador de GNU. Así que hay una gran cantidad de comandos que tiene que acostumbrarse. El primero que probablemente inmediatamente necesitar está en Ejecutar. Entonces, ¿qué es Ejecutar va a hacer? Esto va a empezar nuestro programa. Corred de tal manera, al iniciar el programa, el programa nos pide un número entero de 13. Y entonces es un bucle infinito como era de esperar, excepto Quité el printfs, por lo que ni siquiera vemos eso. Salió con normalidad. Oh. Es posible que envuelve todo el revés, de nuevo a - ignorar eso. Supongamos que no salir normalmente. Hay una respuesta complicada que eso. Así que ahora, eso no es muy útil. Por lo que sólo se ejecuta nuestro programa en el interior de Este depurador no nos ayuda en cualquier manera, ya que podríamos haber hecho dot slash depuración desde fuera del BGF. Así el comando que probablemente te - y voy a salir de esta. -Control d o dejar de fumar, tanto en el trabajo. Así que vamos a abrir de nuevo. Otro comando que probablemente inmediatamente querer acostumbrarse es Break. Así que vamos a romper el principal, por ahora, y luego voy a explicar eso. Bueno, aquí vemos establecemos un punto de interrupción en esta línea en debug.c. Entonces, ¿qué significa ruptura es que cuando escribir ejecutar, el programa va a continuará funcionando hasta que Me golpeó un punto de interrupción. Así que cuando llegué a la ejecución, el programa se inicia, y a continuación, se rompe tan pronto como se entra en la función principal. Romper principal va a ser algo usted bastante común hace. Y ahora, para presentarle a algunos más comandos. Nótese aquí, que está diciendo que se rompió en la línea 11, que es printf, introduzca un entero. Entonces el comando siguiente va a ser la forma en nos vamos a la siguiente línea de código. Esto va a permitir que demos un paso a través de nuestra línea de programa por línea. Así que la próxima. Ahora la línea 12, que vamos para obtener el número entero. Siguiente. Y si simplemente pulse la tecla Enter de nuevo, que va a rehacer la última cosa que hizo. Así que no tengo que escribir al lado cada vez. Así que entrar en un entero de 13. Así que ahora, la línea 14, mientras que i es mayor de 10, y voy a hacer a continuación. Y vemos que vamos a disminuir i. Así que vamos a disminuir i de nuevo. Así que ahora, otra utilidad comando es Imprimir. Así impresión se va a imprimir el valor de la variable. Vamos a poner de manifiesto el valor de i variable. Vamos a imprimir i. Se va a decir i es 11. Ahora estamos de nuevo en Siguiente, mientras i es mayor que 10. Así que es aún mayor que 10, ya que es 11. i minus minus. Vamos a imprimir i de nuevo. Como era de esperar, es 10. Así que ahora, al lado. Se va de nuevo a la condición, i es mayor de 10, pero i es ahora 10, por lo que no es mayor que 10, por lo que esperamos que se caiga del bucle while. Y ahora estamos por debajo de la línea de código. Y otro comando, Lista, sólo va para mostrar la anterior y siguiente par de líneas de código, en caso de que perdió a sí mismo. Así que sólo salía de este bucle while, y ahora hemos entrado en esta while, línea 18. Así, mientras que i no es igual a 0. Y, a continuación, i es igual a i menos 3, y vamos a notar, esto sólo va a seguir adelante. Y podemos imprimir i. Cada comando tiene una especie de atajos. Entonces p es la abreviatura de impresión. Así que puede p i. Hemos de tener la celebración de n, o seguir haciendo en Siguiente. Imprimir i de nuevo. Usted ve ahora es negativo 167. Así que esto va a durar para siempre, pero no realmente para siempre, ya que acaba de ver, es terminará en realidad en algún momento. Así que empieza GDB. Pero vamos a hacer una cosa más en GDB. Uh, de depuración. Así, en este caso particular, la bucle infinito pasó a estar dentro de la función principal. Y por ahora, sólo aceptar que que soy va a mover el bucle infinito en la función foo. Sólo recuerde que, al final de este programa, bueno, esto fue originalmente llamar a foo, que era va a imprimir i. Pero ahora estamos llamando foo, que es va a disminuir i hasta que sea 0, y a continuación, imprimir esa variable. Aceptar. Guarde eso. Hacer debug. Y ahora, de depuración gdb. Aceptar. Así que si sólo Corro entonces yo no voy a poder dar un paso en realidad a través de mi línea por línea de programa. Así que vamos a romper en el principal, y escriba plazo. Así que pasar por esto, printf, introduzca un entero, obtener el número entero de 13. Así que vamos a seguir decremento hasta que i es mayor que 10. Entonces vamos a caer a través de la while, y llegar a la línea - vamos a abrir para arriba en una ventana separada. Así que disminuye hasta que yo ya no era mayor que 10, y luego llamada a la función, foo. ¿Y qué pasó tan pronto como me golpeó function foo, bueno, me llama foo, y entonces ya no tuve control sobre GDB. Así que tan pronto como me golpeó en Siguiente en esta línea, cosas continuaron hasta que pasó esto, donde el programa salió al - asuma que no existía el tiempo. Usted lo vio hacer una pausa por un momento sin embargo. Entonces, ¿por qué he perdido el control sobre el programa en ese momento? Bueno, cuando escribo a continuación, que se destina a la siguiente línea de código literal que se ejecutará. Así que después de la línea 21, la siguiente línea de código que se ejecutará es la línea 22, que es, que sale de principal. Así que no me quiero ir a la siguiente línea de código. Yo quiero entrar en la función, foo, y luego también paso a paso esas líneas de código. Así que por eso, tenemos una alternativa. Dejemos de eso otra vez. Romper principal. Uh, 1, siguiente, siguiente, el 13, al lado, siguiente, siguiente, con cuidado, antes de echarnos a foo línea. Aceptar. Así que ahora, que estamos en la línea 21, donde llamamos foo. No queremos que escriba al lado, ya que se acaba de llamar a la función foo, y ir a la siguiente línea de código. Lo que queremos utilizar es el Paso. Así que hay una diferencia entre el Paso y Next, donde el paso entra a la funcionar, y Next va sobre la función. Simplemente ejecuta la totalidad de la función y sigue subiendo. Así que paso nos va a traer en la función, foo. Y vemos aquí, ahora, estamos de vuelta en este bucle while que es, en teoría, va a continuar para siempre. Y si se golpea Paso, cuando ni siquiera es una función para llamar, entonces es idéntica al siguiente. Así que es sólo cuando usted está en una línea que está llamando a una función que Step va a diferir de Siguiente. Así Paso nos traerá aquí. Paso, paso, paso, paso, paso, paso, y Tendremos bucle infinito para siempre. Así que es posible acostumbrarse a que, como su forma de identificar bucles infinitos, es sólo la celebración de esta tecla Enter para ver dónde te quedas atascado. Hay mejores maneras de hacerlo, pero por ahora, esto es perfectamente suficiente. Y estilísticamente, para cumplir con Estilo 50, que debería haber hecho esto. Aceptar. Así que una última orden a introducir. Bueno, vamos a gdb depuración pulg Así que en lugar de romper en principal, si conocer la función foo es también el problema, entonces yo podría tener sólo dijo, romper en foo, en su lugar. Digamos que yo rompo en tanto principal y foo. Así que usted puede configurar tantos puntos de interrupción como quieras. Cuando escribo plazo, que va para parar en el - ooh, vamos a volver a compilar, ya que He cambiado las cosas. Usted verá esta línea, Advertencia, fuente archivo es más reciente que la ejecutable. Así que eso significa que me fui de aquí y cambiado estos para ajustarse a Estilo 50, pero no a compilar el programa. Así GDB me hace consciente de eso. Dejaré, hacer debug de nuevo, golpear debug gdb. Aceptar. Así que ahora, de vuelta a lo que estaba haciendo. Romper principal foo, romper. Ahora bien, si ejecuto el programa, por lo que es va a continuar hasta que realiza un punto de interrupción. Ese punto de interrupción pasa a ser el primero en principal. Ahora, en vez de hacer las siguiente, siguiente, siguiente, siguiente, siguiente, hasta que llegué a foo, I puede escribir continuar, que continuará hasta llegar a la siguiente punto de interrupción. Tengo que introducir el número entero primero. Continuar continuará hasta que llegué a la siguiente punto de interrupción, que es que función de foo. Así Run se ejecutará hasta llegar a un punto de ruptura, pero sólo se escribe de ejecución cuando vas a empezar el programa y, a continuación, a partir de entonces, es continuar. Si acabo de hacer romper principal y luego corrió, se va a romper en principal, y luego continuar. Como yo no tengo un punto de quiebre en foo, introducir el número entero, entonces ahora estoy no va a romper a foo. Sólo va a infinito bucle hasta que. Aceptar. Así que eso es Introducción a GDB. Usted debe comenzar a usarlo en sus boletines de problemas. Puede ser muy útil para identificar errores. Si realmente justo, línea por línea, vaya a través de su código, y comparar lo que es sucediendo realmente con lo que se espera a suceder, entonces es bastante difícil pasar por alto sus errores. Aceptar. Así que la semana pasada David hizo subir este cosas secretas Criptografía de clave para la primera vez, donde no queremos contraseñas sólo pueden almacenar en nuestro computadora en algún archivo de texto sin formato, donde alguien puede venir y simplemente abrirlo y leerlo. Lo ideal es que se cifran de algún modo. Y en ejercicios 2, se le trata con un método de cifrado, O, bueno, dos métodos, pero que no son tan grandes. Si lo hace la edición hacker, eres también va a estar tratando con descifrar algunas cosas. Así que la cuestión ahora es, bueno, incluso si tenemos el cifrado más potente algoritmo en el mundo, si usted elige un particularmente pobre contraseña, entonces no le ayudará mucho, ya que las personas todavía será capaz de entenderlo. Aunque viendo la cadena cifrada y parece un lío de basura que no significa nada para ellos, si aún sólo tiene que probar un par de contraseñas para entenderlo, entonces usted no son muy seguras. Así que ver un video que hace que ese punto. [REPRODUCCIÓN DE VÍDEO] -Casco, usted Demonio. ¿Qué está pasando? ¿Qué estás haciendo con mi hija? Me-Permitidme que introducir el brillante joven cirujano plástico, el Dr. Phillip Schlotkin, el más grande de la nariz hombre de trabajo en todo el universo, y Beverly Hills. -Su Alteza. -Nariz trabajo? No entiendo. Ella ya ha tenido una cirugía de nariz. Fue un dulce dieciséis presente. -No. No es lo que piensas. Es mucho, mucho peor. Si no me das la combinación de el escudo de aire, el Dr. Schlotkin se dar a su hija de vuelta a su antigua nariz. -No. ¿De dónde sacaste eso? -Muy bien. Te lo diré. Te lo diré. No, papá. No, no debes hacerlo. -Tienes razón, querida. Voy a extrañar su nueva nariz. Pero yo no le voy a decir la combinación, no importa qué. -Muy bien. Dr. Schlotkin, haz lo que quieras. -Es un placer. [TOOLS se agudizó] -No. Espere. Espere. Te lo diré. Te lo diré. -Yo sabía que iba a funcionar. Está bien. Dámelo. -La combinación es uno. -Uno. -Uno. -Dos. -Dos. -Dos. -Tres. -Tres. -Tres. -Cuatro. -Cuatro. -Cuatro. -Cinco. -Cinco. -Cinco. -Así que la combinación es uno, dos, tres, cuatro, cinco. Esa es la combinación más estúpida Que he oído en mi vida. Ese es el tipo de cosa que un idiota tendría en su equipaje. -Gracias, Alteza. -¿Qué hiciste? -Apagué la pared. -No, no lo hiciste. Apagó la película entera. -Debo de haber pulsado el botón equivocado. -Bueno, lo puso de nuevo. Coloque la película de nuevo. -Sí, señor. Sí, señor. -Vamos, Arnold. Venga, Gretchen. Por supuesto, usted sabe que yo seguiré tener que cobrarle por esto. [VIDEO PLAYBACK FIN] ROB BODEN: Muy bien. Así que ahora que ya estamos hablando de seguridad en algunas maneras, agradable pequeño cartel de la película, por lo que en los últimos años día, estos temas con la NSA el seguimiento de todo. Puede ser difícil para sentir que tener algún tipo de intimidad en el mundo en línea, aunque no podría decir que la mayor parte de los detalles de PRISM. Así que ir más allá de PRISM, no vamos a hablar de eso, ahora pensar en su computadora portátil. Así que aquí, quiero cambiar en mi cuenta real, con mi pequeño pingüino. Así que tengo una contraseña establecida, y que contraseña es lo que yo quiero que sea. Pero recuerde que lo que estoy tala con, por lo que este inicio de sesión pronta, es un programa. Es un programa que fue escrito por alguna persona. Y así, esta persona, si son particularmente malicioso, que pudieron han dicho, está bien, así que si la contraseña que entro es igual a mi contraseña real, o es igual en cierta contraseña especial - David es increíble o algo - luego dejarlos entrar Así que un programador malicioso podría tener el acceso a todas sus Macs, o De Windows, o cualquier cosa. Así que no es una gran preocupación, ya que, Quiero decir, este es el programa de inicio de sesión eso se envía con OS X, cientos o miles de personas tienen revisado este código. Y así, si, en el código en alguna parte, usted decir si esta cadena es igual a los iguales David es impresionante, inicio de sesión, entonces alguien está va a ser, como, espere. Esto no está bien. Esto no debería estar aquí. Así que esa es una manera de hacer las cosas a ser una especie de seguro. Pero piensa en programas incluso que usted escribe. Digamos que usted escribió el programa de inicio de sesión. Así que este programa de inicio de sesión que usted escribió, por lo que, obviamente, usted es un buen programador. No vas a poner cualquier malicioso si x es igual a es igual a David es impresionante en el código. Pero este programa, lo que se hace utilizar para compilar este programa? Algo así como Clang. ¿Y qué si la persona que le pasó a escribir Clang especial revestido en Clang algo así como, si estoy recopilando la programa de inicio de sesión, introduzca el código en el programa de inicio de sesión que dice, si x es igual a es igual a David es impresionante? Así que no es del todo todavía, pero tenemos el mismo emitir aquí, donde Clang, bueno, miles, si no decenas de miles de personas, han mirado Clang, tienen mirado a sus líneas de código, y dijo: bien, no hay nada malo aquí. Obviamente, nadie está haciendo algo tan malévolo. Pero, ¿qué se CLANG sí mismo, como, ¿y si compilo Clang? ¿Qué pasa si tengo algún compilador que compila Clang que se inserta en Clang este truco especial que dice, está bien, cuando compilo Clang, entonces el ejecutable se produce especialmente debo mirar dentro del programa de usuario y la inserción esta contraseña, es igual a los iguales Dave es impresionante? Así que recuerde que su propio compilador necesita ser compilado en algún momento. Así que si lo que usted elija para compilar Clang con, sí es dañino, entonces usted podría ser atornillado el conjunto camino por la línea. Así que aquí tenemos a Ken Thompson y Dennis Ritchie. Así que esta es una foto icónica. Dennis Ritchie está a la derecha. Él es uno de los principales - prácticamente escribió C. Así que usted puede darle las gracias por esta clase. Ken Thomson está a la izquierda. Los dos de ellos, básicamente, escribió UNIX. Bueno, eran los principales contribuyentes en UNIX. Hubo algunos otros. Así que Ken Thompson, en algún momento, gana el Premio Turing. Y el premio Turing, siempre he escuchado se hace referencia de esta manera, es el Premio Nobel de la informática. Así que en el Premio Turing, que tiene que dar su discurso de aceptación. Y se le da a este muy famoso discurso Ahora, llamado Reflexiones sobre Confiando Trust, que hemos vinculado a en el sitio web del curso. Y en este discurso, se dice, está bien, así que escribí UNIX, y ahora todos que la gente está usando UNIX. Ahora, recuerda hoy que Linux es un descendiente directo de UNIX. OS X utiliza directamente UNIX. Windows no hace mucho, pero mucho de ideas fueron tomadas de UNIX. Así que se sube al escenario y dice, bien, escribí UNIX. Y para que lo que ustedes saben, yo soy podrá iniciar sesión en cada y cada uno de los equipos. Desde que me puse una de ellas especial si x es igual a es igual a Ken Thomson es impresionante, entonces yo estoy autorizado para iniciar sesión. Así que las personas son como, bueno, ¿Cómo hiciste eso? Nos fijamos en el programa de inicio de sesión y nada está allí. Es como, bueno, he modificado el compilador para ingresar en el programa de inicio de sesión para que el programa de inicio de sesión tendrá ahora que x es igual a es igual a Ken Thompson es impresionante. Y dicen, bueno, eso no es cierto. Estamos pensando en el compilador y el compilador no tiene líneas de código de esa manera. Es como, OK, pero ¿cuáles son usted compilar el compilador? Y piensan, y él es, como, bueno, Yo soy el que te dio el compilador está utilizando para compilar el compilador, por lo está compilando un compilador, que sí es malicioso, y la voluntad romper el programa de inicio de sesión. Así que, básicamente, en ese momento, no hay de ninguna manera se puede mirar en la fuente código del programa de inicio de sesión para ver lo que está mal. Ni siquiera se podía mirar en la código fuente del compilador para ver lo que está mal. Usted tendría que mirar a la máquina código, el binario real de la compilador compilado para ver, espera, éstos líneas de código no deberían estar aquí. Pero Ken Thompson llevó un paso más allá y dijo, bueno, hay estos programas especiales que en realidad ayudará a leer el binario de los programas, y por lo que si alguien utiliza ese programa para leer el binario, verían estos líneas de código. Modificó los programas que decir, todo Está bien, si usted está buscando en la compilador, no muestran este particular, conjunto de binario. Así entonces usted necesita para tomar ese paso más allá y que, básicamente, que podría tener múltiples niveles de indirección tomadas, y en algún momento, nadie en realidad va a ser la comprobación. Así que la moraleja de la historia es, eres No voy a estar escribiendo Clang en esta clase. Usted va a estar usando la escalada Clang mucho en esta clase. Para todos ustedes saben, Clang es un malicioso programa que está saboteando cada solo programa alguna vez has compilado. Y para salir de ese mismo siniestro nota, nos vemos el miércoles. [Aplausos] ALTAVOZ 2: En la siguiente CS50. ALTAVOZ 3: No te atrevas a decir eso. Usted puede hacer esto. Usted ha hecho esto antes, usted puede hacer esto hoy en día, usted puede hacer esto mañana. Has estado haciendo esto durante años. Sólo tienes que ir allí y hacerlo. Usted puede hacer esto. [REPRODUCCIÓN DE MÚSICA]