1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Settimana 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 [Questo è CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> Va bene, questo è CS50, e questo è l'inizio di settimana 4, 5 00:00:12,000 --> 00:00:16,000 e questo è uno dei possibili algoritmi di ordinamento più lento. 6 00:00:16,000 --> 00:00:19,000 Quale è stato che abbiamo appena visto lì? 7 00:00:19,000 --> 00:00:24,000 Era bubble sort, in grande ordine O (n ^ 2) + somma, 8 00:00:24,000 --> 00:00:28,000 e in effetti non siamo gli unici in questo mondo a sembrare di sapere 9 00:00:28,000 --> 00:00:30,000 che tipo bolla è o il suo tempo di esecuzione. 10 00:00:30,000 --> 00:00:33,000 In effetti, questo è stato un colloquio con Eric Schmidt di Google 11 00:00:33,000 --> 00:00:45,000 e l'ex senatore Barack Obama a pochi anni fa. 12 00:00:45,000 --> 00:00:48,000 >> Ora, Senatore, tu sei qui a Google, 13 00:00:48,000 --> 00:00:54,000 e mi piace pensare alla presidenza come un colloquio di lavoro. 14 00:00:54,000 --> 00:00:58,000 Ora, è difficile trovare un lavoro come presidente, e si sta andando attraverso i rigori adesso. 15 00:00:58,000 --> 00:01:00,000 E 'anche difficile trovare un lavoro presso Google. 16 00:01:00,000 --> 00:01:05,000 Abbiamo domande, e chiediamo le nostre domande ai candidati, 17 00:01:05,000 --> 00:01:10,000 e questo è da Larry Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Voi pensate che stia scherzando? E 'proprio qui. 19 00:01:14,000 --> 00:01:18,000 Qual è il modo più efficace per ordinare un milione di interi a 32 bit? 20 00:01:18,000 --> 00:01:21,000 [Risate] 21 00:01:21,000 --> 00:01:24,000 Well- 22 00:01:24,000 --> 00:01:26,000 Mi dispiace. >> No, no, no, no. 23 00:01:26,000 --> 00:01:34,000 Credo che il bubble sort sarebbe il modo sbagliato di procedere. 24 00:01:34,000 --> 00:01:39,000 >> Andiamo, chi disse questo? 25 00:01:39,000 --> 00:01:43,000 La scorsa settimana richiamare abbiamo preso una pausa dal codice, almeno per un giorno, 26 00:01:43,000 --> 00:01:46,000 e ha iniziato a concentrarsi su alcune idee di livello superiore e di problem solving, più in generale 27 00:01:46,000 --> 00:01:49,000 nell'ambito della ricerca e l'ordinamento, 28 00:01:49,000 --> 00:01:53,000 e abbiamo introdotto qualcosa che non abbiamo uno schiaffo questo nome la settimana scorsa, 29 00:01:53,000 --> 00:01:56,000 ma la notazione asintotica, il Big O, l'Omega Big, 30 00:01:56,000 --> 00:02:00,000 e talvolta la notazione Big Theta, e questi erano semplicemente modi 31 00:02:00,000 --> 00:02:02,000 di descrivere il tempo di esecuzione di algoritmi, 32 00:02:02,000 --> 00:02:05,000 quanto tempo ci vuole per un algoritmo per l'esecuzione. 33 00:02:05,000 --> 00:02:08,000 >> E si può ricordare che lei ha parlato il tempo di esecuzione in termini di dimensioni 34 00:02:08,000 --> 00:02:11,000 dell'ingresso, che noi generalmente chiamiamo n, qualunque sia il problema potrebbe essere, 35 00:02:11,000 --> 00:02:13,000 dove n è il numero di persone in sala, 36 00:02:13,000 --> 00:02:17,000 il numero di pagine in una rubrica telefonica, e abbiamo iniziato a scrivere le cose 37 00:02:17,000 --> 00:02:21,000 come O (n ^ 2) e O (n) o O (n log n), 38 00:02:21,000 --> 00:02:24,000 e anche quando la matematica non ha funzionato in modo perfetto 39 00:02:24,000 --> 00:02:28,000 ed era n ² - n / 2 o qualcosa del genere 40 00:02:28,000 --> 00:02:31,000 ci sarebbe invece solo buttare via alcuni dei termini di ordine inferiore, 41 00:02:31,000 --> 00:02:34,000 e la motivazione è che ci vuole veramente un 42 00:02:34,000 --> 00:02:37,000 sorta di passaggio obiettivo di valutare 43 00:02:37,000 --> 00:02:39,000 le prestazioni dei programmi o le prestazioni degli algoritmi 44 00:02:39,000 --> 00:02:42,000 che alla fine della giornata non ha nulla a che fare, per esempio, 45 00:02:42,000 --> 00:02:45,000 con la velocità del vostro computer di oggi. 46 00:02:45,000 --> 00:02:47,000 >> Per esempio, se si implementa bubble sort, 47 00:02:47,000 --> 00:02:50,000 o si implementa merge sort sorta o la selezione del computer di oggi, 48 00:02:50,000 --> 00:02:53,000 un computer 2 GHz, e lo si esegue, 49 00:02:53,000 --> 00:02:56,000 e ci vuole un certo numero di secondi, il prossimo anno c'è un 3 GHz 50 00:02:56,000 --> 00:02:59,000 o un 4 GHz del computer, e si potrebbe quindi affermare che "Wow, il mio algoritmo 51 00:02:59,000 --> 00:03:03,000 è ora due volte più veloce, "quando in realtà non è questo il caso, ovviamente. 52 00:03:03,000 --> 00:03:06,000 E 'solo l'hardware ha ottenuto più veloce, ma il computer 53 00:03:06,000 --> 00:03:10,000 non ha, e quindi vogliamo davvero buttare via le cose come 54 00:03:10,000 --> 00:03:13,000 multipli di 2 o multipli di 3, quando si tratta di descrivere 55 00:03:13,000 --> 00:03:17,000 la velocità o la lentezza è un algoritmo e davvero concentrarsi solo 56 00:03:17,000 --> 00:03:20,000 il n o qualche fattore della stessa, 57 00:03:20,000 --> 00:03:24,000 qualche potere loro, come nel caso dei tipi di settimana. 58 00:03:24,000 --> 00:03:27,000 E ricordare che con l'aiuto di merge sort 59 00:03:27,000 --> 00:03:31,000 siamo stati in grado di fare molto meglio di bubble sort e selection sort 60 00:03:31,000 --> 00:03:33,000 e anche l'inserimento di ordinamento. 61 00:03:33,000 --> 00:03:36,000 >> Siamo arrivati ​​fino al n log n, e di nuovo, 62 00:03:36,000 --> 00:03:39,000 Ricordiamo che log n genere si riferisce a qualcosa che cresce 63 00:03:39,000 --> 00:03:43,000 più lentamente n, per cui n log n finora era buona 64 00:03:43,000 --> 00:03:45,000 perché era meno di ² n. 65 00:03:45,000 --> 00:03:47,000 Ma per raggiungere n log n con merge sort 66 00:03:47,000 --> 00:03:51,000 quello che era il germe di un'idea di base che abbiamo dovuto sfruttare 67 00:03:51,000 --> 00:03:54,000 che abbiamo anche sfruttato nuovo in settimana 0? 68 00:03:54,000 --> 00:03:58,000 Come abbiamo fatto a risolvere il problema di ordinamento sapientemente con merge sort? 69 00:03:58,000 --> 00:04:04,000 Qual è stata l'intuizione fondamentale, forse? 70 00:04:04,000 --> 00:04:07,000 Chiunque a tutti. 71 00:04:07,000 --> 00:04:09,000 Ok, facciamo un passo indietro. 72 00:04:09,000 --> 00:04:11,000 Descrivere merge sort con parole tue. 73 00:04:11,000 --> 00:04:15,000 Come ha funzionato? 74 00:04:15,000 --> 00:04:17,000 Ok, ci remare a 0 alla settimana. 75 00:04:17,000 --> 00:04:19,000 Ok, si '. 76 00:04:19,000 --> 00:04:22,000 [Incomprensibile-studente] 77 00:04:22,000 --> 00:04:26,000 Ok, bene, quindi abbiamo diviso la matrice di numeri in 2 pezzi. 78 00:04:26,000 --> 00:04:29,000 Abbiamo risolto ciascuno di questi pezzi, e poi li abbiamo uniti, 79 00:04:29,000 --> 00:04:33,000 e abbiamo visto questa idea prima di prendere un problema che è questo grande 80 00:04:33,000 --> 00:04:36,000 e tagliare in su in un problema che è questo grande o così grande. 81 00:04:36,000 --> 00:04:38,000 >> Ricordiamo l'esempio rubrica telefonica. 82 00:04:38,000 --> 00:04:42,000 Ricordiamo l'auto-conteggio algoritmo settimane fa, 83 00:04:42,000 --> 00:04:45,000 ordina quindi unire è stato riassunto da questo pseudocodice qui. 84 00:04:45,000 --> 00:04:48,000 Quando si è dato n elementi, in primo luogo è stato controllo di integrità. 85 00:04:48,000 --> 00:04:51,000 Se n <2 allora non fare nulla 86 00:04:51,000 --> 00:04:55,000 perché se n <2 allora n è ovviamente 0 o 1, 87 00:04:55,000 --> 00:04:57,000 e quindi se è 0 o 1 non c'è niente da ordinare. 88 00:04:57,000 --> 00:04:59,000 Il gioco è fatto. 89 00:04:59,000 --> 00:05:01,000 La lista è già banalmente ordinato. 90 00:05:01,000 --> 00:05:04,000 Ma per il resto se hai 2 o più elementi di andare avanti e di dividerli 91 00:05:04,000 --> 00:05:06,000 in 2 parti, a destra ea sinistra. 92 00:05:06,000 --> 00:05:09,000 Ordina ciascuna di queste parti, e quindi unire le due metà ordinate. 93 00:05:09,000 --> 00:05:13,000 Ma il problema è che a prima vista questo sembra che stiamo andare in barca. 94 00:05:13,000 --> 00:05:17,000 Questa è una definizione circolare, nel senso che se ti ho chiesto di ordinare questi elementi n 95 00:05:17,000 --> 00:05:22,000 e tu mi stai dicendo "Va bene, va bene, ci ordinare tali elementi n / 2 e le n / 2," 96 00:05:22,000 --> 00:05:27,000 allora la mia prossima domanda sarà "Bene, come si fa a ordinare la n / 2 elementi?" 97 00:05:27,000 --> 00:05:30,000 >> Ma a causa della struttura di questo programma, 98 00:05:30,000 --> 00:05:33,000 perché c'è questo caso base, per così dire, 99 00:05:33,000 --> 00:05:39,000 questo caso particolare che dice che se n è un valore fisso 00:05:42,000 Non risponderemo con quella stessa risposta circolare. 101 00:05:42,000 --> 00:05:46,000 Questo processo, questa ciclicità finirà. 102 00:05:46,000 --> 00:05:50,000 Se io ti chiedo "ordine questi elementi n," e tu dici: "Bene, ordinare questi n / 2," 103 00:05:50,000 --> 00:05:53,000 poi dici: "Va bene, specie questi n / 4, n / 8, n/16," 104 00:05:53,000 --> 00:05:56,000 alla fine si divide per un numero abbastanza grande 105 00:05:56,000 --> 00:05:59,000 che avrete solo 1 elemento a sinistra, a questo punto si può dire, 106 00:05:59,000 --> 00:06:02,000 "Ecco, qui è un elemento ordinato unico." 107 00:06:02,000 --> 00:06:06,000 Quindi la brillantezza di questo algoritmo è qui fino a derivare dal fatto 108 00:06:06,000 --> 00:06:09,000 che una volta che hai tutti questi elenchi ordinati singolarmente, 109 00:06:09,000 --> 00:06:12,000 che sono tutti di dimensione 1, che sembra essere inutile, 110 00:06:12,000 --> 00:06:15,000 una volta che si avvia una loro fusione e la loro unione 111 00:06:15,000 --> 00:06:19,000 si costruisce infine come Rob ha fatto nel video una lista finalmente risolto. 112 00:06:19,000 --> 00:06:22,000 >> Ma questa idea si estende ben al di là di ordinamento. 113 00:06:22,000 --> 00:06:26,000 C'è questa idea integrato in questo programma noto come ricorsione, 114 00:06:26,000 --> 00:06:29,000 l'idea per cui tu sei un programma, 115 00:06:29,000 --> 00:06:32,000 e per risolvere qualche problema ti chiami, 116 00:06:32,000 --> 00:06:36,000 o mettere nel contesto dei linguaggi di programmazione che sono una funzione, 117 00:06:36,000 --> 00:06:39,000 e al fine di risolvere un problema, è la funzione chiami 118 00:06:39,000 --> 00:06:42,000 ancora e ancora e ancora, ma è la funzione 119 00:06:42,000 --> 00:06:44,000 non può chiamarti infinite volte. 120 00:06:44,000 --> 00:06:47,000 Alla fine si deve toccare il fondo, per così dire, 121 00:06:47,000 --> 00:06:49,000 e un po 'hard-coded condizione di base che dice 122 00:06:49,000 --> 00:06:53,000 a questo punto smettere di chiamare se stessi in modo che l'intero processo 123 00:06:53,000 --> 00:06:56,000 infine si ferma, infatti. 124 00:06:56,000 --> 00:06:58,000 Che cosa significa realmente, per ricorsione? 125 00:06:58,000 --> 00:07:01,000 >> Vediamo, se possiamo fare un semplice, banale esempio con, ad esempio, 126 00:07:01,000 --> 00:07:03,000 3 persone con me fino qui sul palco, se qualcuno è comodo. 127 00:07:03,000 --> 00:07:06,000 1, vieni su, 2 e 3. 128 00:07:06,000 --> 00:07:09,000 Se 3 Vuoi venire qui. 129 00:07:09,000 --> 00:07:12,000 Se si vuole stare accanto a me, qui in una linea, si supponga che il problema a portata di mano 130 00:07:12,000 --> 00:07:15,000 è molto banalmente contare il numero di persone che sono qui. 131 00:07:15,000 --> 00:07:18,000 Ma francamente, sono stanco di tutti questi esempi di conteggio. 132 00:07:18,000 --> 00:07:21,000 Si tratta di andare a prendere un po 'di tempo, 1, 2, e punto, punto, punto. 133 00:07:21,000 --> 00:07:23,000 E 'intenzione di prendere per sempre. 134 00:07:23,000 --> 00:07:25,000 Preferirei solo punt questo problema del tutto con l'aiuto di-come ti chiami? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, va bene. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly e? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly, e Willy. 138 00:07:31,000 --> 00:07:34,000 In questo momento mi è stato chiesto da qualcuno la domanda 139 00:07:34,000 --> 00:07:37,000 quante persone siano in questa fase, e non ho idea. 140 00:07:37,000 --> 00:07:40,000 Si tratta di un elenco molto lungo, e così invece ho intenzione di fare questo trucco. 141 00:07:40,000 --> 00:07:43,000 Ho intenzione di chiedere alla persona accanto a me per fare la maggior parte del lavoro, 142 00:07:43,000 --> 00:07:46,000 e una volta che si è fatto fare la maggior parte del lavoro 143 00:07:46,000 --> 00:07:49,000 Ho intenzione di fare la minor quantità di lavoro possibile e solo aggiungere 1 144 00:07:49,000 --> 00:07:51,000 a tutto ciò che la sua risposta è, quindi ci siamo. 145 00:07:51,000 --> 00:07:54,000 Mi è stato chiesto quante persone sono sul palco. 146 00:07:54,000 --> 00:07:57,000 Quante persone sono sul palco a fianco di te? 147 00:07:57,000 --> 00:08:00,000 La sinistra di me? >> Va bene, ma non barare. 148 00:08:00,000 --> 00:08:04,000 Va bene, è vero, ma se vogliamo continuare questa logica 149 00:08:04,000 --> 00:08:08,000 supponiamo che si desidera allo stesso punt questo problema a sinistra di te, 150 00:08:08,000 --> 00:08:11,000 così invece di rispondere direttamente andare avanti e basta passare la palla. 151 00:08:11,000 --> 00:08:14,000 Oh, quante persone sono a sinistra di me? 152 00:08:14,000 --> 00:08:16,000 Quante persone sono a sinistra? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Risate] 155 00:08:27,000 --> 00:08:30,000 Ok, quindi 0, quindi quello che ora Willy ha fatto 156 00:08:30,000 --> 00:08:33,000 è che hai restituito la risposta questa direzione dicendo 0. 157 00:08:33,000 --> 00:08:36,000 Ora, cosa si deve fare? >> 1. 158 00:08:36,000 --> 00:08:39,000 Ok, quindi tu sei l'uno, in modo da dire: "Va bene, ho intenzione di aggiungere 1 159 00:08:39,000 --> 00:08:41,000 a tutto ciò che conta Willy era, "in modo da 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Ora sei 1 in modo la vostra risposta a destra è ora- 161 00:08:43,000 --> 00:08:45,000 1. >> E la mia sarebbe 2. 162 00:08:45,000 --> 00:08:48,000 Bene, allora si sta prendendo la risposta precedente di 1, 163 00:08:48,000 --> 00:08:51,000 aggiungendo la minima quantità di lavoro che si vuole fare, che è +1. 164 00:08:51,000 --> 00:08:55,000 Si dispone ora di 2, e quindi si darmi quale valore? 165 00:08:55,000 --> 00:08:57,000 3, voglio dire, mi dispiace, 2. 166 00:08:57,000 --> 00:08:59,000 Buona. 167 00:08:59,000 --> 00:09:02,000 >> Beh, abbiamo avuto da 0 a sinistra. 168 00:09:02,000 --> 00:09:05,000 Poi abbiamo avuto uno, e poi aggiungere 2, 169 00:09:05,000 --> 00:09:07,000 e ora mi stai consegnando il numero 2, 170 00:09:07,000 --> 00:09:10,000 e così dico, va bene, +1, 3. 171 00:09:10,000 --> 00:09:13,000 Ci sono infatti 3 persone in piedi accanto a me in questa fase, 172 00:09:13,000 --> 00:09:16,000 così abbiamo potuto, ovviamente, fatto questo molto lineare, 173 00:09:16,000 --> 00:09:19,000 molto nel modo ovvio, ma cosa abbiamo realmente? 174 00:09:19,000 --> 00:09:21,000 Abbiamo preso un problema di dimensione 3 inizialmente. 175 00:09:21,000 --> 00:09:24,000 Abbiamo poi si è rotto in un problema di dimensione 2, 176 00:09:24,000 --> 00:09:27,000 quindi un problema di dimensione 1, e infine il caso base 177 00:09:27,000 --> 00:09:29,000 era davvero, oh, non c'è nessuno, 178 00:09:29,000 --> 00:09:33,000 a questo punto Willy restituito efficacemente un hard-coded in un paio di volte, 179 00:09:33,000 --> 00:09:36,000 e la seconda è stata poi gorgogliare, gorgogliare, gorgogliare, 180 00:09:36,000 --> 00:09:39,000 e poi aggiungendo a questa ulteriore 1 181 00:09:39,000 --> 00:09:41,000 abbiamo implementato questa idea di base della ricorsione. 182 00:09:41,000 --> 00:09:44,000 >> Ora, in questo caso non è davvero risolvere un problema 183 00:09:44,000 --> 00:09:46,000 più efficace allora che abbiamo visto finora. 184 00:09:46,000 --> 00:09:48,000 Ma pensare a degli algoritmi che abbiamo fatto sul palco finora. 185 00:09:48,000 --> 00:09:51,000 Abbiamo avuto 8 pezzi di carta alla lavagna, 186 00:09:51,000 --> 00:09:55,000 il video quando Sean cercava il numero 7, e che cosa ha realmente fatto? 187 00:09:55,000 --> 00:09:58,000 Beh, non ha fatto alcun tipo di divide et impera. 188 00:09:58,000 --> 00:10:01,000 Non ha fatto alcun tipo di ricorsione. 189 00:10:01,000 --> 00:10:03,000 Piuttosto ha appena fatto questo algoritmo lineare. 190 00:10:03,000 --> 00:10:07,000 Ma quando abbiamo introdotto il concetto di numeri ordinati in scena dal vivo la settimana scorsa 191 00:10:07,000 --> 00:10:09,000 poi abbiamo avuto questo istinto di andare verso il centro, 192 00:10:09,000 --> 00:10:13,000 a quel punto abbiamo avuto un elenco più ridotto di dimensione 4 o un altro elenco di dimensione 4, 193 00:10:13,000 --> 00:10:17,000 e poi abbiamo avuto lo stesso identico problema, quindi abbiamo ripetuto, ripetuto, ripetuto. 194 00:10:17,000 --> 00:10:19,000 In altre parole, ci recursed. 195 00:10:19,000 --> 00:10:24,000 La ringrazio molto per i nostri 3 volontari qui per dimostrare la ricorsione con noi. 196 00:10:24,000 --> 00:10:28,000 >> Vediamo se possiamo fare questo ora un po 'più concreta, 197 00:10:28,000 --> 00:10:30,000 soluzione di un problema che ancora una volta abbiamo potuto fare abbastanza facilmente, 198 00:10:30,000 --> 00:10:34,000 ma lo useremo come un trampolino di lancio per l'attuazione del presente idea di base. 199 00:10:34,000 --> 00:10:37,000 Se voglio calcolare la somma di una serie di numeri, 200 00:10:37,000 --> 00:10:39,000 per esempio, se si passa il numero 3, 201 00:10:39,000 --> 00:10:42,000 Io voglio dare il valore di sigma 3, 202 00:10:42,000 --> 00:10:46,000 quindi la somma di 3 + 2 + 1 + 0. 203 00:10:46,000 --> 00:10:48,000 Voglio tornare la risposta 6, 204 00:10:48,000 --> 00:10:51,000 quindi dovremo implementare la funzione di sigma, questa funzione sommatoria 205 00:10:51,000 --> 00:10:54,000 che, ancora una volta, prende in ingresso, e quindi restituisce la sommatoria 206 00:10:54,000 --> 00:10:57,000 di tale numero fino in fondo a 0. 207 00:10:57,000 --> 00:10:59,000 Si potrebbe fare questo piuttosto semplice, no? 208 00:10:59,000 --> 00:11:01,000 Potremmo farlo con un qualche tipo di struttura di ciclo, 209 00:11:01,000 --> 00:11:04,000 così mi permetta di andare avanti e ottenere questo è cominciato. 210 00:11:04,000 --> 00:11:07,000 >> Include stdio.h. 211 00:11:07,000 --> 00:11:09,000 Lasciate che mi entrare in principale per lavorare qui. 212 00:11:09,000 --> 00:11:12,000 Salviamo questo come sigma.c. 213 00:11:12,000 --> 00:11:14,000 Poi ho intenzione di andare qui, e ho intenzione di dichiarare un int n, 214 00:11:14,000 --> 00:11:18,000 e ho intenzione di eseguire le seguenti operazioni mentre l'utente non collabora. 215 00:11:18,000 --> 00:11:22,000 Anche se l'utente non mi ha dato un numero positivo 216 00:11:22,000 --> 00:11:26,000 lasciatemi andare avanti e chiederà loro per GetInt n =, 217 00:11:26,000 --> 00:11:28,000 e fammi dare loro alcune istruzioni per quanto riguarda cosa fare, 218 00:11:28,000 --> 00:11:33,000 così printf ("numero intero positivo per favore"). 219 00:11:33,000 --> 00:11:39,000 Solo una cosa relativamente semplice come questo in modo che per il momento ci ha colpito la linea 14 220 00:11:39,000 --> 00:11:42,000 ora abbiamo un numero intero positivo presumibilmente in n. 221 00:11:42,000 --> 00:11:44,000 >> Ora facciamo qualcosa con esso. 222 00:11:44,000 --> 00:11:50,000 Lasciatemi andare avanti e calcolare la somma, in modo int sum = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma è solo somma, quindi mi sto solo scrivendo nel modo più fantasioso. 224 00:11:54,000 --> 00:11:56,000 Noi chiameremo solo sigma lì. 225 00:11:56,000 --> 00:11:58,000 Questa è la somma, e ora ho intenzione di stampare il risultato, 226 00:11:58,000 --> 00:12:08,000 printf ("La somma è% d \ n", somma). 227 00:12:08,000 --> 00:12:11,000 E poi io restituire 0 per buona misura. 228 00:12:11,000 --> 00:12:15,000 Abbiamo fatto tutto quello che questo programma richiede se non la parte interessante, 229 00:12:15,000 --> 00:12:18,000 che è di attuare effettivamente la funzione sigma. 230 00:12:18,000 --> 00:12:22,000 >> Lasciami andare qui in fondo, e mi dichiaro funzione sigma. 231 00:12:22,000 --> 00:12:26,000 E 'avuto modo di prendere una variabile che è di tipo intero, 232 00:12:26,000 --> 00:12:30,000 e che tipo di dati voglio tornare presumibilmente da sigma? 233 00:12:30,000 --> 00:12:34,000 Int, perché voglio in modo da soddisfare le mie aspettative sulla linea 15. 234 00:12:34,000 --> 00:12:37,000 Qui dentro mi lasci andare avanti e realizzare questo 235 00:12:37,000 --> 00:12:41,000 in modo abbastanza semplice. 236 00:12:41,000 --> 00:12:45,000 >> Andiamo avanti e dire int sum = 0, 237 00:12:45,000 --> 00:12:47,000 e ora ho intenzione di andare un po 'per il ciclo qui 238 00:12:47,000 --> 00:12:50,000 che sta per dire qualcosa del genere, 239 00:12:50,000 --> 00:13:01,000 for (int i = 0; I <= numero, i + +) somma + = i. 240 00:13:01,000 --> 00:13:05,000 E poi ho intenzione di tornare somma. 241 00:13:05,000 --> 00:13:07,000 Avrei potuto implementato questo in molti modi. 242 00:13:07,000 --> 00:13:09,000 Avrei potuto usare un ciclo while. 243 00:13:09,000 --> 00:13:11,000 Avrei potuto saltato utilizzando la variabile somma, se volevo davvero, 244 00:13:11,000 --> 00:13:15,000 ma in breve, non ci resta che una funzione che, se non mi goof dichiara somma è 0. 245 00:13:15,000 --> 00:13:18,000 Poi scorre da 0 in su attraverso il numero, 246 00:13:18,000 --> 00:13:23,000 e ad ogni iterazione aggiunge che il valore corrente di somma e quindi restituisce somma. 247 00:13:23,000 --> 00:13:25,000 >> Ora, c'è una leggera ottimizzazione qui. 248 00:13:25,000 --> 00:13:29,000 Questo è probabilmente un passo sprecato, ma così sia. Questo va bene per ora. 249 00:13:29,000 --> 00:13:32,000 Siamo almeno in maniera accurata e andando 0 tutto il senso in su. 250 00:13:32,000 --> 00:13:34,000 Non è molto difficile e piuttosto semplice, 251 00:13:34,000 --> 00:13:37,000 ma si scopre che con la funzione sigma abbiamo la stessa possibilità 252 00:13:37,000 --> 00:13:39,000 come abbiamo fatto qui sul palco. 253 00:13:39,000 --> 00:13:42,000 Sul palco abbiamo contato quante persone erano accanto a me, 254 00:13:42,000 --> 00:13:47,000 ma se volessimo contare il numero 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 su fino a 0 potevamo punt simile a una funzione 256 00:13:51,000 --> 00:13:55,000 che io invece descrivere come ricorsiva. 257 00:13:55,000 --> 00:13:57,000 Qui facciamo un rapido controllo sanità mentale e assicurarsi che non l'ho fatto goof. 258 00:13:57,000 --> 00:14:00,000 >> So che c'è almeno una cosa in questo programma che ho fatto di sbagliato. 259 00:14:00,000 --> 00:14:04,000 Quando premi invio faccio a ottenere qualsiasi tipo di inveire contro di me? 260 00:14:04,000 --> 00:14:06,000 Cosa farò da urlato a circa? 261 00:14:06,000 --> 00:14:11,000 Si ', ho dimenticato il prototipo, quindi sto usando una funzione chiamata sigma sulla linea 15, 262 00:14:11,000 --> 00:14:16,000 ma non è dichiarata fino a riga 22, quindi meglio andare in modo proattivo qui 263 00:14:16,000 --> 00:14:22,000 e dichiarare un prototipo, e dirò int sigma (int numero), e questo è tutto. 264 00:14:22,000 --> 00:14:24,000 È implementato in basso. 265 00:14:24,000 --> 00:14:27,000 >> Oppure un altro modo avrei potuto risolvere il problema, 266 00:14:27,000 --> 00:14:30,000 Potrei spostare la funzione lassù, che non è male, 267 00:14:30,000 --> 00:14:32,000 ma almeno quando i vostri programmi cominciano a diventare lungo, francamente, 268 00:14:32,000 --> 00:14:35,000 Penso che ci sia un valore in avere sempre principale nella parte superiore 269 00:14:35,000 --> 00:14:38,000 in modo che nel lettore può aprire il file e poi subito a vedere 270 00:14:38,000 --> 00:14:40,000 cosa sta facendo il programma senza dover cercare attraverso di essa 271 00:14:40,000 --> 00:14:42,000 cercando quella funzione principale. 272 00:14:42,000 --> 00:14:49,000 Scendiamo alla mia finestra di terminale qui, provare a fare sigma fare sigma, 273 00:14:49,000 --> 00:14:51,000 e ho fatto un casino anche qui. 274 00:14:51,000 --> 00:14:55,000 Dichiarazione implicita di GetInt funzione significa che ho dimenticato di fare che altro? 275 00:14:55,000 --> 00:14:57,000 [Incomprensibile-studente] 276 00:14:57,000 --> 00:15:00,000 Bene, così apparentemente un errore comune, quindi cerchiamo di mettere questo qui, 277 00:15:00,000 --> 00:15:04,000 cs50.h, e ora torniamo alla mia finestra di terminale. 278 00:15:04,000 --> 00:15:08,000 >> Io pulire lo schermo, e io eseguire nuovamente fare sigma. 279 00:15:08,000 --> 00:15:11,000 Sembra che sia compilato. Permettetemi ora di correre sigma. 280 00:15:11,000 --> 00:15:15,000 Io digitare il numero 3, e io ho avuto 6, quindi non è un controllo rigoroso, 281 00:15:15,000 --> 00:15:18,000 ma almeno sembra funzionare a prima vista, ma ora andiamo li tiri fuori, 282 00:15:18,000 --> 00:15:21,000 e cerchiamo di sfruttare effettivamente l'idea di ricorsione, ancora una volta, 283 00:15:21,000 --> 00:15:24,000 in un contesto molto semplice in modo che nel giro di qualche settimana 284 00:15:24,000 --> 00:15:27,000 quando si inizia ad esplorare le strutture dati più elaborate rispetto alle matrici 285 00:15:27,000 --> 00:15:30,000 abbiamo un altro strumento nel toolkit con cui 286 00:15:30,000 --> 00:15:33,000 manipolare le strutture dati come vedremo. 287 00:15:33,000 --> 00:15:36,000 Questo è l'approccio iterativo, il loop approccio. 288 00:15:36,000 --> 00:15:39,000 >> Vorrei invece ora fare questo. 289 00:15:39,000 --> 00:15:44,000 Vorrei invece dire che la somma del numero di 290 00:15:44,000 --> 00:15:48,000 su fino a 0 è in realtà la stessa cosa 291 00:15:48,000 --> 00:15:53,000 numero + sigma (numero - 1). 292 00:15:53,000 --> 00:15:57,000 In altre parole, proprio come sul palco ho giocato d'azzardo a ciascuna delle persone accanto a me, 293 00:15:57,000 --> 00:16:00,000 che a loro volta tenuti andare in barca fino a quando abbiamo finalmente toccato il fondo a Willy, 294 00:16:00,000 --> 00:16:03,000 che ha dovuto restituire un hard-coded risposta del tipo 0. 295 00:16:03,000 --> 00:16:07,000 Qui ora stiamo simile punting a sigma 296 00:16:07,000 --> 00:16:10,000 la stessa funzione come originariamente chiamato, ma l'idea chiave qui 297 00:16:10,000 --> 00:16:12,000 è che non stiamo chiamando sigma identico. 298 00:16:12,000 --> 00:16:14,000 Non stiamo passando n. 299 00:16:14,000 --> 00:16:17,000 Siamo chiaramente di passaggio in numero - 1, 300 00:16:17,000 --> 00:16:20,000 così un problema leggermente più piccolo, problema leggermente più piccolo. 301 00:16:20,000 --> 00:16:23,000 >> Sfortunatamente, questo non è del tutto una soluzione ancora, e prima di rivolgere il 302 00:16:23,000 --> 00:16:26,000 quello che potrebbe essere che salta fuori come ovvio alcuni di voi 303 00:16:26,000 --> 00:16:28,000 lasciatemi andare avanti ed eseguire di nuovo fare. 304 00:16:28,000 --> 00:16:30,000 Sembra che per compilare bene. 305 00:16:30,000 --> 00:16:32,000 Permettetemi di eseguire di nuovo con 6 sigma. 306 00:16:32,000 --> 00:16:37,000 Ops, vorrei eseguire di nuovo con 6 sigma. 307 00:16:37,000 --> 00:16:42,000 Abbiamo visto prima, anche se il tempo accidentalmente scorso. 308 00:16:42,000 --> 00:16:48,000 Perché ho ricevuto questo errore criptico di segmentazione? Gia '. 309 00:16:48,000 --> 00:16:50,000 [Incomprensibile-studente] 310 00:16:50,000 --> 00:16:53,000 Non c'è nessun caso di base, e più in particolare, quello che probabilmente è successo? 311 00:16:53,000 --> 00:16:58,000 Questo è un sintomo di ciò che il comportamento? 312 00:16:58,000 --> 00:17:00,000 Di 'un po' più forte. 313 00:17:00,000 --> 00:17:02,000 [Incomprensibile-studente] 314 00:17:02,000 --> 00:17:05,000 Si tratta di un ciclo infinito in modo efficace, e il problema con cicli infiniti 315 00:17:05,000 --> 00:17:08,000 quando coinvolgono ricorsione in questo caso, una funzione che si definisce, 316 00:17:08,000 --> 00:17:10,000 ciò che accade ogni volta che si chiama una funzione? 317 00:17:10,000 --> 00:17:13,000 Beh, ripenso a come abbiamo posto la memoria in un computer. 318 00:17:13,000 --> 00:17:16,000 Abbiamo detto che c'è questo pezzo di memoria chiamata stack che è in basso, 319 00:17:16,000 --> 00:17:19,000 e ogni volta che si chiama una funzione di memoria un po 'più viene messo 320 00:17:19,000 --> 00:17:24,000 su questa cosiddetta pila contenente variabili locali di quella funzione o parametri, 321 00:17:24,000 --> 00:17:27,000 quindi se sigma Le chiamate sigma sigma chiama sigma 322 00:17:27,000 --> 00:17:29,000  chiama sigma da dove viene questa storia finirà? 323 00:17:29,000 --> 00:17:31,000 >> Beh, alla fine superamenti l'importo totale 324 00:17:31,000 --> 00:17:33,000 di memoria che avete a disposizione sul vostro computer. 325 00:17:33,000 --> 00:17:37,000 È sovraccarico il segmento che si suppone di rimanere all'interno, 326 00:17:37,000 --> 00:17:40,000 e si ottiene questo errore di segmentazione, core dumped, 327 00:17:40,000 --> 00:17:43,000 e che cosa vuol dire core dumped è che ora ho un file chiamato core 328 00:17:43,000 --> 00:17:46,000 che è un file che contiene zero e uno 329 00:17:46,000 --> 00:17:49,000 che in realtà, in futuro saranno utili alla diagnosi. 330 00:17:49,000 --> 00:17:52,000 Se non è evidente a voi dove il bug è 331 00:17:52,000 --> 00:17:54,000 si può effettivamente fare un po 'di analisi forense, per così dire, 332 00:17:54,000 --> 00:17:58,000 su questo file core dump, che, ancora una volta, è solo un insieme di zero e uno 333 00:17:58,000 --> 00:18:02,000 che rappresenta in sostanza lo stato del programma in memoria 334 00:18:02,000 --> 00:18:05,000 nel momento in cui si è schiantato in questo modo. 335 00:18:05,000 --> 00:18:11,000 >> La correzione è che non possiamo tornare alla cieca sigma, 336 00:18:11,000 --> 00:18:14,000 il numero + sigma di un problema un po 'più piccolo. 337 00:18:14,000 --> 00:18:16,000 Abbiamo bisogno di avere un qualche tipo di scenario di base qui, 338 00:18:16,000 --> 00:18:19,000 e quale dovrebbe essere il caso base probabilmente? 339 00:18:19,000 --> 00:18:22,000 [Incomprensibile-studente] 340 00:18:22,000 --> 00:18:25,000 Va bene, a condizione che il numero è positivo in realtà dovremmo restituire questo, 341 00:18:25,000 --> 00:18:29,000 o per dirla in altro modo, se il numero è, per esempio, <= a 0 342 00:18:29,000 --> 00:18:32,000 sai una cosa, io vado avanti e restituire 0, 343 00:18:32,000 --> 00:18:36,000 molto simile a Willy ha fatto, e il resto, ho intenzione di andare avanti 344 00:18:36,000 --> 00:18:41,000 e restituire il presente, quindi non è che molto più breve 345 00:18:41,000 --> 00:18:44,000 rispetto alla versione iterativa che abbiamo montata per prima con un ciclo for, 346 00:18:44,000 --> 00:18:48,000 a meno di notare che c'è questo tipo di eleganza ad esso. 347 00:18:48,000 --> 00:18:51,000 Invece di restituire un numero e l'esecuzione di tutto questo per la matematica 348 00:18:51,000 --> 00:18:54,000 e aggiungendo le cose con le variabili locali 349 00:18:54,000 --> 00:18:57,000 si sta invece dicendo: "Va bene, se questo è un problema super facile, 350 00:18:57,000 --> 00:19:01,000 come il numero è <0, fammi tornare immediatamente 0. " 351 00:19:01,000 --> 00:19:03,000 >> Non abbiamo intenzione di preoccuparsi di supporto i numeri negativi, 352 00:19:03,000 --> 00:19:05,000 così ho intenzione di codificare il valore 0. 353 00:19:05,000 --> 00:19:08,000 Ma per il resto, per attuare questa idea di riassumere 354 00:19:08,000 --> 00:19:11,000 tutti questi numeri insieme si può effettivamente prendere un piccolo morso 355 00:19:11,000 --> 00:19:14,000 di risolvere il problema, proprio come abbiamo fatto qui sul palco, 356 00:19:14,000 --> 00:19:18,000 poi punt il resto del problema alla persona successiva, 357 00:19:18,000 --> 00:19:20,000 ma in questo caso la persona è prossima stessi. 358 00:19:20,000 --> 00:19:22,000 Si tratta di una funzione con nome identico. 359 00:19:22,000 --> 00:19:25,000 Basta passare un problema sempre più piccola e più piccola di volta in volta, 360 00:19:25,000 --> 00:19:28,000 e anche se non abbiamo cose molto formalizzati nel codice qui 361 00:19:28,000 --> 00:19:33,000 questo è esattamente quello che stava succedendo nella settimana 0 con la rubrica. 362 00:19:33,000 --> 00:19:36,000 Questo è esattamente quello che stava succedendo nelle scorse settimane con Sean 363 00:19:36,000 --> 00:19:39,000 e con le nostre dimostrazioni di ricerca di numeri. 364 00:19:39,000 --> 00:19:42,000 Si sta prendendo un problema e che divide ancora e ancora. 365 00:19:42,000 --> 00:19:44,000 >> In altre parole, c'è un modo ora di tradurre 366 00:19:44,000 --> 00:19:47,000 questo costrutto mondo reale, questo costrutto livello superiore 367 00:19:47,000 --> 00:19:51,000 di dividere e conquistare e fare qualcosa di nuovo e di nuovo 368 00:19:51,000 --> 00:19:56,000 nel codice, quindi questo è qualcosa che vedremo di nuovo nel corso del tempo. 369 00:19:56,000 --> 00:20:00,000 Ora, da parte, se siete nuovi a ricorsione si dovrebbe almeno capire ora 370 00:20:00,000 --> 00:20:02,000 perché questo è divertente. 371 00:20:02,000 --> 00:20:05,000 Ho intenzione di andare a google.com, 372 00:20:05,000 --> 00:20:17,000 e sto andando alla ricerca di alcuni consigli e suggerimenti su ricorsione, digitare. 373 00:20:17,000 --> 00:20:21,000 Dite alla persona accanto a te, se non ridevano solo ora. 374 00:20:21,000 --> 00:20:23,000 Intendevi ricorsione? 375 00:20:23,000 --> 00:20:25,000 Intendevi-ah, ci siamo. 376 00:20:25,000 --> 00:20:28,000 Ok, ora che è il resto di tutti. 377 00:20:28,000 --> 00:20:30,000 Un piccolo uovo di Pasqua incorporato da qualche parte in Google. 378 00:20:30,000 --> 00:20:33,000 Per inciso, uno dei link che abbiamo messo sul sito web del corso 379 00:20:33,000 --> 00:20:36,000 per oggi è proprio questa griglia di vari algoritmi di ordinamento, 380 00:20:36,000 --> 00:20:39,000 alcuni dei quali abbiamo visto la scorsa settimana, ma la cosa bella di questa visualizzazione 381 00:20:39,000 --> 00:20:43,000 come si tenta di avvolgere la vostra mente intorno a varie cose legate agli algoritmi 382 00:20:43,000 --> 00:20:46,000 sapere che si può molto facilmente ora iniziare con diversi tipi di ingressi. 383 00:20:46,000 --> 00:20:50,000 Tutti gli ingressi invertiti, gli ingressi principalmente filtrate, gli ingressi casuale e così via. 384 00:20:50,000 --> 00:20:53,000 Come si tenta di, ancora una volta, distinguere queste cose nella tua mente 385 00:20:53,000 --> 00:20:57,000 si rendono conto che questo URL sul sito web del corso sulla pagina Lectures 386 00:20:57,000 --> 00:21:00,000 potrebbe aiutare a ragionare su alcuni di questi. 387 00:21:00,000 --> 00:21:05,000 >> Oggi finalmente a risolvere il problema da un po 'indietro, 388 00:21:05,000 --> 00:21:08,000 che è stato che questa funzione di scambio non ha funzionato, 389 00:21:08,000 --> 00:21:12,000 e quello che era il problema fondamentale con questo swap funzione, 390 00:21:12,000 --> 00:21:15,000 il cui obiettivo è, ancora una volta, a scambiare un valore qui e qui 391 00:21:15,000 --> 00:21:17,000 in modo tale che questo accade? 392 00:21:17,000 --> 00:21:20,000 Questo in realtà non funziona. Perché? 393 00:21:20,000 --> 00:21:22,000 Gia '. 394 00:21:22,000 --> 00:21:28,000 [Incomprensibile-studente] 395 00:21:28,000 --> 00:21:31,000 Esattamente, la spiegazione di questo bugginess 396 00:21:31,000 --> 00:21:34,000 era semplicemente perché quando si chiamano funzioni in C 397 00:21:34,000 --> 00:21:38,000 e queste funzioni richiedono argomenti, come a e b qui, 398 00:21:38,000 --> 00:21:42,000 si passa su una copia di qualsiasi valore si sta fornendo a tale funzione. 399 00:21:42,000 --> 00:21:46,000 Non si forniscono i valori originali stessi, 400 00:21:46,000 --> 00:21:49,000 così abbiamo visto questo nel contesto di buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, che sembrava un po 'di qualcosa come questo. 402 00:21:52,000 --> 00:21:57,000 >> Ricordiamo che avevamo x ed y inizializzato a 1 e 2, rispettivamente. 403 00:21:57,000 --> 00:21:59,000 Abbiamo poi stampato quello che erano. 404 00:21:59,000 --> 00:22:03,000 Ho poi sostenuto che stavo scambiando chiamando scambio di x, y. 405 00:22:03,000 --> 00:22:06,000 Ma il problema era che la scambio ha funzionato, 406 00:22:06,000 --> 00:22:10,000 ma solo nell'ambito dello swap stesso funzionamento. 407 00:22:10,000 --> 00:22:13,000 Non appena abbiamo raggiunto la linea 40 quei valori invertiti 408 00:22:13,000 --> 00:22:16,000 sono stati gettati via, e quindi nulla 409 00:22:16,000 --> 00:22:21,000 nella funzione principale originale è stato effettivamente cambiato affatto, 410 00:22:21,000 --> 00:22:26,000 quindi se pensate allora da come si presenta in termini della nostra memoria 411 00:22:26,000 --> 00:22:29,000 se questo lato sinistro della scheda rappresenta- 412 00:22:29,000 --> 00:22:33,000 e io farò del mio meglio per tutti di vedere questo, se questo lato sinistro della scheda 413 00:22:33,000 --> 00:22:37,000 rappresenta, per esempio, la RAM, e lo stack è destinato a crescere su in questo modo, 414 00:22:37,000 --> 00:22:43,000 e che noi chiamiamo una funzione come principale, e principale dispone di 2 variabili locali, x e y, 415 00:22:43,000 --> 00:22:48,000 cerchiamo di descrivere quelli come x qui, e cerchiamo di descrivere questi come y qui, 416 00:22:48,000 --> 00:22:55,000 e mettiamo i valori 1 e 2, quindi questo è qui principale, 417 00:22:55,000 --> 00:22:58,000 e quando chiama la funzione principale di scambio del sistema operativo 418 00:22:58,000 --> 00:23:02,000 dà la funzione swap sua striscia sua memoria sullo stack, 419 00:23:02,000 --> 00:23:04,000 proprio quadro sullo stack, per così dire. 420 00:23:04,000 --> 00:23:08,000 Si assegna anche 32 bit per questi int. 421 00:23:08,000 --> 00:23:11,000 Succede a chiamarli a e b, ma questo è del tutto arbitraria. 422 00:23:11,000 --> 00:23:13,000 Si potrebbe li hanno chiamati ciò che vuole, ma cosa succede quando principale 423 00:23:13,000 --> 00:23:19,000 chiamate di swap è che ci vuole questo 1, inserisce una copia lì, mette una copia lì. 424 00:23:19,000 --> 00:23:23,000 >> C'è 1 altra variabile locale in swap, però, detto che cosa? >> Tmp. 425 00:23:23,000 --> 00:23:27,000 Tmp, quindi lasciate che mi dia un altro 32 bit qui, 426 00:23:27,000 --> 00:23:29,000 e quello che ho fatto in questa funzione? 427 00:23:29,000 --> 00:23:34,000 Ho detto tmp int ottiene un, quindi una ha 1, così ho fatto questo, quando abbiamo giocato l'ultima volta con questo esempio. 428 00:23:34,000 --> 00:23:39,000 Poi una si b, quindi b è 2, così ora questo diventa 2, 429 00:23:39,000 --> 00:23:42,000 e ora b ottiene temp, quindi temperatura è 1, 430 00:23:42,000 --> 00:23:44,000 così ora b diventa questo. 431 00:23:44,000 --> 00:23:46,000 E 'fantastico. Ha funzionato. 432 00:23:46,000 --> 00:23:49,000 Ma poi, non appena la funzione restituisce 433 00:23:49,000 --> 00:23:52,000 memoria di swap scompare in modo efficace in modo che possa essere riutilizzato 434 00:23:52,000 --> 00:23:58,000 da qualche altra funzione in futuro, ed è ovviamente del tutto invariato. 435 00:23:58,000 --> 00:24:00,000 Abbiamo bisogno di un modo per risolvere questo problema fondamentale, 436 00:24:00,000 --> 00:24:03,000 e oggi avremo finalmente un modo di fare questo in base al quale 437 00:24:03,000 --> 00:24:06,000 possiamo introdurre qualcosa chiamato un puntatore. 438 00:24:06,000 --> 00:24:09,000 Si scopre che siamo in grado di risolvere questo problema 439 00:24:09,000 --> 00:24:12,000 non passando copie di x ed y 440 00:24:12,000 --> 00:24:18,000 ma passando in quello, pensi che, per la funzione di swap? 441 00:24:18,000 --> 00:24:20,000 Si ', per quanto riguarda l'indirizzo? 442 00:24:20,000 --> 00:24:22,000 Non abbiamo ancora parlato di indirizzi in molti dettagli, 443 00:24:22,000 --> 00:24:25,000 ma se questo lavagna rappresenta la memoria del mio computer 444 00:24:25,000 --> 00:24:28,000 potremmo certamente iniziare la numerazione dei byte nella mia RAM 445 00:24:28,000 --> 00:24:31,000 e dire questo è byte # 1, questo è il byte # 2, # 3 byte, 446 00:24:31,000 --> 00:24:35,000 byte # 4, # byte ... 2 miliardi di euro se ho 2 gigabyte di RAM, 447 00:24:35,000 --> 00:24:38,000 così abbiamo potuto sicuramente trovare un qualche schema di numerazione arbitraria 448 00:24:38,000 --> 00:24:41,000 per tutti i singoli byte nella memoria del mio computer. 449 00:24:41,000 --> 00:24:43,000 >> E se invece quando chiamo di swap 450 00:24:43,000 --> 00:24:47,000 piuttosto che passare una copia di x e y 451 00:24:47,000 --> 00:24:51,000 perchè non ho invece passare l'indirizzo di x qui, 452 00:24:51,000 --> 00:24:55,000 l'indirizzo di y qui, in sostanza, l'indirizzo postale 453 00:24:55,000 --> 00:24:59,000 di x e y perché poi scambiare, se è informato 454 00:24:59,000 --> 00:25:01,000 l'indirizzo in memoria di x ed y, 455 00:25:01,000 --> 00:25:04,000 poi scambiare, se lo ha formato un po ', 456 00:25:04,000 --> 00:25:07,000 egli potrebbe guidare a tale indirizzo, per così dire, 457 00:25:07,000 --> 00:25:11,000 x, e cambiare il numero di là, quindi proseguire per l'indirizzo di y, 458 00:25:11,000 --> 00:25:16,000 modificare il numero lì, anche se in realtà non ottenere copie di se stesso quei valori, 459 00:25:16,000 --> 00:25:19,000 quindi, anche se abbiamo parlato di questo come la memoria principale 460 00:25:19,000 --> 00:25:23,000 e questo scambio come nella memoria dei potenti e la parte pericolosa di C 461 00:25:23,000 --> 00:25:28,000 che è una funzione di memoria può toccare qualsiasi parte del computer, 462 00:25:28,000 --> 00:25:32,000 e questo è potente in quanto si possono fare cose molto elaborate con programmi per computer in C. 463 00:25:32,000 --> 00:25:36,000 Questo è pericoloso perché si può anche rovinare molto facilmente. 464 00:25:36,000 --> 00:25:39,000 In effetti, uno dei modi più comuni per i programmi in questi giorni da sfruttare 465 00:25:39,000 --> 00:25:42,000 non è ancora per un programmatore di realizzare 466 00:25:42,000 --> 00:25:45,000 che lui o lei sta permettendo un dato 467 00:25:45,000 --> 00:25:49,000 da scrivere in una locazione di memoria che non era destinato. 468 00:25:49,000 --> 00:25:51,000 >> Per esempio, lui o lei dichiara un array di dimensione 10 469 00:25:51,000 --> 00:25:56,000 ma poi cerca di mettere accidentalmente 11 byte in quella matrice di memoria, 470 00:25:56,000 --> 00:25:59,000 e di iniziare a toccare parti di memoria che non sono più validi. 471 00:25:59,000 --> 00:26:02,000 Solo per questo contestuale, alcuni di voi potrebbe sapere che 472 00:26:02,000 --> 00:26:06,000 Il software richiede spesso per i numeri di serie o chiavi di registrazione, 473 00:26:06,000 --> 00:26:08,000 Photoshop e Word e programmi come questo. 474 00:26:08,000 --> 00:26:12,000 Esistono crepe, come alcuni di voi sanno, on-line dove è possibile eseguire un piccolo programma, 475 00:26:12,000 --> 00:26:14,000 e voilà, nessuna richiesta di più per un numero di serie. 476 00:26:14,000 --> 00:26:16,000 Come è che funziona? 477 00:26:16,000 --> 00:26:21,000 In molti casi, queste cose sono semplicemente trovare nei computer 478 00:26:21,000 --> 00:26:24,000 segmenti di testo in zeri reali del computer e quelli 479 00:26:24,000 --> 00:26:28,000 dove è quella funzione in cui è richiesto il numero di serie, 480 00:26:28,000 --> 00:26:31,000 e sovrascrivere quello spazio, o mentre il programma è in esecuzione 481 00:26:31,000 --> 00:26:33,000 è possibile capire dove la chiave è in realtà memorizzati 482 00:26:33,000 --> 00:26:37,000 usando una cosa chiamata un debugger, e si può rompere il software in questo modo. 483 00:26:37,000 --> 00:26:40,000 Questo non vuol dire che questo è il nostro obiettivo per i prossimi due giorni, 484 00:26:40,000 --> 00:26:42,000 ma ha molto reali ramificazioni. 485 00:26:42,000 --> 00:26:45,000 Quello succede a coinvolgere furto di software, 486 00:26:45,000 --> 00:26:47,000 ma c'è anche compromissione di intere macchine. 487 00:26:47,000 --> 00:26:50,000 >> In effetti, quando i siti web in questi giorni sono sfruttati 488 00:26:50,000 --> 00:26:53,000 e compromesso e dati è trapelato e le password sono rubati 489 00:26:53,000 --> 00:26:58,000 questo molto spesso si riferisce ad una cattiva gestione della propria memoria, 490 00:26:58,000 --> 00:27:01,000 oppure, nel caso di banche dati, mancata anticipazione 491 00:27:01,000 --> 00:27:03,000 ingresso contraddittorio, in modo più su che nelle settimane a venire, 492 00:27:03,000 --> 00:27:07,000 ma per ora solo in anteprima il tipo di danno che si può fare 493 00:27:07,000 --> 00:27:11,000 da non capire bene come funzionano le cose sotto la cappa. 494 00:27:11,000 --> 00:27:14,000 Andiamo di capire perché questo è rotto 495 00:27:14,000 --> 00:27:17,000 con uno strumento che diventerà sempre più utile 496 00:27:17,000 --> 00:27:19,000 i nostri programmi diventano più complessi. 497 00:27:19,000 --> 00:27:21,000 Finora quando hai avuto un bug nel programma 498 00:27:21,000 --> 00:27:23,000 come sei andato sul debug di esso? 499 00:27:23,000 --> 00:27:25,000 Quali sono le vostre tecniche stato così lontano, se insegnata dal TF 500 00:27:25,000 --> 00:27:27,000 o semplicemente autodidatta? 501 00:27:27,000 --> 00:27:29,000 [Studente] Printf. 502 00:27:29,000 --> 00:27:31,000 Printf, così printf è stato probabilmente il tuo amico nel senso che se volete vedere 503 00:27:31,000 --> 00:27:33,000 quello che sta succedendo all'interno del vostro programma 504 00:27:33,000 --> 00:27:36,000 basta mettere printf qui, printf qui, printf qui. 505 00:27:36,000 --> 00:27:38,000 Poi lo si esegue, e si ottiene un sacco di roba sullo schermo 506 00:27:38,000 --> 00:27:43,000 che è possibile utilizzare per dedurre allora che cosa è in realtà che non va nel programma. 507 00:27:43,000 --> 00:27:45,000 >> Printf tende ad essere una cosa molto potente, 508 00:27:45,000 --> 00:27:47,000 ma è un processo molto manuale. 509 00:27:47,000 --> 00:27:49,000 Dovete mettere un printf qui, un printf qui, 510 00:27:49,000 --> 00:27:51,000 e se lo metti in un loop si potrebbe ottenere 100 linee 511 00:27:51,000 --> 00:27:53,000 di output che è quindi necessario passare al setaccio. 512 00:27:53,000 --> 00:27:58,000 Non è un meccanismo molto facile da usare e interattivo per programmi di debug, 513 00:27:58,000 --> 00:28:00,000 ma per fortuna esistono alternative. 514 00:28:00,000 --> 00:28:03,000 C'è un programma, ad esempio, chiamato GDB, il debugger GNU, 515 00:28:03,000 --> 00:28:06,000 che è un po 'arcano nel modo in cui lo si utilizza. 516 00:28:06,000 --> 00:28:08,000 E 'un po' complessa, ma, francamente, 517 00:28:08,000 --> 00:28:11,000 questa è una di quelle cose in cui, se si mettono in questa settimana e la prossima 518 00:28:11,000 --> 00:28:14,000 il cambio di capire qualcosa come GDB 519 00:28:14,000 --> 00:28:18,000 ti farà risparmiare probabilmente decine di ore nel lungo periodo, 520 00:28:18,000 --> 00:28:21,000 E con questo, mi permetta di darle un teaser di come funziona questa cosa. 521 00:28:21,000 --> 00:28:23,000 >> Sono nella mia finestra di terminale. 522 00:28:23,000 --> 00:28:26,000 Lasciatemi andare avanti e compilare questo programma, buggy3. 523 00:28:26,000 --> 00:28:28,000 E 'già aggiornata. 524 00:28:28,000 --> 00:28:31,000 Vorrei correre, proprio come abbiamo fatto un po 'indietro, e anzi, si è rotto. 525 00:28:31,000 --> 00:28:34,000 Ma perché questo? Forse ho sbagliato la funzione di swap. 526 00:28:34,000 --> 00:28:37,000 Forse è a e b. Non mi ha ancora li muoversi correttamente. 527 00:28:37,000 --> 00:28:39,000 Lasciatemi andare avanti e farlo. 528 00:28:39,000 --> 00:28:43,000 Piuttosto che correre buggy3 lasciatemi invece eseguire questo programma GDB, 529 00:28:43,000 --> 00:28:48,000 e ho intenzione di dire l'esecuzione buggy3, 530 00:28:48,000 --> 00:28:52,000 e ho intenzione di inserire un parametro della riga di comando,-tui, 531 00:28:52,000 --> 00:28:55,000 e noi provvederemo a mettere questo in futuro problemi a spec per ricordare. 532 00:28:55,000 --> 00:28:57,000 E ora questa interfaccia in bianco e nero sono saltate fuori che, ancora una volta, 533 00:28:57,000 --> 00:28:59,000 è un po 'opprimente in un primo momento, perché c'è tutta questa 534 00:28:59,000 --> 00:29:02,000 informazioni sulla garanzia qui, ma almeno c'è qualcosa di familiare. 535 00:29:02,000 --> 00:29:04,000 Nella parte superiore della finestra è il mio codice attuale, 536 00:29:04,000 --> 00:29:08,000 e se scorrere verso l'alto qui permettetemi di scorrere fino alla cima del mio file, 537 00:29:08,000 --> 00:29:11,000 e in effetti, c'è buggy3.c, e notare in fondo a questa finestra 538 00:29:11,000 --> 00:29:13,000 Ho questo prompt GDB. 539 00:29:13,000 --> 00:29:16,000 >> Questo non è lo stesso come il mio normale John Harvard prompt. 540 00:29:16,000 --> 00:29:19,000 Si tratta di un messaggio che sta per permettermi di controllare GDB. 541 00:29:19,000 --> 00:29:21,000 GDB è un debugger. 542 00:29:21,000 --> 00:29:24,000 Un debugger è un programma che ti permette di camminare attraverso 543 00:29:24,000 --> 00:29:27,000 esecuzione del programma riga per riga per riga, 544 00:29:27,000 --> 00:29:30,000 lungo la strada a fare tutto quello che vuoi al programma, 545 00:29:30,000 --> 00:29:33,000 anche chiamare le funzioni, o in cerca, ancora più importante, 546 00:29:33,000 --> 00:29:35,000 a valori di variabili diverse. 547 00:29:35,000 --> 00:29:37,000 Andiamo avanti e farlo. 548 00:29:37,000 --> 00:29:40,000 Ho intenzione di andare avanti e digitare al prompt di esecuzione del GDB, 549 00:29:40,000 --> 00:29:43,000 in modo da notare in basso a sinistra dello schermo che ho digitato correre, 550 00:29:43,000 --> 00:29:45,000 e ho premere invio, e che cosa ha che fare? 551 00:29:45,000 --> 00:29:50,000 E 'letteralmente correva il mio programma, ma non ho davvero visto molto andare qui 552 00:29:50,000 --> 00:29:55,000 perché non ho effettivamente detto il debugger 553 00:29:55,000 --> 00:29:57,000 per mettere in pausa in un particolare momento nel tempo. 554 00:29:57,000 --> 00:29:59,000 Basta digitare esecuzione esegue il programma. 555 00:29:59,000 --> 00:30:01,000 Io in realtà non vede nulla. Non posso manipolare. 556 00:30:01,000 --> 00:30:03,000 >> Invece vorrei fare questo. 557 00:30:03,000 --> 00:30:08,000 In questo prompt GDB vorrei invece digitare pausa, entrare. 558 00:30:08,000 --> 00:30:10,000 Non è quello che volevo scrivere. 559 00:30:10,000 --> 00:30:13,000 Facciamo invece digitare pausa principale. 560 00:30:13,000 --> 00:30:15,000 In altre parole, voglio impostare qualcosa chiamato un punto di interruzione, 561 00:30:15,000 --> 00:30:18,000 che è giustamente chiamato perché si romperà o mettere in pausa 562 00:30:18,000 --> 00:30:21,000 esecuzione del programma in quel determinato luogo. 563 00:30:21,000 --> 00:30:23,000 Principale è il nome della mia funzione. 564 00:30:23,000 --> 00:30:25,000 Si noti che GDB è abbastanza intelligente. 565 00:30:25,000 --> 00:30:28,000 È capito che succede principale per avviare o meno allo linea 18 566 00:30:28,000 --> 00:30:32,000 di buggy3.c e osservare qui in alto a sinistra 567 00:30:32,000 --> 00:30:34,000 b + è proprio accanto alla linea 18. 568 00:30:34,000 --> 00:30:38,000 Questo mi ricorda che ho impostato un punto di interruzione alla riga 18. 569 00:30:38,000 --> 00:30:42,000 Questa volta, quando si digita run, ho intenzione di eseguire il mio programma 570 00:30:42,000 --> 00:30:45,000 fino al punto di interruzione che colpisce, 571 00:30:45,000 --> 00:30:48,000 in modo che il programma si fermerà per me in linea 18. 572 00:30:48,000 --> 00:30:50,000 Ci siamo, correre. 573 00:30:50,000 --> 00:30:53,000 Niente sembra essere successo, ma notate in basso a sinistra 574 00:30:53,000 --> 00:30:58,000 programma iniziale, buggy3, breakpoint 1 in linea principale buggy3.c 18. 575 00:30:58,000 --> 00:31:00,000 Cosa posso fare adesso? 576 00:31:00,000 --> 00:31:03,000 >> Notate che può iniziare a digitare cose come stampa, 577 00:31:03,000 --> 00:31:08,000 Non printf, x stampa, e ora che è strano. 578 00:31:08,000 --> 00:31:11,000 Il $ 1 è solo una curiosità, come vedremo 579 00:31:11,000 --> 00:31:14,000 ogni volta che si stampa qualcosa che si ottiene un nuovo valore di $. 580 00:31:14,000 --> 00:31:18,000 E 'così che si può fare riferimento ai valori precedenti solo nel caso in cui, 581 00:31:18,000 --> 00:31:21,000 ma per ora quello che stampa mi sta dicendo è che il valore di x a questo punto della storia 582 00:31:21,000 --> 00:31:26,000 è apparentemente 134514032. 583 00:31:26,000 --> 00:31:29,000 Cosa? Da dove che anche viene? 584 00:31:29,000 --> 00:31:31,000 [Incomprensibile-studente] 585 00:31:31,000 --> 00:31:34,000 In effetti, questo è ciò che chiamo un valore di spazzatura, e non abbiamo ancora parlato di questo, 586 00:31:34,000 --> 00:31:37,000 ma la ragione per cui si inizializza le variabili 587 00:31:37,000 --> 00:31:40,000 è, ovviamente, in modo che abbiano un certo valore che si desidera loro di avere. 588 00:31:40,000 --> 00:31:44,000 Ma il problema è ricordare che è possibile dichiarare variabili 589 00:31:44,000 --> 00:31:46,000 come ho fatto io poco fa nel mio esempio sigma 590 00:31:46,000 --> 00:31:48,000 senza peraltro riuscire a dare un valore. 591 00:31:48,000 --> 00:31:50,000 Ricordiamo quello che ho fatto qui in sigma. 592 00:31:50,000 --> 00:31:52,000 Dichiarai n, ma che valore ha lo do? 593 00:31:52,000 --> 00:31:56,000 Nessuna, perché sapevo che in poche righe 594 00:31:56,000 --> 00:31:59,000 GetInt si sarebbe preso cura del problema di mettere un valore all'interno di n. 595 00:31:59,000 --> 00:32:02,000 >> Ma a questo punto della storia della linea 11 596 00:32:02,000 --> 00:32:05,000 e 12 la linea e la linea 13 e linea 14 597 00:32:05,000 --> 00:32:08,000 durante tali righe qual è il valore di n? 598 00:32:08,000 --> 00:32:10,000 In C proprio non lo so. 599 00:32:10,000 --> 00:32:14,000 E 'in genere un valore spazzatura, qualche numero del tutto casuale 600 00:32:14,000 --> 00:32:17,000 che è rimasto essenzialmente da qualche funzione precedente 601 00:32:17,000 --> 00:32:21,000 essendo stato eseguito, in modo da il programma viene eseguito 602 00:32:21,000 --> 00:32:24,000 Ricordiamo che la funzione riceve, funzione, funzione. 603 00:32:24,000 --> 00:32:27,000 Tutte queste strutture vengono messe sulla memoria, e poi quelli di ritorno funzioni, 604 00:32:27,000 --> 00:32:31,000 e proprio come ho proposto con la gomma la loro memoria alla fine viene riutilizzato. 605 00:32:31,000 --> 00:32:37,000 Beh, si da il caso che questa variabile x in questo programma 606 00:32:37,000 --> 00:32:41,000 sembra aver contenuto un certo valore come spazzatura 134514032 607 00:32:41,000 --> 00:32:44,000 da qualche funzione precedente, non quello che ho scritto. 608 00:32:44,000 --> 00:32:47,000 Potrebbe essere qualcosa che viene efficacemente con il sistema operativo, 609 00:32:47,000 --> 00:32:49,000 qualche funzione sotto la cappa. 610 00:32:49,000 --> 00:32:52,000 >> Va bene, va bene, ma andiamo ora passare alla riga successiva. 611 00:32:52,000 --> 00:32:55,000 Se scrivo "accanto" al prompt di GDB mia e mi ha colpito entrare, 612 00:32:55,000 --> 00:32:58,000 notare che l'evidenziazione si sposta fino alla linea 19, 613 00:32:58,000 --> 00:33:01,000 ma l'implicazione logica è che la linea 18 614 00:33:01,000 --> 00:33:06,000 ha finito "print x" l'esecuzione, quindi se ho di nuovo tipo 615 00:33:06,000 --> 00:33:10,000 Vorrei ora apparire 1, e anzi, lo faccio. 616 00:33:10,000 --> 00:33:14,000 Anche in questo caso, il $ roba è un modo di GDB ricordando 617 00:33:14,000 --> 00:33:17,000 ciò che la storia di stampe sono che hai fatto. 618 00:33:17,000 --> 00:33:21,000 Ora lasciatemi andare avanti e stampare y, e in effetti, y è un valore folle pure, 619 00:33:21,000 --> 00:33:24,000 ma niente di grave, perché in linea 19 che stiamo per assegnare 620 00:33:24,000 --> 00:33:27,000 il valore 2, per cui vorrei scrivere "Avanti". 621 00:33:27,000 --> 00:33:29,000 E ora siamo in linea printf. 622 00:33:29,000 --> 00:33:31,000 Lasciami fare x stampa. 623 00:33:31,000 --> 00:33:34,000 Lasciami fare y stampa. Francamente, mi sto un po 'stanco della stampa di questo. 624 00:33:34,000 --> 00:33:38,000 Meglio invece digitare "x display" e "visualizzazione y," 625 00:33:38,000 --> 00:33:41,000 e ora ogni volta che si digita un comando, in futuro 626 00:33:41,000 --> 00:33:45,000 Sarò ricordato di ciò che è x e y, che cosa è x e y, che cosa è x e y. 627 00:33:45,000 --> 00:33:48,000 >> Posso anche, per inciso, digitare "informazioni locali". 628 00:33:48,000 --> 00:33:50,000 Info è un comando speciale. 629 00:33:50,000 --> 00:33:52,000 La gente del posto significa che mi mostra le variabili locali. 630 00:33:52,000 --> 00:33:55,000 Solo nel caso in cui ho dimenticato o si tratta di un pazzo, la funzione complessa 631 00:33:55,000 --> 00:33:57,000 che io o qualcun altro ha scritto locals informazioni vi dirà 632 00:33:57,000 --> 00:34:00,000 quali sono tutte le variabili locali all'interno di questa funzione locale 633 00:34:00,000 --> 00:34:03,000 che si potrebbe preoccuparsi se volete curiosare. 634 00:34:03,000 --> 00:34:07,000 Ora, è printf per l'esecuzione, per cui vorrei andare avanti e basta digitare "prossimo". 635 00:34:07,000 --> 00:34:10,000 Perché siamo in questo ambiente non stiamo realmente vedendo 636 00:34:10,000 --> 00:34:14,000 eseguire qui, a meno di notare sta diventando un po 'martoriato qui. 637 00:34:14,000 --> 00:34:17,000 Ma bando è prevalente lo schermo lì, 638 00:34:17,000 --> 00:34:21,000 quindi non è un programma perfetto qui, ma va bene perché posso sempre curiosare 639 00:34:21,000 --> 00:34:23,000 con stampa, se voglio. 640 00:34:23,000 --> 00:34:26,000 >> Permettetemi di tipo successivo di nuovo, e ora ecco la parte interessante. 641 00:34:26,000 --> 00:34:29,000 A questo punto della storia y è 2, ed x è 1, 642 00:34:29,000 --> 00:34:32,000 come suggerito qui, e ancora una volta, 643 00:34:32,000 --> 00:34:35,000 la ragione per cui questo viene automaticamente la visualizzazione di ora è perché ho usato il comando 644 00:34:35,000 --> 00:34:40,000 x display e display y, in modo che il momento in cui ho digitato successivamente 645 00:34:40,000 --> 00:34:43,000 in teoria x ed y dovrebbe diventare scambiati. 646 00:34:43,000 --> 00:34:45,000 Ora, sappiamo già che non sarà il caso, 647 00:34:45,000 --> 00:34:49,000 ma staremo a vedere in un momento come si può scendere ad una profondità di capire perché è vero. 648 00:34:49,000 --> 00:34:54,000 Avanti, e purtroppo, è ancora y 2 e x è ancora 1, e posso confermare tanto. 649 00:34:54,000 --> 00:34:56,000 Stampa x, y stampa. 650 00:34:56,000 --> 00:34:59,000 Infatti, nessun scambio è effettivamente accaduto, quindi cerchiamo di iniziare questo corso. 651 00:34:59,000 --> 00:35:01,000 Chiaramente swap è rotto. 652 00:35:01,000 --> 00:35:04,000 Facciamo invece di tipo "run" di nuovo. 653 00:35:04,000 --> 00:35:07,000 Permettetemi di dire di sì, voglio riavviarlo dall'inizio, entrare. 654 00:35:07,000 --> 00:35:09,000 >> Ora sono di nuovo fino alla riga 18. 655 00:35:09,000 --> 00:35:11,000 Ora notate x e y sono valori spazzatura di nuovo. 656 00:35:11,000 --> 00:35:15,000 Poi, dopo, dopo, dopo. 657 00:35:15,000 --> 00:35:17,000 Se mi annoio posso anche semplicemente digitare n per il prossimo. 658 00:35:17,000 --> 00:35:21,000 È possibile abbreviare la sequenza più breve possibile di caratteri. 659 00:35:21,000 --> 00:35:23,000 Swap è ormai rotto. 660 00:35:23,000 --> 00:35:25,000 Tuffiamoci in, quindi invece di digitare prossimo, 661 00:35:25,000 --> 00:35:30,000 ora ho intenzione di scrivere passo, in modo che io passo all'interno di questa funzione 662 00:35:30,000 --> 00:35:33,000 modo che io possa camminare attraverso di essa, così ho colpito passo e quindi immettere. 663 00:35:33,000 --> 00:35:37,000 Si noti che i salti evidenziando più in basso nel mio programma per la linea 36. 664 00:35:37,000 --> 00:35:39,000 Ora, quali sono le variabili locali? 665 00:35:39,000 --> 00:35:41,000 Informazioni locali. 666 00:35:41,000 --> 00:35:43,000 Niente appena ancora, perché non abbiamo avuto modo di quella linea, 667 00:35:43,000 --> 00:35:47,000 quindi cerchiamo di andare avanti e dire "accanto". 668 00:35:47,000 --> 00:35:50,000 Ora ci sembra di avere tmp, tmp stampa. 669 00:35:50,000 --> 00:35:52,000 Valore Garbage, giusto? Credo di sì. 670 00:35:52,000 --> 00:35:55,000 Che ne dici di stampare una, stampa b, 1 e 2? 671 00:35:55,000 --> 00:35:58,000 In un attimo, non appena ho digitato successivamente di nuovo 672 00:35:58,000 --> 00:36:02,000 tmp sta per assumere un valore di 1, si spera, 673 00:36:02,000 --> 00:36:05,000 perché tmp sta per essere assegnato il valore di una. 674 00:36:05,000 --> 00:36:08,000 >> Ora facciamolo stampa a, b di stampa, 675 00:36:08,000 --> 00:36:11,000 ma ora stampare tmp, ed è davvero 1. 676 00:36:11,000 --> 00:36:14,000 Lasciami fare. Lasciami fare. 677 00:36:14,000 --> 00:36:16,000 Ho finito la funzione di swap. 678 00:36:16,000 --> 00:36:19,000 Sono ancora dentro di esso in linea 40, per cui vorrei stampare una, 679 00:36:19,000 --> 00:36:22,000 stampa b, e non mi importa di quello che è tmp. 680 00:36:22,000 --> 00:36:27,000 Sembra di swap è corretto quando si tratta di scambiare a e b. 681 00:36:27,000 --> 00:36:31,000 Ma se io ora digitato successivamente, Faccio un salto indietro alla riga 25, 682 00:36:31,000 --> 00:36:34,000 e, naturalmente, se digito x e y stampa 683 00:36:34,000 --> 00:36:38,000 sono ancora invariata, quindi non abbiamo risolto il problema. 684 00:36:38,000 --> 00:36:41,000 Ma diagnosticamente ora forse con questo programma GDB 685 00:36:41,000 --> 00:36:44,000 abbiamo ottenuto almeno un passo avanti verso la comprensione 686 00:36:44,000 --> 00:36:47,000 cosa c'è di sbagliato senza lettiera nostro codice mettendo un printf qui, 687 00:36:47,000 --> 00:36:50,000 printf qui, printf qui e poi in esecuzione di nuovo e di nuovo 688 00:36:50,000 --> 00:36:52,000 cercando di capire cosa c'è di sbagliato. 689 00:36:52,000 --> 00:36:55,000 >> Ho intenzione di andare avanti e uscire da questo tutto con smettere. 690 00:36:55,000 --> 00:36:57,000 Si dirà poi, "Esci comunque?" Sì. 691 00:36:57,000 --> 00:37:00,000 Ora sono tornato al mio normale prompt, e ho fatto usando GDB. 692 00:37:00,000 --> 00:37:03,000 Per inciso, non è necessario utilizzare questo-tui bandiera. 693 00:37:03,000 --> 00:37:07,000 Infatti, se si omette si ottiene essenzialmente la metà inferiore dello schermo. 694 00:37:07,000 --> 00:37:11,000 Se quindi digitare pausa principale e quindi eseguire 695 00:37:11,000 --> 00:37:15,000 Posso ancora eseguire il mio programma, ma quello che farà è più testualmente 696 00:37:15,000 --> 00:37:18,000 mi mostrano quello attuale riga alla volta. 697 00:37:18,000 --> 00:37:21,000 Il-tui, interfaccia utente testuale, 698 00:37:21,000 --> 00:37:25,000 mostra solo una più del programma in una sola volta, che è probabilmente un po 'più semplice concettualmente. 699 00:37:25,000 --> 00:37:27,000 Ma in effetti, posso solo fare dopo, dopo, dopo, 700 00:37:27,000 --> 00:37:30,000 e sto andando a vedere una riga alla volta, e se voglio davvero vedere che cosa sta succedendo 701 00:37:30,000 --> 00:37:35,000 Posso digitare lista e vedere un sacco di linee vicine. 702 00:37:35,000 --> 00:37:39,000 >> C'è un video che abbiamo chiesto che si guarda per il problema set 3 703 00:37:39,000 --> 00:37:43,000 Nate in cui vengono illustrate alcune delle complessità di GDB, 704 00:37:43,000 --> 00:37:46,000 e questa è una di quelle cose, onestamente, dove alcuni non banale percentuale di voi 705 00:37:46,000 --> 00:37:49,000 non potrà mai toccare GDB, e che sarà una cosa negativa 706 00:37:49,000 --> 00:37:53,000 perché letteralmente si finirà per spendere di più tempo dopo questo semestre 707 00:37:53,000 --> 00:37:56,000 dare la caccia ai bug allora si avrebbe se si mette in quella mezz'ora / ora 708 00:37:56,000 --> 00:38:00,000 questa settimana e l'apprendimento accanto a mettersi a proprio agio con GDB. 709 00:38:00,000 --> 00:38:02,000 Printf era tuo amico. 710 00:38:02,000 --> 00:38:05,000 GDB dovrebbe essere tuo amico. 711 00:38:05,000 --> 00:38:08,000 >> Hai domande su GDB? 712 00:38:08,000 --> 00:38:12,000 Ed ecco una breve lista di alcuni dei comandi più utili e potenti. 713 00:38:12,000 --> 00:38:15,000 Si '. >> È possibile stampare una stringa? 714 00:38:15,000 --> 00:38:17,000 È possibile stampare una stringa? Assolutamente. 715 00:38:17,000 --> 00:38:19,000 Essa non deve essere solo numeri interi. 716 00:38:19,000 --> 00:38:22,000 Se una variabile s è una stringa è sufficiente digitare s stampa. 717 00:38:22,000 --> 00:38:24,000 Essa vi mostrerà ciò che è variabile di stringa. 718 00:38:24,000 --> 00:38:26,000 [Incomprensibile-studente] 719 00:38:26,000 --> 00:38:28,000 Vi darà l'indirizzo e la stringa stessa. 720 00:38:28,000 --> 00:38:32,000 Essa vi mostrerà entrambi. 721 00:38:32,000 --> 00:38:34,000 E un ultima cosa, solo perché questi sono troppo buono a sapersi. 722 00:38:34,000 --> 00:38:37,000 Backtrace e telaio, fammi tuffarsi in questo tempo ultimo, 723 00:38:37,000 --> 00:38:39,000 stesso programma esatto con GDB. 724 00:38:39,000 --> 00:38:44,000 Lasciami andare avanti ed eseguire la versione testuale interfaccia utente, 725 00:38:44,000 --> 00:38:46,000 rottura principale. 726 00:38:46,000 --> 00:38:49,000 Lasciatemi andare avanti e correre di nuovo. Eccomi. 727 00:38:49,000 --> 00:38:55,000 Ora lasciami andare dopo, dopo, dopo, dopo, dopo, passo, entrare. 728 00:38:55,000 --> 00:39:00,000 >> E ora supponiamo che io sono ora in scambio deliberatamente, ma io sono come "Accidenti, quello che era il valore di x?" 729 00:39:00,000 --> 00:39:02,000 Non posso fare x più. 730 00:39:02,000 --> 00:39:05,000 Non posso fare y perché non sono portata. 731 00:39:05,000 --> 00:39:07,000 Non sono in un contesto, ma nessun problema. 732 00:39:07,000 --> 00:39:09,000 Posso digitare backtrace. 733 00:39:09,000 --> 00:39:13,000 Questo mi mostra tutte le funzioni che sono eseguite fino a questo punto nel tempo. 734 00:39:13,000 --> 00:39:16,000 Si noti che quella sul fondo, principale, si allinea con la principale 735 00:39:16,000 --> 00:39:18,000 essendo sul fondo della nostra immagine qui. 736 00:39:18,000 --> 00:39:22,000 Il fatto che è al di sopra di swap si allinei con scambio di essere al di sopra nella memoria qui, 737 00:39:22,000 --> 00:39:26,000 e se voglio tornare alla pagina principale temporaneamente posso dire "frame". 738 00:39:26,000 --> 00:39:30,000 Che numero? Principale è frame # 1. 739 00:39:30,000 --> 00:39:32,000 Ho intenzione di andare avanti e dire "frame 1." 740 00:39:32,000 --> 00:39:36,000 >> Ora sono di nuovo in main, e posso stampare x, e posso stampare y, 741 00:39:36,000 --> 00:39:40,000 ma non riesco a stampare a o b. 742 00:39:40,000 --> 00:39:43,000 Ma posso se dico: "Va bene, aspetta un attimo. Dov'era lo swap?" 743 00:39:43,000 --> 00:39:46,000 Lasciatemi andare avanti e dire "0 cornice." 744 00:39:46,000 --> 00:39:48,000 Ora sono di nuovo dove voglio essere, e per inciso, 745 00:39:48,000 --> 00:39:52,000 ci sono anche altri comandi, come se siete veramente ottenere digitando annoiato dopo, dopo, dopo, dopo, 746 00:39:52,000 --> 00:39:56,000 si può generalmente dire cose come "prossimi 10", e che è possibile scorrere i prossimi 10 linee. 747 00:39:56,000 --> 00:39:59,000 Si può anche scrivere "continua" quando si ha realmente stufo di passo attraverso di essa. 748 00:39:59,000 --> 00:40:05,000 Continua il programma verrà eseguito senza interruzioni fino a raggiungere un altro punto di interruzione, 749 00:40:05,000 --> 00:40:07,000 se in un ciclo o più in basso nel vostro programma. 750 00:40:07,000 --> 00:40:11,000 >> In questo caso abbiamo continuato fino alla fine, e il programma è terminato normalmente. 751 00:40:11,000 --> 00:40:13,000 Questo è un modo di fantasia, di processo inferiore. 752 00:40:13,000 --> 00:40:16,000 Solo il tuo programma è terminato normalmente. 753 00:40:16,000 --> 00:40:24,000 Più su quello nel video e nelle sessioni di debug a venire. 754 00:40:24,000 --> 00:40:26,000 E 'stato molto. 755 00:40:26,000 --> 00:40:35,000 Prendiamo la nostra pausa di 5 minuti qui, e torneremo con le strutture e file. 756 00:40:35,000 --> 00:40:38,000 >> Se si è tuffato in pset di questa settimana già 757 00:40:38,000 --> 00:40:41,000 saprete che usiamo nel codice di distribuzione, 758 00:40:41,000 --> 00:40:45,000 il codice sorgente che forniamo a voi come un punto di partenza, alcune nuove tecniche. 759 00:40:45,000 --> 00:40:50,000 In particolare, abbiamo introdotto questa nuova parola chiave struct chiamato, per la struttura, 760 00:40:50,000 --> 00:40:53,000 in modo da poter creare variabili personalizzate di sorta. 761 00:40:53,000 --> 00:40:57,000 Abbiamo inoltre introdotto il concetto di file di I / O, file di input e output, 762 00:40:57,000 --> 00:41:00,000 e questo è il modo che si possa salvare lo stato 763 00:41:00,000 --> 00:41:03,000 della tavola Scramble in un file su disco 764 00:41:03,000 --> 00:41:06,000 in modo che i compagni di insegnamento e posso capire 765 00:41:06,000 --> 00:41:09,000 quello che sta succedendo all'interno del programma senza dover giocare manualmente 766 00:41:09,000 --> 00:41:11,000 decine di giochi di Scramble. 767 00:41:11,000 --> 00:41:13,000 Possiamo fare questo più automatedly. 768 00:41:13,000 --> 00:41:18,000 >> Questa idea di una struttura risolve un problema abbastanza convincente. 769 00:41:18,000 --> 00:41:21,000 Supponiamo di voler implementare qualche programma 770 00:41:21,000 --> 00:41:25,000 che in qualche modo tiene traccia delle informazioni sugli studenti, 771 00:41:25,000 --> 00:41:28,000 e studenti potrebbe avere, per esempio, un ID, un nome 772 00:41:28,000 --> 00:41:31,000 e una casa in un posto come Harvard, per cui questi sono 3 pezzi di informazioni 773 00:41:31,000 --> 00:41:34,000 vogliamo tenere in giro, per cui vorrei andare avanti e iniziare a scrivere un piccolo programma qui, 774 00:41:34,000 --> 00:41:38,000 includere stdio.h. 775 00:41:38,000 --> 00:41:42,000 Lasciate fare a me sono cs50.h. 776 00:41:42,000 --> 00:41:44,000 E poi iniziare la mia funzione principale. 777 00:41:44,000 --> 00:41:46,000 Non voglio perdere tempo con gli argomenti della riga di comando, 778 00:41:46,000 --> 00:41:49,000 e qui voglio avere uno studente, così ho intenzione di dire 779 00:41:49,000 --> 00:41:54,000 uno studente ha un nome, così ho intenzione di dire "nome di stringa." 780 00:41:54,000 --> 00:41:59,000 Poi ho intenzione di dire che uno studente ha anche un ID, così int id, 781 00:41:59,000 --> 00:42:03,000 e uno studente ha una casa, così ho anche intenzione di dire "casa di stringa." 782 00:42:03,000 --> 00:42:06,000 Poi mi ordinare questi un po 'più pulito come questo. 783 00:42:06,000 --> 00:42:11,000 Ok, ora ho 3 variabili con cui rappresentano uno studente, in modo da "uno studente". 784 00:42:11,000 --> 00:42:15,000 >> E ora voglio per popolare questi valori, per cui vorrei andare avanti e dire qualcosa del tipo 785 00:42:15,000 --> 00:42:18,000 "Id = 123". 786 00:42:18,000 --> 00:42:21,000 Nome sta per arrivare David. 787 00:42:21,000 --> 00:42:24,000 Diciamo casa sta per arrivare Mather, 788 00:42:24,000 --> 00:42:31,000 e poi ho intenzione di fare qualcosa di arbitrariamente come printf ("% s, 789 00:42:31,000 --> 00:42:37,000 il cui ID è% d,% vive in s. 790 00:42:37,000 --> 00:42:41,000 E ora, che cosa voglio collegare qui, uno dopo l'altro? 791 00:42:41,000 --> 00:42:47,000 Nome, id, casa, di ritorno 0. 792 00:42:47,000 --> 00:42:50,000 Va bene, a meno che non ho sbagliato da qualche parte qui 793 00:42:50,000 --> 00:42:54,000 Penso che abbiamo un programma abbastanza buono che memorizza uno studente. 794 00:42:54,000 --> 00:42:57,000 Naturalmente, questo non è tutto ciò che interessa. Cosa devo fare se voglio avere 2 studenti? 795 00:42:57,000 --> 00:42:59,000 Questo è un grosso problema. Sono in grado di supportare 2 persone. 796 00:42:59,000 --> 00:43:03,000 Lasciatemi andare avanti e mettere in evidenza questo e scendere qui, 797 00:43:03,000 --> 00:43:09,000 e posso dire "id = 456" per uno come Rob che vive a Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Ok, aspetta, ma non posso chiamare queste la stessa cosa, 799 00:43:12,000 --> 00:43:15,000 e sembra che ho intenzione di dover copiare questo, 800 00:43:15,000 --> 00:43:19,000 quindi lasciatemi dire che questi saranno Davide variabili, 801 00:43:19,000 --> 00:43:23,000 e mi permetta di ottenere alcune copie di questi per Rob. 802 00:43:23,000 --> 00:43:27,000 Chiameremo questi Rob ma questo non è andare a lavorare ora 803 00:43:27,000 --> 00:43:33,000 perché ho-aspetta, mi fa cambiare id1, nome1 e house1. 804 00:43:33,000 --> 00:43:35,000 Rob sarà 2, 2. 805 00:43:35,000 --> 00:43:42,000 Ho avuto modo di cambiare questo qui, qui, qui, qui, qui, qui. 806 00:43:42,000 --> 00:43:45,000 Aspetta, che dire di Tommy? Facciamolo di nuovo. 807 00:43:45,000 --> 00:43:49,000 Ovviamente se pensate ancora che questo è un buon modo di fare questo, non è, 808 00:43:49,000 --> 00:43:52,000 quindi copia / incolla male. 809 00:43:52,000 --> 00:43:55,000 Ma abbiamo risolto questo una settimana fa. 810 00:43:55,000 --> 00:43:59,000 >> Qual è stata la nostra soluzione quando volevamo avere più istanze dello stesso tipo di dati? 811 00:43:59,000 --> 00:44:01,000 [Gli studenti] Matrice. 812 00:44:01,000 --> 00:44:03,000 Un array, per cui vorrei provare a pulire questo. 813 00:44:03,000 --> 00:44:07,000 Permettetemi di fare un po 'camera per me in cima, e lasciatemi invece farlo qui. 814 00:44:07,000 --> 00:44:12,000 Chiameremo queste persone, e invece ho intenzione di dire "id int," 815 00:44:12,000 --> 00:44:14,000 e ho intenzione di sostenere noi 3 per ora. 816 00:44:14,000 --> 00:44:18,000 Io vado a dire "i nomi di stringa," e io ti appoggio 3 di noi, 817 00:44:18,000 --> 00:44:22,000 e poi ho intenzione di dire "case di stringa", e ho intenzione di supportare 3 di noi. 818 00:44:22,000 --> 00:44:26,000 Ora, qui invece di Davide ottenere le sue proprie variabili locali 819 00:44:26,000 --> 00:44:28,000 siamo in grado di sbarazzarsi di quelle. 820 00:44:28,000 --> 00:44:30,000 Che si sente bene che stiamo pulire questo. 821 00:44:30,000 --> 00:44:35,000 Posso quindi dire che David sta per essere [0] e nomi [0] 822 00:44:35,000 --> 00:44:38,000 e case [0]. 823 00:44:38,000 --> 00:44:41,000 E poi Rob possiamo analogicamente risparmiare su questo. 824 00:44:41,000 --> 00:44:46,000 Mettiamo questo qui, così sarà arbitrariamente id [1]. 825 00:44:46,000 --> 00:44:50,000 Sta per essere nomi [1], 826 00:44:50,000 --> 00:44:53,000 e poi infine, case [1]. 827 00:44:53,000 --> 00:44:57,000 >> Ancora un po 'noioso, e ora devo questo numero, 828 00:44:57,000 --> 00:45:03,000 quindi diciamo "nomi [0], id [0], case [0], 829 00:45:03,000 --> 00:45:06,000 e cerchiamo di questo plurale. 830 00:45:06,000 --> 00:45:09,000 Ids, id, id. 831 00:45:09,000 --> 00:45:12,000 E ancora, lo sto facendo, così ancora una volta, sto già ricorrere a copiare / incollare di nuovo, 832 00:45:12,000 --> 00:45:14,000 così probabilità sono c'è un'altra soluzione qui. 833 00:45:14,000 --> 00:45:18,000 Probabilmente posso pulire questo ulteriormente con un ciclo o qualcosa del genere, 834 00:45:18,000 --> 00:45:21,000 Così, in breve, è un po 'meglio, ma ha ancora voglia di 835 00:45:21,000 --> 00:45:24,000 Sono ricorso a copiare / incollare, ma anche questo, io sostengo, 836 00:45:24,000 --> 00:45:27,000 non è davvero fondamentalmente la soluzione giusta perché 837 00:45:27,000 --> 00:45:29,000 E se qualche volta si decide sai una cosa? 838 00:45:29,000 --> 00:45:32,000 Abbiamo davvero avrebbe dovuto memorizzare indirizzi e-mail per David e Rob 839 00:45:32,000 --> 00:45:34,000 e tutti gli altri in questo programma. 840 00:45:34,000 --> 00:45:36,000 Dovremmo anche memorizzare i numeri di telefono. 841 00:45:36,000 --> 00:45:39,000 Dovremmo anche memorizzare numeri di contatto di emergenza. 842 00:45:39,000 --> 00:45:41,000 Abbiamo tutti questi pezzi di dati che vogliamo conservare, 843 00:45:41,000 --> 00:45:43,000 così come si fa a farlo? 844 00:45:43,000 --> 00:45:46,000 >> Si dichiara un altro array in alto, e poi aggiungere manualmente 845 00:45:46,000 --> 00:45:49,000 un indirizzo di posta elettronica [0], indirizzo di posta elettronica [1] 846 00:45:49,000 --> 00:45:51,000 per David e Rob e così via. 847 00:45:51,000 --> 00:45:56,000 Ma non c'è davvero solo un presupposto fondamentale di questo progetto 848 00:45:56,000 --> 00:45:59,000 che si sta usando il sistema onore di sapere che 849 00:45:59,000 --> 00:46:03,000 [I] in ciascuna delle più array 850 00:46:03,000 --> 00:46:06,000 così succede per riferirsi alla stessa persona, 851 00:46:06,000 --> 00:46:10,000 in modo da [0] a id è il numero 123, 852 00:46:10,000 --> 00:46:13,000 e ho intenzione di assumere che i nomi [0] 853 00:46:13,000 --> 00:46:16,000 è la stessa persona di nome e case [0] 854 00:46:16,000 --> 00:46:21,000 casa è la stessa persona e così via per tutte le matrici diverse che creano. 855 00:46:21,000 --> 00:46:24,000 Ma nota che non c'è legame fondamentale 856 00:46:24,000 --> 00:46:27,000 tra i 3 pezzi di informazioni, id, il nome e la casa, 857 00:46:27,000 --> 00:46:32,000 anche se l'entità che stiamo cercando di modello in questo programma non è array. 858 00:46:32,000 --> 00:46:35,000 Gli array sono proprio in questo modo programmatico di fare questo. 859 00:46:35,000 --> 00:46:38,000 Che cosa vogliamo veramente modellare nel nostro programma è una persona 860 00:46:38,000 --> 00:46:41,000 come Davide, una persona come Rob all'interno del quale 861 00:46:41,000 --> 00:46:46,000 o incapsulamento è un nome e un ID e una casa. 862 00:46:46,000 --> 00:46:49,000 >> Possiamo in qualche modo esprimere questa idea di incapsulamento 863 00:46:49,000 --> 00:46:52,000 in base al quale una persona ha un ID, un nome e una casa 864 00:46:52,000 --> 00:46:55,000 e non ricorrere a proprio questo hack per cui abbiamo appena 865 00:46:55,000 --> 00:46:58,000 fiducia che qualcosa di staffa 866 00:46:58,000 --> 00:47:02,000 si riferisce alla stessa entità umana in ciascuna di queste matrici disparati? 867 00:47:02,000 --> 00:47:04,000 Si può effettivamente fare questo. 868 00:47:04,000 --> 00:47:08,000 Lasciami andare sopra principale per ora, e lasciami creare il mio proprio tipo di dati 869 00:47:08,000 --> 00:47:10,000 realmente per la prima volta. 870 00:47:10,000 --> 00:47:14,000 Abbiamo usato questa tecnica in Scramble, 871 00:47:14,000 --> 00:47:17,000 ma qui ho intenzione di andare avanti e di creare un tipo di dati, 872 00:47:17,000 --> 00:47:19,000 e sai una cosa, ho intenzione di chiamarlo studente o persona, 873 00:47:19,000 --> 00:47:23,000 e ho intenzione di usare typedef per definire un tipo. 874 00:47:23,000 --> 00:47:25,000 Io vado a dire che questa è una struttura, 875 00:47:25,000 --> 00:47:29,000 e poi questa struttura sta per essere di tipo studente, diremo, 876 00:47:29,000 --> 00:47:31,000 anche se è un po 'datato ormai per me. 877 00:47:31,000 --> 00:47:33,000 Diremo "int id." 878 00:47:33,000 --> 00:47:35,000 Diremo "nome di stringa." 879 00:47:35,000 --> 00:47:37,000 Poi diremo "casa stringa" 880 00:47:37,000 --> 00:47:40,000 così ora per la fine di queste poche righe di codice 881 00:47:40,000 --> 00:47:45,000 Ho appena insegnato clang che esiste 882 00:47:45,000 --> 00:47:49,000 un tipo di dati int, oltre, oltre le stringhe, oltre raddoppia, oltre a carri. 883 00:47:49,000 --> 00:47:54,000 >> Da questo momento in linea di tempo 11, ora c'è un nuovo tipo di dati chiamato gli studenti, 884 00:47:54,000 --> 00:47:58,000 e ora posso dichiarare una variabile studente dove voglio, 885 00:47:58,000 --> 00:48:01,000 così mi permetta di scorrere verso il basso qui per le persone. 886 00:48:01,000 --> 00:48:05,000 Ora posso liberarmi di questo, e non posso andare giù a David qui, 887 00:48:05,000 --> 00:48:10,000 e per David posso effettivamente dire che David, 888 00:48:10,000 --> 00:48:13,000 possiamo letteralmente il nome della variabile dopo di me, 889 00:48:13,000 --> 00:48:16,000 sta per essere dello studente tipo. 890 00:48:16,000 --> 00:48:18,000 Questo potrebbe sembrare un po 'strano, ma questo non è poi così diverso 891 00:48:18,000 --> 00:48:22,000 da dichiarare qualcosa come un int o una stringa o di un galleggiante. 892 00:48:22,000 --> 00:48:24,000 Si dà il caso di essere chiamato ora studente, 893 00:48:24,000 --> 00:48:28,000 e se voglio mettere qualcosa all'interno di questa struttura 894 00:48:28,000 --> 00:48:31,000 Ora è necessario utilizzare un nuovo pezzo di sintassi, ma è piuttosto semplice, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" di capitale D, 896 00:48:39,000 --> 00:48:42,000 e david.house = "Mather," 897 00:48:42,000 --> 00:48:46,000 e ora può sbarazzarsi di questa roba qui. 898 00:48:46,000 --> 00:48:51,000 Avviso ora abbiamo ridisegnato il nostro programma in realtà un modo molto migliore 899 00:48:51,000 --> 00:48:54,000 a che ora il nostro programma rispecchia il mondo reale. 900 00:48:54,000 --> 00:48:57,000 >> C'è un mondo reale nozione di una persona o di uno studente. 901 00:48:57,000 --> 00:49:02,000 Qui abbiamo ora una versione C di una persona o più precisamente uno studente. 902 00:49:02,000 --> 00:49:05,000 All'interno di questa persona sono queste caratteristiche peculiari, 903 00:49:05,000 --> 00:49:10,000 ID, il nome e la casa, in modo da Rob diventa essenzialmente la stessa cosa qui, 904 00:49:10,000 --> 00:49:14,000 così studente rob, e ora rob.id = 456, 905 00:49:14,000 --> 00:49:17,000 rob.name = "Rob". 906 00:49:17,000 --> 00:49:20,000 Il fatto che la variabile è denominata Rob è una sorta di senso. 907 00:49:20,000 --> 00:49:22,000 Avremmo potuto chiamato x o y o z. 908 00:49:22,000 --> 00:49:25,000 Abbiamo appena chiamato Rob di essere semanticamente coerente, 909 00:49:25,000 --> 00:49:28,000 ma in realtà il nome è all'interno di quel campo stesso, 910 00:49:28,000 --> 00:49:30,000 così ora ho questo. 911 00:49:30,000 --> 00:49:33,000 Anche questo non si sente come il migliore design che ho hardcoded David. 912 00:49:33,000 --> 00:49:35,000 Ho hardcoded Rob. 913 00:49:35,000 --> 00:49:39,000 E ho ancora bisogno di ricorrere a un po 'di copia e incolla ogni volta che voglio nuove variabili. 914 00:49:39,000 --> 00:49:43,000 Inoltre, devo dare apparentemente ognuna di queste variabili un nome, 915 00:49:43,000 --> 00:49:46,000 anche se mi piacerebbe molto meglio descrivere queste variabili 916 00:49:46,000 --> 00:49:48,000  studenti più genericamente come. 917 00:49:48,000 --> 00:49:52,000 >> Ora siamo in grado di unire le idee che hanno lavorato bene per noi 918 00:49:52,000 --> 00:49:56,000 e invece dire: "Sai una cosa, dammi di studenti variabile chiamata, 919 00:49:56,000 --> 00:50:01,000 e lasciare che sono sia di dimensione 3 ", così ora posso definire questa ulteriore, 920 00:50:01,000 --> 00:50:04,000 sbarazzarsi del manuale ha dichiarato David, 921 00:50:04,000 --> 00:50:08,000 e posso invece dire una cosa del genere gli studenti [0] qui. 922 00:50:08,000 --> 00:50:11,000 Posso quindi dire che gli studenti [0] qui, 923 00:50:11,000 --> 00:50:14,000 studenti [0] qui, e così via, e posso andare in giro 924 00:50:14,000 --> 00:50:16,000 e la pulizia che per Rob. 925 00:50:16,000 --> 00:50:19,000 Potrei anche andare in giro ora forse l'aggiunta di un ciclo 926 00:50:19,000 --> 00:50:23,000 e l'utilizzo di GetString e GetInt realmente per ottenere questi valori da parte dell'utente. 927 00:50:23,000 --> 00:50:27,000 Potrei fare per aggiungere una costante, perché questo è generalmente cattiva pratica 928 00:50:27,000 --> 00:50:29,000 codificare un numero arbitrario come 3 proprio qui 929 00:50:29,000 --> 00:50:33,000 e poi basta ricordare che si dovrebbe mettere non più di 3 studenti in esso. 930 00:50:33,000 --> 00:50:36,000 Probabilmente sarebbe meglio usare # define nella parte superiore del mio file 931 00:50:36,000 --> 00:50:40,000 e il fattore che fuori, così effettivamente, lasciami andare avanti e questo generalizzare. 932 00:50:40,000 --> 00:50:43,000 >> Vorrei aprire un esempio che è tra di oggi 933 00:50:43,000 --> 00:50:46,000 esempi in anticipo, structs1. 934 00:50:46,000 --> 00:50:49,000 Si tratta di un programma più completo che utilizza # define qui 935 00:50:49,000 --> 00:50:51,000 e dice che stiamo andando ad avere 3 studenti per impostazione predefinita. 936 00:50:51,000 --> 00:50:54,000 Qui sto dichiarando un valore di classe di studenti, 937 00:50:54,000 --> 00:50:57,000 così una classe di studenti, e ora sto usando un ciclo 938 00:50:57,000 --> 00:51:00,000 solo per rendere il codice un po 'più elegante, popolare la classe 939 00:51:00,000 --> 00:51:05,000 con l'input dell'utente, in modo da scorrere da i = 0 su un massimo di studenti, che è 3. 940 00:51:05,000 --> 00:51:07,000 E poi richiedere all'utente in questa versione 941 00:51:07,000 --> 00:51:10,000  ciò che è ID dello studente, e lo ottiene con GetInt. 942 00:51:10,000 --> 00:51:13,000 Che il nome dello studente, e poi ho capito con GetString. 943 00:51:13,000 --> 00:51:15,000 Cosa c'è di casa dello studente? Ho capito con GetString. 944 00:51:15,000 --> 00:51:19,000 E poi in fondo qui ho deciso di cambiare 945 00:51:19,000 --> 00:51:22,000 come sto stampando questi fuori e di utilizzare effettivamente un ciclo, 946 00:51:22,000 --> 00:51:24,000 E chi sono io la stampa? 947 00:51:24,000 --> 00:51:27,000 Secondo il commento che sto stampando nessuno in Mather, 948 00:51:27,000 --> 00:51:30,000 e che è così Rob e Tommy e così via, in realtà Tommy a Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy e David sarebbe stato stampato in questo caso, ma come è questo lavoro? 950 00:51:34,000 --> 00:51:40,000 Non abbiamo visto questa funzione prima, ma prendere a indovinare da quello che fa. 951 00:51:40,000 --> 00:51:42,000 Confronta le stringhe. 952 00:51:42,000 --> 00:51:45,000 >> E 'un po' non ovvio come si confronta stringhe perché si scopre 953 00:51:45,000 --> 00:51:49,000 se restituisce 0 significa che le stringhe sono uguali. 954 00:51:49,000 --> 00:51:53,000 Se restituisce -1 significa che si arriva in ordine alfabetico dopo l'altro, 955 00:51:53,000 --> 00:51:57,000 e se restituisce +1 che significa che l'altra parola è in ordine alfabetico 956 00:51:57,000 --> 00:52:00,000 prima degli altri, e si può guardare online o presso la pagina man 957 00:52:00,000 --> 00:52:04,000 per vedere esattamente in che direzione è che, ma tutto questo ora sta facendo è che sta dicendo 958 00:52:04,000 --> 00:52:09,000 se [i]. casa è uguale a "Mather" 959 00:52:09,000 --> 00:52:13,000 poi andare avanti e stampare così ed è così in Mather. 960 00:52:13,000 --> 00:52:16,000 Ma ecco qualcosa che non abbiamo mai visto prima, e torneremo a questo. 961 00:52:16,000 --> 00:52:21,000 Non ricordo di aver mai a che fare questo in uno dei miei programmi. 962 00:52:21,000 --> 00:52:24,000 Gratuito è apparentemente riferimento alla memoria, liberando la memoria, 963 00:52:24,000 --> 00:52:31,000 ma ciò che la memoria a quanto pare sto liberando in questo ciclo in fondo a questo programma? 964 00:52:31,000 --> 00:52:34,000 Sembra che io stia liberando nome di una persona 965 00:52:34,000 --> 00:52:37,000 e la casa di una persona, ma perché? 966 00:52:37,000 --> 00:52:41,000 >> Si scopre tutte queste settimane che hai utilizzato GetString 967 00:52:41,000 --> 00:52:45,000 abbiamo tipo di introdotto un bug in ogni uno dei vostri programmi. 968 00:52:45,000 --> 00:52:51,000 GetString da disegno in memoria allocata in modo che possa tornare a voi una stringa, 969 00:52:51,000 --> 00:52:55,000 come David, o Rob, e si può fare quello che vuoi 970 00:52:55,000 --> 00:52:59,000 con quella stringa nel programma perché abbiamo riservato la memoria per voi. 971 00:52:59,000 --> 00:53:02,000 Il problema è che per tutto questo tempo ogni volta che si chiama GetString 972 00:53:02,000 --> 00:53:05,000 noi, gli autori di GetString, hanno chiesto il sistema operativo 973 00:53:05,000 --> 00:53:07,000 per darci un po 'di RAM per questa stringa. 974 00:53:07,000 --> 00:53:09,000 Dacci un po 'di RAM per questa stringa successiva. 975 00:53:09,000 --> 00:53:11,000 Dacci un po 'di RAM in più per questa stringa successiva. 976 00:53:11,000 --> 00:53:13,000 Quello che, il programmatore, non sono mai fatto 977 00:53:13,000 --> 00:53:15,000 che ci sta dando indietro la memoria, 978 00:53:15,000 --> 00:53:17,000 così per queste diverse settimane tutti i programmi che hai scritto 979 00:53:17,000 --> 00:53:20,000 hanno avuto quello che si chiama un salto di memoria in base al quale continuare ad usare 980 00:53:20,000 --> 00:53:24,000 memoria sempre di più ogni volta che si chiama GetString, e va bene. 981 00:53:24,000 --> 00:53:27,000 Abbiamo volutamente farlo nelle prime settimane perché non è così interessante 982 00:53:27,000 --> 00:53:29,000 doversi preoccupare di dove la stringa proviene. 983 00:53:29,000 --> 00:53:34,000 Tutto quello che vuoi è la parola Rob di tornare quando l'utente lo tipi poll 984 00:53:34,000 --> 00:53:38,000 >> Ma andare avanti ora dobbiamo iniziare a ricevere più sofisticato su questo. 985 00:53:38,000 --> 00:53:42,000 Ogni volta che l'allocazione della memoria è meglio eventualmente restituire. 986 00:53:42,000 --> 00:53:45,000 In caso contrario, nel mondo reale sul vostro Mac o PC è possibile che di tanto in tanto con esperienza 987 00:53:45,000 --> 00:53:50,000 sintomi in cui il computer è il blocco totale alla fine 988 00:53:50,000 --> 00:53:54,000 o la palla stupida spiaggia filatura è solo occupando del computer 989 00:53:54,000 --> 00:53:56,000 attenzione l'intero e non si può fare le cose. 990 00:53:56,000 --> 00:54:00,000 Questo può essere spiegato con un qualsiasi numero di bug, ma tra i possibili bug 991 00:54:00,000 --> 00:54:03,000 sono cose chiamate perdite di memoria in base al quale una persona che ha scritto quel pezzo di software 992 00:54:03,000 --> 00:54:07,000 si sta utilizzando non ricordava per liberare memoria 993 00:54:07,000 --> 00:54:10,000 che lui o lei ha chiesto al sistema operativo per, 994 00:54:10,000 --> 00:54:14,000 non utilizzando GetString, perché questa è una cosa CS50, ma utilizzando funzioni simili 995 00:54:14,000 --> 00:54:16,000 che chiedono il sistema operativo per la memoria. 996 00:54:16,000 --> 00:54:19,000 Se voi o loro vite e mai realmente tornare la memoria 997 00:54:19,000 --> 00:54:24,000 un sintomo che può essere che un programma rallenta e rallenta e rallenta 998 00:54:24,000 --> 00:54:26,000 a meno che non si ricorda di chiamare gratis. 999 00:54:26,000 --> 00:54:28,000 >> Torneremo a quando e perché si potrebbe chiamare libero, 1000 00:54:28,000 --> 00:54:32,000 ma andiamo avanti per buona misura e prova ad eseguire questo particolare programma. 1001 00:54:32,000 --> 00:54:35,000 Questo è stato chiamato structs1, entrare. 1002 00:54:35,000 --> 00:54:40,000 Lasciami andare avanti ed eseguire structs1, 123, David Mather, 1003 00:54:40,000 --> 00:54:47,000 456, Rob Kirkland, 789, 1004 00:54:47,000 --> 00:54:50,000 Tommy Mather, e vediamo di David a Mather, Tommy in Mather. 1005 00:54:50,000 --> 00:54:53,000 Questo è solo un controllo di integrità sul fatto che il programma è in funzione. 1006 00:54:53,000 --> 00:54:56,000 Ora, purtroppo, questo programma è un po 'frustrante in quanto 1007 00:54:56,000 --> 00:55:00,000 Ho fatto tutto questo lavoro, ho digitato in 9 diverse stringhe, premere invio, 1008 00:55:00,000 --> 00:55:04,000 è stato detto che era in Mather, ma ovviamente sapevo che era in Mather già perché l'ho scritto. 1009 00:55:04,000 --> 00:55:07,000 Sarebbe bello se almeno questo programma è più simile a un database 1010 00:55:07,000 --> 00:55:10,000 e ricorda davvero quello che ho digitato 1011 00:55:10,000 --> 00:55:12,000 così non ho mai più avere a inserire questi record degli studenti. 1012 00:55:12,000 --> 00:55:15,000 Forse è come un sistema registrarial. 1013 00:55:15,000 --> 00:55:21,000 >> Possiamo farlo utilizzando questa tecnica nota come I / O file, file di input e output, 1014 00:55:21,000 --> 00:55:24,000 un modo molto generico di dire ogni volta che si desidera leggere i file o scrivere file 1015 00:55:24,000 --> 00:55:26,000 si può fare questo con un certo insieme di funzioni. 1016 00:55:26,000 --> 00:55:29,000 Lasciatemi andare avanti e aprire questo structs2.c esempio, 1017 00:55:29,000 --> 00:55:33,000 che è quasi identico, ma vediamo cosa fa ora. 1018 00:55:33,000 --> 00:55:36,000 Nella parte superiore del file dichiaro una classe di studenti. 1019 00:55:36,000 --> 00:55:38,000 Ho quindi popolare la classe con l'input dell'utente, 1020 00:55:38,000 --> 00:55:41,000 in modo che le righe di codice sono esattamente come prima. 1021 00:55:41,000 --> 00:55:45,000 Poi scorrere verso il basso se qui mi stampa tutti coloro che sono in Mather arbitrariamente come prima, 1022 00:55:45,000 --> 00:55:47,000 ma questa è una novità interessante. 1023 00:55:47,000 --> 00:55:51,000 Queste righe di codice sono nuovi, e introducono qualcosa qui, 1024 00:55:51,000 --> 00:55:55,000 FILE, tutti i tappi, e che ha in * anche qui. 1025 00:55:55,000 --> 00:55:58,000 Vorrei spostare questo qui, a * qui pure. 1026 00:55:58,000 --> 00:56:00,000 >> Questa funzione non abbiamo visto prima, fopen, 1027 00:56:00,000 --> 00:56:03,000 ma significa aprire il file, quindi cerchiamo di sfogliare questi, 1028 00:56:03,000 --> 00:56:05,000 e questo è qualcosa che torneremo al pset future, 1029 00:56:05,000 --> 00:56:10,000 ma questa linea qui si apre essenzialmente un file chiamato di database, 1030 00:56:10,000 --> 00:56:13,000 e si apre specificamente in modo da poter fare ciò che ad esso? 1031 00:56:13,000 --> 00:56:15,000 [Incomprensibile-studente] 1032 00:56:15,000 --> 00:56:19,000 Giusto, quindi "w" significa semplicemente che sta dicendo il sistema operativo 1033 00:56:19,000 --> 00:56:21,000 aprire questo file in modo che io possa scrivere in essa. 1034 00:56:21,000 --> 00:56:23,000 Non voglio leggerlo. Io non voglio guardare solo a questo. 1035 00:56:23,000 --> 00:56:26,000 Voglio cambiare e aggiungere roba potenzialmente ad esso, 1036 00:56:26,000 --> 00:56:28,000 e il file sta per essere chiamato database. 1037 00:56:28,000 --> 00:56:30,000 Questo potrebbe essere chiamato niente. 1038 00:56:30,000 --> 00:56:32,000 Questo potrebbe essere database.txt. Questo potrebbe essere. Db. 1039 00:56:32,000 --> 00:56:37,000 Questo potrebbe essere una parola come foo, ma arbitrariamente scelto di assegnare un nome al file di database. 1040 00:56:37,000 --> 00:56:42,000 Si tratta di un controllo di integrità poco che torneremo al dettaglio nel corso del tempo, 1041 00:56:42,000 --> 00:56:47,000 se fp, per puntatore a file, non NULL uguale significa che tutto va bene. 1042 00:56:47,000 --> 00:56:51,000 >> Per farla breve, funzioni come fopen a volte falliscono. 1043 00:56:51,000 --> 00:56:53,000 Forse il file non esiste. Forse sei fuori di spazio su disco. 1044 00:56:53,000 --> 00:56:55,000 Forse non hai i permessi per quella cartella, 1045 00:56:55,000 --> 00:56:58,000 quindi se fopen restituisce qualcosa di brutto è accaduto nulla. 1046 00:56:58,000 --> 00:57:02,000 Al contrario, se fopen non restituisce nulla va tutto bene 1047 00:57:02,000 --> 00:57:04,000 e io posso iniziare a scrivere a questo file. 1048 00:57:04,000 --> 00:57:06,000 Ecco un nuovo trucco. 1049 00:57:06,000 --> 00:57:08,000 Si tratta di un ciclo che sta per iterare su ognuno dei miei studenti, 1050 00:57:08,000 --> 00:57:10,000 e questo sembra così simile a quello che abbiamo fatto prima, 1051 00:57:10,000 --> 00:57:15,000 ma questa funzione è un cugino di printf chiamato fprintf per file printf, 1052 00:57:15,000 --> 00:57:18,000 e notare è diverso in soli 2 modi. 1053 00:57:18,000 --> 00:57:20,000 Uno, inizia con f al posto di p, 1054 00:57:20,000 --> 00:57:23,000 ma poi il suo primo argomento è apparentemente cosa? 1055 00:57:23,000 --> 00:57:25,000 [Gli studenti] del file. >> Si tratta di un file. 1056 00:57:25,000 --> 00:57:30,000 Questa cosa chiamata fp, di cui parleremo alla fine prendere in giro a parte quello che è un puntatore a file, 1057 00:57:30,000 --> 00:57:35,000 ma per ora fp rappresenta semplicemente il file che ho aperto, 1058 00:57:35,000 --> 00:57:41,000 così fprintf qui sta dicendo stampare ID di questo utente al file, non sullo schermo. 1059 00:57:41,000 --> 00:57:44,000 Stampare il nome dell'utente al file, non sullo schermo, 1060 00:57:44,000 --> 00:57:47,000 la casa al file, non sullo schermo, e poi giù qui, ovviamente, 1061 00:57:47,000 --> 00:57:50,000 chiudere il file, e poi giù qui liberare la memoria. 1062 00:57:50,000 --> 00:57:53,000 >> L'unica differenza tra la versione 2 e la versione 1 1063 00:57:53,000 --> 00:57:58,000 è l'introduzione di fopen e questo file con * 1064 00:57:58,000 --> 00:58:01,000 e questa nozione di fprintf, quindi cerchiamo di vedere che cosa il risultato finale è. 1065 00:58:01,000 --> 00:58:03,000 Lasciami andare nella mia finestra di terminale. 1066 00:58:03,000 --> 00:58:06,000 Vorrei correre structs2, entrare. 1067 00:58:06,000 --> 00:58:09,000 Sembra che tutto va bene. Facciamo eseguire nuovamente structs2. 1068 00:58:09,000 --> 00:58:15,000 123, David Mather, 456, Rob Kirkland, 1069 00:58:15,000 --> 00:58:19,000 789, Tommy Mather, entrare. 1070 00:58:19,000 --> 00:58:23,000 Sembra che comportava lo stesso, ma se io ora fare ls 1071 00:58:23,000 --> 00:58:28,000 notare ciò che file è qui in mezzo a tutto il mio codice, database, 1072 00:58:28,000 --> 00:58:32,000 quindi cerchiamo di aprire quella, gedit di database, e guardare a questo. 1073 00:58:32,000 --> 00:58:34,000 Non è la più sexy di formati di file. 1074 00:58:34,000 --> 00:58:38,000 E 'davvero un pezzo di linea dati per riga per riga, 1075 00:58:38,000 --> 00:58:42,000 ma quelli di voi che usano i file di Excel o CSV, valori separati da virgola, 1076 00:58:42,000 --> 00:58:47,000 Potrei certamente ho usato fprintf per fare, invece forse qualcosa di simile 1077 00:58:47,000 --> 00:58:50,000 in modo da poter effettivamente creare l'equivalente di un file Excel 1078 00:58:50,000 --> 00:58:53,000 separando le cose con una virgola, non solo nuove linee. 1079 00:58:53,000 --> 00:58:56,000 >> In questo caso, se avessi invece usato le virgole al posto di nuove linee 1080 00:58:56,000 --> 00:59:01,000 Potrei letteralmente aprire il file di database in Excel se ho invece fatto simile a questa. 1081 00:59:01,000 --> 00:59:03,000 In breve, ora che abbiamo il potere di scrivere i file 1082 00:59:03,000 --> 00:59:07,000 ora possiamo iniziare a dati persistenti, tenendolo in giro su disco 1083 00:59:07,000 --> 00:59:10,000 in modo da poter mantenere le informazioni in giro ancora e ancora. 1084 00:59:10,000 --> 00:59:14,000 Si noti un paio di altre cose che ora sono un po 'più familiare. 1085 00:59:14,000 --> 00:59:16,000 Nella parte superiore di questo file C abbiamo un typedef 1086 00:59:16,000 --> 00:59:21,000 perché abbiamo voluto creare un tipo di dati che rappresenta una parola, 1087 00:59:21,000 --> 00:59:25,000 quindi questo tipo è chiamato parola, e all'interno di questa struttura 1088 00:59:25,000 --> 00:59:27,000 è un po 'più elaborato ora. 1089 00:59:27,000 --> 00:59:30,000 Perché è una parola composta da un array a quanto pare? 1090 00:59:30,000 --> 00:59:33,000 Che cosa è una parola solo intuitivamente? 1091 00:59:33,000 --> 00:59:35,000 >> Si tratta di un array di caratteri. 1092 00:59:35,000 --> 00:59:37,000 Si tratta di una sequenza di caratteri back to back to back. 1093 00:59:37,000 --> 00:59:41,000 LETTERE in tutti i tappi sembra essere arbitrariamente dire la lunghezza massima 1094 00:59:41,000 --> 00:59:44,000 di qualsiasi parola nel dizionario che stiamo usando per Scramble. 1095 00:59:44,000 --> 00:59:46,000 Perché ho un +1? 1096 00:59:46,000 --> 00:59:48,000 Il carattere null. 1097 00:59:48,000 --> 00:59:51,000 Ricordate quando abbiamo fatto l'esempio Bananagrams abbiamo bisogno di un valore speciale 1098 00:59:51,000 --> 00:59:55,000 alla fine della parola per tenere traccia 1099 00:59:55,000 --> 00:59:59,000 di dove le parole in realtà ha finito, e come la definizione di un set problema dice 1100 00:59:59,000 --> 01:00:03,000 qui stiamo associando a una parola data un valore booleano, 1101 01:00:03,000 --> 01:00:05,000 una bandiera, per così dire, vero o falso. 1102 01:00:05,000 --> 01:00:09,000 Hai trovato questa parola già, perché ci rendiamo conto 1103 01:00:09,000 --> 01:00:13,000 abbiamo veramente bisogno di un modo di ricordare non solo ciò che una parola è in Scramble 1104 01:00:13,000 --> 01:00:15,000 ma se si, l'umano, l'hanno trovato 1105 01:00:15,000 --> 01:00:20,000 in modo che se si fa trovare la parola "il" non si può semplicemente digitare il, entrare, la, entrare, l', immettere 1106 01:00:20,000 --> 01:00:23,000 e ottenere 3 punti, 3 punti, 3 punti, 3 punti. 1107 01:00:23,000 --> 01:00:26,000 Vogliamo essere in grado di lista nera quella parola impostando un bool 1108 01:00:26,000 --> 01:00:29,000 true se hai già trovato, e così è per questo che abbiamo 1109 01:00:29,000 --> 01:00:31,000 incapsulato in questa struttura. 1110 01:00:31,000 --> 01:00:35,000 >> Ora, qui in Scramble c'è questa struttura altro chiamato dizionario. 1111 01:00:35,000 --> 01:00:39,000 Assenti qui è la parola typedef perché in questo caso 1112 01:00:39,000 --> 01:00:43,000 abbiamo bisogno di incapsulare l'idea di un dizionario, 1113 01:00:43,000 --> 01:00:46,000 e un dizionario contiene un sacco di parole, 1114 01:00:46,000 --> 01:00:49,000 come sottintende questa matrice, e quante di queste parole ci sono? 1115 01:00:49,000 --> 01:00:51,000 Beh, qualunque sia questa dimensione variabile chiamata dice. 1116 01:00:51,000 --> 01:00:53,000 Ma abbiamo solo bisogno di un dizionario. 1117 01:00:53,000 --> 01:00:55,000 Non abbiamo bisogno di un tipo di dati chiamato dizionario. 1118 01:00:55,000 --> 01:00:58,000 Abbiamo solo bisogno di uno di loro, così si scopre in C 1119 01:00:58,000 --> 01:01:03,000 che se non si dice typedef, hai appena detto struct, quindi all'interno delle parentesi graffe 1120 01:01:03,000 --> 01:01:05,000 si mette le variabili, poi metti il ​​nome. 1121 01:01:05,000 --> 01:01:09,000 Questo sta dichiarando un dizionario variabile chiamata 1122 01:01:09,000 --> 01:01:11,000 che assomiglia a questo. 1123 01:01:11,000 --> 01:01:16,000 Al contrario, queste righe sono la creazione di una struttura di dati chiamata riutilizzabile parola 1124 01:01:16,000 --> 01:01:19,000 che è possibile creare più copie di, proprio come abbiamo creato 1125 01:01:19,000 --> 01:01:22,000 più copie di studenti. 1126 01:01:22,000 --> 01:01:24,000 >> Che cosa significa questo in ultima analisi, ci permettono di fare? 1127 01:01:24,000 --> 01:01:30,000 Torniamo in, diciamo, un esempio più semplice da tempi più semplici, 1128 01:01:30,000 --> 01:01:34,000 e lasciami aprire, diciamo, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 Il problema qui a portata di mano è realmente staccare 1130 01:01:38,000 --> 01:01:41,000 lo strato di una stringa e iniziare a prendere da queste ruote di formazione 1131 01:01:41,000 --> 01:01:44,000 perché si scopre che una stringa tutto questo tempo 1132 01:01:44,000 --> 01:01:47,000 è come abbiamo promesso in settimana 1 in realtà solo un soprannome, 1133 01:01:47,000 --> 01:01:51,000 un sinonimo dalla libreria CS50 per qualcosa che sembra un po 'più criptico, 1134 01:01:51,000 --> 01:01:53,000 char *, e abbiamo visto questa stella prima. 1135 01:01:53,000 --> 01:01:55,000 Lo abbiamo visto nel contesto dei file. 1136 01:01:55,000 --> 01:01:59,000 >> Vediamo ora perché abbiamo tenuto nascosto questo dettaglio da qualche tempo. 1137 01:01:59,000 --> 01:02:02,000 Ecco un file chiamato compare1.c, 1138 01:02:02,000 --> 01:02:07,000 e chiede a quanto pare l'utente per 2 stringhe, s e t, 1139 01:02:07,000 --> 01:02:11,000 e poi prova a confrontare le stringhe per l'uguaglianza in linea 26, 1140 01:02:11,000 --> 01:02:14,000 e se sono uguali si dice: "È stato digitato la stessa cosa," 1141 01:02:14,000 --> 01:02:17,000 e se non sono uguali si dice: "È stato digitato cose diverse." 1142 01:02:17,000 --> 01:02:19,000 Lasciami andare avanti ed eseguire questo programma. 1143 01:02:19,000 --> 01:02:23,000 Lasciami andare nella mia directory di origine, fare un compare1. E 'compilato bene. 1144 01:02:23,000 --> 01:02:25,000 Vorrei correre compare1. 1145 01:02:25,000 --> 01:02:27,000 Io lo zoom, inserire. 1146 01:02:27,000 --> 01:02:29,000 Inserisci commento. CIAO. 1147 01:02:29,000 --> 01:02:32,000 Dirò qualcosa di nuovo. CIAO. 1148 01:02:32,000 --> 01:02:34,000 Io sicuramente non scrivere cose diverse. 1149 01:02:34,000 --> 01:02:37,000 >> Fammi provare di nuovo. BYE BYE. 1150 01:02:37,000 --> 01:02:40,000 Sicuramente non diverso, quindi che cosa sta succedendo qui? 1151 01:02:40,000 --> 01:02:44,000 Ebbene, ciò che è veramente a confronto in linea 26? 1152 01:02:44,000 --> 01:02:46,000 [Incomprensibile-studente] 1153 01:02:46,000 --> 01:02:49,000 Sì, così si scopre che una stringa, tipo di dati, è una specie di bugia. 1154 01:02:49,000 --> 01:02:53,000 Una stringa è un char *, ma quello che è un char *? 1155 01:02:53,000 --> 01:02:56,000 Un char *, come si dice, è un puntatore, 1156 01:02:56,000 --> 01:03:00,000 e un puntatore è effettivamente un indirizzo, 1157 01:03:00,000 --> 01:03:05,000 una posizione somma in memoria, e se vi capita di aver digitato una parola come CIAO, 1158 01:03:05,000 --> 01:03:08,000 ricordo dalle discussioni passate stringhe 1159 01:03:08,000 --> 01:03:16,000 questo è come la parola CIAO. 1160 01:03:16,000 --> 01:03:19,000 Ricordate che una parola come CIAO può essere rappresentato 1161 01:03:19,000 --> 01:03:22,000 come un array di caratteri come questo 1162 01:03:22,000 --> 01:03:25,000 e quindi con un carattere speciale alla fine chiamato il carattere nullo, 1163 01:03:25,000 --> 01:03:27,000 come denota \. 1164 01:03:27,000 --> 01:03:29,000 Che cosa è in realtà una stringa? 1165 01:03:29,000 --> 01:03:32,000 Si noti che questo è più blocchi di memoria, 1166 01:03:32,000 --> 01:03:36,000 e in effetti, la fine è noto soltanto allorché si guarda attraverso l'intera stringa 1167 01:03:36,000 --> 01:03:38,000 cercando per il carattere speciale null. 1168 01:03:38,000 --> 01:03:41,000 Ma se questo è un pezzo di memoria dalla memoria del mio computer, 1169 01:03:41,000 --> 01:03:44,000 diciamo arbitrariamente dire che questa stringa semplicemente fortunato, 1170 01:03:44,000 --> 01:03:47,000 e ha posto all'inizio della RAM del mio computer. 1171 01:03:47,000 --> 01:03:54,000 Questo è il byte 0, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> Quando dico qualcosa come GetString e faccio string s = GetString 1173 01:04:02,000 --> 01:04:04,000 cosa sta realmente restituiti? 1174 01:04:04,000 --> 01:04:08,000 Per queste ultime settimane, ciò che sta realmente essere memorizzati in s 1175 01:04:08,000 --> 01:04:13,000 non è questa stringa di per sé, ma in questo caso ciò che viene memorizzato è 1176 01:04:13,000 --> 01:04:18,000 il numero 0 perché ciò che realmente fa GetString 1177 01:04:18,000 --> 01:04:20,000 è non fisicamente restituire una stringa. 1178 01:04:20,000 --> 01:04:22,000 Che non ha nemmeno molto senso concettuale. 1179 01:04:22,000 --> 01:04:24,000 Ciò che fa di ritorno è un numero. 1180 01:04:24,000 --> 01:04:28,000 Questo numero è l'indirizzo del CIAO in memoria, 1181 01:04:28,000 --> 01:04:32,000 stringa s e quindi, se togliere questo strato, stringa in realtà non esiste. 1182 01:04:32,000 --> 01:04:35,000 E 'solo una semplificazione nella libreria CS50. 1183 01:04:35,000 --> 01:04:38,000 >> Questo è davvero qualcosa che si chiama char *. 1184 01:04:38,000 --> 01:04:41,000 Char ha un senso, perché ciò che è una parola, come CIAO? 1185 01:04:41,000 --> 01:04:44,000 Beh, si tratta di una serie di caratteri, una serie di caratteri. 1186 01:04:44,000 --> 01:04:47,000 * Char significa che l'indirizzo di un personaggio, 1187 01:04:47,000 --> 01:04:50,000 così che cosa significa per restituire una stringa? 1188 01:04:50,000 --> 01:04:53,000 Una bella, modo semplice di restituendo una stringa 1189 01:04:53,000 --> 01:04:57,000 è piuttosto che cercare di capire come torno a 5 o 6 byte differenti 1190 01:04:57,000 --> 01:05:01,000 vorrei tornare al cui indirizzo byte? 1191 01:05:01,000 --> 01:05:03,000 La prima. 1192 01:05:03,000 --> 01:05:06,000 In altre parole, mi permetta di darle l'indirizzo di un carattere in memoria. 1193 01:05:06,000 --> 01:05:10,000 Questo è ciò che * char rappresenta, l'indirizzo di un singolo carattere in memoria. 1194 01:05:10,000 --> 01:05:12,000 Chiama quella variabile s. 1195 01:05:12,000 --> 01:05:15,000 Conservare in s questo indirizzo particolare, che ho arbitrariamente detto è 0, 1196 01:05:15,000 --> 01:05:19,000 solo per mantenere le cose semplici, ma in realtà è in genere un numero più grande. 1197 01:05:19,000 --> 01:05:21,000 >> Aspetta un attimo. 1198 01:05:21,000 --> 01:05:23,000 Se solo mi dà l'indirizzo del primo carattere, come faccio a sapere che cosa l'indirizzo è 1199 01:05:23,000 --> 01:05:25,000 del carattere secondo, il terzo, il quarto e il quinto? 1200 01:05:25,000 --> 01:05:27,000 [Incomprensibile-studente] 1201 01:05:27,000 --> 01:05:31,000 Devi solo sapere dove la fine della stringa è per mezzo di questo trucco a portata di mano, 1202 01:05:31,000 --> 01:05:35,000 in modo che quando si usa qualcosa come printf, che letteralmente printf prende come argomento, 1203 01:05:35,000 --> 01:05:39,000 Ricordiamo che usiamo questo segnaposto% s, e poi si passa a 1204 01:05:39,000 --> 01:05:41,000 la variabile che è la memorizzazione di una stringa. 1205 01:05:41,000 --> 01:05:47,000 Quello che stai veramente passando è l'indirizzo del primo carattere della stringa. 1206 01:05:47,000 --> 01:05:50,000 Printf poi usa un ciclo for o un ciclo while dopo aver ricevuto tale indirizzo, 1207 01:05:50,000 --> 01:05:53,000 per esempio, 0, per cui vorrei farlo ora, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n", s); 1209 01:06:02,000 --> 01:06:07,000 Quando chiamo printf ("% s \ n", s); quello che sto veramente fornire con printf 1210 01:06:07,000 --> 01:06:13,000 è l'indirizzo del primo carattere in s, che in questo caso è arbitraria H. 1211 01:06:13,000 --> 01:06:16,000 >> Come fa sapere esattamente cosa printf per visualizzare sullo schermo? 1212 01:06:16,000 --> 01:06:19,000 La persona che ha implementato printf implementato un ciclo while o un ciclo for 1213 01:06:19,000 --> 01:06:23,000 che dice che fa questo personaggio uguale al carattere speciale null? 1214 01:06:23,000 --> 01:06:25,000 In caso contrario, la stampa. Che ne dici di questa? 1215 01:06:25,000 --> 01:06:28,000 Se non stampatelo, stampa, stampare, stamparla. 1216 01:06:28,000 --> 01:06:32,000 Oh, questo è speciale. Interrompere la stampa e ritornare all'utente. 1217 01:06:32,000 --> 01:06:35,000 E questo è letteralmente tutto quello che sta accadendo sotto il cofano, 1218 01:06:35,000 --> 01:06:38,000 e questo è molto da digerire nel primo giorno di una classe, 1219 01:06:38,000 --> 01:06:43,000 ma per ora è davvero il blocco di costruzione di capire tutto 1220 01:06:43,000 --> 01:06:46,000 che sta succedendo all'interno della memoria del nostro computer, 1221 01:06:46,000 --> 01:06:49,000 e alla fine faremo prendere in giro questa parte con un piccolo aiuto 1222 01:06:49,000 --> 01:06:51,000 da uno dei nostri amici a Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> Professor Nick Parlante alla Stanford ha fatto questa sequenza meravigliosa dei video 1224 01:06:56,000 --> 01:06:58,000 da ogni sorta di lingue diverse che hanno introdotto 1225 01:06:58,000 --> 01:07:00,000 questo piccolo Claymation Binky carattere. 1226 01:07:00,000 --> 01:07:03,000 La voce che state per ascoltare in un furtivo anteprima alcuni secondi 1227 01:07:03,000 --> 01:07:05,000 è quella di un professore di Stanford, e si stanno ottenendo 1228 01:07:05,000 --> 01:07:07,000 solo 5 o 6 secondi di questo proprio ora, 1229 01:07:07,000 --> 01:07:09,000 ma questa è la nota su cui ci conclude oggi 1230 01:07:09,000 --> 01:07:11,000 e iniziare il Mercoledì. 1231 01:07:11,000 --> 01:07:15,000 Vi do Fun Pointer con Binky, l'anteprima. 1232 01:07:15,000 --> 01:07:18,000 [♪ Musica ♪] [Professore Parlante] Ehi, Binky. 1233 01:07:18,000 --> 01:07:21,000 Svegliati. E 'tempo per il divertimento puntatore. 1234 01:07:21,000 --> 01:07:24,000 [Binky] Che cos'è? Ulteriori informazioni sui puntatori? 1235 01:07:24,000 --> 01:07:26,000 Oh, goody! 1236 01:07:26,000 --> 01:07:29,000 >> Ci vediamo il Mercoledì. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]