[Powered by Google Translate] [SETTIMANA 5] [David J. Malan, Harvard University] [Questo è CS50.] [CS50.TV] [Donna] Sta mentendo, di quello che, non lo so. [L'uomo] Allora, cosa ne sappiamo? [Donna] che alle 9:15, Ray Santoya era al bancomat. [L'uomo] Quindi la domanda è: che cosa ci faceva alle 9:16? [Donna] Tiro a 9 mm a qualcosa. Forse ha visto il cecchino. [L'uomo] O stava lavorando con lui. [Donna] Aspetta. Torna indietro di una. [L'uomo] Che cosa vedi? [♫ ♫ musica suspense] [Donna] Portare la sua faccia in su. Schermo intero. [All'uomo] la sua occhiali. >> C'è una riflessione. [♫ ♫ musica suspense] [L'uomo] Questa è la squadra di baseball di Nuevita. Questo è il loro logo. [Donna] E sta parlando a chi indossa quella giacca. [David Malan] Quindi, questo è CS50 settimana 5, e oggi si rovina un po 'di televisione e film per voi. Così ogni volta che si sta guardando un programma come questo qui, e la polizia dicono "Si può pulire che fino?" o "Enhance", non vi è migliorare nel mondo reale. In realtà, quello che si ottiene è davvero un po 'di qualcosa come questo. Ho tirato su una delle foto del personale dalla pagina. Si tratta di un programma chiamato Photoshop. Questo è 1 di 2 Bowdens, 1 di 3 Bowdens in realtà, oggi, perché abbiamo la signora Bowden anche qui, con Rob e Paolo. Ma ecco Rob sullo schermo, e se lo zoom su quel luccichio che ha sempre avuto nel suo occhio, quello che si vede attualmente è che ciò che vedi è quello che si ottiene. Questo è "migliorata", così "CSI" ha un po 'sbagliato. C'è un altro clip, se siamo in grado di cogliere in "CSI" solo un po 'più a lungo. Questa è una bella frase di pronunciare d'ora in poi, se si desidera buona formazione tecnica con i tuoi amici, quando, in realtà, stai dicendo niente. [L'uomo] Per settimane ho indagato sugli omicidi Killer Cabby con un certo fascino morboso. [Woman # 1] Questo è in tempo reale. [Woman # 2] creerò una interfaccia GUI utilizzando Visual Basic, vedere se riesco a rintracciare un indirizzo IP. [Malan] Quindi, audio fuori sincrono a parte, la creazione di una interfaccia GUI utilizzando Visual Basic per rintracciare un indirizzo IP è una totale assurdità. In questi giorni non si utilizza Visual Basic, non c'è bisogno di una GUI, e l'indirizzo IP era un termine tecnico preciso. Quindi tenete gli occhi aperti per questi, e uno dei miei preferiti: Questo e 'un po' più arcano, perché è necessario conoscere una lingua diversa. C'è un linguaggio chiamato Objective-C, che è un superset di C. Il che significa che è il C con alcune funzionalità aggiuntive, tra cui programmazione orientata agli oggetti. E questo è il linguaggio che Apple ha reso popolare per la programmazione iOS. E così ecco una clip da uno spettacolo completamente diverso, da "Numeri" che se si guarda da vicino effettivamente sul vostro TiVo e mettere in pausa al momento giusto, vedrai che quello che stanno guardando non è proprio ciò che viene descritto. E mi permetta di provare un connettore audio diverso qui e vedere se non possiamo mantenere l'audio in sincronia questa volta. Io ti do "Numeri". [Man # 1] E 'un indirizzo a 32 bit IPv4. [Man # 2] IP, che è Internet. >> Rete privata. Si tratta di una rete privata di Anita. [Malan] Ok. Si tratta di Objective-C, ed è per il programma di colorazione un po 'di bambini, come si può forse dedurre dal nome della variabile lì. In modo che, allora, era "Numeri". Così oggi e questa settimana vi presentiamo un po 'del mondo forense e il contesto nei problemi quindi. Oggi sarà una lezione abbreviato perché c'è un evento speciale in qui dopo, quindi dovremo dare un'occhiata, e prendere in giro sia gli studenti e genitori oggi con alcune delle cose che sono all'orizzonte. Tra questi, come di Lunedi, si avrà un paio di compagni di classe. Edx, Harvard e MIT nuova iniziativa on-line per open courseware e di più, sta lanciando nel campus di Harvard il Lunedi. Il che significa che vengono Lunedi si avrà - come di ultimo conteggio, 86.000 compagni di classe aggiuntivi saranno in seguito insieme a lezioni di CS50 e sezioni e procedure dettagliate e set problema. E come parte di questo, si diventa membri della classe inaugurale del CS50 e ora CS50x. Come parte di questo, ora, conto che ci saranno alcune upsides pure. Per prepararsi a questo, per il numero enorme di studenti, basti dire che, anche se abbiamo 108 TF e CA, non proprio il miglior rapporto studenti / insegnanti, una volta abbiamo raggiunto 80.000 studenti di altri. Quindi non sta andando ad essere un problema di classificazione tanti imposta manualmente. Così ha introdotto questa settimana nel set problema sarà CS50 Check, che sta per essere una utility a riga di comando all'interno dell'apparecchio che si otterrà una volta che si aggiorna dopo questo fine settimana, e voi sarete in grado di eseguire un comando, controllo 50, sul pset proprio, e si otterrà un feedback sul fatto che il programma è corretto o non corretto in base alle specifiche di design che ci hanno fornito. Quindi più su questo e la definizione di un set problema e i compagni di classe CS50x quali si utilizza questo pure. Così insieme il problema 4 è tutto forense. E questo pezzo è stato ispirato da un po 'di vita reale roba, per cui quando ero a scuola di specializzazione, ho internato per un po 'con Ufficio della contea di Middlesex procuratore distrettuale di fare il lavoro forense con il loro investigatore capo forense, e ciò che questo è pari a si, penso che ho detto dopo alcune settimane, è la Polizia di Stato di massa o altri farebbe entrare, avrebbero scendere cose come hard disk e CD e floppy disk e simili, e quindi l'obiettivo dell'ufficio forense era di accertare se non vi era o non era la prova di qualche tipo. Questa è stata la Squadra Speciale Investigativa, quindi era criminalità dei colletti bianchi, era una sorta di più inquietante di crimini, qualsiasi azione che comporti una sorta di media digitali, scopre che non è che molte persone scrivere una e-mail dicendo: "L'ho fatto." Quindi, molto spesso queste ricerche forensi non si presentò tutto ciò che molto frutto, ma a volte la gente scrivere tali e-mail. Così a volte gli sforzi sono stati premiati. Ma per portare a questo pset forense, saremo introdurre in pset 4 un po 'di grafica. Quindi probabilmente prendere queste cose per scontato, JPEG, GIF e che in questi giorni, ma se davvero pensate, un'immagine, proprio come il viso di Rob, potrebbe essere modellato come una sequenza di punti, o pixel. Ora, nel caso di faccia di Rob, ci sono tutti i colori, e abbiamo iniziato a vedere i singoli punti, otherwide noti come pixel, una volta che abbiamo iniziato a Immagine Ma se semplificare il mondo un po ', e dire che questo qui è Rob in bianco e nero, bene, per rappresentare in bianco e nero si può semplicemente utilizzare binario. E se abbiamo intenzione di utilizzare binario, 1 o 0, siamo in grado di esprimere questa stessa immagine del volto sorridente di Rob con questo modello di bit: 11000011 rappresenta bianco, bianco, nero, nero, nero, nero, bianco. E quindi non è un salto enorme, quindi, cominciare a parlare di fotografie colorate. Le cose che si vedono su Facebook o prendere con una macchina fotografica digitale, ma, di certo, quando si tratta di colori, avete bisogno di più bit. E abbastanza comune nel mondo delle fotografie è di non usare 1-bit di colore, come questo suggerisce, ma colori a 24 bit, in cui è effettivamente ottenere milioni di colori. Così come nel caso in cui ci zoom su occhi di Rob, che era un numero qualsiasi di milioni di differenti possibilità colorati. Quindi dovremo introdurre questo problema insieme a 4 nonché nella procedura dettagliata, che sarà oggi alle 3:30 invece del solito a causa della conferenza 02:30 Venerdì qui. Ma il video sarà online, come di consueto, domani. Inoltre, ti introducono in un altro formato di file. Quindi questo è volutamente pensato per guardare intimidatorio in un primo momento, ma questo è solo un po 'di documentazione per una struct C. Si scopre che Microsoft, anni fa, ha contribuito a diffondere questo formato, chiamato il formato di file bitmap, BMP, e questo era un super-semplice, colorato formato di file grafico che è stato utilizzato per un bel po 'di tempo e talvolta ancora per sfondi per desktop. Se si pensa di nuovo a Windows XP e le dolci colline e il cielo blu, che era tipicamente un file BMP, o di un'immagine bitmap e bitmap sono divertenti per noi, perché hanno la complessità di un po 'di più. Non è così semplice come questa griglia di 0 e di 1; invece, si dispone di cose come un colpo di testa all'inizio di un file. In altre parole, all'interno di un file. Bmp è un insieme di 0 e di 1, ma c'è qualche supplementare 0 e di 1 in là. E si scopre che quello che abbiamo probabilmente dato per scontato per anni, formati di file come. doc o. xls o. mp3 o. mp4, quali che siano i formati di file che si ha familiarità con. Beh, che cosa significa essere anche un formato di file? Perché alla fine della giornata, tutti questi file usiamo avere solo 0 e di 1 e forse coloro 0 e 1 rappresentano a, b, c, tramite ASCII o simile, ma attraverso la fine della giornata, è solo 0 e di 1. Così gli esseri umani solo occasionalmente decide di inventare un nuovo formato di file dove standardizzare ciò che i modelli di bit effettivamente dire. E in questo caso qui, la gente che ha progettato il formato di file bitmap detto che al primo byte in un file bitmap, come indicata da offset 0, esiste, ci sarà un po 'di nomi incomprensibili bfType variabile chiamata, che sta proprio per il tipo di file bitmap, il tipo di file bitmap è. Si può dedurre, forse, dalla seconda fila che ha compensato 2, numero byte 2, ha un modello di 0 e 1 che rappresenta ciò? Le dimensioni di qualcosa, e si va avanti da lì. Così nel set problema 4, sarete camminato attraverso alcune di queste cose. Non finirà per prendersi cura di ognuno di loro, a meno di notare che inizia a diventare interessante attorno alla riga o byte 54, rgbtBlue, verde e rosso. Se hai mai sentito la sigla RGB, rosso verde blu, questo è un riferimento a questo. Perché si scopre che può dipingere tutti i colori dell'arcobaleno con una combinazione di rosso e blu e verde. E, infatti, i genitori nella stanza può ricordare alcuni dei primi proiettori. In questi giorni, basta vedere 1 luce uscendo da una lente. Ma torniamo nel corso della giornata, avete avuto la lente rossa, la lente blu, e la lente verde e insieme volto a schermo e formato un immagine colorata. E molto spesso le scuole medie e superiori avrebbero quelle lenti sempre così un po 'di traverso, in modo che erano una specie di vedere immagini doppie o triple, ma questa era l'idea. Hai avuto luce rossa e verde e blu dipingere un quadro. E questo stesso principio è usato nei computer. Quindi, tra le sfide, allora, per voi nel problema set 4 saranno un paio di cose: uno è quello di ridimensionare un immagine. Prendere in un modello di 0 e di 1, capire quali pezzi di 0 e 1 rappresentano ciò che in una struttura come questa, e poi capire come replicare i pixel: i rossi, i blu, i verdi all'interno in modo che quando una foto simile a questa prima fase, potrebbe essere simile a questo, invece dopo. Tra le altre sfide, anche, sarà che ti verrà consegnato un'immagine forense di un file vero e proprio da una fotocamera digitale e su quella macchina fotografica, un tempo, erano un sacco di foto. Il problema è che abbiamo accidentalmente cancellato o ha avuto l'immagine danneggiato in qualche modo. Le cose brutte succedono con le fotocamere digitali, e così abbiamo subito copiato tutti i 0 e di 1 fuori di quella carta per te, salvato tutti in 1 file grande, e poi noi li mano a te nel problema posto 4 in modo che sia possibile scrivere un programma in C con il quale recuperare tutti questi file JPEG, idealmente. E si scopre che i file JPEG, anche se sono un po 'di un formato di file complesso, sono molto più complesso di questo volto sorridente qui. Si scopre che ogni JPEG inizia con gli stessi schemi di 0 e di 1. Quindi, utilizzando un ciclo while o un ciclo for o simili, è possibile scorrere tutte le 0 la e 1 in questa immagine forense e ogni volta che si vede il motivo speciale che è definito nella specifica il problema proposto, la si può assumere, 'Oh, è qui, con probabilità molto alta, l'inizio di un JPEG, 'e appena si trova lo stesso modello, un certo numero di byte o kilobyte o in megabyte più tardi, si può assumere, 'Ooh! Ecco un secondo JPEG, la foto ho preso dopo il primo. Vorrei smettere di leggere quel file in primo luogo, iniziare a scrivere questo nuovo. ' E l'uscita del programma per pset 4 sta per essere fino a 50 JPEG. E se non è 50 file JPEG, si dispone di un po 'di un ciclo. Se si dispone di un numero infinito di file JPEG, si dispone di un ciclo infinito. Così, anche, sarà un bel caso comune. Questo è quello che è all'orizzonte. Quiz 0, dietro di noi. Realizzare, per il mio e-mail, che sempre c'è gente che sono entrambi soddisfatti, una sorta di folle, e triste intorno quiz 0 Tempo. E vi prego di non entrare in contatto con me, i TF testa, Zamyla, il tuo TF proprio o uno dei CA che si sa se si vuole discutere di come sono andate le cose. Quindi, per impressionare i genitori qui in sala, qual è la biblioteca CS50? Buon lavoro. Qual è la biblioteca CS50? Si '? [Le risposte degli studenti, incomprensibile] >> Ok, bene. Quindi è un insieme di predefiniti di codice che abbiamo, il personale, ha scritto, che offriamo a voi, per fornire alcune funzionalità comuni. Roba come farmi una stringa; farmi un int, tutte le funzioni che sono elencate qui. A partire da ora, si comincia a prendere realmente queste ruote di formazione off. Quindi stiamo per iniziare a portare via una "stringa" da te, che, ricordo, era solo un sinonimo per il tipo di dati effettivo? char *. Quindi, per i genitori, che era probabilmente - questo è un bene, in modo da char * inizieremo a vedere sullo schermo tanto più dal momento che eliminiamo "stringa" dal nostro vocabolario, almeno quando si tratta di realtà la scrittura di codice. Allo stesso modo, ci smettere di usare alcune di queste funzioni tanto, perché i nostri programmi si sta per ottenere più sofisticati piuttosto che scrivere programmi che si trovano lì con un lampeggiante prompt, attesa che l'utente a digitare qualcosa trovi Avrai i tuoi ingressi da qualche altra parte. Per esempio, potrai ottenere da una serie di bit sul disco rigido locale. Avrete invece ottenere in futuro da una connessione di rete, qualche sito web da qualche parte. Quindi cerchiamo di togliere questo strato per la prima volta, e tirare il CS50 apparecchio e questo file chiamato CS50.h, che sei stato forte anche per settimane. Ma andiamo effettivamente vedere cosa c'è dentro di questo. Quindi, la parte superiore del file in blu è solo un insieme di osservazioni, informazioni sulla garanzia e la concessione di licenze. Questa è una sorta di paradigma comune nel software, perché un sacco di software in questi giorni è quello che si chiama "open source" il che significa che qualcuno ha scritto il codice e reso disponibile gratuitamente, non solo di correre e di utilizzare, ma in realtà leggere e modificare e integrare nel proprio lavoro. Ecco, questo è quello che hai usato, il software open source, sebbene in una forma molto piccola. Se scorrere verso il basso oltre i commenti, però, che inizieremo a vedere alcune cose più familiari. Così notare in alto qui, che il file CS50.h comprende un insieme di file di intestazione. Ora, la maggior parte di questi non abbiamo mai visto prima, ma si è familiare, quale di queste abbiamo visto, anche se brevemente, fino ad ora? Si ', librerie standard. Stdlib.h ha malloc, così una volta che abbiamo iniziato a parlare di allocazione dinamica della memoria, che torneremo la prossima settimana pure, abbiamo iniziato anche il file. Si scopre che bool e vero e il falso in realtà non esiste in C, di per sé, a meno che non si include questo file qui. Così abbiamo, per settimane, è compreso di serie bool.h in modo che è possibile utilizzare il concetto di un bool, vero o falso. Senza questo, si dovrebbe ordinare di fingere e utilizzare un int e solo arbitrariamente supporre che 0 è falso e 1 è vero. Ora, se scorrere verso il basso più, ecco la nostra definizione di una stringa. Si scopre, come abbiamo detto prima, che quando ciò * non ha molta importanza. Si può anche avere lo spazio tutto intorno. Noi, in questo semestre, sono state promuovendo come questo per chiarire che la * ha a che fare con il tipo. Ma rendersi conto, come comune, se non un po 'più comune, è quello di mettere lì ma funzionalmente è la stessa cosa. Ma ora, se leggiamo ulteriormente verso il basso, diamo un'occhiata a dire, GetInt, perché abbiamo usato che, forse, prima di tutto questo semestre. Ed ecco GetInt. Questo è ciò? Questo è il prototipo. Così spesso, abbiamo messo prototipi ai vertici della nostra. File c, ma si può anche mettere prototipi nei file di intestazione, i file. h, come questo qui, in modo che quando si scrive alcune funzioni che si desidera che altre persone di essere in grado di utilizzare, che è esattamente il caso della biblioteca CS50, non solo implementare le funzioni in qualcosa come CS50.c, è anche mettere i prototipi non all'inizio del file, ma nella parte superiore di un file di intestazione, poi il file di intestazione è quello che amici e colleghi comprendono, con forte includere nel proprio codice. Quindi tutto questo tempo siete stati inclusi tutti questi prototipi efficacemente nella parte superiore del file, ma per mezzo di questo meccanismo sono taglienti che essenzialmente copie e paste di questo file nel proprio. Ora, ecco un po 'di documentazione molto dettagliata. Abbiamo più o meno per scontato che GetInt ottiene un int, ma è venuto fuori ci sono alcuni casi angolo, giusto? Che cosa succede se l'utente digita in un numero che è troppo grande? Un trilione, che proprio non può andare bene all'interno di un int? Qual è il comportamento previsto? Beh, idealmente, è prevedibile. Quindi, in questo caso, se effettivamente leggere la stampa fine, vedrai che se la linea non può essere letto, questo INT_MAX restituisce. Non abbiamo mai parlato di questo, ma in base alla sua capitalizzazione, quello che è, forse? E 'una costante, quindi è una costante speciale che probabilmente ha dichiarato in una di quelle file di intestazione che c'è più in alto nel file, e INT_MAX è probabilmente qualcosa di simile, circa, 2 miliardi di euro. L'idea è che, perché abbiamo bisogno di indicare in qualche modo che qualcosa è andato storto, noi, sì, hanno 4000000000 numeri a nostra disposizione, negativo 2 miliardi fino a 2 miliardi di euro, prendere o lasciare. Ebbene, ciò che è comune nella programmazione è rubi solo uno di questi numeri. Forse 0, forse 2 miliardi di euro, forse negativo 2 miliardi di euro. Così si spende uno dei vostri valori possibili in modo che si può commettere al mondo che se qualcosa va storto, io tornerò questo super-grande valore. Ma non si desidera che l'utente digita qualcosa di criptico come "2, 3, 4 ..." di numero molto grande, dove si generalizza invece come una costante. Quindi, veramente, se venivano anale nelle ultime settimane, in qualsiasi momento si chiama GetInt, si sarebbe dovuto verificare con una condizione if. Forse il tipo di utente in INT_MAX, o più precisamente, ha fatto ritorno INT_MAX GetInt? Perché se così fosse, questo significa che in realtà non lo scrivere, qualcosa è andato storto in questo caso. Quindi questo è ciò che è generalmente conosciuto come un valore "sentinella", che significa semplicemente speciale. Bene, ora girare per i file. C. Il file C è esistita nel apparecchio per molto tempo, e, in effetti, l'apparecchio ha lo pre-compilati in quella cosa che abbiamo chiamato "codice oggetto", ma semplicemente non importa a voi dove è perché il sistema sa, in questo caso, dove si trova, l'apparecchio. Ma andiamo ora a scorrere verso il basso getInt, e vedere come GetInt ha lavorato per tutto questo tempo. Quindi qui abbiamo commenti simili da prima. Vorrei ingrandire solo la porzione di codice, e ciò che abbiamo per GetInt è la seguente. Prende nessun input e restituisce un int, while (true), quindi abbiamo un ciclo infinito deliberata ma, presumibilmente, faremo uscire da questo in qualche modo, o ritornare all'interno di questa. Quindi cerchiamo di vedere come funziona. Beh, sembrano utilizzare GetString in questa prima linea all'interno del ciclo, 166. Questo è ora buona pratica perché in quali circostanze GetString potrebbe restituire questo particolare parola chiave, NULL? Se qualcosa va storto. Cosa potrebbe andare storto quando si chiama qualcosa come GetString? Si '? [Risposta studente, incomprensibile] >> Si '. Quindi forse malloc non riesce. Da qualche parte sotto il cofano GetString sta chiamando malloc, che alloca la memoria, che consente al negozio di computer tutti i caratteri che l'utente digita nella tastiera. E se l'utente ha avuto un sacco di tempo libero e digitato più, per esempio, di 2 miliardi di caratteri. Altri personaggi che il computer ha anche RAM. Ebbene, GetString deve essere in grado di significare che ti, anche se questo è un super, super-angolo caso raro. Deve essere in qualche modo in grado di gestire questa situazione, e così GetString, se tornare indietro e leggere la sua documentazione, fa, infatti, restituisce NULL. Ora, se non riesce GetString restituendo NULL, GetInt sta per fallire ritornando INT_MAX, proprio come una sentinella. Questi sono solo convenzioni umane. L'unico modo sarebbe che questo è il caso è leggendo la documentazione. Quindi cerchiamo di scorrere verso il basso dove la int è in realtà GotInt. Quindi, se ho scorrere verso il basso un po 'più, in linea 170 abbiamo un commento di cui sopra queste righe. Quindi noi dichiariamo, nel 172, un int n e c char, e poi questa nuova funzione che alcuni di voi hanno imbattuto prima, ma sscanf. Questo sta per stringa f scansione. In altre parole, dammi una stringa e lo esamina per pezzi di informazioni di interesse. Che cosa vuol dire? Bene, supponiamo che digito, letteralmente, 1 2 3 alla tastiera, e poi premere invio. Qual è il tipo di dati di 1 2 3 quando restituito da GetString? E 'ovviamente una stringa, giusto? Ho una stringa, quindi 1 2 3 è davvero "1 2 3" con il \ 0 al termine di essa. Questo non è un int. Questo non è un numero. Si presenta come un numero, ma non è in realtà. Così che cosa GetInt fare? Si deve scansionare la stringa da sinistra a destra, 1 2 3 \ 0, e in qualche modo convertire in numero intero reale. Ora, si può capire come fare questo. Se si pensa di nuovo a pset 2, che presumibilmente sono un po 'confortevole con Cesare o Vigenère in modo da poter scorrere una stringa, è possibile convertire i caratteri di interi con scelta. Questo è un sacco di lavoro. Perché non chiamare una funzione come sscanf che fa per voi? Così sscanf aspetta un argomento, in questo caso chiamato linea, che è una stringa. È quindi possibile specificare, tra virgolette, molto simile a printf, cosa vi aspettate di vedere in questa stringa? Quello che sto dicendo qui è, mi aspetto di vedere un numero decimale e forse un carattere. E vedremo perché questo è il caso in un attimo. Si scopre che questa notazione è ora ricorda di roba abbiamo iniziato a parlare poco più di una settimana fa. Che cosa è & n e & c facendo per noi qui? [Le risposte degli studenti, incomprensibile] Sì >>. Mi sta dando l'indirizzo di n e l'indirizzo di c. Ora, perché è così importante? Beh, lo sai che con le funzioni in C si può sempre restituire un valore o nessun valore. È possibile restituire un int, una stringa, un galleggiante, un char, qualsiasi cosa. Oppure si può restituire void, ma si può restituire solo 1 cosa al massimo. Ma qui vogliamo sscanf tornare me forse un int, un numero decimale, e anche un char, e ti spiego il perché il carattere in un momento. Così si vuole effettivamente f per tornare 2 cose, che non è solo possibile in C. Così si può evitare ciò passando in 2 indirizzi, perché non appena vi consegnerà una funzione di 2 indirizzi, che cosa può fare con loro funzione? E 'in grado di scrivere a questi indirizzi. È possibile utilizzare l'operazione * e "go there" a ciascuna di tali indirizzi. È un po 'questo meccanismo porta di servizio, ma molto comune per modificare i valori delle variabili in più di 1 posto, in questo caso 2. Ora, notate sto controllando per == a1, e poi tornare n se si, in effetti, restituiscono true. Allora, cosa sta succedendo? Beh, tecnicamente, tutto quello che vuole veramente accadere in GetInt è questo. Vogliamo analizzare, per così dire, vogliamo leggere la stringa "1 2 3" e se sembra che ci sia un numero, quello che stiamo dicendo sscanf fare è mettere quel numero, 1 2 3, in questa variabile n per me. Perché, allora, ho avuto anche questo? Qual è il ruolo di dire anche, sscanf, si potrebbe anche ottenere un carattere qui. [Parlando Studente, incomprensibile] >> Non - un punto decimale potrebbe funzionare. Facciamo ritengono che pensò per un momento. Che altro? [Studente, incomprensibile] >> Quindi, buon pensiero, potrebbe essere il carattere NULL. Non è in realtà, in questo caso. Si '? [Studente, incomprensibile] >> ASCII. Oppure, vorrei generalizzare ancora di più. Il c% è solo per il controllo degli errori. Non vogliamo che ci sia carattere dopo il numero, ma ciò che questo mi permette di fare è la seguente: Risulta che sscanf, oltre a memorizzare i valori N e C, in questo esempio qui, quello che fa è anche restituisce il numero di variabili messo valori trovi Quindi, se solo digitare 1 2 3, quindi solo il% d sta per corrispondere e solo n viene memorizzato con un valore come 1 2 3 e nulla viene messo in c; c resta un valore spazzatura, per così dire. Garbage, perché non è mai stato inizializzato come un certo valore. Quindi, in questo caso, sscanf restituisce 1, perché popolato uno di quei puntatori, in tal caso, grande. Ho un int, quindi liberare la linea per liberare la memoria che GetString effettivamente stanziato, e poi torno n. Altrimenti, se siete mai chiesti dove riprovare dichiarazione che viene, viene da qui. Se, al contrario, di tipo I in 1 2 3 foo, solo alcune sequenza casuale di testo, sscanf è andare a vedere, ooh, numero, ooh, numero, ooh, numero, ooh - f. E sta andando a mettere la 1 2 3 n. E 'intenzione di mettere la f in c, e poi tornare 2. Così abbiamo, usando solo la definizione di base del comportamento di scanf, un modo molto semplice - bene, complesso a prima vista, ma alla fine della giornata, meccanismo abbastanza semplice di dire, c'è un int, e in tal caso, è che l'unica cosa che ho trovato? E lo spazio bianco qui è intenzionale. Se andate a leggere la documentazione per sscanf, ti dice che se si include un pezzo di spazio bianco all'inizio o alla fine, sscanf troppo consentirà all'utente, per qualsiasi motivo, per colpire la barra spaziatrice 1 2 3, e che sarà legittimo. Non griderà presso l'utente solo perché hanno colpito la barra spaziatrice, all'inizio o alla fine, che è solo un po 'più user-friendly. Tutte le domande, poi, GetInts? Si '? [Domanda Studente, incomprensibile] >> Buona domanda. Che cosa succede se hai appena digitato un carattere, come la f, e premi invio senza mai digitare 1 2 3, che ne pensi del comportamento di questa riga di codice sarebbe allora? Così sscanf in grado di coprire anche questo, perché in tal caso, non sta andando a riempire n o c, che sta per tornare invece 0. In questo caso, sono anche la cattura di tale scenario, in quanto il valore atteso che voglio è 1. Voglio solo 1, e solo 1 cosa da riempire. Bella domanda. Altri? Va bene, quindi cerchiamo di non passare attraverso tutte le funzioni qui dentro, ma quello che sembra essere, forse, di interesse rimane è GetString perché si scopre che getFloat, GetInt, GetDouble, GetLongLong tutto punt un sacco di loro funzionalità per GetString. Quindi, diamo uno sguardo a come si è implementato qui. Questo sembra un po 'complessa, ma utilizza i fondamenti stessi che abbiamo iniziato a parlare la settimana scorsa. Quindi, in GetString, che prende alcun argomento secondo il vuoto qui, e restituisce una stringa, così mi dichiara una stringa denominata buffer. Io non so davvero che cosa che sta per essere utilizzato per ancora, ma staremo a vedere. Assomiglia capacità è, per impostazione predefinita, 0, non del tutto sicuro dove questo sta andando. Non sei sicuro di quello che n sta per essere utilizzato per la ancora. Ma ora sta diventando un po 'più interessante, così in linea 243, si dichiara un int c, questo è una sorta di un dettaglio stupido. Un char è di 8 bit, e 8 bit in grado di memorizzare il numero di valori diversi? 256. Il problema è che, se si desidera avere 256 caratteri ASCII differenti, che ci sono, se si pensa tornato, e questa non è una cosa da memorizzare. Ma se ripenso a quel grande grafico ASCII abbiamo avuto settimane fa, vi erano, in quel caso, 128 o 256 caratteri ASCII. Abbiamo usato tutti i modelli di 0 e di 1 in su. Questo è un problema se si vuole essere in grado di rilevare un errore. Perché se si sta già utilizzando 256 valori per i tuoi personaggi, che in realtà non pianificare in anticipo, perché ora non c'è modo di dire, "Questo non è un carattere legittimo, questo è un messaggio errato." Quindi, ciò che il mondo non è, si utilizza il valore più prossimo, qualcosa di simile a un int in modo da avere un numero pazzesco di bit, 32 per 4 miliardi di possibili valori, in modo che si può semplicemente finire con, essenzialmente, 257 di loro, uno dei quali ha un significato speciale come un errore. Quindi cerchiamo di vedere come funziona. In linea 246, ho questo grande anello, mentre che chiama fgetc; file di significato f, getc, e quindi stdin. Si scopre che questo è solo il modo più preciso per dire "leggere l'input da tastiera." Tastiera standard mezzi di input, standard output significa schermo, e l'errore standard, che vedremo nel pset 4, significa che lo schermo, ma una parte speciale dello schermo in modo che non è fusero con uscita effettivo che si intende stampare, ma più su che in futuro. Così fgetc significa solo leggere un carattere dalla tastiera, e conservarla dove? Conservare in c, e quindi controllare, quindi sono solo l'utilizzo di alcune congiunzioni booleane qui, verificare che non è uguale a \ n, in modo che l'utente ha premuto invio. Vogliamo fermare a quel punto, fine del ciclo, e vogliamo anche verificare per la costante speciale, EOF, che se si conosce o indovinare - che cosa rappresenta? Fine del file. Quindi questo è una specie di assurdo, perché se sto scrivendo sulla tastiera, non c'è davvero alcun file coinvolti in questo, ma questa è solo una specie di termine generico usato per indicare che nessun altro è in arrivo dalle dita del dell'essere umano. EOF. Fine del file. Per inciso, se hai mai colpito il controllo d a tastiera, non che si devono ancora, hai raggiunto il controllo c. Ma il controllo d invia questo speciale EOF costante chiamata. Così ora non ci resta che un po 'di allocazione dinamica della memoria. Quindi, se n + 1> capacità, ora ti spiego n. n è solo il numero di byte attualmente nel buffer, la stringa che si sta costruendo da parte dell'utente. Se si dispone di più caratteri nel buffer di quello che hai capacità nel buffer, intuitivamente, quello che dobbiamo fare è quindi allocare più capacità. Ho intenzione di sorvolare su alcune delle aritmetica qui e concentrarsi solo su questa funzione qui. Sai cosa malloc è, o almeno generalmente familiare. Prova a indovinare cosa realloc fa. [Risposta studente, incomprensibile] Sì >>. E non è tutto l'aggiunta di memoria, ma riassegna memoria come segue: Se c'è ancora spazio alla fine della stringa per dare più di quel ricordo che dà origine, allora si otterrà che la memoria aggiuntiva. Così si può solo mettere i caratteri stringhe back to back to back to back. Ma se non è questo il caso, perché hai aspettato troppo a lungo e qualcosa di casuale ottenuto si lasciò in memoria lì, ma non c'è più memoria qui, va bene. Realloc sta andando a fare tutto il lavoro pesante per voi, spostare la stringa che hai letto in così lontano da qui, metterlo laggiù, e poi danno pista ancora un po 'a quel punto. Così, con un gesto della mano, lasciatemi dire che quello che sta facendo GetString si sta partendo con un buffer piccolo, forse 1 singolo carattere, e se l'utente digita in 2 caratteri, GetString finisce chiamare realloc e dice: 'Ooh, 1 carattere non era sufficiente. Dammi 2 caratteri. ' Poi se si legge attraverso la logica del ciclo, sta andando a dire: 'Ooh, l'utente ha digitato in 3 caratteri. Dammi ora non 2 ma 4 caratteri, allora dammi 8, poi dammi 16 e 32. ' Il fatto che io sono il raddoppio della capacità di volta in volta significa che il buffer non ha intenzione di crescere lentamente. E 'intenzione di crescere super veloce, e quale potrebbe essere il vantaggio di questo? Perché mi raddoppiando la dimensione del buffer, anche se l'utente potrebbe solo bisogno di 1 carattere aggiuntivo dalla tastiera? [Risposta studente, incomprensibile]. >> Che cos'è? Esattamente. Non c'è bisogno di crescere come spesso. E questo è solo una specie di - tu sei di copertura vostre scommesse qui. L'idea è che non si desidera chiamare realloc molto, perché tende ad essere lento. Ogni volta che si chiede il sistema operativo per la memoria, come vedrete presto in un set problema futuro, tende a richiedere un certo tempo. Quindi, riducendo al minimo tale periodo di tempo, anche se si sta perdendo un po 'di spazio, tende ad essere una buona cosa. Ma se si legge attraverso la parte finale della GetString qui, e ancora, capire ogni singola riga qui non è così importante oggi. Ma notare che alla fine chiama malloc di nuovo, e si assegna esattamente come byte quanti ne sono necessari per la stringa e poi getta via al numero gratuito, il buffer eccessivamente grande, se davvero ha raddoppiato troppe volte. In breve, questo è il modo GetString ha lavorato per tutto questo tempo. Tutto ciò che fa è leggere un carattere alla volta ancora e ancora e ancora e ogni volta che ha bisogno di un po 'di memoria aggiuntiva, chiede il sistema operativo per chiamando realloc. Hai ancora domande? Bene. Un attacco. Ora che abbiamo capito i puntatori, o per lo meno sono sempre più familiari con i puntatori, prendiamo in considerazione come il mondo intero inizia a crollare se non riesco a difendersi contro gli utenti contraddittorio, le persone che stanno cercando di penetrare nel vostro sistema. Le persone che stanno cercando di rubare il software aggirando qualche codice di registrazione che potrebbero altrimenti essere necessario digitare trovi Date un'occhiata a questo esempio qui, che è solo il codice C che ha una funzione principale in fondo, che chiama una funzione foo, e ciò che sta passando a foo? [Studente] Un singolo argomento. >> Singolo argomento. Quindi, argv [1], il che significa che la prima parola l'utente ha digitato dalla riga di comando dopo a.out o qualunque sia il programma si chiama. Quindi foo, in alto, prende in un char *, char *, ma è proprio quello? String. Non c'è niente di nuovo qui, e che la stringa viene arbitrariamente chiamato bar. In questa linea qui, char c [12], in una sorta di semi-inglese tecnico, cosa sta facendo questa linea? Array di -? Caratteri. Dammi un array di 12 caratteri. Così si potrebbe chiamare questo un buffer. E 'tecnicamente chiamato c, ma un buffer in programmazione significa solo un mucchio di spazio che si può mettere un po 'di roba trovi Poi infine, memcpy, non abbiamo usato prima. Ma si può intuire ciò che fa. Esso copia della memoria. Che cosa fa? Beh, a quanto pare copia bar, il suo ingresso, in c, ma solo fino alla lunghezza della barra. Ma c'è un bug qui. Okay, tecnicamente si dovrebbe davvero fare strlen (bar) x sizeof (char), e 'corretto. Ma nel peggiore dei casi qui, supponiamo che that's - così, va bene. Poi ci sono 2 bug. Quindi, sizeof (char), va bene, facciamo questo un po 'di più. Così ora c'è ancora un bug, che è quello che? [Risposta studente, incomprensibile] >> Controlla per cosa? Ok, allora ci dovrebbe essere il controllo per NULL, perché le cose vanno così male quando il puntatore è NULL, Perché si potrebbe finire per andare lì, e non si dovrebbe mai andare a NULL deferenziandolo con l'operatore *. Quindi questo è un bene, e che altro stiamo facendo? Logicamente c'è un difetto anche qui. [Risposta studente, incomprensibile] >> Quindi controllare se argc ≥ 2? Ok, quindi non c'è 3 bug in questo programma. Non stiamo verificando se l'utente effettivamente digitato qualcosa in argv [1], bene. Allora qual è il bug terzo? Si '? [Risposta studente, incomprensibile] >> Bene. Così abbiamo controllato uno scenario. Abbiamo controllato implicitamente non copiare più memoria che supera la lunghezza della barra. Quindi, se la stringa che l'utente digitato è di 10 caratteri, questo sta dicendo, 'Copia solo 10 caratteri.' E va bene, ma cosa succede se l'utente ha digitato in una parola al prompt come una parola di 20 caratteri, questo è, dicendo copia 20 caratteri dalla barra in che cosa? c, altrimenti noto come il buffer, il che significa che i dati appena scritto a 8 posizioni di byte che non si è proprietari, e tu non ne sei il proprietario, nel senso che non li avete mai assegnato. Quindi questo è ciò che è comunemente noto come l'attacco di tipo buffer overflow, o attacco di buffer overrun, e l'attacco, nel senso che se l'utente o il programma che sta chiamando la funzione sta facendo questo maliziosamente, ciò che effettivamente accade successivo potrebbe essere piuttosto male. Diamo uno sguardo a questa immagine qui. Questa foto rappresenta la tua pila di memoria. E ricordare che ogni volta che si chiama una funzione, si ottiene questo quadro poco nello stack e poi un altro e poi un altro e poi un altro. E fin qui abbiamo solo un po 'astratto via come questi rettangoli sia lì sul bordo o sulla schermata qui. Ma se lo zoom su uno di quei rettangoli, quando si chiama una funzione foo, si scopre che c'è di più in pila all'interno di detto telaio e che rettangolo non solo x e y e a e b, come abbiamo fatto parlare di swap. Si scopre che ci sono alcuni dettagli di livello inferiore, tra di loro indirizzo di ritorno. Così si scopre quando principale chiama foo, principale deve informare foo quale indirizzo principale è nella memoria del computer. Perché altrimenti, non appena foo è fatto esecuzione, come in questo caso qui, una volta raggiunto questo tutore vicino riccio alla fine di foo, come cavolo si sa dove foo controllo del programma dovrebbe andare? Si scopre che la risposta a questa domanda è in quel rettangolo rosso qui. Si tratta di un puntatore, e sta al computer per memorizzare, temporaneamente, sulla cosiddetta pila l'indirizzo principale in modo che non appena foo è fatto esecuzione, il computer sa dove e cosa linea principale per tornare a. Frame pointer salvata riferisce in modo simile a questo. Bar * Char qui rappresenta ciò? Bene, ora questo segmento blu è qui cornice foo, che cosa è il bar? Ok, quindi bar è solo l'argomento per la funzione foo. Così ora siamo tornati il ​​quadro familiare. Ci sono più cose e più distrazioni sullo schermo ma questo segmento di luce blu è quello che abbiamo disegnare alla lavagna per qualcosa come swap. Questa è la cornice per foo e l'unica cosa in proprio ora è il bar, che è questo parametro. Ma che altro dovrebbe essere nello stack, in base a questo codice qui? Char c [12]. Quindi dovremmo anche vedere 12 quadrati di memoria, assegnato ad una variabile denominata c. E infatti noi abbiamo che sullo schermo. La cima è c [0], e poi l'autore di questo schema non si preoccupò di disegnare tutte le piazze, ma ci sono davvero 12 si perché se si guarda in basso a destra, c [11], se si contano da 0, sono i 12 byte del genere. Ma ecco il problema: In quale direzione sta crescendo c? Un po 'verso il basso, giusto? Se inizia in alto e cresce verso il basso, non sembra ci lasciato pista molto qui a tutti. Abbiamo tipo di noi stessi in un angolo, e che c [11] è proprio contro il bar, che si trova proprio di fronte puntatore dello stack frame, che si trova proprio di fronte l'indirizzo di ritorno, non c'è più posto. Allora, qual è l'implicazione, allora, se si avvitare, e provare a leggere 20 byte in un buffer di 12 byte? Dove questi 8 byte aggiuntivi intenzione di andare? All'interno tutto il resto, alcuni dei quali è super importante. E la cosa più importante, potenzialmente, è la scatola rossa c'è, l'indirizzo di ritorno. Perché supporre che o si è accidentalmente o contraddittorio sovrascrivere le 4 byte, che si rivolgono a puntatore, non solo con i rifiuti, ma con un numero che succede a rappresentare un indirizzo effettivo di memoria? Qual è il implicaiton, logicamente? [Le risposte degli studenti, incomprensibile] >> Esattamente. Quando ritorna foo e colpisce che la parentesi graffa, il programma sta per procedere non per tornare alla pagina principale, che sta per tornare a qualsiasi indirizzo si trova in quella scatola rossa. Ora, nel caso di registrazione del software eludere, qual è l'indirizzo che viene restituito è la funzione che normalmente viene chiamato dopo che hai pagato per il software e immesso il codice di registrazione? Si potrebbe ordinare di trucco del computer in non andare qui, ma invece, andando qui. Oppure, se sei davvero intelligente, un avversario può effettivamente digitare alla tastiera, per esempio, non una parola vera, non 20 caratteri, ma supponiamo che lui o lei in alcuni tipi di caratteri che rappresentano il codice? E non sarà il codice C, che sta per essere i caratteri che rappresentano codici macchina binario, 0 e di 1. Ma se sono abbastanza intelligenti per farlo, per incollare in qualche modo nel prompt GetString qualcosa che è essenzialmente codice compilato, e gli ultimi 4 byte sovrascrivere l'indirizzo di ritorno, ea che indirizzo vuol fare ingresso? Lo memorizza in questo rettangolo rosso l'indirizzo del primo byte del buffer. Quindi devi essere molto intelligente, e questo è un sacco di tentativi ed errori per le persone cattive là fuori, ma se si riesce a capire quanto è grande questo buffer è, tale che gli ultimi bytes in ingresso che fornisce al programma capita di essere equivalente al indirizzo iniziale del buffer, si può fare questo. Se diciamo, di solito, ciao, e \ 0, questo è ciò che finisce nel buffer. Ma se siamo più intelligenti, e noi riempire il buffer con quello che ci chiamiamo genericamente codice di attacco, A, A, A, A: attacco, attacco, attacco, attacco, dove questo è solo qualcosa che fa qualcosa di male. Ebbene, che cosa succede se si è davvero intelligente, si potrebbe fare questo: Nella scatola rossa qui è una sequenza di numeri: 80, CO, 35, 08. Si noti che che corrisponde al numero che è qui. E 'in ordine inverso, ma più su che un'altra volta. Si noti che questo indirizzo di ritorno siano stati deliberatamente modificati per eguagliare l'indirizzo qui, non l'indirizzo del principale. Quindi, se il cattivo è super intelligente, lui o lei sta andando a includere in tale codice di attacco qualcosa di simile, 'Elimina tutti i file dell'utente.' O 'Copiare le password,' o 'Creare un account utente che può accedere.' Nulla, e questo è sia il pericolo e il potere di C. Perché si ha accesso alla memoria tramite puntatori e si può quindi scrivere tutto quello che vuoi nella memoria di un computer. Si può fare un computer a fare tutto quello che vuoi semplicemente averlo saltare nel suo spazio di memoria. E così, fino ad oggi, così molti programmi e siti web così tanti che sono compromesse si riducono a persone che beneficiano di questo. E questo potrebbe sembrare un super-sofisticato attacco, ma non sempre iniziare in quel modo. La realtà è che ciò che le persone cattive in genere fare è, se si tratta di un programma a riga di comando o un programma con interfaccia grafica o un sito web, vi basta iniziare a fornire una sciocchezza. Si digita in una parola molto grande nel campo di ricerca e premi Invio, e si aspetta di vedere se il crash del sito web. Oppure aspettare per vedere se il programma si manifesta qualche messaggio di errore. Perché se sei fortunato, come il cattivo, e di fornire alcuni input pazzo che va in crash il programma, questo significa che il programmatore non ha previsto il tuo cattivo comportamento il che significa che probabilmente si può, con uno sforzo sufficiente, prova sufficiente ed errori, capire come condurre un attacco più preciso. Così tanto una parte della sicurezza non è solo di evitare questi attacchi del tutto, ma individuarli e in realtà guardando i log e vedere quali fattori pazzi sono persone digitato nel tuo sito web. Quali parole di ricerca sono le persone digitato nel tuo sito web nella speranza di traboccante un buffer? E questo tutto si riduce a semplici le basi di ciò che è un array, e cosa significa per allocare e utilizzare la memoria? E, per tale, anche, è questo. Così facciamo solo uno sguardo all'interno di un hard disk ancora una volta. Così si richiama da una settimana o due fa che quando si trascinare i file al cestino o cestino, cosa succede? [Studente] Niente. >> Si ', assolutamente nulla. Alla fine se si esegue basso lo spazio su disco, Windows o Mac OS avvierà l'eliminazione dei file per voi. Ma se si trascina qualcosa in là, allora non è affatto sicuro. Tutto il membro compagno di stanza, amico o un familiare ha a che fare è fare doppio clic, e voilà. Ci sono tutti i file abbozzato che stai cercando di eliminare. Così la maggior parte di noi almeno sappiamo che è necessario fare clic destro o controllare click e svuotare il cestino, o qualcosa del genere. Ma anche allora, che non farà il trucco. Perché ciò che accade quando si ha un file sul disco rigido che rappresenta circa il documento di Word o un po 'di JPEG? E questo rappresenta il disco rigido, e diciamo che questo frammento qui rappresenta quel file, ed è composto da un insieme di 0 e di 1. Cosa succede quando non solo trascinare il file nel cestino o cestino, ma anche svuotarla? Una specie di nulla. Non è assolutamente nulla. Ora è proprio niente, perché un po 'di qualcosa che accade in forma di questa tabella. Quindi c'è una sorta di database o una tabella all'interno della memoria di un computer che ha essenzialmente 1 colonna per i nomi dei file, e 1 colonna per la posizione del file, dove questo potrebbe essere posizione 123, solo un numero casuale. Così potremmo avere qualcosa di simile x.jpg, e la posizione 123. E cosa succede poi, quando si svuota il cestino? Che se ne va. Ma ciò che non va via è lo 0 e di 1. Così che cosa è, poi, il collegamento al pset 4? Bene, con pset 4, solo perché abbiamo accidentalmente cancellato la scheda Compact Flash che aveva tutte queste foto, o semplicemente perché dalla sfortuna è corrotto, non significa che lo 0 e 1 non sono ancora lì. Forse alcuni di loro si perdono perché qualcosa ha danneggiato nel senso che alcuni divenne 1 0 e di 1 diventa 0. Le cose brutte possono accadere a causa di software difettoso o hardware difettoso. Ma molti di questi frammenti, forse anche il 100% di loro sono ancora lì, è solo che il computer o la fotocamera non sa dove JPEG 1 è partito e dove JPEG 2 è partito, ma se si, il programmatore, sa, con un po 'di buon senso, se tali file JPEG sono o quello che sembrano, è possibile analizzare la 0 e 1 e dire, 'Ooh. JPEG. Ooh, JPEG. ' È possibile scrivere un programma con essenzialmente solo un ciclo for o while che recupera ognuno di quei file. Così la lezione quindi, è quello di iniziare "in modo sicuro" cancellare i file se vuoi evitare questo del tutto. Sì? [Domanda Studente, incomprensibile] >> Avere più memoria di quanto fatto prima - Oh! Bella domanda. Perché, poi, dopo lo svuotamento del cestino, è il computer vi dirà che avete più spazio libero che avete fatto prima? In poche parole, perché sta mentendo. Più tecnicamente, si ha più spazio. Perché ora si è detto, si può mettere altre cose in cui il file una volta, ma questo non significa che i bit stanno andando via, e questo non significa che i bit sono stati cambiati tutti 0, per esempio, per la vostra protezione. Al contrario, se "in modo sicuro" cancellare file, o distruggere fisicamente il dispositivo, questo è davvero l'unico modo, a volte, intorno a quello. Allora perché non lasciamo che il semi-spaventoso nota, e ci vedremo il Lunedi. CS50.TV