1 00:00:00,000 --> 00:00:11,200 2 00:00:11,200 --> 00:00:12,580 >> DAVID MALAN: Va bene, bentornato. 3 00:00:12,580 --> 00:00:13,290 Questo è CS50. 4 00:00:13,290 --> 00:00:15,130 Questo è l'inizio della settimana di sette. 5 00:00:15,130 --> 00:00:18,890 Quindi è stato un po ', così ho pensato di fare un giro vorticoso di dove siamo 6 00:00:18,890 --> 00:00:20,760 lasciato e dove stiamo andando adesso. 7 00:00:20,760 --> 00:00:23,310 >> Quindi questa cosa qui potrebbe avere causato qualche angoscia in un primo momento. 8 00:00:23,310 --> 00:00:27,680 Ma si spera, si sta cominciando a ambientarsi a ciò che questo denota qui - 9 00:00:27,680 --> 00:00:32,670 stelle che rappresenta un puntatore, che è proprio quello che, in termini più povere? 10 00:00:32,670 --> 00:00:33,400 Quindi si tratta di un indirizzo. 11 00:00:33,400 --> 00:00:35,490 >> Quindi è l'indirizzo del qualcosa in memoria. 12 00:00:35,490 --> 00:00:38,260 E abbiamo iniziato a staccare gli strati un paio di settimane fa, le cose come 13 00:00:38,260 --> 00:00:41,800 GetString e altre funzioni tutto questo tempo sono state tornando 14 00:00:41,800 --> 00:00:46,010 indirizzi delle cose in memoria, come la indirizzo del primo carattere 15 00:00:46,010 --> 00:00:46,990 alcuni sequenza. 16 00:00:46,990 --> 00:00:50,360 >> Così abbiamo anche introdotto valgrind, che potrai iniziare a utilizzare per questo problema 17 00:00:50,360 --> 00:00:53,380 impostare, in particolare per il successivo problema regolato pure. 18 00:00:53,380 --> 00:00:54,980 E valgrind fa ciò per noi? 19 00:00:54,980 --> 00:00:57,520 20 00:00:57,520 --> 00:01:01,020 Si verifica la presenza di perdite di memoria, ed è verifica anche per l'abuso di memoria. 21 00:01:01,020 --> 00:01:05,890 >> Si può, con una certa probabilità, di rilevare se il codice sta per toccare la memoria 22 00:01:05,890 --> 00:01:07,100 che semplicemente non dovrebbe. 23 00:01:07,100 --> 00:01:10,410 Quindi non necessariamente una perdita, ma se si andare oltre i confini di alcuni 24 00:01:10,410 --> 00:01:14,730 matrice, e che effettivamente esegue valgrind e indurre comportamenti che mentre 25 00:01:14,730 --> 00:01:17,870 valgrind è in esecuzione nel vostro programma è in esecuzione all'interno di esso, si otterrà 26 00:01:17,870 --> 00:01:21,460 messaggi come questo - "non valido scrivono di dimensioni 4 ", che, ricordano un paio di 27 00:01:21,460 --> 00:01:25,880 settimane fa significava che avevo accidentalmente come su un int troppo 28 00:01:25,880 --> 00:01:27,250 al di là dei confini di un array. 29 00:01:27,250 --> 00:01:30,790 E così formato 4 significa qui la dimensione di quella particolare int. 30 00:01:30,790 --> 00:01:35,260 >> Quindi prendere rassicurazione nel fatto che Uscita di valgrind, il formato di esso, 31 00:01:35,260 --> 00:01:36,170 è semplicemente atroce. 32 00:01:36,170 --> 00:01:40,180 E 'davvero difficile da vedere attraverso il disordine per le informazioni interessanti. 33 00:01:40,180 --> 00:01:42,910 Quindi quello che abbiamo fatto qui è solo estratto alcune delle coppie di più 34 00:01:42,910 --> 00:01:43,850 linee interessanti. 35 00:01:43,850 --> 00:01:46,760 Ma rendersi conto che l'80% dei valgrind di uscita sta per essere un po 'un 36 00:01:46,760 --> 00:01:47,650 distrazione. 37 00:01:47,650 --> 00:01:52,820 >> Basta cercare modelli come questi - valida ragione, non valida leggere, 40 byte 38 00:01:52,820 --> 00:01:56,690 e qualche numero di blocchi sono sicuramente perse, parole chiave come quella. 39 00:01:56,690 --> 00:02:01,920 E ciò che si spera, vedi è un po 'di tipo di traccia di quale funzione del 40 00:02:01,920 --> 00:02:03,340 errore è in realtà dentro 41 00:02:03,340 --> 00:02:07,195 In questo caso qui, in quale linea di il mio codice è stato l'errore pare? 42 00:02:07,195 --> 00:02:09,729 43 00:02:09,729 --> 00:02:14,130 >> 26 in un file denominato memory.c, che era l'esempio stavamo giocando con 44 00:02:14,130 --> 00:02:14,890 al tempo. 45 00:02:14,890 --> 00:02:16,460 Quindi probabilmente non è in malloc. 46 00:02:16,460 --> 00:02:18,630 Probabilmente era nel mio codice, invece. 47 00:02:18,630 --> 00:02:20,910 Quindi vedremo di nuovo e di nuovo in breve tempo. 48 00:02:20,910 --> 00:02:24,080 >> Quindi scanf, questo è venuto su in un paio di forme finora. 49 00:02:24,080 --> 00:02:26,410 Abbiamo visto brevemente sscanf. 50 00:02:26,410 --> 00:02:28,330 Era qualcosa varie si tuffò nel vostro 51 00:02:28,330 --> 00:02:29,535 i preparativi per il quiz. 52 00:02:29,535 --> 00:02:33,130 E scanf è in realtà ciò che il CS50 biblioteca ha usato sotto la 53 00:02:33,130 --> 00:02:36,560 cappa per un bel po 'di tempo per per ottenere input da parte dell'utente. 54 00:02:36,560 --> 00:02:40,420 >> Per esempio, se mi sposto verso il CS50 apparecchio qui, lasciatemi aprire un 55 00:02:40,420 --> 00:02:45,315 esempio oggi che si chiama scanf-0.C Ed è super semplice. 56 00:02:45,315 --> 00:02:46,590 E 'solo un paio di righe di codice. 57 00:02:46,590 --> 00:02:50,880 Ma dimostra veramente come getInt ha lavorato tutto questo tempo. 58 00:02:50,880 --> 00:02:54,710 >> In questo programma, in linea 16 , Si noti che dichiaro un int. 59 00:02:54,710 --> 00:02:57,270 Quindi niente puntatori, nulla di magico lì, solo un int. 60 00:02:57,270 --> 00:03:00,330 Poi, nella riga 17, i Chiede il all'utente un numero, prego. 61 00:03:00,330 --> 00:03:02,930 Poi, verso la fine del 18, io uso scanf qui. 62 00:03:02,930 --> 00:03:06,910 E ho specificato, un po 'come printf, che mi aspetto preventivo 63 00:03:06,910 --> 00:03:08,110 unquote cento i. 64 00:03:08,110 --> 00:03:10,920 >> Quindi per cento Io, naturalmente, denota un int. 65 00:03:10,920 --> 00:03:14,580 Ma notare ciò che la seconda argomento di scanf è. 66 00:03:14,580 --> 00:03:17,350 Come descriveresti il ​​secondo argomento dopo la virgola? 67 00:03:17,350 --> 00:03:19,450 Che cosa è? 68 00:03:19,450 --> 00:03:20,670 >> E 'l'indirizzo di x. 69 00:03:20,670 --> 00:03:25,490 Quindi questo è utile perché fornendo scanf con l'indirizzo di x, che cosa fa 70 00:03:25,490 --> 00:03:29,560 che autorizzano tale funzionalità? 71 00:03:29,560 --> 00:03:33,010 Non basta andare lì, ma anche fare che cosa? 72 00:03:33,010 --> 00:03:34,060 >> Apportare una modifica ad esso. 73 00:03:34,060 --> 00:03:38,080 Perché si può andare lì, è una sorta di come una mappa per una locazione di memoria. 74 00:03:38,080 --> 00:03:41,900 E finché si fornisce scanf, o qualsiasi funzione con una tale mappa, che 75 00:03:41,900 --> 00:03:45,840 funzione può andare lì, e non solo guardare il valore, ma può anche 76 00:03:45,840 --> 00:03:49,670 modificare tale valore, che è utile se lo scopo nella vita è quello di scanf 77 00:03:49,670 --> 00:03:53,060 scansione input dall'utente, specificamente dalla tastiera. 78 00:03:53,060 --> 00:03:57,830 E la f denota formattato, proprio come printf, il f denota un formattata 79 00:03:57,830 --> 00:03:58,930 stringa che si desidera stampare. 80 00:03:58,930 --> 00:04:04,430 >> Così, in breve, la linea 18 dice semplicemente, provare a leggere un int da parte dell'utente del 81 00:04:04,430 --> 00:04:10,420 tastiera e conservarlo all'interno di x, a qualunque indirizzo di x si trova a vivere in. 82 00:04:10,420 --> 00:04:14,860 E poi, infine, la linea 19 dice solo, grazie per l'int, in questo caso. 83 00:04:14,860 --> 00:04:15,940 >> Così mi permetta di andare avanti e fare questo. 84 00:04:15,940 --> 00:04:18,570 Quindi, fare scanf 0. 85 00:04:18,570 --> 00:04:20,130 Lasciami andare avanti e lo zoom dentro 86 00:04:20,130 --> 00:04:22,960 Vado a correre con questo puntini tagliare scanf 0. 87 00:04:22,960 --> 00:04:24,020 Numero, per favore? 88 00:04:24,020 --> 00:04:24,720 50. 89 00:04:24,720 --> 00:04:25,730 Grazie per il 50. 90 00:04:25,730 --> 00:04:27,270 Quindi è abbastanza semplice. 91 00:04:27,270 --> 00:04:28,160 >> Ora che cosa è che non facendo? 92 00:04:28,160 --> 00:04:29,940 Non sta facendo un sacco di controllo degli errori. 93 00:04:29,940 --> 00:04:33,000 Per esempio, se non collaboro, e io non digitare un numero, ma 94 00:04:33,000 --> 00:04:37,860 invece scrivo qualcosa come "ciao" questo è solo un po 'strano. 95 00:04:37,860 --> 00:04:41,130 E così una delle cose che il CS50 biblioteca ha fatto per noi per un po ' 96 00:04:41,130 --> 00:04:43,440 tempo è che reprompting e reprompting. 97 00:04:43,440 --> 00:04:49,320 >> Il nuovo tentativo frase richiamo era in cs50.c, e questo è il motivo che getInt in 98 00:04:49,320 --> 00:04:51,670 la libreria CS50 è in realtà un intero mucchio di linee lunghe, perché siamo 99 00:04:51,670 --> 00:04:53,190 controllando per cose stupide come questa. 100 00:04:53,190 --> 00:04:55,730 Forse l'utente non dà noi, infatti, un int? 101 00:04:55,730 --> 00:04:57,910 Ci ha lui o lei dare qualcosa come una lettera alfabetica? 102 00:04:57,910 --> 00:05:01,410 Se così, vogliamo rilevare che e urlare contro di loro. 103 00:05:01,410 --> 00:05:03,915 >> Ma le cose si fanno più interessanti Nel prossimo esempio. 104 00:05:03,915 --> 00:05:09,840 Se vado a scanf-1.c, qual è quello cosa che è cambiato radicalmente in 105 00:05:09,840 --> 00:05:11,135 prossimo esempio? 106 00:05:11,135 --> 00:05:13,690 107 00:05:13,690 --> 00:05:16,010 Sto utilizzando char *, naturalmente, invece di int. 108 00:05:16,010 --> 00:05:19,210 >> Quindi questo è interessante, perché char *, ricordiamo, è in realtà solo la 109 00:05:19,210 --> 00:05:20,190 stessa cosa di stringa. 110 00:05:20,190 --> 00:05:23,840 Così ci si sente come forse questo è un super- semplice implementazione di GetString. 111 00:05:23,840 --> 00:05:26,010 Ma ho sfogliato lo strato della biblioteca CS50, quindi sono 112 00:05:26,010 --> 00:05:27,550 chiamare questo char * ora. 113 00:05:27,550 --> 00:05:30,070 Così vediamo dove, se da nessuna parte, abbiamo sbagliato. 114 00:05:30,070 --> 00:05:30,840 >> Linea 17 - 115 00:05:30,840 --> 00:05:33,950 Io dico di nuovo, per favore mi dia qualcosa, in questo caso, una stringa. 116 00:05:33,950 --> 00:05:37,940 E poi nella riga successiva, chiamo scanf, nuovamente, dando un codice di formato, 117 00:05:37,940 --> 00:05:39,310 ma questa volta percento s. 118 00:05:39,310 --> 00:05:41,900 E poi questa volta, sono dandogli buffer. 119 00:05:41,900 --> 00:05:43,550 >> Ora notate, non sto usando la e commerciale. 120 00:05:43,550 --> 00:05:47,120 Ma il motivo è che probabilmente bene qui? 121 00:05:47,120 --> 00:05:49,760 Perché ciò che è già tampone? 122 00:05:49,760 --> 00:05:50,770 E 'già un puntatore. 123 00:05:50,770 --> 00:05:51,650 E 'già un indirizzo. 124 00:05:51,650 --> 00:05:54,510 >> E diciamo questa parola "confondere", mi permetta basta chiamare s, per esempio, per 125 00:05:54,510 --> 00:05:55,050 semplicità. 126 00:05:55,050 --> 00:05:58,250 Ma l'ho chiamata tampone, perché in generale, in programmazione, se si dispone di un 127 00:05:58,250 --> 00:06:02,130 pezzo di memoria, che una stringa davvero semplicemente è, si potrebbe chiamare un buffer. 128 00:06:02,130 --> 00:06:04,460 E 'un posto per memorizzare le informazioni. 129 00:06:04,460 --> 00:06:07,400 >> Simile a cose come YouTube, quando stanno tampone, per così dire, che 130 00:06:07,400 --> 00:06:10,270 semplicemente significa che è il download di bit da Internet e la loro memorizzazione in un 131 00:06:10,270 --> 00:06:14,160 matrice locale, un pezzo locale di memoria in modo da che si può guardare in un secondo momento senza 132 00:06:14,160 --> 00:06:16,830 esso saltare o appeso ti durante la riproduzione. 133 00:06:16,830 --> 00:06:20,930 >> Quindi c'è un problema qui, però, perché ti sto dicendo scanf, si aspettano un 134 00:06:20,930 --> 00:06:22,320 stringa dall'utente. 135 00:06:22,320 --> 00:06:24,410 Ecco l'indirizzo del un pezzo di memoria. 136 00:06:24,410 --> 00:06:26,180 Metti che stringa lì. 137 00:06:26,180 --> 00:06:31,230 Perché è quello legato dare noi guai, però? 138 00:06:31,230 --> 00:06:33,490 >> Che cos'è? 139 00:06:33,490 --> 00:06:35,510 Sono autorizzato ad accedere quella parte di memoria? 140 00:06:35,510 --> 00:06:36,250 Sai, io non lo so. 141 00:06:36,250 --> 00:06:39,210 Perché è tampone stato inizializzato a qualcosa? 142 00:06:39,210 --> 00:06:39,820 Non proprio. 143 00:06:39,820 --> 00:06:43,090 E quindi è quello che abbiamo finora chiamato un valore spazzatura, che 144 00:06:43,090 --> 00:06:44,040 non è una parola formale. 145 00:06:44,040 --> 00:06:49,200 Significa solo non abbiamo idea di cosa bit sono all'interno dei quattro byte che 146 00:06:49,200 --> 00:06:51,240 Ho assegnato come buffer. 147 00:06:51,240 --> 00:06:52,450 >> Non ho chiamato malloc. 148 00:06:52,450 --> 00:06:53,940 Non ho assolutamente chiamato GetString. 149 00:06:53,940 --> 00:06:56,380 Quindi, chi sa che cosa è in realtà all'interno di tampone? 150 00:06:56,380 --> 00:07:00,550 Eppure raccontando scanf alla cieca, andare lì e mettere tutto ciò che l'utente ha digitato. 151 00:07:00,550 --> 00:07:04,460 >> Quindi, ciò che rischia di provocare nel nostro codice, se lo usiamo? 152 00:07:04,460 --> 00:07:05,700 Probabilmente un segmentation fault. 153 00:07:05,700 --> 00:07:07,970 Forse no, ma probabilmente un segmentation fault. 154 00:07:07,970 --> 00:07:10,620 E dico forse no, perché a volte si fa, a volte 155 00:07:10,620 --> 00:07:11,380 non si ottiene un segfault. 156 00:07:11,380 --> 00:07:14,280 A volte basta avere fortuna, ma sta comunque andando essere 157 00:07:14,280 --> 00:07:15,340 un bug nel nostro programma. 158 00:07:15,340 --> 00:07:17,060 >> Quindi, mi permetta di andare avanti e compilare questo. 159 00:07:17,060 --> 00:07:18,280 Ho intenzione di farlo nel modo della vecchia scuola. 160 00:07:18,280 --> 00:07:23,825 Così clang dash 0, scanf-1, scanf-1.c, Enter. 161 00:07:23,825 --> 00:07:24,720 Ops, troppo vecchia scuola. 162 00:07:24,720 --> 00:07:26,550 Vediamo. 163 00:07:26,550 --> 00:07:28,440 Dove ho? 164 00:07:28,440 --> 00:07:29,700 Oh, buffer di char *. 165 00:07:29,700 --> 00:07:33,595 166 00:07:33,595 --> 00:07:35,130 Oh, grazie - 167 00:07:35,130 --> 00:07:36,930 Salva, OK - 168 00:07:36,930 --> 00:07:37,690 molto vecchia scuola. 169 00:07:37,690 --> 00:07:38,900 Va bene, e 'passato un po'. 170 00:07:38,900 --> 00:07:41,720 >> Così ho appena salvato il file dopo fare quella temporanea 171 00:07:41,720 --> 00:07:42,700 modificare un momento fa. 172 00:07:42,700 --> 00:07:46,090 E ora ho compilato la manualmente con Clang. 173 00:07:46,090 --> 00:07:49,500 E ora ho intenzione di andare avanti ed eseguire scanf-1, Invio. 174 00:07:49,500 --> 00:07:50,290 String per favore. 175 00:07:50,290 --> 00:07:51,600 Io digitare "ciao". 176 00:07:51,600 --> 00:07:54,070 >> Ed ora, ecco dove, francamente, printf si è un po 'fastidioso. 177 00:07:54,070 --> 00:07:56,020 In realtà non è intenzione di segfault in questo caso. 178 00:07:56,020 --> 00:07:59,860 Printf è un po 'speciale, perché è così super comunemente utilizzato che 179 00:07:59,860 --> 00:08:03,570 essenzialmente printf sta facendo un favore e realizzando, 180 00:08:03,570 --> 00:08:04,830 questo non è un puntatore valido. 181 00:08:04,830 --> 00:08:09,080 Mi permetta di prendere su di me per stampare solo in parentesi nullo, anche 182 00:08:09,080 --> 00:08:13,340 anche se non è necessariamente quello che noi ci aspettavamo. 183 00:08:13,340 --> 00:08:16,940 >> Quindi non possiamo davvero facilmente indurre una segfault con questo, ma è chiaro che questo 184 00:08:16,940 --> 00:08:18,600 non è il comportamento che volevo. 185 00:08:18,600 --> 00:08:19,800 Quindi qual è la soluzione più semplice? 186 00:08:19,800 --> 00:08:25,650 Beh, in scanf-2, lasciatemi propongo invece che in realtà solo l'assegnazione di un 187 00:08:25,650 --> 00:08:30,100 char *, mi permetta di essere un po 'più intelligente questo, e mi permetta di allocare il buffer 188 00:08:30,100 --> 00:08:32,940 come una sequenza di 16 caratteri. 189 00:08:32,940 --> 00:08:34,200 >> Così posso fare questo in un paio di modi. 190 00:08:34,200 --> 00:08:35,610 Potrei assolutamente usare malloc. 191 00:08:35,610 --> 00:08:38,980 Ma posso tornare a due settimane quando Ho solo bisogno di un intero gruppo di 192 00:08:38,980 --> 00:08:39,620 personaggi. 193 00:08:39,620 --> 00:08:40,860 Questo è solo un array. 194 00:08:40,860 --> 00:08:44,870 Così mi permetta, invece ridefinire tampone ad essere un array di 16 caratteri. 195 00:08:44,870 --> 00:08:47,340 >> E ora, quando passo buffer in - 196 00:08:47,340 --> 00:08:49,940 e questo è qualcosa che non abbiamo parlare in due settimane - 197 00:08:49,940 --> 00:08:53,730 ma si può trattare un array come anche se si tratta di un indirizzo. 198 00:08:53,730 --> 00:08:56,390 Tecnicamente, come abbiamo visto, sono un po 'diverso. 199 00:08:56,390 --> 00:09:01,290 Ma scanf non mente se si passa il nome di un array, perché ciò che 200 00:09:01,290 --> 00:09:05,030 Clang farà per noi è essenzialmente curare il nome di quella matrice come il 201 00:09:05,030 --> 00:09:08,280 indirizzo del blocco di 16 byte. 202 00:09:08,280 --> 00:09:09,550 >> Quindi questo è migliore. 203 00:09:09,550 --> 00:09:12,110 Questo significa che ora posso spera effettuare le seguenti operazioni. 204 00:09:12,110 --> 00:09:16,800 Permettetemi di zoom out per un momento e fare fare scanf-2, compilato OK. 205 00:09:16,800 --> 00:09:19,390 Ora vorrei fare avuto barra scanf-2. 206 00:09:19,390 --> 00:09:22,430 String per favore. "Ciao." E sembrava funzionare questa volta. 207 00:09:22,430 --> 00:09:26,020 >> Ma qualcuno può proporre uno scenario in cui potrebbe non funzionare ancora? 208 00:09:26,020 --> 00:09:28,550 Sì? 209 00:09:28,550 --> 00:09:30,640 Qualcosa di più di 16 caratteri. 210 00:09:30,640 --> 00:09:32,020 E in realtà, possiamo essere un po 'più precisi. 211 00:09:32,020 --> 00:09:36,540 Qualcosa di più poi 15 caratteri, perché in realtà abbiamo bisogno di tenere a mente 212 00:09:36,540 --> 00:09:39,920 che abbiamo bisogno che il backslash a zero implicitamente alla fine della stringa, 213 00:09:39,920 --> 00:09:42,950 che è una parte scanf volontà tipicamente prendersi cura di per noi. 214 00:09:42,950 --> 00:09:46,210 >> Quindi, mi permetta di fare una cosa del genere - 215 00:09:46,210 --> 00:09:48,040 a volte possiamo solo lasciarlo così. 216 00:09:48,040 --> 00:09:50,630 OK, ora abbiamo indotto il nostro errore di segmentazione. 217 00:09:50,630 --> 00:09:51,000 Perché? 218 00:09:51,000 --> 00:09:54,940 Perché ho scritto per più di 15 personaggi, e così abbiamo effettivamente 219 00:09:54,940 --> 00:09:58,280 memoria toccato che ho effettivamente non dovrebbe avere. 220 00:09:58,280 --> 00:10:00,180 >> Così che cosa è veramente la soluzione qui? 221 00:10:00,180 --> 00:10:02,210 Beh, e se abbiamo bisogno di una stringa più lunga? 222 00:10:02,210 --> 00:10:03,960 Bene, noi forse facciamo 32 byte. 223 00:10:03,960 --> 00:10:05,160 Beh, e se questo non è abbastanza lungo? 224 00:10:05,160 --> 00:10:06,040 Come circa 64 byte? 225 00:10:06,040 --> 00:10:07,080 E se questo non è abbastanza lungo? 226 00:10:07,080 --> 00:10:09,640 Come circa 128 o 200 byte? 227 00:10:09,640 --> 00:10:12,660 Che cosa è davvero la soluzione qui in caso generale, se non sappiamo in 228 00:10:12,660 --> 00:10:14,460 anticipare ciò che l'utente sta per digitare? 229 00:10:14,460 --> 00:10:20,000 230 00:10:20,000 --> 00:10:23,050 >> E 'solo una specie di grande dolore nel culo, ad essere onesti, è per questo che la 231 00:10:23,050 --> 00:10:29,050 CS50 biblioteca dispone di una dozzina di linee di codice che collettivamente implementare 232 00:10:29,050 --> 00:10:32,390 GetString stringa in un modo che noi non sappiamo deve conoscere in anticipo l' 233 00:10:32,390 --> 00:10:33,430 utente sta per digitare. 234 00:10:33,430 --> 00:10:37,370 In particolare, se si guarda indietro a cs50.c da due settimane fa, si vedrà 235 00:10:37,370 --> 00:10:40,480 GetString che realmente fa non usare scanf in questo modo. 236 00:10:40,480 --> 00:10:43,720 Piuttosto, si legge un carattere alla volta. 237 00:10:43,720 --> 00:10:46,010 >> Perché l'unica cosa bella di la lettura di un carattere è che possiamo 238 00:10:46,010 --> 00:10:48,490 garantire a noi stessi di sempre avere almeno un carattere. 239 00:10:48,490 --> 00:10:51,740 Posso solo dichiarare un char, e poi prendere questi passaggi veramente bambino di appena 240 00:10:51,740 --> 00:10:54,380 leggere un carattere in in un tempo dalla tastiera. 241 00:10:54,380 --> 00:10:58,240 E poi, quello che vedrete GetString fa è ogni volta che si esaurisce, 242 00:10:58,240 --> 00:11:02,280 diciamo, 16 byte di memoria, utilizza malloc, o un suo cugino, per 243 00:11:02,280 --> 00:11:06,810 allocare più memoria, la copia del vecchio memoria nel nuovo, e poi strisciando 244 00:11:06,810 --> 00:11:09,900 lungo, ottenendo un carattere alla volta, e quando si esaurisce di che 245 00:11:09,900 --> 00:11:13,370 pezzo di memoria, getta via, palio un pezzo più grande di memoria, copia antica 246 00:11:13,370 --> 00:11:14,750 in nuove e ripetizioni. 247 00:11:14,750 --> 00:11:18,480 Ed è davvero un dolore da realtà realizzare qualcosa di semplice come 248 00:11:18,480 --> 00:11:19,710 ricevendo input da un utente. 249 00:11:19,710 --> 00:11:21,090 >> Così si può usare scanf. 250 00:11:21,090 --> 00:11:22,430 È possibile utilizzare le altre funzioni simili. 251 00:11:22,430 --> 00:11:25,420 E un sacco di libri di testo e online esempi fanno, ma sono tutti 252 00:11:25,420 --> 00:11:27,210 vulnerabili a problemi come questo. 253 00:11:27,210 --> 00:11:29,550 E alla fine, ottenendo un segfault è una specie di fastidioso. 254 00:11:29,550 --> 00:11:30,680 Non è un bene per l'utente. 255 00:11:30,680 --> 00:11:33,560 >> Ma nel peggiore dei casi, che cosa fa è fondamentalmente mettere il vostro 256 00:11:33,560 --> 00:11:37,160 codice a rischio di? 257 00:11:37,160 --> 00:11:39,250 Una specie di attacco, potenzialmente. 258 00:11:39,250 --> 00:11:41,680 Abbiamo parlato di un attacco del genere - traboccante la pila. 259 00:11:41,680 --> 00:11:44,660 Ma in generale, se si è permesso di troppo pieno di un buffer, come abbiamo fatto un 260 00:11:44,660 --> 00:11:48,070 paio di settimane fa, con solo la scrittura più di "ciao" in pila, si 261 00:11:48,070 --> 00:11:52,330 può infatti assumere, potenzialmente, un computer o almeno avere a dati che 262 00:11:52,330 --> 00:11:53,510 non appartiene a voi. 263 00:11:53,510 --> 00:11:55,970 >> Così, in breve, questo è il motivo per cui abbiamo quelle ruote di formazione. 264 00:11:55,970 --> 00:11:59,090 Ma ora, cominciamo a toglierli, come i nostri programmi non hanno più bisogno, 265 00:11:59,090 --> 00:12:00,610 necessariamente, input dall'utente. 266 00:12:00,610 --> 00:12:03,960 Ma nel caso di problema definito sei, il tuo contributo verrà da un enorme 267 00:12:03,960 --> 00:12:07,520 file di dizionario con 150 alcuni dispari di mille parole. 268 00:12:07,520 --> 00:12:10,330 >> Così non dovrete preoccuparvi di ingresso arbitrario dell'utente. 269 00:12:10,330 --> 00:12:13,720 Vi daremo alcune ipotesi su quel file. 270 00:12:13,720 --> 00:12:20,340 Qualsiasi problema puntatori o scanf o l'input dell'utente in generale? 271 00:12:20,340 --> 00:12:24,450 >> Va bene, quindi un rapido sguardo poi in una sola trailing argomento da due settimane fa. 272 00:12:24,450 --> 00:12:28,590 E questo era il concetto di una struct. 273 00:12:28,590 --> 00:12:34,180 Non che - questa nozione di un struct, che era quello che? 274 00:12:34,180 --> 00:12:35,430 Cosa gli struct fare per noi? 275 00:12:35,430 --> 00:12:39,280 276 00:12:39,280 --> 00:12:39,860 >> Definire - 277 00:12:39,860 --> 00:12:41,710 scusate? 278 00:12:41,710 --> 00:12:42,820 Definire un tipo di variabile. 279 00:12:42,820 --> 00:12:44,410 Quindi, più o meno. 280 00:12:44,410 --> 00:12:46,180 Stiamo in realtà la combinazione di due argomenti. 281 00:12:46,180 --> 00:12:49,510 Quindi, con typedef, ricordare che possiamo dichiarare un tipo di nostro, come un 282 00:12:49,510 --> 00:12:51,500 sinonimo, come stringa di char *. 283 00:12:51,500 --> 00:12:56,200 Ma usando typedef e struct, possiamo creare davvero le nostre strutture dati. 284 00:12:56,200 --> 00:12:59,600 >> Per esempio, se torno in gedit qui solo per un momento, e vado avanti 285 00:12:59,600 --> 00:13:08,230 e di fare qualcosa di simile, mi permetta di risparmiare questo come, diciamo, structs.c 286 00:13:08,230 --> 00:13:10,840 temporaneamente, sto solo andando di andare avanti e di includere 287 00:13:10,840 --> 00:13:14,360 standardio.h, int void main. 288 00:13:14,360 --> 00:13:18,960 E poi qui, suppongo che voglio scrivere un programma che memorizza 289 00:13:18,960 --> 00:13:21,840 più studenti provenienti da molteplici case, per esempio. 290 00:13:21,840 --> 00:13:24,430 Quindi è come un registrarial banca dati di qualche tipo. 291 00:13:24,430 --> 00:13:29,550 >> Quindi, se ho bisogno del nome di uno studente, ho potrebbe fare qualcosa come char * nome, 292 00:13:29,550 --> 00:13:31,570 e farò qualcosa di simile - 293 00:13:31,570 --> 00:13:34,410 in realtà, usiamo la libreria CS50 solo per un momento per rendere questo un 294 00:13:34,410 --> 00:13:38,380 po 'più semplice, in modo che possiamo prendere in prestito quelle decine di righe di codice. 295 00:13:38,380 --> 00:13:39,340 E facciamo solo mantenere le cose semplici. 296 00:13:39,340 --> 00:13:42,610 Noi terremo stringa, e ora GetString. 297 00:13:42,610 --> 00:13:47,420 >> Quindi io pretendo ora che ho memorizzato il nome di qualche studente, e la casa di 298 00:13:47,420 --> 00:13:50,240 qualche studente, semplicemente usando le variabili come abbiamo fatto noi e in una settimana. 299 00:13:50,240 --> 00:13:52,370 Ma suppongo che adesso voglio sostenere studenti più. 300 00:13:52,370 --> 00:13:58,460 Va bene, così i miei istinti sono a fare stringa nome2, ottiene GetString, stringa 301 00:13:58,460 --> 00:14:01,370 house2 ottiene GetString. 302 00:14:01,370 --> 00:14:05,850 E poi il nostro terzo studente, facciamo nome3 GetString. 303 00:14:05,850 --> 00:14:09,170 >> Va bene, quindi questo è sorprendente spera voi come un po 'stupido, 304 00:14:09,170 --> 00:14:11,580 perché questo processo è davvero mai andando a finire, e sta solo andando a 305 00:14:11,580 --> 00:14:13,130 rendere il mio codice aspetto peggiore e sempre peggio. 306 00:14:13,130 --> 00:14:14,810 Ma abbiamo risolto anche questo in due settimane. 307 00:14:14,810 --> 00:14:19,450 Qual è stata la nostra soluzione relativamente pulito quando abbiamo avuto più variabili dello 308 00:14:19,450 --> 00:14:23,580 stesso tipo di dati, che sono tutti collegati, ma non volevamo questo casino atroce 309 00:14:23,580 --> 00:14:26,870 di variabili nome simile? 310 00:14:26,870 --> 00:14:30,060 Che cosa abbiamo fatto, invece? 311 00:14:30,060 --> 00:14:31,260 >> Quindi penso che ho sentito un paio di posti. 312 00:14:31,260 --> 00:14:32,590 Abbiamo avuto un array. 313 00:14:32,590 --> 00:14:37,110 Se si desidera che più istanze di qualcosa, perché non abbiamo pulito tutto questo 314 00:14:37,110 --> 00:14:39,540 e basta dire, dammi array chiamato nomi? 315 00:14:39,540 --> 00:14:41,640 >> E per ora, diamo codice duro 3. 316 00:14:41,640 --> 00:14:44,450 E poi dammi un altro array chiamato case, e lasciami per 317 00:14:44,450 --> 00:14:45,800 codice ora dura 3. 318 00:14:45,800 --> 00:14:49,220 E ho massicciamente ripulito l' casino che ho appena creato. 319 00:14:49,220 --> 00:14:52,400 Ora, io ho ancora difficile codificato 3, ma anche il 3 potrebbe venire dinamicamente dal 320 00:14:52,400 --> 00:14:54,350 utente o argv, o simili. 321 00:14:54,350 --> 00:14:55,720 Quindi questo è già più pulito. 322 00:14:55,720 --> 00:15:00,100 >> Ma che cosa è fastidiosa di questo è che ora, anche se un nome è in qualche modo 323 00:15:00,100 --> 00:15:02,280 fondamentalmente legata alla casa di uno studente - 324 00:15:02,280 --> 00:15:04,720 si tratta di uno studente che ho davvero vuole rappresentare - 325 00:15:04,720 --> 00:15:08,080 Ora ho due array paralleli nel senso che sono il 326 00:15:08,080 --> 00:15:13,930 stesse dimensioni e nomi staffa 0 presumibilmente mappe a case staffa 0, 327 00:15:13,930 --> 00:15:16,600 e nomi di staffa 1 mappe alle case staffa 1. 328 00:15:16,600 --> 00:15:19,280 In altre parole, quello degli studenti vive in quella casa, e che altro studente 329 00:15:19,280 --> 00:15:20,530 vive in quella casa di altri. 330 00:15:20,530 --> 00:15:23,720 Ma sicuramente questo potrebbe essere fatto ancora più pulito. 331 00:15:23,720 --> 00:15:24,990 >> Beh, si può, in effetti. 332 00:15:24,990 --> 00:15:28,730 E mi permetta di andare avanti e aprire fino structs.h, e ti 333 00:15:28,730 --> 00:15:31,130 vedere questa idea qui. 334 00:15:31,130 --> 00:15:34,905 Notate che ho usato typedef, come si accennato poco fa a dichiarare la nostra 335 00:15:34,905 --> 00:15:35,570 proprio tipo di dati. 336 00:15:35,570 --> 00:15:39,660 Ma sto usando anche questa altra parola chiave chiamata struct che mi dà un nuovo 337 00:15:39,660 --> 00:15:40,790 struttura dati. 338 00:15:40,790 --> 00:15:43,980 >> E questa struttura dati rivendico sta avere due cose all'interno 339 00:15:43,980 --> 00:15:47,060 esso - una stringa chiamata nome, e una stringa chiamata casa. 340 00:15:47,060 --> 00:15:49,820 E il nome che sto per dare a questa struttura dati sta 341 00:15:49,820 --> 00:15:51,005 di essere chiamato studente. 342 00:15:51,005 --> 00:15:54,030 Potrei chiamare tutto quello che voglio, ma questo rende semanticamente 343 00:15:54,030 --> 00:15:55,810 senso per me nella mia mente. 344 00:15:55,810 --> 00:15:59,160 >> Così ora, se apro una versione migliore del programma ho iniziato a scrivere 345 00:15:59,160 --> 00:16:00,390 lì, mi permetta di scorrere verso l'alto. 346 00:16:00,390 --> 00:16:03,190 E c'è un po 'di più linee di codice qui, ma vorrei concentrarmi per 347 00:16:03,190 --> 00:16:04,160 momento su uno. 348 00:16:04,160 --> 00:16:07,790 Ho dichiarato un costante cosiddetti studenti e hard coded 3 per ora. 349 00:16:07,790 --> 00:16:11,110 Ma ora, notate come pulito il mio codice inizia per arrivare. 350 00:16:11,110 --> 00:16:15,030 >> In linea 22, dichiaro schiera di studenti. 351 00:16:15,030 --> 00:16:18,760 E notare che studente è apparentemente ora un tipo di dati. 352 00:16:18,760 --> 00:16:23,360 Perché nella parte superiore di questo file, notare Ho incluso il file di intestazione 353 00:16:23,360 --> 00:16:24,820 che ho tirato su solo un momento fa. 354 00:16:24,820 --> 00:16:28,820 E questo file di intestazione semplicemente aveva questa definizione di uno studente. 355 00:16:28,820 --> 00:16:32,470 >> Così ora, ho creato i miei dati personalizzati tipo quella di C anni gli autori 356 00:16:32,470 --> 00:16:33,890 fa non pensare in anticipo. 357 00:16:33,890 --> 00:16:34,570 Ma non è un problema. 358 00:16:34,570 --> 00:16:35,870 Posso farlo io stesso. 359 00:16:35,870 --> 00:16:39,050 Quindi questo è un array chiamato gli studenti, ciascuno dei componenti la cui 360 00:16:39,050 --> 00:16:41,100 è una struttura di studente. 361 00:16:41,100 --> 00:16:44,270 E voglio che tre di quelli nella matrice. 362 00:16:44,270 --> 00:16:46,030 >> E ora, che cosa fa il resto di questo programma di fare? 363 00:16:46,030 --> 00:16:47,550 Avevo bisogno di qualcosa di un po 'arbitraria. 364 00:16:47,550 --> 00:16:51,450 Così da linea 24 in poi, I iterazioni da 0 a 3. 365 00:16:51,450 --> 00:16:54,000 Ho poi chiedere all'utente di il nome dello studente. 366 00:16:54,000 --> 00:16:56,110 E poi io uso GetString come prima. 367 00:16:56,110 --> 00:16:59,410 Poi mi chiedo casa dello studente, e io uso GetString come prima. 368 00:16:59,410 --> 00:17:01,780 >> Ma la gara - leggermente nuovo pezzo di sintassi - 369 00:17:01,780 --> 00:17:07,010 Posso ancora indice per l'i-esimo studente, ma come faccio ad ottenere i dati specifici 370 00:17:07,010 --> 00:17:08,354 campo all'interno della struct? 371 00:17:08,354 --> 00:17:11,770 Beh, cosa c'è a quanto pare il nuovo pezzo di sintassi? 372 00:17:11,770 --> 00:17:13,339 E 'solo l'operatore punto. 373 00:17:13,339 --> 00:17:14,510 >> Noi non abbiamo veramente visto questo prima. 374 00:17:14,510 --> 00:17:17,819 L'hai visto in pset cinque se hai tuffato in già con i file bitmap. 375 00:17:17,819 --> 00:17:22,372 Ma il puntino significa solo all'interno di questa struct o più campi, danno dot 376 00:17:22,372 --> 00:17:24,510 nome, o darmi casa dot. 377 00:17:24,510 --> 00:17:28,690 Ciò significa andare all'interno della struct e ottenere quei particolari settori. 378 00:17:28,690 --> 00:17:30,200 >> Che cosa fa il resto di questo programma? 379 00:17:30,200 --> 00:17:31,190 E non è tutto quello sexy. 380 00:17:31,190 --> 00:17:34,640 Notate che ho iterazioni da 0 a 3 di nuovo, e io semplicemente creare un inglese 381 00:17:34,640 --> 00:17:40,500 frase come così e così è in questo e una casa, passando in nome dot da 382 00:17:40,500 --> 00:17:43,320 l'i-esimo degli studenti e il loro casa come bene. 383 00:17:43,320 --> 00:17:47,560 >> E poi, infine, ora inizieremo a ottenere anale su questo, ora che siamo 384 00:17:47,560 --> 00:17:49,580 familiarità con ciò che malloc e altre funzioni sono state 385 00:17:49,580 --> 00:17:50,570 facendo tutto questo tempo. 386 00:17:50,570 --> 00:17:54,220 Perché devo liberare entrambe nome e la casa, anche se io 387 00:17:54,220 --> 00:17:56,960 non ha chiamato malloc? 388 00:17:56,960 --> 00:17:58,020 >> GetString fatto. 389 00:17:58,020 --> 00:18:00,930 E questo è stato il piccolo sporco segreto per diverse settimane, ma ha GetString 390 00:18:00,930 --> 00:18:03,530 state perdite di memoria in tutto il mettere tutto il semestre finora. 391 00:18:03,530 --> 00:18:05,990 E Valgrand finalmente rivelare questo a noi. 392 00:18:05,990 --> 00:18:10,730 >> Ma non è un grosso problema, perché so che posso semplicemente liberare il nome 393 00:18:10,730 --> 00:18:15,750 e la casa, anche se tecnicamente, per essere super, super sicura, dovrei essere 394 00:18:15,750 --> 00:18:17,890 facendo qualche errore di verifica qui. 395 00:18:17,890 --> 00:18:19,040 Quali sono il tuo istinto ti dice? 396 00:18:19,040 --> 00:18:22,480 Cosa dovrei controllare per prima che io libero Che cosa è un 397 00:18:22,480 --> 00:18:25,470 stringa, aka che un char *? 398 00:18:25,470 --> 00:18:33,460 >> Dovrei davvero controllerò se gli studenti Staffa I Nome punto non 399 00:18:33,460 --> 00:18:34,840 pari nullo. 400 00:18:34,840 --> 00:18:40,400 Poi sarà OK per andare avanti e gratuito tale puntatore, e lo stesso o l'altro 401 00:18:40,400 --> 00:18:41,160 uno pure. 402 00:18:41,160 --> 00:18:46,860 Se il supporto agli studenti i casa dot non è uguale a null, questo ora vi proteggerà 403 00:18:46,860 --> 00:18:52,520 contro la cassa nell'angolo in cui GetString restituisce qualcosa come null. 404 00:18:52,520 --> 00:18:57,310 E abbiamo visto un momento fa, printf volontà proteggerci quassù da solo dicendo 405 00:18:57,310 --> 00:18:58,990 nullo, il che sta a guardare strano. 406 00:18:58,990 --> 00:19:02,340 Ma almeno non sarà segfault, come abbiamo visto. 407 00:19:02,340 --> 00:19:05,990 >> Beh, fammi fare un'altra cosa qui. struct-0 è una specie di stupido programma 408 00:19:05,990 --> 00:19:09,700 perché io entro tutti questi dati, e quindi è perso una volta che il programma termina. 409 00:19:09,700 --> 00:19:10,940 Ma mi permetta di andare avanti e di fare questo. 410 00:19:10,940 --> 00:19:12,830 Permettetemi di fare il terminale finestra un po 'più grande. 411 00:19:12,830 --> 00:19:17,000 Permettetemi di fare le struct-1, che è una nuova versione di questo. 412 00:19:17,000 --> 00:19:18,520 >> Io zoomare un po '. 413 00:19:18,520 --> 00:19:21,620 E adesso lasciatemi correre dot tagliare le strutture-1. 414 00:19:21,620 --> 00:19:22,590 Nome dello studente - 415 00:19:22,590 --> 00:19:31,500 David Mather, facciamo Rob Kirkland, facciamo Lauren Leverett. 416 00:19:31,500 --> 00:19:33,650 La cosa interessante è ora di gara - 417 00:19:33,650 --> 00:19:35,540 e lo so solo questo perché Ho scritto il programma - 418 00:19:35,540 --> 00:19:38,930 c'è un file ora sulla mia attuale directory chiamata students.csv. 419 00:19:38,930 --> 00:19:40,420 Alcuni di voi potrebbero aver visto questi nel mondo reale. 420 00:19:40,420 --> 00:19:42,980 >> Che cos'è un file CSV? 421 00:19:42,980 --> 00:19:44,170 Valori separati da virgole. 422 00:19:44,170 --> 00:19:46,670 E 'un po' come un uomo povero di versione di un file Excel. 423 00:19:46,670 --> 00:19:50,580 E 'una tabella di righe e colonne che è possibile aprire in un programma come Excel, 424 00:19:50,580 --> 00:19:51,800 o numeri su un MAC. 425 00:19:51,800 --> 00:19:55,180 >> E se apro questo file qui su gedit, gara - ed i numeri non ci sono. 426 00:19:55,180 --> 00:19:57,360 Questo è solo gedit raccontare mi numeri di riga. 427 00:19:57,360 --> 00:19:59,740 Comunicazione relativa alla prima linea di questo file è David e Mather. 428 00:19:59,740 --> 00:20:01,450 La prossima linea è Rob virgola Kirkland. 429 00:20:01,450 --> 00:20:04,170 E la terza linea è Lauren Leverett virgola. 430 00:20:04,170 --> 00:20:05,480 >> Quindi cosa ho creato? 431 00:20:05,480 --> 00:20:09,580 Ora ho scritto un programma in C che effettivamente in grado di generare fogli di calcolo 432 00:20:09,580 --> 00:20:11,840 che può essere aperto in programma come Excel. 433 00:20:11,840 --> 00:20:15,520 Non tutto ciò che un insieme di dati convincenti, ma se si dispone di molto più grandi blocchi di 434 00:20:15,520 --> 00:20:18,440 dati che si vuole realmente manipolare e fare grafici delle e dei 435 00:20:18,440 --> 00:20:21,260 come, questo è forse uno modo per creare quei dati. 436 00:20:21,260 --> 00:20:25,370 Inoltre, CSV sono in realtà super-comune solo per la memorizzazione di dati semplici - 437 00:20:25,370 --> 00:20:28,940 Yahoo Finance, per esempio, se si ottiene quotazioni di borsa tramite la loro cosiddetta 438 00:20:28,940 --> 00:20:33,180 API, il servizio gratuito che vi permette di ottenere corrente magazzino up-to-the-date 439 00:20:33,180 --> 00:20:35,650 citazioni per le aziende, che di fornire tali dati nel 440 00:20:35,650 --> 00:20:37,800 semplice formato super-CSV. 441 00:20:37,800 --> 00:20:39,380 >> Così come abbiamo fatto questo? 442 00:20:39,380 --> 00:20:42,530 Ben notare, la maggior parte di questo programma di quasi la stessa. 443 00:20:42,530 --> 00:20:46,870 A meno di notare qui, piuttosto che stampa gli studenti fuori, sulla linea 35 444 00:20:46,870 --> 00:20:51,040 poi, io sostengo che sto salvando il studenti su disco, in modo da salvare un file. 445 00:20:51,040 --> 00:20:53,630 >> Così accorgo che sto dichiarando un FILE * - 446 00:20:53,630 --> 00:20:57,260 Ora, questo è una specie di un'anomalia in C. Per qualsiasi motivo, FILE è tutto maiuscolo, 447 00:20:57,260 --> 00:21:00,690 che non è come la maggior parte di altri tipi di dati in C. Ma questo è un built-in 448 00:21:00,690 --> 00:21:02,320 tipo di dati, FILE *. 449 00:21:02,320 --> 00:21:05,900 E sto dichiarando un puntatore a un file, è come si può pensare che. 450 00:21:05,900 --> 00:21:08,070 >> fopen significa file aperto. 451 00:21:08,070 --> 00:21:09,470 Quale file vuoi aprire? 452 00:21:09,470 --> 00:21:12,620 Voglio aprire un file che voglio io arbitrariamente chiamare students.csv. 453 00:21:12,620 --> 00:21:14,480 Potrei chiamare che tutto quello che voglio. 454 00:21:14,480 --> 00:21:15,200 >> E poi prendere una supposizione. 455 00:21:15,200 --> 00:21:18,960 Che cosa fa il secondo argomento a fopen probabilmente significa? 456 00:21:18,960 --> 00:21:21,480 Destra, w per la scrittura, potrebbe essere r per la lettura. 457 00:21:21,480 --> 00:21:24,120 C'è una per append se voler aggiungere righe e non 458 00:21:24,120 --> 00:21:25,200 sovrascrivere il tutto. 459 00:21:25,200 --> 00:21:28,005 >> Ma voglio solo creare questo file una volta, quindi userò tra virgolette w. 460 00:21:28,005 --> 00:21:31,880 E so che da solo dopo aver letto la documentazione, o la pagina man. 461 00:21:31,880 --> 00:21:35,100 Se il file non è nullo - in altre parole, se nulla è andato storto lì - 462 00:21:35,100 --> 00:21:37,820 mi permetta di scorrere i studenti 0-3. 463 00:21:37,820 --> 00:21:40,410 >> E ora notato che c'è qualcosa sempre in modo leggermente diverso 464 00:21:40,410 --> 00:21:42,110 sulla linea 41 qui. 465 00:21:42,110 --> 00:21:42,960 Non printf. 466 00:21:42,960 --> 00:21:46,530 E 'fprintf per file di printf. 467 00:21:46,530 --> 00:21:47,790 Così sta andando a scrivere sul file. 468 00:21:47,790 --> 00:21:48,860 Quale file? 469 00:21:48,860 --> 00:21:53,630 Quella il cui puntatore si specifica come primo argomento. 470 00:21:53,630 --> 00:21:55,940 >> Poi specifichiamo una stringa di formato. 471 00:21:55,940 --> 00:21:59,660 Poi specifichiamo la stringa che vogliamo plug in per cento del primo s, e 472 00:21:59,660 --> 00:22:04,320 poi un'altra variabile o la seconda cento s. 473 00:22:04,320 --> 00:22:06,760 Allora chiudiamo il file con fclose. 474 00:22:06,760 --> 00:22:09,380 Che ho liberare la memoria, come prima, anche se Dovrei tornare indietro e aggiungere 475 00:22:09,380 --> 00:22:10,540 alcuni controlli per null. 476 00:22:10,540 --> 00:22:12,090 >> E questo è tutto. 477 00:22:12,090 --> 00:22:16,960 fopen, fprintf, fclose mi dà la capacità di creare file di testo. 478 00:22:16,960 --> 00:22:19,640 Ora, vedrete in problema insieme a cinque, che coinvolge le immagini, che verrà usato 479 00:22:19,640 --> 00:22:20,990 file binari invece. 480 00:22:20,990 --> 00:22:24,200 Ma fondamentalmente, l'idea è la stessa, anche se le funzioni di cui avrete bisogno 481 00:22:24,200 --> 00:22:28,710 vedere sono un po 'diverso. 482 00:22:28,710 --> 00:22:32,580 >> Così rapido giro, ma si otterrà fin troppo familiare con il file I/O-- 483 00:22:32,580 --> 00:22:34,960 ingresso e uscita - con pset cinque. 484 00:22:34,960 --> 00:22:38,607 E tutte le domande circa il basi iniziali qui? 485 00:22:38,607 --> 00:22:39,857 Sì? 486 00:22:39,857 --> 00:22:41,880 487 00:22:41,880 --> 00:22:43,710 >> Che cosa succede se si tenta di liberare un valore nullo? 488 00:22:43,710 --> 00:22:48,880 Credo che, a meno che libero ha ottenuto un po 'più user-friendly, è possibile 489 00:22:48,880 --> 00:22:49,890 potenzialmente segfault. 490 00:22:49,890 --> 00:22:54,160 Passando NULL è male perché non mi credere gratuito preoccupa di controllare per voi, 491 00:22:54,160 --> 00:22:57,330 perché sarebbe potenzialmente uno spreco di tempo per fare per sé 492 00:22:57,330 --> 00:22:59,022 tutti nel mondo. 493 00:22:59,022 --> 00:23:00,590 Bella domanda, però. 494 00:23:00,590 --> 00:23:04,300 >> Va bene, quindi questo tipo di ottiene noi di un argomento interessante. 495 00:23:04,300 --> 00:23:07,010 Il tema del problema insieme cinque è forensics. 496 00:23:07,010 --> 00:23:08,420 Almeno questo è una parte del problema proposto. 497 00:23:08,420 --> 00:23:12,030 Forensics si riferisce generalmente al recupero di informazioni che possono o 498 00:23:12,030 --> 00:23:14,110 Non può essere stato cancellato deliberatamente. 499 00:23:14,110 --> 00:23:18,680 E così io ho pensato di dare una rapida assaggio di ciò che sta realmente accadendo tutto 500 00:23:18,680 --> 00:23:21,230 questa volta sotto la cofano del vostro computer. 501 00:23:21,230 --> 00:23:23,960 >> Per esempio, se si dispone all'interno della vostra laptop o computer desktop a 502 00:23:23,960 --> 00:23:28,040 disco rigido, è sia un meccanico dispositivo che gira in realtà - 503 00:23:28,040 --> 00:23:31,650 ci sono cose circolari chiamato piatti che somiglia abbastanza quello che ho 504 00:23:31,650 --> 00:23:34,540 appena avuto sullo schermo qui, anche se questo è sempre più vecchia scuola. 505 00:23:34,540 --> 00:23:37,370 Si tratta di un tre-e-un-mezzo pollice disco rigido. 506 00:23:37,370 --> 00:23:40,070 E tre pollici e mezzo si riferisce di con della cosa quando lo si installa 507 00:23:40,070 --> 00:23:40,890 in un computer. 508 00:23:40,890 --> 00:23:44,890 >> Molti di voi ragazzi nel vostro laptop ora avere unità a stato solido, o SSD, 509 00:23:44,890 --> 00:23:46,260 che non hanno parti in movimento. 510 00:23:46,260 --> 00:23:49,170 Sono più come RAM e meno come questi dispositivi meccanici. 511 00:23:49,170 --> 00:23:51,450 Ma le idee sono sempre gli stessi, di certo in quanto si riferiscono 512 00:23:51,450 --> 00:23:52,790 al problema di impostare cinque. 513 00:23:52,790 --> 00:23:57,400 >> E se ci pensate ora un disco rigido rappresenta di essere un cerchio, che 514 00:23:57,400 --> 00:23:58,930 Io traggo come questo qui. 515 00:23:58,930 --> 00:24:02,290 Quando si crea un file sul computer, che si tratti di un SSD, o in 516 00:24:02,290 --> 00:24:06,610 questo caso, un vecchio disco rigido scuola, tale file comprende più bit. 517 00:24:06,610 --> 00:24:10,510 Diciamo che si tratta di questo 0 e 1, un gruppo intero di 0 e 1. 518 00:24:10,510 --> 00:24:11,660 Quindi questo è il mio intero disco rigido. 519 00:24:11,660 --> 00:24:13,225 Questo è apparentemente una abbastanza grande file. 520 00:24:13,225 --> 00:24:18,080 E utilizza il 0 e 1 in quel porzione del piatto fisico. 521 00:24:18,080 --> 00:24:19,750 >> Beh, che è quella parte fisica? 522 00:24:19,750 --> 00:24:25,310 Bene, si scopre che su un disco rigido, almeno di questo tipo, c'è 523 00:24:25,310 --> 00:24:27,340 queste minuscole particelle magnetiche. 524 00:24:27,340 --> 00:24:32,630 E hanno essenzialmente a nord e poli sud a loro, in modo che se si 525 00:24:32,630 --> 00:24:35,710 trasformare una di queste particelle magnetiche questo modo, si potrebbe dire che è 526 00:24:35,710 --> 00:24:36,720 rappresenta un 1. 527 00:24:36,720 --> 00:24:39,340 E se è a testa in giù a sud di nord, si potrebbe dire che è 528 00:24:39,340 --> 00:24:40,390 rappresenta un 0. 529 00:24:40,390 --> 00:24:43,660 >> Così nel mondo fisico reale, che è come si potrebbe rappresentare qualcosa di 530 00:24:43,660 --> 00:24:45,670 stato binario di 0 e un 1. 531 00:24:45,670 --> 00:24:46,720 Ecco, questo è tutto un file è. 532 00:24:46,720 --> 00:24:49,300 C'è un sacco di magnetico particelle che sono loro così o 533 00:24:49,300 --> 00:24:51,920 in questo modo, la creazione di modelli di 0 e 1. 534 00:24:51,920 --> 00:24:56,760 >> Ma si scopre quando si salva un file, alcune informazioni vengono salvate separatamente. 535 00:24:56,760 --> 00:25:00,000 Quindi questo è un piccolo tavolo, una directory, per così dire. 536 00:25:00,000 --> 00:25:05,810 E io chiamo questo il nome della colonna, e Chiamerò questa posizione colonna. 537 00:25:05,810 --> 00:25:08,850 >> E ho intenzione di dire, supponiamo questo è il mio curriculum. 538 00:25:08,850 --> 00:25:14,050 Il mio resume.doc viene conservato a posizione, diciamo 123. 539 00:25:14,050 --> 00:25:15,390 Vado sempre per quel numero. 540 00:25:15,390 --> 00:25:18,810 Ma basti dire che, proprio come in RAM, si può prendere un disco rigido 541 00:25:18,810 --> 00:25:22,350 questo è un gigabyte o 200 gigabyte o di un terabyte, e si può 542 00:25:22,350 --> 00:25:23,750 numero di tutti i byte. 543 00:25:23,750 --> 00:25:26,480 È possibile numerare tutti i blocchi di 8 bit. 544 00:25:26,480 --> 00:25:29,030 >> Quindi diremo che questo è la posizione 123. 545 00:25:29,030 --> 00:25:32,070 Quindi questa directory all'interno del mio esercizio sistema si ricorda che la mia 546 00:25:32,070 --> 00:25:34,250 curriculum è in posizione 123. 547 00:25:34,250 --> 00:25:36,850 Ma si fa interessante quando si elimina un file. 548 00:25:36,850 --> 00:25:37,820 >> Così, per esempio - 549 00:25:37,820 --> 00:25:40,790 e per fortuna, la maggior parte del mondo ha catturato su questo - che cosa accade quando 550 00:25:40,790 --> 00:25:45,040 si trascina un file per il sistema operativo Mac Cestino o il vostro Cestino di Windows? 551 00:25:45,040 --> 00:25:48,290 552 00:25:48,290 --> 00:25:50,510 Qual è lo scopo di fare questo? 553 00:25:50,510 --> 00:25:53,860 E ', ovviamente, di sbarazzarsi del file, ma quello che fa il gesto di trascinamento e 554 00:25:53,860 --> 00:25:57,550 cadere nel cestino o la vostra Cestino fare su un computer? 555 00:25:57,550 --> 00:25:59,230 >> Assolutamente niente, davvero. 556 00:25:59,230 --> 00:26:00,320 E 'proprio come una cartella. 557 00:26:00,320 --> 00:26:01,800 E 'una cartella speciale, per essere sicuri. 558 00:26:01,800 --> 00:26:04,460 Ma lo fa effettivamente cancellare il file? 559 00:26:04,460 --> 00:26:06,780 >> Beh, no, perché alcuni di voi probabilmente sono stati come, oh accidenti, non l'hai fatto 560 00:26:06,780 --> 00:26:07,420 significa per farlo. 561 00:26:07,420 --> 00:26:09,130 Così si fa doppio clic sul Trash o Cestino. 562 00:26:09,130 --> 00:26:11,630 Hai curiosato e hai recuperato il file semplicemente trascinandolo 563 00:26:11,630 --> 00:26:12,110 fuori di lì. 564 00:26:12,110 --> 00:26:14,420 Quindi, chiaramente, non è necessariamente eliminarlo. 565 00:26:14,420 --> 00:26:15,990 >> OK, tu sei più intelligente di così. 566 00:26:15,990 --> 00:26:18,860 Voi sapete che solo trascinandolo nella Trash o Cestino non significa 567 00:26:18,860 --> 00:26:19,930 si sta svuotando il cestino. 568 00:26:19,930 --> 00:26:24,110 Così si va fino al menu, e si dice Vuota il Cestino o Svuota cestino. 569 00:26:24,110 --> 00:26:25,360 Allora che cosa succede? 570 00:26:25,360 --> 00:26:29,070 571 00:26:29,070 --> 00:26:32,530 >> Sì, così viene eliminato più. 572 00:26:32,530 --> 00:26:37,660 Ma tutto ciò che accade è questo. 573 00:26:37,660 --> 00:26:45,350 Il computer dimentica dove resume.doc era. 574 00:26:45,350 --> 00:26:47,400 >> Ma ciò che non è cambiato apparentemente nella foto? 575 00:26:47,400 --> 00:26:51,390 576 00:26:51,390 --> 00:26:55,570 I bit, lo 0 e 1 che rivendico sono sul sito di qualche aspetto fisico 577 00:26:55,570 --> 00:26:56,280 l'hardware. 578 00:26:56,280 --> 00:26:57,110 Sono ancora lì. 579 00:26:57,110 --> 00:26:58,930 E 'solo il computer ha dimenticato quello che sono. 580 00:26:58,930 --> 00:27:03,160 >> Quindi è essenzialmente liberato del file bit in modo che possano essere riutilizzati. 581 00:27:03,160 --> 00:27:06,940 Ma non prima di creare più file, e altri file, e più file di volontà 582 00:27:06,940 --> 00:27:12,150 probabilisticamente, quelli 0 e 1, queste particelle magnetiche, vengono riutilizzati, 583 00:27:12,150 --> 00:27:16,220 lato testa o fino, per altri file, 0 ed 1. 584 00:27:16,220 --> 00:27:17,980 >> In modo da avere questa finestra di tempo. 585 00:27:17,980 --> 00:27:19,860 E non si tratta di prevedibile lunghezza, davvero. 586 00:27:19,860 --> 00:27:22,240 Dipende dalla dimensione del disco unità e quanti file avete e 587 00:27:22,240 --> 00:27:23,490 quanto velocemente si fanno nuovi. 588 00:27:23,490 --> 00:27:27,050 Ma c'è questa finestra di tempo durante il che quel file è ancora perfettamente 589 00:27:27,050 --> 00:27:27,770 recuperabile. 590 00:27:27,770 --> 00:27:31,050 >> Quindi, se mai utilizzare programmi come McAfee o Norton per cercare di recuperare 591 00:27:31,050 --> 00:27:35,680 dati, tutti stanno facendo sta cercando di recuperare questa cosiddetta directory di 592 00:27:35,680 --> 00:27:37,340 capire dove il file è stato. 593 00:27:37,340 --> 00:27:40,605 E a volte Norton e dirà: file è il 93% recuperabile. 594 00:27:40,605 --> 00:27:42,020 Ebbene, che cosa vuol dire? 595 00:27:42,020 --> 00:27:45,690 Questo significa solo che qualche altro file casualmente finito per usare, per esempio, 596 00:27:45,690 --> 00:27:48,920 quelle punte dal vostro file originale. 597 00:27:48,920 --> 00:27:51,950 >> Quindi, ciò che è effettivamente coinvolto nel recupero dati? 598 00:27:51,950 --> 00:27:55,720 Beh, se non hai qualcosa di simile Norton pre-installato sul computer, 599 00:27:55,720 --> 00:27:59,510 il meglio a volte si può fare è guardare in tutto il disco rigido alla ricerca di 600 00:27:59,510 --> 00:28:00,510 pattern di bit. 601 00:28:00,510 --> 00:28:05,350 E uno dei temi del problema insieme cinque è che si cercherà il 602 00:28:05,350 --> 00:28:09,570 equivalente di un disco rigido, un forense immagine di una scheda Compact Flash da un 603 00:28:09,570 --> 00:28:13,660 macchina fotografica digitale, alla ricerca della 0s 1s e che tipicamente, con elevata 604 00:28:13,660 --> 00:28:16,720 probabilità, rappresentano l' inizio di una immagine JPEG. 605 00:28:16,720 --> 00:28:21,120 >> E voi potete recuperare le immagini da assumendo, se vedo questo modello di 606 00:28:21,120 --> 00:28:24,380 bit sul immagine forense, con alta probabilità, che segna 607 00:28:24,380 --> 00:28:25,650 l'inizio di un JPEG. 608 00:28:25,650 --> 00:28:29,520 E se vedo ancora una volta lo stesso modello, che probabilmente segna l'inizio di 609 00:28:29,520 --> 00:28:32,440 un altro JPEG, e un altro JPEG, e un altro JPEG. 610 00:28:32,440 --> 00:28:34,970 E questo è in genere come recupero di dati funzionerà. 611 00:28:34,970 --> 00:28:37,870 Che cosa è bella di file JPEG è pur il formato di file per sé è piuttosto 612 00:28:37,870 --> 00:28:44,400 complesso, all'inizio di ogni tale file è in realtà abbastanza identificabile 613 00:28:44,400 --> 00:28:47,370 e semplice, come si vedrà, Se non hai già. 614 00:28:47,370 --> 00:28:50,270 >> Quindi, diamo uno sguardo più da vicino sotto il cofano come esattamente ciò che è stato 615 00:28:50,270 --> 00:28:53,360 in corso, e ciò che questi 0 e 1 sono, per darvi un po 'di più di un 616 00:28:53,360 --> 00:28:55,330 contesto di questa particolare sfida. 617 00:28:55,330 --> 00:28:55,510 >> [RIPRODUZIONE VIDEO] 618 00:28:55,510 --> 00:28:58,700 >> -Dove il vostro PC memorizza la maggior parte dei suoi dati permanenti. 619 00:28:58,700 --> 00:29:03,390 Per fare questo, i dati viaggiano da RAM insieme a segnali software che raccontano 620 00:29:03,390 --> 00:29:06,110 il disco rigido come memorizzare i dati. 621 00:29:06,110 --> 00:29:09,410 I circuiti del disco rigido traducono tali segnali in tensione 622 00:29:09,410 --> 00:29:10,870 fluttuazioni. 623 00:29:10,870 --> 00:29:14,970 Questi, a loro volta, controllano il disco rigido del parti mobili, alcuni dei pochi 624 00:29:14,970 --> 00:29:17,910 parti mobili lasciati in computer moderno. 625 00:29:17,910 --> 00:29:22,130 >> Alcuni dei segnali di controllo di un motore che gira piatti in metallo rivestite. 626 00:29:22,130 --> 00:29:25,470 I vostri dati sono effettivamente memorizzati su questi piatti. 627 00:29:25,470 --> 00:29:28,610 Altri segnali muovono la lettura / scrittura testine di lettura o 628 00:29:28,610 --> 00:29:30,710 scrivere i dati sui piatti. 629 00:29:30,710 --> 00:29:35,450 Questo macchinario così precisa che un essere umano capelli non riusciva nemmeno a passare tra la 630 00:29:35,450 --> 00:29:37,280 testine e piatti rotanti. 631 00:29:37,280 --> 00:29:40,316 Eppure, tutto funziona a una velocità terrificante. 632 00:29:40,316 --> 00:29:40,660 >> [FINE RIPRODUZIONE VIDEO] 633 00:29:40,660 --> 00:29:42,190 >> DAVID MALAN: Zoom in un piccolo più profonda ora a ciò che è 634 00:29:42,190 --> 00:29:44,360 in realtà su quei piatti. 635 00:29:44,360 --> 00:29:44,720 >> [RIPRODUZIONE VIDEO] 636 00:29:44,720 --> 00:29:47,660 >> -Diamo un'occhiata a ciò che abbiamo appena visto al rallentatore. 637 00:29:47,660 --> 00:29:51,710 Quando un breve impulso di energia elettrica è inviato alla testina di lettura / scrittura, se lanci 638 00:29:51,710 --> 00:29:54,650 su una piccola elettromagnetica per una frazione di secondo. 639 00:29:54,650 --> 00:29:58,970 Il magnete crea un campo, che cambia la polarità di un piccolo, piccolo 640 00:29:58,970 --> 00:30:02,850 porzione delle particelle metalliche che cappotto ogni superficie del piatto. 641 00:30:02,850 --> 00:30:05,940 >> Una serie di pattern di questi piccoli, aree carico-up sul disco 642 00:30:05,940 --> 00:30:08,470 rappresenta un singolo bit di dati del numero binario 643 00:30:08,470 --> 00:30:10,530 sistema utilizzato dai computer. 644 00:30:10,530 --> 00:30:13,775 Ora, se viene inviato l'attuale senso unico attraverso la testina di lettura / scrittura, l'area 645 00:30:13,775 --> 00:30:15,970 è polarizzata in una direzione. 646 00:30:15,970 --> 00:30:17,950 Se la corrente viene inviata nella direzione opposta, la 647 00:30:17,950 --> 00:30:19,930 polarizzazione è invertita. 648 00:30:19,930 --> 00:30:22,370 >> Come ottenere i dati dal disco rigido? 649 00:30:22,370 --> 00:30:24,090 Basta invertire il processo. 650 00:30:24,090 --> 00:30:26,550 Quindi è le particelle sul disco che ottengono la corrente nel 651 00:30:26,550 --> 00:30:27,960 lettura / scrittura testa mobile. 652 00:30:27,960 --> 00:30:30,700 Mettere insieme milioni di queste segmenti magnetizzati, e 653 00:30:30,700 --> 00:30:32,160 hai un file. 654 00:30:32,160 --> 00:30:36,060 >> Ora, i pezzi di un singolo file può essere sparsi in tutto un disco di 655 00:30:36,060 --> 00:30:39,970 piatti, un po 'come il casino di carte sulla scrivania. 656 00:30:39,970 --> 00:30:43,500 Quindi uno speciale extra file tiene traccia di dove tutto è. 657 00:30:43,500 --> 00:30:45,985 Non avresti voluto qualcosa di simile? 658 00:30:45,985 --> 00:30:46,470 >> [FINE RIPRODUZIONE VIDEO] 659 00:30:46,470 --> 00:30:47,820 >> DAVID MALAN: OK, probabilmente no. 660 00:30:47,820 --> 00:30:52,070 Così come molti di voi ragazzi cresciuto con questi? 661 00:30:52,070 --> 00:30:53,970 OK, quindi è sempre meno mani ogni anno. 662 00:30:53,970 --> 00:30:56,550 Ma sono contento che tu sia almeno familiare con loro, perché questo e il nostro 663 00:30:56,550 --> 00:31:00,520 libro di demo, purtroppo, stanno morendo una molto rallentare la morte qui di familiarità. 664 00:31:00,520 --> 00:31:04,010 >> Ma questo è quello che io, almeno, di nuovo in scuola superiore, uso usato per i backup. 665 00:31:04,010 --> 00:31:08,110 Ed è stato incredibile, perché si potrebbe memorizzare 1.4 megabyte su 666 00:31:08,110 --> 00:31:08,930 questo disco in particolare. 667 00:31:08,930 --> 00:31:12,260 E questa era la versione ad alta densità, come indicato dal HD, che ha 668 00:31:12,260 --> 00:31:14,240 significa prima di oggi i video in HD. 669 00:31:14,240 --> 00:31:16,400 >> Densità standard era di 800 kilobyte. 670 00:31:16,400 --> 00:31:18,640 E prima ancora, ci sono stati Dischi 400 kilobyte. 671 00:31:18,640 --> 00:31:23,120 E prima ancora, ci sono stati 5 e 1/4 dischi pollici, che erano vere floppy, 672 00:31:23,120 --> 00:31:25,680 e un po 'più ampia e più alta di queste cose qui. 673 00:31:25,680 --> 00:31:29,150 Ma si può effettivamente vedere il cosiddetto aspetto floppy di questi dischi. 674 00:31:29,150 --> 00:31:32,630 >> E funzionale, sono in realtà abbastanza simile ai dischi rigidi di a 675 00:31:32,630 --> 00:31:33,570 Almeno questo tipo. 676 00:31:33,570 --> 00:31:37,270 Ancora una volta, gli SSD in computer più recenti lavorare un po 'diverso. 677 00:31:37,270 --> 00:31:41,530 Ma se si sposta quella linguetta metallica poco, si può effettivamente vedere un po 'di biscotto, 678 00:31:41,530 --> 00:31:42,560 o piatto. 679 00:31:42,560 --> 00:31:43,830 >> Non è di metallo come questo. 680 00:31:43,830 --> 00:31:46,000 Questo è in realtà un po 'di più economico di materiale plastico. 681 00:31:46,000 --> 00:31:46,750 Ed è possibile tipo di muovere esso. 682 00:31:46,750 --> 00:31:50,310 E hai trully appena cancellato alcuni numero di bit o particelle magnetiche 683 00:31:50,310 --> 00:31:51,220 da questo disco. 684 00:31:51,220 --> 00:31:52,710 >> Quindi per fortuna, non c'è nulla su di esso. 685 00:31:52,710 --> 00:31:55,790 Se quella cosa è nel modo in cui - e coprire i tuoi occhi e quelli del tuo vicino di casa - 686 00:31:55,790 --> 00:31:58,865 si può solo tipo di tirare questo tutto fuori guaina così. 687 00:31:58,865 --> 00:32:01,900 Ma c'è una piccola sorgente, in modo da essere consapevole che con i vostri occhi. 688 00:32:01,900 --> 00:32:03,620 Così ora avete veramente un disco floppy. 689 00:32:03,620 --> 00:32:07,090 >> E quel che è notevole di questo è che in quanto questo è un 690 00:32:07,090 --> 00:32:10,830 rappresentazione in scala ridotta di un più ampio disco rigido, queste cose sono super, 691 00:32:10,830 --> 00:32:11,590 super semplice. 692 00:32:11,590 --> 00:32:15,170 Se pizzicare il fondo di esso, ora che che cosa di metallo è fuori, e la buccia 693 00:32:15,170 --> 00:32:20,990 aprirli, tutto quello che c'è è di due pezzi di feltro e il cosiddetto disco floppy 694 00:32:20,990 --> 00:32:22,930 con un pezzo di metallo all'interno. 695 00:32:22,930 --> 00:32:25,990 >> E non ci va la metà di il contenuto del mio disco. 696 00:32:25,990 --> 00:32:27,540 Ci va un altro mezzo di loro. 697 00:32:27,540 --> 00:32:31,375 Ma questo è tutto quello che stava filando dentro del computer in tempi passati. 698 00:32:31,375 --> 00:32:35,220 699 00:32:35,220 --> 00:32:38,310 >> E ancora, per mettere questo in prospettiva, quanto grande è la maggior parte del 700 00:32:38,310 --> 00:32:39,560 duro spinge in questi giorni? 701 00:32:39,560 --> 00:32:41,960 702 00:32:41,960 --> 00:32:46,230 500 gigabyte, un terabyte forse in un computer desktop, 2 terabyte, 3 703 00:32:46,230 --> 00:32:47,630 terabyte, 4 terabyte, giusto? 704 00:32:47,630 --> 00:32:52,480 Questo è un megabyte, prendere o lasciare, che non può nemmeno andare bene un tipico MP3 705 00:32:52,480 --> 00:32:55,310 più in questi giorni, o alcune file musicale simile. 706 00:32:55,310 --> 00:32:59,500 >> Quindi un piccolo souvenir per te oggi, e anche per contribuire a contestualizzare ciò che 707 00:32:59,500 --> 00:33:03,570 saremo dare per scontato ora nel problema impostare cinque. 708 00:33:03,570 --> 00:33:04,820 Quindi questi sono il vostro da mantenere. 709 00:33:04,820 --> 00:33:07,340 710 00:33:07,340 --> 00:33:13,370 Quindi, mi permetta di transizione in cui sarà Passo successivo pset pure. 711 00:33:13,370 --> 00:33:18,470 Così ora abbiamo impostato questa pagina - oh, un paio di annunci in modo rapido. 712 00:33:18,470 --> 00:33:21,730 >> Questo Venerdì, se si desidera unirsi CS50 per il pranzo, andare al solito posto, 713 00:33:21,730 --> 00:33:23,610 cs50.net/rsvp. 714 00:33:23,610 --> 00:33:25,100 E del progetto definitivo - 715 00:33:25,100 --> 00:33:28,520 così per il programma, abbiamo pubblicato il specifiche di progetto definitivo già. 716 00:33:28,520 --> 00:33:31,410 Rendetevi conto che ciò non significa è dovuto in particolare al più presto. 717 00:33:31,410 --> 00:33:33,990 E 'pubblicato, in realtà, solo per ottenere voi ragazzi a pensarci. 718 00:33:33,990 --> 00:33:37,620 E, in effetti, un super significativo Percentuale di voi sarà affrontando 719 00:33:37,620 --> 00:33:40,780 progetti finali sul materiale che abbiamo non hanno ancora ottenuto per la classe, 720 00:33:40,780 --> 00:33:42,730 ma sarà già la prossima settimana. 721 00:33:42,730 --> 00:33:45,530 >> Si noti, però, che la specifica richiede pochi componenti diverse dello 722 00:33:45,530 --> 00:33:46,190 progetto finale. 723 00:33:46,190 --> 00:33:49,590 Il primo, in poche settimane, è un proposta preliminare, una e-mail abbastanza casuale per 724 00:33:49,590 --> 00:33:52,760 il vostro TF di dirgli o che cosa sei pensare per il vostro progetto, con 725 00:33:52,760 --> 00:33:53,650 nessun impegno. 726 00:33:53,650 --> 00:33:56,710 La proposta sarà la vostra particolare impegno, dicendo: ecco, questo è ciò che 727 00:33:56,710 --> 00:33:57,770 Mi piacerebbe fare per il mio progetto. 728 00:33:57,770 --> 00:33:58,250 Cosa ne pensi? 729 00:33:58,250 --> 00:33:58,650 Troppo grande? 730 00:33:58,650 --> 00:33:59,145 Troppo piccolo? 731 00:33:59,145 --> 00:34:00,330 E 'gestibile? 732 00:34:00,330 --> 00:34:02,230 E vedi le specifiche per maggiori dettagli. 733 00:34:02,230 --> 00:34:05,060 >> Un paio di settimane dopo che è lo stato relazione, che è un modo simile 734 00:34:05,060 --> 00:34:08,260 e-mail casuale alla vostra TF dire quanto molto indietro siete nella vostra finale 735 00:34:08,260 --> 00:34:12,360 attuazione del progetto, seguito dalla il CS50 Hackathon a cui tutti 736 00:34:12,360 --> 00:34:17,520 è invitato, che sarà un evento da 20:00 una sera fino a 07:00 737 00:34:17,520 --> 00:34:19,150 Del mattino successivo. 738 00:34:19,150 --> 00:34:22,560 Pizza, come posso aver detto in settimana pari a zero, wil essere servita alle 9:00 PM, 739 00:34:22,560 --> 00:34:24,120 Cibo cinese alle 01:00. 740 00:34:24,120 --> 00:34:27,929 E se siete ancora svegli alle 5:00, vi porteremo a IHOP per la prima colazione. 741 00:34:27,929 --> 00:34:31,310 >> Quindi la Hackathon è uno dei più esperienze memorabili nella classe. 742 00:34:31,310 --> 00:34:35,290 Poi l'implementazione è dovuta e poi il climax CS50 Fiera. 743 00:34:35,290 --> 00:34:38,070 Maggiori dettagli su tutte queste nelle settimane a venire. 744 00:34:38,070 --> 00:34:40,739 >> Ma torniamo a qualcosa di vecchia scuola - 745 00:34:40,739 --> 00:34:41,920 nuovamente, un array. 746 00:34:41,920 --> 00:34:45,040 Quindi un array è stato bello, perché risolve problemi come l'abbiamo visto solo un 747 00:34:45,040 --> 00:34:49,290 poco fa con strutture studentesche sempre un po 'fuori controllo, se 748 00:34:49,290 --> 00:34:52,405 vogliono avere uno studente, studente di due, studente tre, studente puntini puntini, 749 00:34:52,405 --> 00:34:54,400 qualche numero arbitrario di studenti. 750 00:34:54,400 --> 00:34:58,850 >> Così gli array, qualche settimana fa, piombò in e risolto tutti i nostri problemi di non 751 00:34:58,850 --> 00:35:03,340 sapendo in anticipo quante cose di un certo tipo che potremmo desiderare. 752 00:35:03,340 --> 00:35:07,390 E abbiamo visto che le strutture ci possono aiutare organizzare ulteriormente il nostro codice e mantenere 753 00:35:07,390 --> 00:35:11,660 variabili concettualmente simili, come un nome e una casa, insieme, in modo da 754 00:35:11,660 --> 00:35:15,570 li può trattare come un'unica entità, all'interno di cui ci sono più piccole parti. 755 00:35:15,570 --> 00:35:17,810 >> Ma array hanno alcuni svantaggi. 756 00:35:17,810 --> 00:35:19,780 Quali sono alcuni degli svantaggi abbiamo incontrato 757 00:35:19,780 --> 00:35:22,320 con array finora? 758 00:35:22,320 --> 00:35:23,450 Che cos'è? 759 00:35:23,450 --> 00:35:28,130 Misura fissa - quindi, anche se si potrebbe essere in grado di allocare memoria per una 760 00:35:28,130 --> 00:35:32,310 array, una volta che si sa quanti studenti avete, quanti caratteri hai 761 00:35:32,310 --> 00:35:35,460 da parte dell'utente, una volta assegnato la matrice, hai sorta di dipinto 762 00:35:35,460 --> 00:35:36,740 te in un angolo. 763 00:35:36,740 --> 00:35:40,600 >> Poiché non è possibile inserire nuovi elementi nel bel mezzo di un array. 764 00:35:40,600 --> 00:35:43,660 Non è possibile inserire più elementi al termine di un array. 765 00:35:43,660 --> 00:35:47,750 Davvero, è necessario ricorrere alla creazione di un tutta una serie nuova, come abbiamo discusso, 766 00:35:47,750 --> 00:35:49,320 copiando il vecchio nel nuovo. 767 00:35:49,320 --> 00:35:52,610 E di nuovo, questo è il mal di testa che GetString offerte con per voi. 768 00:35:52,610 --> 00:35:56,170 >> Ma ancora una volta, non si può nemmeno inserire qualcosa nel mezzo della matrice 769 00:35:56,170 --> 00:35:58,200 se il tasso non è completamente riempita. 770 00:35:58,200 --> 00:36:03,010 Per esempio, se questa matrice qui di dimensione sei ha solo cinque cose in esso, 771 00:36:03,010 --> 00:36:06,080 Beh, si potrebbe semplicemente virare qualcosa sull'estremità. 772 00:36:06,080 --> 00:36:08,200 Ma cosa succede se si vuole inserire qualcosa in mezzo alla 773 00:36:08,200 --> 00:36:11,280 matrice, anche se potrebbe avere cinque su sei cose in esso? 774 00:36:11,280 --> 00:36:14,250 >> Ebbene, che cosa abbiamo fatto quando abbiamo avuto tutti dei nostri volontari umani sul palco in 775 00:36:14,250 --> 00:36:15,110 ultime settimane? 776 00:36:15,110 --> 00:36:18,710 Se volessimo mettere qualcuno qui, sia queste persone come spostare questo 777 00:36:18,710 --> 00:36:22,540 modo, o queste persone come spostare questo modo, e che è diventato costoso. 778 00:36:22,540 --> 00:36:26,950 Lo spostamento di persone all'interno di un serie finì sommando e costano 779 00:36:26,950 --> 00:36:31,240 noi ora, quindi molto del nostro n quadrato tempi di esecuzione come insertion sort, per 780 00:36:31,240 --> 00:36:32,550 esempio, nel caso peggiore. 781 00:36:32,550 --> 00:36:36,520 Così gli array sono grandi, ma si deve sai in anticipo quanto grande vuoi. 782 00:36:36,520 --> 00:36:38,030 >> Quindi, OK, ecco una soluzione. 783 00:36:38,030 --> 00:36:43,860 Se io non so in anticipo quante studenti che potrebbero avere, e so che una volta 784 00:36:43,860 --> 00:36:47,870 Decido, però, mi sono bloccato con quella molti studenti, perché non ho sempre 785 00:36:47,870 --> 00:36:51,740 allocare il doppio dello spazio come potrei pensare ho bisogno? 786 00:36:51,740 --> 00:36:54,450 Non è forse una soluzione ragionevole? 787 00:36:54,450 --> 00:36:58,240 >> Realisticamente, non credo che siamo andando ad avere bisogno di più di 50 slot 788 00:36:58,240 --> 00:37:02,190 in una matrice per una classe di medie dimensioni, così facciamo solo Round Up. 789 00:37:02,190 --> 00:37:07,040 Farò 100 slot nel mio array, basta in modo che possiamo sicuramente ottenere il 790 00:37:07,040 --> 00:37:10,330 numero di studenti che mi aspetto di essere in qualche classe di medie dimensioni. 791 00:37:10,330 --> 00:37:14,320 Allora perché non arrotondare e allocare più memoria, tipicamente, per un array 792 00:37:14,320 --> 00:37:16,290 di quanto si pensi si potrebbe anche bisogno? 793 00:37:16,290 --> 00:37:20,190 Che cos'è questo semplice pushback a questa idea? 794 00:37:20,190 --> 00:37:21,440 >> Stai solo sprecando memoria. 795 00:37:21,440 --> 00:37:25,350 Letteralmente ogni programma che si scrive allora è forse utilizzando il doppio della quantità di memoria 796 00:37:25,350 --> 00:37:26,680 hai veramente bisogno. 797 00:37:26,680 --> 00:37:28,990 E che proprio non sentire come un particolarmente soluzione elegante. 798 00:37:28,990 --> 00:37:31,990 Inoltre, diminuisce solo l' probabilità di un problema. 799 00:37:31,990 --> 00:37:35,300 Se ti capita di avere un corso popolare un semestre e si hanno 101 800 00:37:35,300 --> 00:37:39,610 studenti, il programma è ancora fondamentalmente di fronte lo stesso problema. 801 00:37:39,610 --> 00:37:44,280 >> Quindi per fortuna, c'è una soluzione per questo annuncio a tutti i nostri problemi in forma 802 00:37:44,280 --> 00:37:46,790 di strutture di dati che sono più complessa di quelle 803 00:37:46,790 --> 00:37:47,970 che abbiamo visto finora. 804 00:37:47,970 --> 00:37:50,530 Questo, io sostengo, è una lista concatenata. 805 00:37:50,530 --> 00:37:51,920 Questa è una lista di numeri - 806 00:37:51,920 --> 00:37:54,970 9, 17, 22, 26, e 34 - 807 00:37:54,970 --> 00:38:00,120 che sono stati collegati tra loro per mezzo di quello che ho disegnato come frecce. 808 00:38:00,120 --> 00:38:03,580 >> In altre parole, se ho voluto rappresentare un array, ho potuto fare 809 00:38:03,580 --> 00:38:04,910 qualcosa di simile a questo. 810 00:38:04,910 --> 00:38:07,310 E io ci metto questo sulla testa in un attimo. 811 00:38:07,310 --> 00:38:09,970 Potevo fare - 812 00:38:09,970 --> 00:38:12,520 ciao, tutto bene. 813 00:38:12,520 --> 00:38:14,470 Stand by. 814 00:38:14,470 --> 00:38:17,360 Nuovo computer qui, chiaro - 815 00:38:17,360 --> 00:38:18,090 tutto bene. 816 00:38:18,090 --> 00:38:21,730 >> Quindi, se ho questi numeri in serie - 817 00:38:21,730 --> 00:38:28,880 9, 17, 22, 26, 24 - 818 00:38:28,880 --> 00:38:30,530 non necessariamente in scala. 819 00:38:30,530 --> 00:38:33,730 Bene, ecco la mia matrice - 820 00:38:33,730 --> 00:38:34,980 oh mio dio. 821 00:38:34,980 --> 00:38:38,700 822 00:38:38,700 --> 00:38:40,395 Bene, ecco il mio array. 823 00:38:40,395 --> 00:38:44,110 824 00:38:44,110 --> 00:38:45,050 Oh mio dio. 825 00:38:45,050 --> 00:38:48,820 >> [Risata] 826 00:38:48,820 --> 00:38:49,440 >> DAVID MALAN: Pretend. 827 00:38:49,440 --> 00:38:52,330 E 'troppo sforzo per tornare indietro e fissare che, quindi non - 828 00:38:52,330 --> 00:38:54,290 26. 829 00:38:54,290 --> 00:38:57,650 Quindi abbiamo questa serie di 9, 17, 22, 26, e 34. 830 00:38:57,650 --> 00:39:00,260 Per quelli di voi può vedere la imbarazzante errore che ho appena fatto, 831 00:39:00,260 --> 00:39:00,830 non vi è. 832 00:39:00,830 --> 00:39:04,490 >> Quindi io sostengo che questo è un soluzione molto efficiente. 833 00:39:04,490 --> 00:39:07,310 Ho ripartito come molti interi come Ho bisogno - uno, due, tre, 834 00:39:07,310 --> 00:39:09,100 quattro, cinque, o sei - 835 00:39:09,100 --> 00:39:11,660 e ho quindi memorizzati i numeri all'interno di questa matrice. 836 00:39:11,660 --> 00:39:15,220 Ma supponiamo, allora, voglio inserire un valore come il numero 8? 837 00:39:15,220 --> 00:39:16,100 Beh, dove va a finire? 838 00:39:16,100 --> 00:39:18,530 Supponiamo che io voglio inserire un numero come 20. 839 00:39:18,530 --> 00:39:19,790 Beh, dove va a finire? 840 00:39:19,790 --> 00:39:23,160 Da qualche parte lì in mezzo, o il numero 35 deve andare 841 00:39:23,160 --> 00:39:24,010 qualche parte alla fine. 842 00:39:24,010 --> 00:39:25,320 Ma sono tutti fuori di spazio. 843 00:39:25,320 --> 00:39:29,120 >> E quindi questa è una sfida fondamentale di array che non sono la soluzione. 844 00:39:29,120 --> 00:39:32,280 Ho affermato poco fa, GetString risolve questo problema. 845 00:39:32,280 --> 00:39:37,380 Se si desidera inserire un sesto numero in questo array, quello che è almeno un 846 00:39:37,380 --> 00:39:40,090 soluzione che si può ripiegare su di sicuro, proprio come facciamo con GetString? 847 00:39:40,090 --> 00:39:44,340 848 00:39:44,340 --> 00:39:46,030 Che cos'è? 849 00:39:46,030 --> 00:39:48,190 >> Beh, renderlo più grande è più facile a dirsi che a farsi. 850 00:39:48,190 --> 00:39:52,810 Non possiamo necessariamente fare la matrice più grande, ma cosa possiamo fare? 851 00:39:52,810 --> 00:39:56,570 Fare un nuovo array che è più grande, di dimensioni 6, o forse taglia 10, se vogliamo 852 00:39:56,570 --> 00:40:00,490 per andare avanti delle cose, e quindi copiare la vecchia matrice nel nuovo, e poi 853 00:40:00,490 --> 00:40:01,680 libera il vecchio array. 854 00:40:01,680 --> 00:40:05,770 >> Ma che cosa è il tempo di esecuzione ora di quel processo? 855 00:40:05,770 --> 00:40:09,870 È grande O di n, perché la copiatura sta andando a costare alcune unità di 856 00:40:09,870 --> 00:40:13,480 tempo, quindi non così ideale se dobbiamo allocare un nuovo array, che sta 857 00:40:13,480 --> 00:40:15,610 di consumare il doppio memoria temporanea. 858 00:40:15,610 --> 00:40:16,660 Copiare vecchio in nuovo - 859 00:40:16,660 --> 00:40:18,800 Voglio dire, è solo un mal di testa, che è, di nuovo, perché abbiamo scritto 860 00:40:18,800 --> 00:40:19,920 GetString per voi. 861 00:40:19,920 --> 00:40:21,380 >> Così che cosa potremmo fare invece? 862 00:40:21,380 --> 00:40:25,000 Beh, e se la nostra struttura dati in realtà ha lacune in esso? 863 00:40:25,000 --> 00:40:30,790 Suppongo che mi rilasso il mio obiettivo di avere blocchi contigui di memoria, in cui 9 864 00:40:30,790 --> 00:40:34,500 Ubicato accanto a 17, che è accanto a 22, e così via. 865 00:40:34,500 --> 00:40:39,570 >> E supponiamo che 9 può essere qui in RAM, e 17 possono essere qui in RAM, 866 00:40:39,570 --> 00:40:40,990 e 22 possono essere qui in RAM. 867 00:40:40,990 --> 00:40:43,610 In altre parole, non ho bisogno di loro anche back to back più. 868 00:40:43,610 --> 00:40:47,850 Non mi resta che infilare in qualche modo un ago attraverso ciascuno di questi numeri, o ciascun 869 00:40:47,850 --> 00:40:51,010 di questi nodi, come chiameremo il rettangoli come li ho disegnati, a 870 00:40:51,010 --> 00:40:55,670 ricordare come raggiungere l'ultimo tale nodo dalla prima. 871 00:40:55,670 --> 00:40:59,940 >> Allora, qual è il costrutto di programmazione abbiamo visto poco tempo fa con la quale ho 872 00:40:59,940 --> 00:41:03,030 possono implementare quel filo, o disegnato qui, con la quale posso 873 00:41:03,030 --> 00:41:05,430 implementare quelle frecce? 874 00:41:05,430 --> 00:41:06,500 Puntatori così, giusto? 875 00:41:06,500 --> 00:41:09,560 Se non ho allocare solo un int, ma un nodo - e da 876 00:41:09,560 --> 00:41:10,810 nodo, mi riferisco solo contenitore. 877 00:41:10,810 --> 00:41:12,900 E visivamente, intendo un rettangolo. 878 00:41:12,900 --> 00:41:16,420 Così un nodo apparentemente bisogno per contenere due valori - 879 00:41:16,420 --> 00:41:21,490 l'int stessa, e quindi, come implica la metà inferiore del rettangolo, 880 00:41:21,490 --> 00:41:23,010 abbastanza spazio per un int. 881 00:41:23,010 --> 00:41:26,130 >> Quindi, solo pensando al futuro qui, quanto è grande questo nodo, questo 882 00:41:26,130 --> 00:41:27,170 contenitore in questione? 883 00:41:27,170 --> 00:41:29,250 Quanti byte per l'int? 884 00:41:29,250 --> 00:41:31,310 Presumibilmente 4, se è come al solito. 885 00:41:31,310 --> 00:41:33,270 E poi quanti byte per il puntatore? 886 00:41:33,270 --> 00:41:33,650 4. 887 00:41:33,650 --> 00:41:37,940 Quindi questo contenitore, o questo nodo, è andando ad essere una struttura di 8 byte. 888 00:41:37,940 --> 00:41:41,760 Oh, e questa è una felice coincidenza che abbiamo appena introdotto questo concetto di 889 00:41:41,760 --> 00:41:44,400 una struttura o di una struttura C. 890 00:41:44,400 --> 00:41:48,890 >> Quindi io sostengo che voglio fare un passo verso questo più sofisticato 891 00:41:48,890 --> 00:41:52,560 attuazione di una lista di numeri, un lista collegata di numeri, ho bisogno di fare un 892 00:41:52,560 --> 00:41:56,920 po 'di più il pensiero su fronte e dichiarare non solo un int, ma una struct 893 00:41:56,920 --> 00:41:58,620 che chiamerò convenzionalmente qui, nodo. 894 00:41:58,620 --> 00:42:01,630 Potremmo chiamare tutto ciò che vogliamo, ma nodo sta per essere tematico in un sacco 895 00:42:01,630 --> 00:42:03,560 delle cose iniziamo guardando ora. 896 00:42:03,560 --> 00:42:06,480 >> All'interno di tale nodo è un int n. 897 00:42:06,480 --> 00:42:09,350 E poi questa sintassi, un po ' strano a prima vista - 898 00:42:09,350 --> 00:42:12,960 struct nodo * prossimo. 899 00:42:12,960 --> 00:42:16,900 Beh pittoricamente, che cos'è? 900 00:42:16,900 --> 00:42:21,000 Questa è la metà inferiore della il rettangolo che abbiamo visto 901 00:42:21,000 --> 00:42:22,730 solo un momento fa. 902 00:42:22,730 --> 00:42:27,600 >> Ma perché dico struct nodo * rispetto a solo nodo *? 903 00:42:27,600 --> 00:42:31,370 Perché se tale puntatore punta a un altro nodo, è solo il 904 00:42:31,370 --> 00:42:32,760 indirizzo di un nodo. 905 00:42:32,760 --> 00:42:35,630 Questo è coerente con quello che abbiamo discusso puntatori finora. 906 00:42:35,630 --> 00:42:39,690 Ma perché, se io rivendico questa struttura è chiamato nodo, cosa devo dire struct 907 00:42:39,690 --> 00:42:42,660 nodo dentro qui? 908 00:42:42,660 --> 00:42:43,190 >> Esattamente. 909 00:42:43,190 --> 00:42:46,490 E 'una sorta di stupida realtà di C. Il typedef, per così dire, non ha 910 00:42:46,490 --> 00:42:47,220 ancora successo. 911 00:42:47,220 --> 00:42:48,510 C è super letterale. 912 00:42:48,510 --> 00:42:51,050 Si legge il codice in alto a basso, da sinistra a destra. 913 00:42:51,050 --> 00:42:54,930 E fino a quando colpisce che punto e virgola sulla linea di fondo, indovinate un po 'non 914 00:42:54,930 --> 00:42:57,590 esistere come un tipo di dati? 915 00:42:57,590 --> 00:42:59,060 Node, nodo unquote preventivo. 916 00:42:59,060 --> 00:43:03,050 >> Ma a causa del più prolisso dichiarazione che ho fatto in prima linea - 917 00:43:03,050 --> 00:43:05,340 nodo typedef struct - 918 00:43:05,340 --> 00:43:08,790 perché quello avvenne prima, prima della parentesi graffe, che è un po 'come 919 00:43:08,790 --> 00:43:11,800 pre-educare Clang che, si sapere che cosa, dammi una struct 920 00:43:11,800 --> 00:43:13,570 chiamato nodo struct. 921 00:43:13,570 --> 00:43:16,270 Francamente, non mi piacciono le cose di chiamata struct nodo struct nodo tutto 922 00:43:16,270 --> 00:43:17,090 tutto il mio codice. 923 00:43:17,090 --> 00:43:20,660 Ma io uso solo una volta, appena dentro, in modo che io possa effettivamente 924 00:43:20,660 --> 00:43:25,010 creare una sorta di riferimento circolare, non un puntatore a me stesso per sé, ma un 925 00:43:25,010 --> 00:43:29,400 puntatore ad un'altra di un'altra identica. 926 00:43:29,400 --> 00:43:32,330 >> Così si scopre che in una struttura dati come questo, ci sono alcune 927 00:43:32,330 --> 00:43:34,470 operazioni che potrebbero essere di interesse per noi. 928 00:43:34,470 --> 00:43:37,460 Potremmo voler inserire in una lista come questa. 929 00:43:37,460 --> 00:43:39,850 Potremmo voler cancellare da una lista come questa. 930 00:43:39,850 --> 00:43:43,490 Potremmo voler cercare la lista per un valore, o più in generale poligonale. 931 00:43:43,490 --> 00:43:46,410 E traverso è solo un modo elegante di dicendo inizio a sinistra e spostare tutti 932 00:43:46,410 --> 00:43:47,650 la strada a destra. 933 00:43:47,650 --> 00:43:52,640 >> E notate, anche con questo un po 'più sofisticata struttura di dati, lasciare 934 00:43:52,640 --> 00:43:56,510 Mi propongo di prendere in prestito alcuni dei le idee delle ultime due settimane e 935 00:43:56,510 --> 00:43:58,410 implementare una funzione denominata ricerca come questa. 936 00:43:58,410 --> 00:44:01,360 E 'intenzione di restituire true o falso, indicando, sì o 937 00:44:01,360 --> 00:44:03,390 no, n è nella lista. 938 00:44:03,390 --> 00:44:05,960 Il suo secondo argomento è un puntatore alla lista stessa, quindi un 939 00:44:05,960 --> 00:44:07,920 puntatore a un nodo. 940 00:44:07,920 --> 00:44:10,350 >> Tutto quello che sto per fare è quindi dichiarare una variabile temporanea. 941 00:44:10,350 --> 00:44:12,730 Lo chiameremo PTR per convenzione, per il puntatore. 942 00:44:12,730 --> 00:44:15,220 E io la assegno pari al inizio della lista. 943 00:44:15,220 --> 00:44:16,680 >> E ora notare il ciclo while. 944 00:44:16,680 --> 00:44:20,640 Finché puntatore non è uguale a nulla, vado a controllare. 945 00:44:20,640 --> 00:44:24,520 È freccia puntatore n pari a la n che è stato passato in? 946 00:44:24,520 --> 00:44:26,410 E aspetta un attimo - nuovo pezzo di sintassi. 947 00:44:26,410 --> 00:44:29,324 Qual è la freccia tutto ad un tratto? 948 00:44:29,324 --> 00:44:30,574 Sì? 949 00:44:30,574 --> 00:44:34,200 950 00:44:34,200 --> 00:44:34,810 >> Esattamente. 951 00:44:34,810 --> 00:44:38,860 Quindi, mentre a pochi minuti fa, abbiamo usato la notazione del punto per accedere a qualcosa 952 00:44:38,860 --> 00:44:43,080 all'interno di una struct, se la variabile si è non è la struct 953 00:44:43,080 --> 00:44:47,420 se stessa, ma un puntatore ad una struct, per fortuna, un pezzo di sintassi 954 00:44:47,420 --> 00:44:48,620 finalmente ha un senso intuitivo. 955 00:44:48,620 --> 00:44:52,360 La freccia significa seguire il puntatore, come le nostre frecce genere significa 956 00:44:52,360 --> 00:44:56,570 pittoricamente, e andare a campo dati all'interno. 957 00:44:56,570 --> 00:44:59,700 Così freccia è la stessa cosa di punto, ma lo si utilizza quando si dispone di un puntatore. 958 00:44:59,700 --> 00:45:05,270 >> Quindi, solo per ricapitolare poi, se il campo n all'interno della struct chiamata puntatore 959 00:45:05,270 --> 00:45:07,760 uguale uguale a n, restituisce vero. 960 00:45:07,760 --> 00:45:11,970 In caso contrario, questa linea qui - pointer uguale indicatore accanto. 961 00:45:11,970 --> 00:45:17,540 Così che cosa sta facendo questo, si noti, è che se io attualmente sto indicando la struct 962 00:45:17,540 --> 00:45:21,430 contenente 9, e 9 non è il numero Sto cercando - suppongo che sto cercando 963 00:45:21,430 --> 00:45:22,830 per n uguale a 50 - 964 00:45:22,830 --> 00:45:25,930 Ho intenzione di aggiornare il mio puntatore temporaneo a non puntare a questo nodo 965 00:45:25,930 --> 00:45:31,190 più, ma il puntatore a freccia accanto, che sta per lasciarmi qui. 966 00:45:31,190 --> 00:45:34,270 >> Ora, che ho capito è un turbine introduzione. 967 00:45:34,270 --> 00:45:37,380 Mercoledì scorso, avremo effettivamente fare questo con alcuni esseri umani e con alcuni più 968 00:45:37,380 --> 00:45:38,900 codice ad un ritmo più lento. 969 00:45:38,900 --> 00:45:42,990 Ma realizzare, ora stiamo facendo i nostri dati strutture più complesse in modo che il nostro 970 00:45:42,990 --> 00:45:45,780 algoritmi possono ottenere più efficiente, che sta per essere requisito per 971 00:45:45,780 --> 00:45:50,500 pset sei anni, quando si carica in, ancora una volta, quelli 150.000 parole, ma è necessario farlo 972 00:45:50,500 --> 00:45:55,650 in modo efficiente, e idealmente, creare un programma che gira per i nostri utenti non in 973 00:45:55,650 --> 00:46:00,460 lineare, non in n al quadrato, ma in tempo costante, in ideale. 974 00:46:00,460 --> 00:46:02,300 >> Ci vediamo il Mercoledì. 975 00:46:02,300 --> 00:46:07,240 >> SPEAKER: Al prossimo CS50, David dimentica il suo caso base. 976 00:46:07,240 --> 00:46:12,770 >> DAVID MALAN: Ed è così che si invia messaggi di testo con C. Che - 977 00:46:12,770 --> 00:46:14,020 >> [VARIE MESSAGGIO TESTO Suoni di notifica] 978 00:46:14,020 --> 00:46:19,734