>> [GIOCO MUSICA]
DAVID J. MALAN: Va bene.
Questo è CS50, e questo è la fine della quarta settimana.
E uno dei temi oggi è quello della digital forensics,
l'arte di recuperare informazioni.
E infatti, anche se siete nel bel mezzo
in questo momento di pace a tre e Breakout, la prossima settimana,
l'attenzione sarà focalizzata sulla Proprio questo dominio.
>> Così uno dei lavori più cool che mai avuto era tornato a scuola di specializzazione,
quando lavoravo per il locale Middlesex County procuratore distrettuale di
ufficio, forensics fare il lavoro.
Quindi, in sostanza, il Massachusetts Polizia di Stato, in occasione,
quando si lavora su casi sarebbe portare a cose come hard disk
e floppy disk e schede di memoria e simili.
E li avrebbero portata di mano a me e il mio mentore,
e il nostro obiettivo era quello di trovare le prove, se c'era, su questi terreni.
Ora, potreste aver visto scorci di questo mondo di medicina legale
nei media, TV e film.
Ma il lavoro che ho avuto, e Oserei dire che il mondo,
non è abbastanza come volete vederlo.
Diamo un'occhiata a ciò che probabilmente avete visto.
[RIPRODUZIONE VIDEO]
-OK.
Ora, mettiamoci una buona occhiata a voi.
>> [GIOCO MUSICA]
>> -hold Esso.
Eseguire che indietro.
>> -wait Un minuto.
Andate a destra.
-Ci.
Congelare tale.
Full-screen.
>> -OK.
Congelare tale.
-Tighten Su quella, vero?
>> -vector In esso ragazzo dalla ruota posteriore.
>> -zoom In proprio qui su questo luogo.
>> -Con La giusta attrezzatura, il l'immagine può essere ingrandita e affilata.
>> -Che È?
>> -È Un programma di miglioramento.
>> -Puoi Chiaro che qualsiasi?
>> -Non Lo so.
Facciamo valorizzarlo.
>> -e La valorizzazione Sezione A6.
Ho migliorato il dettaglio, e--
-I Credo che ci sia sufficiente a migliorare.
Rilasciare al mio schermo.
>> -I Migliorato la riflessione nel suo occhio.
-Let Gestito questo attraverso correzione video.
>> -Edgar, Si può migliorare questo?
>> -hang Su.
>> -Ho Lavorato su questa riflessione.
>> La riflessione di qualcun -Ci.
>> -Reflection.
-C'è Un riflesso del volto dell'uomo.
>> Riflessione -Il!
-C'è Una riflessione.
-zoom In sullo specchio.
Si può vedere un riflesso.
>> -Can A migliorare l'immagine da qui?
-Can A migliorare esso?
-Può Aumentiamo questo?
-Can A migliorare esso?
-hold Su un secondo.
Io Migliora.
-zoom In sulla porta.
-Times 10.
-Zoom.
-Muovi In.
-Più.
-Aspetta, Stop.
-Stop.
-PAUSE Esso.
Ci -rotate 75 gradi attorno alla verticale, per favore.
>> -Stop.
Torna alla parte sulla porta di nuovo.
>> -Got Intensificatore di immagine che può bitmap?
>> -Forse Possiamo usare il Pradeep Singh metodo per vedere le vetrine.
>> -Il Software è lo stato dell'arte.
>> -Il Autovalore è spento.
>> -Con Destra combinazione di algorithms--
>> Preso l'illuminazione di -Lui algoritmi per il livello successivo,
e io li posso usare per migliorare questa fotografia.
>> -lock Su e ingrandire l'asse z.
>> -e La valorizzazione.
Migliora.
-e La valorizzazione.
-Freeze E migliorare.
[FINE RIPRODUZIONE VIDEO]
DAVID J. MALAN: Così quelli sono tutte le parole, ma non erano
utilizzato in frasi correttamente.
E infatti, in futuro, in qualsiasi momento, per favore, si sente qualcuno dire la parola,
"Migliorare" risatina solo un po '.
Perché quando si tenta di migliorare, per esempio, questo è ciò che accade.
>> Quindi, ecco una foto bellissima.
Questo è proprio Daven del CS50.
E supponiamo che volevamo concentrarsi sulla scintillio negli occhi,
o la riflessione della cattivo ragazzo che era chiaramente
catturata dalla telecamera di sicurezza.
Questo è ciò che accade quando si ingrandisce un'immagine che
ha solo un numero finito di bit ad esso associati.
>> Questo è ciò che si ottiene.
E infatti, negli occhi di Daven è ma quattro, forse sei pixel
che compongono esattamente quello è stato scintillante lì.
Così Problema Set Quattro infine avrà esplorare questo mondo, in particolare
dalla natura di qualcosa noi chiamiamo il file I / O, dove
I / O è solo un modo elegante di dicendo ingresso e uscita.
>> Quindi finora, tutte le interazioni abbiamo avuto con un computer
sono stati in gran parte con il tastiera e lo schermo,
ma non tanto con il disco rigido, o il salvataggio di file oltre quelli che
te scrivere.
I vostri programmi finora hanno non state creando e salvando,
e aggiornare i propri file.
>> Beh, che cosa è un file?
Beh, qualcosa come un JPEG.
Questa è l'immagine che si potrebbe avere o caricare su Facebook,
o consultare ovunque sul web.
In effetti, quella foto che abbiamo appena sega di Daven era un JPEG.
E cosa c'è di interessante sui file come JPEG
è che possono essere identificati, in genere, da certi schemi di bit.
>> In altre parole, cos'è che distingue un JPEG da una GIF
da un PING da un Word documento da un file di Excel?
Beh, è ​​solo diverso pattern di bit.
E quei diversi modelli sono solitamente all'inizio di tali file.
>> In modo che quando il computer si apre una Parola doc, o quando un computer si apre un file JPEG,
sembra tipicamente alla prime più bit nel file.
E se riconosce un modello, si dice, oh, questa è l'immagine.
Permettetemi lo mostro a l'utente come un grafico.
In alternativa, oh, questo appare come un documento di Word.
Mi permetta di mostrare all'utente come un saggio.
>> Così, per esempio, JPEG, si scopre, sono
abbastanza sofisticato sotto la cappa.
Ma i primi tre byte in più ogni JPEG iniziare con questi tre numeri.
Così byte zero, uno e due sono, in più ogni JPEG, 255, allora il numero
216, poi il numero 255.
>> E che cosa sarete in grado per iniziare a fare la prossima settimana
è in realtà frugando sotto la cappa di file come file JPEG
e come file bitmap, e vedendo quello che è sempre stato lì per tutto il tempo
come sei stato utilizzando un computer.
>> Ma ciò che è non vi è in genere scritto come numeri decimali come questo.
Gli informatici non lo fanno tendono a parlare in decimale.
Essi in realtà non parlano in binario.
In genere, quando vogliamo per esprimere i numeri,
abbiamo effettivamente utilizziamo esadecimale, che si può ricordare
da, diciamo, Problem Set Uno, che ha sfidato
a pensare a un sistema diverso.
>> Noi, naturalmente, conosciamo con decimali, da zero a nove.
Abbiamo parlato di binario.
E in realtà non abbiamo utilizzare più di tanto qui
in avanti, perché i computer che utilizzeranno.
Ma i programmatori sarà molto spesso, ma non sempre,
utilizzare esadecimale, che significa semplicemente si hanno 16 lettere nel vostro alfabeto,
al contrario di due o 10.
>> Così come si conta di più alto di nove in esadecimale?
Si va 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, solo per convenzione.
Ma ciò che è fondamentale è che ogni di questi è un unico simbolo.
Non esiste 10.
Non c'è 11, di per sé, poiché ogni delle vostre cifre, proprio come in decimale
e proprio come in binario, dovrebbe solo essere un singolo carattere, per convenzione.
>> In modo che poi è l'alfabeto che abbiamo a nostra disposizione per esadecimale.
Che cosa fa un JPEG apparire come se si dovevano scrivere quelle prime tre
Non byte come decimale, ma, per esempio, come esadecimale?
E perché è hex anche tutto ciò che è utile?
>> Beh, un rapido sguardo a un esempio.
Quindi se scrivo i bit che rappresentare questi numbers-- decimale
questo potrebbe essere un po 'arrugginito ormai da un paio di settimane fa,
ma la sinistra e la quello di destra è abbastanza facile.
255 era il numero più grande che potrebbe rappresentare con otto bit.
Era tutti quelli.
Quindi l'unico che è leggermente interessante è quella centrale.
E se i tipi di fate fuori del matematica, si deduce che, in effetti,
quel modello di uno e zeri rappresenta 216.
Così facciamo solo per stipulare ora che questi sono corretti.
Ma perché è interessante?
>> Ebbene, un byte, naturalmente, è di otto bit.
E si scopre che se si pensa di un byte come due blocchi di quattro bit,
come questo.
Vorrei solo aggiungere un po 'di spazio.
Quindi, prima, dopo.
Ho appena aggiunto un po 'di spazio bianco per l'amor di visualizzazione qui.
Come possiamo ora rappresentare, per esempio, esadecimale ogni quad di bit,
ogni serie di quattro bit?
>> Così, per esempio, a sinistra Ora, noi abbiamo 1111 in binario.
Qual è quel numero in decimale, se fate la matematica?
Hai il posto quelli, il posto due, il posto a quattro zampe, e il luogo otto.
>> PUBBLICO: 15.
DAVID J. MALAN: E '15.
Quindi, se facciamo otto più quattro più due più uno, otteniamo 15.
Così ho potuto scrivere le 15 di seguito 1111, ma il punto qui
è esadecimale, non decimale.
Così, invece di scrivere 15, 1-5, Ho intenzione di scrivere che in esadecimale,
che se si pensa di nuovo, se si dispone di zero a f, ciò che è 15 sarà?
PUBBLICO: f.
DAVID J. MALAN: Così si scopre che di f.
E si può lavorare che col dire, bene, se a è 10, quindi OK, f è 15.
Così in effetti, potremmo riscrivere la stessa serie di numeri come f f.
E poi se facciamo un po 'di matematica, ci deduciamo che questo è d.
Otto è abbastanza facile, perché noi avere uno nel posto otto.
E poi, abbiamo un altro paio di f f.
>> Così che cosa gli esseri umani tendono a fare per convenzione quando usano esadecimale è semplicemente
scrivere questo un po 'più succintamente, sbarazzarsi della maggior parte di quello spazio bianco.
E tanto per essere super chiaro a lettori che questa è esadecimale,
la semplice convenzione tra esseri umani è che si scrivono a zero
x, che non ha significato altro di un identificatore visivo di,
ecco che arriva un numero esadecimale.
>> E poi, mettete le due cifre, f f in questo caso, allora d un, allora f f.
Quindi, per farla breve, esadecimale tende solo
essere utile perché ciascuno dei suoi cifre, zero attraverso f, perfettamente linee
con un pattern di quattro bit.
>> Quindi, se avete due cifre esadecimali, zero a F, ancora e ancora,
che ti dà perfettamente otto bit o un byte.
Ecco perché esso tende a essere convenzionalmente utile.
Non c'è intellettuale contenuto davvero oltre che,
altro che la sua effettiva utilità.
>> Ora JPEG non sono l'unica formati di file per la grafica.
Si potrebbe ricordare che ci sono i file di questo tipo nel mondo,
almeno da un paio di anni fa.
>> Quindi questo era in realtà installato in Windows XP
su milioni di PC in tutto il mondo.
E questo era un file bitmap, BMP.
E un file bitmap, come vedrete prossimo settimana, significa semplicemente un modello di punti,
pixel come si chiamano, Una mappa in bit, davvero.
>> Così che cosa interessante, però, su questo formato di file, BMP, è
che sotto il cofano, ha più di soli tre byte
che compongono la sua intestazione, in modo a parlare, i primi morsi.
In realtà sembra un po ' complicato a prima vista.
E vedrete questo nel set P.
E ottenere qualcosa particolare da questa ora
non è così importante, in quanto solo il fatto che all'inizio di ogni bitmap
file, un formato grafico, c'è un sacco di numeri.
>> Ora Microsoft, il autore di questo formato,
tende a chiamare gli Le cose non interi e caratteri
e carri, ma le parole e le d parole e anela e byte.
Quindi sono solo diversi tipi di dati.
Sono nomi diversi per la stessa cosa.
Ma vedrai che in P Set Four.
>> Ma questo è solo per dire che se un umano doppio-clic qualche file BMP sul suo
o il suo hard disk, e una finestra si apre up che mostra lui o lei che l'immagine,
quello che è successo perché il funzionamento sistema presumibilmente notato non solo
l'estensione del file BMP nel nome del file,
ma anche il fatto che c'è una certa convenzione per il modello di bit
all'inizio di quel file bitmap.
>> Ma andiamo ora concentriamoci su un file complicata,
ma invece su qualcosa di simile.
Supponiamo qui in gedit, I basta avere gli inizi
di un programma che è abbastanza semplice.
Ho avuto qualche intende cima.
Ora ho #include "structs.h", ma Tornerò a che in un attimo.
Ma questo è utile per ora.
Quindi questo è un programma che sta per implementare
come database del registrar.
Quindi un database di studenti, e ogni studente nel mondo
ha un nome e una casa e, probabilmente, un po ' altre cose, ma noi terremo le cose semplici.
Ogni studente ha un nome e una casa.
>> Quindi, se volessi scrivere un programma il cui scopo nella vita
era solo per scorrere da zero, su un massimo di tre,
se ci sono tre studenti presso la Harvard University.
E voglio solo per ottenere, utilizzando GetString, il nome e la casa di ogni studente,
e poi basta stampare quelli fuori.
>> Questo è un po 'come Settimana One, Two Week roba adesso,
dove voglio solo una per loop o qualcosa del genere.
E voglio chiamare GetString alcuni tempi, e quindi stampare f un paio di volte.
Quindi, come potrei fare questo, però, quando sia un nome e una casa
sono coinvolti per ogni studente?
>> Quindi il mio primo istinto potrebbe essere quello di fare qualcosa di simile.
Potrei dire prima, bene, dammi, dire, un array di stringhe chiamati nomi.
E io non voglio un hardcode tre qui.
Cosa voglio mettere lì?
Così gli studenti, perché questo è solo una costante dichiarata in alto,
solo così io non devo hardcode tre in più luoghi.
In questo modo, posso cambiarlo un unico luogo, e colpisce un cambiamento in tutto il mondo.
E poi, potrei fare stringa ospita STUDENTI.
>> E ora, potrei fare qualcosa di simile for (int i = 0; i <STUDENTI, i ++.
Così sto scrivendo in fretta, ma questo è probabilmente sintassi familiare ora.
>> E ora, questo era più recente.
Se voglio mettere nel i-esimo il nome dello studente, penso che faccio questo.
E poi, non nomi ma case staffa I.
Lo faccio, GetString, e lasciare me tornare indietro e correggere questa linea.
Accetto?
Non sono d'accordo?
Non è molto user-friendly.
Io non ho detto che l'utente cosa fare.
>> Ma ora, se anche voluto in seguito, cerchiamo di
per esempio, stampare queste cose fuori-- così TODO tardi.
Ho intenzione di fare di più con Questa poi questo probabilmente IS
una corretta attuazione di ottenere i nomi e le case, tre
di loro totale di ciascuna, da un utente.
>> Ma questo non è molto buona progettazione, giusto?
Che cosa succede se uno studente non ha solo un nome e una casa, ma anche un numero ID,
e un numero telefonico, e un indirizzo e-mail,
e magari una home page, e forse un manico Twitter,
e qualsiasi numero di altri dettagli associata ad uno studente o una persona,
più in generale.
Come potremmo iniziare ad aggiungere funzionalità a questo programma?
>> Beh, mi sento come il modo più semplice potrebbe essere quello di fare qualcosa di simile, diciamo,
int IDS STUDENTI.
Così posso mettere tutti i loro ID in là.
E poi, per qualcosa come numeri di telefono,
Io non sono sicuro di come rappresentare quella appena ancora.
Quindi andiamo avanti e appena chiamata questo cinguetta STUDENTI, che
è un po 'strano, ma-- e un gruppo più campi.
>> Ho iniziato in modo efficace copia e incolla qui.
E questo sta andando a crescere abbastanza ingombrante abbastanza rapidamente, giusto?
Non sarebbe bello se ci fossero nel mondo noto una struttura dati
non come un int o una stringa, ma qualcosa livello superiore, una astrazione, così
a parlare, conosciuto come uno studente?
C non è venuto con built-in funzionalità per gli studenti,
ma cosa succede se volevo dargli tale?
>> Beh, si scopre, ho intenzione di aprire un file chiamato structs.h qui,
e si può fare esattamente questo.
E abbiamo intenzione di iniziare a farlo ora.
E sotto il cofano di P Set Tre, hai già fatto questo ora.
Non esiste una cosa come un g rect o un g ovale nel linguaggio di programmazione C.
>> Gente di Stanford attuate quelle tipi di dati utilizzando questo approccio qui,
dichiarando la propria nuova dati tipi utilizzando una nuova parola chiave
chiamato struct e un altro uno chiamato typedef.
Ed in effetti, anche se la sintassi sembra un po 'diverso da roba
abbiamo visto prima, in linea di principio, è super semplice.
>> Questo significa solo "definire un tipo."
Ciò sta andando essere un struttura, e una struttura
è come un contenitore per di più le cose.
E che la struttura sta avere una stringa chiamata nome,
e una stringa chiamato casa.
E chiamiamolo, solo per comodità, tutto questo studente struttura dati.
>> Quindi il momento si arriva a il punto e virgola, che hai ora
creato i propri dati tipo chiamato studente
che ora si affianca int, e float e char, e la stringa,
e g rect, e g ovale, e qualsiasi numero di altre cose che le persone hanno inventato.
>> Quindi cosa c'è di utile su questo ora è che se vado indietro
a struct 0 e finire questo implementazione, che ho scritto
in anticipo qui, notare che tutti del disordine inevitabile che
stava per cominciare accadendo come ho aggiunto numeri di telefono e cinguetta e tutti
queste altre cose a definizione di uno studente,
ora è succintamente avvolto come solo un array di studenti.
>> E ciascuno di quegli studenti ora ha diverse cose all'interno di esso.
In modo che lascia solo una domanda.
Come si ottiene nel nome, e la casa, e l'ID,
e quant'altro è all'interno dello studente?
Super semplice, pure.
Nuova sintassi, ma una semplice idea.
>> È sufficiente indice nella matrice, come abbiamo fatto la settimana scorsa e questa.
E qual è chiaramente il nuovo pezzo di sintassi?
Basta., Che significa "andare dentro l' la struttura e ottenere il campo chiamato
nome, ottenere il campo chiamato casa, ottenere il campo denominato studente ".
>> Quindi, in P Set Tre, se siete ancora lavorando su questo,
e la maggior parte delle persone ancora sono, rendersi conto che, come si
iniziare a utilizzare le cose come g rettangoli e ovali g
e altre cose che non sembrano provengono da Settimana Zero, uno, o due,
si rendono conto che questo è perché Stanford dichiarato alcuni nuovi tipi di dati.
>> E in effetti, questo è esattamente quello che faremo fare, come pure, in P Set Four, quando
cominciamo a che fare con le cose come le immagini, bitmap, e altro ancora.
Ecco, questo è solo un teaser e un modello mentale di ciò che è a venire.
Ora, ho procrastinato un po 'di questa mattina.
Ero un po 'curioso di vedere cosa la carta da parati Microsoft in realtà
sembra oggi.
E si scopre che qualcuno nel 2006 in realtà è andato a quasi esattamente
lo stesso posto per fotografare in realtà quello che sembra che questi giorni.
Il campo è ormai un po 'troppo cresciuto.
>> Così parlando adesso di immagini, cerchiamo di riportare Daven qui
sullo schermo e Nicola, e solo ricordare
che se vuoi unirti a noi per il pranzo questo Venerdì, la testa al nostro solito URL
Qui.
>> Allora, dove abbiamo lasciato fuori il Lunedi?
Abbiamo introdotto questo problema, giusto?
Questo è stato apparentemente un corretto implementazione di scambio,
per cui si prendere due interi, uno chiamato, uno chiamato b,
li scambiare, proprio come ha fatto Laura qui sul palco con il latte e l'acqua,
utilizzando un temporaneo variabile, o una tazza vuota,
in modo da poter mettere in un b e una in b senza fare un pasticcio di cose.
Abbiamo usato una variabile.
Si chiama temperatura.
>> Ma quello che era il fondamentale problema con questo codice il Lunedi?
Qual era il problema?
Già.
>> PUBBLICO: Ci vuole più spazio.
>> DAVID J. MALAN: occupa più spazio, perché sto usando una variabile,
e questo è OK.
Questo è vero, ma io sono andando a dire che è OK.
E 'solo 32 bit nella grande schema delle cose, quindi non è un grosso problema.
Altri pensieri?
PUBBLICO: Si scambia solo le variabili localmente.
DAVID J. MALAN: Esattamente.
Si scambia solo le variabili a livello locale.
Perché ogni volta che si chiama una function-- quando ho avuto i vassoi da Annenberg
l'ultima volta, avete principale sul fondo.
Non appena si chiama una funzione chiamata di scambio, di swap non ottiene x e y,
i valori originali.
Che cosa fa di swap get, abbiamo pretendiamo?
PUBBLICO: Copie.
DAVID J. MALAN: Quindi copia.
Così diventa uno e due, se si ricordare l'esempio dall'ultima volta,
ma una copia di uno e due che vengono scambiati con successo.
Ma purtroppo, alla fine, tali valori sono sempre gli stessi.
Così possiamo vedere questo con la nostra nuovo amico, si spera GDB,
che voi o il TF e Ca sono stato guidandovi verso come segue.
>> Quindi nessun richiamo di swap sembra like-- facciamo aprire questo-- simile a questa.
Abbiamo inizializzato x per uno, y per due.
Aveva un mucchio di stampa di f.
Ma poi, la chiamata chiave qui è stato quello di scambiare, che
è esattamente il codice che appena visto un momento fa.
Che è corretto in un primo momento sguardo, ma funzionale,
questo programma non funziona, perché non scambiare permanentemente xe y.
>> Quindi cerchiamo di vedere questo, un rapido caldo qui con GDB, un ./noswap.
Un mucchio di informazioni travolgente che Prendo eliminare con controllo L per ora.
E ora, ho intenzione di andare avanti ed eseguirlo.
E purtroppo, che Non era che utile.
Correva il programma all'interno di questo programma chiamato GDB, un debugger,
ma non mi ha lasciato curiosare.
>> Così come posso effettivamente mettere in pausa esecuzione all'interno di questo programma?
Così rompere.
E potrei rompere su qualsiasi numero, uno, 10, 15 linea.
Ma posso anche rompere simbolicamente dicendo pausa principale.
E che sta per impostare una pausa punto, a quanto pare in linea 16 in principale.
E dove è la linea 16?
Andiamo fino al codice e andare fino a noswap.
E in effetti, la linea 16 è il prima nel programma.
>> Così ora, se vado avanti e tipo eseguire questa volta, Enter, si fermò.
Quindi cerchiamo di curiosare.
Stampa X-- perché è x pari a zero?
E ignorare il simbolo del dollaro.
Questo è solo per amatore Utilizzo del programma.
Perché è x nulla in questo momento?
Già.
>> PUBBLICO: Si fermò proprio davanti linea 16, in realtà non in linea 16.
DAVID J. MALAN: Esattamente.
GDB, per impostazione predefinita, è in pausa esecuzione appena prima linea 16.
Così non è stato eseguito, che significa x è di qualche valore sconosciuto.
E siamo stati fortunati che è qualcosa di pulito come zero.
Così ora se digito il prossimo, ora eseguito 16.
Sta aspettando che io eseguo 17.
Lasciami andare avanti e stampa x.
E 'uno.
Lasciami andare avanti e di stampa y.
Cosa devo vedere ora?
>> PUBBLICO: [incomprensibile]
>> DAVID J. MALAN: Un po 'più forte.
>> PUBBLICO: [incomprensibile]
DAVID J. MALAN: Non proprio un consenso.
Quindi sì, vediamo un certo valore spazzatura.
Ora, y è 134514064 lì.
Beh, è ​​solo un valore spazzatura.
Il mio programma utilizza RAM per scopi diversi.
Ci sono altre funzioni.
Altre persone hanno scritto dentro il mio computer.
Quindi i bit sono stati utilizzati per altri valori, e quello che sto vedendo
è i resti di alcuni uso precedente di quella memoria.
>> Quindi un grosso problema, perché appena mentre sto scrivendo il prossimo e quindi stampare y,
è inizializzato a il valore che voglio.
Così ora, andiamo avanti un po 'più veloce.
N per il prossimo.
Facciamolo di nuovo.
Ma io non voglio colpire qui, perché se io
voglio vedere cosa sta succedendo all'interno di scambio, qual è il comando?
>> PUBBLICO: passaggi.
>> DAVID J. MALAN: passaggi.
Quindi questo mi passi in un funzione, piuttosto che su di esso.
E ora, è un po 'criptico onestamente, ma questo è solo
mi dice che sono in linea 33 ora.
E facciamolo di nuovo.
Stampa temperatura.
Valore Garbage, negativo questa volta, ma questo è solo ancora un valore spazzatura.
Allora, facciamo il prossimo, temp stampa.
E 'inizializzato a 1, che era il valore di x, aka a.
>> Ora, dove sono la A e X provenienti da?
Beh, notiamo in principale, abbiamo chiamato questi valori x e y.
Siamo poi passati loro di scambiare come segue.
X è venuto prima, comma a.
E poi, di swap potrebbe chiamarli x e y.
Ma per chiarezza, è chiamandoli a e b.
Ma a e b sono ora in corso per essere copie di xey, rispettivamente.
>> Quindi, se torno a GDB, temp è ora uno e ora è uno.
Ma se lo faccio dopo e ora fare stampare una, una è già stato spostato.
Il latte è stato versato nella ex bicchiere di succo d'arancia, o viceversa.
>> E se lo faccio la prossima volta, e ora se stampo come un controllo di integrità,
una è ancora due, ma b è ora uno.
Francamente, è ancora lì.
Non mi interessa quello che temp è.
Ma appena ho ora Tipo, diciamo, Continuo a tornare indietro, ora sono alla fine
il programma.
E purtroppo, x è ancora uno e y è ancora due.
>> Allora, qual era l'utilità del GDB lì?
E non ha aiutato me fix il problema di per sé,
ma speriamo mi aiuti capire realizzando
che sì, la mia logica è giusta, ma il mio codice non è in ultima analisi, avendo
un impatto permanente.
Ecco, questo è un problema che siamo andando a risolvere ora di oggi.
>> Ma veniamo lì per mezzo di questo.
String è una menzogna.
Essa, inoltre, non un tipo di dati che esiste in C. E '
sinonimo per alcuni tempo per qualcos'altro,
e possiamo rivelare che, come segue.
>> Lasciami andare avanti e apro un programma chiamato confrontare-0.
E piuttosto che scrivere questo fuori, inizieremo a camminare attraverso il codice
Ho già scritto, ma è solo poche righe.
Quindi questo è confrontare-0.
E la prima cosa che sto facendo è sempre una riga di testo.
>> Ma accorgo di quello che sto facendo per la prima volta.
Che cosa è diverso chiaramente sulla linea 21?
In realtà, aspetta un minuto.
Questa è la copia di due.
Che non è nemmeno il programma giusto.
Va bene, spoiler alert.
Va bene, quindi non importa che.
Questa è la risposta ad una futura domanda.
>> Qui si confronta-0, e sono per cominciare una riga di testo.
Programma di molto più semplice.
Quindi questo è semplice.
Questo è come la Settimana One, Two Week roba al momento. string s = GetString.
Ora, lo dico di nuovo qui.
stringa t = GetString.
E poi, l'ultima cosa in questo programma, come suggerisce il nome,
è ho intenzione di provare a confrontarli.
>> Così se s, la prima stringa, uguale = t, allora sono
per dire si digita la stessa cosa.
Altrimenti, ho intenzione di dire si digita cose diverse.
Quindi cerchiamo di compilare ed eseguire il programma.
Quindi, fare confrontare zero.
Sembra buono.
Nessun errore di compilazione.
>> Lasciami andare avanti ora e digitare ./compare-0.
Lasciami andare avanti e dire qualcosa : Daven e qualcosa: Rob.
E scrivo cose diverse.
Fin qui tutto bene.
Programma sembra essere corretta.
>> Ma corriamo di nuovo.
Dire qualcosa: Gabe.
Bene.
Forse mi ha colpito la barra spaziatrice o qualcosa del genere funky.
Facciamolo di nuovo.
Così Zamyla.
Zamyla.
Cose diverse.
Così che cosa sta succedendo?
>> Quindi abbiamo queste due linee di codice, GetString chiamato due volte.
E poi, io sono semplicemente cercando di confrontare s e t.
Ma ciò che realmente poi sta succedendo?
Beh, in merito alla mia calligrafia macellare questo esempio un po '.
E diciamo effettivamente gettare questo fino qui, pure.
>> Quindi abbiamo una linea simile string s = GetString.
Ecco, questo è semplicemente il primo interessante linea da quel programma.
Ma ciò che è stato tutto questo tempo succedendo sotto il cofano?
Beh, sul-lato sinistro è stringa, che è un certo tipo di variabile,
e si chiama s.
Quindi so che questo sta usando memoria, o RAM, nel mio computer in qualche modo.
Quindi ho intenzione di astrattamente disegnare che come un quadrato.
32 bit, si scopre, ma più in futuro.
E allora, che cosa sta succedendo qui?
>> Beh, ovviamente GetString Ottiene una stringa dall'utente.
E GetString ottenuto Zamyla o Gabe o Daven.
Quindi cerchiamo di scegliere il primo di quelli, che era Daven.
Così efficace, cosa GetString ottenuto me in quel primo caso era D-a-v-e-n.
E poi, che altro ha fatto mi dà di nascosto?
PUBBLICO: [incomprensibile]
DAVID J. MALAN: Sì, il carattere / 0 o nullo.
Così effettivamente mi ha dato una stringa.
Ma sappiamo già da precedente sembra che una stringa è semplicemente un array
di caratteri, ed è terminato da questo speciale carattere sentinella, / 0.
>> Ma se questo è vero e questo è un quadrato,
questo è chiaramente un rettangolo molto più grande.
E in effetti, questo è, Io rivendico, solo 32 bit.
E questo è chiaramente più di 32 bit, perché questo è probabilmente
otto più otto più otto più otto più otto,
solo a causa di byte in ASCII.
Come diavolo stiamo andando per adattarsi Daven in questa piccola scatola qui?
>> Ebbene, ciò che è GetString effettivamente facendo?
Beh, questa griglia qui rappresenta memoria del mio computer o RAM.
Quindi cerchiamo di arbitrariamente dire che se ciascuno di questi rappresenta un byte,
allora possiamo pensare di ogni byte come avere un indirizzo,
come 33 Oxford Street, o 34 Oxford Street, o 35 Oxford Street.
>> Quindi, proprio come le case dispongono di indirizzi e gli edifici hanno indirizzi,
così fanno i singoli byte di memoria hanno indirizzi o numeri
che li identificano in modo univoco.
Ora, questo è arbitrario.
Ma per mantenere le cose semplici, ho intenzione di utilizzare esadecimale solo per convenzione,
ma la 0x significa altro che "questo è esadecimale."
e ho intenzione di affermare che la "D" finisce a Byte One in memoria.
>> Non ho niente altro in corso in memoria, in modo da Daven ottenuto il primo posto
a Byte One.
Questo, quindi, sta per essere 0x2.
Questo sta per 0x3.
Questo sta per essere 0x4.
Questo sta per 0x5.
Questo sta per essere 0x6.
>> Ma una volta che iniziare a pensare su ciò che fatto dal computer
sotto la cappa, si può iniziare a dedurre
come, qualche anno fa, sarebbe hanno attuato C sé.
Che cosa è GetString probabilmente returning-- perché
si sente come non è ritorno Daven, di per sé,
perché non è certo andando per adattarsi in questo piccolo box--
Così che cosa è GetString probabilmente tornando?
>> PUBBLICO: [incomprensibile]
>> DAVID J. MALAN: La posizione di Daven.
Ed è fatto questo da allora Week One.
Quello che è veramente GetString il ritorno non è una stringa, di per sé.
Questa è una delle piccole bugie bianche.
È restituendo l'indirizzo del stringa in memoria, l'indirizzo univoco.
Daven vive a 33 Oxford Street.
Ma più succintamente, Gavin vive a 0x1, Indirizzo Numero Uno.
>> Così che cosa viene messo in questo piccola scatola poi, per intenderci,
è solo l'indirizzo di quella stringa.
Quindi tutto questo tempo, questo è andata avanti.
Ma ciò che questo suggerisce ora è che se tutti S ha
è un numero all'interno di esso, che è di fermarti, il programmatore,
dal mettere qualsiasi numero in qualsiasi variabile e proprio salto
a quel pezzo di memoria?
E infatti, vedremo che è una minaccia prossima volta.
>> Ma per ora, questo si sente insufficiente.
Se dico, farmi una stringa, tu mi dai Daven.
Ma in realtà non mi dai Daven.
Tutto mi dai è l'indirizzo di Daven.
Come faccio poi so per certo Daven dove inizia e ends--
la storia di sempre weird-- Daven dove inizia e finisce,
quindi, la successiva stringa in memoria inizia?
>> Beh, se si sta consegnando me l'inizio di Daven,
in sostanza, come faccio a sapere dove alla fine del suo nome è?
Questo speciale carattere null, che è tanto più importante ora
se le stringhe sotto il cappuccio sono semplicemente identificati
unicamente dalla loro posizione nella memoria.
Quindi tutto questo tempo, che è cosa sta succedendo su.
>> Così, quando guardiamo ora il codice qui, spiegare
se si farebbe il bug in linea 26.
Perché Zamyla e Zamyla diverso?
Perché Gabe e Gabe diverso?
Sì, in indietro.
>> PUBBLICO: Hanno indirizzi diversi.
>> DAVID J. MALAN: Semplicemente perché hanno indirizzi diversi.
Perché quando si chiama GetString ancora una volta, che io farò in fretta qui,
se questa è la seconda linea, corda t, come ho fatto in quel programma,
equivale un'altra chiamata a GetString.
La prossima volta che chiamo GetString, io vado
per ottenere un diverso pezzo di memoria.
>> GetString è consentito di chiedere al funzionamento
sistema per ulteriori e più memoria.
Non sta andando a riutilizzare lo stesso sei byte ogni singola volta.
E 'intenzione di ottenere un nuovo pezzo di memoria, che
significa t sta per arrivare un altro valore qui.
>> Così, quando faccio s uguale = t, non stai confrontando
D contro questo e contro A questo e V contro questo.
Stai confrontando questo contro questa, che
francamente è abbastanza useless-- useful-- è abbastanza inutile, perché chi veramente
se ne frega dove le stringhe sono nella memoria?
>> E infatti, noi non abbiamo.
E non stiamo andando a avviare particolarmente attento.
Solo nella misura in cui i bug possono sorgere e le minacce alla sicurezza possono sorgere volontà
abbiamo effettivamente iniziare a preoccuparsi di questo.
Quindi cerchiamo di risolvere questo problema.
Risulta, a risolvere il problema semplicemente eccellente.
>> E andiamo in realtà, prima di rivelano che ancora una volta, che cosa sarebbe
fate se in una classe CS50, e si doveva implementare
un confronto con due stringhe.
È chiaro che non si può semplicemente usare s è uguale a = t.
Ma logicamente, come vuoi confrontare questa stringa
contro questa stringa utilizzando il codice C?
Già.
>> PUBBLICO: Basta fare il per il ciclo [incomprensibile]
DAVID J. MALAN: Perfetto.
PUBBLICO: [incomprensibile]
DAVID J. MALAN: Già.
Basta usare un ciclo for o di una while o qualsiasi altra cosa.
Ma basta applicare l'idea di base che se questo è un pezzo di memoria o un array
e questo è, un'iterazione su entrambi allo stesso tempo.
E basta confrontare le lettere.
>> E devi essere un poco attenti, perché si
non vogliono un dito andare oltre l'altra
perché una stringa è più lunga dell'altra.
Così si sta andando a voler verificare per questo valore speciale alla fine, nullo.
Ma è realmente, nella fine, così semplice.
E, francamente, non abbiamo bisogno di di reinventare quella ruota.
Ecco Version Two.
E quello che sto per dire qui è che invece di confrontare s è uguale a = t,
Io invece vado a dire, se la stringa confronto di s virgola t è uguale a = 0.
Ora, ciò che si stringa confrontare?
>> Si scopre, è una funzione che viene fornito con C, il cui scopo nella vita
è quello di confrontare due stringhe.
E mescolare confrontare, se leggiamo la sua pagina o documentazione o CS50 uomo
riferimento, sarà semplicemente dirvi che stir
confrontare i rendimenti sia un negativo numero o un numero positivo o pari a zero,
dove lo zero indica che sono uguali.
>> Quindi, solo congetture.
Che cosa potrebbe significare se mescolate rendimenti confrontare
valore negativo o un valore positivo?
PUBBLICO: Maggiore o meno.
DAVID J. MALAN: Sì, superiore o inferiore.
Quindi, se si vuole ordinare un intero mazzo di stringhe in un dictionary--
come ci sarà finalmente giù strada-- funzione perfetta da utilizzare potenzialmente,
perché sta andando a farlo confronto di stringhe per voi, e dire
si fa una viene prima di b, o fa b venire prima di un ordine alfabetico.
Possiamo fare esattamente questo.
>> E notate che ho fatto un altro cosa in questo esempio.
Cos'altro è cambiato più alto in questa funzione principale?
Char *.
E questa è l'altra bugia bianca.
Per tutto questo tempo, quando hai state scrivendo stringa,
siamo stati segretamente riscrivendo stringa char * in modo che clang realtà
si capisce.
>> In altre parole, in CS50.h e come ci vediamo alla fine,
abbiamo fatto una stringa sinonimo chiamato che è la stessa cosa di char *.
E per ora, so solo che il *, In questo contesto, almeno,
indica l'indirizzo.
>> L'indirizzo di cosa?
Beh, il fatto che ho detto char *, e non int * o * float,
significa che char * è l'indirizzo di un char.
Così questa piccola scatola qui, aka stringa, è in realtà di tipo char *,
che è semplicemente un modo elegante per dire, in questa casella andrà un indirizzo.
E cosa che indirizzo si riferisce a?
A quanto pare, un char.
>> Ma potremmo assolutamente hanno int * e altre cose.
Ma per ora, char * è davvero il più semplice e uno di interesse.
Quindi questo problema sta a salire, però, di nuovo.
>> Supponiamo che io apro questo programma.
Vediamo se ora siamo in grado di prevedere cosa c'è di sbagliato in questo codice.
Quindi, in questo programma, copia-0, sono intenzione di andare avanti e di nuovo chiamare
GetString e memorizzare il valore in s.
>> E allora, perché sto facendo questo, proprio come un richiamo da settimane passato?
Abbiamo fatto dire che GetString a volte restituisce null.
Cosa significa se GetString restituisce null?
Qualcosa è andato storto.
Probabilmente significa che la corda è troppo grande, il computer di memoria.
Succede super, super, super raramente, ma potrebbe succedere.
Vogliamo verificare la presenza di esso, e questo è tutto quello che stiamo facendo.
>> Perché vedremo ora, se non lo fai avviare il controllo abitualmente per le cose
come null, si potrebbe effettivamente iniziare ad andare
agli indirizzi di memoria che non sono validi.
E si sta andando ad avviare indurre sempre più difetti di segmentazione.
O in un Mac o un PC, basta causando un blocco del computer
o un programma per congelare, potenzialmente.
>> Così ora, rivendico in copia-0.c, che io sto andando a copiare queste stringhe in via
della linea 28.
E poi, io vado la rivendicazione sul fondo
qui che sto andando cambiare uno di loro.
>> Quindi notare questo.
Sto chiamando il nostro vecchio amico strlen.
E proprio spiegare in inglese cosa questa linea 34 sta facendo?
Che cosa fa t staffa 0 rappresentare sulla sinistra.
Già.
>> PUBBLICO: Primo carattere di t?
DAVID J. MALAN: Primo carattere di t.
Questo è tutto.
Primo carattere di t, voglio per assegnare la versione maiuscola
del primo carattere in t.
Quindi questo sta capitalizzando la prima lettera.
E poi, l'ultima cosa che faccio in questo programma è sostengo qui è
l'originale, s, ed ecco la copia, t.
>> Ma basato sulla storia che abbiamo appena raccontato ciò che le stringhe sono realmente,
ciò che è davvero la linea 28 fare, e ciò che è
il bug risultante in corso di essere sullo schermo?
>> Quindi, prima, la prima domanda, 28.
Che cosa è la stringa t = s davvero facendo?
Se abbiamo in-mano sinistra lato qui stringa t = s;
che mi dà una scatola qui e una scatola qui.
E supponiamo che questo indirizzo è 0x, diciamo, 50 questa volta, arbitrariamente.
Cosa stringa t = s fare sotto il cofano?
>> PUBBLICO: [incomprensibile]
>> DAVID J. MALAN: Memorizza la memoria affrontare lì, quindi 0x50 va là.
Quindi, se ora, vado alla prima carattere in maiuscolo e t esso,
cosa sto effettivamente facendo per s?
Sto davvero facendo la stessa cosa, giusto?
Perché se 0x50-- Indirizzo e giusto, io non hanno molto spazio sulla scheda di qui,
ma per scontato che questo sia 0x50 quaggiù, da qualche parte nella memoria del mio computer.
>> E ho, per esempio, Gabe in minuscolo qui, come questo.
E ho detto staffa t 0 ottiene capitalizzati.
Beh, t staffa 0 è la prima lettera t.
Così poco g sta per diventare grande G. Ma il problema
è, ciò che s anche il punto di?
>> PUBBLICO: Lo stesso.
>> DAVID J. MALAN: La stessa cosa esatta.
Quindi una semplice spiegazione, forse, anche se la sintassi è un po 'strano.
Quindi cerchiamo di fare questo.
Fai copia-0 e poi ./copy-0.
Dire qualcosa: Gabe.
E purtroppo, entrambi loro ora sono stati capitalizzati,
ma per quella sottostante ragione che siamo semplicemente
ora si tratta di indirizzi.
>> Quindi, come si comincia a address-- no pun intended--
come possiamo cominciare ad affrontare questo particolare problema?
Beh, in copy1.c, le cose stanno andando per ottenere un po 'più complicato.
Ma vorrei rivendicare un soluzione concettualmente semplice.
>> Così difficile da ottenere a prima vista.
Non sarà facile per la prima volta che si digita fuori, forse,
ma se il problema è che semplicemente facendo t = s solo
copia l'indirizzo, cosa, ancora se posso prendere su di te,
sta per essere la soluzione per realtà la copia di una stringa?
>> PUBBLICO: noi probabilmente utilizzare nuovamente un ciclo.
>> DAVID J. MALAN: Già.
Quindi stiamo andando ad avere bisogno di nuovo un ciclo.
E perché se vogliamo copiare una stringa s in un'altra stringa,
probabilmente vogliamo farlo carattere per carattere.
Ma il problema è, se questo è di origine s,
ora abbiamo bisogno di cominciare in modo esplicito allocazione di memoria per t.
>> In altre parole, cerchiamo di ridisegnare per l'ultima volta.
Se questa è la stringa s = GetString.
E mettiamo questo qui, pure.
Questo è GetString.
E poi, l'immagine di qualcosa come che sta per essere come prima,
g-a-b-e-/ 0.
Che sembra un po 'di qualcosa come questo.
E s quindi, noi chiamiamo questo 0x50, e che sta per essere 51, 52.
>> Quindi questo è 0x50.
E poi, io faccio stringa t.
In memoria, che sta solo andando a dammi un po 'quadrato come questo.
Allora qual è il passo fondamentale adesso?
Se voglio copiare s in t, ciò che blank abbiamo bisogno di compilare qui?
O che cosa abbiamo bisogno per fare ad alto livello?
Sì?
Qualcuno?
Già.
>> PUBBLICO: Abbiamo bisogno di [incomprensibile].
DAVID J. MALAN: Sì, abbiamo necessario compilare in questo vuoto.
Non riesco a copiare e poi capitalizzare il nome di Gabe
fino Chiedo il sistema operativo per un altro pezzo di memoria
che è almeno altrettanto grande come l'originale.
In modo che ci lascia con una domanda.
>> Come faccio a chiedere il sistema operativo non solo per un semplice piccolo pointer--
come questo è chiamato, un indirizzo, un non pointer--
per una semplice piccola scatola come questo chiamato una stringa?
Come faccio a chiedere il funzionamento sistema per una grossa fetta di memoria?
Finora, ho ottenuto solo che indietro indirettamente chiamando GetString.
Così come è GetString anche ottenere la sua memoria?
>> Beh, si scopre che non c'è questa altra funzione qui
che ora inizieremo ad usare.
Ora, questo sembra than-- modo più criptico e io sono l'unico che può vedere it--
questa linea sembra molto più criptico poi dovrebbe a prima vista.
Ma cerchiamo di prendere in giro a parte.
>> Sul lato sinistro, ho char * t.
Quindi, in inglese, cominciamo a formulare frasi appropriate in gergo tecnico.
Quindi questo è l'allocazione di un variabile di tipo char * chiamato t.
Ora, che cosa significa in realtà?
>> Bene, questo significa, che cosa sono io che vado di mettere in questa variabile chiamata t?
Un indirizzo di un char.
Ecco, questo è solo il più semplice, modo più ragionevole
di descrivere il lato sinistro.
Così che crea questa casella qui solo.
Quindi il lato destro, presumibilmente, sta andando
di destinare tale grande pezzo di memoria come?
Quindi cerchiamo di prendere in giro questa parte.
>> E 'sconvolgente a prima vista, ma cosa sta succedendo qui dentro?
In primo luogo, c'è malloc, che è apparentemente il nostro nuovo amico,
"Memoria allocare."
Quindi questo è l'argomento di essere passati in esso, quindi è una bella grande argomento.
Quindi cerchiamo di prendere in giro questa parte.
>> strlen di s, naturalmente, rappresenta the--
PUBBLICO: Il numero di caratteri.
DAVID J. MALAN: Solo il numero di caratteri in s.
Quindi la lunghezza s, la stringa originale.
Quindi G-a-b-e.
Quindi è probabilmente quattro in questo caso.
Perché sto facendo uno dopo chiamando strlen di s?
PUBBLICO: [incomprensibile]
DAVID J. MALAN: Per questo speciale carattere null.
Se mi chiedete qual è la lunghezza di Il nome di Gabe, vado a dire quattro.
Sotto il cofano, però, ho bisogno di che il quinto byte per il carattere null.
Ecco perché sto facendo il +1.
>> Ora, nel caso in cui si esegue questa programma su un computer diverso, diciamo,
l'apparecchio CS50, in cui la dimensione di un char
potrebbe essere diverso dalla mia computer--
Risulta che posso chiamare questo sizeof operatore, basta chiedere al computer,
quali sono le dimensioni di un char su questo computer?
>> E moltiplicando cinque in questo esempio la dimensione di un carattere, che
sulla maggior parte dei computer sarà essere solo uno, malloc
sta per allocare per me questo grande pezzo di memoria qui a destra.
E sta andando a return-- è un function-- quindi è
intenzione di tornare a me che cosa?
PUBBLICO: L'indirizzo?
DAVID J. MALAN: l'indirizzo di cosa?
PUBBLICO: della memoria è allocata?
DAVID J. MALAN: Del la memoria è allocata.
Quindi non ho idea, francamente, dove questo sta per finire.
Ho intenzione di proporre che sta andando a finire a 0x88.
Completamente arbitrario, ma altrove rispetto 0x50,
perché il sistema operativo, cosa Windows e Mac OS fanno per me, è
assicurarsi che sta dando Mi diversi pezzi di RAM.
>> Quindi questo è il valore in cui questo pezzo di memoria potrebbe finire.
Quindi questo è quello che finisce qui, 0x88.
Così ora chiaramente, posso capire che questo non è lo stesso di questo,
perché sono che punta a diversi blocchi di memoria.
Quindi, se io ora effettivamente voglio copiare questo in, facciamo la soluzione proposta.
>> Andiamo, creare un ciclo for, e fare la staffa t i s ottiene staffa i.
Perché ora posso usare questa notazione array-like,
perché anche se malloc molto genericamente mi alloca memoria,
memoria è solo byte contigui.
Byte, byte, byte, back to back to back.
>> Posso sicuramente come programmatore trattarlo come un array, che
significa che posso usare questo finalmente familiare notazione di solo alcuni parentesi quadre.
>> Quindi lasciatemi pausa lì, perché questo è un sacco tutto in una volta, anche
se l'idea di base di ricapitolare è che stringa, tutto questo tempo,
Non è un nuovo tipo di dati di per sé.
E 'solo un cosiddetto puntatore, l'indirizzo di un personaggio,
il che significa semplicemente che è un numero che per convenzione umana
tendiamo a scrivere come 0x qualcosa.
>> Ma è solo un numero, come 33 Oxford Street,
che sembra essere il Indirizzo di CS dell'edificio.
Hai domande su questi dettagli?
Sì?
>> PUBBLICO: Perché controlliamo per t uguale a null?
>> DAVID J. MALAN: Perché noi verificare la presenza di t uguale a null?
Se leggiamo la documentation-- grande interrogo per malloc,
sta andando a dire in stampa fine, a volte malloc potrebbe restituire null,
proprio come GetString.
E infatti, GetString restituisce null se, a sua volta, malloc restituisce null,
perché GetString utilizza malloc.
>> E che potrebbe accadere se il sistema operativo, Mac OS, Windows, qualunque sia, è semplicemente
di memoria per voi.
Ecco, questo è quello che è successo lì.
>> E mi permetta di rivelare un'altra cosa che potrebbe solo saltare la vostra mente
o completamente essere troppo lontano oltre la linea.
Ma mi permetta di tirare il stesso ciclo for per la copia,
che un momento fa, il richiamo era questo. staffa t i s ottiene staffa i.
>> Bello e facile da usare.
Sembra Week Two di nuovo.
Ma questa versione in realtà può essere riscritto come questo, che sembra criptico.
Si tratta di un puntatore tecnica chiamata aritmetica, indirizzo aritmetica.
Ma perché fa questo lavoro?
>> Ora fastidiosamente, il autori di C ha deciso di utilizzare
il simbolo * per scopi diversi.
Abbiamo visto in passato già una volta, char *, che significa "dammi una variabile
che sta per contenere l'indirizzo di un carattere. "
* Così char in quel contesto significa "dammi una variabile."
>> Purtroppo, se si utilizza il *, senza una parola di fronte ad esso, come char,
è ora chiamato il operatore dereference.
E vedremo più di questa prima lunga.
Ma significa solo "andare lì."
E 'come dire, se qualcuno mi porse su un pezzo di carta "33 Oxford Street,"
se faccio "* 33 Oxford Street," che significa "Andare giù per la strada per la costruzione CS."
>> Quindi * significa semplicemente andare lì se non c'è nessuna parola di fronte ad essa.
Così che cosa è t, per essere chiari?
t è l'indirizzo del blocco di memoria che è stato dato a me.
s è l'indirizzo di quello che, per intenderci, nell'esempio di cui abbiamo discusso,
di Gabe minuscolo?
s è l'indirizzo di--
PUBBLICO: La stringa.
DAVID J. MALAN: Di nome originale di Gabe.
Quindi è l'indirizzo del questo pezzo di memoria.
Quindi, se io dico t + i-- i, comunicazione, è solo il nostro vecchio amico.
E 'solo una variabile indice che è l'iterazione da zero in su
alla lunghezza della stringa s.
Quindi sarà pari a zero, poi uno, poi due, poi tre, poi quattro.
Quindi cerchiamo di montare questi nuovi Pezzi del puzzle Scratch-come, se si vuole,
anche se, di nuovo, la sintassi è molto più arcana di Scratch.
Quindi t è un indirizzo + i è andando a dare me
un numero, perché questi sono tutti numeri che abbiamo disegno come esadecimale.
Ma sono solo numeri.
>> Quindi, se l'indirizzo di t abbiamo detto era 0x88, 0x88 che cosa è più zero.
Anche se non stai bene con ancora un hex, prendere una supposizione.
>> PUBBLICO: L'originale.
>> DAVID J. MALAN: Still 0x88.
Così che cosa * 0x88 significa?
Significa, "andare là", che significa efficace, "mettere il dito qui."
E ora sul lato destro della questa espressione, * e poi in parentesi,
s + i significa s, che rappresenta l' indirizzare fino qui del piccolo g.
s + 0 è, naturalmente, s, qualunque s è.
>> Così adesso, è s *, che proprio come * 33 Oxford Street significa andare all'indirizzo
s.
Quindi, ecco questo dito, mano destra.
Così che cosa sto andando a copiare in che cosa?
La cosa sulla destra, che è Gabe, poco g qui, in questa sede.
>> E così l'effetto di tale prima iterazione del ciclo,
come avete proposto, anche se sembra pazzo più complicato di qualsiasi cosa
abbiamo visto prima, è semplicemente dicendo andate qui e copiare quel personaggio qui.
Ti sta dando una mappa per entrambe le posizioni.
>> E vedremo molto più di questo.
Ma per ora, la speranza è solo quello di introdurre alcune di queste idee di base.
E infatti, diamo un'occhiata a un programma definitivo qui,
e poi la claymation promesso, che renderà tutto bene.
Bene.
Così mi permetta di aprire up-- ci andiamo.
Quindi cerchiamo me-- ci torneremo a questo quadro poco tempo.
Permettetemi di aprire questo ultimo esempio qui.
>> Così qui è un super, super programma che compie
niente nella vita che fa quanto segue.
E prima dichiara due variabili, x e y, che non sono numeri questa volta,
per sé.
Non sono numeri interi, di per sé.
Essi sono apparentemente int *.
Così chiunque, cosa significa se il tipo di dati, la variabile,
è di tipo int * stelle?
Questo è l'indirizzo di un int.
>> Quindi non ho idea di dove si trova ancora.
Significa solo "mettere, alla fine, l'indirizzo di un int qui. "
0x50, 0x88, ovunque esso si trovi memoria, un indirizzo è andare lì.
Ed è quello che y è andando essere, pure.
>> Se io ora dico x = malloc (sizeof (int)), questo è un modo elegante per dire,
hey sistema operativo, tramite malloc, dammi memoria sufficiente per la dimensione
di un int, che è probabilmente sta per essere a 32 bit o quattro byte.
>> Così che cosa fa tornare malloc?
Malloc restituisce un indirizzo.
Allora, cosa sta per ottenere memorizzato in x?
L'indirizzo del pezzo di memoria, i quattro byte, che malloc
appena trovato per me chiedendo il sistema operativo.
>> Ora nel frattempo, la linea quattro qui, il * x = 42.
Giusto per essere chiari, cosa sta succedendo laggiù?
Sul lato sinistro, * x.
che è come * 33 Oxford Street.
Così * x cosa significa?
>> PUBBLICO: Vai a.
>> DAVID J. MALAN: Vai a questo indirizzo.
Ovunque quel pezzo di memoria è, andare a esso.
E mettere quello che c'è, ovviamente?
PUBBLICO: 42.
DAVID J. MALAN: 42.
Va bene, * y, stessa idea.
Vai all'indirizzo in y.
Mettere il numero 13 lì, ma ciò che è y in questo momento?
PUBBLICO: Non c'è memoria per y.
DAVID J. MALAN: Ci non è memoria per y.
Così che cosa y fa probabilmente contengono, come stiamo dicendo?
>> PUBBLICO: Garbage.
>> DAVID J. MALAN: Alcuni valore spazzatura.
Ora, il valore spazzatura è ancora un numero.
Si può ancora essere scambiato per un indirizzo.
E 'come se qualcuno scarabocchiato qualcosa verso il basso,
e ho interpretato male come significato qualche edificio in fondo alla strada.
E se si tenta di andare in qualche edificio non si possiede,
o qualche pezzo di memoria che non hai stata data, le cose brutte possono accadere.
Computer potrebbe bloccarsi, o qualche altro comportamento indeterminato potrebbe accadere.
>> Così l'intro, poi, a Binky è questo.
Ricordo ancora, 20 alcuni anni dispari dopo,
dove ero quando ho finalmente capito puntatori.
>> Vale a dire, se si lasciare qui in tre minuti
e credo che non lo faccio capire i puntatori, realizzare
Ho ricordato per 20 anni per qualche ragione pazzo
quando e perché finalmente affondato in, seduto con il mio insegnamento
compagno, Nishat Mehta nel indietro di Eliot Dining Hall.
Ora, ho ricordato questo perché questo era
uno dei temi che, in particolare, lottato con.
E poi, finalmente cliccato, come oserei dire un sacco di argomenti
alla fine sarà.
E ora, per fare che sentire tutto il più felice e ancor più convincente,
diamo uno sguardo finale del nostro ultimi tre minuti qui a Binky,
dal nostro amico, Nick Parlante da Stanford.
>> [RIPRODUZIONE VIDEO]
>> Ehi, Binky.
Svegliati!
E 'tempo di puntatore divertimento.
>> -Che È?
Ulteriori informazioni su puntatori?
Oh, goody!
>> Be ', per iniziare, direi che siamo andando a bisogno di un paio di puntatori.
>> -OK.
Questo codice assegna due puntatori, che può puntare a numeri interi.
-OK.
Beh, vedo i due puntatori, ma non sembrano essere che punta a nulla.
>> -Che È di destra.
Inizialmente, puntatori non puntare a nulla.
Le cose a cui puntano sono chiamati pointees, e la loro istituzione del
una fase separata.
>> Oh, giusto, giusto.
Sapevo che.
I pointees sono separati.
Er, così come si fa assegnare una pointee?
>> -OK.
Beh, questo codice alloca un nuovo pointee intero,
e questo set parte x per puntare ad esso.
>> Ehi, che sembra meglio.
Così fanno fare qualcosa.
>> -OK.
Io dereference il puntatore x a memorizzare il numero 42 nella sua pointee.
Per questo trucco, ho bisogno il mio Bacchetta magica di Dereferencing.
>> -Il Bacchetta magica di Dereferenziare?
Che-- che è grande.
>> -Questo È ciò che il codice è simile.
Mi limiterò a impostare il numero, e [POP]
>> Ehi, guarda.
Ci va.
>> -Quindi Facendo un dereference su x segue la freccia per accedere sua pointee.
In questo caso, un negozio di 42 in là.
Hey provare a utilizzare per memorizzare il numero 13 attraverso l'altro puntatore, y.
>> -OK.
Ti basta andare qui per y, e ottenere il numero 13 set up.
E poi, prendere la Bacchetta di Dereferenziare e proprio [BUZZ]
>> Oh!
>> Oh, hey!
Che non ha funzionato.
Dite, Binky, non credo dereferencing y è una buona idea, perché si sa,
impostazione della pointee è una fase separata.
E non credo che abbiamo mai fatto.
>> Punto -Buona.
-Già.
Abbiamo assegnato il puntatore y, ma noi mai impostarlo per puntare a un pointee.
>> -Molto Attento.
Ehi, stai guardando bene lì, Binky.
Riesci a risolvere il problema in modo che i punti y allo stesso pointee come x?
>> -Certo.
Userò la mia bacchetta magica Assegnazione di Pointer.
>> -È Che sta per essere un problema come prima?
-No.
Questo non tocca i pointees.
Si cambia solo un puntatore a indicare la stessa cosa di un altro.
>> Oh, vedo.
Ora y punti allo stesso posto come x.
Quindi aspettare.
Ora, y è fissa.
Ha un pointee.
Così si può provare la Bacchetta di Dereferenziare nuovamente di inviare il 13 sopra.
>> -Uh, OK.
Qui si va. [POP]
>> Ehi, guarda che.
Ora dereferencing opere su y.
E poiché i puntatori sono la condivisione che uno pointee, entrambi vedono il 13.
-Già.
Condivisione, qualunque sia.
Quindi stiamo andando a cambiare posti ora?
>> Oh, guarda.
Siamo fuori tempo.
>> -But--
>> -Basta Ricordare le tre regole puntatore.
Numero Uno, la struttura di base è che avete un puntatore,
e che punti verso un pointee.
Ma il puntatore e pointee sono separati,
e l'errore comune è quello di creare un puntatore,
ma a dimenticare di dare un pointee.
>> Numero Due, puntatore dereferenziazione inizia in corrispondenza del puntatore
e segue la sua freccia su per accedere al suo pointee.
Come tutti sappiamo, questo funziona solo se c'è
un pointee, che tipo di si rimette alla regola numero uno.
>> Numero Tre, puntatore Assegnazione prende un puntatore
e lo cambia per puntare al stesso pointee come un altro puntatore.
Così, dopo l'assegnazione, i due puntatori
punterà alla stessa pointee.
A volte, che si chiama condivisione.
E questo è tutto quello che c'è da fare, davvero.
Bye-bye ora.
[FINE RIPRODUZIONE VIDEO]
DAVID J. MALAN: Questo è tutto per CS50.
Vedremo la prossima settimana.