>> [REPRODUCCIÓN DE MÚSICA]
DAVID J. MALAN: Esto es como un seminario de primer año en la actualidad.
OK.
Así que muy lluvioso cabo.
Esto tiende a ocurrir los miércoles, pero aún más oportunidad
para preguntas hoy.
Así que vamos a empezar en realidad con la película en un momento.
Pero vamos a empezar con grandilocuencia como siempre.
>> Esto es CS50, y esto Es el fin de semana 4.
Así que si alguna vez has visto La TV o una película en la que
hay algunos expertos en informática y la policía o el FBI, o alguna agencia
está tratando de tomar un poco de adversario, así, que haya
probablemente escuchado la expresión "mejorar" por la que ese técnico de alguna manera
zooms mágicamente en infinitamente para poder ver a los criminales
identidad o el número de matrícula incluso en el brillo de un espejo
o el brillo de los ojos de alguien.
Así que de hecho, vamos a echar un vistazo a algunas de esas escenas de Hollywood.
[REPRODUCCIÓN DE VÍDEO]
-OK, Ahora vamos a obtener un buen vistazo.
>> -Mantenga Ella.
Corre que volver.
>> -Espera un minuto.
Ve a la derecha.
>> -No, Congelar eso.
-Pantalla completa.
-OK, Congelar eso.
Endurecerá hasta en eso, ¿verdad?
-Vector en el que chico por la rueda trasera.
-zoom En aquí en este lugar.
-Con El equipo adecuado, la imagen podría ser ampliado y agudizado.
-¿Que es eso?
-Es Un programa de mejora.
-¿Puedes Claro que cualquier?
-No lo sé.
Vamos a mejorarlo.
>> Sección A6 -Mejorar.
>> -I Mejora el detalle, y- Creo que hay
suficiente para mejorar, liberar a mi pantalla.
-I Mejoró la reflexión en su ojo.
>> -Vamos A ejecutar esto a través de mejora de vídeo.
-Edgar, Puedes mejorar esto?
>> -Aférrate.
>> -He Estado trabajando en esta reflexión.
>> La reflexión de -Alguien.
-Reflexión.
-Hay Un reflejo de la cara del hombre.
-El reflejo.
-Hay Una reflexión.
-zoom En el espejo.
-Usted Puede ver un reflejo.
-Puede A mejorar la imagen de aquí?
-Puede Que lo mejorar aquí?
-¿Puedes Potenciarlo?
¿Puedes mejorarla?
>> -¿Podemos Mejoramos esto?
>> -¿Puedes Potenciarlo?
-Mantenga En un segundo, voy a Mejorar.
-zoom En la puerta.
-los Tiempos 10.
-zoom.
-Mudarse.
-Más.
-Espera, Deténgase.
-Deténgase.
-PAUSE Ella.
Nos -Girar 75 grados alrededor de la vertical, por favor.
-Deténgase.
Volver a la parte sobre la puerta, de nuevo.
>> -Got Un promotor de imagen que puede mapa de bits?
>> -Oye, Tal vez podemos usar el Pradeep Método de Sen para ver por las ventanas.
Software -Este es el estado de la técnica.
>> -El Valor propio está apagado.
>> -Con La derecha combinación de algorithm--
>> Eliminación tomada de -Él algoritmos para el siguiente nivel,
y puedo utilizarlos para mejorar esta fotografía.
>> -Lock Encendido y ampliar el eje z.
>> -Mejorar.
-Freeze Y mejorar.
>> [FIN DE REPRODUCCIÓN]
>> DAVID J. MALAN: Muy bien, así todos esos son en realidad palabras.
Sólo están ensartados en un de manera que no es en realidad sensible.
Y, de hecho, CS50 y cursos como es tiende a arruinar un montón de TV y películas
para ti.
Porque cuando los expertos en informática se recitar términos y diciendo
cosas de lujo como vectores propios, y el eje z,
y cualquier número de otra en realidad términos más técnicos,
que realmente están simplemente tensando palabras juntas con demasiada frecuencia.
¿Es eso una de nuestras esperanzas es que, como un efecto secundario de tomar cursos
como éste, lo hará más personas en el mundo realmente sea capaz de pesar en
y solo muy ligeramente influir en el la calidad y la exactitud de esas películas?
>> De hecho, vamos a echar un vistazo a la realidad.
Así que aquí está la foto personal de María, uno de nuestros compañeros docentes.
Y supongo que es sospechoso de algo.
Y, sin embargo, hay un atisbo de alguna pieza de evidencia en su ojo,
o en el reflejo de sus gafas.
Bueno, si lo hacemos exactamente como las películas proponer, en el que nos acercamos y "mejoramos",
esto es la cantidad de información es en el rostro de María
cuando se captura una imagen con la resolución original.
>> Y, de hecho, se puede ver estos puntos.
Y estos son los que son denominados píxeles, P-I-X-E-L-S,
que es sólo una plaza típicamente que es un punto que compone una imagen.
Y de vuelta en el día, y de hecho aun hoy con algunos de los televisores LED de hoy
o televisores LCD, si tienes una en su habitación o en el hogar,
si subes muy cerca de ella, y especialmente si se trata de un televisor algo mayor,
es probable que incluso se puede ver estos puntos y eso es lo que componer una imagen.
>> Y no hay más la información que esto.
Podríamos "mejorar", en el sentido de suavizar las cosas una y tipo de
inferir la clase de, clase de lo color debe estar al lado de los ojos de María
por lo que no es en realidad tan pixelada.
Pero si sigo zoom, hay es el malo de la película en los ojos.
Al igual que es tanto información que tenemos.
No puede crear Información de la nada.
Sólo hay una finita número de bits allí.
>> Así que en el problema Set 4, donde usted tiene una oportunidad
jugar con este tipo de mundo.
En el problema Set 4, explorará la mundo de los gráficos y análisis forense,
y en realidad escribir código que recupera imágenes perdidas.
Vas a escribir código que manipula imágenes existentes
y, finalmente, entender lo que está pasando por debajo de la capucha.
>> Y, resulta que, en realidad no tan complicado.
Por ejemplo, si quisiéramos representar una cara sonriente en
con estos píxeles negros, o estos puntos negros,
así, podríamos simplemente representar como un verdadero mapa de bits.
Y si había oído hablar alguna vez de que mapa de bits expresión, tal vez
ahora empieza a hacer una poco más hoy sentido.
>> Ya sabemos lo que un poco es.
Es 0 o 1.
Y un mapa es sólo algo como un trozo de papel
que ofrece direcciones y tiene tal vez una cuadrícula de x e y coordenadas.
Así que aquí es un mapa de bits.
Es un mapa de bits mediante el cual un 1 es aparentemente
pasando de representar un píxel blanco, y un 0 va a representar un pixel negro.
Pero sin duda podríamos darle la vuelta alrededor.
Realmente no importa lo Mientras estemos consistente.
Y aquí es cómo, en el interior binary-- de la memoria de una computadora, o incluso en el interior
de un archivo en su disco drive-- podrías guardar
el más simple de imágenes de caras sonrientes.
Pero, ¿qué somos nosotros, por supuesto, carente de esta imagen?
Color, ¿no?
Es un siguiente paso obvio o mejora para mejorar esto con color.
Así que por desgracia con un solo poco, 0 o 1, que podría representar el color.
Eso podría ser de color rojo o azul, o negro, o blanco, o verde o rosa,
o cualquier pares de colores.
Sin embargo, para simplificar, vamos a simplemente asumir blanco y negro.
>> Así que lo que lógicamente necesitamos si queremos quiere aplicar color en una imagen?
¿Que tenemos que hacer?
Al igual que si el factor limitante aquí es que con un bit sólo se puede
representar a dos estados, 0 o 1, blanco o negro, ¿qué quieres que haga?
AUDIENCIA: Más datos.
DAVID J. MALAN: más bits, yeah más datos, más bits.
Y, de hecho, eso es exactamente cómo imágenes en color están representados.
En lugar de utilizar un solo bit, una 0 o 1 para cada píxel, cada punto,
sólo tiene que utilizar múltiples.
Utilizar Tal 8, tal vez, más comúnmente utilizar 24, y de hecho, en la Serie de problemas
4, ¿quieres jugar con un archivo formato de 24 bits que utiliza normalmente.
>> Pero la mayoría de ustedes probablemente familiarizados con los archivos JPEG.
Si alguna vez has tomado una foto en su teléfono,
o subido o ha visto algo en Facebook o Flickr, cualquier número
de sitios web basados ​​en las fotos, no tienes Probablemente visto una imagen JPEG antes.
Y resulta que, este es el archivo formato que vamos a utilizar en PSet 4,
por el que se va a tiene que recuperar imágenes
que he borrado accidentalmente de un tarjeta de memoria dañada en la cámara,
si se quiere.
>> Y resulta que a pesar de que JPEG es bastante sophisticated--
es mucho más sofisticado que los puntos blancos y negros
que vimos hace un momento, porque hay algoritmos realidad de fantasía que
se utilizan para comprimir un JPEG, por lo que se puede tener una muy buena,
calidad de imagen, pero utilizando relativamente pocos bits.
Y volveremos a compresión en poco tiempo.
Resulta que la primera tres bytes en un image-- JPEG
no importa lo que usted ha tomado una fotografía de-- son los valores 255, 216, 255.
>> En otras palabras, si sólo ver que el patrón de bits,
representado aquí como de tres bytes o 24 bits en total,
con alta probabilidad se puede inferir que usted está buscando en esta primera de tres
bytes de un archivo JPEG.
Y esto es lo que se conoce como la firma de un JPEG.
Una gran cantidad de formatos de archivo por ahí tienden a comenzar
con ciertos patrones de 0s y 1s, para que Windows y Mac OS y iOS,
y Android sabe qué tipo de archivo que son, además del archivo de llamada
extensión que una gran cantidad de archivos tiene.
Si ha .jpg, eso es otra pista a la computadora.
>> Así que vamos ahora mira esto un poco más técnicamente.
Sabemos que el decimal sistema es del 0 al 9.
Sabemos binario es 0 y 1.
Y si usted piensa de nuevo a PSet 0, tuvimos que luchas con,
para un poco, algo llamado hexadecimal,
donde usted tiene 16 dígitos, en lugar de 10 o en lugar de 2.
Y esas cifras, por convención, son del 0 al 9 y luego un
a través de f, donde f representa lo que número decimal, al igual que una cordura rápida
comprobar?
Por lo tanto, 15.
Y algo que debe representar el 10, justo por naturaleza de la orden que he dado.
Es sólo una convención arbitraria, pero es bastante estándar.
>> Así que si nos fijamos en este patrón tres bytes-- vamos
acaba de empezar a mirar en de una manera consistente con la forma
científicos de la computación en general mirar y pensar acerca de los archivos.
Por supuesto que puede pensar archivos en 0s y 1s, y decimal,
pero en realidad, tendemos a usar binaria o más típicamente hexadecimal--
de vuelta de PSet 0.
Así que permítanme propongo 255, 216, y 255 son sólo estos patrones de 0s y 1s.
Y se puede comprobar esto si quieren hacer los cálculos de la Semana 0.
Pero, por ahora, sólo asumir que esto es correcto.
Yo sólo he reescrito de tres decimales números como tres valores binarios.
Ahora lo que voy a hacer es sólo tiene que añadir un poco de espacio blanco,
sólo por el bien de la legibilidad.
Y fíjense, yo sólo voy para mover cosas aparte.
Así que antes, después, antes, después.
Yo estoy haciendo nada interesante otra que sólo la difusión de las cosas de modo
que la notificación cada conjunto de ocho años bits es ahora dos conjuntos de cuatro bits.
Esto es útil porque hexadecimal es particularmente moda
porque cada dígito hexadecimal de 0 a f, o más específicamente de 0 a 15,
puede ser representada con exactamente cuatro bits.
En otras palabras, en hexadecimal si quiere representar un 0, es sólo 0000,
cuatro ceros.
Y si usted quiere representar 15, es 1,111, que es de cuatro bits.
Y si se hacen las cuentas, si este es el lugar de las unidades,
este es el lugar 16, eso va a dar usted--
más bien, que va a-- lo siento, en binario,
eso va a dar 15, queridos lugar, twos lugar, a cuatro patas y ochos lugar.
Así que permítanme propongo que un conjunto de cuatro bits de la izquierda
es lo que vamos a llamar a f.
Es el mayor número que puede representar con cuatro bits.
Y ya sabemos de hexadecimal, f es la más grande de dígitos en hexadecimal.
Tenemos otro f allí, dos más allá.
Y por ahora, acaba de tomar en la fe que he hecho el derecho de matemáticas
y que la mitad izquierda de esos bits, 1101,
es lo mismo que d en hexadecimal.
Y la mano derecha, 1000, está a sólo 8.
>> Y de que uno fácil de ver, ¿no?
El 8 represents-- es correcto debajo de ese lugar ochos.
Así que tenemos una en la columna de la ochos y nada en las cuatro patas, dos en dos queridos o.
Así que ahora más convencional, los seres humanos tienden escribir dígitos hexadecimales como este,
sólo les aplastas juntos, y luego se les prefijo 0x.
No significa nada que no sea una pista visual a un human--
aquí viene un value-- hexadecimal porque puede que no de otra manera sería obvio.
>> Es decir, en última instancia, que el patrón de ceros y unos,
o el patrón de hexadecimal dígitos equivalentemente que eres
va a empezar a buscar en Boletín de problemas 4 es esto--
y el problema Set 4 spec caminará a través de esto con más detail--
pero se dan cuenta como una especie de arcano como esto podría parecer a primera vista,
vas a empezar a ver esto mucho.
Y de hecho, incluso en GDB, el depurador introdujimos el lunes
y Dan introduce en PSet 3, va a menudo le mostrará valores hexadecimales
sólo porque tienden a ser más convencional que decimal o binario
en el mundo de las computadoras.
Ahora vamos a poner esto en contexto.
Muchos de ustedes pueden recordar esto imagen aquí, que vino de qué?
Vista, por lo que incluso antes de lo que, Windows XP hicieron este debut.
Así que este es un hermoso paisaje.
Y de hecho, si te asomas alrededor online-- Creo que es un artículo de Wikipedia,
en donde alguien muy sorprendentemente salió encontrado este lugar en el mundo creado
su cámara en precisamente el lugar-- derecho
y esto hoy parece como-- pero es exactamente la misma configuración.
Esta imagen, sin embargo, está en un archivo formato llamado mapa de bits, b-m-p.
Y vamos a tomar un super rápido vistazo a lo que eso significa.
>> Pero de mapa de bits es sólo una forma diferente de imágenes que representan todavía con píxeles
en 0 y 1, en última instancia.
Pero al rápido vistazo, tiene una firma más interesante
en el principio del archivo.
No se trata sólo de tres bytes, en lugar hay
un montón de patrones de bytes que han determinado significado.
Por ejemplo, en algún lugar de la primeros bytes de la imagen de mapa de bits
va a ser el tamaño de la imagen, la anchura de la imagen,
la altura de la imagen, por lo metadatos útiles, si se quiere.
Información útil que Photoshop o cualquier gráfico programa que utiliza
en realidad podría preocuparse.
>> Así más sobre esto en Problema Set 4, pero esto
es sólo para decir que al final del dia
todos los formatos de archivo que usted ha estado utilizando para los archivos de Microsoft Word años--,
Números archivos, archivos de Excel, cualquier número de formatos de archivo
que podría tener alguna extensión de archivo conocido
son sólo 0s y 1s debajo del capó.
Y los seres humanos han decidido lo que las convenciones son,
lo que los patrones de 0s y 1s representan presentar una palabra frente a un archivo de Excel,
frente a cualquier número de otros formatos de archivo.
Así que en PSet 4, tendrá un oportunidad de jugar con eso.
>> Pero ¿qué significa tener una estructura.
Esto es realmente una buena segue ahora en C, que tiene sólo un par
características de adicionales que no hemos mirado todavía.
Es una muy pequeña lengua y uno de las características buenas de C es una estructura.
Por ejemplo, si usted querido represent-- vamos
Dices que quería tener una variable que representa un estudiante en algún programa.
Tal vez estuviera escribiendo un curso programa de registro, o de compras núcleo
herramienta, o algo así.
¿Cuáles son piezas de datos relacionados a un estudiante que viene a la mente?
Como un estudiante es representado con qué valores?
¿Sí?
Usted tiene un nombre como estudiante.
¿Qué más tiene un estudiante típico?
>> AUDIENCIA: [inaudible]
>> DAVID J. MALAN: Así que, lo siento.
>> AUDIENCIA: Edad.
>> DAVID J. MALAN: Una edad o cumpleaños equivalentemente, sí.
¿Qué otra cosa?
AUDIENCIA: número de identificación?
DAVID J. MALAN: Así que un número de identificación, tal vez un número de teléfono, tal vez un dormitorio, o casa,
o la universidad, o algo así.
Cualquier número de piezas de datos que que pueda tener en su lista de contactos
es lo que se podría definir un estudiante.
Así que si lo que queríamos hacer esto, en el código, que podríamos hacer algo tan simple como esto.
Puede ser que tengamos un programa para que tiene digamos, int main (void).
Y si quiero representar una estudiante que podría tener, por ejemplo,
una cadena llamado nombre para ese estudiante, una cadena llamada dormitorio para ese estudiante,
tal vez un int llamado ID para ese estudiante.
Y porque estoy usando cuerdas, me tenga que volver atrás y aguantar CS50.h.
Tal vez voy a necesitar stdio.h.
Así que permítanme preventivamente hago esas y estoy va a llamar a este student.c por ahora
y guarde este.
>> Y ahora puedo hacer algo con estas variables.
Y sólo vamos a escribir que como un comentario en pseudo código,
porque no es interesante lo que hacemos por el momento.
Aceptar, por lo que este es un programa que de alguna manera almacena un estudiante.
¿Qué es lo que quiero hacer si desea almacenar dos estudiantes?
Así que mi primer instinto va a estar bien, espera un minuto,
si tengo otro estudiante por qué no hacer yo acaba de hacer nombre de la cadena 2, cadena de dormitorio 2,
int id2.
Y lo hemos hecho se ha ido por esto antes
y lo que era nuestra solución a lo que parece a ser una especie de pasta de copia hackish
trabajo aquí?
AUDIENCIA: Una matriz.
DAVID J. MALAN: Sí, podríamos utilizar una matriz.
Haga esto muy rápidamente se vuelve difícil de manejar.
Usted tiene que ordenar de forma arbitraria iniciar nombrar todas estas variables.
Y usted, el ser humano, tiene que mantener seguimiento que corresponde OK nombre2
con dorm2 corresponde con id2.
Sólo se convierte en un desastre.
Así que es mucho más fácil, recordar desde hace unas semanas,
sólo tener que llamados nombres de cadena y tal vez nos dé tres de ellos.
Y entonces tal vez tenemos dormitorios cadena y tienen
tres de ellos, o con una constante, int identificadores y tienen tres de ellos.
Pero incluso ahora, esto se siente un poco descuidado, derecha.
Estamos hablando de los estudiantes y sin embargo, Estoy realmente detenerse en el nivel bajo
detalles de implementación.
El estudiante es un nombre y una residencia de estudiantes y el ID.
>> ¿Por qué no puedo simplemente declarar una variable llamó estudiante y lo llaman es.
Y si quiero otro estudiante, ¿por qué no simplemente lo llamo t.
O si quiero un montón de los estudiantes, ¿por qué no lo hago yo sólo
decir que tengo toda una clase de estudiantes, y es tres de ellos.
En otras palabras, ¿por qué no puedo ir con mi propio tipo de datos, llamada
Los estudiantes, dentro de los cuales es un nombre, es una identificación, es una residencia de estudiantes,
es cualquier número de otros campos.
Y resulta que puede hacer exactamente eso.
>> Así que C tiene esta característica denominada struct.
Esa es una característica de un lenguaje que nos permite hacer exactamente esto.
Voy a seguir adelante y abrir structs.h
donde vamos a ver el siguiente definición de un estudiante.
Resulta - y éste es incluso más sencillo que el que implica un ID
hace un momento.
Si quieres llegar a su tipo de datos hecha en casa,
y además de int y carbón y flotar y todos esos otros que existen,
usted puede hacerlo, literalmente, escribir typedef struct,
a continuación, algunas llaves, dentro de los cuales usted
una lista de las variables que desea asociar con estos nuevos datos a medida
escriba como un nombre y un dormitorio, y luego después de las llaves
le das un nombre al nuevo tipo de datos.
Así, por ejemplo, de los estudiantes.
>> Y lo que es bueno de esto es que ahora si nos fijamos en el código correspondiente,
la convención, primero de todos, es poner este
en un archivo llamado algo dot h, un archivo de cabecera, que no tenemos
comenzado a usar nosotros mismos demasiado.
Pero vamos a empezar usando un poco ahora.
Y lo que podemos hacer con esto, en última instancia, en estas pocas líneas de código
se declare exactamente eso tipo de datos, un estudiante.
Y ahora vamos a utilizar la misma.
>> Voy ahora a entrar en un archivo llamado structs1.c.
Y vamos a echar un vistazo a una algunas características aquí.
Así las cosas aquí es sobre todo familiar, y vamos a
volver a lo que no lo es familiar en un momento.
Por supuesto, esto es incluyendo mi propia archivo de cabecera, que es nuevo, así,
a excepción de PSet 3 donde, retiro, tenemos helpers.h.
Así que usted puede recordar helpers.h #include.
>> ¿Por qué aunque estoy usando comillas en lugar de corchetes angulares?
¿Cuándo puedo elegir entre ellos?
Casi siempre me parece utilizar paréntesis angulares.
Y luego, de repente, en línea de seis estoy usando comillas dobles.
¿Por qué podría ser?
¿Sí?
>> AUDIENCIA: [inaudible]
DAVID J. MALAN: Eso es un real, ¿qué?
AUDIENCIA: Eso está en su IDE.
DAVID J. MALAN: Sí, eso es en mi IDE real.
Y no habitan en el IDE, porque eso es sólo una herramienta que estoy usando.
Eso es en mi actual directorio, específicamente.
Así structs.h es mi propio archivo no se instala en el IDE,
en el sistema operativo en sí mismo, sino que es en mi directorio actual.
Así que la convención es que si quieres para incluir su propio archivo de cabecera,
sólo tiene que utilizar comillas dobles.
>> ¿Cómo se llama esto en línea 8, en términos generales?
¿Esto es lo que?
algo #define.
Esto representa constantes, ¿verdad?
Si usted quiere tener un valor en su programa
que se utiliza en su totalidad montón de veces, es
buena convención para factorizar a cabo, declarará, con el símbolo de hash
definir, entonces, por convención, en todo mayúsculas palabra-- aunque no es
estrictamente necesario, pero es convención humana
para capitalizar constantes para que saltan
por lo que el espacio y el visually-- entonces el valor que desea ser
equivalente a nombre de esa constante.
No coma, pero simplemente seguir ese patrón de allí.
>> Así que lo que estoy haciendo en este código real.
Así que echemos un vistazo a el programa principal aquí.
En la línea 12 porque yo han incluido structs.h,
Ahora tengo mágicamente en mi disposición un nuevo tipo de datos.
Yo no sólo tengo acceso a int, y char, y el flotador, y la cadena,
y azul y otros.
Ahora tengo acceso a un tipo de datos de los estudiantes.
Así, en la línea 12, que estoy combinando dos ideas-- solo un tipo de datos personalizados y dos,
utilizando una matriz.
Y así, en este programa si Quiero apoyar realidad
tres estudiantes de diferentes en mi programa,
simplemente puede decir dame una variable llamados estudiantes, cada uno de los cuales
es de los estudiantes de tipo, que es mi tipo de datos personalizado.
Y, en concreto, dame tres de ellos en mi matriz.
>> Así que ahora, ¿qué hacemos en este programa?
He aquí sólo para la iteración del bucle de 0 a 3, porque eso es
lo que el valor de los estudiantes es.
Sólo estoy pidiendo al usuario dame el nombre del estudiante.
Y luego, en la línea 17, que tener una línea sobre todo familiar.
Tenemos nuestro viejo amigo GetString a la derecha.
¿Y qué pedazo de sintaxis es aparentemente nueva,
si nunca has programado en C antes, y nunca han utilizado las estructuras?
¿Sí?
>> AUDIENCIA: El .name.
DAVID J. MALAN: El .name.
Pero esto no es demasiado de un salto, porque ahora los estudiantes soporte de E
le da al estudiante de orden i.
Y si quieres bucear dentro de esa estructura,
sólo tiene que utilizar un solo período y a continuación, el nombre de la variable dentro,
o la propiedad dentro de ese Quieres tener acceso a.
Del mismo modo entonces, si a continuación, pedir al usuario, dame residencia del estudiante,
se puede almacenar de manera similar que cadena en la variable de residencia en el interior
de que la estructura de los estudiantes.
>> Y ahora las cosas se ponen un poco de fantasía.
Y esto se va a ver en tal vez un montón bastante pronto.
Pero verás esto mucho más en PSet 4, por lo que vamos a simplemente mirar a ahora.
Resulta que en la línea 23 a través 38, ¿qué crees que tal vez estoy haciendo?
He quitado los comentarios para hoy, pero la versión
del código en línea para referencia tiene todos los comentarios.
¿Qué me parece que estoy haciendo?
>> AUDIENCIA: Guardar el archivo con todo la información que el usuario ha introducido.
>> DAVID J. MALAN: Sí, exactamente, esta es una nueva forma
que estamos viendo dos, otra característica de C,
mediante el cual puedo crear mis propios archivos.
Hasta ahora, casi todos los programas que has escrito es apátrida.
Tan pronto como se hace correr, eso es todo.
No hay memoria o recuerdo de ella.
No hay archivo guardado.
Pero si usted quiere guardar entrada que tiene
sucedido, como en un juego o un programa así, resulta que podemos hacerlo.
Y verás esto más en PSet 4 y en la Sección.
Pero esta línea 23 esencialmente crea un archivo llamado students.csv.
Y que podría haber visto esto antes.
Incluso si nunca has estudiado CS antes, CSV es de variables separadas por comas.
Es como una muy pobre hombre versión de un archivo de Excel,
lo que significa que se puede abrir en Excel y en Números de Apple,
y tiene filas y columnas.
Pero no es una propiedad formato como Microsoft o Apple.
Son sólo las comas que separan el valores que veremos en un momento.
>> Y acaba de tomar una conjetura.
En la línea 23, en el mismo final, mi segundo argumento
a esta nueva función llamada f abierto para abrir el archivo es w.
Lo que podría denotar w?
¿Sí?
>> AUDIENCIA: Se le permite escribir en el fichero?
>> DAVID J. MALAN: Permite se escribe en el archivo.
Así que hay un par de variantes que podemos enchufar aquí.
Pero si lo que quieres leer el archivo, es mirarlo
y leerlo en la memoria, sólo tiene que utilizar comillas "r".
Si desea escribir en el archivo, utilice comillas "w".
También ha anexar y un par de otras cosas
si desea modificar los archivos existentes.
Ahora vamos a seguir viendo a esta cosa, entonces nos va a volver a la línea 24.
NULL, resulta, es un valor especial que
pueden ser devueltos por ciertas funciones si algo ha ido wrong--
si el archivo no existe, si has quedado sin memoria,
o un montón de otros errores.
Pero por ahora, vamos a suponer que esta es la comprobación de errores simplemente convencional.
Aquí, en la línea 26, que estoy iteración de 0 a 3 sobre todos mis estudiantes.
Y esto es una especie de clase de una nueva función, fprintf,
pero sólo tomar una conjetura.
Si printf es sólo de impresión una cadena con formato,
¿qué significa probablemente fprintf?
AUDIENCIA: Imprimir a un archivo.
DAVID J. MALAN: Imprima una cadena con formato a un archivo.
Eso es lo que la tasa adicional medios f es archivo.
Y el nuevo primer argumento tiene que ser la variable que representa el archivo.
Entonces sólo tenemos un formato cadena como printf.
Y a pesar de que este la sintaxis es nuevo, esto sólo
significa conectar el nombre del estudiante, plug-in de la residencia de estudiantes, y luego
con fclose, cierre el archivo.
Y luego lastly-- esto es nuevo y volveremos a este
antes long-- estoy liberando el estudiante por razones
eso pasó por encima de allí.
Pero volveremos a que antes de long--
eso es debido a cómo es GetString en realidad trabajan debajo de la campana.
>> Así que vamos a echar un vistazo rápido aquí.
Si escribo ls en mi directorio, cuenta de que no lo hago
tener un archivo llamado students.csv, simplemente no hay, no existe.
Así que si ahora puedo compilar este programa, hacer estructuras-1,. / estructuras-1,
y yo voy a seguir adelante y escribir Andi, que vive en Berkeley en Yale.
Vamos a tener que Rob vive en Thayer estos días.
Y vamos a llegar con el lugar donde es, creo, María está en Mather,
si he recordado correctamente.
>> Así que nada parece suceder.
Pero si escribo ls ahora, hay students.csv.
Vamos a seguir adelante y students.csv abierta.
Esto es de nuevo una muy formato de archivo de peso ligero.
Pero simplemente he adoptado una convención que tengo dos filas y columnas aquí.
La primera columna es primeros nombres de las personas.
La segunda columna es el estudiante de dormitorio, o universidad, o una casa, o lo que sea.
Y ahora me he ahorrado este permanentemente en un archivo.
>> Así que no es tan interesante.
Pero esto es sólo un peldaño en el camino ahora de ser capaz de mantener la información
de forma permanente.
Así que vamos a ver ahora qué más podemos ver con estas y otras características.
Pero primero, cualquier pregunta?
Eso era mucho, y eso fue rápido.
Pero verás un montón más en PSet 4, también.
¿Sí?
>> AUDIENCIA: ¿Hay una manera de seguir añadiendo nombres a ese archivo?
>> DAVID J. MALAN: Buena pregunta.
¿Hay una manera de continuar añadiendo nombres a ese archivo?
Sí.
Y, de hecho, si al final hasta volver a abrir el archivo,
usted utilizaría cotización fin de la cita "a" para añadir,
que acaba de añadir una nueva línea, un nueva línea una y otra vez, exactamente.
Buena pregunta.
¿Otras preguntas?
¿Sí?
AUDIENCIA: Si ejecutó el programa de nuevo en este momento,
habría que seguir añadiendo nombres a la Archivo o tendría que abrir un nuevo archivo?
>> DAVID J. MALAN: Ah, buena pregunta.
Si ejecutó el programa de nuevo a la derecha Ahora, tal vez escrito en nuevos nombres,
habría que añadir al archivo o sobrescribir el archivo?
Esto último, porque estoy No se utiliza el modo de agregación.
Y porque estoy ciegamente abrir el archivo para escritura,
que sólo va a sobrescribir el archivo.
Así que yo de hecho que tenga que hacer es añadir, si yo quiero tener en realidad un largo plazo
base de datos.
>> Ahora CSV es útil, francamente, incluso para como si eres writing--
y finalmente veremos este más tarde en el semestre cuando
usamos CSVs para otros fines.
Si desea almacenar toda la gente que se han registrado para algún evento,
o inscrito para su estudiante grupo, o algo así,
almacenar los datos en este tipo de formato es muy práctico.
Debido a que, literalmente, si eran para descargar este archivo.
Podía double-- y vamos a tratar esta realidad
si tengo Excel o números aquí.
>> Voy a botón derecho del ratón o control clic en mi archivo.
¡Vaya.
Haga clic derecho o control clic en mi archivo.
Vamos, mi ratón no está cooperando.
Download-- voy a descargar todos los archivos de aquí, así
para que yo pueda tomar éste.
Y vamos a ver si esto funciona students.csv-- primera vez
He activado.
Ahora quieren ver mis contactos.
Ahora, me tengo que registrar.
Vea lo fácil que es utilizar CSV?
Sí, sigue así hasta la fecha.
OK, ahora estamos listos para la clase.
OK, oh, ¿qué hay de nuevo?
OK, cerca.
Fue mágico.
Bien, ahora tenemos que actualizar.
Y ahora, se olvidó de lo presento abrí originalmente,
pero lo que A-- ahí vamos.
OK, así que ahora tenemos un archivo de Excel.
Gracias.
>> OK, así que lo que hice fue la parte fácil.
Por supuesto que podría haber instalado previamente Excel o Numbers, o cualquier programa.
Pero esto es bueno, porque ahora puedo manipular
los datos en un formato estándar.
>> Así que ahora vamos contexto cambiar a donde lo dejamos
la última vez, que iba a comenzar para despegar las ruedas de entrenamiento.
Pero primero, no lo hiciste ver este almuerzo anterior
de nuevo está sucediendo aquí en Fuego y Hielo en Cambridge, Sitar en New Haven.
Regístrate en la página web CS50s ASAP para unirse a los estudiantes CS50 y el personal.
>> Así que tomamos las ruedas de entrenamiento fuera el lunes debido a follows--
cuerdas ha sido declarado en Biblioteca CS50s durante algún tiempo.
Y es bueno, porque permite que hablemos de las variables como
palabras y frases completas y más.
Pero resulta que la cadena no existe.
Eso es sólo un sinónimo o un alias, que hemos creado algo que
en realidad es un poco más técnica llamada char *.
>> Y de hecho, vimos un ejemplo de un programa de este lunes
que no se comportó bastante como esperábamos.
Este fue el archivo, comparar-0.
Y recuerdan que comparar-0, si Yo recompilar el programa del lunes
y ejecutar compare-0 y el tipo de madre en minúsculas, y la mamá en minúsculas nuevo.
El programa insistió en que escribir cosas diferentes,
a pesar de que mamá, todo en minúsculas, es idéntico visualmente.
Entonces, ¿cuál fue la respuesta corta por qué el equipo piensa
esas dos cadenas son diferentes?
¿Sí?
>> AUDIENCIA: [inaudible]
DAVID J. MALAN: Correcto.
Así, la mamá, la primera vez Escribo en ella, está siendo
almacenada en algún lugar de mi equipo memoria, pero en una ubicación diferente
que la segunda vez que escribo en mamá.
Ahora sin duda podría ser optimizado.
El equipo podría ser inteligente y darse cuenta de estas dos cadenas, hey,
son idénticos.
Permítanme no redundante almacenarlo.
Pero las computadoras no hacen eso optimización a menos que diga que lo hagan.
Así que, por defecto, que son sólo va a terminar
en dos lugares diferentes en la memoria.
Y así, para ser más claro, cuando comparamos las dos cadenas,
El primero fue llamado s, el segundo fue llamado
t, lo que era específicamente I comparando aquí en la línea 13?
Sí.
>> AUDIENCIA: Es el lugar en la memoria que la variable apuntará a.
>> DAVID J. MALAN: Exactamente, yo era comparando el lugar en la memoria
aquellas variables que apuntaban a.
Así en concreto, si la madre estaba en el byte número 1, y 2, y 3,
y 4-- porque recuerdan la barra invertida 0 tiene que ser todo el camino al final.
Y la otra instancia de la madre, m-o-m, fue en la dirección 10, 11, 12 y 13.
Yo estaba comparando 1, esa dirección, que la ubicación en la memoria,
contra 10, que es obviamente no es el mismo.
1 no es 10.
>> Así que esto es agradable en que es bastante sencillo.
Pero es problemático en la medida en parece que no podemos comparar cadenas.
Así fundamentally-- y en este bajo nivel,
si usted quiere poner en práctica un programa para comparar
dos palabras separadas que la usuario ha escrito en cuanto a calidad,
hacen que se alinean carbón para char, sólo en términos generales,
¿qué es lo que tenemos que hacer, por lo visto?
No es suficiente sólo para mirar esas dos direcciones.
¿Qué necesitamos hacer?
¿Sí?
>> AUDIENCIA: Iterar a través la cadena [inaudible].
>> DAVID J. MALAN: Sí, vamos a iterar a través de la cadena.
Vamos a utilizar un bucle for, un bucle while, o lo que está más cómodo.
Y si tenemos dos cadenas en alguna parte en la memoria, echemos un vistazo a cada uno de
primer carácter, entonces cada uno es segundo carácter, a continuación, tercero, y cuarto,
y quinto, hasta que golpeó qué valor especial centinela?
AUDIENCIA: [inaudible]
DAVID J. MALAN: Sí, la barra invertida cero, en cuyo punto, ya sea en cadena de
podemos decidir que eso es todo.
¿Hemos emparejado cada personaje?
En caso contrario, devuelve falso.
Si es así, vuelva realidad.
Y eso es exactamente lo que esta versión del programa compara-1.c hace.
Es idéntico a lo que mirado Lunes excepto que he I
librado de la palabra string-- aunque que no tiene impact-- funcional todo
Que estoy haciendo ahora es la eliminación algunas ruedas de entrenamiento visual,
sino para ver claramente que s y t son direcciones.
Y eso es lo que la estrella, el asterisco, representa
es una dirección, también conocida más técnicamente como un puntero.
>> Así que cuando me declaro en s la línea 9 y decir char * s,
eso no significa que me diera una cadena.
Eso significa que me dé una variable cuyo propósito en la vida es almacenar una dirección.
Porque yo estoy a punto de poner el dirección de una cadena en el mismo.
Y, en efecto, GetString, para ser claro, no devuelve una cadena.
No devuelve mamá barra invertida cero, per se.
¿Qué significa GetString específicamente y volver precisamente?
AUDIENCIA: [inaudible]
DAVID J. MALAN: Una dirección, la dirección del primer carácter
en alguna cadena se ha conseguido.
Y por lo que ahora estamos viendo una palabra clave especial de nuevo.
Y, aludí a esta antes.
Esto va a ser bueno de convenciones que vamos a ver una y otra vez ahora.
Estoy comprobando para asegurarse de que s no es nulo y t no es nulo.
Debido a que la base de mi realidad mención rápida antes,
lo que podría significar si GetString no regresa una dirección, pero N-U-L-L, que es de nuevo,
algún valor especial?
>> AUDIENCIA: Error.
>> DAVID J. MALAN: Es un error.
Algo salió mal.
Y lo que normalmente que podría suceder, especialmente
con lo que podría ser strings-- de longitud desconocida en advance--
tal vez los equipos de los sin memoria, tal vez
que ha escrito de tal larga palabra o frase
o pegado un gran ensayo tales que no hay suficiente memoria.
Y así GetString no puede regresar la dirección de todo el asunto,
por lo que sólo devuelve nada.
Y dice un error ha ocurrido devolviendo el valor especial NULL.
Es la dirección de cero, por así decirlo.
>> Ahora resulta que C viene con un función que hace que iteración.
No tenemos para implementar esto con un bucle o un bucle while nosotros mismos.
Podemos utilizar una función, llamada de manera sucinta,
revuelva un borrador, o cadena comparar, cuya propósito en la vida es hacer exactamente eso.
Se le da dos punteros, dos direcciones, y va a ir a esas direcciones
y luego comparar carta para letra por letra por la calidad,
deteniéndose sólo cuando lo que es verdad?
Cuando intuitivamente debe agitar un borrador dejan de iteración, para ser claros?
Cuando se realiza un barra invertida 0 en cualquiera cadena, en cuyo punto se puede decidir
tiene todo igualado, o ha habido una discrepancia?
>> Por lo tanto, si corremos esto ahora y tratar nuestro pequeño juego de capitalización,
así que compare-1, ./compare-1, y escriba madre en minúsculas en ambas ocasiones.
Ahora es lo mismo.
Y si lo hago de nuevo con minúscula y luego tal vez mayúsculas.
Ahora en verdad distingue entre mayúsculas y minúsculas.
Así que no es tan difícil o mágico, pero sí ahora explicar
lo que está pasando debajo de la campana.
>> Entonces, ¿qué más se puede extraer que de este tipo de lección?
Así que vamos a echar un vistazo a esto.
Voy a seguir adelante y escribir una programa rápido aquí llamado copia-0.
Y ahora vamos a seguir adelante y de hecho vamos a hacer esto-- con el copia-0,
echar un vistazo a lo que tengo aquí.
La primera vez que digo que el usuario, decir algo.
Entonces consigo una cadena y guardé en s.
Entonces puedo comprobar si s es igual a es igual a NULL, simplemente volver 1.
Así que esto es sólo la comprobación de errores estándar.
Nada interesante ha sucedido.
Y de hecho, si nos deshacemos del error cheques, esto se parece a la semana 1 código
En el momento.
Pero he empezado a conseguir un poco mejor por eso.
>> Ahora bien, en la línea 16, hace una semana, tal vez día incluso un par de minutos o hace,
se podría decir la línea 16 es la creación de una variable llamada t
y la copia es en ella.
Y eso es una perfecta comida para llevar razonable.
Pero más exactamente ahora.
Lo que está sucediendo en la línea 16?
Lo que está siendo copiado ¿de derecha a izquierda?
¿Sí?
AUDIENCIA: ¿Es t recibiendo una dirección de s?
>> DAVID J. MALAN: Exactamente, t es conseguir la dirección de s.
Así que para ser claro ahora, si me voy de nuevo a ese ejemplo anterior
y extraigo lo que he escrito en.
Y lo que he escribí en-- aquí está s, y aquí
es lo que he escrito en algún lugar de la memoria, la mamá y luego una barra invertida
0 que se agrega para mí.
Lo guardé aquí, recordar, esto es en la posición 1, 2, 3, 4,
esto es lo que hay actualmente en el s.
Así que si en la línea 16, digo dame otra variable llamada ty tienda
en en el valor de s, lo se almacena aquí no será mamá
sino sólo el número 1.
>> Así que si miramos hacia el futuro en este programa ahora, ¿qué va a pasar?
Así que observe que hay esta función podría
han usado este tiempo atrás para César, o Vigenére, o tal vez no del todo.
Yo reclamo con mi printf, estoy va a capitalizar la copia t.
Primero en la línea 19, la cordura rápida control, controles strlen la longitud del t.
Porque no quiero tratar de capitalizar algo
si no hay cadena de allí.
Si el usuario simplemente pulse Enter, no hay nada para sacar provecho.
Así que no quiero hacer la línea 21.
Así que la línea 21 está capitalizando qué letra, al parecer, en t?
>> AUDIENCIA: m?
DAVID J. MALAN: Parece como si fuera la copia cuál?
AUDIENCIA: m.
DAVID J. MALAN: Uh, m.
OK, así que la primera m, debido aviso de que estoy
pasando a toupper, que si nunca has visto es
sólo una función de capitalizar como su entrada.
t soporte de cero significa dar me el carácter cero del t.
Y entonces, ¿cómo funciona esto cambio de imagen, para ser claro?
¿Qué se necesita para ser reescrito o modificado con respecto a s y t y la mamá
cero barra invertida.
>> AUDIENCIA: [inaudible]
>> DAVID J. MALAN: Sí, así que éste aquí simplemente
necesita para cambiarse a-- fijar esto-- debe cambiarse a una capital m.
Pero ahora, y mira adelante en el programa, si imprimo
s y t como puedo limpiar aquí, ver lo que hay va a pasar imprimiendo s y t.
Así que copia-0, ./copy-0.
Déjame ir adelante y escribo en mamá en minúsculas.
Observe el original y la copia se han capitalizado.
¿Por qué?
Bueno, s y t son ambos apuntan a, si se quiere, la misma cantidad de memoria.
Y, francamente, esto se está poniendo Realmente uninteresting-- el hecho
que estamos utilizando cero dirección aquí.
Quiero decir, no me importa donde la materia está en la memoria.
Lo siento, estoy borrando un poco demasiado.
Pero yo no me importa dónde están las cosas en la memoria.
Y así, de hecho, lo que programadores tienden a pensar
es que cuando se habla de una dirección, o un puntero,
a quién le importa donde está en la memoria.
No me importa si es en byte uno o mil millones.
Yo sólo me importa que esta variable es efectivamente
señalando en ese trozo de memoria.
Y así, a partir de ahora, en lugar de objeción sobre las direcciones de memoria arbitrarias, vamos a
simplemente comenzar a dibujar punteros como punteros, como flechas.
Así que lo que S y T son en realidad, de acuerdo con este programa,
por la forma en que he creado t, es sólo dos variables separadas
señalando al mismo trozo de memoria.
Y no nos importa dónde se encuentren.
Así que podemos abstraer ese detalle.
>> Entonces, ¿cómo puedo solucionar esto?
Si quiero escribir una versión de la copia programa que en realidad copia la cadena
y capitaliza sólo el copia, simplemente intuitivamente,
lo que tiene que haber una ingrediente para nuestra solución?
AUDIENCIA: [inaudible]
DAVID J. MALAN: Necesitamos un qué?
AUDIENCIA: Pedazo de la memoria.
DAVID J. MALAN: Necesitamos otra parte de la memoria, ¿no?
No sabemos cómo hacerlo, sin embargo, necesariamente.
Pero que tipo de necesidad que esto suceda de manera que la madre original en caso de baja
termina en ese pedazo extra de memoria.
Y luego cuando cambio la copia, yo no quieren cambiar esta copia aquí.
Yo en cambio quiero cambiar sólo esto copia para que el original no se modifica.
>> Así que, vamos a ver cómo podemos hacer esto.
En copy-1, que ya tiene sido despojado de comentario,
pero se comenta en línea.
En su lugar hacemos la following-- éstos líneas son idénticos, tráeme una cadena
y lo llaman es.
Pero ahora vamos a ver uno de nuestros más complejo, pero el último de la complejidad
por un tiempo, la línea 16 hace exactamente esto.
Así que si su cómoda, con la foto acabamos drew--
dame un nuevo trozo de memoria, copiar todo en él,
vamos a ver cómo traducimos eso a código.
>> Así que la línea 16, en el lado de la mano izquierda, char * t me da esta caja aquí.
Eso es todo lo que hace.
Al lado derecho, m alloc o malloc,
es la asignación de memoria, super lujoso, una forma críptica de decir simplemente
dame un trozo de memoria.
¿Cuánta memoria necesitamos?
Bueno, es una especie de gran expresión.
Pero vamos a ver lo que dice aquí.
Así que esto, por supuesto, es dar me la longitud de cadena del s.
Así, la mamá debe ser qué?
Así que sólo tres, ¿no? mamá es de tres caracteres.
No contamos el barra invertida cero cuando
hablar de la longitud de una cadena que es en realidad las letras visibles humanos.
Así que mamá, así que esto me da 3.
Pero espere un minuto, yo ahora estoy añadiendo 1.
¿Por qué en realidad quiero asignar los 4 bytes y no sólo 3?
¿Sí?
>> AUDIENCIA: Para el valor centinela?
>> DAVID J. MALAN: Exactamente, para ese valor centinela.
Para la barra invertida cero, Necesito 4 bytes en total.
Así que necesito la longitud de la cadena plus 1.
Y a continuación, sólo para el bien measure-- a pesar de que en este sistema,
Siempre va a ser 1-- que estoy diciendo multiplicar este por el tamaño de un char.
Resulta que es sizeof un operador en C que
sólo te la dice número de bytes que es
requerida para un cierto tipo de datos.
No funciona para las matrices, típicamente, a veces lo hace.
Pero en el caso general, no.
Pero me dirá cuántos bytes de un Char es, que resulta es siempre 1.
Así que esto es como multiplicar por 1.
>> Línea de mira tan super críptica de código.
Pero todo lo que hace es da mí un trozo de memoria.
Pero tampoco parece estar copiando nada en esa memoria?
Aún no.
Y así, ¿qué tengo en la línea 22 y 23, 24, 25, bueno, yo simplemente hago esto.
Y esto es una especie de antiguo cosas de la escuela ahora.
Esto es como PSet 2, donde estás moviendo cosas
alrededor en la memoria, o más bien en las cadenas.
>> Así que estoy iteración de 0 a la longitud de la cadena s.
Y estoy copiando el carácter de orden i en s en el carácter de orden i en t.
Y porque yo, el programador, hizo Asegúrese de asignar exactamente tantos bytes
ya que necesito, es perfecto uno-a-one relación.
Y copio madre en minúsculas a la nueva.
Y luego, por último, hago esta línea.
Y por lo que el efecto es sólo para capitalizar este t aquí.
Así que mucho que absorber, pero si sólo consideras
lo que realmente está pasando de debajo del capó
se acaba de mover estos bytes alrededor, todo lo que
que se necesita para resolver este problema es justo para dar a este pedazo de la memoria.
Ahora con el riesgo de abrumadora, déjame mostrarte
otro ejemplo que es casi idéntica, a excepción de éste
línea de código.
Así que esta es la versión pirata de este programa, si se quiere.
Pero vamos a destilar en lo que está pasando.
Línea 24 solía ser este t soporte de I consigue s abrazadera i.
Ahora, voy a cambiar esto a la estrella mucho más críptico t
más 1 es igual a la estrella s más 1.
>> Así que lo que está pasando y por qué tenemos un personaje estrella?
Hemos visto la estrella antes, y se está utilizando de manera diferente aquí.
Anteriormente vimos char *, ahora que estoy viendo Una estrella en el principio, y eso está bien.
Porque resulta que puede tipo de inferir solo
de los primero principios de lo que está pasando.
Así que para que quede claro, lo que es s?
La semana pasada, era una cadena.
Eso no basta ya.
¿Qué es s, específicamente?
>> AUDIENCIA: [inaudible]
>> DAVID J. MALAN: Es un puntero.
Es la dirección del primer carácter que escribió en.
OK, ¿cuál es t?
>> AUDIENCIA: [inaudible]
>> DAVID J. MALAN: La dirección del primer byte
en t, que parte de la memoria reasignada.
Así que resulta que cuando iterar desde 0 hasta en la cadena
longitud-- en primer lugar, i comienza en 0, ya que
de esta vieja escuela por lo bucle.
Así que por simplicidad, vamos a asumir que la primera línea de código
es realmente sólo esto, la derecha.
Si i es cero, añadiendo cero a algo presumiblemente
no va a tener un efecto.
>> Entonces, ¿qué es esta palabra?
Resulta que la estrella operador en este contexto
es la dereference operador, que es justo
una forma elegante de decir ir a la siguiente dirección.
Así que si s es la dirección de la primera personaje en esta parte de la memoria,
* s medios van allí.
Y porque hemos dibujado la imagen de esta manera,
puede adoptar el siguiente modelo mental.
Si esto es s, y dices * s * s, algo así como rampas y escaleras,
si usted recuerda el juego de la infancia, es como seguir la flecha e ir
a la dirección.
>> * t es la misma cosa.
Así que empieza aquí, vaya a su trozo.
No puedo dibujar en esta pantalla de esa manera.
* t significa ir aquí.
Y luego, el bucle for es sólo diciendo mover este personaje aquí,
mover este personaje aquí, mover este personaje aquí.
Pero, ¿cómo lo hago incrementación?
Tengo que deshacer lo que acaba de eliminar.
Esto es lo que generalmente se llama aritmética de punteros, que
significa matemáticas con direcciones.
>> Si, en este bucle, Sigo incrementando i,
y s es una dirección y t es un dirección, si yo sigo añadiendo 1,
eso sólo significa seguir adelante, y hacia adelante, y adelante en la memoria.
Es como Oxford Street, el calle que el edificio está en CS.
Los edificios CS está en 33 Oxford Street.
Así que si usted fuera a hacer 33 Oxford Street, más 1,
que lleva a 34 Oxford Street, luego 35 Oxford Street,
entonces 36 Oxford Street, cualesquiera que edificios son en realidad - si es que existen.
Y así, eso es todo lo que estamos haciendo aquí con la aritmética de punteros.
>> Así que es una manera estupenda arcana de expresarnos.
Pero todo lo que está sucediendo debajo de la campana
es sólo seguir estas direcciones, como seguir un mapa, si se quiere,
o siguiendo las flechas como hemos dibujado en la pantalla.
OK, una gran cantidad de digerir.
Cualquier pregunta sobre la sintaxis, los conceptos, punteros, malloc, o similares.
Sí, por aquí primero.
>> AUDIENCIA: Entonces, ¿dónde que dice * t es igual a toupper * t,
es que va a capitalizar todas las letras o sólo--
>> DAVID J. MALAN: Ah, muy buena pregunta.
Así que en esta línea de aquí, 31, ¿Esto va a capitalizar
la primera letra o la totalidad de las letras.
Así que vamos a responder que al ir volver a los primeros principios.
Y los primeros principios aquí me refiero basta con ir a las definiciones básicas
de lo que está involucrado.
Así toupper es una función que capitaliza un char.
Eso es todo.
* t significa ir al primero-- ir a la dirección en t.
Por lo tanto, en la imagen, si este es el trozo de la memoria nos asignaron con malloc,
y esto es t, * t significa ir aquí.
>> Mientras tanto, usted está pasando ese valor, minúsculas m
a toupper, que está recibiendo de vuelta M mayúscula, donde estás poniendo él?
Estás poniendo en ese mismo lugar.
Y así por que la lógica de aquellos definiciones básicas es sólo
mayúscula la primera letra a menos que iterar con i o una
de lazo o un bucle while, no va para hacer algo más de lo que pides.
Buena pregunta.
¿Sí?
>> AUDIENCIA: ¿Por qué se utiliza el dereference método en lugar de
la matriz?
>> DAVID J. MALAN: Ah, buena pregunta.
¿Por qué utilizar el dereference método en lugar del método de matriz?
No hay ninguna razón en particular, para ser honesto.
Y, de hecho, para este clase de ejemplo, a la derecha,
Sólo estoy argumentando hacer la programa más complicado,
más ojos están vidriosos, la gente está mirando
porque esto se ve super arcano, pero a pesar de que está haciendo lo mismo.
Y así, francamente, se trata de una solución innecesariamente visualmente compleja
al problema.
>> Sigue siendo un buen diseño, cinco de cinco para el diseño,
ya sea en el soporte notación o la notación puntero.
Pero- especialmente cuando lleguemos más tarde en el curso de PSet 5
cuando ponemos en práctica ese diccionario que He mencionado un par de veces--
vamos realmente se preocupan por la direcciones de memoria de bajo nivel
que realmente entendemos que esta pasando.
>> Pero, por ahora, resulta que esta línea de código entre paréntesis aquí cuadrados
en realidad no existe.
Ellos son lo que se llama azúcar sintáctico, que
es sólo una manera extrañamente fría de decir la compilador convierte corchetes sean
que la expresión matemática.
Así que es una convención humana para poder simplemente escribir
estos soportes muy fácil de usar.
Pero lo que el compilador, sonido metálico, que realmente está haciendo cualquier momento
usted escribe lo que está resaltado en línea 24, debajo de la capilla que es realmente
la conversión a esto.
Es sólo más placentero como un ser humano a leer y escribir código como la línea 24.
Pero con el tiempo los ruedas de entrenamiento también se desprenden
cuando la propia comodidad se hace más fuerte.
>> Muy bien, así que recordar entonces que este Era el tipo de problema más grande
nos encontramos.
Y eso es lo que provocó todo este maldita conversación acerca de los punteros,
y direcciones, y cosas de copiado.
Fue porque nos estropeó sobre esta estúpida, estúpida cuestión, por lo que
He implementado logically-- con Lauren aquí en la demo y el zumo de naranja
en el milk-- un perfectamente función algorítmica correcta
para el bombeo de dos variables ' valores, pero la maldita cosa
no tenía ninguna persistente o permanente, efecto en mi código.
>> ¿Y por qué fue eso?
En pocas palabras, ¿por qué es esto implementación de canje
lógicamente correcto, pero no tiene ningún impacto sobre las variables que se pasan a la misma,
como x e y para la principal?
¿Cuál fue la esencia de la cuestión?
¿Sí?
AUDIENCIA: Debido a la variable hace copias de la variable en el pase
a través de la función.
>> DAVID J. MALAN: Exactamente, cuando se pasa variables en una función, o argumentos
en una función, son aprobada por copia, que
significa que usted obtiene un aspecto idéntico patrón de bits para ambos X e Y,
llamado aquí a y b.
Y usted puede hacer cualquier cosa que quiera con esas copias,
pero van a tener ninguna efecto sobre la función de llamada.
Y, de hecho, dibujamos que imagen en la pantalla, el recuerdo
la última vez, por lo que si usted realmente pensar en lo que es
pasando por debajo de la hood-- si esto es la memoria del equipo,
y aquí está la parte de memoria que se utiliza para el principal,
esta es la parte de memoria que se utiliza para el intercambio,
y tiene por lo que incluso si principal dos variables, X e Y,
intercambio podría tener mirando idéntica valores, ambos de los cuales son 1 y 2,
pero son completamente diferentes trozos de memoria.
>> Así que tenemos una solución a esto.
Y, francamente, parece que ahora tener una solución a este problema, a la derecha.
Si ahora tenemos la capacidad de manipular las cosas a través de las direcciones
y, tipo de rampas y escaleras estilo, siga estas flechas
e ir a donde queramos en la memoria, ¿no nos
resolver este problema pasando de principal para intercambiar
no los valores que quieren swap, pero sólo intuitivamente
¿qué podríamos pasar para cambiar su lugar?
>> [Interponiendo VOCES]
>> DAVID J. MALAN: ¿Por qué no lo hacemos sólo pasarlo las direcciones, ¿verdad?
¿Por qué no le damos una permuta mapa del tesoro, si se quiere,
que conduce a la valores reales x e y.
Vamos swap, en realidad cambiar esos bits originales, en lugar de
de paso copias de los bits.
Y así, de hecho, eso es lo que hay va a ser la solución.
Esta versión aquí es claramente malo y defectuoso.
Y ahora, a primera vista, que sólo se ve como hemos añadido un montón de estrellas al azar
y cruzó los dedos que sería compilar.
Pero, sería ahora compilar.
>> Pero vamos a ver qué quiere decir esto.
Y, por desgracia, los autores de C podría haber elegido otro símbolo
para hacer esto un poco más clara, pero el operador estrella
tiene significado diferente en dos contextos diferentes.
Y hemos visto tanto, pero vamos a distinguir.
>> Así que en la parte superior existe, cuando he cambiado a y b
de ser int de la mala versión a int estrellas, a y b,
Anteriormente, se enteros.
¿Cuáles son ayb ahora el bien, la versión verde?
Son direcciones.
Direcciones de lo que, para ser claro?
Direcciones de números enteros.
Así que el hecho de que soy diciendo medios int estrella
esta es la dirección de un entero, específicamente.
>> Así que ahora cuenta en las líneas de código, algo más ha cambiado demasiado.
tmp sigue siendo el mismo, porque es sólo el número entero temporal,
hay magia memoria allí.
Pero ahora necesita una estrella.
Y, de hecho, cada otra mención de a y b,
cuenta de que todo lo que es cambiar de rojo a verde
es que estoy anteponiendo las variables con las estrellas.
Porque yo no quiero copiar a y b.
Porque si yo copio a y b y de intercambio ayb, ¿qué estoy hecho el canje?
A sólo direcciones, quiero cambiar lo que está en esas direcciones.
Quiero ir ahí.
Y por lo que el operador de la estrella dentro de mi función,
no dentro de la lista de parámetros, implica que vaya a esas direcciones
y en realidad cambiar esos valores.
>> Entonces, ¿qué hace la foto ahora verá como su lugar.
Bueno, si en vez estoy pasando por A y B no 1 y 2--
Yo realmente necesito agregar otra definición aquí.
Así que supongo que este trozo de la memoria está en la posición 10.
>> Esto es en la posición 11, pero esto es un poco de una simplificación,
Ahora tengo dos opciones hacen que pase x ey o puedo pasar sus direcciones?
Si paso sus direcciones como éste, sólo
ahora tenemos que poner en práctica intercambio por el código de color verde
de modo que cuando se ve una y cuando b ve, no sólo tienes que copiar a y b
y mover la leche y zumo de naranja.
El jugo de la leche y naranja metáfora ahora se rompe,
porque esas son las tazas de los mapas de líquidos y no.
Nosotros en cambio tenemos que ir para hacer frente a 10 y nos
tenga que ir al frente 11, y a continuación, realizar esa lógica intercambio.
>> Así que la lógica es la misma, pero necesitamos una manera ligeramente diferente
de acceder a dichas variables.
Y así, al final, lo que el programa tiene que verse como es esto.
En swap.c copiado literalmente, y pegar la versión verde.
Pero tengo que hacer un cambio.
No es suficiente sólo para cambiar de intercambio.
¿Qué otra línea de código Qué tengo que cambiar?
¿Sí?
>> AUDIENCIA: ¿Dónde toma los argumentos.
>> DAVID J. MALAN: Dónde toma su argumento.
Así que si me desplazo hasta principal, me no sólo puede pasar en x e y,
y, lo prometo, la última pieza de nueva sintaxis hoy.
Tengo que pasar no xy y, pero la dirección de x e y.
Y resulta que, el símbolo que los autores de C escogieron
es si se utiliza un signo aquí, no para debe confundirse con el signo bit a bit,
si se utiliza un símbolo de unión aquí y un signo aquí,
esto se da cuenta de que, ¿cuál es la dirección de x,
tal vez es 10, ¿cuál es el dirección de y, tal vez es
11, y pasa aquellos en su lugar.
>> Así que mucho que absorber todos a la vez.
Pero veamos ahora rápidamente nuestros cuatro minutos para el final
donde las cosas pueden salir mal.
Y como un aparte, en realidad Tomé esta imagen,
TF tomó esta fotografía de un año o dos atrás.
Así que esta es la esquina trasera de Eliot Dining Hall.
Los punteros son quizás los más difíciles tema que cubrimos en CS50.
Así que si usted se preocupa el tipo de la pendiente es como tal vez es
más de un palo de hockey así, darse cuenta
estamos a punto de tipo de un pico en términos de la complejidad conceptual.
>> Y traigo a colación este foto, porque te juro
a dios, en el otoño de 1996, cuando tomé CS50 con mi compañero de enseñanza,
Nishat Mehta, me sentó en el esquina de la Eliot D. Hall durante el almuerzo,
o la cena, o algo para tratar de para ayudarme a entender punteros.
Y aquí es donde estuve semanas después que se introdujo en la conferencia cuando
Finalmente entendí punteros.
Y tengo la esperanza de que este haremos clic mucho antes para usted.
Pero darse cuenta de esto absolutamente entre los temas más sofisticados
hemos visto.
Pero es uno de los más poderosos.
Y cuando lo consigues, es realmente todo sólo va a finalmente se unen.
Así que puede estar seguro de que no lo hace necesitará toda lavabo en la actualidad.
>> Así que aquí está el último programa vamos a ver.
Y vamos a terminar con una rápidos tres minutos de animación con plastilina
tomada por nuestro amigo, Nick Parlante.
Aquí hay un programa, que en los dos primeros líneas declara una variable x e y.
Ambos de los cuales son direcciones de enteros, punteros AKA.
A continuación, asignar suficiente memoria para almacenar un int
y almacenar la dirección de que la memoria en x.
Por lo tanto, es aún más simple que el ejemplo anterior.
Dame cuatro bytes de memoria, ese es el tamaño de un int,
y poner esa dirección en x.
Esta línea significa aquí ir a la dirección de x
y poner el significado de la vida, el número 42 allí.
Pero esta línea me preocupa.
Star y significa ir a la dirección en y, y poner el número de mala suerte 13 allí.
¿Por qué es peligroso, en este punto en la historia-- aunque dijo rápidamente
en nuestros últimos minutos aquí-- ¿por qué es malo
para mí decir, ir a la dirección de y?
>> AUDIENCIA: Usted no tiene [inaudible].
DAVID J. MALAN: Yo no tengo poner nada en y.
Entonces, ¿cuál es el valor de y, en este punto de la historia?
No tenemos ni idea.
Es cierto valor de basura y ni sabe Binky.
Si pudiéramos terminar con esta nota.
>> [REPRODUCCIÓN DE VÍDEO]
>> -Oye, Binky, despierta.
Es tiempo para la diversión puntero.
>> -¿Que es eso?
Entérese de los punteros?
Oh, chuchería.
>> -Bueno, Para empezar, creo que estamos va a necesitar un par de punteros.
>> -OK.
Este código asigna dos punteros que puede apuntar a números enteros.
>> -OK, Así veo el dos punteros, pero ellos
no parecen estar apuntando a nada.
>> -Eso es correcto.
Inicialmente punteros no apunte a nada.
Las cosas que apuntan son llamada pointees y la que fueron creados
es un paso separado.
>> -Oh, Derecha, derecha.
Lo sabía.
Los pointees están separados.
Entonces, ¿cómo asignar un pointee?
>> -Ok, Bueno este código asigna un nuevo pointee número entero,
y esta parte fija xa apuntan a la misma.
>> -Oye, Que se ve mejor.
Así que haga algo.
>> -OK, Voy a eliminar la referencia del puntero x para almacenar el número 42 en su pointee.
Para este truco, necesitaré mi varita mágica de la eliminación de referencias.
>> -Su Varita mágica de la eliminación de referencias?
Uh, eso, eso es genial.
>> -Esto Es lo que el código se parece.
Voy a configurar el número y-
>> [POP SONIDO]
>> -Oye, Mira ahí va.
Así, haciendo un dereference en x sigue la flecha para acceder a su pointee.
En este caso, para almacenar 42 allí.
Hey, pruebe a utilizar para almacenar el número 13 a través del otro puntero, y.
>> -OK.
Voy a ir por aquí ay, y obtener el número 13 de puesta en marcha.
Y luego tomar la varita de eliminación de referencias y sólo--
>> [BUZZER SOUND]
>> Oh, bueno eso no funcionó.
Diga, uh, Binky, no lo hago pensar eliminación de referencias
y es una buena idea, porque el establecimiento el pointee es un paso separado.
Y yo no creo que nunca hicimos.
>> -Hmm, Buen punto.
>> -Sí, Nos asignaron el puntero, y, pero nunca nos pusimos a apuntar a un pointee.
>> -Hmm, Muy observador.
-Oye, Te ves bien allí, Binky.
¿Se puede arreglar para que los puntos Y a la misma pointee como x.
>> -Claro, Yo uso mi varita mágica de asignación de puntero.
>> -Es Que va a ser un problema, al igual que antes?
>> -No, Esto no toca los pointees.
Sólo cambia un puntero para que apunte a la misma cosa--
>> [POPPING SONIDO]
--como otra.
>> -Ah, ya veo.
Ahora Y apunta al mismo lugar que x.
Así, espera, ahora y se fija.
Tiene un pointee.
Así que usted puede probar la varita de eliminación de referencias volver a enviar el 13 más.
>> Oh, bien, aquí va.
>> Oye, mira eso.
Ahora dereferencing obras en y.
Y debido a que los punteros están compartiendo que uno pointee, ambos ven el 13.
>> -Sí, Compartir, eh, lo que sea.
Por lo tanto, vamos a cambiar de lugar ahora?
>> Oh, mira que estamos fuera de tiempo.
>> -Pero--
>> -Sólo Recuerda las tres reglas de puntero.
Número 1, la estructura básica es que usted tiene un puntero,
y apunta a un pointee.
Pero el puntero y pointee están separados.
Y el error común es la creación de un puntero
pero que se olvide de darle una pointee.
>> Número 2, desreferencia puntero comienza en el puntero
y sigue su flecha sobre para acceder a su pointee.
Como todos sabemos, esto sólo funciona si hay es un pointee, qué tipo de vuelva
a la regla número 1.
>> Número 3, puntero asignación tiene un puntero
y cambia a apuntar a la pointee mismo como otro puntero.
Así que después de la cesión, los dos punteros
apuntará a la misma pointee, A veces eso se llama compartir.
Y eso es todo lo que hay que hacer, de verdad.
Adiós ahora.
>> [FIN DE REPRODUCCIÓN]
>> DAVID J. MALAN: Eso es todo por CS50.
Gracias al profesor Nick Parlante.
Nos vemos la semana que viene.
>> [REPRODUCCIÓN DE MÚSICA ELECTRÓNICA]