[Powered by Google Translate] [Semana 5] [David J. Malan - Harvard University] [Esta es CS50. - CS50.TV] Esto es CS50, la Semana 5. Hoy en día, y esta semana, presentamos un poco del mundo de la ciencia forense en el contexto del boletín de problemas 4. Hoy será una lección abreviada porque hay un evento especial en aquí después. Así que vamos a echar un vistazo y se burlan tanto de los estudiantes como para los padres de hoy en día con algunas de las cosas que están en el horizonte. Entre ellos, a partir del lunes, tendrá un poco más de sus compañeros de clase. EDX, Harvard y la nueva iniciativa en línea del MIT OpenCourseWare y para más, está poniendo en marcha en el campus de Harvard, el lunes, lo que significa venir Lunes tendrá, a partir del último recuento, 86.000 compañeros de clase adicionales que estará siguiendo a lo largo de con charlas CS50 y las secciones y los tutoriales y los conjuntos de problemas. Y como parte de esto, se convertirán en miembros de la clase inaugural del CS50 y CS50x ahora. Como parte de esto ahora, se dan cuenta que habrá algunos Upsides también. Para prepararse para esto, por la enorme cantidad de estudiantes, baste decir que a pesar de que contamos con 108 TFS y CAS, no es exactamente el mejor estudiante-maestro una vez que llegamos a 80.000 de los estudiantes. No vamos a calificar problema para muchos juegos de forma manual, que hubieran introducido esta semana en el conjunto de problemas será CS50 Check, que va a ser una utilidad de línea de comandos en el aparato que obtendrá una vez que lo actualice a finales de este fin de semana. Usted será capaz de ejecutar un comando, check50, en su propio conjunto de procesadores, y obtendrá información instantánea sobre si su programa es correcto o incorrecto de acuerdo con las especificaciones de diseño diferentes que nos han brindado. Más sobre esto en la especificación de problemas. Los compañeros de clase CS50x va a utilizar esto también. Boletín de problemas 4 tiene que ver con la medicina forense, y este conjunto de procesadores fue inspirado realmente por algunas cosas de la vida real por lo que cuando yo estaba en la universidad me internaron por un tiempo con la oficina del Fiscal del Condado de Middlesex el distrito está haciendo el trabajo forense con su investigador forense plomo. Lo que esto equivale a, como creo que he mencionado un par de semanas pasado, es la policía estatal de comunicación u otras personas pudieran entrar, ellos dejan las cosas como discos duros y CD y los disquetes y similares, y entonces el objetivo de la oficina forense era determinar si hubo o no evidencia de algún tipo. Esta fue la Unidad de Investigaciones Especiales, así que era delitos de cuello blanco. Era algo más preocupante de los delitos, cualquier cosa que implica algún tipo de medios de comunicación digitales. Resulta que no es que mucha gente escribe un e-mail diciendo: "Yo lo hice". Así que muy a menudo, estas búsquedas forenses no se presentó todo lo que mucho fruto; pero a veces la gente iba a escribir dichos correos electrónicos. Así que a veces, los esfuerzos fueron recompensados. Pero para llevar a este conjunto de procesadores forense, vamos a introducir en pset4 un poco de gráficos. Es probable que tomar estas cosas por sentado - JPEG, GIF y similares - en estos días. Pero si usted realmente piensa de él, una imagen, al igual que la cara de Rob, puede modelarse como una secuencia de puntos o píxeles. En el caso de la cara de Rob, hay todo tipo de colores, y empezamos a ver los puntos individuales, conocidos como píxeles, una vez que empezamos para acercar la imagen Pero si simplificamos el mundo un poco y decir que esto aquí es Rob en blanco y negro, para representar en blanco y negro, sólo puede utilizar binario. Y si vamos a utilizar binario, 1 ó 0, podemos expresar esta misma imagen de cara sonriente de Rob con este patrón de bits. 11000011 representa el blanco, blanco, negro, negro, negro, negro, blanco, blanco. Y lo que no es un gran salto después de comenzar a hablar acerca de fotografías a todo color, cosas que te gustaría ver en Facebook o tomar con una cámara digital. Pero, ciertamente, cuando se trata de colores, necesita más bits. Y muy común en el mundo de las fotografías es utilizar no 1-bit color, ya que esto sugiere, pero de 24-bit color, en el que realmente obtener millones de colores. Así como en el caso cuando el zoom en el ojo de Rob, que era cualquier número de millones de posibilidades diferentes colores. Así que vamos a introducir en este Boletín de problemas 4, así como en el tutorial, que será hoy a las 3:30 en lugar de las habituales a causa de 2:30 conferencia del viernes aquí. Pero el video estará en línea como de costumbre mañana. También voy a presentar a otro formato de archivo. Esto está deliberadamente destinada a parecer intimidante al principio, pero esto es sólo parte de la documentación para una estructura C. Resulta que Microsoft hace años ayudó a popularizar este formato llamado el formato de archivo de mapa de bits, bmp, y esto fue un super formato simple, colorido gráfico de archivos que se ha utilizado desde hace bastante tiempo ya veces aún para los papeles pintados de escritorio. Si usted piensa de nuevo a Windows XP y las colinas y el cielo azul, que era por lo general una imagen de mapa de bits bmp o. Los mapas de bits son divertidos para nosotros porque tienen un poco más de complejidad. No es tan simple como esta red de 0s y 1s. En su lugar, tienen cosas como un encabezado al comienzo de un archivo. En otras palabras, dentro de un archivo. Bmp es un montón de 0s y 1s, pero hay algo adicional 0s y 1s en ese país. Y resulta que lo que probablemente ha dado por sentado durante años - formatos de archivo como. doc o. xls o. mp3, mp4,. cualesquiera que sean los formatos de archivo que usted está familiarizado con - ¿qué significa ser incluso un formato de archivo, porque al fin y al cabo todos estos archivos que utilizamos tiene sólo 0s y 1s. Y tal vez los 0s y 1s representan ABC a través de ASCII o similares, pero al final del día, todavía es sólo 0s y 1s. Así que los humanos sólo de vez en cuando deciden inventar un nuevo formato de archivo donde estandarizar lo que los patrones de bits realmente significan. Y en este caso aquí, amigos los que diseñó el formato de archivo de mapa de bits dijo que en el primer byte en un archivo de mapa de bits, como se denota por 0 Offset allí, que va a ser un poco crípticamente llamado bfType variable llamada, que sólo representa el tipo de archivo de mapa de bits, el tipo de archivo de mapa de bits es la siguiente. Se puede inferir tal vez desde la segunda fila que compensado 2, número 2 byte, tiene un patrón de 0 y 1 que representa qué? El tamaño de algo. Y continúa desde allí. Así que, en conjunto Problema 4, se le atravesó algunas de estas cosas. No vamos a llegar a preocuparse por todos ellos. Pero note que empieza a ponerse interesante alrededor byte 54: rgbtBlue, Verde y Rojo. Si alguna vez has escuchado la sigla RGB - rojo, verde, azul - se trata de una referencia a esa porque resulta que se puede pintar todos los colores del arco iris con una combinación de rojo, azul y verde. Y de hecho, los padres en la habitación puede recordar algunos de los primeros proyectores. En estos días, usted acaba de ver una luz brillante que sale de una lente, pero de vuelta en el día en que tuvo la lente de color rojo, la lente azul y verde de la lente, y juntos dirigida a una pantalla y forman un cuadro de colores. Y muy a menudo, las escuelas intermedias y secundarias que tienen esos lentes muy ligeramente ladeado, por lo que eran una especie de ver imágenes dobles o triples. Pero esa era la idea. Tenías luz roja, verde y azul que pinta un cuadro. Y ese mismo principio se utiliza en las computadoras. Así que uno de los desafíos a continuación, para que en el Problema 4 van a ser unas cuantas cosas. Uno de ellos es para redimensionar una imagen, para tomar en un patrón de 0s y 1s, averiguar qué trozos de 0s y 1s representan lo que en una estructura de este tipo, y luego encontrar la manera de reproducir los píxeles - los rojos, los azules, los verdes - dentro, así que cuando una imagen se ve como este principio, puede parecer que esta vez después de eso. Entre los otros retos que también va a ser que se le entregó una imagen forense de un archivo real de una cámara digital. Y en esa cámara, hace mucho tiempo, eran un montón de fotos. El problema es que accidentalmente borrados o tenía la imagen dañada de alguna manera. Las cosas malas suceden con cámaras digitales. Y por lo que rápidamente copiado todos los de 0s y 1s de esa carta para ti, salvado a todos en un solo archivo grande, y luego los vamos a entregar a usted en problemas n º 4 de modo que usted puede escribir un programa en C con el que recuperar todos esos archivos JPEG, idealmente. Y resulta que los archivos JPEG, aunque son algo así como un formato de archivo complejo - son mucho más complejas que esta cara sonriente aquí - resulta que cada JPEG comienza con los mismos patrones de 0s y 1s. Así, utilizando, en definitiva, un bucle while o un ciclo for o similar, puede iterar sobre todos los 0s y 1s en esta imagen forense, y cada vez que ves el patrón especial que está definido en la especificación del conjunto de problemas, se puede asumir aquí es, con una probabilidad muy alta, el inicio de un JPEG. Y tan pronto como usted encuentra el mismo patrón determinado número de bytes o kilobytes o megabytes más tarde, se puede asumir que aquí hay una segunda JPEG, la foto que tomé después de la primera. Permítanme dejar de leer ese archivo en primer lugar, empezar a escribir este nuevo, y la salida de su programa para pset4 va a haber hasta 50 imágenes JPEG. Y si no son 50 imágenes JPEG, tiene un poco de un bucle. Si usted tiene un número infinito de imágenes JPEG, tiene un bucle infinito. Así que eso también será un caso bastante común. Así que eso es lo que está en el horizonte. Concurso 0 a nuestras espaldas, por cuenta de mi correo electrónico que siempre hay personas que son a la vez feliz, especie de punto muerto, triste y alrededor cuestionario tiempo 0. Y por favor acercarse a mí, la cabeza TF Zamyla, su propio TF, o una de las entidades emisoras de certificados que usted sepa si usted quisiera discutir cómo iban las cosas. Así que para impresionar a los padres aquí en la habitación, lo que es la biblioteca CS50? [Risas] Buen trabajo. ¿Cuál es la biblioteca CS50? Si. >> [Estudiante] Es un conjunto preescrito de código [inaudible] Bien, bien. Es un conjunto preescrito de código que escribió el personal, proporcionamos a usted, que proporciona parte de la funcionalidad común, cosas como hacerme una cadena, tráeme un int - todas las funciones que se enumeran aquí. A partir de ahora, empezamos a tomar realmente estas ruedas de entrenamiento apagado. Vamos a comenzar a llevar una cadena de usted, recuerdo que era un sinónimo para el tipo de datos real? >> [Varios estudiantes] Char *. * Char. Para los padres, que probablemente fue [hace sonido de soplido]. Eso es bueno. * Char vamos a empezar a ver en la pantalla con mayor razón ahora quitamos cadena de nuestro vocabulario, al menos cuando se trata de realmente escribir código. Del mismo modo, vamos a dejar de utilizar algunas de estas funciones tanto ya que nuestros programas se van a poner más sofisticado. En lugar de escribir programas que sentarse allí con un mensaje parpadeando, esperando a que el usuario escriba algo adentro, usted recibirá los aportes de otros lugares. Por ejemplo, usted los reciba de una serie de bits en el disco duro local. En su lugar, voy a conseguir en el futuro de una conexión de red, un sitio web en alguna parte. Así que vamos a pelar esta capa, por primera vez y tire hacia arriba del Dispositivo CS50 y el archivo llamado cs50.h, que ha sido incluido # durante semanas, pero vamos a ver realmente lo que hay dentro de esto. La parte superior del archivo en azul es sólo un montón de comentarios: información sobre la garantía y licencia. Esta es una especie de paradigma común en el software porque una gran cantidad de software en estos días es lo que se llama código abierto, lo que significa que alguien ha escrito el código y lo hizo libremente disponible no sólo para ejecutar y utilizar, sino para realmente leer y modificar e integrar en su propio trabajo. Así que eso es lo que usted ha estado utilizando software de código abierto, aunque de una forma muy pequeña. Si me desplazo hacia abajo más allá de los comentarios, sin embargo, vamos a empezar a ver algunas cosas más familiares. Aviso en la parte superior aquí que el archivo cs50.h incluye una gran cantidad de archivos de cabecera. La mayoría de ellos, no hemos visto antes, pero uno es familiar. Cuál de estos hemos visto, aunque brevemente, hasta el momento? >> [Estudiante] Biblioteca estándar. Sí, la biblioteca estándar. stdlib.h tiene malloc. Una vez que empezamos a hablar acerca de la asignación de memoria dinámica, que vamos a volver a la semana siguiente, así, que comenzó a incluir ese archivo. Resulta que bool y verdadero y lo falso en realidad no existe en C per se a menos que incluya el archivo aquí. Hemos estado durante semanas incluso stdbool.h de modo que usted puede utilizar la noción de una. bool, verdadero o falso Sin esto, usted tendría que ordenar de fingir y utilizar un int y sólo arbitrariamente asumir que 0 es falso y 1 es verdadera. Si nos desplazamos hacia abajo aún más, aquí es nuestra definición de una cadena. Resulta que, como hemos dicho antes, que esta estrella es donde en realidad no importa. Usted puede incluso tener espacio a su alrededor. Tenemos este semestre ha estado promoviendo como esto para dejar claro que la estrella tiene que ver con el tipo, pero se dan cuenta tan común, si no un poco más común, es ponerlo allí, pero funcionalmente es lo mismo. Pero ahora, si leemos más abajo, vamos a echar un vistazo a getInt porque hemos utilizado que quizás primero antes que nada este semestre. Aquí está getInt. Esto es lo que? >> [Estudiante] Un prototipo. >> Esto es sólo un prototipo. A menudo, hemos puesto prototipos en la parte superior de nuestro. Archivos c, pero también se puede poner en prototipos archivos de cabecera, archivos. h, como este de aquí de modo que al escribir algunas de las funciones que desea que otras personas puedan utilizar, que es exactamente el caso de la biblioteca CS50, no sólo poner en práctica sus funciones en algo así como cs50.c, también poner los prototipos no en la parte superior de dicho archivo, pero en la parte superior de un archivo de cabecera. Luego de que el archivo de cabecera es lo que los amigos y colegas incluir con # include en su propio código. Así que todo este tiempo que has estado incluyendo todos estos prototipos, eficazmente en la parte superior de su archivo, pero a través de este mecanismo # include, que esencialmente copia y pega este archivo en su cuenta. Aquí hay alguna documentación muy detallada. Hemos prácticamente por sentado que getInt recibe un int, pero resulta que hay algunos casos de esquina. ¿Qué pasa si el usuario escribe un número que es demasiado grande, un trillón, que no puede caber dentro de un int? ¿Cuál es el comportamiento esperado? Lo ideal es predecible. Así que en este caso, si uno lee la letra pequeña, que realmente va a ver que si la línea no puede ser leído, este INT_MAX devoluciones. Nunca hemos hablado de esto, pero en base a su capitalización, lo que es probable que sea? [Estudiante] Constante. >> Es una constante. Es una constante especial que probablemente está declarado en uno de los archivos de cabecera que es más alto en el archivo, y INT_MAX es probablemente algo así como unos 2 millones de dólares, La idea es que, porque tenemos que indicar de alguna manera que algo salió mal, nosotros, sí, tenemos 4 millones de números a nuestra disposición: -2 millones de dólares en hasta 2 millones de dólares, más o menos. Bueno, lo que es común en la programación es que robar uno de esos números, 0 tal vez, tal vez 2 millones de dólares, tal vez -2 mil millones, para que pase una de sus posibles valores para que pueda comprometerse con el mundo que si algo sale mal, yo me volveré este valor grande super. Pero usted no desea que el usuario escriba algo críptico como 234 ..., un número muy grande. Lo generalizar en cambio, como una constante. Así que en realidad, si se estaban anal en las últimas semanas, cada vez que se llama getInt, usted debe haber estado revisando con una condición, si lo hizo el tipo de usuario en INT_MAX, o, más específicamente, hizo INT_MAX getint retorno, porque si lo hiciera, que en realidad quiere decir que no lo escriba. Algo salió mal en este caso. Así que esto es lo que se conoce generalmente como un valor centinela, que sólo significa especial. Pasemos ahora en el archivo. C. El archivo de C ha existido en el aparato durante algún tiempo. Y de hecho, el aparato tiene que pre-compilados para usted en esa cosa que se llama código objeto, pero eso no le importa a usted donde está porque el sistema sabe en este caso donde es: el aparato. Vamos ahora a desplazarse hacia abajo y ver cómo getInt getInt ha estado trabajando todo este tiempo. Aquí tenemos comentarios similares de antes. Permítanme hacer un zoom sobre sólo la parte del código. Y lo que tenemos para getInt es la siguiente. No se necesita entrada. Se devuelve un int, mientras que (verdad), así que tenemos un bucle infinito deliberada, pero se supone que vamos a salir de esto de alguna manera o volver desde este. Vamos a ver cómo funciona esto. Parece que estamos usando GetString en esta primera línea dentro del bucle, 166. Esto ahora es una buena práctica porque bajo qué circunstancias podría volver GetString la palabra clave NULL especial? >> [Estudiante] Si algo sale mal. Si algo sale mal. ¿Y qué podría salir mal cuando se llama algo así como GetString? Si. >> [Estudiante] Malloc no imponerle los ints. Si. Tal vez malloc falla. En algún lugar debajo de la capilla, está llamando a malloc GetString, que asigna la memoria, que permite a la tienda de informática a todos los personajes que el usuario escribe en el teclado. Y supongamos que el usuario tenía un montón de tiempo libre y escribió más, por ejemplo, de 2 millones de caracteres, más caracteres que el equipo aún tiene RAM. GetString tiene que ser capaz de indicar que en su caso. Incluso si se trata de un caso super, super esquina poco común, tiene que ser de alguna manera capaz de manejar esto, y así GetString, si nos volvimos y leer su documentación, lo hace en NULL hecho de retorno. Así que ahora si GetString falla al devolver NULL, getInt va a fallar al volver INT_MAX así como un centinela. Estos son sólo convenciones humanas. La única manera de saber que este es el caso es leer la documentación. Vamos a desplazarse hacia abajo para que el int es realmente conseguido. Si desplácese hacia abajo un poco más lejos, en la línea 170, que tiene un comentario sobre estas líneas. Declaramos en un int 172, n, y char a, c, y entonces esta nueva función, que algunos de ustedes han tropezado antes, sscanf. Esto significa scanf cadena. En otras palabras, dame una cadena y lo voy a buscar los fragmentos de información de interés. ¿Qué significa eso? Supongamos que yo escribir, literalmente, 123 en el teclado y luego pulsa Enter. ¿Cuál es el tipo de datos de 123 cuando son devueltos por GetString? >> [Estudiante] String. Obviamente es una cadena, ¿no? Tengo una cadena. Así que 123 es realmente, entre comillas, 123 con el 0 \ al final de la misma. Eso no es un int. Eso no es un número. Parece un número, pero no es en realidad. Entonces, ¿qué getInt tengo que hacer? Se tiene que explorar esa cadena de izquierda a derecha - 123 \ 0 - y de alguna manera convertir a un entero real. Usted podría encontrar la manera de hacer esto. Si piensas en pset2, usted probablemente tiene un poco cómodo con César o Vigenère, así que usted puede iterar sobre una secuencia, puede convertir caracteres a enteros. Pero diablos, es un montón de trabajo. ¿Por qué no llamar a una función como sscanf que hace eso para usted? Así sscanf espera un argumento - en este caso llamado línea, que es una cadena. A continuación, especifique entre comillas, muy similar a printf, lo que se espera ver en esta cadena. Y lo que estoy diciendo aquí es que espero ver un número decimal y tal vez un personaje. Y vamos a ver por qué este es el caso en un momento. Y resulta que esta notación es ahora una reminiscencia de cosas que empezamos a hablar de poco más de una semana. ¿Cuál es & N y & c haciendo por nosotros aquí? >> [Estudiante] Dirección de n y la dirección de c. Si. Me está dando la dirección de n y la dirección de c. ¿Por qué es tan importante? Ustedes saben que con funciones en C, siempre se puede devolver un valor o ningún valor en absoluto. Usted puede devolver un int, cadena, un flotador, char a, lo que sea, o puede regresar vacío, pero sólo se puede volver una cosa al máximo. Pero aquí queremos sscanf para mí volver tal vez un entero, un número decimal, y también a. char, y voy a explicar por qué el char en un momento Que efectivamente quiere volver a sscanf dos cosas, pero eso no es posible en C. Puede evitar que al aprobar en dos direcciones porque en cuanto te entregan una función de dos direcciones, lo que puede que la función de hacer con ellos? >> [Estudiante] Escribir a esas direcciones. Se puede escribir en esas direcciones. Usted puede utilizar la operación estrella y ir allí, a cada una de esas direcciones. Es una especie de este mecanismo de la puerta trasera pero muy común para cambiar los valores de las variables más de un solo lugar - en este caso, dos. Ahora note que estoy comprobando == 1 y luego regresar n si eso es así, de hecho, se evalúan como true. Entonces, ¿qué está pasando? Técnicamente, todo lo que realmente queremos que suceda en getInt es esto. Queremos analizar, por decirlo así, queremos leer la cadena - entre comillas 123 - y si parece que hay un número allí, lo que estamos diciendo sscanf hacer es poner ese número - 123 - en esta variable n para mí. Entonces, ¿por qué entonces tengo realmente esto así? ¿Cuál es el papel de sscanf diciendo que también puede ser que consiga un personaje aquí? [Respuesta de los estudiantes inaudible] >> Un punto decimal en realidad podría funcionar. Vamos a celebrar que pensó por un momento. ¿Qué más? [Estudiante] Puede ser NULL. >> Buena idea. Podría ser el carácter nulo. En realidad no es en este caso. Si. >> [Estudiante] ASCII. ASCII. O deja que me generalizar aún más. El% c no es sólo para la comprobación de errores. No queremos que haya un carácter después del número, pero lo que esto me permite hacer es lo siguiente. Resulta que sscanf, además de almacenar los valores de N y C en este ejemplo aquí, lo que también hace es que devuelve el número de variables que poner los valores cm Así que si sólo escribe en el año 123, sólo el% d va a coincidir, y sólo se almacena n con un valor como 123, y nada se pone en c. C sigue siendo un valor basura, por así decirlo - basura, ya que nunca se ha inicializado a un valor. Así que en ese caso, sscanf devuelve 1 porque poblada 1 de los punteros, en cuyo caso grande, tengo un int por lo que liberar la línea para liberar la memoria GetString que realmente asignado, y luego vuelvo n, else if Te has preguntado donde Reintentar declaración que viene, que viene de aquí. Así que si, por el contrario, de tipo I en 123foo - sólo algunos secuencia aleatoria de texto - sscanf va a ver el número, número, número, f, y que va a poner el 123 en n, sino que va a poner en la f c y luego volver 2. Así que tenemos, simplemente usando la definición básica de la conducta sscanf, una manera muy simple - así, complejo a primera vista, pero al final de la día mecanismo bastante simple - de decir que existe un entero y si lo es, que lo único que he encontrado? Y el espacio en blanco aquí es deliberada. Si usted lee la documentación de sscanf, le dice que si se incluye una pieza de espacios en blanco al principio o al final, sscanf también permitirá que el usuario, por cualquier razón, 123 para golpear la barra espaciadora y que será legítimo. Usted no va a gritar que el usuario sólo porque pulsa la barra espaciadora al principio o al final, que es sólo un poco más fácil de usar. Cualquier pregunta entonces sobre getInt? Si. >> [Estudiante] ¿Qué pasa si usted acaba de poner en un char? Buena pregunta. ¿Qué pasa si usted acaba de escribir en un char como f y pulse Enter sin escribir 123? ¿Qué te parece el comportamiento de esta línea de código sería entonces? [Respuesta de los estudiantes inaudible] Sí, ¿y sscanf puede cubrir eso también, porque en ese caso, no va a llenar n o c. Va a volver en vez 0, en cuyo caso estoy también ponerse ese escenario debido a que el valor esperado que quiero es 1. Sólo quiero una cosa y sólo una parte del utilizador. Buena pregunta. ¿Otros? Está bien. Mejor no ir a través de todas las funciones de aquí, pero la que parece ser tal vez de interés restante es GetString porque resulta que GetFloat, getInt, GetDouble GetLongLong todo punt gran parte de su funcionalidad a GetString. Así que echemos un vistazo a la forma en que se lleva a cabo aquí. Éste parece un poco complejo, pero utiliza los mismos fundamentos que empezamos a hablar de la semana pasada. En GetString, que toma ningún argumento como por el vacío hasta aquí y devuelve una cadena, que al parecer estoy declarando una cadena denominada buffer. Realmente no sé lo que va a ser utilizado para todavía, pero ya veremos. Parece que la capacidad por defecto es 0. No estoy seguro de a dónde va esto, no sé lo que n se va a utilizar para, sin embargo, pero ahora se está poniendo un poco más interesante. En la línea 243, que declara un int, c. Esta es una especie de un detalle tonto. Un char es de 8 bits, y 8 bits puede almacenar cuántos valores diferentes? >> [Estudiante] 256. >> 256. El problema es que si quieres tener 256 caracteres distintos de ASCII, los cuales hay si usted piensa de nuevo - y esto no es algo para memorizar. Pero si piensas en esa tabla ASCII grande que tuvimos semanas atrás, existían en ese caso, 128 o 256 caracteres ASCII. Utilizamos todos los patrones de hasta 0s y 1s. Eso es un problema si usted quiere ser capaz de detectar un error porque si usted ya está usando 256 valores para sus personajes, que en realidad no planificar el futuro porque ahora no hay manera de decir: este no es un carácter de fiar, este es un mensaje erróneo. Así que lo que el mundo hace es que se utiliza el valor más grande que viene, algo así como un int, de modo que usted tiene un número loco de bits, 32 por 4 billones de posibles valores por lo que sólo tiene que terminan usando esencialmente 257 de ellos, 1 de los cuales tiene un significado especial como un error. Así que vamos a ver cómo funciona esto. En la línea 246, que tengo este bucle while grande que está llamando fgetc, f significado archivo, por lo getc, a continuación, stdin. Resulta que esto es sólo la forma más precisa de decirlo leer la entrada desde el teclado. Teclado estándar medio de entrada, la salida estándar significa pantalla, y el error estándar, que veremos en pset4, significa que la pantalla pero una parte especial de la pantalla para que no se confunden con la producción real que pretende imprimir. Pero más sobre esto en el futuro. Así fgetc sólo significa leer un carácter del teclado y almacenarlo donde? Guárdelo en c. Y a continuación, comprobar - así que estoy usando algunas conjunciones booleanas aquí - comprobar que no es igual a - \ n, por lo que el usuario ha pulse Enter, queremos dejar en ese momento, final del bucle - y también queremos comprobar la constante EOF especial, que si sabe o adivina, ¿qué significa? >> [Estudiante] Final del archivo. >> Final del archivo. Esto es un poco absurdo porque si estoy escribiendo en el teclado, no hay realmente ningún archivo involucrados en esto, pero esto es sólo una especie del término genérico utilizado para referirse que nada más viene de los dedos del humano. EOF - final del archivo. Como acotación al margen, si alguna vez te has golpeado Control D en su teclado, no es que usted tendría todavía - usted ha golpeado Control C - Control D envía esta constante especial llamada EOF. Así que ahora sólo nos queda un poco de asignación de memoria dinámica. Así que si (n + 1> capacidad). Ahora voy a explicar n. N es sólo cuántos bytes se encuentran actualmente en el búfer, la cadena que se está construyendo en la actualidad por parte del usuario. Si usted tiene más personajes en el búfer de lo que tiene la capacidad de la memoria intermedia, intuitivamente lo que tenemos que hacer entonces es asignar más capacidad. Así que voy a pasar rozando algunas de las operaciones aritméticas aquí y centrarse sólo en esta función aquí. ¿Sabes lo que es malloc o por lo menos generalmente familiar. Adivina lo que realloc hace. >> [Estudiante] Añade la memoria. No es bastante la adición de memoria. Se reasigna la memoria de la siguiente manera. Si todavía hay espacio en el extremo de la cuerda para que dure más de que la memoria de lo que originalmente le da, entonces usted conseguirá que la memoria adicional. Así que usted puede seguir poniendo los personajes de la cadena de vuelta a espalda con espalda con espalda. Pero si ese no es el caso, ya que esperó demasiado tiempo y se dejó caer algo al azar quedó en la memoria hay pero no hay más memoria por aquí, eso está bien. Realloc va a hacer todo el trabajo pesado para usted, mover la cadena ha leído hasta ahora de aquí, lo dejó allí, y luego le dan la pista un poco más en ese punto. Así que con un gesto de la mano, déjame decir que lo que está haciendo GetString se está comenzando con un buffer pequeño, tal vez un solo carácter, y si el usuario escribe en dos personajes, GetString termina llamando realloc y dice: un personaje no era suficiente, dame dos personajes. Entonces, si usted lee a través de la lógica del circuito, que va a decir el usuario escribió en 3 caracteres; dame ahora no 2, pero 4 personajes, entonces dame 8, entonces dame 16 y 32. El hecho de que estoy doblando la capacidad cada vez significa que el buffer no va a crecer poco a poco, va creciendo super rápido. Y lo que podría ser la ventaja de eso? ¿Por qué estoy doblando el tamaño de la memoria intermedia aunque el usuario sólo puede ser que necesite un personaje extra del teclado? [Respuesta de los estudiantes inaudible] >> ¿Qué es eso? >> [Estudiante] Usted no tiene que crecer con tanta frecuencia. Exactamente. Usted no tiene que crecer con tanta frecuencia. Y esto es sólo un poco de te de cobertura sus apuestas aquí, La idea es que usted no desea llamar realloc mucho, ya que tiende a ser lenta. Cada vez que usted le pide al sistema operativo para la memoria, como pronto veremos en un futuro conjunto de problemas, tiende a tomar algún tiempo. Así que minimiza la cantidad de tiempo, incluso si usted está perdiendo algo de espacio, tiende a ser una buena cosa. Pero si leemos a través de la parte final del GetString aquí - y otra vez la comprensión de cada línea aquí no es tan importante hoy en día - cuenta de que finalmente llama a malloc nuevo y se asigna exactamente tantos bytes como necesita para la cadena y luego tira a la basura llamando gratis el búfer excesivamente grande si de hecho he doblado varias veces. Así que en resumen, así es como GetString ha estado trabajando todo este tiempo. Todo lo que hace es leer un caracter a la vez una y otra vez y otra vez, y cada vez que necesita algo de memoria adicional, le pide al sistema operativo para que llamando realloc. ¿Alguna pregunta? Está bien. Un ataque. Ahora que entendemos punteros o por lo menos están cada vez más familiarizados con los punteros, vamos a considerar cómo el mundo entero comienza a derrumbarse si no alcanzas a defender contra los usuarios contradictorio, personas que están tratando de cortar en su sistema, personas que están tratando de robar su software eludiendo un código de registro que de lo contrario podría tener que escribir pulg Echa un vistazo a este ejemplo aquí, que es sólo el código C que tiene una función principal en la parte inferior que llama a una función foo. ¿Y qué es lo que pasa a foo? [Estudiante] Un solo argumento. >> [Malan] Un solo argumento. Así que argv [1], lo que significa la primera palabra que el usuario escribe en la línea de comandos después a.out o lo que se denomina el programa. Así foo en la parte superior lleva en un char *. Pero char * es qué? >> [Estudiante] Una cadena. [Malan] Una cadena, así que no hay nada nuevo aquí. Esa cadena es arbitrariamente ser llamado bar. En esta línea aquí, char c [12], en una especie de semi-Inglés técnico, lo que está haciendo esta línea? [Estudiante] Matriz de - Array de >>? >> [Estudiante] Caracteres. Caracteres. >> Dame una matriz de 12 caracteres. Así que podríamos llamar esto un buffer. Es técnicamente llamado c, pero un amortiguador en la programación sólo significa un montón de espacio que usted puede poner algunas cosas pulg A continuación, por último, memcpy no hemos usado antes, pero que es fácil adivinar lo que hace. Copia de la memoria. ¿Qué hacer? Aparentemente copia bar, su entrada, en c, pero sólo hasta la longitud de la barra. Pero hay un error aquí. >> [Estudiante] Se necesita el carácter sizeof. >> Okay. Técnicamente, deberíamos hacer strlen (bar) * sizeof (char)). Eso es correcto. Pero en el peor de los casos aquí, vamos a suponer que eso es - Bien. Entonces hay dos errores. Así sizeof (char)); Vamos a hacer esto un poco más. Así que ahora que todavía hay un error, que es lo que? >> [Respuesta de los estudiantes inaudible] Compruebe qué? >> [Estudiante] Comprobar valor NULL. Por lo general, se debe comprobar si NULL porque suceden cosas malas cuando el puntero es NULL, ya que podría terminar yendo allí, y no siempre se va a NULL por eliminación de referencias con el operador estrella. Así que eso es bueno. ¿Y qué más vamos a hacer? Lógicamente, hay una falla aquí también. [Estudiante] Comprobar si argc es> = a 2. A fin de comprobar si argc es> = 2. Bien, hay tres errores en este programa. Estamos comprobando si el usuario realmente escribió en nada en argv [1]. Bueno. ¿Cuál es el error tercera? Si. >> [Estudiante] C puede no ser lo suficientemente grande. Bueno. Nos registramos un escenario. Hemos comprobado implícitamente no copiar más memoria de la que se exceda la longitud de la barra. Así que si la cadena que el usuario escribió en es de 10 caracteres de longitud, esto se limitó a decir copiar 10 caracteres. Y eso está bien. Pero ¿qué pasa si el usuario escribió en una palabra en el indicador como una palabra de 20 caracteres? Esto es decir copia 20 caracteres de barra en qué? C, también conocido como nuestro buffer, lo que significa que acabas de escribir datos a 8 lugares byte que usted no es dueño, y no los poseen en el sentido de que nunca se les asignan. Así que esto es lo que se conoce generalmente como el ataque de desbordamiento de búfer o ataque saturación del búfer. Y es un ataque en el sentido de que si el usuario o el programa que está llamando a su función está haciendo maliciosamente, lo que realmente sucede a continuación en realidad podría ser muy malo. Así que vamos a echar un vistazo a esta foto aquí. Este cuadro representa la pila de memoria. Recuerde que cada vez que se llama a una función recibe este pequeño marco en la pila y luego otro y luego otro y otro. Y hasta ahora, tenemos sólo un poco abstraído estos en forma de rectángulos ya sea en el tablero o en la pantalla aquí. Pero si nos centramos en uno de esos rectángulos, cuando se llama a una función foo, resulta que hay más en el interior de la pila que enmarcan en ese rectángulo que apenas x e y y a y b, como lo hicimos hablando de swap. Resulta que hay algunos detalles de menor nivel, entre los que remite. Así que resulta cuando principal llama foo, el principal tiene que informar foo cuál es la dirección principal está en la memoria del ordenador porque de lo contrario, tan pronto como foo se hace ejecutar, como en este caso aquí, una vez que llegue a este corchete cerrado al final del foo, ¿cómo demonios se foo saber dónde está el control del programa se supone que debe ir? Resulta que la respuesta a esa pregunta está en este rectángulo rojo aquí. Esto representa un puntero, y le toca a la computadora para almacenar temporalmente en la pila de llamada de la dirección principal, de modo que tan pronto como foo se hace ejecutar, el equipo sabe dónde y qué línea principal para volver. Puntero salvado Frame refiere de manera similar a esta. Bar Char * aquí representa qué? Ahora bien, este segmento azul aquí es el marco de foo. ¿Qué es el bar? Bar es sólo el argumento de la función foo. Así que ahora estamos de vuelta en una especie de cuadro familiar. Hay más cosas y más distracciones en la pantalla, pero este segmento de color azul claro sólo es lo que hemos estado dibujando en la pizarra para algo como swap. Ese es el marco para foo. Y la única cosa en la que ahora mismo es el bar, que es este parámetro. Pero lo que más debería estar en la pila de acuerdo con este código aquí? [Estudiante] char c [12]. >> [Malan] char c [12]. También hay que ver 12 cuadros de memoria asignada a una variable llamada c, y de hecho tenemos que en la pantalla. La parte superior hay c [0], y entonces el autor de este diagrama no se molestó en dibujar todas las plazas, pero en realidad hay 12 hay porque si nos fijamos en la parte inferior derecha, c [11] si se cuentan desde 0 es el byte tal 12. Pero aquí está el problema. ¿En qué dirección se c creciendo? Ordenar de arriba hacia abajo si comienza en la parte superior y crece hasta el fondo. No se ve como nos dejó la pista mucho aquí en absoluto. Hemos clase de nosotros mismos pintado en una esquina, y que c [11] es justo contra bar, que está justo en contra puntero guardado, que es justo en contra del remite. No hay más lugar. ¿Cuál es la implicación entonces si metes la pata y se intenta leer 20 bytes en un búfer de 12 bytes? ¿Dónde están esos 8 bytes adicionales va a ir? >> [Estudiante] Inside - Dentro de todo lo demás, algunos de los cuales es súper importante. Y lo más importante, potencialmente, es el cuadro rojo allí, Dirección de Retorno, porque supongo que usted ya sea accidental o de contradicción sobrescribir esos 4 bytes, que la dirección del puntero, no sólo con la basura pero con un número que pasa a representar una dirección real en la memoria. ¿Cuál es la implicación, lógicamente? >> [Estudiante] Función que va a volver a un lugar diferente. Exactamente. Cuando regresa foo y éxitos que corchete, el programa se va a proceder no para volver al menú principal, va a volver a lo que la dirección está en esa caja roja. En el caso del registro de software eludir, ¿Y si la dirección que está siendo devuelto a es la función que normalmente se llama después de haber pagado por el software y introduce tu código de registro? Te puedes engañar al ordenador en no ir aquí, pero en vez de subir aquí. O si eres realmente inteligente, un adversario realmente puede escribir en el teclado, por ejemplo, no es una palabra real, los personajes no 20, pero supongo que él o ella actualmente los tipos de algunos personajes que representan código. Y no va a ser el código C, en realidad van a ser los personajes que representan el código binario de máquina, 0s y 1s. Pero supongamos que eres lo suficientemente inteligente como para hacer eso, para pegar alguna manera en el símbolo del sistema GetString algo que es esencialmente código compilado, y los últimos 4 bytes sobrescribir ese remitente. ¿Y qué dirección quiere que la entrada de hacerlo? Se almacena realmente en este rectángulo rojo la dirección del primer byte de la memoria intermedia. Así que hay que ser muy inteligente, y esto es un montón de prueba y error para la gente mala por ahí, pero si usted puede averiguar qué tan grande es este tampón de manera que los últimos bytes de la entrada le proporcionará al programa pasar a ser equivalente a la dirección del inicio de su buffer, que puede hacer esto. Si decimos hola y normalmente 0 \, eso es lo que termina en el búfer. Pero si eres más inteligente y llenamos ese búfer con lo que genéricamente llamaremos código de ataque - AAA, ataque, ataque, ataque - que es sólo algo que hace algo malo, ¿qué pasa si eres realmente inteligente, es posible hacer esto. En el cuadro rojo aquí es una secuencia de números - 80, C0, 35, 08. Tenga en cuenta que que coincide con el número que está aquí arriba. Está en orden inverso, pero más de eso en otro momento. Tenga en cuenta que esta dirección de retorno se hayan modificado para igualar la dirección de aquí, no la dirección de la principal. Así que si el malo de la película es súper inteligente, él o ella va a incluir en ese código de ataque algo así como eliminar todos los archivos del usuario o copiar las contraseñas o crear una cuenta de usuario que puede acceder a - nada en absoluto. Y este es el peligro y el poder de la C. Debido a que tiene acceso a la memoria a través de punteros y por lo tanto se puede escribir lo que quiera en la memoria de una computadora, usted puede hacer que un equipo hacer lo que quieras simplemente por haberlo saltar dentro de su propio espacio de memoria. Y así hasta el día de hoy tantos programas y sitios web internacionales de tantos que están en peligro se reducen a las personas que toman ventaja de esto. Y esto puede parecer un sofisticado ataque super, pero no siempre comienza de esa manera. La realidad es que lo que la gente mala suele hacer es, si se trata de un programa en una línea de comandos o un programa de interfaz gráfica de usuario o una página web, que acaba de empezar a proporcionar una tontería. Usted escribe en una palabra muy grande en el campo de búsqueda y pulsar Intro, y esperar a ver si el sitio web se estrella o esperar a ver si el programa se manifiesta algún mensaje de error porque si tienes suerte como el malo de la película y ofrecerle alguna entrada loco que bloquea el programa, lo que significa que el programador no previó su mal comportamiento, lo que significa que probablemente puede con bastante esfuerzo, el juicio suficiente y error, encontrar la manera de librar un ataque más preciso. Así que una parte tan importante de la seguridad no es sólo evitar estos ataques en conjunto pero su detección y, de hecho mirando logs y ver lo que la gente loca entradas tecleadas en su sitio web, qué términos de búsqueda y la gente escribe en su página web con la esperanza de algún desbordamiento buffer. Y todo esto se reduce a lo básico sencillas de lo que es una matriz y ¿qué significa para asignar y usar la memoria. Relacionado a continuación, que también es esta. Vamos a echar un vistazo en el interior de un disco duro nuevo. Usted recordará de una o dos semanas atrás, que al arrastrar archivos a la papelera de reciclaje o bote de basura, ¿qué pasa? >> [Estudiante] Nada. >> Absolutamente nada, ¿verdad? Finalmente, si se ejecuta sin espacio en disco, Windows o Mac OS comenzará a eliminar archivos por usted. Pero si arrastra algo ahí, eso no es del todo seguro. Toda su compañero de cuarto o de un amigo o miembro de la familia tiene que hacer es doble clic y, voila, hay todos los archivos incompletos que intentaron borrar. La mayoría de nosotros por lo menos saber que usted tiene que hacer clic derecho o control Haga clic en y vaciar la basura o algo así. Pero incluso entonces, que no acaba de hacer el truco porque lo que sucede cuando se tiene un archivo en el disco duro que representa algún documento de Word o algún JPEG, lo que representa el disco duro, y digamos que esta astilla aquí representa ese archivo, y se compone de un montón de 0s y 1s. ¿Qué sucede cuando usted no sólo arrastrar el archivo a la papelera o papelera de reciclaje pero también vaciarlo? Una especie de nada. No hay absolutamente nada ahora. Ahora sólo es nada porque un poco de algo que ocurre en la forma de esta mesa. Así que hay una especie de base de datos o tabla dentro de la memoria de una computadora que esencialmente tiene una columna para los nombres de archivos y una columna para los archivos 'ubicación, donde esto podría ser la ubicación 123, un número al azar. Así que podríamos tener algo como x.jpeg y la ubicación 123. ¿Qué sucede entonces cuando realmente vaciar la papelera? Que se vayan. Pero lo que no desaparece es el 0s y 1s. ¿Cuál es entonces la conexión a pset4? Bueno, con pset4, sólo porque hemos borrado accidentalmente la tarjeta Compact Flash que tenía todas esas fotos o simplemente porque la mala suerte se corrompió no quiere decir que el 0 y 1 no están todavía allí. Tal vez algunos de ellos se han perdido porque algo se corrompe en el sentido de que algunos 0s y 1s 1s convirtió se convirtió en 0s. Las cosas malas pueden suceder a causa de software defectuoso o hardware defectuoso. Pero muchos de esos bits, tal vez incluso el 100% de ellos, todavía están allí. Es que el ordenador o la cámara no sabe dónde comenzó JPEG1 y donde JPEG2 empezar. Pero si usted, el programador, saber con un poco de sentido común en esos JPEGs son o cómo se ven para que pueda analizar el 0 y 1 y dicen JPEG, JPEG, usted puede escribir un programa con esencialmente un bucle for o while que se recupera cada uno de esos archivos. Así que la lección es, pues, para empezar a borrar los archivos de forma segura si quieres evitar esto por completo. Sí. [Estudiante] ¿Cómo es que dice en su computadora que tiene más memoria que antes? Tener más memoria que antes - >> [estudiante] Más memoria disponible. Oh. Buena pregunta. Entonces, ¿por qué después de vaciar la basura tiene su ordenador le dirá que tiene más espacio libre que antes? En pocas palabras, porque está mintiendo. Más técnicamente, usted tiene más espacio porque ahora usted ha dicho puedes poner otras cosas en ese archivo una vez fue. Pero eso no significa que los bits van a desaparecer, y eso no significa que los bits están siendo cambiados para todos 0s, por ejemplo, para su protección. Así que por el contrario, si bien borrar archivos o destruir físicamente el dispositivo, que es realmente la única manera a veces alrededor de eso. Así que ¿por qué no nos vamos en esa nota semi-miedo, y nos vemos el lunes. [Aplauso] [CS50.TV]