[Powered by Google Translate] [Semana 2, continuación] [David J. Malan, Harvard University] [Esta es CS50. - CS50.TV] Está bien. Esto es CS50, y este es el fin de semanas 2. Si usted espera a tener hambre alrededor de esta hora mañana, Sabemos que vamos a celebrar como un pequeño grupo de mañana, jueves, 1:15 pm. Hay un URL aquí si desea confirmar su asistencia. El espacio es limitado, así que por favor, perdóname si el formulario se llena en el momento de rellenar esto. Otra URL, sin embargo, que podría ser de interés es la siguiente. En casi un mes, el curso se va a poner a disposición tanto más ampliamente a través de EDX, a través del cual la gente en el Internet será capaz de seguir adelante, participar en el curso muy activamente, de hecho. Se va a utilizar el aparato CS50 CS50 y Comenta y la mayoría de las herramientas de software diferentes que ya han estado usando este semestre. Y una de las iniciativas que nos gustaría tomar como un experimento de este año es ver hasta qué punto podemos traducir el contenido a otras lenguas habladas y escritas. Así que si usted podría tener interés en participar en este proyecto por lo que vamos a ofrecer transcripciones en inglés y subtítulos para las conferencias del curso y los pantalones cortos y seminarios y secciones y similares, si usted habla con fluidez y escribir con fluidez otro idioma, nos encantaría participar en este proyecto mediante el cual se toma en uno o más de los videos, traducirlos a un lenguaje que conozco bastante bien. Para que os hagáis una idea de la interfaz, hay una interfaz de usuario basada en web que vamos a utilizar, que creará esencialmente una interfaz de usuario de esta manera. Esto me estaba enseñando algunos de Halloween hace, y en el lado derecho hay en negro al lado de estas marcas de tiempo, podrás ver las varias cosas que salieron de mi boca ese día, y luego por debajo de la misma será capaz de traducir a otro idioma exactamente lo que la cartografía es el medio, en este caso, Inglés y, por ejemplo, el español. Así que en realidad es un muy fácil de usar herramienta. Puede rebobinar y avanzar rápidamente muy fácilmente con el teclado. Así que si usted desea participar en este experimento y que sus palabras visto y leído por miles de potenciales personas por ahí, por favor, no dude en participar. Una palabra acerca del gatito del lunes. Para que no nos han enviado un mensaje demasiado miedo, dan cuenta de que, como indican las horas de oficina y como sugieren las secciones, el diseño del recorrido es mucho para que los estudiantes colaborando y hablando de trabajar a través de los boletines de problemas y los problemas juntos, y realmente la línea sólo se reduce a, una vez más, el trabajo que en última instancia debe ser presentar el suyo propio. Y así, con toda sinceridad, en horario de oficina es totalmente normal, está totalmente de esperar, incluso, a estar chateando con algún amigo a tu lado. Si él o ella está luchando con algunos temas y usted es como, "Oh, bueno, te voy a dar una idea de alguna línea de código que escribí," eso está bien, que pasa, y eso es muy favorable, creo que, con el proceso de aprendizaje. Cuando la línea se cruza cuando la cabeza es una especie de inclinación hacia aquí durante unos segundos demasiados o minutos para que realmente haber sido sólo una oportunidad de desbloqueo para su amigo, y, ciertamente, cuando las cosas se intercambian a través de correo electrónico y Dropbox y similares, allí también es la línea. Así que por todos los medios se sientan cómodos y se sienten animados a charlar con los amigos y compañeros acerca de conjuntos de procesadores y más y sólo se dan cuenta de que lo que en última instancia, presentar realmente debe ser el producto de su creación y no otra persona. Y así uno de los problemas específicos de dominio para pset2, que saldrá mañana por la noche tarde, es sumergirse en el mundo de la criptografía, que es el arte de cifrar o codificar la información, y esto en última instancia se relaciona con el mundo de la seguridad. Ahora, la seguridad para la mayoría de nosotros se presenta en forma de mecanismos bastante mundanas. Todos nosotros tenemos nombres de usuario y contraseñas, y todos tenemos nombres de usuario y contraseñas muy malos, muy probablemente. Si la contraseña es la misma en varios sitios web, que probablemente no es la mejor idea, como veremos hacia el final del semestre. Si la contraseña se escribe en una nota adhesiva - no es broma - en el monitor, que tampoco es necesariamente el mejor diseño, sino un fenómeno bastante común. Y si usted no está utilizando la criptografía para cifrar las contraseñas, son particularmente vulnerables. Así que si usted piensa que está siendo súper inteligente por tener un documento de Word oculto en algún lugar de su disco duro que tiene todas sus contraseñas pero está en una carpeta que nadie va a mirar, eso también no es un mecanismo muy seguro. Y así lo pset2 presentaré es este arte de la criptografía información y luchando para que cosas como contraseñas son tanto más seguro. El contexto aquí es que con los datos inseguros llega una oportunidad para cifrar y para trepar. Y por lo que este, por ejemplo, es un ejemplo de un mensaje cifrado. En realidad, esto dice algo en Inglés, pero es evidente que no es totalmente obvio. Y vamos a llegar al punto de partida hoy a desmenuzar lo que este mensaje secreto aquí es. Pero en el mundo real de las computadoras, las cosas no parecen que incluso podrían ser frases en inglés. Por ejemplo, esto es lo que puedes encontrar en un estándar de Linux o Mac o UNIX en un archivo que fue en otro tiempo llamado el archivo de contraseñas. Hoy en día se han trasladado a otros lugares. Pero si nos fijamos en el lugar correcto en un sistema, podrás ver no sólo su nombre de usuario o la de otras personas en el sistema, pero usted verá una versión encriptada de su contraseña. En efecto, la cripta hay palabra sugiere que las siguientes cosas se cifra, y esta serie de letras aparentemente al azar y caracteres y números, y así sucesivamente sólo se puede descifrar en general por conocer algún secreto - una palabra secreta, un número secreto - Y de hecho, el arte de la criptografía en última instancia se reduce a confiar de algún tipo y saber algo que nadie más lo hace. Así que vamos a explorar en detalle un poco más hoy y en el conjunto de procesadores por venir. Y ahora una palabra sobre pasa / falla. Sobre todo porque algunos de ustedes han buceado en pset1, el aparato, y un mundo muy nuevo para usted, se dan cuenta que las frustraciones y confusiones y sólo dificultades técnicas son bastante de esperar, especialmente con el conjunto de procesadores en primer lugar, donde hay tantas cosas nuevas, sólo a familiarizarse con ls y cd y todos estos comandos arcanos y un nuevo ambiente, y eso es independiente del material real y la programación en sí. Así cuenta también que hay ciertamente horas de oficina que existen como una estructura de soporte. Secciones comenzará el próximo domingo. Pero lo más importante, si te sientes solo que este no es el mundo para ti, darse cuenta de que en realidad se limita a tomar tiempo. Y si no fuera por esta oportunidad hace años para mí de tomar una clase de paso / falla, Honestamente, nunca me hubiera puesto un pie en el aula. Y usted puede cambiar esto para arriba hasta, digamos, el quinto lunes del curso, así que si usted está en el borde ahora, darse cuenta de que en lugar de cabeza en algunas otras aguas por completo, Qué duda considerar simplemente cambiar para pasar / fallar. Una vez más, no hay realmente esta cultura aquí en Harvard de tomar las cosas de pasa / falla ya que todo el mundo quiere alcanzar o superar, pero, francamente, esto es una maravillosa manera de probar algo que puede no ser familiar para usted, y usted va a terminar haciendo, en la mayoría de los casos, bastante bien, quizás mucho a su sorpresa. Y en términos más concretos, lo que creo que pasa / no pasa generalmente lo hace, especialmente en lo que podría haber experimentado con pset0, si se pone en 10 horas, 15 horas, 25 horas en algún conjunto de procesadores y estás golpeando su cabeza contra la pared y se está poniendo súper altas horas de la noche pero que ha tomado el conjunto de procesadores 90% del camino y simplemente no puedo entender una cosa, pasa / no pasa realmente toma el borde de una clase como esta, donde se puede ordenar felizmente de decir: "Bueno, yo sé que no es perfecto, pero trabajé el culo en esto, estoy bastante contento con el lugar donde terminó " y que cumpla con las expectativas de pasa / no pasa. Así que tenlo en cuenta. Está bien. Así que aquellos de ustedes que han tenido dificultades para utilizar la Universidad de Harvard Wi-Fi, Sabemos que hay un SSID CS50, una conexión Wi-Fi, flotando que podría tener mejor suerte para. Es un poco irónico que la contraseña para esto, si usted desea probar la conexión a este para obtener mejores velocidades - y háganos saber si no es mejor - es 12345, todo el camino hasta el 8 8 porque es más seguro que 5. Así que si usted necesita la contraseña de Wi-Fi, conexión inalámbrica a CS50 aquí, 12345678, e incluir en CS50 Hable si usted todavía tiene problemas de conectividad intermitente, y vamos a dejar que los poderes que se conocen para este espacio. Está bien. Así que un reclamo rápido, especialmente para aquellos de ustedes que son chicos o chicas fans de todas las cosas de Apple. Lo que desenterrado de hace unos años era este archivo aquí, iUnlock.c, sólo para tipo de concreto más y más complejos algunos de los programas en C más básicas que hemos estado escribiendo. Así que abrí este archivo, iUnlock.c. Está disponible en la página de Lecturas para hoy. En el lado izquierdo se ve una larga lista de funciones. Así que el tipo que escribió esto escribió una gran cantidad de funciones, más que principal. Él utilizó una gran cantidad de bibliotecas aquí, y, si empezamos a desplazarse a través de lo que esto es, es la primera, creo, crack para el iPhone original. Cuando se quería hacer jailbreak al iPhone original, lo que significa que desanudar de AT & T y en realidad instalar software especial en él y hacer cosas que Apple no quería que la gente lo hace, alguien se tomó el tiempo para averiguar exactamente cómo podrían explotar fallos de software, errores, errores en el software de Apple, y así nació iUnlock.c-- que si se compila en el equipo y lo instaló en un iPhone que estaba conectado a su ordenador a través de, por ejemplo, un cable USB, esto le daría privilegios de administrador o root en tu iPhone y le permiten hacer casi todo lo que quieras. Y así ha sido este fascinante gato y al ratón entre Apple y el resto del mundo, en particular en lo que, al igual que muchas empresas, tratar de bloquear sus cosas abajo de manera que sólo se puede hacer con ella lo que tenía planeado. Pero gracias a gente como esta y la comprensión de detalles de bajo nivel - y en este caso la programación C - y muchas de las construcciones conocidas que hemos empezado a jugar, usted puede realmente aprovechar el hardware de una manera mejor le parezca y no necesariamente una entidad corporativa. Así, por ejemplo, no tengo ni idea de lo que todo esto está haciendo, GetVersion pero suena bastante sencillo, y parece que esta es una función que esta persona escribió. Se necesita algún tipo de número entero como argumento, no devuelve nada, pero parece bucle con un bucle aquí y si una condición, si la interrupción condición, y de alguna manera se relaciona con los números de versión si se desplaza hacia abajo, a pesar de que muchas de estas palabras clave van a ser nuevos. Y hay un montón de funciones en aquí nunca hemos visto y que no vea nunca en el transcurso del semestre. Al final del día, sigue las mismas reglas y la lógica que hemos estado jugando con hasta el momento. Así que esto es demasiado viejo para romper sus 3s iPhone o días estos 4s 5s o pronto, pero sepan que todo está muy deriva de este mundo que hemos buceado en. Echemos un vistazo a un pequeño ejemplo más simple: éste, sólo para entrar en calor con un poco de sintaxis y también otro tipo de datos que ya hemos hablado, pero no han visto realmente en C. Se trata de un archivo llamado positive1.c, y, por los comentarios en la parte superior esto sólo requiere que el usuario proporcione un número positivo. Así que es un ejemplo de un bucle do-while, que es agradable para los programas de usuario interactivas donde tiene que decirle al usuario que haga algo, y si ellos no cooperan les gritas o rechazar su entrada. Un ejemplo: yo voy a hacer líneas 19 a la 24 siempre y cuando el usuario no se me ha dado un número positivo. Este detalle aquí en la línea 18, ¿por qué yo declaro n por encima de este bucle entero construir en contraposición a la derecha al lado de la línea 22 en el que realmente importa para obtener n? Si. [Estudiante] Scope. >> Si, por lo que este problema de alcance. Y, en términos sencillos, ¿qué alcance se refiere? Si. >> [Respuesta de los estudiantes inaudible] >> ¿Puedes hablar un poco más alto? [Estudiante] Donde se puede acceder a esa variable. >> Perfect. Donde se puede acceder a una variable en particular. Y, en general, la regla general hasta ahora ha sido que el alcance de una variable se define por las llaves más recientes que he visto. Y así, en este caso, si he cometido el error de declarar n en la línea 22, la línea iba a funcionar. Me gustaría conseguir un int, por lo que lo pone en esa variable n en la línea 22, pero qué línea de código ahora no tendría ni idea de lo que estoy hablando? >> [Estudiante] 25. [Malan] 25, y resulta que 24 así porque en este caso cae fuera de las llaves. Así que un poco de una molestia, pero muy fácil de resolver con sólo declarar la variable fuera de la propia función. Ya veremos el día de hoy se puede ir un paso más allá y que incluso podría ser un poco perezoso. Y esto no es recomendable en general, sino que incluso podría volverse perezoso y poner una variable a nivel mundial, por así decir, no dentro de una función, no dentro de un bucle, sino en el propio archivo, fuera de todas las funciones que usted ha escrito, como lo hice aquí en la línea 15. Esto es generalmente mal visto, pero se dan cuenta que es una solución a veces a otros problemas, ya que con el tiempo veremos. Así que por ahora vamos a dejarlo así, pero vamos a ver si podemos reescribir esta sólo para empezar a expresarnos de manera diferente. Este programa, sólo para que quede claro, es positive1. Déjame ir por delante aquí y en mi ventana de terminal hacer positive1, Enter. Compila bien. Voy a correr positive1, pulse Enter. Exijo que me des un entero positivo. Diré -1. Eso no funcionó. 0, 99. Esto parece que funciona. Quizás no es la prueba más rigurosa, pero al menos es una comprobación de validez agradable que estamos en el camino correcto. Así que ahora vamos a seguir adelante y abrir la versión 2 de la presente, y lo que es diferente ya? Pone en práctica la misma cosa, pero lo que está saltando como claramente diferente esta vez? Esta bool en verde. Se destaca en verde, esta palabra clave se conoce como bool, que es un tipo de datos. No viene integrado en todas las versiones de C. Tienes que incluir una biblioteca específica. En nuestro caso, incluí la biblioteca CS50 para que tengamos acceso a bool. Sin embargo, en la línea 18, parece que tenemos un valor booleano llamado aquí agradecidos. Podría haber llamado a esta nada, pero me llamó agradecido sólo para transmitir algún tipo de significado semántico. Así que al principio de la línea 18, estoy agradecido al parecer no porque el valor agradecido Boolean se inicializa en false en la línea 18. Y entonces parece que lo que he hecho aquí, en las líneas 21 a 23 se acabo tipo de reescribir mi lógica. Así que no funcionalmente diferentes, pero en la línea 22 ahora compruebo si el int el usuario ha proporcionado es mayor que 0, entonces simplemente cambiar el valor de agradecer a true. ¿Y por qué lo hago? Debido a que en la línea 25, al parecer voy a comprobar una condición. ¿Es este bucle while agradecido es falso. Así que me propuso esto como una alternativa a la versión 1 porque es al menos un poco más intuitivo quizás, es un poco más de tierra en Inglés. Así que haga lo siguiente mientras no estás agradecido o agradecida mientras que es falso. Y esta vez yo también, aparentemente, no me importa recordar lo que el usuario escribió en porque no hay ningún aviso de n variable, lo que en realidad, una pequeña mentira piadosa allí. Funcionalmente, el programa es un poco diferente una vez que lleguemos al fondo de la cuestión porque no voy a recordar lo que n es. Pero yo quería demostrar que también en este caso a pesar de que hemos visto getInt y GetString se utiliza en el lado derecho de un signo igual hasta ahora para que recordemos el valor, técnicamente, no es estrictamente necesario. Si por cualquier razón usted no les importa para guardar el valor, lo que desea es comprobar el valor, observe que simplemente podemos escribir esto como getInt, abierto paren, paren cerca. Esta función va a devolver un valor, como lo hemos estado diciendo. Se te va a devolver un int. Y así, si mentalmente pensar de que esto ocurra, cuando escribo en 99, getInt devuelve el número 99, y por lo tanto conceptualmente, es como si mi código eran en realidad esto. Así que si 99 es en realidad mayor que 0, entonces se convierte en verdad agradecido, luego la línea 25 se da cuenta ooh, hemos terminado porque ahora estoy agradecido, y en la línea 26, que simplemente decir: "Gracias por el entero positivo!" lo que resultó ser. Ahora vamos a hacer el azúcar sintáctico leve aquí, por así decirlo. Vamos a ver si podemos limpiar esta línea 25 con esta variante de la tercera y última en positive3. Tenga en cuenta que la única diferencia ahora es qué línea de código? >> [Estudiante] 25. >> [Malan] Sí, 25. Y no hemos visto realmente este truco todavía, pero nos hicieron ver el signo de exclamación en lunes, que denota qué? >> [Los estudiantes] no. No >> o negación. Así que toma un valor booleano y voltear su valor. Cierto convierte en falso, falso se hace realidad. Así que esto, propongo, es aún un poco más intuitiva manera de escribir el código porque todavía agradecido inicializar en false, lo sigo haciendo lo siguiente, Puse agradecido a true cuando llegue el momento, pero ahora usted puede realmente sólo traducir el código verbal izquierda a derecha, mientras que (gracias!), ya que el punto explosión o exclamación denota la noción de no así que mientras no agradecido. Así que de nuevo, no hemos introducido nuevos conceptos en sí. Hablamos de Booleanos atrás cuando jugamos con Scratch, pero se dan cuenta ahora podemos empezar a escribir nuestro código de muchas maneras diferentes. Por tanto, y en pset1 si usted es una especie de lucha por descubrir la manera de escribir algún programa, más probable es que estás de suerte porque no puede haber cualquier número de soluciones que le puede suceder a. Por ejemplo, esto es sólo 3 de incluso el más simple de los programas. Está bien. Y ahora recuerdo el lunes nos fuimos en esta nota con valores de retorno. Así que para la primera vez que escribimos un programa que no sólo tiene principal; también tiene su propia función personalizada que escribí aquí. Así, en la línea 31 a la 34 He implementado una función de cubo. No es complejo. Es sólo a * a * a en este caso. Pero lo importante de esto es que estoy tomando de entrada en forma de un y me estoy volviendo salida en forma de * a * a. Así que ahora tengo la capacidad, tanto como solía hacerlo con prinf solo, llamar a esta función llamando a la función de cubo. Y la función de cubo tiene alguna información, y la función devuelve un cubo de salida. Por el contrario, printf acabo de hacer algo. No volvió todo lo que nos importaba, a pesar de que en un aparte que devuelve ningún valor; que acaba generalmente lo ignoran. Printf acabo de hacer algo. Tenía un efecto secundario de la impresión en la pantalla. En cambio aquí, tenemos la función de cubo, que en realidad devuelve algo. Así que para aquellos que están familiarizados con esto, es una idea bastante sencilla. Pero para aquellos menos familiarizados con la idea de pasar en las entradas y salidas de volver, vamos a tratar sólo algo simple super. ¿Hay alguien que viene cómodo en el escenario brevemente? Usted tiene que estar cómodo con una cámara en usted también. ¿Sí? Bien. ¿Cuál es tu nombre? >> [Estudiante] Ken. >> Ken. Está bien. Ken, vamos arriba. Ken va a ser una función del tipo aquí. Vamos a seguir adelante y hacer esto. Vayamos un poco sofisticado. Gusto en conocerlo. Bienvenido al centro del escenario. Está bien. Vamos a golpear el botón aquí. Está bien. Así que aquí tienes una pizarra moderna, y lo que yo soy es la función principal, por ejemplo, y no tengo un iPad en la mano. Yo no me acuerdo cómo - Bueno, no puedo decir que. Yo realmente no tengo buena letra, y por lo tanto, quiero que imprimir algo en la pantalla para mí. Estoy siendo el programa principal, y yo voy a tener que decir esto escribiendo en mi garabatos y luego pasar que una entrada. Tan tonto aunque este ejercicio es, la noción de funciones y llamar a una función y devuelve una función realmente se reduce a esto. Estoy principal, que acabo de escribir printf, entre comillas algo en la pantalla, Estoy ejecutando este programa, y ​​tan pronto como se llama printf, Toma un argumento o un parámetro a veces entre comillas dobles. Aquí está el argumento. Lo estoy pasando a Ken. Él es un cuadro negro escrito un número de años que al parecer sólo sabe imprimir cosas en la pantalla. Así que ejecutar. Eso no es malo. Muy bueno. Así que ahora se lleva a cabo la ejecución de Ken. ¿Tiene que darme nada a cambio? No es que hemos visto hasta el momento. Una vez más, es en realidad printf devuelve un número, pero vamos a ignorar que por ahora porque nunca he utilizado. Así que eso es todo por Ken. Y ahora principal toma el control de nuevo el programa porque esa línea de código, printf, se lleva a cabo la ejecución. Y nos ocupamos de nuestro camino, la ejecución de cualquier otras líneas están ahí. Así que ahora vamos a probar un ejemplo un poco diferente. Esta vez aquí primero vamos a borrar la pantalla, y esta vez vamos a hacer la función de medición de volumen, pero esta vez, espero que un valor de salida. Así que vamos a seguir adelante y hacerlo. Ahora tengo una línea de código que dice que x se cúbica de x. La línea de código, el recuerdo, se ve así: x = cubo (x); Entonces, ¿cómo se va a trabajar? Vamos a seguir adelante y darle una pantalla en blanco de nuevo. Voy a escribir ahora el valor de x, que en este momento pasa a ser, digamos, 2 para mantener las cosas simples. He escrito en un pedazo de papel el valor de 2, lo cual es mi valor x. Se lo entrego a Ken. >> Y acabo de escribir la respuesta? >> Sí, vamos a escribir la respuesta. Bien. Y ahora me tiene que devolver algo. Perfecto. Niza segue. Así que ahora me pasa de nuevo el valor de 8 en este caso, y qué debo hacer con él? En realidad - vamos a ver, obtener este derecho. ¿Qué voy a hacer con él? Ahora me voy a tomar este valor y almacenarlo en realidad en esos mismos bits en la memoria. Pero note que soy una especie de lucha aquí. Estoy un poco confundido porque donde puedo realmente escribir el valor de x, porque lo que acabas de hacer es físicamente Ken mano un pedazo de papel que tenía el valor 2, que era x, y, de hecho, eso es precisamente lo que sucedió. Así que resulta que cuando se llama a la función y se le pasa un argumento como hola, mundo, ni se le pasa un argumento como el 2, en general, está pasando una copia de ese argumento. Y así como yo anoté el número 2 aquí y se lo dio a Ken, eso quiere decir que todavía tengo una copia del valor 2 en algún lugar porque de hecho, ahora que lo he conseguido volver el valor 8, tengo que volver en la memoria RAM y en realidad anotar 8, donde una vez tuve el número 2. Así visualmente, recuerda esta idea de pasar en, literalmente, una copia del valor. Ken hace sus cosas, me da algo de vuelta - en este caso un valor como 8 - y luego tengo que hacer algo con ese valor si quiero mantenerlo ahí. Así que todo esto volverá a ser demasiado familiar en poco tiempo. Muchas gracias por esta demostración aquí, Ken. [Aplauso] Muy bien hecho. Vamos a ver cómo eso se relaciona en última instancia, a parte de la función de llamada que hemos estado haciendo aquí. Déjame ir por delante y nos lleve de nuevo al ejemplo cubicación aquí. Tenga en cuenta que si queremos realmente empezar a tomar este más futuro, vamos a tener que tener en cuenta el hecho de que el número x que está siendo pasado por aquí es diferente de lo que realmente está pasando en la función. Así que de nuevo, este paso por copia va a ser muy afín en un momento. Vamos a echar un vistazo a algo que no acaba de funcionar bien todavía. Voy a seguir adelante y abrir un ejemplo calesa tercera, que está viciado por la naturaleza, y se llama buggy3 e implementa una función de intercambio. Aquí tenemos una función principal que ha x e y arbitrariamente inicializa a 1 y 2, respectivamente. Podríamos utilizar getInt, pero sólo necesitamos un ejercicio simple, por lo que es codificada como 1 y 2. En las líneas 21 y 22, que al parecer imprimir x e y, una por línea. A continuación, en la línea 23, sostengo que estoy cambiando estos valores, punto, punto, punto. Me aparentemente llamar a una función en la línea 24 de intercambio llamada que dura 2 argumentos. Está totalmente de fiar para las funciones que tomar 2 argumentos. Hemos visto printf hacerlo ya. Así intercambio aparentemente toma x e y, y como sugiere su nombre, Espero que esto va a cambiar estos 2 valores. Así que me dicen en la línea 25 "cambiaron!" y reimprimir x e y bajo el supuesto de que han sido efectivamente intercambiados. Pero si realmente ejecutar este programa - que me abra una ventana de terminal, quiero dejar buggy3 - como su nombre lo indica, esto no va a terminar bien porque cuando pulse la tecla Enter, nótese que x es 1, y es 2, y sin embargo, al final del programa, todavía son, de hecho, el mismo. Así que basado en la demostración acaba con Ken, lo que realmente está pasando? ¡Entremos en esta función swap. Es súper corto. No es más que unas pocas líneas de código de tiempo. Pero ¿cuál es el problema fundamental que debe basarse en la simple historia dice aquí con Ken? ¿Por qué el canje de rompe? [Estudiante] Usted está almacenando una copia, no la variable. Exactamente. Estamos en guardar una copia, no la variable en sí. En otras palabras, de intercambio aparentemente tiene 2 argumentos, un int, y es llamado arbitrariamente a y b, y aquí he pasado en x e y, que son, respectivamente, 1 y 2, pero no estoy literalmente pasando x, no estoy literalmente pasando y, Estoy pasando una copia de x y una copia de y. Es casi como si usted copiar y pegar en canje los valores que desea para manipular realmente. Así que si ese es el caso, cuando el inicio del programa la ejecución de la línea 35 después de 36 años, cuando llegue a la línea 37, en este momento de la historia, ¿cuál es el valor de a? En este punto de la historia, línea 37, ¿cuál es el valor de una en este momento? >> [Estudiante] 1. [Malan] Simplemente debe ser 1, a la derecha, ya que x se pasa como primer argumento, y esta función sólo arbitrariamente está llamando a su primer argumento. Del mismo modo es Y el segundo argumento, y es simplemente llamar a la b arbitrariamente segundo argumento. Esta dicotomía es en realidad bastante simple explicación. Piensa en ello. Ninguno de nosotros ha conocido a la persona que escribió printf, por lo que seguramente, él o ella no tiene idea de lo que nuestras variables de 30 años más tarde se iba a llamar. Así que tiene que haber una distinción entre lo que llaman las variables en las funciones que estás escribiendo y lo que ustedes llaman las variables en las funciones que está llamando o utilizando. En otras palabras, he escrito mis variables como x e y, pero si alguien había escrito la función de intercambio, él o ella seguramente no sabría lo que mis variables se va a llamar, así darse cuenta de que esto es por qué tiene esa dualidad de nombres. Técnicamente, yo podría hacer esto por casualidad, pero aún así se pasa como copias. Sólo sería una pura coincidencia estéticamente si esa persona que escribió intercambio había utilizado los mismos nombres. Así que en este punto de la historia, línea 37, a es 1, b es 2, y ahora me dedico a intercambiarlas. En primer lugar, quisiera realmente hacer esto mucho más simple. No sé cuáles son esas 3 líneas de código hacían. Permítanme hacer esto: b = a; a = b; hecho. ¿Por qué esta roto, lógicamente? Es algo de lo intuitivo, ¿verdad? Así una y B se convierte en b se convierte en una, pero el problema es que tan pronto como se ejecuta la línea 37, ¿cuál es el valor de a y b? Lo mismo, 1, porque ha paliza, por así decirlo, has cambiado b sea igual a. Así que una vez que se ha ejecutado la línea 37, que está muy bien, ahora tienes 2 copias de la número 1 dentro de esta función, por lo que a continuación, cuando usted dice en la línea 38 a = b, eres un poco jodido porque estás asignando 1 a 1. Usted ha perdido el tipo de valor que le importaba. Así que en la versión original de este, observe lo que hice. Yo en cambio tuvo una tercera línea de código que se veía así. Yo declaro una variable temporal. Tmp es un nombre muy común para una variable temporal, y es un int porque tiene que coincidir con lo que yo quiero hacer una copia de. Puedo guardar una copia de dentro de tmp, así que una vez que la línea 37 se ha ejecutado, el valor de a es - comprobación de validez rápida - 1, el valor de b es 2, y el valor de tmp es también 1. Así que ahora ejecutar la línea 38. Una vez que la línea 38 se ejecuta, una toma el valor de b. Y b fue de 2, por lo que ahora es un 2. Así que en este punto de la historia, a es 2, b es 2, y tmp es 1, por lo que ahora, lógicamente, podemos valorar sólo tmp plop en la b y ya está. Para ello hemos resuelto ese problema. Por desgracia, cuando ejecuto este programa en esta forma, en realidad no cambiar ningún valor. Pero para que quede claro, ¿por qué? He arreglado el problema lógico de hace un momento, pero de nuevo, si ejecuta este programa, x e y no cambian por el final de la ejecución del programa. [Comentario estudiante inaudible] >> No hemos devuelto nada, así que eso es cierto. Pero resulta que hay un pequeño problema aquí, porque hasta el momento, lo único que he sido capaz de volver es una cosa, y ésta es una restricción de la C. Sólo puede volver realmente un valor, en cuyo caso estoy un poco atascado aquí porque pude devolver el nuevo valor de x o podía devolver el nuevo valor de y, pero quiero que los dos de vuelta. Así que regresa no es la solución simple aquí. Pero el problema fundamental es ¿por qué? ¿Qué hemos cambiado en realidad? [Estudiante] a y b. >> A y b. Pero a y b son copias de x e y, por lo que acabamos de hacer todo este trabajo, Acabamos de pasar 3 minutos hablando acerca de la función de intercambio y los 3 de estas variables, y eso es genial, perfectamente correcto en el aislamiento, pero a y b del alcance sólo está en estas líneas aquí. Así como un bucle, si se declara un entero i dentro del bucle for, Del mismo modo, si usted está declarando dentro de a y b de la función que usted ha escrito, solo son válidos dentro de esa función, lo que significa que tan pronto como intercambio se realiza ejecutando y vamos a partir de la línea 24 a la línea 25, x e y no han cambiado en absoluto. Usted acaba de perder un montón de tiempo que se tarda copias de variables. Así resulta que la solución a esto es en realidad no evidente. No es más que suficiente para devolver valores porque sólo podemos devolver un valor, y realmente quiero cambiar tanto x como y, al mismo tiempo, así que vamos a tener que volver a esto. Pero por ahora, darse cuenta de que el problema fundamental deriva del hecho de que a y b son copias y están en su propio ámbito. Vamos a tratar de resolver esto de alguna manera. Permítanme retroceder en realidad aquí y abren, digamos, una cuarta variante de esto, buggy4. ¿Qué pasa con esto? Este es un problema similar pero más sencillo que mirar antes de tomar una puñalada en su solución. Este programa se llama incremento, y al parecer se inicializa un entero x a 1 en la línea 18. Entonces me dicen x es 1, entonces me dicen "Incrementar ..." Entonces llame incremento, pero luego en las líneas 22 y 23, que dicen que ha sido incrementado, Yo reclamo x ahora es lo que es - 2, probablemente - pero este programa está libre de errores. ¿Cuál es el problema? Si. >> [Respuesta de los estudiantes inaudible] >> Exactamente. Así que x ha sido declarada, por supuesto, en la línea 18. Es dentro de llaves principal. Así que la respuesta simple es que mientras que x existe aquí, que no existe en la línea 32, por lo que este programa realmente ni siquiera se compilará. El compilador cuando intento compilar este código va a gritarme sobre algún identificador no declarado o algo por el estilo. De hecho, vamos a intentarlo. Se trata de hacer buggy4. Ahí está. El uso de 'x' identificador no declarado en la línea 32. Y, de hecho, vamos a ser más explícito aquí hoy para que esto sea útil en horas de oficina y en casa. Tenga en cuenta que es un poco críptico escrito. Pero el hecho de que tiene Clang nos gritaba, diciendo buggy4.c: 32:5, es realmente útil. Esto significa que el error está en la línea 32 en la posición de carácter 5. Así 1, 2, 3, 4, 5. Eso es, en efecto, donde el problema es. Y también, también, tener en cuenta en las horas de oficina y en casa, tengo suerte aquí. Tengo un error. Va a ser relativamente fácil de solucionar. Pero si tienes una pantalla llena de mensajes de error abrumadoras, otra vez darse cuenta de que el situado más abajo podría ser un síntoma de la más alta. Así que siempre persigue a sus errores, de arriba hacia abajo porque no sólo podría ser un efecto en cadena que sugiere que tiene problemas mucho más de lo que realmente hacen. Entonces, ¿cómo podemos solucionar este problema si mi objetivo es incrementar x? >> [Estudiante] x Haga global. Bueno, por lo que podemos hacer x global. Vamos a tomar el atajo que me advirtió acerca de antes, pero demonios, sólo necesitamos una solución rápida, así que vamos a decir int x aquí. Eso hace que x global. Así que ahora principal tiene acceso a la misma y el incremento tiene acceso a ella, y así que déjame ir adelante y compilar este momento. Hacer buggy4, Enter. Parece compilar ahora. Vamos a correr buggy4. Y parece que funciona realmente. Esta es una de esas cosas que se hacen como yo digo, no lo que hago, como acabo de hacer aquí, ya que en general, nuestros programas se van a poner mucho más interesante y mucho más que esto, y si la solución a problemas de la vida se acaba de poner todas las variables en la parte superior de su archivo, muy rápidamente qué programas se horriblemente difícil de manejar. Se hace más difícil de idear nuevos nombres de variables, se hace más difícil entender qué variable está haciendo qué, y así, en general, esto no es una buena solución. Así que vamos a hacer esto mejor. No queremos utilizar una variable global aquí. Yo quiero incrementar x, así que obviamente podría - al final del día, esto es un poco de una historia tonta porque simplemente hacer esto - pero si yo no sabía nada de ese operador o que no se le permitió cambiarlo principal en sí, ¿Cómo podría yo poner en práctica Ken acá esta vez no para incrementar cubo pero a? ¿Cómo puedo cambiar esto de aquí? Si. [Estudiante] Pass en x y volver luego [inaudible] >> Bien, bien. ¿Por qué no puedo pasar en x y entonces en vez de devolverlo, ¿Por qué no me lo devuelva x + 1. Un par de cosas que tienen que cambiar aquí. Estoy en el camino correcto. ¿Qué más necesita para modificar? Alguien más. Si. [Respuesta de los estudiantes inaudible] Tengo que cambiar el tipo de retorno de incremento porque no se anulará. Nada Void medios se están devolviendo, pero es evidente que ahora es, así que esto tiene que cambiar a - >> [estudiante] int. int para ser coherente con lo que en realidad estoy regresando. Ahora, otra cosa es aún con errores aquí. Si. [Respuesta de los estudiantes inaudible] >> [Malan] Así que necesito para incrementar x? [Respuesta de los estudiantes inaudible] >> [Malan] Ah, así que tengo que pasar x. Así que tengo que hacer esto aquí. >> [Comentario estudiante inaudible] [Malan] Así que el prototipo, tengo que cambiar esto aquí. Así que esto tiene que ser un int, esto tiene que ser - hmm, yo en realidad tienen un error aquí. Vamos a arreglar esto primero. ¿Cuál debe ser esta realidad? Tiene que ser un algo int. Podría ser x, pero, francamente, si usted empieza a llamar a todos los de su x variables, que va a recibir menos y menos clara cuál es cuál. Así que vamos a elegir arbitrariamente una nomenclatura diferente para las funciones de mi ayudador; las funciones que estoy escribiendo. Lo llamaremos a, o podríamos llamarlo - Digamos que es el número sea aún más explícito. Así que tengo que devolver todo lo que el número es más 1, y ahora tengo que cambiar una cosa aquí y otra cosa aquí. ¿Qué tengo que cambiar en la línea 21 en primer lugar? >> [Respuesta de los estudiantes inaudible] [Malan] tengo que asignar a x. No puedo llamar incremento (x). Necesito recordar la respuesta al cambiar el valor de x en el lado izquierdo. Y a pesar de que x se encuentra ahora en la izquierda y la derecha, que es totalmente bien debido a que el lado derecho se ejecuta primero y luego se dejó caer en la cosa de la izquierda - x en este caso. Y por último, esta es una solución fácil ahora. Esto sólo debe coincidir con lo que está abajo, el número int. Así que un montón de cambios para una función realmente estúpido pero representativa de las cosas que cada vez querrá hacer. Así que buggy4. Me he cagado en alguna parte. Oh, Dios mío. Cinco errores en un programa de 6 líneas. Entonces, ¿qué hay de malo en la línea 18, el carácter 5? Así que tengo que declarar este tipo int. Vamos a ver. Hay un montón de otros errores. Oh, Dios mío - 19, 18, 21 -, pero de nuevo, vamos a borrar la pantalla, L Control de aquí, y vuelva a ejecutar Clang. Así que 5 problemas que en realidad es sólo una. Así que ahora vamos a ejecutar buggy4, Enter. ¡Menos mal, x se ha incrementado correctamente. Está bien. Cualquier pregunta sobre la forma de incrementar los números? Si. [Pregunta estudiante inaudible] >> Buena pregunta. ¿Cómo es que sólo puedo cambiar x a número y el programa sabrá de inmediato? Una vez más, pensar en ella como esta abstracción. Así que si yo soy principal y Ken es el incremento, francamente, no me importa lo que Ken llama a su iPad. No me importa lo que él llama cualquier cosa que tenga que ver con su implementación de esta funcionalidad. Este es un detalle de implementación que yo, principal, no tienen que preocuparse. Y así, simplemente cambiando constantemente dentro de la función - y el número de serie aquí aquí - es todo lo que toma tanto tiempo como yo recompilar. Es algo así como si se piensa en muchos de nosotros, aquellos que tengan licencias de conducir que han impulsado o si usted incluso ha conducido en un coche, la mayoría de nosotros no tenemos idea de cómo funciona un coche bajo la campana. Y, literalmente, si se abre el capó, la mayoría de nosotros - yo incluido - no vamos a saber realmente lo que estamos viendo, especie de que se puede sentir con cosas como esta ahora mismo. Pero en realidad no tienen que cuidar cómo el coche funciona, que no tienen que cuidar lo que todas las varillas y pistones y los cables en el interior del coche en realidad están haciendo. Así que algo como lo que ustedes llaman el pistón no tiene importancia aquí en este caso. La misma idea. Si. >> [Pregunta estudiante inaudible] Si hay más usos de la variable xa momento antes, usted, el programador, tendría que cambiar todas partes. O usted podría literalmente hacer Archivo, Menú, y luego Buscar, Reemplazar - algo así - pero vas a tener que hacer esos cambios por su cuenta. Hay que ser coherente. >> [Estudiante] Si hay varias variables [inaudible] Una orden particular, como aquí, si se trataba de int otro número? >> [Estudiante] Correcto. [Malan] Yeah. Orden importa cuando se llama a la función. Así que si me estaban llamando incremento aquí con algo algo coma, hay una correlación directa. La primera variable, como se llame, se hace una copia del primer argumento por aquí. Lo siento. Esto no debería ser un paréntesis. Las líneas del segundo argumento para arriba con el segundo. Así orden, sí, importa. Está bien. Lo siento. Tomé el camino más largo para llegar allí. Otras preguntas? Está bien. Así que vamos a ver si podemos pintar un cuadro de lo que realmente está pasando aquí debajo de la campana, por así decirlo. Este es un rectángulo que podría representar la memoria de su computadora. Incluso si usted no tiene idea de cómo funciona la memoria RAM o cómo funciona, al menos se supone que tiene racimos de él en estos días. Tienes megabytes de ella, tienes gigabytes de la misma, y sabemos por semana 0 que un byte es qué? >> [Estudiante] 8 bits. 8 bits, ¿no? Así que 8 ceros y 1. Así que si su equipo tiene un giga de RAM, 2 gigas de RAM en estos días, Tiene un billón o 2 millones de bytes de memoria o bits de aproximadamente 8 millones de dólares o 16 mil millones dentro de su equipo. A diferencia de la pequeña Wooly Willy ejemplo, no es típicamente partículas magnéticas más. Cada vez más - en los ordenadores portátiles por lo menos - es unidades de estado sólido, SSD, que simplemente no tienen partes móviles. Todo es electrónico. Es toda la electricidad basada en. Así que piensa de este rectángulo como apenas representa el 1 o 2 gigabytes de memoria que tiene. Así que es un trozo de memoria. El mundo de la informática tiene una especie de particiones de trozos de memoria para hacer cosas diferentes. Por ejemplo, si esta es la memoria RAM de su computadora, como lo sugiere el rectángulo allí, resulta que, por convención, en la parte superior de la memoria RAM, por así decirlo, generalmente es lo que se llama un segmento de texto. Esos son el 0 y 1 que haya recopilado. Por eso, cuando hemos mirado debajo de la capucha lo a.out es, todos estos 0s y 1s, cuando se ejecuta un programa, los 0s y 1s son cargados desde el disco duro en algo que se llama memoria RAM, y en la RAM se las coloca en la parte superior. Mientras tanto, usted tiene otras cosas: inicializar los datos, desinicializar datos. Esas dos franjas de memoria se refieren a las variables globales, que no se utilizan a menudo pero a veces si lo hace, terminan allí también. Entonces hay algunas otras cosas: variables de entorno, que no vamos a pasar mucho tiempo en adelante, pero 2 cosas importantes que volver lo largo del semestre, pila y pila. Así que la mayoría de la memoria del equipo está reservado al ejecutar un programa por algo que se llama la pila y algo que se llama el montón. No vamos a hablar sobre el montón de hoy, pero vamos a hablar de la pila. La pila está destinado a evocar la visual de las bandejas de comida en el comedor Mather House o donde quiera que sea, donde el personal de comedor limpiarlas todos los días, que ellos comparan desde el suelo hacia arriba, y del mismo modo, en la memoria, no es la idea de poner algo en una pila, poner algo en una pila, poner algo en una pila. Y ¿qué es lo que queremos decir con esto? Vamos a ampliar en casi la mitad inferior de la imagen, la memoria RAM de su computadora, a proponer la siguiente. Resulta que cuando se ejecuta un programa como a.out o hello - cualquiera que sea el programa que has escrito - de nuevo, los 0s y 1s son cargados desde el disco duro, que es un almacenamiento prolongado, permanece allí incluso cuando se tire de la clavija, se carga en la memoria RAM. RAM es más rápido que los discos duros - es más pequeño que los discos duros - pero es donde los programas en vivo mientras está en funcionamiento. Así se hace doble clic en un programa en un Mac o PC, se carga desde el disco duro a la RAM. Tan pronto como se carga en la memoria RAM, el go 0s y 1s en la parte superior forma, el segmento de texto llamado, pero tan pronto como el programa realmente se pone en marcha, la principal función es llamada, y principal, como hemos visto, a menudo tiene variables locales, y tiene enteros y cadenas y caracteres y similares. Así que si tu programa que usted ha escrito o del programa que haya hecho doble clic utilizado algunas variables dentro de la principal, terminan en la parte inferior de la pila de la memoria, por así decirlo. Más concretamente, ¿qué significa esto realmente? Esto sólo significa que si íbamos a numerar los bytes de RAM en el ordenador, notar que este podría ser el número de bytes 0, este podría ser el número de bytes 1, 2, 3, 4, 5, 6, todo el camino hasta 2 mil millones sería todo el camino hasta allí en la parte superior. En otras palabras, cuando se habla de la memoria RAM o en términos de bytes, sólo significa que alguien ha decidido a contar lo que cada uno de esos trozos de memoria. Así que cuando usted necesita 32 bits para un int o necesita 8 bits para un char, ¿de dónde van a parar a la memoria? Conceptualmente, se acaba de terminar en el fondo de esta cosa llamada la pila. Pero lo interesante ahora es cuando llama a una función principal - supongamos una función llamada foo, sólo un nombre arbitrario - lo que sucede es principal está en la parte inferior de esta pila de la memoria; foo ahora se coloca en la parte superior de la memoria principal. Así que las variables locales que se acaban foo tipo de vista conceptual encima de los de principal. Si foo llama a otra función llamada bar, aquellas variables terminan aquí. Si la barra pide algo más, aquí, aquí, aquí. Así que lo que es interesante acerca de la ejecución de un programa es que al llamar a funciones y como esas funciones y llamar a funciones como las funciones que llaman a funciones, construir el edificio esta pila de funciones en la memoria. Y sólo una vez devuelve una función no comienza a recibir esa memoria espalda. Así que una de las maneras más fáciles de ejecutar fuera de la memoria en un programa informático es escribir funciones que nunca vuelven. Así, por ejemplo, vamos a demostrar como mucho con un programa intencionalmente buggy. Déjenme seguir adelante y hacer # include, int main (void) y yo voy a hacer mientras que (2> 1), lo que probablemente no va a cambiar en nosotros, y déjame seguir adelante ahora y hacer printf. En realidad, eso va a ser menos interesante visualmente. Vamos a hacer esto. Para int i = 0; i> 0 - vamos a cometer este error - i + +. Y no printf aquí. Vamos a practicar lo que predicaba. Vamos a echar un método aquí, chorus vacío, y vamos a decir int i, y luego voy a decir printf - no, vamos a hacer esto más interesante. Que en realidad no imprime nada en absoluto. Vamos a ello: chorus (i). Está bien. Así que esto tiene fallos porque ¿por qué? Estoy haciendo esto como voy porque el programa no hace nada de interés. Pero ese no es el objetivo. El objetivo es escribir un programa que tiene como principal función hace lo que, al parecer? Llame a sí mismo. Y en realidad, no necesitamos el bucle. Vamos a simplificar aún esto sólo para no perder de vista realmente el error fundamental. Principales llamadas coro para cantar algunos coros, entonces hice algo estúpido y yo tuvimos coro coro llamada porque supuse que alguien más iba a ponerlo en práctica, tal vez, y ahora esto no se va a compilar todavía. Tengo que hacer qué? Necesito el prototipo, recuerda. Así que tengo que tener aquí coro void (int i); Así que ahora si me voy por aquí - en realidad, vamos a utilizar la ventana más grande. Vamos a seguir adelante y hacer coros. Vamos a seguir adelante y hacer coros. El uso de identificador no declarado i. Oh, eso fue estúpido. No necesitamos el argumento. Vamos a hacer esto. Me hubiera gustado haber comenzado de esta manera. Hubiera sido un programa mucho más fácil de escribir. Ya está. Ahora vamos a ir a mi ventana de terminal, ejecute de nuevo Clang, y aquí vamos. Eso fue muy rápido. Lo que en realidad acaba de ocurrir, sin embargo? Bueno, ahora voy a añadir la línea de impresión para que podamos ver. Permítanme decir printf ("Estoy aquí") - sin variables. Lo dejaremos así. Permítanme hacer volver a ejecutar. Permítanme volver a ejecutar coro. Y ... vamos. Sigue adelante. Como acotación al margen, ¿por qué no lo ha derrumbado todavía? El fallo de segmentación pasó súper rápido antes. [Respuesta de los estudiantes inaudible] >> Exactamente. Así que se necesita tiempo para imprimir, ¿verdad? Solo se necesita más trabajo por parte del equipo. Y ahí está: Segmentation fault. Así notar cuán rápido ejecutar programas. Si no está imprimiendo algo, super rápido. Pero todavía tengo este error de segmentación porque lo que estaba pasando? Si usted piensa acerca de cómo la memoria del equipo se presenta, esto pasa a ser principal, pero aquí vamos a llamar a este coro, y vamos a llamar a este coro. Y ahora si hago mi estética bien, esto es sólo va a decir coro, coro, coro, coro, coro, coro, coro, hasta la saciedad, y, finalmente, ¿qué va a pasar? Si el cuadro grande, literalmente, es la siguiente, ¿qué le pasa conceptual? Los excesos de la pila la pila. O, peor aún, que acaba de invadir todo, incluyendo el segmento de texto, que es el 0 y 1 que representa el programa. En resumen, esto es sólo super, super mal. Su programa se ha disparado fuera de control. Usted está utilizando la memoria mucho más de lo previsto todo a causa de un error estúpido en este caso, o en este caso una función muy deliberadamente hecho en sí de llamada. Ahora, esto no es del todo malo. Las funciones que se llaman en realidad tiene un gran poder cuando se lo usa correctamente. Yo no lo he usado correctamente aquí. Así que esto no es del todo malo, pero el hecho de que en realidad nunca me detengo llamando es una debilidad fundamental de este programa aquí. Entonces, ¿dónde vamos con todo esto? ¿Qué está pasando realmente? Cuando llamo a la función de incremento como si estuviéramos haciendo en estos ejemplos, Tengo un valor como una que yo paso pulg Me pasa una copia del número 1, por lo que sucede a continuación. Vamos a entrar en el incremento ejemplo, este tipo por aquí. Esto es lo que está sucediendo realmente. Cuando llamo incremento y paso en x, gráficamente, lo que está pasando aquí es lo siguiente. Si tengo el valor de 1 almacenan aquí y yo en realidad llamar incremento, que ahora se llama coro - el iPad me está echando de aquí. Vamos a llamar a este incremento, y no sabemos lo que esta función viene va a ser. Entonces, ¿qué está sucediendo realmente está aquí en alguna parte principal que tengo un trozo de memoria que almacena el número 1. Cuando llamo incremento, estoy usando otro trozo de la memoria, pero ahora tengo la copia de 1. Al aumentar este valor, este se convierte en 2, pero entonces lo que ocurre tan pronto como regresa de incremento? Esta memoria sólo se entregó de nuevo al sistema operativo, lo que significa que todo lo que hemos hecho es nada útil. El 1 que figuraba originalmente en el principal sigue siendo realmente allí. Entonces, ¿a dónde vamos con esto? Resulta que en la memoria que tiene esta secuencia de back-to-back de bytes que se pueden poner cosas adentro, y resulta que ya hemos visto algo que consiste en colocar las cosas vuelvan a espalda con espalda con espalda. ¿Qué es una cadena basada en la semana 1 y la semana 2 ahora? Es sólo un conjunto de caracteres. Así que resulta tal como se puede poner los números en la memoria, Del mismo modo se puede poner caracteres en la memoria. Y una vez que empezamos a poner en la memoria de personajes de espaldas a la espalda con espalda, resulta que el uso de las cosas más simples como un bucle o un bucle while, podemos repetir de izquierda a derecha sobre los caracteres de una cadena y empezar a masajear en personajes completamente diferentes - podría convertirse en una b, b podría ser c - por lo que en última instancia, podemos tomar una frase Inglés que realmente tiene sentido y convertir cada una de estas una cartas en un momento caminando a través de la memoria de nuestro ordenador de izquierda a derecha para cifrar en realidad. Así que vamos a tener nuestros cinco minutos de descanso aquí, y cuando regresemos, vamos a empezar este proceso de codificación de la información. Está bien. Antes de sumergirse en alguna crypto y estas cosas llamadas matrices, permítanme hacer una pausa para cualquier pregunta, porque me siento como si realmente algo confusa algunos de esos temas. Así que vamos a arreglar ahora si podemos. Acabamos de hablar sobre valores de retorno, hablamos de argumentos, y hablamos de esta idea, que vamos a volver en las próximas semanas, de visualización de la memoria como un manojo entero de estas bandejas apiladas, por así decirlo, de abajo hacia arriba, de manera que cada bandeja que se ponen en la pila representa una función que está siendo llamado. ¿Alguna pregunta? Permítame hacerle una pregunta aquí. Permítanme simplificar esto a lo que era antes de que algunos de nuestra anterior Q & A. El hecho de que el incremento tiene paréntesis de apertura, número int, cerrado paréntesis - ¿qué número representa int? [Estudiante] Un argumento. >> Un argumento. Bien. Pero lo que es un argumento? [Respuesta de los estudiantes inaudible] >> ¿Qué es eso? >> [Estudiante] Algo que se pasa pulg Está bien, así que algo que se pasa pulg Y más en general, es sólo la entrada. Si estuviera escribiendo una función y propósito de tal función en la vida es hacer algo un poco diferente cada vez que lo utilice, entonces la única forma para que eso suceda realmente parece ser que le facilitara la entrada para que se pueda hacer algo diferente con esa entrada cada vez. Así que hay que especificar dos cosas cuando una función toma de entrada. Es necesario especificar el nombre que desea dar a esa entrada exclusivamente para su propia conveniencia, para que pueda referirse a ella en la función que usted está escribiendo, como lo hice aquí en la línea 32. Pero también hay que especificar su tipo, ya que C es un lenguaje de programación que sólo requiere que si quieres una variable, usted tiene que decirle a la computadora qué tipo de datos es, en gran parte, de manera que conozca el número de bits a asignar a esa variable porque podría ser de 6 - lo siento, no va a ser 6. Puede ser 16, puede ser 8, puede ser 32, incluso 64, pero el equipo tiene que saber. Ahora, la INT en el lado izquierdo representa lo que, por el contrario? [Respuesta de los estudiantes inaudible] >> ¿Qué es eso? >> [Estudiante] Tipo de función. El tipo de una función y, más específicamente, el tipo de su producción. Derecha. Así, mientras que la cosa en paréntesis representa su entrada, en su caso, la cosa a la izquierda representa la salida. Y en este caso, el incremento aparentemente devuelve un int, y así int es el tipo de retorno de esta función. ¿Qué significa regresar? Literalmente, se utiliza la palabra clave return y luego, si lo va a devolver a la derecha de la palabra clave es un número entero, entonces que es consistente con lo que hemos prometido. No se podría hacer algo como esto - hola, mundo - porque eso es una cadena. Obviamente, no es un número entero. Así que en resumen, la carga está realmente en nosotros, el programador, para ser específico en cuanto a lo que estamos regresando y para entonces que seguir para devolverlo. El contexto aquí es que la memoria de su computadora es un gigabyte, 2 gigabytes - lo que sea - tal vez es más, tal vez es menos, pero el equipo que considera que tiene diferentes secciones. Algo pasa ahí abajo, algo más va allá arriba, cosas diferentes va en el medio, y hoy simplemente comenzar a contar la historia, pero vamos a volver a este momento de nuevo. Por ahora, la única memoria que realmente importa es el segmento de texto ya que sólo representa el 0 y 1 que Clang se emiten. Así que cuando se ejecuta un comando en el teclado como a.out o hace doble clic en un icono en Mac OS o Windows, el programa se carga desde el disco duro a la RAM y se dejó caer en la cima de la memoria RAM del ordenador, por así decirlo. Mientras tanto, comienza tu programa de entrenamiento y principal llamada se en el programa que escribió o escribe el programa de Microsoft o Apple, cualquiera de sus variables locales terminan ahí abajo en la parte inferior de la memoria de su computadora. Pero si las llamadas principales a otra función que se tiene variables o argumentos, terminan encima de ella. Y si esa función llama a algo, terminan encima de él, encima de él, encima de él. Y sólo una vez una función se hace ejecutar es la pila de bandejas, por así decirlo, comienzan a ponerse más y más. Y esto es lo que entonces, en pocas palabras, explica por qué cuando se llama cubo o puede llamar al incremento, que está pasando por una copia del valor. Y lo que eso significa es que pictóricamente está literalmente escrito el número 1 en otra parte de la memoria, el cambio de que 1 a 2 en el caso de incremento o a un 8 en el caso de cubo y luego tirar de que la memoria de distancia tan pronto como el incremento de los rendimientos o de funciones de cubo. Pregunta. [Estudiante] ¿Dónde se almacenan las variables globales? Las variables globales se almacenan en lo que se llama actualmente los datos inicializados o datos sin inicializar, la diferencia está en si tiene una variable global y se le asigna un valor inmediato con el signo de igualdad, termina en la parte superior hay, y si lo que dicen int x; sin valor, termina ligeramente inferior en RAM simplemente por convención. Otras preguntas? Está bien. Así que esta imagen regresará a medida que más poderoso con lo que podemos hacer con el ordenador, pero por ahora, vamos a tener una breve introducción a la criptografía, un tipo específico de criptografía que no resuelve todos los problemas del mundo pero es resolver algunos de ellos. En este caso aquí, tenemos algo que se llama criptografía de clave secreta. Criptografía de clave secreta, como el nombre sugiere, deriva su seguridad de un secreto. Por ejemplo, si estaban de vuelta en la escuela primaria y que estaban pasando una carta secreta poco de amor para el chico o la chica con la que estaban aplastando en adelante, si quería pasar esa nota a través de la audiencia, es probable que no iba a escribir una nota en Inglés o lo que su lengua materna es. Más bien, es posible cifrar o simplemente puede enviarles un mensaje de texto en estos días. Pero que en realidad podría pasar una nota a través de la sala de clase. Y para hacerlo con seguridad, de tal manera que sus amigos y el profesor no sabes lo que estás escribiendo, es posible llegar a un algoritmo bastante simple, joven, aunque es posible que, con sólo mezclar las palabras. Así que en lugar de escribir una puede escribir b, en lugar de b puede escribir c, en vez de c puede escribir d, y así sucesivamente. O bien, podría llegar a una traducción más sofisticada de cartas a diferentes letras. Pero el problema es el chico o la chica a la que le está enviando esta nota tiene que saber algo, que es lo que, obviamente? >> [Estudiante] Lo que usted está enviando. ¿Cuál es su secreto, como lo es que la asignación entre una y la de B y de C y D's. ¿Es sólo la adición de 1 a cada una de las letras para ir de A a B, de B a C? ¿Es más complejo que eso? Así que tú y tu enamorado es necesario tener esta información secreta, pero hay una especie de catch-22 aquí. Si esta es la primera vez que va a enviar esta carta de amor a través de la clase, ¿cómo es ese niño o niña va a saber cuál es el secreto incluso es? Así clave secreta de cifrado no resuelve todos los problemas del mundo, y de hecho hay una relación que aquí vamos a volver a hacia el final del semestre. Del mismo modo, no la mayoría de nosotros conoce a alguien que trabaja, por ejemplo, en Amazon.com, y sin embargo, muchos de nosotros hemos comprado cosas en Amazon.com, y se nos ha enseñado a asumir que estas transacciones de comercio electrónico son seguros. La dirección URL https probablemente dice, hay tal vez un icono de candado poco tonto en alguna parte, hay una especie de criptografía asegurar su información de tarjeta de crédito entre usted y Amazon.com. Y sin embargo, si la criptografía implica saber algún secreto y sin embargo, yo no conozco a nadie en Amazon y no he arreglado sin duda algún tipo de secreto con alguien en el Amazonas, ¿cómo es mi ordenador o mi navegador haciendo esto? Resulta que hay otros tipos de criptografía en conjunto que resolver ese problema. Pero por hoy, nos centraremos en el sencillo donde se puede organizar con antelación para conocer algún secreto como una u otra asignación entre una y la de b. Y el proceso de criptografía generalmente implica esto. Usted tiene un poco de texto sin formato, representado aquí a la izquierda, se ejecuta a través de algún tipo de algoritmo o procedimiento para cifrarlo - tal vez eso es sólo una se convierte en b, b se convierte en c - y entonces termina con texto cifrado. Mientras tanto, una vez que su enamoramiento recibe esta nota secreta, él o ella tiene que descífralo por lo general revertir ese algoritmo con el fin de recuperar el texto sin formato. Hay encarnaciones físicas de este. Por ejemplo, este es un anillo decodificador secreto poco, y este es un anillo en el sentido de que hay dos diales aquí. En la periferia exterior de esta cosa, no hay letras de la A a la Z, aunque están en orden aleatorio, y en el interior, de hecho hay algunos números de tal manera que con este anillo te pueden especie de vuelta al exterior pero no el interior con el fin de alinear los números con letras. A partir de una película que se llama Un cuento de Navidad, verás que poco Ralphie estaba tan ansioso de averiguar cuál es el mensaje secreto Little Orphan Annie era para él que había sido comunicada, creo, en forma de mensajes numéricos en una caja de cereal y ha tenido que acumular todas las pequeñas tarjetas que vienen en la caja de cereal, había que enviarlos por correo, había que recuperar el anillo decodificador secreto de modo que usted puede finalmente entender lo que el mapeo es entre las letras y los números o letras y letras. ¿Cómo en un ordenador podemos ir sobre la aplicación o representar las cosas de esta manera? Necesitamos una manera de expresarnos un poco más flexible que nuestras variables hasta el momento han permitido. Hemos tenido enteros, hemos tenido caracteres, hemos tenido flotadores y dobles y algunos otros, pero esas son las piezas individuales de la memoria que realmente no nos permiten expresar cosas como las palabras y las oraciones y frases. De hecho, hemos llamado cuerdas esas cosas, pero prometo que esto es sólo una simplificación en la biblioteca CS50 que estamos intentando pelar. Así que vamos a empezar a hacer eso aquí. Déjenme seguir adelante y abrir un archivo - todos estos archivos están disponibles, como de costumbre, en línea - array.c llamada para resolver un problema no relacionado con las cadenas, pero que pinta un cuadro aquí de cómo podríamos usar algo que se llama una matriz. Una matriz es un tipo de datos. Es un tipo de variable de tipo que tiene varios tipos de datos más pequeñas dentro de ella espalda con espalda a espalda con espalda. Así, por ejemplo, si queremos escribir un pequeño programa que te da el promedio de concurso para un curso como 50 que tiene dos cuestionarios, que podría muy fácilmente escribir este programa basado incluso en algunos de los materiales de la semana pasada mediante el uso de getInt y un par de variables: int quiz1, int quiz2. Y es bastante sencillo. Es tal vez 10, 20 líneas de código máximo para poner en práctica un programa de que pide al usuario 2 puntuaciones prueba y luego calcula su promedio mediante la adición de ellos juntos, dividiendo por 2, y luego imprimir los resultados. Probablemente podríamos hacer eso muy fácilmente ahora, después de un cierto número de minutos. Pero el problema es que suponer que 50 tenían 3 o 4 pruebas. Supongamos que usted quisiera utilizar el mismo programa para una clase que tenía pruebas semanales. Piense en una clase que ha exámenes semanales. Si hay 16 o más semanas en un semestre, ahora tiene 16 variables: quiz1 int, int quiz2, int quiz3, int quiz4. Tan pronto como usted comienza a ver esta redundancia, esta copiando y pegando el código, debe comenzar a hacer que te gustaría que hubiera una manera mejor. Y gracias a Dios, a causa de las matrices que hay. Así que vamos a hacer esto. En primer lugar, permítanme presentarles a una cosa muy simple que no hemos usado hasta ahora, pero lo vas a ver de vez en cuando en el código. Esto es lo que generalmente se llama una constante. Así que es una constante en el sentido de que este valor nunca cambia. La convención humana cuando se crea una constante es el uso de letras mayúsculas sólo para que realmente se destaca en su código, y la palabra clave especial que se utiliza en C # define. Por eso decimos # define, luego un espacio, entonces la palabra que desea utilizar para el nombre de la constante de y luego el valor de la constante. Tenga en cuenta que esto es diferente de asigna algo a una variable. No hay ningún signo igual, no hay punto y coma. Esto es lo que se conoce generalmente como una directiva de preprocesador, pero más de eso en otro momento. Por ahora, esto crea un valor inmutable llamado TESTS cuyo valor numérico real es 2. Así que donde quiera que vea pruebas, exámenes, pruebas cortas a lo largo de este archivo, eso es sólo el número 2. Si miro principal ahora, vamos a ver cómo funciona esto. Primero se ve un poco críptico, pero es todo cosas de la semana 1. Pida al usuario para los grados. ¿Cómo podemos hacer esto? En la línea 22 - esta es realmente la parte jugosa - Declaro un flotador pero no es sólo un solo flotador. Estoy declarando, más bien, un conjunto de valores de punto flotante. Esa variable se va a llamar grados, como se implica aquí, pero la única nueva sintaxis entonces son estos corchetes. El hecho de que lo que he dicho grados flotador y luego abrir el paréntesis y luego el número a - cuenta si se trata de una constante es igual que lo hicimos - esto quiere decir, "Hey ordenador, déme 2 flotadores y vamos a llamarlos colectivamente grados". Esto está en contraste con un proceso mucho más tedioso así: flotador grado 1; grade2 flotar, y así sucesivamente. Así que una matriz que nos permite poner en práctica esta idea, pero mucho menos desordenadamente, de tal manera que podemos escribir una línea de código en lugar de, por ejemplo, 16 para un semestre de 16 semanas. Yo no quería que codificar 2 porque si se piensa en esto ahora, lógicamente, Supongo que el año que viene CS50 cambios a 3 cuestionarios en lugar y yo tenía el número 2 aquí, yo tenía el número 2 aquí, Yo tenía el número 2 aquí, el número 2 aquí. Se vuelve muy tedioso y muy fácil meter la pata y cambiar accidentalmente un valor a 3 y se pierda algún otro valor de 2. Así que voy a este lugar abstracto lejos y utilizar esta constante que, Como su nombre indica, nunca cambia. Y ahora no importa si tenemos diferentes concursos de este año o el próximo, Sólo tengo que cambiarlo en un lugar aquí en la parte superior. Así que eso es todo, una constante es. Mientras tanto, la característica nueva es que conceptual de una matriz. Así que los corchetes darme esta flota y muchos me permite llamarlos colectivamente grados aquí. Así que ahora vamos a ver lo que voy a hacer. Aquí, en la línea 24 es el inicio de un bucle. Esto es realmente nada especial. Es sólo mediante TESTS lugar de un número codificado. Pero no hay nada intelectualmente diferente allí la semana pasada. Esto es sólo printf, así printf ("Quiz #% d de% d:") porque sólo quiero imprimir dame concurso número 1 de 2 y luego 2 de 2. Así que esto es algo puramente estético. Pero la parte más interesante ahora está en la línea 27. A fin de llenar en uno de los dos marcadores de posición con un valor de punto flotante, de nuevo utilizar corchetes. En este caso, estoy usando i porque este bucle for se ha iniciado con i igualando el valor que, al parecer? [Estudiante] 0. >> [Malan] 0. Así que en la primera iteración de este bucle, es como si yo escribí esto en el código, pero en la segunda iteración de este bucle, es como si yo escribí esto en mi código. Pero el hecho de que yo estoy usando una variable es perfecto porque, como su nombre lo indica, está variando su valor en cada iteración, así que estoy llenando esta matriz un lugar a la vez. ¿Qué hace este arreglo parece? La razón por la que dibujó el cuadrado super simple en la pantalla de aquí antes de que fue por esta razón. Una matriz es simplemente un trozo de memoria seguido de otro trozo de memoria seguido por otro bloque de memoria y así sucesivamente. Así que si mi matriz es de tamaño 2 en este caso aquí, lo único que estaría haciendo escribiendo en las puntuaciones de mis concursos como aquí - Tengo 100 en éste y luego me dieron un 99 en este caso - entonces esta memoria que ni siquiera puede utilizar porque sólo he pedido al equipo para una matriz de tamaño 2. Las plazas están todavía allí, ¿verdad? Aún dispone de 2 gigabytes de RAM, incluso si sólo está solicitando para 2 carros. Así que la idea detrás de las matrices es que la computadora sólo toma un trozo de memoria y luego reparte trozos más pequeños de espaldas a la espalda con espalda. Y eso es todo un arreglo es. Es un trozo contiguo de memoria dentro de la cual usted puede poner las cosas. Esto le pasa a hacer a continuación, sólo un poco de aritmética aburrido. Si me desplazo hasta aquí, aquí es donde me iterar sobre la matriz. Vengo con la suma de todos los valores de la matriz, y luego usar la función round aquí para hacer realidad la suma dividida por Quizzes. Pero permítanme saludar a mi mano que como una especie de aritmética suficiente por ahora. Pero todo lo que está haciendo por mí en última instancia está calculando un promedio. Así que prueba primero más segundo cuestionario dividido por 2 y luego imprimirlos como un int. Pero ahora vamos a la transición a un ejemplo diferente llamado cadena1, que pinta un cuadro similar pero utilizando cuerdas. Déjenme seguir adelante y simplificar esto por un momento. Perdona la sangría por ahora. Observe en la línea 19 de este ejemplo, tengo una cadena del usuario. Pero note lo que estoy haciendo en la siguiente líneas 22 en adelante. En realidad estoy iterar desde i hasta - y este es un nuevo truco - strlen, longitud de la cadena. Esta es una función que viene con C que si se le pasa una cadena, te dice cuántos caracteres hay en esa cadena. Eso es todo. Y el hecho de que es strlen en lugar de la longitud de la cadena es sólo porque es más conciso. Treinta años atrás, la gente le gusta escribir cosas lo más sucintamente posible, así que hemos mantenido esa convención aquí. i + + sólo significa incrementar i en cada iteración. Y ahora noten esto, que es muy interesante. En la línea 24, le digo, "Ordenador, dame un personaje, 8 bits, y lo llaman c". ¿Pero qué es esto en la parte derecha diciendo? En Inglés, ¿qué representa? [Estudiante] El primer carácter del conjunto. Exactamente. Dame el primer carácter de la matriz. O, más en general, me dan el carácter i en la matriz. Y darse cuenta de que es importante ahora que como los informáticos, en realidad estamos contando desde 0. Usted no tiene la discreción para empezar a hacerlo. Ahora usted tiene que comportarse de acuerdo con las expectativas del equipo y contar de 0 porque [0] va a ser el primer carácter de una cadena, [1] va a ser la segunda, [2] que va a ser el tercero, y así sucesivamente. Así que este programa, si lo compila, se trata nuevamente de cadena1, así que cadena1, y ahora me he encontrado en mi cadena1 ventana de terminal. Se espera para la entrada, así que voy a escribir en David, Enter, y ahora imprime David todo en líneas diferentes, porque fíjate lo que estoy haciendo. Estoy imprimiendo un carácter a la vez. No vamos a entrar en detalles hoy sobre esto, pero he eliminado hace un momento este cheque aquí. Resulta que si el usuario se está portando mal, contradictorio, confuso o simplemente en realidad se puede dejar de dar una serie de cierta extensión. Si se pulsa la tecla equivocada en el teclado, se puede dar ninguna cadena en absoluto, o si usted es malicioso, puede intentar para pegar en el patrimonio de un gigabyte de un ensayo para llenar esta cadena, y si el equipo se queda sin memoria, resulta que vamos a volver este valor especial llamado NULL. Así que por ahora, sólo sé que hay este valor especial llamado NULL que nos permitirá comprobar cuando estamos fuera de la memoria, entre otras cosas. Pero si abro ahora cadena2, note una diferencia aquí. Tenga en cuenta una diferencia aquí con cadena2. Con cadena2, este bucle for es un poco diferente. Déjame borrar los valores NULL para que podamos hablar de aquellos en otro momento. ¿Qué hay de diferente en el bucle for esta vez? Puedo volver al ejemplo anterior. Así que es la versión 2, esta es la versión 1. 1, 2. 1, 2. La llamada strlen es ¿dónde? Está en la primera parte del bucle for. ¿Alguna idea de por qué estoy haciendo esto? Si. [Estudiante] Así no se llama a la función cada vez. [Malan] Así que no llame a la función cada vez. Exactamente. Recuerde que en los bucles for que son super simple una vez que una especie de comprender que esta es la inicialización, la condición, y la actualización. El problema es que la condición ocurre en cada iteración del bucle. Y así, en este ejemplo aquí, ¿qué tiene de malo el hecho de que esta es mi condición? [Estudiante] Estás llamando strlen. [Malan] Estás llamando strlen una y otra vez y otra vez. Pero una vez que has escrito en David, la longitud de la cadena es de 5, y eso no va a cambiar en cada iteración del bucle porque la cadena es aún D-A-v-i-d. Así que esta es una pista de lo que va a convertirse en una idea cada vez más importante conocida como una decisión de diseño donde simplemente no hacer que el ordenador haga el trabajo innecesario. Así como un anticipo de pset2, pset2 en la edición estándar te va a desafiar a aplicar en la práctica un cierto número de cifras, un número de algoritmos de cifrado, por lo que ambos puedan cifrar y descifrar mensajes secretos muy similar a la Ralphie hay un decodificado. En la edición pirata de pset2, vamos a ir un poco más lejos. Nos vamos a entregar un archivo de un sistema informático actual que contiene una gran cantidad de nombres de usuario y contraseñas cifradas reales, y el reto de la edición pirata va a ser para agrietar las contraseñas y averiguar lo que la criptografía o qué secreto se utilizó para generar realmente las contraseñas. Y vamos a hacer esto utilizando una nueva característica de C que te voy a dar sólo un demo del conocido como argumentos de línea de comandos. Resulta que, como algunos de ustedes pueden haber visto en la sección o en libros de texto, principal no tiene que siempre ser nulo entre paréntesis. Resulta que la principal también se puede escribir así, con dos argumentos, argc y argv, donde argc es el número de palabras que se escribe después del nombre del programa en la línea de comandos y argv son las palabras reales. Y como los corchetes indican allí, argv es aparentemente una matriz. Va a ser una cadena después de una serie después de una cadena en la memoria. Entonces, ¿qué vamos a ser capaces de hacer a partir de conjunto de procesadores 2 es algo como esto. Si hago argv1, que es un ejemplo vamos a volver a los lunes, y ejecutarlo, cuenta de que no parece hacer nada. Simplemente imprime su propio nombre. Pero si digo adiós clase, observe que este programa aparentemente se repite sobre cada una de las palabras que se escriben en el indicador. Y los medios por los que vamos a tener acceso a las palabras que el usuario ha escrito en el indicador es cambiando principal a partir de este fin de semana desde int main (void) para int main (argc, argv) y así nacerá argumentos de línea de comandos. Y una vez que estés muy sofisticado en esto, usted será capaz de escribir programas realmente trippy como este aquí, que va por encima y más allá algunas de las funciones que hemos hecho hasta ahora, pero todo muy potente. Así que vamos a salir de esto con la siguiente en la pantalla, y nos vemos el lunes. [CS50.TV]