[GIOCO MUSICA] ROB BODEN: Va bene. Quindi, prima cosa prima, video da un volto familiare. [RIPRODUZIONE VIDEO] -Va bene. Questo è CS50, e questo è l'inizio di tre settimane. Mi dispiace che non potevo essere lì con voi oggi, ma mi permetta di introdurre Del CS50 proprio Rob Boden. [END RIPRODUZIONE VIDEO] [Applausi e acclamazioni] ROB BODEN: The nell'elenco in che il video è fantastico. Bene. Quindi, prima, c'è un altro pranzo. E 'domani alle 01:15. Non c'è pranzo questo Venerdì. È con Quora. E Tommy non è ancora arrivato, ma uno dei il popolo vi è l'ex CF testa, Tommy McWilliam. Quindi lui è un ragazzo divertente. Dovresti venire. Bene. Così la settimana scorsa, abbiamo iniziato a sbriciolarsi su ciò che una stringa è davvero. Abbiamo saputo fin dall'inizio che è una sequenza di caratteri. Ma la scorsa settimana, abbiamo approfondito il fatto che ciò che è davvero una sequenza di personaggi, bene, ora abbiamo array di caratteri. E sappiamo che una stringa, un array di caratteri, alla fine, abbiamo questo speciale byte null, questo backslash 0, che indica la fine di la stringa. E così una stringa è un array di personaggi, ma possiamo avere più di solo un array di caratteri, possiamo avere una matrice di qualsiasi tipo di cosa che vogliamo. Quindi, se vi ricordate della scorsa settimana, l' Programma Ages che David ha introdotto molto velocemente. Quindi prima cosa che andremo a fare è chiedere all'utente per un numero intero, la numero di persone nella stanza. Una volta che abbiamo che integer, stiamo dichiarando un array. Notate questa sintassi staffa. Hai intenzione di abituarsi a questo. Quindi stiamo dichiarando un array di interi chiamato età, e ci sono n numeri interi in questa matrice. Quindi questo modello proprio qui, questo 4 int i è uguale a 0, i è minore di n, i plus plus, che è anche sarà un modello che si ottiene molto abituati. Perché questo è più o meno come sei sempre andando per scorrere gli array. Quindi ricorda che n è il lunghezza del nostro array. Ed ecco, noi stiamo chiedendo ripetutamente per l'età del soggetto i nella camera. Dopo questo, scendiamo, e per qualunque ragione arbitraria, abbiamo poi stampare quanti anni stanno andando ad essere un anno da ora. E in esecuzione il programma, andiamo fare le età, puntino età oblique. Quindi, il numero di persone nella stanza, diciamo che ci sono tre. E dire, la prima persona è di 13, successivo è 26, e l'ultimo è 30. Allora che sarà un'iterazione su quei tre persone, stampare 14, 27, e 31. Quindi ricorda che quando si dichiara un array di dimensione n, gli indici che matrice, la matrice ha valori e indici 0, 1, 2, fino fino a n meno 1. Così, quando abbiamo detto che c'erano tre persone in camera, e abbiamo messo in qui la prima iterazione attraverso questo loop, i sta per essere 0. Così nell'indice 0. Stiamo assegnando il primo invecchiare l'utente inserisce. Poi, in quello successivo, stiamo entrando nella n secondo l'utente immette, in accanto a due, l'ultimo n. Quindi notare che una matrice di dimensione tre non ha nulla nell'indice tre. Questo non è valido. Bene. Quindi, tornando qui. Quindi, ora che abbiamo affrontato con gli array, abbiamo una certa familiarità. Ora stiamo andando a passare al comando argomenti della riga, che stanno per essere abbastanza rilevante a questo problema insieme. Quindi, fino ad ora, ogni volta che avete ha dichiarato la funzione principale, abbiamo ha detto int void main. Quindi nulla significa solo che non stiamo passando alcun argomenti a questa funzione. Ora stiamo andando a vedere quella principale può prendere alcuni argomenti. Qui li chiamiamo int argc e staffe argv stringa. Le staffe, ancora una volta, indicando che abbiamo a che fare con gli array. Così qui, parentesi stringa argv, siamo si tratta di un array di stringhe. Così argc, che sta andando per indicare quanti argomenti abbiamo passato a questo programma. E per vedere che cosa significa, chiudiamo questo. OK. Quindi, fino ad ora, abbiamo eseguito ogni programma come età oblique dot. Possiamo anche, nella riga di comando, passato passare argomenti, così il termine, comando argomenti della riga. Così il primo argomento, ciao mondo. Così qui, argc sarebbe tre. E 'il numero degli argomenti nella riga di comando. Argc è sempre almeno 1, dal dot tagliare le età, stessa, conta come uno dei gli argomenti della riga di comando. Allora ciao è il primo. Se matura oblique punto è il zeroth, poi ciao è il primo, e del mondo è l' secondo argomento della riga di comando. Così il argv stringa, stiamo andando a vedere, contiene le stringhe, barra dot età, ciao, e del mondo. E, su richiesta di David, stiamo andando per riprodurre un video che introduce questo. [RIPRODUZIONE VIDEO] -Fino ad ora nei programmi che abbiamo scritto, abbiamo dichiariamo principale, come int void main. E tutto questo tempo, che nulla ha semplicemente stati specificando che il programma non si assume alcuna argomenti della riga di comando. In altre parole, quando un utente esegue una programma, lui o lei può fornire comando gli argomenti della riga di scrittura di ulteriori parole o frasi dopo del programma nome al prompt. Beh, se volete che il vostro programma prendere gli argomenti della riga di comando, uno o più tali parole, abbiamo bisogno di sostituire annullare con un paio di argomenti. Allora facciamolo. Includi CS50.h. Includi io.h. norma Int main. E adesso, invece di nulla, ho intenzione di specificare un int chiamato argc, e un array di stringhe chiamato argv. Ora, argc e argv sono semplicemente convenzioni. Avremmo potuto chiamato questi argomenti più tutto ciò che vogliamo. Ma ciò che è importante è che argc è un int perché, per definizione, è andando a contenere il numero di argomento, la numero di parole in totale che il utente ha digitato a sua richiesta. argv, nel frattempo, l'argomento vettore, è andando ad essere in realtà un array memorizzazione tutte le parole che l'utente ha digitato a sua richiesta. Andiamo a fare qualcosa adesso con uno o più di questi argomenti della riga di comando. In particolare, andiamo avanti e stampa qualunque parola l'utente dopo il nome del programma al prompt. Aprire la staffa. Chiudi staffa. Printf cento s backslash e virgola. Ed ora ho bisogno di dire printf che valore di collegare in quel segnaposto. Voglio che la prima parola che l'utente ha digitato dopo il nome del programma, e così ho intenzione di specificare argv staffa 1, primo parentesi, punto e virgola. Ora, perché la staffa 1 e non 0 staffa? Beh, si scopre, memorizzate automaticamente in argv 0 sta per essere l' nome effettivo del programma. Quindi la prima parola che l'utente digita dopo il nome del programma è, per convenzione, sta per essere memorizzato in argv 1. Vediamo ora compilare e eseguire questo programma. Fai argv 0, dot barra argv 0. Ed ora una parola come ciao. Invio. E non l'abbiamo, ciao. [END RIPRODUZIONE VIDEO] ROB BODEN: Va bene. Chiudere tale. Quindi, dare un'occhiata a quel programma che abbiamo appena introdotto a noi, bene, basta per mostrare, se stampiamo argv 0, fare, ora quello che è, argv 0, dot barra argv 0. Quindi, come previsto, sta stampando la il nome del programma, dal momento che argv 0 è andando sempre di essere il il nome del programma. Ma facciamo qualcosa di un po 'più interessante. Così nel problema set, sarete introdotto a questa funzione, atoi. Quindi cosa usiamo atoi per? Che sta per convertire un stringa in un intero. Quindi, se mi passate la stringa, uno due tre, a atoi, che convertiremo che al numero intero, uno due tre. Quindi stiamo andando a convertire il primo linea di comando per un numero intero, e poi basta stampare il numero intero. Quindi, fondamentalmente, siamo un po ' reimplementando getint, solo l' integer viene immesso al comando linea anziché nel programma interattivo. Allora, facendo argv 0, facciamolo qui dentro, e chiudere quello. Così esecuzione argv 0, e cerchiamo di inserire il integer, uno due tre quattro uno due. Così lo stamperemo il numero intero, una due tre quattro uno due. Ci sono alcune sottigliezze a atoi che si fermerà curarsi di nulla al di là di un carattere numerico valido, ma questo non importa. Allora, cosa pensi che succeda se faccio questo? Segmentation fault. Allora perché? Se si guarda indietro al nostro programma, siamo conversione argv 1, il primo argomento dopo il nome del programma, in un numero intero. Ma non c'è argomento passato dopo il nome del programma. Così qui, vediamo che si tratta di un buggy programma, dal momento che, se proviamo a farlo funzionare senza argomenti, sarà solo in crash. Così un altro schema comune vedrai è qualcosa di simile, se argc è meno di due, indicando che non c'era almeno il nome del programma e primo argomento, poi faremo qualcosa come printf, non abbastanza argomenti della riga di comando. Questo non è probabilmente una buona stampa, è probabilmente qualcosa, come si deve inserire un numero intero nella riga di comando. Mi limiterò a finire lì. E poi ritorno 1. Quindi ricorda che alla fine del nostro programma, se torniamo 0, quella sorta di indica il successo. Ed principale anche automaticamente restituisce 0 se non lo fai. Così qui, stiamo risintonizzare 1 per indicare che questo non è successo. E si può tornare quello che vuoi, solo, 0 indica il successo, e qualsiasi altra cosa indica un fallimento. Quindi cerchiamo di eseguire questa versione delle cose. Così ora, se non entriamo una riga di comando argomento, si dirà correttamente noi, non abbastanza da riga di comando. Non finire la frase. Altrimenti, se abbiamo effettivamente passiamo uno, si può completare il programma. Quindi questo è come si usa argc in Per convalidare il numero di argomenti della riga di comando sono effettivamente passati. Quindi cerchiamo di fare questo programma un po 'più complicato, e guardare il secondo iterazione delle cose. Così ora, stiamo non solo la stampa del primo argomento della riga di comando. Qui, stiamo scorrendo da uguali i int 0, i è inferiore a argc, i plus plus, e la stampa argv, indice i. Quindi questo modello, di nuovo, questo è lo stesso motivo come prima, tranne che invece di chiamare la variabile n, stiamo usando argc. Quindi questo è iterazione di ciascun indice nella matrice e la stampa di ogni elemento di tale matrice. E così, quando si corre questo programma, beh, Io non entro in qualsiasi riga di comando argomenti, quindi solo stampe il nome del programma. Se entro in un sacco di cose, sarà stampare una, ciascuna sulla propria linea. OK. Quindi cerchiamo di prendere questo un ulteriore passo avanti. E invece di stampare ogni argomento sulla propria linea, cerchiamo di stampare ogni carattere di ogni argomento sulla propria linea. Quindi ricorda che argv è un array di stringhe. Così che cosa è una stringa, ma un array di caratteri? Quindi questo significa che argv è davvero un di una matrice di caratteri. Così, approfittando di questo, cerchiamo di ignorare questo per ora. Diciamo solo Consideriamo la stringa argv 0. Quindi, se vogliamo portare ogni carattere di argv 0 sulla propria linea, allora voglio per fare il modello a cui siamo abituati, i è inferiore alla lunghezza della matrice, che qui, è di strlen, che è non quello che voglio fare, stringa s uguale argv 0. Così i è minore della lunghezza della nostra matrice, che in questo caso è un array di personaggi, i plus plus. E così, come abbiamo visto la scorsa settimana, è ideale se ci muoviamo che strlen fuori della condizione, dal momento che n sarà l'aggiunta di la strlen di s ogni volta che andiamo attraverso il ciclo, ed è non ho intenzione di cambiare. Quindi imposteremo uguale a n qui. OK. Così ora, stiamo iterare su ogni indice dell'array. E così, se vogliamo stampare ogni personaggio di tale matrice, cento c è la bandiera vogliamo utilizzare per i caratteri. E ora a i staffa sta per essere il stringa di caratteri indice i, quindi se il stringa erano ciao. poi s 0 sta per essere h, s staffa 1 sarà posta, e così via. Così ora vogliamo combinare queste due cose. Noi vogliamo stampare ogni personaggio di ogni argomento della riga di comando. Quindi stiamo andando ad avere un ciclo for nidificato. E convenzionalmente, il primo contatore Sono io, il prossimo sarà j, n sarà la strlen di argv i, i è minore di n, i plus plus. E ora invece di stampa argv i, così argv staffa i sta per indice - che sta per essere la linea di comando i-esimo argomento, argv i, j sta per essere il carattere j-esima di l'argomento i-esimo. Io mi libererò di questo qui adesso poiché abbiamo messo in quel ciclo. Così è equivalente a pari stringa s argv i, e quindi la staffa s j. Beh, non abbiamo bisogno di dichiarare questo s variabile. Invece, ci limiteremo a combinare queste due in quello che avevamo, argv i, j. SPEAKER 1: [incomprensibile]. ROB BODEN: Good chiamata. Quindi questo è rotto. Se io in realtà sono imbattuto essa, avremmo hanno realizzato questo. Così il contatore mi preoccupo in questo particolare per loop è j, l'iteratore. Così si sarebbe incorrere in problemi, probabilmente un ciclo infinito, se non era fisso che. Ecco perché stiamo anche parlando sul debug di oggi. OK. Quindi cerchiamo di eseguire questo programma. E diciamo in realtà aggiungiamo un printf separato proprio qui che sarà solo la stampa un'altra linea, poiché questo significa che quando abbiamo eseguire il programma, ci sarà un vuoto linea tra ogni carattere di ogni argomento della riga di comando. Beh, vedremo che cosa significa. Oop. Hai qualche bug. Errore implicitamente dichiara funzione di libreria strlen. Quindi, tornando nel nostro programma, ho dimenticato di hash includere string.h. Così string.h sarà il file di intestazione che dichiara la funzione strlen. OK, si compila. Ora, cerchiamo di eseguirlo. Quindi, solo questo. E 'intenzione di stampare la nostra nome del programma, ciao mondo. Sta andando a stampare ogni cosa, ogni carattere, sulla propria linea. OK. Quindi cerchiamo di prendere effettivamente questo un ulteriore passo avanti. E invece di usare string.h, cerchiamo di pensare a come ci piacerebbe implementare la nostra funzione strlen. Quindi darò subito una firma di funzione. Quindi cerchiamo di chiamare in my_strlen, ed è andando a prendere una stringa come argomento, e ci aspettiamo di restituire il lunghezza della stringa. Allora, dov'è quel ragazzo? Sì. OK. Quindi ricorda dalla diapositiva precedente che fu anche dalla settimana scorsa, che un array di caratteri, beh, una stringa, quindi diciamo che questa è la nostra stringa s. Quindi, se s è la stringa, ciao, allora, H-E-L-L-O, nella memoria, che sta per essere, e allora questo backslash 0 personaggio. Quindi, come possiamo ottenere la lunghezza di s? Beh, il trucco è alla ricerca di questo Backlash 0 personaggio, questa nullo terminatore. Quindi, l'algoritmo è in corso essere qualcosa come pochi caratteri sufficienti che - diamo questa mano rappresentano alcuni contatore, chiamiamolo questa lunghezza int. Così, partendo da qui, siamo andando per scorrere la nostra stringa. Così il primo carattere, è H, e non è indietro ridurre drasticamente 0, quindi la lunghezza è 1. Scorrere al carattere successivo, E, e non è backslash 0. La lunghezza è 2. L, 3. L, 4. O, 5. E infine, arriviamo backslash 0, e in modo che i mezzi, bene, questa stringa è finita. Quindi torniamo 5. Quindi, in realtà attuazione di tale, in primo luogo, mia lunghezza n è uguale a 0, la mia mano destra. E stiamo andando a scorrere - SPEAKER 1: [incomprensibile] ROB BODEN: Oh, sparare. Buona chiamata. Boom. Così lunghezza n è uguale a 0. Così ora, lunghezza, mentre s non uguali, e quindi, backslash 0. Quindi ricordate, questo backslash 0, si tratta di un carattere effettivo, e indica la fine della stringa. Proprio come, anche, backslash n è un carattere effettivo. Barra rovesciata 0 va ad indicare la fine della nostra stringa. Non voglio mettere che c'è. E mentre s indicizzati per lunghezza non è pari al terminatore nullo, stiamo solo andando a incrementare la lunghezza. Allora, alla fine del nostro programma, lunghezza è finalmente sta per 5 essere in questo caso. E dobbiamo solo tornare lunghezza. OK. Così ora qui, non lo faccio fare my_strlen. Diciamo compilazione per assicurarsi tutto fila liscio. Ci facevo in 2? O era che 1? Che dovrebbe fare. Bene. Quindi questo è argv 2. Funziona come anticipato, anche se era che quello che ho fatto altrove? Sì. OK. Questa versione di cose non ha avuto la nuova linea printf dopo, ma non fa alcuna differenza. OK. Così ha lavorato come previsto. Ora possiamo anche combinare un passo inoltre, se l'avviso qui, bene, in primo luogo, stiamo afferrando la strlen di argv i, e poi stiamo iterare su ogni carattere in quella stringa. Così, invece di fare che, se noi basta combinare questa logica di attesa fino a quando ci ha colpito backslash 0 a destra in questo ciclo for? Quindi scorrere mentre argv i, j fa Non uguale backslash 0. Quindi cerchiamo di eseguirlo prima. Bene. Ecco, questa condizione sta dicendo - cerchiamo di chiarire questo. Così ora, lasciate che questo sia il nostro argv. Così, quando ho appena eseguito il programma prima, argv è un array di stringhe. E così, se corro con dot barra argv 2, ciao mondo, allora il argv è di per sé lunghezza 3, per argv zero, ciao, e del mondo. E all'interno di ciascuno di questi indici è, di per sé un array, dove questo sarà dot, questo sarà slash, non so se quella era la direzione giusta, mi non credo che fosse. A-R-V dash, bisogno di più spazio. Tagliamo in questo array. Dash 0, e quindi backslash 0 A-R-V. E poi in disordine sarà ciao. Diciamo, H-E backslash 0. E, infine, W-O backslash 0. Quindi l'algoritmo che abbiamo appena scritto, il cicli for nidificati, quello che stanno facendo è, dobbiamo prima l' contrastare i e poi j. Questo sarebbe più facile con codice a schermo, Torniamo al presente. OK. Così notato che i è l'iteratore che è iterare su ogni comando argomento della riga. E j è l'iterazione iteratore su ogni personaggio in quella argomento della riga di comando. Così che cosa questa printf interno sta facendo è, abbiamo printf argv 0 0, printf argv 0 1, printf argv 0 2 0 3 0 4 0 5, 0 6, ma ora, argv 0 7 sta per uguale backslash 0. Allora usciamo che per il ciclo, e ora mi scorre a 1. E ora stiamo andando a stampa argv 1 0, argv 1 1 - bene, ora, dal momento che ho tagliato ciao a breve, argv 1 2 è ancora una volta sarà backslash 0. E così, incrementare i e continua, e così via, fino a quando stampiamo fuori tutti mondo, e questi sono tre riga di comando argomenti, e noi usciamo fuori il ciclo più esterno, e terminare il nostro programma. OK. Quindi cerchiamo di tornare qui. Così otterrai una certa familiarità con argomenti della riga di comando su questo problema particolare set. Ora, debugging. Quindi, probabilmente avete già avuto a che fare un po 'di debug con il precedente problema set. E un modo molto semplice di debugging, in primo luogo, diamo un'occhiata a un programma buggy. Beh, camminando attraverso questo programma, stiamo andando a chiedere l'utente per un integer, afferrare quel numero intero, e poi, arbitrariamente, abbiamo un ciclo while che sta solo andando a diminuire i finché non è uguale a 10. Diciamo solo supporre sto entrando un numero intero maggiore di 10. Così decrementare i finché non è uguale a 10. E poi abbiamo un altro ciclo while che, mentre io non è uguale a 0, siamo andando a diminuire i da 3. Quindi, se vedete l'intento del bug qui, è che questo sarà diminuire i per essere di 10, e poi questo ciclo while volontà decremento i 10, a 7, a 4, a 1, a negativo 2, al negativo 5, e così via, all'infinito negativo, dal momento che i farà in realtà mai uguale a 0. E poi alla fine di questo programma, abbiamo la funzione foo che è in corso di stampa che i. Quindi questo è un programma breve e banale, e il bug è evidente, soprattutto dopo che ho appena detto quello che il bug è stato. Ma l'intento è qui, beh, questo potrebbe effettivamente sembrare un po 'del tuo Le soluzioni da avidi dall'ultimo problema di set, e magari avete qualche ciclo infinito nel programma, e non avete idea cosa sta causando. Quindi una tecnica di debug molto utile è quello di aggiungere solo printfs tutto il codice. Così qui voglio un printf esterno primo ciclo while. E qui voglio un printf, e mi limiterò a stampare i. Io anche fare primo ciclo while, i. All'esterno, secondo ciclo while. Ancora una volta, la stampa all'interno di qui, il valore di i. E corriamo questo. Così dot barra di debug. Immettere un numero intero. Facciamo 13. E boma. Si vede che siamo loop infinito all'interno del secondo ciclo while. Così ora sappiamo che cosa il bug è. Ma printf debug è perfettamente grande, ma una volta che i programmi si più lunga e complicata, ci sono soluzioni più sofisticate per far funzionare le cose. Quindi cerchiamo di rimuovere tutte queste printfs. E facciamo in modo che non ho rompere nulla. OK. Così il programma che stiamo andando introdurre si chiama GDB, per GNU Debugger. Beh, in realtà, cerchiamo di rimuovere debug per un secondo, e fare di nuovo il debug. Beh, in realtà in primo luogo, una buona lezione in argomenti della riga di comando. Si noti che questo comando Clang cioè la compilazione di tutto viene passato nella riga di comando, questi argomenti della riga di comando. Quindi, esattamente come si sta andando di utilizzare argomenti della riga di comando, come abbiamo fatto prima, e come si vedrà in PSET 2, è così che Clang li sta usando. Quindi notare che questa prima bandiera, dash ggdb3, quello che sta dicendo è, Clang, è necessario compilare questo file con il intento che ci sarà alla fine necessità di debug. Quindi, finché si dispone di quella bandiera, allora possiamo GDB debug. E si aprirà il Debugger GNU. Quindi ci sono un sacco di comandi che è necessario per abituarsi. In primo luogo quello che probabilmente vi immediatamente bisogno è Run. Così che cosa è Run intenzione di fare? E 'intenzione di iniziare il nostro programma. Quindi eseguire, il programma di partenza, il programma ci chiede per un numero intero, 13. E poi è loop infinito come previsto, tranne che ho rimosso il printfs, quindi non abbiamo nemmeno vedere che. Uscito normalmente. Oh. E 'possibile che il tutto avvolto viceversa, torna a - ignorando quello. Si supponga che non uscire normalmente. C'è una risposta complicata a questo. Così ora, che non è molto utile. Quindi, solo in esecuzione il nostro programma interno di questo debugger non ci aiuta in qualsiasi modo, dal momento che avremmo potuto appena fatto dot ridurre drasticamente il debug da fuori GDB. Quindi il comando quello che probabilmente vi - e io smetterò questo. Control-d o uscire, sia il lavoro. Quindi cerchiamo di aprire di nuovo. Un altro comando che probabilmente vi vogliono subito abituarsi è rottura. Quindi dovremo rompere il principale, per ora, e poi ti spiego che. Bene, qui vediamo abbiamo impostato un punto di interruzione in questa linea in debug.c. Così che cosa significa rottura è che quando ho digitare la parola, il programma sta per continuare a funzionare fino al Mi ha colpito un punto di interruzione. Così, quando ho colpito esecuzione, il programma si avvia, e poi si rompe appena entra nella funzione principale. Rompere principale sta per essere qualcosa è praticamente comunemente fate. E ora, di presentarvi ad alcuni altri comandi. Si noti qui, che sta dicendo che rotto alla riga 11, che è printf, immettere un numero intero. Così il comando successivo sta per essere come andiamo alla successiva riga di codice. Questo sta per permetterci di passo attraverso il nostro programma riga per riga. Così la prossima. Ora la linea 12, stiamo andando per ottenere il numero intero. Avanti. E se hai appena colpito di nuovo Invio, sarà ripetere l'ultima cosa che hai fatto. Quindi non ho bisogno di digitare successiva ogni volta. Quindi, immettere un numero intero, 13. Così ora, la linea 14, mentre i è maggiore di 10, e farò il prossimo. E vediamo che stiamo andando a diminuire i. Quindi stiamo andando a diminuire i. Così ora, un altro utile comando di stampa. Così Stampa sta per stampare il valore della variabile. Andiamo a far emergere il valore della variabile i. Facciamo stampare i. Sta andando a dire i è 11. Ora siamo di nuovo Avanti mentre i è maggiore di 10. Così ho 'ancora maggiore di 10, dal momento che è 11. i meno meno. Facciamo stampare i. Come previsto, è 10. Così ora, dopo. Sta tornando alla condizione, i è maggiore di 10, ma i è ora 10, così non è maggiore di 10, quindi ci aspettiamo la caduta fuori dal ciclo while. E ora siamo sotto quella riga di codice. E un altro comando, List, è solo andare per visualizzare la precedente e la successiva paio di linee di codice, in caso hai perso te stesso. Così abbiamo appena usciti questo ciclo while, e ora siamo entrati in questo ciclo while, la linea 18. Così, mentre io non uguale a 0. E, poi, i è uguale i meno 3, e faremo notare, questo sarà solo andare avanti. E possiamo stampare i. Ogni comando sorta di ha scorciatoie. Quindi p è l'abbreviazione di stampa. Così possiamo p i. Basta tenere in possesso di n, o continuare a fare Avanti. Stampare i. Si vede ora è negativo 167. Quindi, questo andrà avanti per sempre, ma non davvero per sempre, dal momento che avete appena visto, si sarà effettivamente finire a un certo punto. Quindi, che sta cominciando GDB. Ma facciamo una cosa in GDB. Uh, debug. Quindi, in questo caso particolare, l' loop infinito capitato di essere all'interno di la funzione principale. E per ora, solo accettare il fatto che che sono andando a spostare il ciclo infinito in la funzione foo. Basta ricordare che, alla fine di questa programma, beh, questo era in origine chiamando foo, che era appena andare in stampa i. Ma ora stiamo chiamando foo, che è andando a decrementare i finché non è 0, e quindi stampare quella variabile. OK. Salva questo. Effettuare il debug. E ora, gdb debug. OK. Quindi, se ho solo correre allora io non ho intenzione di essere in grado di intervenire in realtà attraverso la mia riga per riga di programma. Quindi cerchiamo di rompere al principale, e quindi digitare run. Quindi, passare attraverso questo, printf, immettere un numero intero, ottenere il numero intero, 13. Quindi stiamo andando a mantenere decremento fino a quando i è maggiore di 10. Poi stiamo andando a cadere attraverso il ciclo while, e arrivare alla linea - apriamo in su in una finestra separata. Così abbiamo decrementando fino a quando non ero più maggiore di 10, e poi chiamata la funzione foo. Allora cosa è successo appena ho colpito funzione foo, beh, ho chiamato foo, e allora non ho più avuto il controllo su GDB. Quindi, non appena mi ha colpito Accanto a questa linea, cose continuarono fino a questo successo, dove il programma disattivato quando - assumere non esisteva alla fine. L'hai visto mettere in pausa per un po 'però. Allora, perché ho perso il controllo su il programma a quel punto? Beh, quando digito il prossimo, che va a la riga successiva letterale di codice che eseguirà. Così, dopo la linea 21, la riga di codice successiva che verrà eseguito è la linea 22, che è, uscendo dalla principale. Quindi io non voglio andare solo alla successiva riga di codice. Voglio andare nella funzione, foo, e poi una dopo l'altra quelle righe di codice. Quindi, per questo, abbiamo un'alternativa. Facciamo uscire di nuovo. Rompere principale. Uh, 1, Avanti, Avanti, 13, il prossimo, Avanti, Avanti, con attenzione, prima di colpire la linea foo. OK. Così ora, siamo alla riga 21, dove noi chiamiamo foo. Noi non vogliamo scrivere il prossimo, dal momento che sarà solo chiamare la funzione foo, e passare alla riga successiva di codice. Quello che vogliamo usare è Step. Quindi c'è una differenza tra Passo e Next, dove passo passo sul funzione, e Next va sulla funzione. E 'appena esegue la totalità dei la funzione e continua a andare. Così passo sta per portare noi nella funzione, foo. E vediamo qui, ora, siamo tornati a questo ciclo while che è, in teoria, intenzione di continuare per sempre. E se si colpisce Step, quando non è nemmeno una funzione per chiamare, allora è identico al successivo. Quindi è solo quando sei in una linea che sta chiamando una funzione che passo sta per essere diverso dal successivo. Così Passo ci porterà qui. Passo, passo, passo, passo, passo, passo, e Dobbiamo solo ciclo infinito per sempre. Così si potrebbe abituare che come vostro modo di identificare cicli infiniti, è appena premuto questo tasto Invio per vedere dove ti trovi in ​​difficoltà. Ci sono modi migliori per farlo, ma per ora, che è perfettamente sufficiente. E stilisticamente, conforme ai Style 50, avrei dovuto fare questo. OK. Così un ultimo comando per introdurre. Bene, GDB di debug dentro Così, invece di rompere a principale, se conoscere la funzione foo è anche il problema, quindi ho potuto avere solo detto, rompere a foo, invece. Diciamo che mi rompo a sia principale che foo. Così si può impostare come molti punti di interruzione come si desidera. Quando scrivo corsa, sta andando fermarsi al - ooh, cerchiamo di ricompilare, dal momento che Ho cambiato le cose. Vedrai questa linea, Warning, fonte il file è più recente eseguibile. Quindi questo significa che ho appena andato qui e ha cambiato questi per conformarsi a Style 50, ma non ho ricompilare il programma. Così GDB mi rende consapevole di questo. Io smetterò, fare di nuovo il debug, colpito gdb debug. OK. Così ora, torna a quello che stavo facendo. Rompere principale, pausa foo. Ora, se faccio funzionare il programma, quindi è intenzione di continuare fino a quando colpisce un breakpoint. Questo punto di interruzione succede a essere il primo a principale. Ora, invece di fare next, next, next, Avanti, Avanti, fino a quando mi ha colpito foo, mi possibile digitare continuare, che continuerà fino a colpire il successivo punto di interruzione. Devo inserire il numero intero prima. Continuare continuerà fino a quando ho colpito il prossimo breakpoint, che è quella funzione foo. Così Run verrà eseguito fino a colpire un breakpoint, ma è solo la digitazione di esecuzione quando si sta iniziando il programma, e poi, da allora in poi, è continuare. Se ho appena fatto rompere principale e poi corse, sarà rompe a principale, e poi continuare. Dal momento che non ho un punto di rottura a foo, immettere il numero intero, allora ora sono non andare a rompere a foo. E 'solo andando a infinito ciclo finché tale. OK. Ecco, questo è Intro to GDB. Si dovrebbe iniziare ad usarlo nei vostri set di problemi. Può essere molto utile per identificare i bug. Se effettivamente solo, linea per linea, andate attraverso il codice e confrontare ciò che è realmente accadendo con quello che vi aspettate accadere, allora è abbastanza difficile da mancare i bug. OK. Così la scorsa settimana Davide ha portato questa roba di crittografia a chiave segreta per l' prima volta, dove non vogliamo password solo essere memorizzati sul nostro del computer in alcuni file di testo, dove qualcuno può venire e basta aprirlo e leggere. Idealmente, sarebbero criptati in qualche modo. E in Problem Set 2, avrete a che fare con un metodo di crittografia, o, anche, due metodi, ma essi non sono così grandi. Se fai l'edizione hacker, sei anche andando a che fare con decifrare alcune cose. Quindi il problema ora è, bene, anche se abbiamo la crittografia forte algoritmo nel mondo, se si sceglie un particolarmente povera password, quindi si non vi aiuterà molto, perché la gente sarà ancora in grado di capirlo. Anche se vedendo la stringa crittografata e sembra un pasticcio di spazzatura questo significa nulla per loro, se ancora solo bisogno di provare alcune password per capirlo, quindi si non sono molto sicuro. Quindi la visione di un video che rende quel punto. [RIPRODUZIONE VIDEO] -Elmetto, si demonio. Cosa sta succedendo? Cosa stai facendo per mia figlia? Me-Permettetemi di introdurre il brillante giovane chirurgo plastico, il dottor Phillip Schlotkin, il più grande naso uomo di lavoro in tutta la universo, e Beverly Hills. -Vostra Altezza. -Nose lavoro? Non capisco. Ha già avuto un lavoro di naso. E 'stato un dolce sedici presente. -No. Non è quello che pensi. E 'molto, molto peggio. Se non mi dai la combinazione di lo scudo aereo, Dr. Schlotkin sarà dare tua figlia il suo vecchio naso. -No. Dove l'hai preso? -Va bene. Te lo dico. Te lo dico. No, papà. No, non si deve. -Hai ragione, mia cara. Mi mancherà il tuo nuovo naso. Ma io non gli dirò la combinazione, non importa quale. -Molto bene. Dr. Schlotkin, fare la tua peggiore. -Il piacere è mio. [UTENSILI da affilare] -No. Aspetta. Aspetta. Te lo dico. Te lo dico. -Sapevo che avrebbe funzionato. Bene. Dallo a me. -La combinazione è uno. -One. -One. -Two. -Two. -Two. -Tre. -Tre. -Tre. -Four. -Four. -Four. -Five. -Five. -Five. -Quindi, la combinazione è uno, due, tre, quattro, cinque. Questa è la combinazione più stupida Io abbia mai sentito in vita mia. Questo è il genere di cosa che un idiota avrebbe sui suoi bagagli. -Grazie, Altezza. -Che cosa hai fatto? -Ho spento il muro. -No non l'hai fatto. Si è disattivato l'intero film. -Devo aver premuto il pulsante sbagliato. -Beh, rimetterlo su. Mettere il filmato su. -Si, signore. Sì, signore. -Andiamo, Arnold. Vieni, Gretchen. Certo, tu sai che io sarò ancora devono fatturare per questo. [END RIPRODUZIONE VIDEO] ROB BODEN: Va bene. Quindi, ora che stiamo già parlando sicurezza in qualche modo, bello piccolo manifesto di film, così negli ultimi giorni, questi problemi con la NSA monitoraggio di tutto. Può essere difficile da sentire come si avere una sorta di privacy in mondo online, anche se non ho potuto dire ti maggior parte dei dettagli di Prism. Quindi, andando oltre PRISM, non stiamo andando a parlare di questo, ora pensare al vostro portatile. Quindi qui, voglio cambiare al mio account reale, con il mio piccolo pinguino. Così ho impostata una password, e che password è quello che voglio che sia. Ma ricordate che quello che sto registrazione con, quindi questo login richiesta, è qualche programma. E 'qualche programma che era scritto da qualche persona. E così, quella persona, se sono particolarmente dannoso, che potevano hanno detto, va bene, quindi se la password che ho immesso è uguale al mio password reale, o è uguale ad alcune password speciale - David è eccezionale o qualcosa del genere - poi farli entrare Quindi un programmatore malintenzionato potrebbe avere accesso a tutti i vostri Mac, o Finestre, o qualsiasi cosa. Così che non è tanto importante, poiché, Voglio dire, questo è il programma di accesso che è spedito con OS X, centinaia o migliaia di persone hanno recensito questo codice. E così, se, nel codice da qualche parte, si dire se la stringa è uguale uguale David è eccezionale, login, poi qualcuno è sta per essere, come, attendere. Questo non è giusto. Questo non dovrebbe essere qui. Ecco, questo è un modo otteniamo le cose ad essere di tipo sicuro. Ma pensa anche programmi che si scrive. Diciamo che avete scritto il programma di login. Quindi questo programma di login che hai scritto, così ovviamente, sei un buon programmatore. Tu non stai andando a mettere qualsiasi dannoso se x è uguale uguale David è impressionante nel codice. Ma questo programma, quello che fate utilizzare per compilare questo programma? Qualcosa di simile Clang. Quindi, cosa succede se la persona che è accaduto a scrivere Clang speciale alloggiati in Clang qualcosa di simile, se io sono la compilazione del programma di login, quindi immettere il codice nel programma di login che dice, se x è uguale uguale David è fantastico? Quindi non ancora abbastanza, ma abbiamo la stessa emettere qui, dove Clang, bene, migliaia, se non decine di migliaia di persone, hanno esaminato Clang, hanno guardato le sue linee di codice e ha detto, tutto bene, non c'è niente di male qui. Ovviamente, nessuno sta facendo nulla di questo dannoso. Ma ciò che si sta clang, come, cosa succede se compilo Clang? Cosa succede se ho qualche compilatore che compila Clang che inserisce in Clang questo hack speciale che dice, va bene, quando compilo Clang, poi il eseguibile ottengo dovrei appositamente guardare all'interno del programma di login e l'inserto questa password, uguale uguale Dave è incredibile? Quindi ricorda che il compilatore stesso deve essere compilato a un certo punto. Quindi, se ciò che si sceglie di compilare Clang con, è di per sé dannoso, allora si potrebbe essere avvitata tutta senso giù la linea. Così qui, abbiamo Ken Thompson e Dennis Ritchie. Quindi questa è una foto iconica. Dennis Ritchie è sulla destra. Lui è un grande - praticamente ha scritto C. Così si può lo ringrazio per questa classe. Ken Thomson è sulla sinistra. I due fondamentalmente scritto UNIX. Beh, erano maggiori contribuenti in UNIX. Ci sono stati alcuni altri. Così Ken Thompson, a un certo punto, vince il Premio Turing. E il premio Turing, ho sempre sentito si fa riferimento in questo modo, è il Premio Nobel dell'informatica. Così alla Turing Award, deve dare il suo discorso di accettazione. E lui dà questo molto famoso discorso ora, chiamato Riflessioni sulla Fidarsi Trust, che abbiamo collegato Per il sito web del corso. E in questo discorso, egli dice, va bene, così ho scritto UNIX, e ora tutto si la gente utilizza UNIX. Ora, ricordate oggi che Linux è un discendente diretto di UNIX. OS X utilizza direttamente UNIX. Windows non fa tanto, ma molto delle idee sono state prese da UNIX. Così si sale sul palco e dice: tutto bene, ho scritto UNIX. E così voi ragazzi sapete, io sono in grado di accedere in ogni un unico dei computer. Da quando ho messo uno di questi speciale se x uguale uguale Ken Thomson è impressionante, allora io sono autorizzato a effettuare il login. Quindi le persone sono come, bene, come hai fatto? Abbiamo guardato il programma login e nulla c'è. E 'come, beh, ho modificato il compilatore per accedere al programma di login in modo che il programma login adesso dovrà che x è uguale uguale a Ken Thompson è impressionante. E dicono, beh, questo non è vero. Stiamo guardando il compilatore e il compilatore non ha linee di codice come tale. E 'come, OK, ma quello che sono compilazione del compilatore con? E pensano, e lui è, come, beh, Sono quello che ti ha dato il compilatore si utilizza per compilare il compilatore, in modo si sta compilando un compilatore, che è di per sé dannoso, e rompere il programma login. Quindi, in pratica, a quel punto, c'è nessun modo si poteva guardare alla fonte codice del programma di accesso per vedere ciò che è sbagliato. Non si poteva nemmeno guardare in codice sorgente del compilatore per vedere ciò che è sbagliato. Si avrebbe bisogno di guardare la macchina codice, il binario effettiva del compilatore compilato a vedere, aspettare, questi righe di codice non dovrebbero essere qui. Ma Ken Thompson ha preso un passo oltre e ha detto, beh, ci sono questi programmi speciali che in realtà aiutano a leggere il binario di programmi, e quindi se qualcuno ha utilizzato quel programma per leggere il binario, che avrebbero visto questi righe di codice. Ha modificato i programmi da dire, tutti a destra, se stai guardando il compilatore, non mostrano questo particolare insieme di binario. Allora avete bisogno di prendere che un passo ulteriormente e sostanzialmente, che potrebbe avere prese livelli multipli di indirezione, e ad un certo punto, nessuno in realtà andando a controllare. Quindi la morale della storia è, sei non andare di scrivere Clang in questa classe. Hai intenzione di utilizzare l'arrampicata Clang molto in questa classe. Per tutti sapete, Clang è un maligno programma che sta sabotando ogni unico programma hai mai compilato. E per lasciare su quel molto inquietante nota, ci vediamo il Mercoledì. [Applausi] SPEAKER 2: Alla prossima CS50. SPEAKER 3: Non ti azzardare a dire che. Si può fare questo. Hai fatto questo prima, si può fare questo Oggi, si può fare domani. Hai fatto questo per anni. Basta andare lì e farlo. Si può fare questo. [GIOCO MUSICA]