SPEAKER 1: Ciao a tutti. Stiamo per iniziare. Penso che le persone sono ancora in corso essere filtraggio a. Ma nell'interesse di tempo, in modo che possiamo ottenere voi ragazzi fuori di qui in tempo, stiamo per cominciare. Quindi benvenuto alla CS50 Quiz 0 recensione. Per quelli di voi che non hanno capito eppure, hai una domanda su Mercoledì. Woo-hoo. Se non hai ancora iniziato a studiare o Non hanno capito che questo esiste ancora, quiz del passato e tutte le informazioni su il quiz sono su cs50.net/quizzes. C'è un po 'di roba abbastanza buona in là, quiz ultimi degli ultimi 10 anni, così come le informazioni su questo quiz e temi che saranno coperti. Quindi cerchiamo di iniziare. Quindi voi ragazzi potrebbe ricordare, il primo giorno di lezione David ha avuto queste lampade su. Quindi, in sostanza, tutto ciò che va sotto il cofano di un computer è fatto in binario. Binary significa quello che sembra come, 0 e 1 di. Essa ha due valori che può essere rappresentato. Quindi, proprio come nel primo giorno di sezione quando David accese la luce lampadina per rappresentare il, o 1, il nostro computer capisce come binario 0 e 1 di, acceso o spento. Nozioni di base di Binary. Ogni luogo è rappresentata in base due. Quindi si aggiunge 2 alla 0 al 1 alla 2 tutta la strada fino. Per calcolare ciò che il binario è a decimale, basta seguire questa equazione tipo di cosa. Se si dispone di un 1 in uno qualsiasi di questi luoghi, si moltiplica per qualunque basare è in, aggiungere in su, e si ottiene il decimale. Quindi questo è come si contano a 5 in binario. Proprio come quello che stavamo facendo sul ultima diapositiva, questo è come si farebbe rappresentare da 1 a 5. Allo stesso modo, proprio come è possibile aggiungere e sottrazione in decimale o base 10, o davvero qualsiasi base, su può aggiungere e sottrarre in binario. Esattamente quello che ci si aspetta quando si aggiungere i due su, se è uguale a maggiore di 1, si portano a 1, fanno un 0, e fare l'aggiunta in quel modo, solo come ci si aspetterebbe, con regolare decimale o qualsiasi altra base. Freddo. Così come ho detto prima, tutto ciò che va sotto il cofano del nostro computer è fatto in 0 e di 1, o binario. Così come esprimiamo, per esempio, lettere o numeri o caratteri? E la risposta è ASCII. ASCII è un mapping tra i caratteri che avremmo normalmente vedere nel Lingua inglese come A, il B di, C di, sottolineatura, trattini, e qualcosa di simile. E le mappe che ad un valore ASCII. Un valore ASCII è solo un numero che può essere compreso dal computer. E proprio come si può fare addizioni e sottrazione con i numeri, si può fare li con valori ASCII. Quindi, in questo esempio, ciò sarà questo stampare? Sì, così solo uno spazio B space space C D. Dove ha fatto il mio mouse andare? Si noti che si può definire un int a 65. E quando si stampa che utilizzando cento C, sarà interpretare che come un carattere e stamperà A. Allo stesso modo, è possibile dichiarare come un char. E quando si stampa utilizzando per cento C, sarà interpretare che come cento D. E proprio come è possibile aggiungere un numero, è possibile aggiungere caratteri sono Valori ASCII, in questo caso. Quindi un po 'di puntatore per tutti. 5, come una stringa, non attualmente pari 5. Così come potremmo convertire il stringa 5 per il numero intero 5? Tutte le idee? Già. Quindi, se abbiamo 5 come una stringa, possiamo sottrarre 0. E che ci darà 5. E allo stesso modo, se abbiamo 5 come integer, aggiungere che alla stringa 0. E che ci dà la stringa 5. Freddo. Ora, ricordo torna a tenere una conferenza in cui uno abbiamo parlato di algoritmi. Quindi, come possiamo effettivamente vogliamo un computer di fare cose interessanti? Sai, solo aggiungendo e sottraendo i numeri e le cose da stampa fuori non è così eccitante. Di solito, vogliamo che il nostro computer per eseguire un qualche tipo di algoritmo. Qualcosa di un po 'più complessa di una semplice aritmetica. Un algoritmo è solo un passo per passo insieme di istruzioni per come eseguire un certo task-- proprio come una ricetta. Si potrebbe ricordare il primo giorno di classe dove Davide aveva ci contare una camera di persone e quante persone erano in camera. Si potrebbe essere utilizzato per il conteggio uno per uno. 1, 2, 3, 4. In tal caso, un algoritmo tempo lineare. Ma David ha introdotto un algoritmo per di contare le persone nella stanza dove ognuno si alza, si dice il vostro numero a un altro soggetto, aggiungere che numero alto, e una persona si siede. E si ripete quella. Questo è un tipo di algoritmo. Possiamo analizzare un modo efficiente algoritmo si basa su di esso è tempo di esecuzione. Ma parleremo un po ' di più su che più tardi. Quindi, tutti gli algoritmi possono anche essere scritto in pseudocodice. Pseudocodice è solo un inglese come sintassi utilizzata per rappresentare un linguaggio di programmazione. Ad esempio, se volessimo chiedere a un utente di indovinare il mio numero preferito, noi potrebbe avere pseudocodice come tali. Ricevi un utente indovinare. Se l'ipotesi è corretta, dire loro siano corrette, altrimenti dire loro non sono corrette. E pseudocodice è un modo di facile che rappresenta un'idea o un algoritmo. Così ora potremmo voler effettivamente scrivere questo nel linguaggio che il computer potrebbe comprensione. Così potremmo scrivere il nostro pseudocodice e interpretare che in codice sorgente. Finora, il codice sorgente deve rispettare ad un certo sintassi un linguaggio di programmazione. E finora, in CS50, abbiamo state utilizzando per lo più c. Quindi questo potrebbe essere il codice sorgente per il c. Più tardi nel corso, si arriva di notte a contatto con altri programmi linguaggi come PHP. O se ancora di prendere altre classi, si potrebbe fare Java, Python, o addirittura OCML. Ma nel nostro linguaggio di programmazione C, questo è come potremmo scrivere il codice sorgente per l'algoritmo pseudocodice che Ho appena descritto in precedenza. Così come fa il computer in realtà capire che? Come ho detto prima, è veramente solo capisce zero e uno. Così come si ottiene dalla sorgente codice a qualcosa che può essere capito? Beh, abbiamo qualcosa detto compilatore. Se vi ricordate indietro nella maggior parte del vostro pset, hai avuto qualche tipo di programma scritto in un file di punti c. E poi è necessario digitare make. Così che cosa sta facendo fare? È possibile digitare make per compilare il vostro programma perché someone-- chi ha scritto il vostro p set; probabilmente David-- creato un make file. E che racconta far sapere per eseguire il compilatore, chiamato clang, che la volontà quindi compilare il codice sorgente di opporsi codice, che è zero e uno che il computer capisce. Ma un po 'più tardi, andremo più in profondità su compilatori. Così ricordare pset 0, where-- sì, hai una domanda? PUBBLICO: [incomprensibile]? SPEAKER 1: Sì. Penso che in realtà dovrebbe essere online. Già. PUBBLICO: E 'come [incomprensibile]? SPEAKER 1: Non è. Il sono il cs50.net/quizzes. PUBBLICO: quiz Slash, tagliano il 2013, tagliare 0, e basta cliccare attraverso 2013 quiz e quiz 0, rivedere la sezione diapositive. SPEAKER 1: Sì, quindi se voi volete tirarlo su e guardarlo sul vostro proprio computer, va bene anche. Dire ancora una volta che. PUBBLICO: [incomprensibile]. SPEAKER 1: Sì, [incomprensibile] è la variabile dummy. Ah, sì? PUBBLICO: [incomprensibile]? SPEAKER 1: No, scioperi non sono l'esame. Siamo spiacenti, la sua domanda era, era scioperi l'esame. E non è. Così pset 0, voi ragazzi dovrebbe disporre di tutte implementato qualcosa usando zero. E abbiamo imparato un po 'di programmazione di base blocchi di costruzione utilizzando zero. Quindi, diamo uno sguardo ad alcuni di questi blocchi che compongono un programma. Il primo è espressione booleana. Espressioni booleane sono quelli e 0 di o qualsiasi cosa che ha due valori possibili. In questo caso, vero o falso, acceso o spento, e sì o no. Un esempio di una semplice, molto semplice, programma che utilizza un valore booleano espressione qui. Quindi, al fine di espressioni booleane per essere utile, abbiamo operatori booleani. Questi sono gli operatori che possono essere utilizzati per confrontare certi valori. Così abbiamo e non o uguale a, meno o uguale, maggiore o uguale e minore o superiore. Ma questi operatori non sono molto utili a meno che non li possiamo combinare in condizioni. Quindi voi ragazzi potrebbe ricordare da zero e dal vostro p imposta che avuto condizioni. Sono, in sostanza, come forcelle in la logica del programma che esegue a seconda che una condizione è soddisfatta. Così una delle condizioni che avevamo usato molte volte in questo corso è il se, in caso contrario, se, e le condizioni di altro. Ecco un esempio di come si potrebbe usare quella. Qualcuno sa la differenza tra usando solo se tutte le dichiarazioni fino in fondo versi se, in caso contrario, se, e altro combinato? Sì? PUBBLICO: [incomprensibile]. SPEAKER 1: Esattamente. Quindi, se ho avuto, se fino in fondo questa modo, anche se tale condizione restituisce vero, continuerà ancora testare i prossimi due. Considerando che, con un altro-se, un altro dichiarazione, se la si restituisce true, gli altri non sono testati. Tutte le domande di questo? Freddo. Quindi si utilizza un altro se-di un altro dichiarazione se si sa che si può solo essere uno di questi casi. Così sappiamo se x è minore di 0, è sicuramente non sta per essere maggiore di 0. Accanto, un altro mattone che abbiamo imparato sono cicli. Abbiamo tre tipi di cicli. Per i cicli, cicli while, e fare cicli while. E in genere, quando ci si siede a scrivere qualcosa, si deve decidere quale dei tre che si desidera utilizzare. Quindi, come facciamo a decidere quale? Generalmente usiamo un ciclo for se sappiamo quante volte vogliamo iterare attraverso qualcosa o quante volte vogliamo eseguire un compito. Usiamo i cicli while, se abbiamo bisogno di qualche condizione per essere vero per continuare a correre. E usiamo facciamo mentre molto simile a mentre, ma vogliamo che il nostro codice da eseguire a almeno una volta. Quindi fare mentre, tutto ciò che è nel fare la volontà eseguito sempre almeno una volta. Considerando che, con il tempo, si può non funzionare affatto se il condizione non è soddisfatta. Tutte le domande con quello? Quindi la struttura di un ciclo for. Voi ragazzi avete visto tutti questo. Si inizializzato. Avete qualche tipo di condizione. Così, per esempio, potremmo inizializzare come per i uguale a 0. i è inferiore a 10. E i ++. Uno molto semplice che abbiamo fatto. Per un ciclo while, allo stesso modo, si ha di avere un qualche tipo di inizializzazione, un certo tipo di condizione, e qualche tipo di aggiornamento. Così possiamo realizzare il nostro ciclo for anche come un ciclo durante l'utilizzo di questo. E allo stesso modo con un ciclo Do While, potremmo avere un po 'di inizializzazione, eseguire qualcosa, aggiornarlo, e quindi controllare la condizione. Così ora funzioni. Abbiamo messo insieme tutto. Si potrebbe desiderare di scrivere qualche tipo di funzione. Funzione comune che si potrebbe hanno visto già è principale. Principale è una funzione. Ha un tipo di ritorno, int. Ha un nome di funzione, principale. E ha argomenti, argc e argv. Così principale è solo una funzione. Altre funzioni eventualmente utilizzate, printf printf-- è un function-- GetInt, toupper. Ma questi capita di essere stato realizzato per noi da una sorta di biblioteca. Se voi ragazzi ricordo compresi Questa libreria CS50.h o il I Standard / O biblioteca. Sì, in discussione? PUBBLICO: è il principale appena inerente c? Lo fa solo tipo di [incomprensibile]? SPEAKER 1: La domanda è se il principale è inerente a c. E sì, tutte le funzioni avere una funzione principale. È sorta di necessario al computer sapere da dove cominciare l'esecuzione del codice. Pubblico: Così non sarebbe [incomprensibile]? SPEAKER 1: No. Tutte le altre domande? Freddo. Così come è possibile utilizzare una funzione di che è scritto per voi, è possibile anche scrivere la propria funzione. Questa è una funzione che qualcuno potrebbe hanno scritto per calcolare il volume di un q, per esempio. C'è un tipo di ritorno qui, in questo caso int, il nostro nome e la nostra funzione q elenco di parametri. E notare che si deve scrivere i dati tipo del parametro che si desidera utilizzare altrimenti la funzione non fa sapere che tipo di parametro dovrei essere accettare. Quindi, in questo caso, vogliamo un intero come il nostro ingresso. Allora perché potremmo voler usare le funzioni? Prima di tutto, grande per l'organizzazione. Aiutano a spezzare il codice in più organizzata pezzi e fare più facile da leggere. Semplificazione. Questo è un bene per il design. Quando stai leggendo un pezzo di codice e la funzione principale è veramente, davvero lunga, potrebbe essere più difficile da ragionare su quello che sta succedendo. Quindi, se si scomposizione in funzioni, potrebbe essere più facile da leggere. E riutilizzare-abilità. Se hai un pezzo di codice che viene chiamato o eseguire più volte, invece di riscrivere quel codice 10 volte nella tua funzione principale, si potrebbe voglia di riutilizzarlo. E poi ogni volta che si ha bisogno di usare quel pezzo di codice, chiamare la funzione. Così ora se ci ricordiamo di nuovo a zero, abbiamo anche parlato di alcuni concetti, di cui una filettatura. La discussione è il concetto di multiplo sequenze di codice esecuzione allo stesso tempo. Quindi, pensare di nuovo al giorno in cui David aveva ragazzi contare il numero di persone nella stanza. In sostanza, che cosa stava succedendo è tutto su di voi ragazzi erano esecuzione di thread separati. E quei fili stavano arrivando insieme per ottenere qualche tipo di risposta. Allo stesso modo, in Scratch, quando si hanno più sprites, si potrebbe avere un gatto e un cane. E sarebbero simultaneamente in esecuzione i propri script. Questo è un esempio di filettatura. E l'altro concetto che è stato introdotto nel scratch è stato eventi. E gli eventi sono quando più parti di il codice di comunicare tra loro. In Scratch, questo è stato quando si è utilizzato il il controllo e la trasmissione quando sono Ricevi blocchi. E anche, in Set Problema 4, abbiamo visto un po 'di eventi come bene. Voi ragazzi potrebbero avere usato la biblioteca Gevent. E c'era una funzione waitForClick in cui stavate aspettando per l'utente di scegliere. E il tuo scatto, in questo caso, sarebbe l'evento e attendere per click è la vostra gestore di eventi. E inoltre, per tutta l'esecuzione vostre pset e lavorare sui vostri pset, si avrebbe potuto entrare in contatto con alcuni di questi comandi. Questo è ciò che hai digitato nel tuo finestra di terminale o di qualunque finestra che compare sul vostro g di modifica a, in sostanza, individuare il computer. Così, per esempio, LS elenca l' contenuto di una directory. Fai directory crea una nuova cartella. CD, cambiare directory. RM, rimuovere, elimina un file o qualche directory. E poi rimuovere la directory rimuove una directory. PUBBLICO: [incomprensibile]? SPEAKER 1: Sì, certo. Spiacenti, la domanda era se si suggerirebbe mettere questo sul foglietto. Essa potrebbe aiutare. Se avete spazio, si può mettere su. E 'anche solo generalmente abbastanza buono da ricordare perché quando lo si utilizza si potrebbe desiderare di appena l'hanno memorizzato. Che sarà rendere la vostra vita molto più facile. Ho risposto alla tua domanda? Così ora, abbiamo parlato un po ' brevemente le librerie. Ma i due principali che sono stati utilizzando finora in corso sono I / O e CS50 standard. Che tipo di cose sono inclusi nella libreria standard di I / O? Sì, finora abbiamo usato printf. In CS50, abbiamo usato GetInt e GetString. E la stringa tipo di dati avviene anche essere dichiarati in questa biblioteca CS50. Parleremo un po 'più in profondità su come le biblioteche funzionano e come interagire con il resto del codice. Ma questi sono i due principali che abbiamo sono venuti a contatto con finora il corso. Tipi. Questi sono buoni per ricordare quanto ogni tipo è rappresentato da o come molti byte ciascuno di tipo requires-- int, 4 byte; char, 1 byte. Float è 4 byte. Che cosa è un doppio? PUBBLICO: [incomprensibile]. SPEAKER 1: Sì, quindi un galleggiante ma raddoppiare le dimensioni. Che dire di un lungo? PUBBLICO: [incomprensibile]. SPEAKER 1: OK. Che cosa è un lungo? PUBBLICO: [incomprensibile]. SPEAKER 1: Sì, raddoppiare un int. Sì. PUBBLICO: [incomprensibile]. SPEAKER 1: Lunga [incomprensibile]. E poi un lungo lungo è il doppio di quello. PUBBLICO: No, no. Un lungo è solo un int. Essa dipende dall'architettura prima che il [incomprensibile] e int hanno la stessa dimensione. [Incomprensibile]. SPEAKER 1: Quindi un lungo e un int sono gli stessi. E poi un lungo lungo è il doppio int. Freddo. E allora, qual è l'ultimo tipo? PUBBLICO: Pointer. SPEAKER 1: Sì, così abbiamo imparato un po 'di puntatori. E indipendentemente da ciò che un puntatore è indicando a-- potrebbe essere una stella char o un int star-- è sempre 4 byte per un puntatore. Domande su che? Sì? PUBBLICO: [incomprensibile]? SPEAKER 1: Quindi un lungo e un int sono lo stesso in questo apparecchio CS50. PUBBLICO: L'apparecchio sono completamente intercambiabili. SPEAKER 1: Già. Allora una lunga lunga è doppio un int. PUBBLICO: Questo è il bit 32? SPEAKER 1: 32 bit, sì. PUBBLICO: Così [incomprensibile]? SPEAKER 1: Sì, se non lo fa esplicitamente dire, si dovrebbe assumere un po '32. PUBBLICO: Sarebbe dire qualcosa come nell'ipotesi di un all'architettura come l'apparecchio. Per 64 bit, le uniche cose che cambiamento sono long e puntatori. Entrambi [incomprensibile]. SPEAKER 1: Sì? PUBBLICO: Domanda. Così su uno dei quiz di pratica, si chiede un unsigned int. Così come vorrei che essere determinato da un int [incomprensibile]? SPEAKER 1: Un unsigned in è anche 4 byte. Ma ciò che è diverso di una firma int e unsigned int? PUBBLICO: [incomprensibile]. SPEAKER 1: Destra. Si può rappresentare valori negativi. Ma come farlo? PUBBLICO: [incomprensibile]. SPEAKER 1: Sì, salva 1 bit per rappresentare il segno. Il sottoscritto ha un bit che rappresenta il segno. Ed è proprio unsigned tutti positivi. PUBBLICO: OK. Quindi lei dice che è una doppia il doppio di un galleggiante? SPEAKER 1: doppio è il doppio le dimensioni di un galleggiante, sì. PUBBLICO: Come funziona un puntatore per un lungo lungo [incomprensibile]? SPEAKER 1: Quindi la domanda è come fa il puntatore di un lungo long-- Come è che solo quattro byte quando un lungo lungo i suoi 8 byte. Quindi ricorda che cosa è un puntatore, in sostanza, al valore base stessa. PUBBLICO: [incomprensibile]. SPEAKER 1: Sì, così un puntatore è solo una posizione di memoria. Quindi non importa quanto spazio puntatore che punta a. Ha bisogno solo di 4 byte per tenere traccia di quella locazione di memoria. Tutte le altre domande? Freddo. Quindi l'ultima cosa che ho è uscita standard. Li dovrebbe usare frequentemente sufficiente che si può ricordare. Ma questo è quando usiamo printf, per esempio. E abbiamo questi segnaposti che sono stati chiamati codici di formato. Quindi per cento c char, cento i per int, e possiamo anche usare per cento d. E 'la stessa cosa. Ma, in generale, in CS50 noi provare a utilizzare i cento. Percentuale f per float. Percentuale ld per molto tempo e s per cento per la stringa. Allo stesso modo, abbiamo usato un paio di di queste sequenze di escape. Ad esempio, backslash n per la nuova linea. Questo è solo per quando si sta formattando il codice per la stampa f. Sì? PUBBLICO: Che cosa è per cento d? SPEAKER 1: Quindi la domanda è ciò che è cento per d? Percentuale d è per int. Percentuale d e i cento sono gli stessi. PUBBLICO: Qual è la differenza tra backslash n e backslash r? SPEAKER 1: Quindi la domanda è: qual è il differenza tra il gioco e il n r contraccolpo? Penso backslash r è-- PUBBLICO: Così backslash r implica solo ritorna all'inizio della riga senza realmente andare ad una nuova linea. Quindi, se si stampa un backslash r e si tornare all'inizio della riga allora si stampa più roba, si sovrascrive la roba che è già sul [Incomprensibile]. Considerando che, n in realtà va a un nuovo linea e va a [incomprensibile]. SPEAKER 1: Beh, tutte le altre domande? Bene. Ho intenzione di darlo via a Dan che continuerà. [Applausi] DAN: Tutti righty. Così sarò parlando di un altro grande gamma di idee della classe che sono circa rappresentante della settimana e due l'inizio di tre settimane partendo con la fusione, che è solo un modo di trattamento di un valore di un certo tipo un valore di un tipo differente. Così possiamo fare questo con caratteri a int, galleggianti a int, e lunghe anela a raddoppiare. Tutte queste cose possono essere utilizzati come modi di trattare un certo valore numerico meno char come qualche altro valore numerico. Così ci sono alcuni problemi con questo, di Naturalmente, che viene quando si esegue il cast cose come float a int. Quindi questo è un po 'strano. Abbiamo un galleggiante che è 1,31. Noi moltiplichiamo per 10.000. E poi stampiamo come un int. Che cosa significa questa uscita? 10.000 volte 1.31. Quindi 13.000, è che la congettura? PUBBLICO: Penso che sia 10.000. DAN: Così sto moltiplicandolo per 10.000 prima che io sto lanciarla. PUBBLICO: Oh. Non ci sarebbe un 9 e alcuni numeri 0? DAN: Si potrebbe avere alcune cifre strane. Quindi a destra, è 1,3 volte 10.000. Ecco, questo è 13.000. E questo weird-- supplementare PUBBLICO: 13.100. DAN: 13.100. Grazie, Rob. E questo weirdness-- supplementare questo 9,9-- è semplicemente perché questo casting finito per arrotondamento verso il basso dove non dovrebbe avere. Già. PUBBLICO: Il casting avviene dopo qualsiasi altra cosa? DAN: Allora, perché ho questo in stampa, fa questo moltiplicazione prima che fa questo casting. PUBBLICO: [incomprensibile]. DAN: Penso che sarebbe gettato in primo luogo, sì, che sarebbe 10.000. Qualunque altra cosa? Freddo. Quindi questo è 13.099. Perché accade questo? L'imprecisione. I galleggianti non sono perfetti. Essi possono rappresentare solo numeri a un certo numero di cifre significative. Quindi, se stampiamo 8 fichi sig su questo galleggiante, si ottiene una sorta di brutto numero guardando. E questo perché non si può con precisione 1.31 essere rappresentate da semplici potenze di due in macchina. Così si finisce per prendere la più vicina indovinare, che finisce per essendo un po 'bassa. Dare un senso? Ok. Ora, sono passati un modo diverso di facendo istruzioni condizionali in cui tutti i ci preoccupiamo è una singola variabile. Quindi, in questo particolare esempio, siamo ottenere un numero intero da parte dell'utente. E poi stiamo guardando ciò che è intero. Presumibilmente, è il numero tra uno e quattro. Questo è quello che stiamo chiedendo. Così si fa un interruttore di il nome della variabile. Quindi si imposta casi di possibile Valori potrebbe essere. Quindi caso uno, dicono che è basso. E poi si interrompe per uscire della condizione interruttore così non andare avanti. Nel prossimo case-- così caso due e caso sulle tre ruote se si tratta di due casi appena scende a la prima riga di codice che considera con maiuscole e tre fino a quando non vede una rottura. Quindi la ragione si ottiene un caso di solo bassa stampa è perché io avere questa pausa qui. Se io, per esempio, ignorato questa break-- se ho buttato questo breakaway-- sarebbe stampare basso, e allora sarebbe stampare centrale, e quindi si spezzerebbe. Così le pause sono una parte importante di cambiare le condizioni e dovrebbero essere lì. I casi che non sono indicati esplicitamente sono gestiti dal predefinita nel caso l'interruttore e deve essere gettato. PUBBLICO: Così 1, 2, 3, e 4 sarebbero n? DAN: Valori che possono essere n. Sì. Sì? PUBBLICO: Quindi, quando si ha che [incomprensibile]? DAN: si stampa basso, e poi sarebbe stampare centrale, e allora si spezzerebbe. PUBBLICO: Perché sarebbe stampare metà se [incomprensibile]? DAN: Quindi tutto sotto un caso prima di una pausa rientra. Quindi un caso di stampa è caso sotto uno come è il seguente stampa. Sì? PUBBLICO: [incomprensibile]? DAN: Quindi questo numero è solo un particolare valore che questa variabile può prendere, giusto? Questo fa senso? Già. PUBBLICO: [incomprensibile]? DAN: Sì, caso due sarebbe stampare centro e poi rompersi. PUBBLICO: [incomprensibile]? DAN: Penso che qualsiasi? Quali altri tipi di dati si può passare? PUBBLICO: È possibile passare su qualsiasi tipo di dati. Ma significa solo nulla più caratteri e int e cose del genere, perchè se stai passando sopra un puntatore che in realtà non ha senso, commutazione di carichi, anche se cerchiamo di fate che, a causa di virgola mobile di precisione, non sarebbe davvero voglia di farlo comunque. Quindi praticamente, solo int e caratteri e roba del genere. DAN: Sì, è quando si ha esplicita valori che si sa, credo, può essere che un interruttore è effettivamente utile. Buono? Ok. Scope è la gamma che un dichiarato variabile si estende. Quindi, in questo piccolo pezzo di codice che ho, sarebbe pieno di errori. E la ragione è dichiarai questo int Ho nell'ambito di questo ciclo for. E poi sto cercando di riferimento che Io al di fuori di tale portata per ciclo. Quindi, fondamentalmente, si può pensare di portata come tutto ciò che si dichiara con al suo interno una serie di parentesi graffe solo esiste all'interno di tali parentesi graffe. E se si tenta di utilizzare tale variabile al di fuori di quelle parentesi graffe, ti ottenere un errore del compilatore. Sì? PUBBLICO: Quindi questo non funziona? DAN: Questo non funziona, sì. Stringhe. String un char *. Sono esattamente lo stesso. Sono solo puntatori a caratteri. E tutte le stringhe che avete dovrebbero terminare con backslash zero, che è solo una convenzione c. Si chiama il terminatore NULL. E NULL-- capitale N, U maiuscola, il capitale L, capitale L-- non è lo stesso del Terminatore NULL. Questo è un puntatore. Questo è un carattere. Sono molto distinti. Ricordalo. Sarà il quiz, probabilmente. Non ho visto il quiz. Sì? PUBBLICO: NULL Così è, per esempio, il puntatore? DAN: Sì. PUBBLICO: Cosa fa [incomprensibile]? DAN: se, per esempio, malloc viene chiamato quando si non hanno abbastanza memoria per ottenere qualsiasi dimensione che stai chiedendo, malloc ritorna NULL. È, in sostanza, ogni volta che una funzione è dovrebbe restituire un puntatore, si necessario verificare contro NULL perché NULL è un grazioso buono-- è, una sorta di, il valore spazzatura. E 'uno zero per quanto riguarda puntatori andare. Ogni volta che si chiama una funzione, che restituisce un puntatore. Stai andando a voler verificare di essere Assicurarsi che tale puntatore non è NULL perché NULL è molto comune. Si tratta di una sorta di ritorno spazzatura. Quindi, se qualcosa non è andato a destra, appena di ritorno invece NULL. PUBBLICO: [incomprensibile]? DAN: Sì, ed è questo. PUBBLICO: [incomprensibile]? DAN: Spell come questo. E 'il terminatore NULL. È minuscolo N-U-L-L se stai ortografia. PUBBLICO: E ho appena andato indietro e testato. E se si tenta di mettere una virgola mobile valore in un interruttore, che sarà urlare a voi dicendo, dichiarazione richiede espressione di tipo integer. DAN: ci si va. Ma sì, qual era la domanda? PUBBLICO: [incomprensibile]? DAN: Così capitale N, U capitale, il capitale L, L maiuscola è un vero e proprio c cosa. E 'il puntatore NULL e volontà essere trattato solo come tale. Non sarà mai cercare di precisare la Carattere NULL e vedere qualsiasi altro modo che questo. Sì? PUBBLICO: Quindi tornando a char max o qualcosa nelle note, è vero incarnano la stessa funzione come [incomprensibile]? Pubblico: Così si riferisce a ritorno max char da getchar, o qualunque essa sia? PUBBLICO: Sì. PUBBLICO: Sì, così il generale termine per tutte quelle cose sono valori sentinella. Così come ritornare int max da GetInt e char max da getchar, è dovrebbe essere come, tutto bene, se queste cose stanno tornando a noi, qualcosa è andato storto. Per i puntatori, abbiamo appena capita di avere questo valore sentinella che tutti concorda. E questa è la cosa che si torna quando le cose vanno male. Quindi max char è quello che stiamo usando a rappresentare qualcosa di come NULL o getchar. PUBBLICO: Quindi, se si sta testando getchar, potrebbe semplicemente mettere NULL? Vorrei che fare la differenza? DAN: Non si poteva solo controllare NULL. Dovresti controllare char max perché il valore restituito dalla funzione è un personaggio non un puntatore. Sì? PUBBLICO: Questa domanda si chiede per la lunghezza della stringa. Fa che includono il carattere NULL? DAN: No. E questo è in realtà come la lunghezza della stringa sa fermarsi perché passa attraverso la matrice di caratteri fino a vede un carattere NULL. E poi è come, tutto a destra, ho finito. PUBBLICO: [incomprensibile] cinque? DAN: Ciao sarebbero cinque. Yep. Così gli array sono continue blocchi di memoria. Essi hanno accesso immediato dicendo il nome della matrice e poi, a riccio bretelle, qualunque indice si vuole andare a, sono indicizzati da zero attraverso la lunghezza della matrice meno 1. E sono dichiarati dal tipo di cosa che stai memorizzazione nel matrice, il nome della matrice, e poi qualunque sia la dimensione è di tale matrice. Quindi questo è un array di caratteri di lunghezza sei che ha questi valori. Sì? PUBBLICO: [incomprensibile]? DAN: Sì. PUBBLICO: [incomprensibile]? DAN: Se si dispone di ciò che sta accadendo nella matrice già fatto. Così si potrebbe specificare questo invece come, per esempio, char, qualunque sia il nome del array è, tra parentesi vuote uguale ricci tutore H virgola E virgola L virgola L virgola O virgola carattere NULL e la parentesi graffa. Che sarebbe anche funzionare come una dichiarazione. PUBBLICO: [incomprensibile]? DAN: Allora avete bisogno di avere la dimensione già fatto. PUBBLICO: [incomprensibile]? DAN: Sì. Tutti righty. Argomenti della riga di comando sono un modo di avere un input da parte dell'utente, come argomenti di principale. Principale prende due argomenti. Il numero di argomenti che si sta passato lungo la linea di comando e una vettore stringa o un array di stringhe di tutti gli argomenti. Quindi, se io, per esempio, chiamai una funzione come un punto fuori 1 posto, 2 spazio, tre, argc sarebbe 4. E il argv 0 sarebbe un punto fuori. Argv1 sarebbe 1. argv2 sarebbe 2. argv3 sarebbero 3, in quel caso particolare. Sì? PUBBLICO: [incomprensibile]? DAN: L'ultimo elemento dell'array perché la matrice è la lunghezza argc più uno dei argb, l'ultimo elemento è il puntatore NULL. E 'argc più 1. Quindi, nel caso che ho appena detto, sarebbe argv 0 è un punto fuori. argv 1 è 1 argv2 è 2 argv 3 è 3. argv 4, che è una grande di argc sarebbe NULL. E questo è il puntatore NULL. Sì. E questo perché stringa è una stella char è un puntatore. Quindi deve essere dello stesso tipo. Sì? PUBBLICO: Due domande. Così uno, qual è la differenza tra questo e GetString diverso da un tipo nel motore utente? E due, si è memorizzata all'interno la memoria recente? Così come, GetString farebbe essere [incomprensibile]? DAN: Dove è memorizzato? Non so da dove sono archiviati. PUBBLICO: Quindi, in realtà, si sa come qualsiasi funzione che si chiama di argomenti sono memorizzati nello stack? Così argc e argv sono argomenti di principale e sono in pila, o realmente appena sopra quello che pensi come l'inizio della pila. Qual è stata l'altra parte della questione? PUBBLICO: Allora, qual è il [incomprensibile]? DAN: Sì, è solo un modo diverso di avere un input da parte dell'utente. Questo suo leggermente più efficiente e è più maneggevole per gli script, perché voi può solo passare gli argomenti al main funzione piuttosto che dover attendere per gli utenti, se non avete alcun utente. PUBBLICO: E sì, ottenere stringhe sarebbe [incomprensibile]. Sarebbe memorizzare le cose avete bisogno. DAN: Sì? PUBBLICO: [incomprensibile]? DAN: Sì, argv 0 include sempre il dot ridurre drasticamente la chiamata di funzione. Sì? PUBBLICO: [incomprensibile]? DAN: Sì, tutti gli argomenti sono conclusa nel carattere NULL perché sono stringhe. PUBBLICO: [incomprensibile]? DAN: Sì, argc argv è un puntatore NULL. PUBBLICO: [incomprensibile]? DAN: Oh yeah. Sì, mi dispiace. PUBBLICO: Così [incomprensibile]? DAN: Quindi la domanda è se si ha la riga di comando dot ridurre drasticamente un punto fuori 1, 2, sarebbe il numero di riga di comando argomenti siano due o sarebbe tre? PUBBLICO: Penso che non lo fa davvero importa. Io tendo a dire, oh, non hai superato eventuali argomenti della riga di comando quando, ovviamente, hai chiamato la funzione. Quindi tendo ad escludere vocalmente l' funzione dalla riga di comando argomenti anche se è inclusi in argv. DAN: Ma se era sul test-- yeah-- e anche se dici qualcosa come argc è uguale a 3, sei in piedi al sicuro. Sì? PUBBLICO: [incomprensibile]? DAN: Penso che se invece di chiamare questo in argc e argv stringa staffe ma mantenuto gli stessi tipi e appena chiamato loro qualcosa di diverso come un e b, sarebbe ancora funzionare? E sarebbe ancora funzionare, si solo-- invece di utilizzare argc-- devi usare a e b. Sì? PUBBLICO: [incomprensibile]? DAN: Quindi la domanda è GetString è andando a memorizzare memoria nel mucchio perché GetString è char *. Memorizza memoria nel mucchio perché chiama ora malloc entro l'attuale implementazione di GetString. OK, passare. Sicurezza. Quindi, per essere veramente sicuro, si basano su nessun uno e lasciate che nessuno l'accesso a qualsiasi delle informazioni, che è il motivo per ognuno costruisce le proprie macchine, i propri sistemi operativi, tutta la loro programmi da zero, e, ovviamente, non collegare ad altre macchine via internet. Così i computer sono insicuri. Sono davvero. Dobbiamo fidarci altre persone. E l'idea di sicurezza è che sei cercando di limitare la quantità di fiducia che avete bisogno. E uno dei mezzi di farlo è attraverso la crittografia. La crittografia è, in sostanza, abbiamo segreti. A volte dobbiamo passare nostri segreti lungo attraverso, ad esempio, internet o altre cose. E noi non vogliamo che la gente conoscere questi segreti. Quindi noi codifichiamo i nostri segreti in un modo che speriamo non si riesce a capire. Così abbiamo used-- attraverso il corso di questa class-- cose come cifrario di Cesare e [Incomprensibile], che sono entrambi molto, molto insicure vie della crittografia di cose. Sono facili da capire che cosa sono e quali sono i vostri segreti sono. Il mondo reale utilizza molto di più schemi di cifratura complicati. E noi non entreremo in molto di più. Debug. GDB è il migliore. Io vado a sottolineare questo di nuovo. Utilizzare GDB tutto il tempo ogni volta che hai un problema. I comandi che sono utili in GDB sono rompe, che si passa o una linea numero, un nome di funzione, essenzialmente in cui nel codice si vuole fermare, ed essere in grado di prendere il controllo. Stampa prende una variabile e stampa tutto ciò che è variabile in quel punto della vostra esecuzione. Prossime mosse tua esecuzione lungo un passo. E un passo gradini all'interno di una funzione nella tua esecuzione. Altre cose sono gestite, che è come effettivamente esegue il codice. Continuare prende tutte le misure necessarie per arrivare al successivo punto di interruzione. E ci sono molti, molti altri. Guarda in su. Sono grandi. Sì? PUBBLICO: [incomprensibile]? DAN: Sì, che è un debugger. Quindi un debugger è un programma che consente di eseguire il debug del programma. Non è un programma che trova i bug per si, anche se questo sarebbe grande. E per ultimo per me è la ricerca. Così i tipi di ricerca di cui abbiamo parlato circa in questa classe sono ricerca lineare, che è solo che si guarda attraverso ogni elemento dello spazio di ricerca, uno elemento alla volta, fino a trovare quello stai cercando o fino a raggiungere la fine del vostro spazio di ricerca in cui punto si dice che non si poteva trovare l'elemento che stavi cercando. E questo richiede tempo nel migliore dei casi costante, che è 0 a 1 e nel peggiore dei casi lineare tempo, che è 0 di n. La ricerca binaria, che ha bisogno di Elementi sordidi. Si va al centro dei vostri elementi, vedere se l'elemento che stai cercando è più grande o più piccolo del elemento che tu sei al centro. Essa è più grande, si dice che il fondo della ricerca spaziale è la vostra posizione attuale, al centro, e si riavvia il processo. Se è più piccolo, si guarda dire che the-- sì, che cosa succede? PUBBLICO: [incomprensibile]? DAN: Sì. Qualsiasi tipo di genere che è stato insegnato in la classe è un gioco equo per il test. [Risate] DAN: E il fatto che non hai avuto di farlo per una serie problema, è giusto gioco per la prova. PUBBLICO: Possiamo andare su di esso come a-- DAN: Sarà andato oltre. SPEAKER 2: il codice effettivo per [Incomprensibile] è su study.cs50.net. Quindi, se si guarda al problema prassi nella pagina di merge sort study.cs50.net, c'è il codice per l'attuazione di merge sort. Quindi non dovete implementare te stasera. Ma assicurarsi di aver compreso piuttosto che solo memorizzarlo. PUBBLICO: [incomprensibile]? SPEAKER 2: La pagina di merge sort su study.cs50.net, vi è una pratica problema che, se si fa clic attraverso il problema, alla fine c'è una soluzione, che è l'unione implementazione sorta. Ma assicuratevi di capire che piuttosto che memorizzarlo o copia di essa verso il basso. PUBBLICO: E perfettamente valido problema per l'esame sarebbe qualcosa di simile ecco una lista. Che cosa significa questa lista sembra dopo un passo delle selezioni tipo o insertion sort o qualsiasi altra cosa. Una iterazione completa della lista. Quindi, anche se non si finisce per dover codice per esso, è necessario capire che abbastanza per sapere come sta andando da modificare questo array. DAN: Questo è tutto per me. [Applausi] LUCAS: Ciao a tutti. Il mio nome è Lucas. Ho intenzione di parlare di ricorsione, tutti il genere che abbiamo imparato, e un po 'di tutti i puntatori. Ok? Quindi prima di tutto, ricorsione. Che cosa significa dire che una funzione è ricorsiva? PUBBLICO: si chiama. LUCAS: OK, si chiama, sì. Quindi ti piace questa immagine, per esempio. E 'come l'immagine all'interno di una immagine e così via. Così, per esempio, è possibile have-- come Dan che stava parlando di ricerca binaria. Un modo in cui la ricerca binaria è ricorsiva è il fatto che sei cercando di trovare un numero. Così si va al centro. E poi di controllare se i numeri ci nella sinistra e nella destra. E poi se si trova il numero è sta per essere sulla sinistra, è la stessa cosa fare di nuovo la ricerca ma appena sulla sinistra della lista. Ecco come suona come è ricorsivo. Ecco perché voi ragazzi avete ricorsiva soluzione per merge sort. OK, ecco un esempio. Quindi diciamo che voglio scegliere tutti i numeri da 1 a n. Posso capire che la somma degli n numero è n più n meno 1 fino a 1. Ma poi, se guardo n meno 1 più n meno 2 più 1, che è la stessa cosa come numeri sommatori fino a n meno 1. Quindi posso dire che la somma di una somma pari n è uguale più la somma di n meno 1. Questo fa senso? E anche io avrei qualcosa d'altro chiamato il caso base, che è quella la somma dei numeri fino a zero è pari a zero. Così, non appena ottengo il numero pari a zero, mi fermo a contare. Questo fa senso? Quindi, ecco un esempio di come Posso attuare tale. Quindi ho questa funzione in alcuni. Questo richiede un numero intero n. Così qui ho controllare se n è minore o uguale a zero. Quindi, se è minore o uguale a zero, ho ritorno a zero, che è il nostro caso base. In caso contrario, posso solo tornare n più la somma dei numeri da uno a uno n meno. Dare un senso? Ok. Quindi, ecco quello che sembra. Hai somma di 2 pari 2 più la somma di 1. E alcuni di 1 è 1 più la somma di 0, che è 0. Dare un senso? Quindi, se guardiamo la pila del vostro programma, questo è quello che sembra. In primo luogo, abbiamo la funzione principale. E poi la funzione principale chiamato somma 2. E poi somma 2 sta per dire, oh, somma 2 è uguale a 2 più la somma di uno. Quindi aggiungo somma di 1 nello stack. E la somma di 1 sta per chiamare somma di 0, che è anche andare da aggiungere allo stack. E poi ognuno di questi quelli che sono sopra l'altro deve tornare prima che gli altri possono andare avanti. Così, per esempio, qui, somma di 0, prima, sta per restituire 0. E poi scegliere somma di 1. Poi somma di 1 sta per ritorno 1 a Somma di 2. E, infine, somma di 2 sta andando per tornare alla principale 3. Questo fa senso? E 'molto importante capire come lo stack funziona e cercare di vedere se ha senso. OK, così l'ordinamento. Allora, perché è l'ordinamento importante, prima di tutto? Perché dovremmo preoccuparci? Chiunque? Dammi un esempio? Sì? PUBBLICO: [incomprensibile]. LUCAS: Sì, OK. Così si può cercare in modo più efficiente. Questo è un buon modo. Così, per esempio, abbiamo un sacco di cose, in realtà, nella nostra vita che sono allineati. Ad esempio, dizionari. E 'molto importante avere tutti i parole in un certo tipo di ordine che noi può accedere facilmente. Ecco, questo è quello che stava dicendo. È possibile cercare in modo più efficiente. Pensate a quanto sia difficile sarebbe di avere un dizionario in cui le parole sono in ordine casuale. Dovrete guardare, più o meno, ogni singola parola, fino a trovare il parola che stai cercando. Se si sta utilizzando anche Facebook, quando si sta guardando i tuoi amici, sei andando a vedere che Facebook ha messo il vostro più stretta amica di sopra di quelli che non si parli più di tanto. Se si va fino in fondo la vostra lista amici, si sta andando a vedere persone che probabilmente non hanno nemmeno ricordate che siete amici con. E questo perché Facebook tipi i tuoi amici in base a come sei vicino a loro. Così organizzazione dei dati. Anche Pokemon. Così si vede che tutti i Pokemon avere i numeri. E questo è come un facile modo di accesso ai dati. PUBBLICO: Accesso Pokemon. LUCAS: Già. PUBBLICO: [incomprensibile]. LUCAS: Yep. OK, così ordinamento per selezione. Selezione tipo sta per selezionare il valore più piccolo di un elenco non ordinato ogni tempo in ogni iterazione. E 'un po' come il tipo che si fa nella tua testa quando si sta cercando di ordinare un elenco a portata di mano. In sostanza, tutto ciò che fai è guardare per il numero più piccolo. Hai messo nella lista ordinata. E poi si guarda per il successivo numero più piccolo. E poi si mantiene facendo che e così via. Quindi ordinamento per selezione è fondamentalmente si selezionare ogni volta la più piccola valore non ordinato. Mettere alla fine del ordinate parte della lista. E continuare a farlo. Quindi cerchiamo di vedere rapidamente cosa questo sembra. Quindi, ecco l'ordinato e la lista non ordinata. Così, per l'ordinata di lista, è inizialmente vuoto. E poi ho intenzione di selezionare la più piccolo numero qui, che è 2. Così ottengo il numero 2 e ho messo nella parte anteriore della lista. E poi guardo per il prossimo più piccolo elemento, che è 3. Così l'ho messo alla fine della lista ordinata. E poi continuo a farlo. Trovo 4 e metterlo alla fine. Trova 5 e metterlo alla fine. E guarda come tutto di quei tempi che Sto dicendo messo alla fine è, fondamentalmente, scambiando due valori. Ok? E poi l'ultimo, appena avere un elemento in più. Quindi è già ordinato. OK, così insertion sort. Insertion sort si sta andando ad avere anche quella cosa di avere un ordinato e un elenco non ordinato. L'unica cosa è che ogni volta che si sta aggiungendo un elemento alla ordinato lista, basta scegliere l'elemento che è in testa alla lista non ordinata. E allora si sta andando a trovare ciò che posizione dovrebbe essere in ordinata parte della lista. Vediamo cosa è così questo ha più senso. Così, inizialmente, per esempio, sto cercando per inserire il numero tre del parte ordinata della lista. Quindi la lista non ha nulla. Quindi posso solo mettere il numero 3. Ora, voglio aggiungere il numero 5 per la parte ordinata della lista. Così guardo il numero 5. Ho notato che è maggiore di 3. Quindi so che deve essere dopo 3. Così ho messo 3 e 5. Poi voglio inserire il numero 2. Ho notato che il numero 2 è in realtà durare poi sia 3 e 5. Quindi io in realtà devo mettere tutto il modo all'inizio della lista. Quindi devo, tipo, spostare tutto il elementi della lista ordinata così posso fare spazio per il numero 2. Poi vedo il numero 6. Vedo che dovrebbe essere dopo 5. Così ho messo lì. E, infine, guardo il numero 4. E ho notato che dovrebbe essere compresa tra 3 e 5. E poi ho messo lì e lo spostamento tutti gli altri elementi. Dare un senso? Bubble Sort. Quindi bubble sort è fondamentalmente ciò che sei andando a fare-- chiamiamo bolla specie perché si passa attraverso il list-- in realtà è meglio se mi limito a mostrare ti piace questo-- e si sta andando a confrontare numeri adiacenti. E si sta andando a scambiare la loro posizioni se non sono nel giusto ordine. Quindi, fondamentalmente, ciò che sta per accadere è qui, per esempio, si dispone di 8 e 6. Voi sapete che l'ordine sarà ordinato in realtà essere di 6 e 5, giusto? Quindi hai intenzione di scambiare gli ordini. Poi vedo 8 e 4 qui. E faccio la stessa cosa. I Swap di nuovo. E, infine, 2 e 8. Ho anche scambiarli. Si chiama Bubble Sort perché dopo ciascuna di queste iterazioni, in realtà, il maggior numero nell'elenco ottiene tutto fino alla fine della lista. Questo fa senso? Perché mantiene scambiandolo e spostandolo verso destra. OK, quindi questa è la seconda iterazione. Sarebbe la stessa cosa. Farò uno swap e poi l'ultimo. Io che non esistono swap e la lista è ordinata. Quindi, in Bubble Sort, abbiamo praticamente manteniamo passare attraverso la lista e scambiare cose fino a quando mi accorgo che non ho fatto eventuali swap facendo quella iterazione, che significa che la lista è già ordinato. Dare un senso? Parliamo un po ' sul tempo di esecuzione. Quindi voi ragazzi ricordo Big O, Omega e Theta? Sì? OK, qual è Big O, innanzitutto? PUBBLICO: [incomprensibile]. LUCAS: Sì, si chiama un caso peggiore runtime, il che significa solo che è quanto si aspetta il programma a prendere a correre. Come, in termini di-- in questo case-- n. Il numero di elementi nella lista nel caso peggiore. Come, nel caso peggiore possibile. Così per Bubble Sort, per esempio, abbiamo Big O di n quadrati. Perché abbiamo che? Perché Bubble Sort Big O n piazza? PUBBLICO: [incomprensibile]. LUCAS: Sì, così il caso peggiore sarà che dovrò fare n iterazioni. Quindi ciascuna delle iterazioni sta per portare l'elemento più grande alla fine dell'elenco. Così il caso peggiore è che ho per fare che cosa n volte. E per ciascuno di quei tempi, devo fare n swap perché devo confrontare ogni due elementi. Ecco perché è n al quadrato perché è n volte n. Poi, ordinamento per selezione è anche n piazza perché, per ogni iterazione, devo guardare ogni singolo elemento nella lista. E poi trovare il più piccolo, il che significa che devo guardare attraverso n elementi. E devo farlo n volte perché Devo selezionare tutti gli elementi n. Un insertion sort è anche n piazza perché lo scenario peggiore sarà essere, uno, devo inserire n numeri, giusto? Quindi so già che sto andando di avere n iterazioni. Ma per ognuno di quei numeri, se avessi a guardare tutti i numeri in l'elenco ordinato e messo tutto il modo nella parte anteriore, che saranno n piazza perché sarà n volte n nuovo. Dare un senso? Che dire di omega? PUBBLICO: [incomprensibile]. LUCAS: E 'la migliore delle ipotesi. Così è come, in un sacco di volte per ordinamento, la migliore delle ipotesi è quando la lista è già ordinato. Quindi non hanno davvero di fare nulla. Bubble Sort ha la migliore scenario di n. Voi ragazzi sapete perché? PUBBLICO: [incomprensibile]. LUCAS: Sì, se si tiene traccia di se razione dati avesse qualche swap o non, se avete qualcosa come impostato vero se ci fosse una iterazione, se l' lista è già ordinato, in fondo, cosa sta per accadere è che ho intenzione di provare a sostituire ogni due elementi adiacenti. Io vado a vedere che non ci sono swap. E ho appena torno subito. Quindi vuol dire che ho dovuto passare attraverso la lista una volta. Quindi è n perché guardo a n elementi. Perché ordinamento per selezione n Square? Sì, anche se la lista è ordinata, per ogni iterazione di ordinamento per selezione, ho dovrà selezionare l'elemento minimo. Quindi questo significa che devo a guardare a tutti gli elementi della indifferenziati elencare e trovare il minimo per ogni iterazione. Questo fa senso? E inserzione spada è n perché nel caso che sto cercando di inserire la numeri e tutti i numeri, quando ho cercare di inserirli, vedo che sono nella giusta posizione. Non devo andare a controllare tutti gli altri numeri nella lista non ordinata. Ecco perché sarà n. Dare un senso? E che cosa è theta? PUBBLICO: [incomprensibile]. LUCAS: Che cosa, scusa? Dillo di nuovo. PUBBLICO: [incomprensibile]. LUCAS: Esattamente. Così si può vedere che solo la selezione memorizzato in merge sort avere Theta. E questo è perché hai solo theta se entrambi Big O e Omega sono gli stessi. Ok. E, infine, merge sort a dire nel registro n. E poi, come diceva Dan, merge sort è un po 'come allo stesso modo che fate la ricerca binaria. Così si ottiene la lista. E si sta andando a tagliare a metà. E poi li taglia a metà più piccoli. E poi li uniscono. Ragazzi ricordate che, giusto? OK, come egli diceva. OK, puntatori. Così che cosa è un puntatore? PUBBLICO: [incomprensibile]. LUCAS: Un indirizzo. Ok. So che David mostra un mazzo di video di Binky e cose di puntamento l'un l'altro. Ma mi piace pensare di puntatori come un semplice indirizzo. Quindi è una variabile che sta andando per memorizzare un indirizzo. Quindi è proprio questa variabile speciale che è lunga quattro byte. Ricordate, che puntatore a nulla è sempre quattro byte lunghi per il nostro 32-bit macchina così il caso l'apparecchio. E ha solo la posizione di una variabile all'interno di esso. OK, quindi non c'è questa memoria, in fondo. Quindi ogni blocco di memoria ha effettivamente un etichetta, che è l'indirizzo della memoria Slotty. Quindi questo significa che posso avere un puntatore che punta a uno di questi indirizzi. Quindi la ragione per cui useremo i puntatori è se devo ricordare la posizione che una variabile specifica è una memoria. E voi ragazzi ricordate che uno di quelli casi era se ho una funzione se ho davvero si vuole swap per reali, in realtà ho necessario inviare un puntatore. Non è la variabile. Voi ragazzi ricordo che? La differenza between-- qual è il nome? Chiamata per valore e chiamando per riferimento, giusto? OK, sì. Così chiamata per valore. Quando basta inviare una variabile di funzione che si sta solo l'invio di un valore. Quindi, si sta effettivamente inviando una copia della variabile. E il programma non potrebbe importare di meno su se stessa variabile in realtà fa una copia. E che chiama dal riferimento significa che In realtà sto inviando copia della puntatore a quella variabile. Quindi vuol dire che sto inviando il posizione di quella variabile. Così senso che ho la posizione del variabile, quando chiamo la funzione con i puntatori, sono in grado di effettivamente modificare i dati che era in principale. Dare un senso? Anche se, il puntatore è una copia, il puntatore ha ancora il vero indirizzo di la variabile che voglio cambiare. Dare un senso? Quindi la creazione di puntatori. Ricordate, il puntatore ha sempre il tipo che sta puntando ae poi una stella. E poi si mette il nome. Quindi ricorda che ogni volta che avete qualunque stella, è come un puntatore a che qualunque variabile tipo che hai avuto. Così qui a stella, ad esempio, è un puntatore e un intero. E poi char stella è un puntatore stella char e così via. Sì? PUBBLICO: Che cosa succede se abbiamo un puntatore a n a stella x. So che crea un puntatore a x. Ha dichiarare anche x un numero intero? LUCAS: OK, quindi quando dici n stella x, non si sta creando un puntatore a un variabile x. Si sta creando un puntatore di nome x. PUBBLICO: [incomprensibile]. LUCAS: Così quando dico n stella x, sono dicendo, hey, nella memoria, ho intenzione di ottenere uno di questi tre caselle. E ho intenzione di dire che quella sta per essere x, che è andando ad essere un puntatore. E qualcosa di interessante puntatori è che noi dire che essi hanno 4 byte per una macchina a 32-bit. E la ragione di ciò è dovuto al fatto 4 byte sono 32 bit. E le macchine che sono 64 bit effettivamente avere indirizzi puntatori che sono lunghe 64 bit. Quindi, significa solo che la dimensione del indirizzi nella macchina è differente. Così Riferimento e Dereferenziare. Ci sono due operatori che voi ragazzi dovreste ricordare. Il primo è commerciale. Il secondo è stella. Non lasciatevi confondere da quella stella e questo stella perché ricordare che, in questo caso, si ha n stella. E 'come una cosa tutta insieme. Non c'è spazio stella n. Quindi vuol dire che è il tipo. Ricordate, che quando si hanno la stella variabile, sei parlando del tipo. Quando hai appena stella e poi la nome della variabile, significa che stai dereferenziazione il puntatore, che significa che si sta guardando la puntatore, trovare l'indirizzo è indicando, andare a questo indirizzo, e guardando ogni volta che hai lì. Quindi io dico ai miei studenti che quando si hanno stella, si dovrebbe pensare che sia l'abbreviazione del contenuto di. Quindi, se avete un puntatore e si fare puntatore stella, è il contenuto del puntatore. Quindi si va a tutto ciò che sta puntando a e guardare il contenuto costante. E la commerciale è la stessa cosa come indirizzo. Quindi, se ho una variabile a-- come, diamo dire che ho fatto un int uguale 3-- se voglio trovare l'indirizzo di tale una memoria variabile, posso solo fare Ampersand a. Quindi è l'indirizzo di una. Dare un senso? Quindi, ecco un esempio. Questo manca int b, int c. Così int a è uguale 3 mezzi Ho intenzione di andare a memoria. E ho intenzione di trovare uno slot e mettere il numero 3 qui. E poi int b è uguale a 4. Ho intenzione di fare la stessa cosa. Vai a memoria e mettere un numero 4 in una delle caselle. E int uguale a 5. Trova un'altra scatola e mettere un numero di 5. Così che cosa è questa linea che fa fuori? n stella pa equivale commerciale a. Quindi prima di tutto, n stella pa. Che cosa sta facendo? PUBBLICO: [incomprensibile]. LUCAS: Sì, così n stella pa, in primo luogo, dichiara un puntatore chiamato pa. E poi sta assegnando il valore di tale puntatore sia l'indirizzo di un. Così Ampersand a. Poi, se faccio stelle pb, che cosa è un pb stella? Oh, mi dispiace. Questo è anche mancante. n pb stella. Voglio dire pc stelle. Mi dispiace tanto. E 'la stessa cosa. Ma ora sto bene ar creazione di un puntatore a B e poi un puntatore a c. Sì? PUBBLICO: [incomprensibile]? LUCAS: Sì. Quindi, se si va a memoria e si va a la scatola che è designatore per la pa, si sta effettivamente andando a vedere l'indirizzo di un. Ok? Sì? PUBBLICO: [incomprensibile]? LUCAS: Sì, puntatore è un indirizzo. Non dimenticate mai che. E 'come la più importante parte su puntatori. C'è la memorizzazione e l'indirizzo certa variabile. Qualunque altra cosa? Tutte le altre domande? Ok. Così Puntatori e array. Ricordate che quando faccio int matrice 3, fondamentalmente, quello che sto facendo è che io sono, specie di, dichiarando in un puntatore. Quindi array è un po 'come un puntatore a un luogo specifico in memoria in cui assegnati tre slot per gli interi. Questo fa senso? Così, quando faccio int matrice 3, quello che sto facendo, in fondo, è la creazione di tre slot di memoria. Così ho appena trovato tre slot di memoria. Quindi, se lo faccio, poi, un array di stelle, fondamentalmente significa che il contenuto della matrice, il che significa che cancellerò il puntatore, vado a quel luogo che sta indicando, e ho messo il numero uno. E poi, se lo faccio allineamento stella più 1, che è la stessa cosa di fare di array Staffe uno, il che significa solo che vado a il luogo che sta puntando a. E poi il più 1 marche Mi sposto di una posizione. Così vado a questa posizione, in realtà, e mettere il numero due. E poi, finalmente, quando faccio matrice più 2, vado dove punta di array. E poi mi trasferisco in blocchi di memoria. E poi ho messo il numero tre qui. Sì? PUBBLICO: array Così stella è semplicemente dicendo che il primo punto. E si può aggiungere 1, proprio perché siamo veramente solo riferimento a quel primo indirizzo. LUCAS: Già. Perché, per esempio, diciamo di matrice 0, 1 campo, e la matrice 2? Sto dicendo, perché lo fai 0, 1, 2, 3 invece di 1, 2, 3? Uno dei motivi è, uno, computer programmatori preferiscono iniziare a contare da 0. Due è perché quando lo fai matrice 0, è la stessa cosa di fare di array oltre a 0, il che significa che vado a quella posizione, e io non lo faccio saltare tutti i blocchi di memoria. Quindi non mi muovo tutti i blocchi di memoria. Sì? PUBBLICO: [incomprensibile]? LUCAS: Quindi lei sta chiedendo che cosa è la differenza tra fare questo o fare malloc. Una delle differenze è che int matrice 3 è la creazione di un matrice nello stack. E quando lo faccio malloc, esso crea sul mucchio. Questo fa senso? Così come malloc realmente funzionano? Quindi perché abbiamo ancora bisogno di usare malloc? Il tuo compilatore tipo di figure fuori tutto le variabili che sono stati dichiarati. E si crea spazio per tutti Di loro nello stack. Quindi tutte le variabili stanno andando essere da qualche parte nello stack. Così qui è le variabili di ambiente. Quindi, fondamentalmente, lo spazio per le variabili in memoria viene allocata a tempo di compilazione. Quindi significa che il computer ha di conoscere tutte quelle variabili anticipo. Non ha bisogno di sapere quale valore si sta andando a mettere in loro. Ma ha bisogno di sapere come quantità di memoria avete bisogno. Ma ora diciamo che, per esempio, si sta creando un array o di prendere una stringa che si sta prendendo dall'utente. Tu non sai quanto tempo la stringa sta per essere, per esempio. Quindi non si sa esattamente quante blocchi di memoria si allocano, giusto? Quindi in realtà non ha senso per di dire mettere 100 caratteri. E poi cosa succede se l'utente scrive 150? Si sta andando ad essere avvitato. Quindi, fondamentalmente, non si può essere sicuri di come quantità di memoria è necessario allocare quando si compila il programma. Sai solo che il tempo di esecuzione. Ecco perché avete la heap. Così l'heap sta per avere memoria che si sta assegnando durante la durata del programma in esecuzione. Quindi, fondamentalmente, quando si fa malloc, cosa che stai facendo è l'allocazione di memoria a runtime, il che significa che sei decidendo proprio in quel momento che si dovrebbe avere quella memoria. Ecco, questo è quando si sta assegnazione. Questo fa senso? Quindi ricorda, lo stack ha variabili che vengono creati in fase di compilazione. E poi il mucchio ha variabili che vengono creati, come si va con malloc, per esempio. PUBBLICO: [incomprensibile]? LUCAS: Così è GetString andare a chiamare malloc. Lasciatemi parlare di malloc, e Mi spiego GetString. Quindi malloc è la stessa cosa come allocazione della memoria. Così sta andando a destinare memoria heap. E sta andando a restituire un puntatore a dove che la memoria è stato assegnato a. Quindi, quando si fare-- qui per example-- n puntatore stella. E poi puntatore è uguale a malloc dimensione di volte 10 pollici. Sto creando un puntatore. E poi sto assegnando tale puntatore a il valore del puntatore che malloc mi dà. Così sto chiedendo malloc è possibile allocare spazio per 10 interi. Questo è quello che sta dicendo. E malloc mi restituisce un puntatore a quel luogo. Dare un senso? Ok. Io E GetString è, in fondo, facendo un chiamata a malloc in modo da poter allocare memoria durante l'esecuzione. Ricordatevi sempre di controllare nulla perché malloc sta per restituire null se non può allocare memoria. Diciamo che si chiede per un ridicolo quantità di memoria. Il computer non sta per essere in grado di allocare più di tanto. Così malloc è solo andare a restituire null. Quindi ricordatevi sempre di controllare se il puntatore che avete ottenuto da malloc è nullo o non perché, se lo è, si potrebbe essere dereferencing un puntatore e causando guasti laterali. E, infine, non dimenticare la memoria libera. Malloc sta creando memoria nella heap. E si deve liberare la memoria prima che il programma termina. OK, questo è tutto per me. Siamo spiacenti, Rob. Grazie. [Applausi] LUCAS: Tutte le ultime domande prima di Rob arriva? No? Sì? PUBBLICO: non ho visto questo uno online. Hai caricato ancora? LUCAS: Credo che Dave è caricarlo presto. DAVE: Sarà pubblicato. LUCAS: Sarà online. PUBBLICO: E 'in su. LUCAS: E 'in su? Ok. Sì? PUBBLICO: [incomprensibile]? LUCAS: Sì, si dovrebbe liberare tutto il memoria che viene messo nel mucchio. PUBBLICO: [incomprensibile]? LUCAS: Sì. Ogni volta che si dispone di una malloc cultura, si dovrebbe avere una cultura libera dopo aver smettere di usare quella variabile. Così malloc e libero sono sempre insieme. I loro migliori amici. Già. Rob? ROB: Vado in fretta. E anche il video sarà messo. Ho il microfono su. OK, quindi settimana cinque roba. La prima cosa che abbiamo è lo stack. Quindi ricorda che c'è solo una pila frame per chiamata di funzione attiva. Vedremo che in un secondo. E anche ricordare ciò che in realtà va in ogni stack frame stanno per essere le variabili locali delle nostre funzioni, gli argomenti che vengono passati nel nostro funzioni, insieme con una coppia altre cose non si ha realmente bisogno di preoccuparsi. Quindi, ecco un esempio di programma in cui, avviso, principale è printfing il ritorno valore di foo 4. foo è solo andare a restituire il valore della barra 4 comma 6. E bar sta per impostare alcuni locali n variabile pari a 4 volte 6. E poi tornare n. Quindi diamo un'occhiata al camino in tutta l'iterazione attuale di questo programma. Quindi c'è la parte inferiore del nostro stack. Ricordate che lo stack cresce. Quindi, nella parte inferiore del nostro stack, abbiamo avere uno stack frame per principale. Quando il programma viene avviato, principale sta andando sempre essere al fondo del nostro stack. E ciò che è dentro la nostra impilare cornice per principale? Quindi, anche se non ci sono locali variabili a principale, come ho detto prima, abbiamo argc e RGV occupare spazio all'interno di stack frame principale. Così principale è ora di andare a chiamare la funzione foo. E questo significa che foo sta per ottenere il proprio stack frame. Così ora siamo dentro di la funzione foo. E ciò che deve andare in stack frame di pippo? Beh, foo ha un argomento n. E n è uguale a 4 in quanto questo è ciò che principale sta passando come argomento di foo. Così ora foo sta per chiamare bar. Che cosa è il bar avrà all'interno della sua 'stack frame? Ha x uguale a 4 y uguale a sei. Ma non è tutto che stiamo andando ad avere nel frame dello stack poiché bar ha anche una variabile locale n. E n stiamo andando a impostare uguale a 24. Così ora bar sta per tornare n. Quindi bar sta tornando a 24 il foo stack frame. E poiché bar torna ora, che significa che stiamo popping lo stack frame per bar fuori della pila. Così tutta la memoria che bar era stato utilizzando è ora dallo stack. Ora, foo è anche andare per tornare alla principale 24. Quindi, ora che foo sta tornando, la memoria foo che stava usando nel suo ' stack frame è anche andato. E ora, principale sta per chiamare printf. Quindi printf è solo un'altra funzione. Quando chiamiamo printf, che sta per essere un altro stack frame per la printf chiamata di funzione. Cosa stiamo passando printf? Questo è ciò che sta per andare sul suo stack frame. Per lo meno, stiamo passando che cento i backslash n e l'argomento 24. Potrebbe avere più nella sua stack frame printf se capita di essere utilizzando alcuni variabili locali. Non lo sappiamo. Ma tutto ciò che va in printf del impilare telaio. E 'intenzione di eseguire la printf. Poi printf e 'fatto. Si tornerà. Infine, principale viene fatto. Principale tornerà. E poi il nostro programma è fatto. Sì? PUBBLICO: Stai vedendo [incomprensibile] argomenti [incomprensibile] parametri? ROB: Quindi c'è una sottile differenza tra argomenti e parametri. E davvero, nel parlare comune, le persone tendono per mescolarli appena tutto il tempo. Ma i parametri sono il formale il nome delle cose. Così argc e argv sono la parametri principale. Gli argomenti sono quello che effettivamente passare come tali parametri. Quindi non quando chiamo foo di 4, 4 è l'argomento che sto passando. E il parametro n, all'interno di foo, assume il valore 4 dal 4 era l'argomento. PUBBLICO: [incomprensibile]? ROB: n è una variabile locale al bar. n è ancora locale a foo, ma è un parametro a foo. Non è una variabile locale. Sì? PUBBLICO: [incomprensibile]? ROB: foo bar è solo chiamare e tornando qualsiasi bar rendimenti. PUBBLICO: [incomprensibile]? ROB: Sì, solo per vedere di più impilare i frame. Sì? PUBBLICO: Perchè foo è stato chiamato prima printf? ROB: Perché foo chiamato prima printf? Così ho potuto avere, invece, fatto qualcosa come int x è uguale a foo di 4 e poi stampati x. Ma invece, ho unito la funzione rimettere in discussione la printf. Ma si noti che non possiamo realmente eseguire la chiamata a printf fino a quando non capire cosa foo di 4 è. Quindi stiamo andando a valutare questo. E solo una volta fatto stanno andando di tornare e valutare questo. Sì? PUBBLICO: Dal momento che sia bar [incomprensibile] valore, perché non abbiamo [incomprensibile]? ROB: Sono totalmente dovrebbero essere int. Che non è stato catturato nel corso più passaggi. Così dovrebbe essere int bar e int foo poiché sia ​​di quelli stanno tornando interi. Void è solo se non stanno andando per restituire i valori effettivi. Sì? PUBBLICO: Se tu avessi una linea sopra il ritorno, [incomprensibile]? ROB: una linea sopra il ritorno? PUBBLICO: Sì. Come se avete fatto printf e [incomprensibile], sarebbe stampare due volte? ROB: Così all'interno di foo? Se avessimo un printf proprio qui? PUBBLICO: Sì. ROB: Quindi, se avessimo un diritto printf qui, sarebbe stampare una volta. Dal momento che stiamo chiamando foo una volta a destra qui, poi ci ha colpito la printf. Poi chiameremo bar. E poi foo torneranno. E questo è tutto. Abbiamo sempre e solo incontriamo printf volta. Sì? PUBBLICO: [incomprensibile] printf chiamando foo perché siamo prima chiamando printf e poi stiamo passando gli argomenti. ROB: Quindi, in teoria, non è printf chiamando foo? Quindi non. Proprio l'ordine che c sta per eseguire queste cose è, prima di poter chiamare una funzione, tutti gli argomenti alla funzione dover essere completamente valutati. Quindi è questo completamente valutata? Sì, è solo una stringa. E 'solo un valore. Poi dobbiamo completamente valutare questo. Una volta fatto questo, ora tutto i suoi argomenti vengono valutati. E ora possiamo fare la chiamata a printf. Sì? PUBBLICO: Una domanda. Se si dispone di una funzione void, deve avete ritorno punto e virgola? ROB: Non fare un punto e virgola ritorno se si dispone di una funzione void. Ok. Così ora alcune cose heap. Così heap è come stiamo andando a trattare con la gestione della memoria dinamica. E questo contrasta direttamente con la pila che noi chiameremmo automatico gestione della memoria. Così in pila, non hai mai veramente avere a che fare con come le variabili locali vengono spinti e spuntato fuori tutti questi stack frame e tutta quella roba. Non dovete preoccuparvi di questo. E 'automatico. Così l'heap è manuale. E il [incomprensibile] proviene da queste funzioni malloc e gratuito. Quindi, ecco un altro programma. Tutto quello che stiamo facendo è mallocing un numero intero. Stiamo riporlo in stella x. Naturalmente, dobbiamo controllare per vedere se x è nullo. Poi andremo a fissare solo ciò che x sta indicando a 50. Stampa ciò che x sta puntando a, print x, e quindi libero x. Così come è questo in realtà andando a guardare se guardiamo il nostro stack e heap? Quindi inizieremo di nuovo. La parte inferiore del nostro stack come prima. Ricordate che ti Heap direttamente oppone la pila? Quindi stiamo andando ad avere la top della nostra mucchio lassù. Così il fondo del nostro stack, abbiamo il nostro stack frame per principale. Ha lo spazio per argc, argv, e noi ora hanno una variabile x locale, che è un int stella. Quindi stiamo andando a iterare attraverso questo programma. La prima cosa che abbiamo è una chiamata a malloc. Quindi stiamo facendo una chiamata a malloc. Malloc è una funzione. E 'intenzione di ottenere un frame dello stack. Che cosa stiamo passando a malloc? Che sta per entrare dello stack frame. Stiamo passando dimensioni n, che è 4. In modo che è passato a malloc. Cosa fa malloc fare? Ci prende un po 'di spazio sul mucchio. Quindi stiamo per andare al mucchio. E stiamo andando a prendere 4 byte dal mucchio. Quindi cerchiamo di dare solo che un indirizzo arbitrario. 0x123 Basta finta che è un indirizzo che è sul mucchio. Così che cosa è in realtà all'interno di tale regione di memoria all'indirizzo Ox123? Garbage. Quindi non abbiamo nulla in esso memorizzati. Quindi, per quanto ne sappiamo, potrebbe essere qualsiasi cosa. Non si dovrebbe presumere che sia pari a zero. E 'più probabile non è pari a zero. Ritorna Così ora malloc. E cosa facciamo quando ritorni malloc? Abbiamo impostato cosa restituisce. Abbiamo impostato x pari a quello si sta tornando. Così che cosa è che tornando? Sta tornando 0x123 dato che questo è il indirizzo del blocco di memoria che appena stanziato nel mucchio. Quindi tornare 0x123 x sta ora essere impostati pari a 0x123 che, pittoricamente, abbiamo spesso traiamo come x avere un reale freccia che punta a quel blocco. Ma x è solo memorizzando tale indirizzo. Così ora dobbiamo controllare se x è nullo. Non è nullo. Facciamo finta che quella malloc riuscito. Così ora stella x è uguale a 50. Così stella ricorda significa vai a questo indirizzo. Così 0x123 Stiamo andando a vai a questo indirizzo. In modo che ci porta lassù. Cosa stiamo facendo a questo indirizzo? Stiamo memorizzazione 50. Così, dopo questa linea, che è ciò che le cose stanno andando a guardare come. Così ora non è più immondizia lassù. Ora sappiamo che 50 è in quel particolare indirizzo perché abbiamo impostato a quello. Ok? Così ora stiamo andando a stampare f. Così prima che andremo a stampare stella x. Così che cosa è stella x? Ancora una volta, stella x significa andare al cosa che x sta puntando. Allora x sta memorizzando 0x123 Vai a questo. Otteniamo 50. Quindi stampare f che. E questo significa che sta andando a stampare 50. E allora che ritorna. E poi abbiamo la seconda printf. Ora siamo cento p. Se non lo avete visto, che è proprio come si stampa un puntatore. Così abbiamo i cento, cento f, e tutti quelli già. Così per cento p, stampare un puntatore. Quindi x è un puntatore. Quindi, se abbiamo intenzione di stampare x stesso, stiamo stampando ciò che è in realtà dentro x, che è 0x123 Quindi la prima stampa f sta per stampare 50. La seconda stampa f sta stampare 0x123 Sì? PUBBLICO: Usi per cento x per stampare un puntatore? ROB: Così si usa per cento x per stampare un puntatore? Così si può, ma cento x è solo, in generale, per come se avete qualche intero e si desidera stampare come esadecimale. Questo è solo come farlo. Considerando che, per cento d sarebbe stampare come decimale. Questo è dove abbiamo otteniamo per cento d. i è appena intero. cento p è specificamente per i puntatori. Quindi x è un puntatore. Vogliamo usare per cento p. Ma cento x potrebbe funzionare. Sì? PUBBLICO: [incomprensibile]? ROB: Già. Almeno per questo call-- così ho non includerla in qui. Ma questi due argomenti sono necessariamente all'interno di questo stack frame insieme a eventuali variabili locali printf capita di essere utilizzando. E poi la successiva chiamata a printf ora all'interno della printf stack frame è cento p backslash n e qualunque sia il valore di x è, che è 0x123. Sì? PUBBLICO: [incomprensibile]? ROB: Sarà stampare qualcosa che assomiglia a questo. PUBBLICO: [incomprensibile]. ROB: Così la stampa in forma di indirizzo. Sembra un indirizzo. Sì? PUBBLICO: [incomprensibile]? ROB: Perché cosa? PUBBLICO: [incomprensibile]? ROB: Perché è questo puntatore di 4 byte? Quindi ci sono un sacco di 0 di fronte a questo. Quindi è davvero 0x0000000123. Su un sistema a 64 bit, non ci sarebbe un sacco di altri zeri. Sì? PUBBLICO: [incomprensibile]. ROB: Così il primo printf sta per print-- PUBBLICO: [incomprensibile]. ROB: Sì, sta andando a stampare ciò che x sta puntando a. Stella dice che cosa è questo cosa che indica. Prendi. Così che cosa è che puntando? 50. Prendi. Questo è quello che andremo a stampare. Considerando che, il prossimo, che siamo solo x la stampa stessa. Ciò che è dentro di f? 0x123. Ok. E poi, finalmente, abbiamo il libero. Che cosa stiamo passando a liberare? Stiamo passando x. Quella volta ho effettivamente visualizzato nel frame dello stack. Quindi stiamo passando il valore 0x123 per liberare. Così ora libero sa, va bene, Devo andare fino al mucchio e senza che la memoria. Non è più con ciò che è all'indirizzo 0x123. Così libero sta per rilasciare che dal mucchio. Ora il nostro heap è di nuovo vuota. Non ci sono perdite di memoria. Ora libera tornerà. Si noti che x è ancora 0x123. Ma che ora non è memoria valida. Non dovremmo più dereference x. Sì? PUBBLICO: è il ritorno 0 ridondante? ROB: E 'Returen 0 ridondante? Sì. Abbiamo appena messo che lì perché abbiamo un ritorno uno per l'aria. Così è come, sì, lascia includere il ritorno 0. Sì? PUBBLICO: [incomprensibile]? ROB: Così, dopo gratuiti x, cosa succede se cerchiamo di dereference il puntatore? E 'possibile che niente vada storto. E 'possibile che avremo ancora ottenere 50. E 'possibile, inoltre, che tale memoria è ora utilizzato per qualcos'altro. Quindi è un comportamento indefinito. E undefined significa nulla può succedere. Sì? PUBBLICO: [incomprensibile]? ROB: No, quindi se si assegna x a qualcos'altro. Quindi, se qui abbiamo detto x è uguale malloc qualcosa else-- malloc dimensioni event-- poi quel blocco originale di memoria non viene liberata. E abbiamo ufficialmente perso. Questa è una perdita di memoria. Abbiamo perso tutti i riferimenti a tale blocco di memoria. Quindi non c'è modo possiamo mai liberarlo. OK, così poi ritornare 0 significa fatto. Va bene, troppo pieno così stack. Qual è l'idea? Quindi ricorda, heap sta andando giù. Stack sta salendo. Quindi questo era l'esempio da lezione, Penso, in cui principale è solo andare a chiamare questa funzione foo, che sta chiamare se stessa ricorsivamente su e di nuovo. Così pila fotogrammi stanno per lavorare esattamente lo stesso. Quindi stiamo per iniziare con principale come lo stack frame inferiore. Poi principale sta per chiamare foo, che sta per ottenere un frame dello stack. Poi foo sta per chiamare foo ancora una volta, che sta per arrivare un altro stack frame. E poi ancora, e ancora, e ancora, e ancora fino a quando, alla fine, corriamo nel mucchio. Quindi, questo è come si ottiene un overflow dello stack. E a questo punto, si Seg colpa. Oppure avresti veramente criticare seg prima questo punto, ma sì. PUBBLICO: E 'core dump del stessa colpa seg? ROB: così vedrete la segmentazione nucleo colpa dumping. Si ottiene un core dump quando si Seg colpa. Ed è come una discarica di tutti i contenuto della memoria corrente in modo che si può provare e identificare perché si Seg errore. Sì? PUBBLICO: [incomprensibile]? ROB: Quindi un mezzo errore di segmentazione c'è un overflow dello stack. Quindi non necessariamente. Un errore di segmentazione significa che sei ricordo toccante in modo Non si dovrebbe essere. Quindi un modo che ciò accada è, quando si Stack Overflow, iniziamo toccante memoria in un modo che non dovremmo essere. Sì? PUBBLICO: [incomprensibile]? ROB: Così all'interno di un loop infinito. Come, questo è come un infinito ricorsiva loop e così otteniamo un altro pila di inquadrare ogni volta. Ma appena all'interno di un normale infinito mentre tra-- bene, cerchiamo di non stampare anche F-- fare qualcosa. Qualunque cosa. Non stiamo andando a essere sempre un altro stack frame. Stiamo solo andando a continuare a looping su questa singola istruzione. La pila non è in crescita. È il fatto che ogni ricorsiva chiamata ci sta dando una stack frame. Ecco perché otteniamo un overflow dello stack. Sì? PUBBLICO: Quindi, se si ha detto che per ottenere il mentre il ciclo e poi [incomprensibile]? ROB: Quindi, se all'interno del ciclo while c'era una printf, si farebbe ancora colpa non seg. Io non volevo confondere le cose. Sarebbe loop. Si otterrebbe un unico stack cornice per il printf. Poi printf sarebbe tornato. Allora faresti di nuovo ciclo. Si otterrebbe un unico stack cornice per il printf. Sarebbe ritorno. Fotogramma singolo stack. Quindi non stai ricevendo questa infinita accumulando stack frame. PUBBLICO: [incomprensibile]? ROB: Sì. Quindi questo Stack Overflow accade perché nessuno di questi chiamate a foo stanno tornando. Quindi, se ci ritorno, allora avremmo iniziare a perdere stack frame. E poi non avremmo impilare troppo pieno. Ed è per questo che avete bisogno di un caso base per le funzioni personali. Sì? PUBBLICO: è la dimensione potenziale e la impilare per il mucchio lo stesso per tutti i programmi? ROB: Circa. È la dimensione potenziale della pila e mucchio lo stesso per tutti i programmi? Circa. C'è qualche randomizzazione a dove inizia la pila e dove l'heap inizia. Se vi capita di avere un sacco di variabili globali e le cose, si potrebbe togliere un pò di spazio per il vostro heap. In un sistema a 64 bit, è praticamente avere memoria infinita. C'è solo così tanto. Tra 32 bit e 64 bit, che è una differenza significativa. Stai andando a ottenere molto di più impilare e lo spazio di heap su un 64-bit sistema perché c'è solo più indirizzi che possono usare. Ma su un sistema individuale, lo farà essere all'incirca la stessa quantità di pila e lo spazio di heap. Bene. Quindi ultima cosa è la compilazione. Così si dovrebbe sapere questo processo. Ci sono quattro grandi passi. Quindi il primo dovrebbe essere facile da ricordare. Pre-processing. Ha il prefisso pre in esso. Quindi viene prima di tutto. La cosa da ricordare è l'hash. Così definisce hash e hash include in tutti quelli. Quelli sono tutti pre-processore direttive. Queste sono le cose che i pre-processore si prende cura di. Che cosa fa un pre-processore fare? E 'una cosa veramente stupida. Tutto è in grado di sono tutti questi copia, e tagliare e incollare le operazioni. Così hash include di serie i0 dot h. Che cosa è che facendo? E 'afferrare lo standard I0 dot h il file e incollarlo nella top ovunque si dice hash include standard di I0 dot h. E ogni hash definire che abbiamo visto, che cosa è che facendo? Il suo copiando il valore che l'hash definito viene definito come e incolla che ovunque si utilizza il valore. Così il preprocessore non solo molto operazioni di base di testo semplice. Non fa nulla intelligente. Quindi, tutto il resto è più complicato. Quindi, ora che il preprocessore è fatto, abbiamo effettivamente compilare. Così che cosa significa la compilazione? Stiamo andando dal codice c di codice assembly. Sì? PUBBLICO: [incomprensibile]? ROB: Sì, abbiamo preso quella. Così la compilazione. Stiamo andando da c per il montaggio. Quindi questo è un cambiamento di linguaggio vero e proprio. Compilazione sé significa andare da un linguaggio di livello superiore per un linguaggio di livello inferiore. E c è un linguaggio di alto livello rispetto al montaggio. Che cosa è l'Assemblea? Le istruzioni che sono, piuttosto molto, fatto per la CPU. Ma il computer fa ancora non capire il montaggio. Si capisce solo uno e zero. Quindi il passo successivo è l'assemblaggio, che ci porta da queste istruzioni la CPU capisce e realtà li traduce, a gli uni e zeri. Quindi C per montaggio a binario. Ma non ho ancora un eseguibile. Quindi pensare alla biblioteca CS50. Vi abbiamo fornito con un binario per questa biblioteca CS50, che ha GetString e GetInt e tutto il resto. Ma il CS50 library-- in e di itself-- non è eseguibile. Esso non ha una funzione principale. E 'solo un mucchio di binario che è possibile utilizzare. Quindi il collegamento è come mettere insieme tutti di questi diversi file binari in un eseguibile effettivo. Uno che è possibile digitare dot ridurre drasticamente un punto fuori. Quindi questo è come il file che si ha scritto, - qualunque sia il vostro programma è-- Ceaser dot c. Ma ora è stato compilato fino al binario. Così Ceaser dot o. E questo è il nostro CS50 librerie binarie. E sono in corso combinati in un singolo file eseguibile. Sì? PUBBLICO: [incomprensibile]? ROB: Quindi, prima comprende, ricordiamo, l'hash includere è in realtà un fase di pre-processore. Ma questo è separato. Se non si sta utilizzando tutte le funzioni che sono al di fuori del singolo file, allora, no, non è necessario collegare nulla dal momento che hai tutto. Detto questo, printf è collegata in. Se si utilizza mai printf, che è qualcosa che deve essere collegato in perché non hai scritto che. E, infatti, printf è automaticamente collegato in. Sapete come nella riga di comando o quando si digita make, si vede che hanno dash l CS50, che abbia un collegamento in biblioteca CS50? Printf, e cose del genere, sta essere collegate in modo automatico. Tutte le altre domande su qualsiasi cosa? PUBBLICO: [incomprensibile]? ROB: collegamento? Abbiamo un sacco di diversi file binari. Questo è l'esempio canonico che usiamo è biblioteca CS50. Abbiamo raccolto e dato a voi il binario per questa libreria CS50. Si desidera utilizzare GetString nel vostro programma. Così si va e utilizzare GetString. Ma senza il mio codice binario per GetString, quando si compila il codice verso il basso, non si può effettivamente eseguire il programma perché GetString String è non ancora completamente definita. E 'solo quando si collega nel mio binario che contiene GetString che ora, tutti a destra, posso effettivamente eseguire GetString. Il mio file è completo. E posso correre questo. Sì? PUBBLICO: Fa linking convertire il binario eseguibile? Quindi, anche se non si dispone di altri biblioteche, non sarebbe ancora necessario tradurre il [incomprensibile]? ROB: Quindi un eseguibile è ancora in binario. E 'solo unendo un intero mazzo di binari. PUBBLICO: Grazie mille. ROB: Nessun problema. Tutte le altre domande? In caso contrario, siamo tutti insieme. Bene. Grazie. [Applausi] PUBBLICO: Grazie. ROB: Già.