1 00:00:00,000 --> 00:00:00,499 2 00:00:00,499 --> 00:00:11,261 [GIOCO MUSICA] 3 00:00:11,261 --> 00:00:12,640 >> DAVID J. MALAN: Va bene. 4 00:00:12,640 --> 00:00:14,525 Questo è CS50. 5 00:00:14,525 --> 00:00:16,009 E questo è l'inizio della settimana 5. 6 00:00:16,009 --> 00:00:18,050 E come avrete notato, parte del materiale 7 00:00:18,050 --> 00:00:21,050 è sempre un po 'di più complesso, il poco più denso. 8 00:00:21,050 --> 00:00:24,560 >> Ed è molto facile, soprattutto se sei stato l'abitudine per qualche tempo, 9 00:00:24,560 --> 00:00:28,600 per cercare di scribacchiare più tutto quello che facciamo, stiamo dicendo in classe. 10 00:00:28,600 --> 00:00:31,626 Ma si rendono conto, che non è forse l'approccio pedagogico ideale 11 00:00:31,626 --> 00:00:34,250 per imparare questo tipo di materiale, e più in generale di materiale. 12 00:00:34,250 --> 00:00:37,250 E così siamo lieti di annunciare proprio Gheng che di CS50 13 00:00:37,250 --> 00:00:39,780 Gong ha iniziato a preparare un insieme canonico di note 14 00:00:39,780 --> 00:00:42,100 per il corso, la speranza di cioè che, uno, questi 15 00:00:42,100 --> 00:00:44,030 servire non solo come riferimento e una risorsa 16 00:00:44,030 --> 00:00:47,410 per la revisione del materiale e andare indietro attraverso materiale che potrebbe avere 17 00:00:47,410 --> 00:00:51,230 si sfuggiti la prima volta intorno, ma anche in modo che le vostre teste possono essere più 18 00:00:51,230 --> 00:00:53,740 alto che verso il basso, quando arriva il momento di tenere una conferenza, 19 00:00:53,740 --> 00:00:56,960 in modo che si potrebbe coinvolgere più pensieroso, come 20 00:00:56,960 --> 00:00:59,170 al contrario di più Scribbly. 21 00:00:59,170 --> 00:01:02,510 >> Detto questo, ciò che troverete su il sito è tali documenti come questo. 22 00:01:02,510 --> 00:01:04,660 E notate, in alto a sinistra, c'è non solo un sommario, 23 00:01:04,660 --> 00:01:06,920 ma anche i codici di tempo che provoca il salto immediato si 24 00:01:06,920 --> 00:01:09,077 per la parte appropriata nel video online. 25 00:01:09,077 --> 00:01:11,410 E che cosa Chang qui ha fatto è, in sostanza, documentata 26 00:01:11,410 --> 00:01:13,340 quello che è successo in questo particolare lezione. 27 00:01:13,340 --> 00:01:16,370 E molte delle lezioni sono già online con questo URL. 28 00:01:16,370 --> 00:01:20,110 E noi continueremo a postare il resto di quelli per la fine di questa settimana, 29 00:01:20,110 --> 00:01:22,380 in modo da trarre vantaggio da tale risorsa. 30 00:01:22,380 --> 00:01:25,740 >> Quindi, senza ulteriori indugi, abbiamo iniziato a buccia indietro 31 00:01:25,740 --> 00:01:28,180 lo strato che è stata stringa per qualche tempo. 32 00:01:28,180 --> 00:01:30,670 E che cosa abbiamo detto una stringa in realtà è la settimana scorsa? 33 00:01:30,670 --> 00:01:31,720 34 00:01:31,720 --> 00:01:32,900 Stella Così char. 35 00:01:32,900 --> 00:01:34,900 E char stella, bene, che cosa ha fatto che realmente significa? 36 00:01:34,900 --> 00:01:37,150 Bene, tutto questo tempo, se abbiamo stato chiamare una funzione, 37 00:01:37,150 --> 00:01:40,450 come getString, e la memorizzazione il cosiddetto ritorno 38 00:01:40,450 --> 00:01:42,910 valore di getString in un variable-- si chiama 39 00:01:42,910 --> 00:01:47,721 Tipo di s string-- abbiamo scriviamo la riga di codice lassù sopra. 40 00:01:47,721 --> 00:01:49,970 Ed è solo quando vedo il mio scrittura a mano ingrandita qui 41 00:01:49,970 --> 00:01:51,930 mi rendo conto di quanto questo è atroce. 42 00:01:51,930 --> 00:01:54,180 >> Tuttavia, supponiamo che, sul lato destro 43 00:01:54,180 --> 00:01:57,070 è, tuttavia, un ragionevole rappresentazione di ciò che è 44 00:01:57,070 --> 00:01:58,880 sta succedendo tutto questo tempo con getString. 45 00:01:58,880 --> 00:02:00,380 getString, naturalmente, ottiene una stringa. 46 00:02:00,380 --> 00:02:01,691 Ma che cosa significa in realtà? 47 00:02:01,691 --> 00:02:04,190 Significa che ottiene un pezzo di memoria dal sistema operativo 48 00:02:04,190 --> 00:02:06,040 chiamando una funzione, chiamata malloc. 49 00:02:06,040 --> 00:02:07,390 Ma ne riparleremo più avanti. 50 00:02:07,390 --> 00:02:09,139 E poi popola che pezzo di memoria 51 00:02:09,139 --> 00:02:11,764 con le lettere l'utente ha digitato, seguito da, ovviamente, 52 00:02:11,764 --> 00:02:14,800 un carattere null, o backslash zero alla fine. 53 00:02:14,800 --> 00:02:18,280 >> Nel frattempo, sul lato sinistro di questa storia, tutto questo tempo, 54 00:02:18,280 --> 00:02:20,850 abbiamo dichiarazione di una variabile, come s. 55 00:02:20,850 --> 00:02:24,770 E quello variabile è ciò che ora inizierà chiamare un puntatore. 56 00:02:24,770 --> 00:02:29,190 Non è una scatola all'interno della quale abbiamo messo la corda, Daven, di per sé, 57 00:02:29,190 --> 00:02:32,550 ma abbiamo messo in quella piazza casella sulla sinistra che cosa esattamente? 58 00:02:32,550 --> 00:02:34,890 59 00:02:34,890 --> 00:02:35,390 Sì? 60 00:02:35,390 --> 00:02:37,118 >> PUBBLICO: L'indirizzo di dove si trova in memoria. 61 00:02:37,118 --> 00:02:38,118 >> DAVID J. MALAN: Esattamente. 62 00:02:38,118 --> 00:02:40,690 L'indirizzo di dove Daven si trova nella memoria. 63 00:02:40,690 --> 00:02:44,650 E non dove tutti Daven si trova, di per sé, ma in particolare l'indirizzo 64 00:02:44,650 --> 00:02:45,150 di che cosa? 65 00:02:45,150 --> 00:02:46,311 66 00:02:46,311 --> 00:02:46,810 Sì? 67 00:02:46,810 --> 00:02:47,460 >> PUBBLICO: Primo carattere. 68 00:02:47,460 --> 00:02:50,209 >> DAVID J. MALAN: Il primo carattere in Daven, che, in questo caso, 69 00:02:50,209 --> 00:02:53,820 Ho proposto è stato arbitrariamente e irrealisticamente 1, OX1, 70 00:02:53,820 --> 00:02:55,910 che significa semplicemente l' numero esadecimale di 1. 71 00:02:55,910 --> 00:02:57,993 Ma è probabilmente andando essere un numero molto più grande 72 00:02:57,993 --> 00:03:01,260 che potremmo trarre con un 0x come prefisso, 73 00:03:01,260 --> 00:03:02,806 rappresenta un carattere esadecimale. 74 00:03:02,806 --> 00:03:05,930 E perché non abbiamo bisogno di sapere dove il resto dei personaggi di Daven 75 00:03:05,930 --> 00:03:09,860 sono, a causa di ciò che il design semplice decisione che è stata fatta molti anni fa? 76 00:03:09,860 --> 00:03:10,548 Sì? 77 00:03:10,548 --> 00:03:11,651 >> PUBBLICO: Barra rovesciata 0. 78 00:03:11,651 --> 00:03:12,900 DAVID J. MALAN: Sì, esattamente. 79 00:03:12,900 --> 00:03:18,100 Il backslash 0 consente, sia pure in tempo lineare, per attraversare la stringa, 80 00:03:18,100 --> 00:03:20,400 a piedi da sinistra a destra, con un ciclo for, o un po ' 81 00:03:20,400 --> 00:03:22,608 loop, o qualcosa di simile che, e determinano, oh, qui 82 00:03:22,608 --> 00:03:24,751 è la fine di questa stringa particolare. 83 00:03:24,751 --> 00:03:27,000 Così, con solo l'indirizzo al l'inizio di una stringa, 84 00:03:27,000 --> 00:03:30,290 possiamo accedere alla totalità delle , perché tutto questo tempo, 85 00:03:30,290 --> 00:03:32,030 una stringa è appena stato una stella char. 86 00:03:32,030 --> 00:03:36,370 >> Quindi è certamente bene a continuare a utilizzare la biblioteca CS50 e questa astrazione, 87 00:03:36,370 --> 00:03:38,440 per così dire, ma ce la faremo cominciare a vedere esattamente 88 00:03:38,440 --> 00:03:41,230 quello che sta succedendo sotto tutto questo tempo. 89 00:03:41,230 --> 00:03:45,260 Così si può ricordare questo esempio, troppo, dall'ultima volta, confrontare 0, 90 00:03:45,260 --> 00:03:47,300 che in realtà non confrontare. 91 00:03:47,300 --> 00:03:49,070 Ma abbiamo cominciato a risolvere questo problema. 92 00:03:49,070 --> 00:03:52,020 >> Ma, come forse un aggiornamento, potrei interessare a qualcuno 93 00:03:52,020 --> 00:03:54,261 in un elefante rosa di oggi, fatta anche da Chang? 94 00:03:54,261 --> 00:03:55,760 Come su di te di fronte? [Incomprensibile]. 95 00:03:55,760 --> 00:03:56,660 Andiamo su. 96 00:03:56,660 --> 00:03:58,740 >> E nel frattempo, come si arriva, cerchiamo di 97 00:03:58,740 --> 00:04:01,670 prendere in considerazione solo per un attimo che cosa questo codice è stato effettivamente facendo. 98 00:04:01,670 --> 00:04:04,917 Si dichiara due variabili up top, s e t, e chiamando getString. 99 00:04:04,917 --> 00:04:08,250 Questo non è un programma molto facile da usare, perché non ti dice cosa fare. 100 00:04:08,250 --> 00:04:10,541 Ma facciamo solo supporre che siamo concentrandosi sulla parte succosa. 101 00:04:10,541 --> 00:04:14,470 E allora che facciamo, se s è uguale a è uguale a t, si dovrebbe dire printf, 102 00:04:14,470 --> 00:04:16,170 digitato la stessa cosa. 103 00:04:16,170 --> 00:04:16,670 Ciao. 104 00:04:16,670 --> 00:04:17,050 Come ti chiami? 105 00:04:17,050 --> 00:04:17,779 >> Janelle: Janelle. 106 00:04:17,779 --> 00:04:19,529 DAVID J. MALAN: Janelle, piacere di conoscerti. 107 00:04:19,529 --> 00:04:21,800 Così il vostro sfida mano per questo elefante 108 00:04:21,800 --> 00:04:25,230 è a noi disegnare prima un quadro di ciò che è essere rappresentati in quei primi due 109 00:04:25,230 --> 00:04:25,970 linee. 110 00:04:25,970 --> 00:04:28,139 Quindi s e t potrebbe essere rappresentata come sullo schermo? 111 00:04:28,139 --> 00:04:30,680 E si può solo disegnare con il dito su questa grande schermo. 112 00:04:30,680 --> 00:04:31,780 113 00:04:31,780 --> 00:04:34,510 >> Quindi ci sono due metà di ogni lato di questa equazione. 114 00:04:34,510 --> 00:04:37,760 Quindi c'è s a sinistra, e poi getString sulla destra. 115 00:04:37,760 --> 00:04:40,540 E poi c'è t sulla sinistra, e poi getString sulla destra. 116 00:04:40,540 --> 00:04:42,630 Così come potremmo cominciare un disegno che 117 00:04:42,630 --> 00:04:46,340 rappresenta ciò che sta succedendo qui in memoria, diresti? 118 00:04:46,340 --> 00:04:49,150 E lascia che ti permettono di spiegare quello che stai facendo, come si va. 119 00:04:49,150 --> 00:04:49,820 >> Janelle: OK. 120 00:04:49,820 --> 00:04:58,890 Beh, in primo luogo, sarebbe chiedere di ottenere la stringa di input. 121 00:04:58,890 --> 00:05:00,439 E sarebbe store-- oh, mi dispiace. 122 00:05:00,439 --> 00:05:01,230 DAVID J. MALAN: OK. 123 00:05:01,230 --> 00:05:01,730 Buona. 124 00:05:01,730 --> 00:05:03,330 E questo si chiama cosa? 125 00:05:03,330 --> 00:05:03,950 Oh, OK. 126 00:05:03,950 --> 00:05:04,450 Andare avanti. 127 00:05:04,450 --> 00:05:05,575 Non volevo interrompere. 128 00:05:05,575 --> 00:05:07,060 Janelle: Mi dispiace. 129 00:05:07,060 --> 00:05:14,237 Quindi sarebbe in ingresso in l'indirizzo non di-- sicuro. 130 00:05:14,237 --> 00:05:17,320 Non ricordo esattamente il numero, ma credo che stava iniziando con 0. 131 00:05:17,320 --> 00:05:18,420 >> DAVID J. MALAN: Questo è tutto giusto, perché ho fatto i numeri in su, 132 00:05:18,420 --> 00:05:19,650 quindi non c'è una risposta giusta. 133 00:05:19,650 --> 00:05:22,105 >> Janelle: A partire dal 0 arco. 134 00:05:22,105 --> 00:05:24,000 >> DAVID J. MALAN: OK, così elemento 0. 135 00:05:24,000 --> 00:05:24,765 Certo. 136 00:05:24,765 --> 00:05:28,295 >> Janelle: E allora se è stato come solo un due letter-- 137 00:05:28,295 --> 00:05:30,496 >> DAVID J. MALAN: OK, di nuovo voi. 138 00:05:30,496 --> 00:05:33,629 >> Janelle: Così elemento 0, e quindi elemento 1 o elemento 2. 139 00:05:33,629 --> 00:05:36,670 DAVID J. MALAN: E quale parte di l'immagine stai disegnando in questo momento? 140 00:05:36,670 --> 00:05:37,690 La chiamata a getString? 141 00:05:37,690 --> 00:05:38,830 O la dichiarazione di s? 142 00:05:38,830 --> 00:05:42,890 >> Janelle: La dichiarazione di s, credo. 143 00:05:42,890 --> 00:05:45,980 Oh, la getString, perché sarebbe essere immessi in ciascuna [? zona. ?] 144 00:05:45,980 --> 00:05:46,510 >> DAVID J. MALAN: Good. 145 00:05:46,510 --> 00:05:47,051 Esattamente. 146 00:05:47,051 --> 00:05:49,300 Anche se questo in modo efficace restituisce una matrice, richiamo, 147 00:05:49,300 --> 00:05:53,300 quando torniamo una stringa, possiamo indice in quella stringa con 01 e 2. 148 00:05:53,300 --> 00:05:56,180 Tecnicamente, questi sono probabilmente rappresentata da singoli indirizzi, 149 00:05:56,180 --> 00:05:57,100 ma va bene. 150 00:05:57,100 --> 00:06:00,170 >> Quindi supponiamo, se posso solo veloce inoltrare a dove avevamo interrotto 151 00:06:00,170 --> 00:06:04,320 ultima volta, se uno dei le corde erano g a b e, 152 00:06:04,320 --> 00:06:10,337 backslash 0, rappresentando in tal modo Gabe ingresso, come potremmo rappresentare s adesso? 153 00:06:10,337 --> 00:06:12,670 Se questa è la memoria che è stato restituito da getString? 154 00:06:12,670 --> 00:06:14,415 155 00:06:14,415 --> 00:06:17,610 >> Janelle: Sarebbe rappresentato da un arco? 156 00:06:17,610 --> 00:06:18,750 >> DAVID J. MALAN: da un arco? 157 00:06:18,750 --> 00:06:19,130 Beh, no. 158 00:06:19,130 --> 00:06:21,171 Diciamo solo che, pittoricamente, vorrei solo andare avanti 159 00:06:21,171 --> 00:06:25,710 e proporre che, se questo è s, questo è il valore di ritorno di getString. 160 00:06:25,710 --> 00:06:29,482 E che hai disegnato questo come 0, 1, 2, che è perfettamente ragionevole, perché noi 161 00:06:29,482 --> 00:06:30,940 in grado di indicizzare nella stringa, in quanto tale. 162 00:06:30,940 --> 00:06:33,340 Ma solo per essere coerenti con l'ultima volta, lasciami andare avanti 163 00:06:33,340 --> 00:06:37,310 e arbitrariamente proporre che questo è l'indirizzo 1, questo è l'indirizzo 2, 164 00:06:37,310 --> 00:06:39,597 questo è l'indirizzo 3, e così via. 165 00:06:39,597 --> 00:06:41,430 E così, giusto per essere super chiaro, che cosa sta succedendo 166 00:06:41,430 --> 00:06:44,580 andare in s come risultato di tale prima riga di codice, diresti? 167 00:06:44,580 --> 00:06:45,420 >> Janelle: Indirizzo 1? 168 00:06:45,420 --> 00:06:46,420 >> DAVID J. MALAN: Esattamente. 169 00:06:46,420 --> 00:06:47,190 So Indirizzo 0x1. 170 00:06:47,190 --> 00:06:48,220 171 00:06:48,220 --> 00:06:51,230 E intanto, lasciami andare avanti e duplicare gran parte di quello che hai fatto 172 00:06:51,230 --> 00:06:52,740 e aggiungere la mia t qui. 173 00:06:52,740 --> 00:06:56,340 Se dovessi digitare Gabe di nuovo, una seconda volta, 174 00:06:56,340 --> 00:07:01,530 quando richiesto con getString, dove, naturalmente, è Gabe sta per andare? 175 00:07:01,530 --> 00:07:02,280 Beh, presumably-- 176 00:07:02,280 --> 00:07:04,935 177 00:07:04,935 --> 00:07:05,975 >> Janelle: Ti piace qui? 178 00:07:05,975 --> 00:07:06,850 DAVID J. MALAN: Già. 179 00:07:06,850 --> 00:07:08,516 Janelle: O è anche nelle stesse scatole? 180 00:07:08,516 --> 00:07:11,940 DAVID J. MALAN: Fammi propongo, sì, esattamente, così in queste caselle aggiuntive. 181 00:07:11,940 --> 00:07:15,230 Ma ciò che è fondamentale ora è che, anche se ho disegnato questi abbastanza vicino 182 00:07:15,230 --> 00:07:18,650 together-- 0x1, questo è 0x2-- in realtà, 183 00:07:18,650 --> 00:07:25,750 questo ora potrebbe essere l'indirizzo 0x10, per esempio, e 0x11, 0x12 e, 184 00:07:25,750 --> 00:07:26,870 e così via. 185 00:07:26,870 --> 00:07:29,955 E così, se questo è il caso, quello che sta andando a finire qui in t? 186 00:07:29,955 --> 00:07:30,830 >> Janelle: 0x10? 187 00:07:30,830 --> 00:07:31,830 DAVID J. MALAN: Esattamente. 188 00:07:31,830 --> 00:07:33,180 Così 0x10. 189 00:07:33,180 --> 00:07:34,570 E così ora, ultima domanda. 190 00:07:34,570 --> 00:07:37,510 Lei ha, di gran lunga, ha dovuto lavorare il più difficile per un elefante finora. 191 00:07:37,510 --> 00:07:42,650 A questo punto, se mi tiro su il codice ancora una volta, quando lo faccio, in linea tre, 192 00:07:42,650 --> 00:07:47,630 se s è uguale uguale a t, che cosa sono in realtà confrontando che abbiamo disegnato qui? 193 00:07:47,630 --> 00:07:49,271 >> Janelle: I due indirizzi? 194 00:07:49,271 --> 00:07:50,270 DAVID J. MALAN: Esattamente. 195 00:07:50,270 --> 00:07:53,350 Così sto dicendo è s uguale uguale a t? 196 00:07:53,350 --> 00:07:56,210 In altre parole, è 1 uguale uguale a 10? 197 00:07:56,210 --> 00:07:59,710 E, naturalmente, il risposta ovvia è ora, no. 198 00:07:59,710 --> 00:08:02,920 E quindi questo programma è in ultima analisi andando a stampare ciò, diresti? 199 00:08:02,920 --> 00:08:05,770 200 00:08:05,770 --> 00:08:08,405 >> Janelle: Sarebbe, digitato la stessa cosa? 201 00:08:08,405 --> 00:08:11,446 >> DAVID J. MALAN: Quindi, se s è 1 e t è di 10? 202 00:08:11,446 --> 00:08:13,320 >> Janelle: È stato digitato cose diverse. 203 00:08:13,320 --> 00:08:13,570 >> DAVID J. MALAN: Esattamente. 204 00:08:13,570 --> 00:08:14,480 È stato digitato cose diverse. 205 00:08:14,480 --> 00:08:14,850 Bene. 206 00:08:14,850 --> 00:08:16,714 Quindi un applauso, se potessimo, qui. 207 00:08:16,714 --> 00:08:17,214 [Applausi] 208 00:08:17,214 --> 00:08:17,708 E 'stato doloroso. 209 00:08:17,708 --> 00:08:18,208 Lo so. 210 00:08:18,208 --> 00:08:19,684 Ben fatto. 211 00:08:19,684 --> 00:08:24,690 Così ora vediamo se non possiamo prendere in giro a parte ciò che la correzione era. 212 00:08:24,690 --> 00:08:28,040 E, naturalmente, quando abbiamo fissato questo-- che io oggi rappresento in green-- 213 00:08:28,040 --> 00:08:29,690 abbiamo fatto un paio di miglioramenti qui. 214 00:08:29,690 --> 00:08:32,409 In primo luogo, proprio come un sanity controllare, sto controllando prima 215 00:08:32,409 --> 00:08:35,110 se s è uguale a nulla e t è uguale a null. 216 00:08:35,110 --> 00:08:39,440 E tanto per essere chiari, quando potrebbe s o t essere null in codice come questo? 217 00:08:39,440 --> 00:08:43,140 218 00:08:43,140 --> 00:08:44,490 Quando potrebbero s o t essere nullo. 219 00:08:44,490 --> 00:08:44,990 Sì? 220 00:08:44,990 --> 00:08:45,990 >> PUBBLICO: [incomprensibile]. 221 00:08:45,990 --> 00:08:49,490 222 00:08:49,490 --> 00:08:50,510 >> DAVID J. MALAN: Esattamente. 223 00:08:50,510 --> 00:08:52,840 Se la stringa che l'utente digitato è troppo lungo 224 00:08:52,840 --> 00:08:56,140 per adattarsi in memoria, o qualche angolo strano caso del genere, 225 00:08:56,140 --> 00:08:59,010 getString, come vedremo, letteralmente oggi, nella sua documentazione, 226 00:08:59,010 --> 00:09:02,330 dice che restituirà null come un valore sentinella speciale, 227 00:09:02,330 --> 00:09:05,417 o semplicemente una sorta di simbolo speciale questo significa che qualcosa è andato storto. 228 00:09:05,417 --> 00:09:07,500 Quindi vogliamo controllare che, perché si scopre 229 00:09:07,500 --> 00:09:09,720 che null è un valore molto pericoloso. 230 00:09:09,720 --> 00:09:14,250 >> Spesso, se si tenta di fare qualcosa con nulla che coinvolge un function-- passandola 231 00:09:14,250 --> 00:09:17,470 come input, per instance-- quella funzione potrebbe molto in crash e, con esso, 232 00:09:17,470 --> 00:09:19,090 prendere giù tutto il programma. 233 00:09:19,090 --> 00:09:22,570 Quindi questa terza linea ora è solo una sanità mentale controllare, controllo degli errori, se si vuole. 234 00:09:22,570 --> 00:09:25,450 Questa è una buona abitudine ora ci si trova in ogni volta che 235 00:09:25,450 --> 00:09:28,050 tentare di utilizzare un valore che potrebbe, potenzialmente, essere nullo. 236 00:09:28,050 --> 00:09:32,000 >> Ora, nella quarta linea qui, "Se strcmp (s, t)," bene, 237 00:09:32,000 --> 00:09:33,180 cosa c'è che riferisce? 238 00:09:33,180 --> 00:09:36,750 Beh, abbiamo detto che questo era un modo molto succinto funzione denominata per il confronto tra stringhe. 239 00:09:36,750 --> 00:09:40,370 E il suo scopo nella vita è quello di confrontare il suo primo argomento contro di essa secondo, 240 00:09:40,370 --> 00:09:44,640 ma non in termini di indirizzi, come abbiamo fatto involontariamente un momento 241 00:09:44,640 --> 00:09:48,270 fa con il codice rosso, ma piuttosto per confrontare quei due 242 00:09:48,270 --> 00:09:53,210 stringhe nel umanamente intuitiva modo confrontando questo, contro questo, 243 00:09:53,210 --> 00:09:56,690 contro questo, contro questo, e poi fermarsi se e quando uno 244 00:09:56,690 --> 00:09:59,590 o entrambe le mie dita colpisce una barra rovesciata 0. 245 00:09:59,590 --> 00:10:04,530 Strcmp Così qualcuno anni fa, attuate di attuare per noi la funzionalità 246 00:10:04,530 --> 00:10:08,890 che speravamo avremmo ottenuto semplicemente confrontando due valori semplici. 247 00:10:08,890 --> 00:10:14,929 >> Ora, francamente, io continuo il disegno tutti questi diversi numeri. 248 00:10:14,929 --> 00:10:17,470 Ma la realtà è, sono stato rendendo questi su tutto il tempo. 249 00:10:17,470 --> 00:10:19,580 E così vorrei solo andare avanti e scarabocchiare questi fuori 250 00:10:19,580 --> 00:10:23,100 per fare un punto che, alla fine del giorno e andare avanti, 251 00:10:23,100 --> 00:10:30,160 non stiamo davvero andando a cura di quali affronta le cose sono in realtà 252 00:10:30,160 --> 00:10:30,790 in memoria. 253 00:10:30,790 --> 00:10:34,320 Quindi io non ho intenzione di disegnare questi tipi di numeri tanto più, 254 00:10:34,320 --> 00:10:38,970 Sono solo un abstract questa via un po 'più amichevole con solo le frecce. 255 00:10:38,970 --> 00:10:42,060 >> In altre parole, se s è un puntatore, bene, facciamo solo disegnare esso, letteralmente, 256 00:10:42,060 --> 00:10:45,430 come un puntatore, una freccia rivolta da se stessa a qualcos'altro, 257 00:10:45,430 --> 00:10:48,280 e non preoccuparsi troppo di più la minuzia di questi indirizzi 258 00:10:48,280 --> 00:10:49,910 che, ancora una volta, ho fatto lo stesso. 259 00:10:49,910 --> 00:10:52,680 Ma staremo a vedere quegli indirizzi, a volte, durante il debug del codice. 260 00:10:52,680 --> 00:10:56,450 >> Ora, nel frattempo, il programma qui correzioni, naturalmente, 261 00:10:56,450 --> 00:10:58,720 che problema confrontando queste due stringhe. 262 00:10:58,720 --> 00:11:00,260 Ma abbiamo incontrato un altro problema. 263 00:11:00,260 --> 00:11:03,180 Questo è stato dalla copia programmare l'ultima volta, 264 00:11:03,180 --> 00:11:06,880 in base al quale, stavo cercando di capitalizzare solo il primo carattere di una stringa. 265 00:11:06,880 --> 00:11:09,620 Ma quello che era il sintomo abbiamo visto l'ultima volta in cui 266 00:11:09,620 --> 00:11:14,150 un utente digitato un valore, come Gabe in minuscolo, per s, 267 00:11:14,150 --> 00:11:19,310 poi abbiamo assegnato s in t, come nella terza riga lì, 268 00:11:19,310 --> 00:11:22,900 e poi ho cercato di capitalizzare t Staffa 0? 269 00:11:22,900 --> 00:11:25,950 Qual è stato l'effetto di cambiando t Staffa 0 qui? 270 00:11:25,950 --> 00:11:27,150 >> PUBBLICO: E 'cambiato s. 271 00:11:27,150 --> 00:11:29,360 >> DAVID J. MALAN: Sì, Ho cambiato s, pure. 272 00:11:29,360 --> 00:11:31,050 Perché quello che stava realmente accadendo? 273 00:11:31,050 --> 00:11:34,130 Beh, fammi vedere se riesco a pulire questa immagine, come segue. 274 00:11:34,130 --> 00:11:41,390 >> Se s è, ancora una volta, la parola g, a, b, e, backslash, 0, e s 275 00:11:41,390 --> 00:11:44,084 continueremo disegno come una scatola qui, ma non di più indirizzi. 276 00:11:44,084 --> 00:11:45,250 Smettiamola di fare le cose. 277 00:11:45,250 --> 00:11:47,510 Diciamo solo tracciare un quadro di semplificare il mondo. 278 00:11:47,510 --> 00:11:52,640 >> Quando Dichiaro t con stringa t, che crea quel pezzo di memoria. 279 00:11:52,640 --> 00:11:55,850 Piazza capita di essere 32 bit nella maggior parte dei computer. 280 00:11:55,850 --> 00:11:59,530 Infatti, se hai mai sentito parlare di un computer con un'architettura a 32 bit, 281 00:11:59,530 --> 00:12:03,000 davvero fantasia-parlare, che appena significa che utilizza indirizzi a 32 bit. 282 00:12:03,000 --> 00:12:05,370 E come un tecnico a parte, Se vi siete mai chiesti 283 00:12:05,370 --> 00:12:09,630 perché i computer più vecchi, se effettivamente cercato di zuppa in su con un sacco di RAM, 284 00:12:09,630 --> 00:12:12,360 potrebbe avere solo un massimo di quattro gigabyte di RAM, 285 00:12:12,360 --> 00:12:14,860 bene è perché, letteralmente, il vostro vecchio computer poteva solo 286 00:12:14,860 --> 00:12:17,250 Numero alto come 4 miliardi, 4 miliardi di byte, 287 00:12:17,250 --> 00:12:20,590 perché stava usando 32 bit numeri per gli indirizzi. 288 00:12:20,590 --> 00:12:23,260 >> Ma in ogni caso, in questa esempio, di storia molto più semplice. 289 00:12:23,260 --> 00:12:27,250 t è solo un altro puntatore, o davvero una stella char, aka stringa. 290 00:12:27,250 --> 00:12:30,860 E come voglio aggiornare questa immagine ora con quella seconda riga di codice, 291 00:12:30,860 --> 00:12:31,950 dopo il punto, dot, dot? 292 00:12:31,950 --> 00:12:35,845 Quando faccio stringa t è uguale a s punto e virgola, Come cambia questa immagine? 293 00:12:35,845 --> 00:12:37,500 294 00:12:37,500 --> 00:12:38,000 Sì? 295 00:12:38,000 --> 00:12:38,916 >> PUBBLICO: [incomprensibile]. 296 00:12:38,916 --> 00:12:41,087 297 00:12:41,087 --> 00:12:42,020 >> DAVID J. MALAN: Già. 298 00:12:42,020 --> 00:12:42,600 Esattamente. 299 00:12:42,600 --> 00:12:45,620 Ho appena messo una freccia dalla t casella allo stesso indirizzo, 300 00:12:45,620 --> 00:12:47,570 la stessa prima lettera ha dato. 301 00:12:47,570 --> 00:12:50,850 Oppure tecnicamente, se questa ragazzo erano ancora in 0x1, 302 00:12:50,850 --> 00:12:53,052 E 'come se avessi 0x1 0x1 qui e qui. 303 00:12:53,052 --> 00:12:54,760 Ma ancora una volta, chi se ne frega riguardo gli indirizzi? 304 00:12:54,760 --> 00:12:56,345 E 'solo l'idea che conta ora. 305 00:12:56,345 --> 00:12:57,720 Quindi questo è quello che sta succedendo qui. 306 00:12:57,720 --> 00:13:02,690 Così, naturalmente, se si fa staffa t 0, che è la notazione di matrice, 307 00:13:02,690 --> 00:13:05,650 naturalmente-- e francamente, sembra come se ci fosse un array qui, 308 00:13:05,650 --> 00:13:07,340 ma ora c'è questa cosa strana. 309 00:13:07,340 --> 00:13:11,160 Sappiate che il linguaggio di programmazione, C, vi offre questa funzione, 310 00:13:11,160 --> 00:13:14,650 per cui, anche se t è un puntatore oppure s è un puntatore, 311 00:13:14,650 --> 00:13:18,050 è comunque possibile utilizzare quella familiare, confortevole parentesi quadra 312 00:13:18,050 --> 00:13:22,520 notazione per passare al primo elemento, o il secondo elemento, o qualsiasi elemento 313 00:13:22,520 --> 00:13:26,130 che tale puntatore punta a causa, presumibilmente, essa 314 00:13:26,130 --> 00:13:29,410 è, come in questo caso, punta a un certo array. 315 00:13:29,410 --> 00:13:30,340 >> Quindi, come possiamo risolvere questo problema? 316 00:13:30,340 --> 00:13:33,660 Francamente, questo è dove ha ottenuto un poco travolgente a prima vista. 317 00:13:33,660 --> 00:13:35,340 Ma qui è una versione nuova e migliorata. 318 00:13:35,340 --> 00:13:37,460 >> Quindi, prima, mi sto liberarsi della biblioteca CS50, 319 00:13:37,460 --> 00:13:41,170 solo per esporre che s è infatti una stella char, solo un sinonimo. 320 00:13:41,170 --> 00:13:43,540 E t è anche una stella char. 321 00:13:43,540 --> 00:13:48,290 Ma ciò che sta accadendo sul destra di tale linea 322 00:13:48,290 --> 00:13:49,970 dove t è assegnato un valore? 323 00:13:49,970 --> 00:13:50,790 >> Che cosa è malloc? 324 00:13:50,790 --> 00:13:51,630 Che cosa è strlen? 325 00:13:51,630 --> 00:13:52,547 Che cosa è sizeof (char)? 326 00:13:52,547 --> 00:13:54,380 Perché diavolo fa questo linea sguardo così complesso? 327 00:13:54,380 --> 00:13:55,713 Che cosa ci fa ad alto livello? 328 00:13:55,713 --> 00:13:56,482 329 00:13:56,482 --> 00:13:57,440 Che cosa è la memorizzazione in t? 330 00:13:57,440 --> 00:13:58,646 Sì? 331 00:13:58,646 --> 00:14:01,104 PUBBLICO: E 'assegnazione di un certa quantità di spazio di memoria. 332 00:14:01,104 --> 00:14:03,032 E 'per memorizzare, immagino, lettere [incomprensibile]. 333 00:14:03,032 --> 00:14:04,032 >> DAVID J. MALAN: Perfetto. 334 00:14:04,032 --> 00:14:04,540 Perfetto. 335 00:14:04,540 --> 00:14:06,650 E 'assegnazione di un certo quantità di spazio di memoria 336 00:14:06,650 --> 00:14:08,940 per memorizzare, presumibilmente, lettere futuri. 337 00:14:08,940 --> 00:14:11,310 E in particolare, malloc è quindi tornando cosa? 338 00:14:11,310 --> 00:14:13,114 339 00:14:13,114 --> 00:14:14,851 >> PUBBLICO: Restituzione del [incomprensibile]? 340 00:14:14,851 --> 00:14:15,850 DAVID J. MALAN: Esattamente. 341 00:14:15,850 --> 00:14:18,850 Tornando l'indirizzo di tale memoria, che è un modo elegante per dire, 342 00:14:18,850 --> 00:14:21,640 restituisce l'indirizzo del primo byte di quella memoria. 343 00:14:21,640 --> 00:14:25,460 L'onere è su di me per ricordare quanta memoria ho effettivamente 344 00:14:25,460 --> 00:14:27,140 assegnati o chiesto malloc per. 345 00:14:27,140 --> 00:14:28,384 >> Ora, quanto costa? 346 00:14:28,384 --> 00:14:30,550 Beh, anche se non c'è un sacco di parentesi qui, 347 00:14:30,550 --> 00:14:32,970 malloc vuole solo un singolo argomento. 348 00:14:32,970 --> 00:14:37,250 E sto specificando strlen di s, in modo da dare me tanti byte come ci sono in s, 349 00:14:37,250 --> 00:14:37,800 ma aggiungerne uno. 350 00:14:37,800 --> 00:14:38,300 Perché? 351 00:14:38,300 --> 00:14:39,030 352 00:14:39,030 --> 00:14:39,530 Sì? 353 00:14:39,530 --> 00:14:40,840 >> PUBBLICO: Il backslash 0. 354 00:14:40,840 --> 00:14:41,840 DAVID J. MALAN: Esattamente. 355 00:14:41,840 --> 00:14:43,423 Dobbiamo fare un po 'di pulizia. 356 00:14:43,423 --> 00:14:45,970 Quindi, perché c'è una barra rovesciata 0, faremmo meglio a ricordare che. 357 00:14:45,970 --> 00:14:47,310 Altrimenti, stiamo andando per creare una stringa che 358 00:14:47,310 --> 00:14:49,170 non ha che terminatore speciale. 359 00:14:49,170 --> 00:14:52,640 >> Nel frattempo, giusto per essere super anale, ho sizeof (char), 360 00:14:52,640 --> 00:14:55,730 nel caso in cui qualcuno corre il mio codice non sull'apparecchio CS50, 361 00:14:55,730 --> 00:14:58,220 ma forse un altro computer complessivamente cui caratteri 362 00:14:58,220 --> 00:15:01,470 sono un byte, per convenzione, ma due byte, o qualcosa di più grande di quello. 363 00:15:01,470 --> 00:15:04,490 E 'solo di essere super, Super contrari a errori. 364 00:15:04,490 --> 00:15:06,940 Anche se, in realtà, è molto probabilmente sarà un 1. 365 00:15:06,940 --> 00:15:11,490 >> Ora, intanto, vado avanti e copiare la stringa, staffa t i è uguale a staffa t s. 366 00:15:11,490 --> 00:15:14,962 E io rinviare alla settimana scorsa codice sorgente per vedere cosa sta succedendo. 367 00:15:14,962 --> 00:15:17,670 Ma il takeaway chiave, e la motivo per cui ho messo il codice ora in verde, 368 00:15:17,670 --> 00:15:22,520 è dovuto al fatto che molto ultima riga, t Staffa 0 è uguale toupper, 369 00:15:22,520 --> 00:15:25,230 ha l'effetto di Capitalizzazione che stringa? 370 00:15:25,230 --> 00:15:26,960 t e / o s? 371 00:15:26,960 --> 00:15:29,280 372 00:15:29,280 --> 00:15:30,580 L'ultima riga di codice. 373 00:15:30,580 --> 00:15:32,930 374 00:15:32,930 --> 00:15:35,560 >> Proprio t, perché ciò che è successo questa volta, 375 00:15:35,560 --> 00:15:41,500 se mi sciolgo un po 'che ultimo passo, ciò che è accaduto è, quando chiamo malloc, 376 00:15:41,500 --> 00:15:45,380 Ho in sostanza ottenere un pezzo di memoria che è lo stesso formato dell'originale, 377 00:15:45,380 --> 00:15:47,020 perché questo è il aritmetica che ho fatto. 378 00:15:47,020 --> 00:15:50,920 Sto memorizzazione in t l'indirizzo di quel pezzo di memoria. 379 00:15:50,920 --> 00:15:53,370 Anche se questo sembra bello e carina, bella e vuota, 380 00:15:53,370 --> 00:15:56,882 la realtà è che c'è, quello che faremo continuare ad invocare, i valori della spazzatura in qui. 381 00:15:56,882 --> 00:15:59,340 Quel pezzo di memoria potrebbe molto pure sono state utilizzate prima, 382 00:15:59,340 --> 00:16:00,940 pochi secondi, pochi minuti fa. 383 00:16:00,940 --> 00:16:04,410 Quindi ci potrebbe assolutamente essere numeri o lettere lì, solo per caso. 384 00:16:04,410 --> 00:16:08,580 Ma non sono valide, fino a quando ho Mi popolano questo pezzo di memoria 385 00:16:08,580 --> 00:16:12,510 con caratteri reali, come ho fare in quel ciclo for lì. 386 00:16:12,510 --> 00:16:13,180 Bene? 387 00:16:13,180 --> 00:16:16,180 >> Così ora, il culmine di questi tre esempi 388 00:16:16,180 --> 00:16:20,730 che sono stati apparentemente rotto l'ultima volta, questo esempio Swap, questa funzione 389 00:16:20,730 --> 00:16:23,670 lavorato in senso che cambiasse ae b. 390 00:16:23,670 --> 00:16:25,620 Ma non ha funzionato in quale altro senso? 391 00:16:25,620 --> 00:16:27,616 392 00:16:27,616 --> 00:16:28,614 Sì? 393 00:16:28,614 --> 00:16:29,612 >> PUBBLICO: [incomprensibile]. 394 00:16:29,612 --> 00:16:35,600 395 00:16:35,600 --> 00:16:36,700 >> DAVID J. MALAN: Esattamente. 396 00:16:36,700 --> 00:16:39,530 Se dovessi chiamare questa funzione da another-- per esempio, 397 00:16:39,530 --> 00:16:42,870 da una funzione come principale, dove Ho una variabile, x e y, come ho 398 00:16:42,870 --> 00:16:46,160 ha fatto la scorsa settimana, stesso codice, e passo in x e y 399 00:16:46,160 --> 00:16:49,860 di Swap, e quindi chiamare Swap-- questo, naturalmente, è la versione corretta 400 00:16:49,860 --> 00:16:52,220 è quello che stiamo per see-- non ha funzionato. 401 00:16:52,220 --> 00:16:53,770 Allora, qual è la soluzione? 402 00:16:53,770 --> 00:16:56,850 >> Bene, così giusto per essere chiaro, lasciami andare avanti 403 00:16:56,850 --> 00:17:05,450 e- dammi uno secondo qui, e vedere se posso mostrarvi l'ultimo, che 404 00:17:05,450 --> 00:17:12,464 sarà dentro-- vediamo se riesco a trovare questo vero e proprio OK fast--, [incomprensibile]. 405 00:17:12,464 --> 00:17:18,440 406 00:17:18,440 --> 00:17:19,240 OK, ci è. 407 00:17:19,240 --> 00:17:21,000 Quindi ignorare i comandi Sto solo battitura. 408 00:17:21,000 --> 00:17:23,780 Voglio che recuperare a all'ultimo minuto un esempio 409 00:17:23,780 --> 00:17:27,960 dall'ultima volta, che ora è chiamato non Swap. 410 00:17:27,960 --> 00:17:30,200 >> Quindi non Swap è dove avevamo lasciato l'ultima volta, 411 00:17:30,200 --> 00:17:32,930 per cui, ho inizializzato x 1 e y 2. 412 00:17:32,930 --> 00:17:35,840 Ho poi chiamo Swap, passando in 1 e 2. 413 00:17:35,840 --> 00:17:37,930 E allora questa funzione lavorato in un certo senso, 414 00:17:37,930 --> 00:17:40,750 ma non aveva permanente effettuare su xe y. 415 00:17:40,750 --> 00:17:45,430 Quindi la domanda è a portata di mano, come ora possiamo effettivamente risolvere questo problema? 416 00:17:45,430 --> 00:17:47,820 Qual è la soluzione a portata di mano? 417 00:17:47,820 --> 00:17:53,150 >> Beh, in swap.c, che è nuovo oggi, notare un paio di differenze. 418 00:17:53,150 --> 00:17:54,700 xey sono uguali. 419 00:17:54,700 --> 00:17:57,250 Ma ciò che è chiaramente diverso in linea 25? 420 00:17:57,250 --> 00:17:58,880 421 00:17:58,880 --> 00:18:01,715 Cosa c'è di nuovo lì, se vi ricordate quello che sembrava un secondo fa? 422 00:18:01,715 --> 00:18:02,565 >> PUBBLICO: [incomprensibile]. 423 00:18:02,565 --> 00:18:03,440 >> DAVID J. MALAN: Già. 424 00:18:03,440 --> 00:18:06,680 Così i ampersands sono un nuovo pezzo di sintassi non solo in questo programma, 425 00:18:06,680 --> 00:18:08,560 ma anche più in generale in CS50. 426 00:18:08,560 --> 00:18:10,680 Fino ad oggi, non credo abbiamo visto esempi 427 00:18:10,680 --> 00:18:14,070 o realmente parlato di loro in qualsiasi particolare, diverso, forse, preventivamente 428 00:18:14,070 --> 00:18:16,467 in sezione, una e commerciale come questo. 429 00:18:16,467 --> 00:18:19,300 Beh, si scopre e commerciale è una degli ultimi pezzi della nuova sintassi 430 00:18:19,300 --> 00:18:20,174 stiamo andando a imparare. 431 00:18:20,174 --> 00:18:23,500 Tutto ciò significa l' indirizzo di una variabile. 432 00:18:23,500 --> 00:18:25,070 A quale indirizzo non x vivere? 433 00:18:25,070 --> 00:18:26,510 Ma che cosa vuol indirizzo y vive? 434 00:18:26,510 --> 00:18:28,700 Perché se il problema fondamentale prima 435 00:18:28,700 --> 00:18:32,970 era che x e y si ripercuotono come copie, ciò che realmente vogliamo fare 436 00:18:32,970 --> 00:18:38,780 è fornire Swap con come un tesoro mappa che conduce dove xey effettivamente 437 00:18:38,780 --> 00:18:41,910 sono in RAM, in modo che Swap può seguire quella mappa 438 00:18:41,910 --> 00:18:47,760 e andare ovunque x o y segna il punto e cambiare i valori effettivi 1 e 2 439 00:18:47,760 --> 00:18:48,270 Là. 440 00:18:48,270 --> 00:18:50,710 >> Quindi Swap bisogno di cambiare un po 'troppo. 441 00:18:50,710 --> 00:18:53,760 E a prima vista, questo potrebbe sembrare un po 'simile a char stella. 442 00:18:53,760 --> 00:18:54,850 E in effetti lo è. 443 00:18:54,850 --> 00:18:59,635 Quindi, a è un puntatore a quale tipo di dati, sulla base di questa porzione evidenziata? 444 00:18:59,635 --> 00:19:00,810 445 00:19:00,810 --> 00:19:01,620 Quindi è un int. 446 00:19:01,620 --> 00:19:04,880 >> Quindi una non è più un int, è l'indirizzo di un int. 447 00:19:04,880 --> 00:19:07,910 E allo stesso modo, b sta ora per essere l'indirizzo di un int. 448 00:19:07,910 --> 00:19:12,470 Così, quando ho adesso chiamo Swap da Main, Non ho intenzione di dare Swap 1 e 2. 449 00:19:12,470 --> 00:19:15,540 Ho intenzione di dare come Ox-qualcosa e Ox-qualcosa, 450 00:19:15,540 --> 00:19:19,820 due indirizzi che porteranno Swap nelle loro posizioni attuali 451 00:19:19,820 --> 00:19:21,310 nella memoria del mio computer. 452 00:19:21,310 --> 00:19:25,580 >> Così ora, la mia implementazione rimanente ha bisogno di cambiare un po '. 453 00:19:25,580 --> 00:19:28,650 Che cosa è ovviamente diverso ora in queste tre righe di codice? 454 00:19:28,650 --> 00:19:31,350 Ci sono questi maledetti stelle tutti sul posto, tutto a posto? 455 00:19:31,350 --> 00:19:33,014 Così che cosa sta succedendo qui? 456 00:19:33,014 --> 00:19:33,514 Sì? 457 00:19:33,514 --> 00:19:35,055 >> PUBBLICO: E 'ovviamente [incomprensibile]. 458 00:19:35,055 --> 00:19:36,832 459 00:19:36,832 --> 00:19:37,990 >> DAVID J. MALAN: Esattamente. 460 00:19:37,990 --> 00:19:41,560 Quindi in questo context-- e questo non era la decisione migliore progettazione, è vero, 461 00:19:41,560 --> 00:19:42,530 anni fa. 462 00:19:42,530 --> 00:19:45,110 In questo contesto, dove hai solo una stella, 463 00:19:45,110 --> 00:19:48,240 e non si dispone di un tipo di dati, come int, subito a sinistra, 464 00:19:48,240 --> 00:19:53,146 invece si dispone di un segno di uguale, chiaramente, in questo contesto, quando si dice una stella, 465 00:19:53,146 --> 00:19:56,980 questo significa andare al indirizzo che è in una. 466 00:19:56,980 --> 00:19:58,870 Segui la mappa del tesoro, per così dire. 467 00:19:58,870 --> 00:20:01,720 >> E intanto, in linea 37, significa la stessa cosa. 468 00:20:01,720 --> 00:20:05,460 Vai all'indirizzo di una, e mettere quello che c'è? 469 00:20:05,460 --> 00:20:09,520 Qualunque sia al posizione che b specifica. 470 00:20:09,520 --> 00:20:10,980 In altre parole, andare a b. 471 00:20:10,980 --> 00:20:12,130 Prendi quel valore. 472 00:20:12,130 --> 00:20:15,620 Vai a una e, per la parità di firmare, l'operatore di assegnazione, 473 00:20:15,620 --> 00:20:17,010 mettere quel valore lì. 474 00:20:17,010 --> 00:20:19,272 >> Allo stesso modo, int temp è solo un int. 475 00:20:19,272 --> 00:20:20,730 Nulla deve cambiare di temperatura. 476 00:20:20,730 --> 00:20:24,810 E 'solo un bicchiere di riserva da Annenberg per un po 'di latte o succo d'arancia. 477 00:20:24,810 --> 00:20:27,630 Ma ho bisogno di dire, andare a b. 478 00:20:27,630 --> 00:20:31,449 Vai a tale destinazione e mettere il valore di temperatura lì. 479 00:20:31,449 --> 00:20:32,490 Così che cosa sta succedendo allora? 480 00:20:32,490 --> 00:20:36,540 Quando ho effettivamente Inverti chiamata questa volta, se questo primo cassetto qui rappresenta il principale, 481 00:20:36,540 --> 00:20:42,270 questo secondo vassoio rappresenta Swap, quando Passo ampersand x e y e commerciale 482 00:20:42,270 --> 00:20:47,150 da principale a Swap, tanto per essere chiari, che cosa è questo stack telaio di ricezione? 483 00:20:47,150 --> 00:20:48,700 484 00:20:48,700 --> 00:20:49,200 Sì? 485 00:20:49,200 --> 00:20:50,180 >> PUBBLICO: [incomprensibile]. 486 00:20:50,180 --> 00:20:51,180 DAVID J. MALAN: Esattamente. 487 00:20:51,180 --> 00:20:53,129 L'indirizzo della x e l'indirizzo di y. 488 00:20:53,129 --> 00:20:55,170 E si può pensare di questi come indirizzi postali. 489 00:20:55,170 --> 00:20:58,772 33 Oxford Street e 35 Oxford Street, e si 490 00:20:58,772 --> 00:21:01,230 desidera spostare i due edifici che sono in quei luoghi. 491 00:21:01,230 --> 00:21:04,680 >> E 'una sorta di un'idea ridicola, ma è tutto quello che noi intendiamo per indirizzo. 492 00:21:04,680 --> 00:21:07,000 Dove nel mondo può a trovare quei due interi? 493 00:21:07,000 --> 00:21:09,470 Dove nel mondo si può trovare quei due edifici? 494 00:21:09,470 --> 00:21:15,170 Quindi, se finalmente, dopo tutto questo tempo mi andare in codice sorgente di oggi e compilare 495 00:21:15,170 --> 00:21:22,110 Swap ed eseguire ./swap, infine, per il prima volta che facciamo in realtà vediamo che 496 00:21:22,110 --> 00:21:25,330 i miei valori sono infatti stato scambiato con successo. 497 00:21:25,330 --> 00:21:30,860 E ora, possiamo anche prendere nota di questo, per esempio, gdb. 498 00:21:30,860 --> 00:21:32,740 >> Quindi lasciami andare nello stesso file. 499 00:21:32,740 --> 00:21:35,010 Lasciami andare avanti ed eseguire gdb di ./swap. 500 00:21:35,010 --> 00:21:36,590 501 00:21:36,590 --> 00:21:40,547 E ora, in Swap, ho intenzione di andare avanti e impostare un punto di interruzione nel principale. 502 00:21:40,547 --> 00:21:42,630 E ora ho intenzione di andare avanti ed eseguire il programma. 503 00:21:42,630 --> 00:21:45,810 E ora vediamo il mio codice pausa a quella linea. 504 00:21:45,810 --> 00:21:48,330 >> Se vado avanti e stampa x, che cosa dovrei vedere qui? 505 00:21:48,330 --> 00:21:49,314 506 00:21:49,314 --> 00:21:49,980 E 'una domanda. 507 00:21:49,980 --> 00:21:51,030 508 00:21:51,030 --> 00:21:51,530 Dire di nuovo? 509 00:21:51,530 --> 00:21:52,295 >> PUBBLICO: [incomprensibile]. 510 00:21:52,295 --> 00:21:53,910 >> DAVID J. MALAN: Così numeri casuali, forse. 511 00:21:53,910 --> 00:21:56,010 Forse sono fortunato, ed è bello e semplice, come 0. 512 00:21:56,010 --> 00:21:57,230 Ma forse è un po 'di numeri casuali. 513 00:21:57,230 --> 00:21:58,090 In questo caso, ho avuto fortuna. 514 00:21:58,090 --> 00:21:59,030 Succede solo per essere 0. 515 00:21:59,030 --> 00:22:00,780 Ma è davvero fortuna, perché non fino a quando ho 516 00:22:00,780 --> 00:22:06,280 tipo successivo e poi stampare x ha che riga di codice, linea 19, stato giustiziato. 517 00:22:06,280 --> 00:22:10,942 >> Nel frattempo, se digito il prossimo di nuovo, e ora stampare y, vado a vedere 2. 518 00:22:10,942 --> 00:22:13,900 Ora, se digito il prossimo, sta andando a ottenere un po 'di confusione, perché ora, 519 00:22:13,900 --> 00:22:17,250 printf sta per apparire su lo schermo, come ha fatto. x è 1. 520 00:22:17,250 --> 00:22:18,606 >> Facciamolo di nuovo. 521 00:22:18,606 --> 00:22:20,480 Ed ora, ecco dove le cose si fanno interessanti. 522 00:22:20,480 --> 00:22:21,580 523 00:22:21,580 --> 00:22:26,580 Prima che io chiamo Swap o addirittura passo in esso, diamo un po 'un'occhiata. 524 00:22:26,580 --> 00:22:28,980 x è, ancora una volta, 1. 525 00:22:28,980 --> 00:22:33,240 Y è, naturalmente, sanità mentale rapido controllare, 2, quindi non è difficile là. 526 00:22:33,240 --> 00:22:35,740 Ma ciò che è commerciale x? 527 00:22:35,740 --> 00:22:36,760 528 00:22:36,760 --> 00:22:39,350 Risposta, è una specie di funky cerchi. 529 00:22:39,350 --> 00:22:43,500 Ma l'int stella tra parentesi è solo modo di gdp di dire questo è un indirizzo. 530 00:22:43,500 --> 00:22:48,290 Non è un int, è un puntatore ad un int, o altrimenti conosciuto come un indirizzo. 531 00:22:48,290 --> 00:22:49,742 >> Che cosa è questa cosa pazzesca? 532 00:22:49,742 --> 00:22:51,825 Non abbiamo mai visto qualcosa abbastanza come prima. 533 00:22:51,825 --> 00:22:53,650 534 00:22:53,650 --> 00:22:58,120 Quindi questo è l'indirizzo nel mio computer di ricordo di dove x si trova a vivere. 535 00:22:58,120 --> 00:22:59,040 E 'Ox-qualcosa. 536 00:22:59,040 --> 00:23:01,290 E questo è, francamente, perché Ho iniziato a disegnare frecce, 537 00:23:01,290 --> 00:23:03,340 invece di numeri, perché a chi importa veramente 538 00:23:03,340 --> 00:23:06,890 che il vostro int è in un particolare indirizzo che è così grande. 539 00:23:06,890 --> 00:23:12,160 Ma bffff0c4, questi sono tutti anzi cifre esadecimali, 540 00:23:12,160 --> 00:23:13,720 che sono da 0 a f. 541 00:23:13,720 --> 00:23:16,590 >> Quindi non stiamo andando a soffermarsi troppo a lungo su ciò che quelle cose sono. 542 00:23:16,590 --> 00:23:19,400 Ma se stampo fuori y, Naturalmente, vedo 2. 543 00:23:19,400 --> 00:23:22,440 Ma ampersand y, vedo questo indirizzo. 544 00:23:22,440 --> 00:23:26,527 E notate, per i curiosi, quanto distanti siano x e y? 545 00:23:26,527 --> 00:23:27,985 È possibile ignorare la maggior parte dell'indirizzo. 546 00:23:27,985 --> 00:23:29,330 547 00:23:29,330 --> 00:23:29,920 Quattro byte. 548 00:23:29,920 --> 00:23:33,510 E questo è coerente con la nostra precedenza affermare che quanto è grande un int? 549 00:23:33,510 --> 00:23:34,130 Quattro byte. 550 00:23:34,130 --> 00:23:37,420 Quindi sembra fodera del tutto up bene, come si potrebbe sperare, in memoria. 551 00:23:37,420 --> 00:23:40,010 >> Così ora, diciamo solo avanti veloce alla fine di questa storia. 552 00:23:40,010 --> 00:23:43,290 Andiamo avanti e tipo di passo, immergersi nella funzione Swap. 553 00:23:43,290 --> 00:23:46,880 Ora notate, se si digita una, è identico all'indirizzo di x. 554 00:23:46,880 --> 00:23:52,130 Se digito b, è identico all'indirizzo di y. 555 00:23:52,130 --> 00:23:57,020 Quindi cosa devo vedere se ho dire, andare all'indirizzo un? 556 00:23:57,020 --> 00:23:58,120 Quindi, stampare una stella. 557 00:23:58,120 --> 00:24:00,130 Così stella significa andare lì, in questo contesto. 558 00:24:00,130 --> 00:24:02,730 Ampersand indica qual è l'indirizzo. 559 00:24:02,730 --> 00:24:05,000 Quindi protagonista un mezzo 1. 560 00:24:05,000 --> 00:24:09,590 E stampa stella b mi dà 2. 561 00:24:09,590 --> 00:24:15,750 >> E lasciatemi presumo, per il momento, che almeno il codice che 562 00:24:15,750 --> 00:24:18,950 procede ad eseguire ora può essere motivata attraverso in quel modo. 563 00:24:18,950 --> 00:24:21,150 Ma ci rivisitare questa idea in poco tempo. 564 00:24:21,150 --> 00:24:23,850 Quindi questa versione di Swap ora è corretta e consente 565 00:24:23,850 --> 00:24:26,650 ci scambiamo questo particolare tipo di dati. 566 00:24:26,650 --> 00:24:29,120 >> Quindi, tutte le domande allora Swap? 567 00:24:29,120 --> 00:24:29,890 Su stella? 568 00:24:29,890 --> 00:24:30,690 Su indirizzo? 569 00:24:30,690 --> 00:24:33,270 E vedrai, con problema set 4, sorta di, 570 00:24:33,270 --> 00:24:37,310 ma problema set 5, sicuramente, come queste le cose sono utili e ottenere molto di più 571 00:24:37,310 --> 00:24:39,584 bene con loro, come risultato. 572 00:24:39,584 --> 00:24:40,430 Niente di niente? 573 00:24:40,430 --> 00:24:40,930 Bene. 574 00:24:40,930 --> 00:24:44,350 Quindi malloc è, ancora una volta, questa funzione che assegna solo la memoria, la memoria 575 00:24:44,350 --> 00:24:45,330 allocazione. 576 00:24:45,330 --> 00:24:47,024 E perché è utile? 577 00:24:47,024 --> 00:24:48,940 Ebbene, tutto questo tempo, hai utilizzato malloc. 578 00:24:48,940 --> 00:24:52,230 Se si considera ora come getString lavori, presumibilmente, è 579 00:24:52,230 --> 00:24:56,140 stato chiedere a qualcuno per un pezzo di memoria, in qualsiasi momento l'utente digita una stringa 580 00:24:56,140 --> 00:24:59,040 in, perché certamente non sapeva, come il personale CS50, 581 00:24:59,040 --> 00:25:02,710 quanto grande quelle corde che gli esseri umani stanno per digitare potrebbe essere. 582 00:25:02,710 --> 00:25:07,910 >> Quindi cerchiamo di, per la prima volta, iniziano a Staccare come funziona la biblioteca CS50, 583 00:25:07,910 --> 00:25:10,990 mediante una coppia di esempi che ci porterà lì. 584 00:25:10,990 --> 00:25:15,300 Quindi, se apro gedit e di aprire scanf 0, 585 00:25:15,300 --> 00:25:17,055 stiamo andando a vedere il codice seguente. 586 00:25:17,055 --> 00:25:18,720 587 00:25:18,720 --> 00:25:23,530 Scanf 0, disponibile sul sito web di oggi, ha relativamente poche righe di codice 588 00:25:23,530 --> 00:25:25,351 qui, da 14 a 20. 589 00:25:25,351 --> 00:25:26,600 E vediamo che cosa sta facendo. 590 00:25:26,600 --> 00:25:28,920 Si dichiara un int, chiamato x. 591 00:25:28,920 --> 00:25:30,850 Si dice qualcosa del tipo, numero di favore. 592 00:25:30,850 --> 00:25:33,940 E ora si dice, scanf% i, & x. 593 00:25:33,940 --> 00:25:35,620 Quindi c'è un sacco di roba nuova c'è. 594 00:25:35,620 --> 00:25:38,420 >> Ma scanf, è possibile tipo di pensare come l'opposto di printf. 595 00:25:38,420 --> 00:25:40,090 printf, naturalmente, stampe alla schermata. 596 00:25:40,090 --> 00:25:44,410 scanf sorta di scansioni da parte dell'utente del tastiera qualcosa che lui o lei ha digitato. 597 00:25:44,410 --> 00:25:46,550 >> % I è proprio come printf. 598 00:25:46,550 --> 00:25:49,410 Ciò significa che si aspettano l' all'utente di digitare un int. 599 00:25:49,410 --> 00:25:52,820 E ora, perché pensi che io potrebbe essere passare scanf & x? 600 00:25:52,820 --> 00:25:54,030 601 00:25:54,030 --> 00:25:57,770 Se lo scopo della vita di scanf è quello di ottenere qualcosa da parte dell'utente, 602 00:25:57,770 --> 00:26:02,480 qual è il significato di passarlo, & x, adesso? 603 00:26:02,480 --> 00:26:02,980 Sì? 604 00:26:02,980 --> 00:26:03,896 >> PUBBLICO: [incomprensibile]. 605 00:26:03,896 --> 00:26:05,540 606 00:26:05,540 --> 00:26:06,540 DAVID J. MALAN: Esattamente. 607 00:26:06,540 --> 00:26:12,900 Qualunque cosa io, l'umano, digitare, il mio ingresso sta per essere salvato in quella posizione. 608 00:26:12,900 --> 00:26:17,660 Non è sufficiente ricordare, ad appena passare x, perché abbiamo visto già, 609 00:26:17,660 --> 00:26:21,630 ogni volta che si passa solo una variabile grezza, come un int, a qualche altra funzione, 610 00:26:21,630 --> 00:26:25,640 certo, si può cambiare la situazione variabile, ma non in modo permanente. 611 00:26:25,640 --> 00:26:27,360 Non può avere un effetto sulla principale. 612 00:26:27,360 --> 00:26:29,420 Si può cambiare solo la propria copia locale. 613 00:26:29,420 --> 00:26:32,560 Ma se, invece, non lo fai dammi l'int reale, 614 00:26:32,560 --> 00:26:36,640 ma tu mi dai le indicazioni per che int, ora, essendo scanf, 615 00:26:36,640 --> 00:26:41,050 sicuramente, posso seguire che affrontare e mettere un numero non 616 00:26:41,050 --> 00:26:43,280 in modo da avere accesso ad esso pure. 617 00:26:43,280 --> 00:26:45,120 >> Così, quando ho eseguito questo programma, vediamo. 618 00:26:45,120 --> 00:26:49,660 Fai scanf 0 dot barra, scanf 0. 619 00:26:49,660 --> 00:26:54,030 E se io ora digito un numero come 50, grazie per la 50. 620 00:26:54,030 --> 00:26:58,150 Se ora digito un numero come negativo 1, per il negativo 1. 621 00:26:58,150 --> 00:27:04,200 Ora digitare un numero come 1,5, hm. 622 00:27:04,200 --> 00:27:06,030 Perché il mio programma mi ignora? 623 00:27:06,030 --> 00:27:07,300 624 00:27:07,300 --> 00:27:09,880 Beh, semplicemente perché, ho detto ad aspettarsi solo un int. 625 00:27:09,880 --> 00:27:10,380 Bene. 626 00:27:10,380 --> 00:27:11,630 Ecco, questo è una versione di questo. 627 00:27:11,630 --> 00:27:16,600 Prendiamo le cose su una tacca e propone che questo non è buono. 628 00:27:16,600 --> 00:27:20,530 E qui si trova un esempio molto semplice di come possiamo iniziare la scrittura di codice 629 00:27:20,530 --> 00:27:24,450 che altre persone possano sfruttare o compromettere facendo cose cattive. 630 00:27:24,450 --> 00:27:28,336 Così la linea 16, così simili in spirito di prima, 631 00:27:28,336 --> 00:27:29,960 ma io non sto dichiarando che int questa volta. 632 00:27:29,960 --> 00:27:32,970 Sto dichiarandola stelle char, aka stringa. 633 00:27:32,970 --> 00:27:35,190 >> Ma che cosa significa in realtà? 634 00:27:35,190 --> 00:27:38,790 Quindi, se non si specifica un address-- e Sto chiamando arbitrariamente, tampone, 635 00:27:38,790 --> 00:27:43,370 ma ho potuto chiamo s, per essere simple-- e poi faccio questo, spiegare a me, 636 00:27:43,370 --> 00:27:48,630 se si potesse, sulla base della precedente logica, ciò che è scanf facendo in linea 18, 637 00:27:48,630 --> 00:27:55,000 se il passaggio% s e tampone, che è un indirizzo? 638 00:27:55,000 --> 00:27:58,210 Che cosa è scanf, se si applica il esatto stessa logica la versione 0, 639 00:27:58,210 --> 00:28:00,640 intenzione di provare a fare qui, quando l'utente digita qualcosa? 640 00:28:00,640 --> 00:28:02,630 641 00:28:02,630 --> 00:28:03,409 Sì? 642 00:28:03,409 --> 00:28:04,407 >> PUBBLICO: [incomprensibile]. 643 00:28:04,407 --> 00:28:07,401 644 00:28:07,401 --> 00:28:08,890 >> DAVID J. MALAN: Esattamente. 645 00:28:08,890 --> 00:28:11,577 Scanf, dalla logica precedente, sta andando a prendere la stringa 646 00:28:11,577 --> 00:28:13,410 che la digitato umano dentro-- ora è una stringa, 647 00:28:13,410 --> 00:28:15,790 non è un numero, presumibilmente, se lui o lei cooperates-- 648 00:28:15,790 --> 00:28:19,310 e sta andando a cercare di mettere che stringa in memoria a qualsiasi indirizzo 649 00:28:19,310 --> 00:28:20,340 tampone specifica. 650 00:28:20,340 --> 00:28:23,870 E questo è grande, perché tampone è infatti destinato ad essere un indirizzo. 651 00:28:23,870 --> 00:28:30,470 >> Ma io sostengo questo programma è bacato in un modo molto serio, perché quello che è il valore 652 00:28:30,470 --> 00:28:31,330 tampone di default? 653 00:28:31,330 --> 00:28:33,380 654 00:28:33,380 --> 00:28:34,790 Che cosa ho inizializzato in? 655 00:28:34,790 --> 00:28:35,770 Che pezzo di memoria? 656 00:28:35,770 --> 00:28:37,480 657 00:28:37,480 --> 00:28:38,620 Io non ho, giusto? 658 00:28:38,620 --> 00:28:42,265 >> Quindi, anche se ho assegnato una char stella che non si chiama s, 659 00:28:42,265 --> 00:28:48,030 è invece chiamato, buffer-- così cerchiamo di disegnare il nome della variabile 660 00:28:48,030 --> 00:28:53,380 ora come buffer-- se non ho chiamato getString o malloc qui, 661 00:28:53,380 --> 00:28:56,030 che significa effettivamente che buffer è solo un valore spazzatura. 662 00:28:56,030 --> 00:28:57,030 >> Ora, che cosa significa? 663 00:28:57,030 --> 00:29:00,220 Significa che ho detto scanf aspettarsi una stringa dall'utente. 664 00:29:00,220 --> 00:29:01,300 E sai una cosa? 665 00:29:01,300 --> 00:29:03,883 Qualunque sia questa cosa sta indicando a-- e traggo punto interrogativo, 666 00:29:03,883 --> 00:29:07,060 ma in realtà, sta andando ad essere qualcosa come OX1, 2, 3, giusto? 667 00:29:07,060 --> 00:29:10,730 E 'un valore falso che appena capita di essere lì da prima. 668 00:29:10,730 --> 00:29:13,440 Quindi, in altre parole, è come se buffer è solo 669 00:29:13,440 --> 00:29:16,180 che punta a qualcosa in memoria. 670 00:29:16,180 --> 00:29:17,610 Non ho idea di cosa. 671 00:29:17,610 --> 00:29:24,130 >> Quindi, se digito Gabe ora, sta andando per cercare di mettere g-a-b-e / 0 lì. 672 00:29:24,130 --> 00:29:25,530 Ma chi sa di cosa si tratta? 673 00:29:25,530 --> 00:29:27,480 E in passato, qualsiasi tempo abbiamo cercato di toccare 674 00:29:27,480 --> 00:29:29,770 memoria che non appartiene a noi, che cosa è successo? 675 00:29:29,770 --> 00:29:31,020 676 00:29:31,020 --> 00:29:32,870 O quasi ogni volta. 677 00:29:32,870 --> 00:29:34,310 Segmentation fault, giusto? 678 00:29:34,310 --> 00:29:37,829 >> Questa freccia, non ho idea di dove è puntamento. è solo un valore casuale. 679 00:29:37,829 --> 00:29:40,370 E, naturalmente, se si interpreta un valore casuale come un indirizzo, 680 00:29:40,370 --> 00:29:42,610 avete intenzione di andare a una certa destinazione casuale. 681 00:29:42,610 --> 00:29:46,810 Così Gabe potrebbe infatti incidente il mio programma in questo caso qui. 682 00:29:46,810 --> 00:29:50,600 >> Che cosa possiamo fare che è quasi peggio? 683 00:29:50,600 --> 00:29:52,660 Considerate questo terzo e ultimo esempio di scanf. 684 00:29:52,660 --> 00:29:53,890 685 00:29:53,890 --> 00:29:56,870 Questa versione è meglio in che senso? 686 00:29:56,870 --> 00:29:57,990 687 00:29:57,990 --> 00:30:01,400 Se hai dimestichezza con la problema precedente, questo è meglio. 688 00:30:01,400 --> 00:30:02,250 Perché? 689 00:30:02,250 --> 00:30:03,250 >> PUBBLICO: [incomprensibile]. 690 00:30:03,250 --> 00:30:06,235 691 00:30:06,235 --> 00:30:07,110 DAVID J. MALAN: Good. 692 00:30:07,110 --> 00:30:09,970 Quindi questo caso della linea 16 è meglio, nel senso 693 00:30:09,970 --> 00:30:12,030 che siamo esplicitamente allocazione della memoria. 694 00:30:12,030 --> 00:30:14,190 Noi non stiamo usando malloc, stiamo usando la settimana 2 695 00:30:14,190 --> 00:30:16,060 approccio di solo dichiarare un array. 696 00:30:16,060 --> 00:30:18,130 E abbiamo detto prima che una stringa è solo un array di caratteri, 697 00:30:18,130 --> 00:30:19,690 quindi questo è del tutto legittimo. 698 00:30:19,690 --> 00:30:22,910 Ma è, naturalmente, come si nota, dimensione fissa, 16. 699 00:30:22,910 --> 00:30:25,440 >> Quindi questo programma è totalmente sicuro, se digito 700 00:30:25,440 --> 00:30:29,760 in stringhe di un carattere, due caratteri stringhe, 15 stringhe di caratteri. 701 00:30:29,760 --> 00:30:34,970 Ma appena comincio a digitare 16, 17, 18, 1.000 stringhe di caratteri, 702 00:30:34,970 --> 00:30:37,390 dove sta la stringa sta per finire? 703 00:30:37,390 --> 00:30:39,570 Sta andando a finire in parte qui. 704 00:30:39,570 --> 00:30:42,820 Ma poi chissà cos'altro è al di là dei confini 705 00:30:42,820 --> 00:30:44,270 di questa particolare array? 706 00:30:44,270 --> 00:30:48,015 >> E 'come se ho dichiarato 16 scatole qui. 707 00:30:48,015 --> 00:30:49,300 708 00:30:49,300 --> 00:30:52,690 Quindi, piuttosto che tirare fuori tutto 16, faremo solo finta che ho disegnato 16. 709 00:30:52,690 --> 00:30:56,540 Ma se poi provo a leggere un stringa che è molto più lungo, come 50 caratteri, 710 00:30:56,540 --> 00:31:01,270 Ho intenzione di iniziare a mettere a, b, c, d, x, y, z. 711 00:31:01,270 --> 00:31:04,916 E questo è probabilmente qualche altro segmento di memoria 712 00:31:04,916 --> 00:31:06,790 che, ancora una volta, potrebbe causare il mio programma di crash, 713 00:31:06,790 --> 00:31:10,600 perché non ho chiesto qualcosa di più di soli 16 byte. 714 00:31:10,600 --> 00:31:12,260 >> Quindi chi se ne frega? 715 00:31:12,260 --> 00:31:13,880 Bene, ecco la biblioteca CS50. 716 00:31:13,880 --> 00:31:17,220 E la maggior parte di questo è solo come le istruzioni sulla parte superiore. 717 00:31:17,220 --> 00:31:21,670 La biblioteca CS50, tutto questo tempo, ha avuto questa linea in linea 52. 718 00:31:21,670 --> 00:31:23,680 Abbiamo visto typedef, o si vedrà typedef 719 00:31:23,680 --> 00:31:27,930 in pset 4, che crea solo un tradurre cui char stelle può essere più 720 00:31:27,930 --> 00:31:29,290 semplicemente indicato come stringa. 721 00:31:29,290 --> 00:31:31,540 Quindi questo è uno dei alcune ruote di formazione 722 00:31:31,540 --> 00:31:34,120 abbiamo usato di nascosto sotto il cofano. 723 00:31:34,120 --> 00:31:36,490 >> Nel frattempo, ecco la funzione getchar. 724 00:31:36,490 --> 00:31:38,190 Ora a quanto pare, non c'è nessun corpo ad esso. 725 00:31:38,190 --> 00:31:40,273 E infatti, se continuo scorrimento, io in realtà non 726 00:31:40,273 --> 00:31:42,080 vedi tutte le implementazioni di queste funzioni. 727 00:31:42,080 --> 00:31:43,140 728 00:31:43,140 --> 00:31:45,516 Come un controllo di integrità, perché? 729 00:31:45,516 --> 00:31:46,795 >> PUBBLICO: [incomprensibile]. 730 00:31:46,795 --> 00:31:47,670 DAVID J. MALAN: Già. 731 00:31:47,670 --> 00:31:48,950 Quindi questo è il file di intestazione. 732 00:31:48,950 --> 00:31:52,520 E file di intestazione contengono prototipi, più alcune altre cose, a quanto pare, 733 00:31:52,520 --> 00:31:53,780 come typedef. 734 00:31:53,780 --> 00:31:56,910 Ma in CS50.c, che abbiamo mai dato a titolo definitivo, 735 00:31:56,910 --> 00:32:02,100 ma è stato nel apparecchio CS50 tutto questa volta, nel profondo delle sue cartelle, 736 00:32:02,100 --> 00:32:04,990 notare che c'è un intero gruppo di funzioni in qui. 737 00:32:04,990 --> 00:32:06,720 >> In realtà, cerchiamo di scorrere verso il basso. 738 00:32:06,720 --> 00:32:08,810 Ignoriamo la maggior parte di loro, per ora. 739 00:32:08,810 --> 00:32:12,670 Ma scorrere verso il basso per getInt e vedere come funziona getInt. 740 00:32:12,670 --> 00:32:13,890 Così qui è getInt. 741 00:32:13,890 --> 00:32:17,727 E se mai veramente curato come arrivare int funziona, ecco la sua documentazione. 742 00:32:17,727 --> 00:32:19,560 E tra le cose che dice è che ti dice 743 00:32:19,560 --> 00:32:21,340 quali gli intervalli di valori che possono tornare. 744 00:32:21,340 --> 00:32:24,400 E 'essenzialmente negativo 2 miliardi al positivo 2 miliardi, prendere o lasciare. 745 00:32:24,400 --> 00:32:26,420 >> E si scopre, tutto questo tempo, anche se non abbiamo mai 746 00:32:26,420 --> 00:32:28,570 se aveste verificare la presenza di esso, se qualcosa va storto, 747 00:32:28,570 --> 00:32:30,680 si scopre che tutti questa volta, ha getInt 748 00:32:30,680 --> 00:32:33,600 state restituendo una speciale costante, non nullo, 749 00:32:33,600 --> 00:32:36,760 ma piuttosto INT_MAX, che è convenzione solo un programmatore. 750 00:32:36,760 --> 00:32:38,846 Significa: ecco un valore speciale. 751 00:32:38,846 --> 00:32:41,470 Assicuratevi di controllare per questo, basta in caso qualcosa vada storto. 752 00:32:41,470 --> 00:32:43,261 Ma non abbiamo mai disturbati con che fino ad oggi, 753 00:32:43,261 --> 00:32:45,200 perché ancora una volta, questo si intende per semplificare. 754 00:32:45,200 --> 00:32:46,950 >> Ma come fa getInt ottenere implementato? 755 00:32:46,950 --> 00:32:48,450 Beh, si, ma non accetta argomenti. 756 00:32:48,450 --> 00:32:49,390 Sappiamo che. 757 00:32:49,390 --> 00:32:50,820 Esso restituisce un int. 758 00:32:50,820 --> 00:32:51,950 Sappiamo che. 759 00:32:51,950 --> 00:32:54,460 Così come funziona sotto il cofano? 760 00:32:54,460 --> 00:32:58,290 >> Quindi c'è apparentemente un infinito ciclo, almeno l'apparenza di uno. 761 00:32:58,290 --> 00:33:00,290 Notate che stiamo usando getString. 762 00:33:00,290 --> 00:33:04,000 Ecco, questo è interessante. getInt chiama la nostra funzione, getString. 763 00:33:04,000 --> 00:33:05,645 E ora perché potrebbe essere questo il caso? 764 00:33:05,645 --> 00:33:07,400 765 00:33:07,400 --> 00:33:09,842 Perché mi viene difensiva qui in linea 165? 766 00:33:09,842 --> 00:33:11,390 767 00:33:11,390 --> 00:33:15,639 Cosa potrebbe accadere in linea 164, tanto per essere chiari? 768 00:33:15,639 --> 00:33:16,930 E 'la stessa risposta di prima. 769 00:33:16,930 --> 00:33:18,660 770 00:33:18,660 --> 00:33:20,089 Potrebbe essere solo la memoria. 771 00:33:20,089 --> 00:33:23,130 Qualcosa va storto con getString, dobbiamo essere in grado di gestire questo. 772 00:33:23,130 --> 00:33:27,070 E la ragione per cui non tornare nulla è che, tecnicamente, è un puntatore nullo. 773 00:33:27,070 --> 00:33:29,120 getInt deve restituire un int. 774 00:33:29,120 --> 00:33:31,060 Così ho arbitrariamente ha deciso, in sostanza, 775 00:33:31,060 --> 00:33:34,600 che 2 miliardi, più o meno, sta ad essere un valore speciale che non potrò mai 776 00:33:34,600 --> 00:33:35,970 effettivamente ottenere da parte dell'utente. 777 00:33:35,970 --> 00:33:39,930 E 'solo un valore di Vado sprecare per rappresentare un codice di errore. 778 00:33:39,930 --> 00:33:41,540 >> Così ora, le cose si fanno un po 'di fantasia. 779 00:33:41,540 --> 00:33:44,670 E non è proprio la stessa funzione come prima, ma è molto simile. 780 00:33:44,670 --> 00:33:50,120 Così Noto, dichiaro qui, in linea 172, sia un int n e un char c. 781 00:33:50,120 --> 00:33:53,600 E poi io uso questa linea funky, sscanf, che si scopre 782 00:33:53,600 --> 00:33:55,990 non eseguire la scansione di una stringa da tastiera. 783 00:33:55,990 --> 00:33:59,226 Si trova una stringa esistente che l'utente ha già digitato. 784 00:33:59,226 --> 00:34:02,100 Così ho già chiamato getString, che significa che ho una stringa in memoria. 785 00:34:02,100 --> 00:34:05,020 sscanf è quello che ci si chiamare una funzione di parsing. 786 00:34:05,020 --> 00:34:07,760 Esso esamina la stringa ho digitato, carattere per carattere, 787 00:34:07,760 --> 00:34:09,250 e fa qualcosa di utile. 788 00:34:09,250 --> 00:34:10,969 Tale stringa viene memorizzato in linea. 789 00:34:10,969 --> 00:34:13,560 E so che solo andando eseguire il backup qui e dire, oh, OK, 790 00:34:13,560 --> 00:34:15,143 Ho chiamato non s questa volta, ma la linea. 791 00:34:15,143 --> 00:34:15,989 792 00:34:15,989 --> 00:34:18,080 >> E ora questo è un po 'diverso. 793 00:34:18,080 --> 00:34:22,480 Ma questo significa efficacemente, per motivi faremo un po 'sventoliamo le nostre mani a oggi, 794 00:34:22,480 --> 00:34:26,070 che stiamo verificando a vedere se l'utente ha digitato in 795 00:34:26,070 --> 00:34:29,909 e int e forse un altro personaggio. 796 00:34:29,909 --> 00:34:33,610 Se l'utente ha digitato in un int, è andando a essere immagazzinate nella n, perché sono 797 00:34:33,610 --> 00:34:36,739 passando da questo indirizzo, il nuovo trucco che abbiamo visto oggi. 798 00:34:36,739 --> 00:34:41,570 Se l'utente anche digitato a come 123x, che x 799 00:34:41,570 --> 00:34:45,060 sta per finire un lettera in carattere c. 800 00:34:45,060 --> 00:34:48,739 >> Ora si scopre che sscanf mi dirà, in modo intelligente, 801 00:34:48,739 --> 00:34:54,750 quante variabili è stato sscanf con successo in grado di riempire. 802 00:34:54,750 --> 00:34:58,770 Così da questa logica, se la funzione Sto esecuzione è getInt, 803 00:34:58,770 --> 00:35:00,900 ma io sto controllando, potenzialmente, per l'utente 804 00:35:00,900 --> 00:35:04,190 di aver digitato in un int seguita da qualcosa d'altro, 805 00:35:04,190 --> 00:35:08,580 cosa voglio di sscanf valore di ritorno veramente di essere? 806 00:35:08,580 --> 00:35:10,950 Se lo scopo è quello di ottenere solo un int da parte dell'utente? 807 00:35:10,950 --> 00:35:13,980 808 00:35:13,980 --> 00:35:19,300 >> Quindi, se sscanf rendimenti 2, che cosa significa? 809 00:35:19,300 --> 00:35:21,660 L'utente ha digitato in qualcosa di simile, letteralmente, 810 00:35:21,660 --> 00:35:24,770 123x, che è solo una sciocchezza. 811 00:35:24,770 --> 00:35:27,490 Si tratta di una condizione di errore, e Voglio controllare per questo. 812 00:35:27,490 --> 00:35:32,960 >> Quindi, se l'utente digita questo, da questa logica, quello che fa sscanf ritorno, 813 00:35:32,960 --> 00:35:33,740 diresti? 814 00:35:33,740 --> 00:35:35,070 815 00:35:35,070 --> 00:35:39,130 Così sta andando a tornare 2, perché la 123 sta per andare in qui, 816 00:35:39,130 --> 00:35:41,580 e la x sta per finire qui. 817 00:35:41,580 --> 00:35:43,970 Ma io non voglio la x per ottenere riempito. 818 00:35:43,970 --> 00:35:48,580 Voglio sscanf per avere successo solo in riempiendo la prima delle sue variabili. 819 00:35:48,580 --> 00:35:52,490 Ed ecco perché io Voglio sscanf per tornare 1. 820 00:35:52,490 --> 00:35:55,750 >> E se questo è un po 'sopra la testa per il momento, che è totalmente soddisfacente. 821 00:35:55,750 --> 00:36:00,030 Realizzare però, che uno dei valori di getInt e getString 822 00:36:00,030 --> 00:36:03,630 è che noi stiamo facendo un diavolo di un sacco di controllo degli errori come questo così 823 00:36:03,630 --> 00:36:07,130 che, ad oggi, si può tranquillamente digitare nulla a vostra tastiera, 824 00:36:07,130 --> 00:36:08,490 e noi prenderlo. 825 00:36:08,490 --> 00:36:10,592 E certamente, il personale, non sarà sicuramente 826 00:36:10,592 --> 00:36:13,300 essere la fonte di un bug nel programma, perché siamo sulla difensiva 827 00:36:13,300 --> 00:36:16,270 controllando tutti i stupido cose che un utente potrebbe fare, 828 00:36:16,270 --> 00:36:18,900 come digitando una stringa, quando si voleva davvero int. 829 00:36:18,900 --> 00:36:21,350 Quindi per now-- verremo Torna alla prima long-- 830 00:36:21,350 --> 00:36:23,710 ma tutto questo tempo, getString e getInt hanno 831 00:36:23,710 --> 00:36:29,950 stato sotto la cappa di utilizzare questo idea di base di indirizzi di memoria. 832 00:36:29,950 --> 00:36:32,580 >> Così ora, facciamo le cose un poco user-friendly più. 833 00:36:32,580 --> 00:36:38,740 Come ricorderete, da Binky ultimo tempo-- se il mio mouse si cooperate-- così 834 00:36:38,740 --> 00:36:42,560 abbiamo avuto questo codice, che francamente, è abbastanza assurdo. 835 00:36:42,560 --> 00:36:45,330 Questo codice ottiene nulla utile, ma è stato l'esempio 836 00:36:45,330 --> 00:36:48,330 quel professore Parlante utilizzato per rappresentare 837 00:36:48,330 --> 00:36:51,840 quello che stava succedendo in un programma che coinvolge la memoria. 838 00:36:51,840 --> 00:36:54,850 >> Quindi cerchiamo di raccontare questa storia eccellente brevemente. 839 00:36:54,850 --> 00:36:58,720 Queste prime due righe, in Inglese, fai quello, diresti? 840 00:36:58,720 --> 00:37:01,230 841 00:37:01,230 --> 00:37:05,430 Proprio in ragionevolmente umano, ma leggermente termini tecnici, prendere una pugnalata. 842 00:37:05,430 --> 00:37:06,346 PUBBLICO: [incomprensibile]. 843 00:37:06,346 --> 00:37:07,705 844 00:37:07,705 --> 00:37:11,080 >> DAVID J. MALAN: OK, siete stabilire indirizzi per la vostra variabili x e y. 845 00:37:11,080 --> 00:37:15,520 Non proprio, perché x e y non sono variabili in senso tradizionale. 846 00:37:15,520 --> 00:37:18,054 x e y sono indirizzi o memorizza l'indirizzo. 847 00:37:18,054 --> 00:37:19,220 Quindi proviamo una volta di più. 848 00:37:19,220 --> 00:37:21,010 Non male come inizio, però. 849 00:37:21,010 --> 00:37:21,510 Sì? 850 00:37:21,510 --> 00:37:22,426 >> PUBBLICO: [incomprensibile]. 851 00:37:22,426 --> 00:37:23,966 852 00:37:23,966 --> 00:37:24,840 DAVID J. MALAN: Good. 853 00:37:24,840 --> 00:37:26,173 Penso che sia un po 'più pulito. 854 00:37:26,173 --> 00:37:28,630 Dichiarare due puntatori, due interi. 855 00:37:28,630 --> 00:37:30,150 E stiamo chiamandoli x e y. 856 00:37:30,150 --> 00:37:32,790 Oppure, se dovessimo disegnare questo come un quadro, di nuovo, 857 00:37:32,790 --> 00:37:36,410 ricordare semplicemente che tutti stiamo facendo con quella prima linea 858 00:37:36,410 --> 00:37:39,690 sta disegnando una scatola come questa, con un certo valore spazzatura in esso, 859 00:37:39,690 --> 00:37:41,920 e chiamandolo X, e poi un'altra scatola come questo, 860 00:37:41,920 --> 00:37:43,880 con un certo valore di immondizia in essa, chiamandolo a. 861 00:37:43,880 --> 00:37:45,810 Abbiamo dichiarato due puntatori che in ultima analisi 862 00:37:45,810 --> 00:37:47,860 memorizza l'indirizzo di un int. 863 00:37:47,860 --> 00:37:49,170 Ecco, questo è tutto lì. 864 00:37:49,170 --> 00:37:53,290 >> Così quando Binky ha fatto questo, il argilla appena guardato come questo. 865 00:37:53,290 --> 00:37:55,350 E Nick solo tipo di avvolto le frecce, 866 00:37:55,350 --> 00:37:57,590 come se non stanno puntando ovunque in particolare, perché sono solo 867 00:37:57,590 --> 00:37:58,250 valori di immondizia. 868 00:37:58,250 --> 00:38:01,670 Non sono esplicitamente inizializzate ovunque in particolare. 869 00:38:01,670 --> 00:38:03,980 >> Ora la prossima linea di codice, richiamo, era questo. 870 00:38:03,980 --> 00:38:07,510 Quindi, in ragionevolmente user-friendly, ma l'inglese un po 'tecnico, 871 00:38:07,510 --> 00:38:09,790 che cosa è questa riga di codice facendo? 872 00:38:09,790 --> 00:38:10,391 Sì? 873 00:38:10,391 --> 00:38:11,333 >> PUBBLICO: [incomprensibile]. 874 00:38:11,333 --> 00:38:12,746 875 00:38:12,746 --> 00:38:13,950 >> DAVID J. MALAN: Perfetto. 876 00:38:13,950 --> 00:38:17,016 E 'assegnazione della fetta del memoria che è la dimensione di un int. 877 00:38:17,016 --> 00:38:18,140 E questo è la metà della risposta. 878 00:38:18,140 --> 00:38:20,056 Hai risposto il diritto metà dell'espressione. 879 00:38:20,056 --> 00:38:22,473 Che cosa sta accadendo sul lato sinistro del segno di uguale? 880 00:38:22,473 --> 00:38:22,972 Sì? 881 00:38:22,972 --> 00:38:24,814 PUBBLICO: e assegna alla variabile x? 882 00:38:24,814 --> 00:38:27,690 >> DAVID J. MALAN: e assegna alla variabile x. 883 00:38:27,690 --> 00:38:31,650 Quindi, per ricapitolare, destra assegna laterali memoria sufficiente per memorizzare un int. 884 00:38:31,650 --> 00:38:34,150 Ma malloc specificamente restituisce l'indirizzo 885 00:38:34,150 --> 00:38:37,270 di quel pezzo di memoria, che hai appena proposto viene memorizzato in x. 886 00:38:37,270 --> 00:38:42,560 >> Così che cosa ha fatto Nick ultima volta con Binky è che ha trascinato il puntatore fuori, l'argilla, 887 00:38:42,560 --> 00:38:46,820 per puntare ora ad un pezzo bianco di memoria che è uguale alla dimensione di un int. 888 00:38:46,820 --> 00:38:49,360 E in effetti, che è destinata per rappresentare quattro byte. 889 00:38:49,360 --> 00:38:55,310 >> Ora, la prossima riga di codice fatto questo, stella x ottiene 42. 890 00:38:55,310 --> 00:38:58,530 Quindi 42 è diretto sul destra, senso della vita. 891 00:38:58,530 --> 00:39:00,500 Lato sinistro, stella x significa ciò? 892 00:39:00,500 --> 00:39:01,600 893 00:39:01,600 --> 00:39:03,280 Anche questo potrebbe avere gone-- che è OK. 894 00:39:03,280 --> 00:39:04,220 Ok. 895 00:39:04,220 --> 00:39:06,875 >> PUBBLICO: Fondamentalmente, andare al [incomprensibile] 896 00:39:06,875 --> 00:39:07,750 DAVID J. MALAN: Good. 897 00:39:07,750 --> 00:39:08,760 PUBBLICO: [incomprensibile]. 898 00:39:08,760 --> 00:39:09,760 DAVID J. MALAN: Esattamente. 899 00:39:09,760 --> 00:39:11,979 Sinistra significa andare a x. 900 00:39:11,979 --> 00:39:12,520 x è l'indirizzo. 901 00:39:12,520 --> 00:39:15,520 E 'come 33 Oxford Street, o OX1. 902 00:39:15,520 --> 00:39:18,690 E stelle x significa andare a quel affrontare e mettere quello che c'è? 903 00:39:18,690 --> 00:39:19,520 42. 904 00:39:19,520 --> 00:39:21,290 >> Così in effetti, questo è esattamente quello che ha fatto Nick. 905 00:39:21,290 --> 00:39:23,740 Ha iniziato con da, in sostanza, mentalmente 906 00:39:23,740 --> 00:39:26,270 puntando il dito contro x, seguendo la freccia 907 00:39:26,270 --> 00:39:30,670 per la scatola bianca sulla destra lato, e mettendo il numero 42 lì. 908 00:39:30,670 --> 00:39:34,120 Ma poi le cose sono un po 'pericoloso, giusto? 909 00:39:34,120 --> 00:39:35,860 Binky sta per perdere la testa. 910 00:39:35,860 --> 00:39:39,465 >> Stella y è uguale a 13, la sfortuna, che cosa significa? 911 00:39:39,465 --> 00:39:43,620 Così stella mezzi y vanno all'indirizzo di y. 912 00:39:43,620 --> 00:39:45,630 Ma qual è l'indirizzo in y? 913 00:39:45,630 --> 00:39:47,899 914 00:39:47,899 --> 00:39:49,440 Va bene, il suo valore spazzatura, giusto? 915 00:39:49,440 --> 00:39:50,800 Ho disegnato come un punto interrogativo. 916 00:39:50,800 --> 00:39:54,850 Nick ha attirato come una freccia rannicchiata. 917 00:39:54,850 --> 00:39:59,600 E non appena si tenta di fare stella y, dicendo andare lì, 918 00:39:59,600 --> 00:40:03,872 ma non c'è un legittimo indirizzo, è certa posizione falsa, 919 00:40:03,872 --> 00:40:05,080 il programma sta andando in crash. 920 00:40:05,080 --> 00:40:08,580 E la testa di Binky sta a volare fuori qui, come ha fatto. 921 00:40:08,580 --> 00:40:12,130 >> Così, alla fine, questo programma era appena flat out difetto. 922 00:40:12,130 --> 00:40:13,540 E 'stato un programma buggy. 923 00:40:13,540 --> 00:40:14,760 E aveva bisogno di essere fissato. 924 00:40:14,760 --> 00:40:18,260 E l'unico modo, davvero, per risolvere il problema sarebbe, per esempio, questa linea, 925 00:40:18,260 --> 00:40:21,010 che non abbiamo neanche raggiungere, perché il programma si è schiantato troppo presto. 926 00:40:21,010 --> 00:40:26,170 Ma se dovessimo risolvere questo problema, cosa effetto fa fare y pari x hanno? 927 00:40:26,170 --> 00:40:30,010 Beh, che punti essenzialmente aa qualsiasi valore x punta verso. 928 00:40:30,010 --> 00:40:32,430 >> Così nella storia di Nick, o la storia di Binky, sia 929 00:40:32,430 --> 00:40:34,640 x e y sono state rivolte l'una verso il pezzo bianco della memoria, 930 00:40:34,640 --> 00:40:38,300 in modo che, alla fine, quando si non a stella Y è uguale a 13 di nuovo, 931 00:40:38,300 --> 00:40:43,080 si finisce per mettere 13 in nella posizione appropriata. 932 00:40:43,080 --> 00:40:47,640 Quindi tutte queste linee sono perfettamente legittima, tranne per questo, 933 00:40:47,640 --> 00:40:51,730 quando è successo prima di effettivamente assegnato un certo valore y. 934 00:40:51,730 --> 00:40:54,290 >> Ora per fortuna, non è necessario avere a ragionare attraverso tutti 935 00:40:54,290 --> 00:40:56,560 di questi tipi di problemi da soli. 936 00:40:56,560 --> 00:40:59,310 Lasciami andare avanti e aprire una finestra di terminale qui 937 00:40:59,310 --> 00:41:03,050 e di aprire, solo per un attimo, un super breve programma che 938 00:41:03,050 --> 00:41:04,360 è anche una sorta di inutile. 939 00:41:04,360 --> 00:41:05,152 E 'brutto. 940 00:41:05,152 --> 00:41:06,610 Essa non ottiene nulla di utile. 941 00:41:06,610 --> 00:41:10,180 Ma questo dimostra questioni della memoria, così diamo un'occhiata. 942 00:41:10,180 --> 00:41:11,830 >> Principale, super semplice. 943 00:41:11,830 --> 00:41:14,830 E a quanto pare chiama una funzione, F, e quindi restituisce 0. 944 00:41:14,830 --> 00:41:16,310 È un po 'difficile da rovinare questo. 945 00:41:16,310 --> 00:41:18,540 Quindi principale è abbastanza buono, finora. 946 00:41:18,540 --> 00:41:20,100 >> Quindi f è problematico. 947 00:41:20,100 --> 00:41:22,120 E proprio non ha messo molto sforzo in nominarlo 948 00:41:22,120 --> 00:41:23,990 qui, per mantenere l'attenzione sul codice. 949 00:41:23,990 --> 00:41:25,740 f ha due linee. 950 00:41:25,740 --> 00:41:27,610 E vediamo quello che sta ora accadendo. 951 00:41:27,610 --> 00:41:29,840 Così, da un lato qui-- e fammi fare 952 00:41:29,840 --> 00:41:32,680 questa linea con il precedente example-- da un lato, 953 00:41:32,680 --> 00:41:35,830 il lato sinistro è facendo ciò, in inglese? 954 00:41:35,830 --> 00:41:36,493 Si è-- 955 00:41:36,493 --> 00:41:37,701 PUBBLICO: Creazione di un puntatore. 956 00:41:37,701 --> 00:41:40,830 DAVID J. MALAN: Creazione di un puntatore ad un int e chiamandolo x. 957 00:41:40,830 --> 00:41:43,789 Così è la creazione di una di quelle scatole Continuo a disegnare sul touch screen. 958 00:41:43,789 --> 00:41:45,913 E ora, sulla destra lato, malloc, naturalmente, 959 00:41:45,913 --> 00:41:47,420 è l'assegnazione di un pezzo di memoria. 960 00:41:47,420 --> 00:41:49,989 E tanto per essere chiari, come quantità di memoria è apparentemente 961 00:41:49,989 --> 00:41:52,030 assegnazione, se solo tipo di fare la matematica qui? 962 00:41:52,030 --> 00:41:53,200 963 00:41:53,200 --> 00:41:54,040 >> Quindi è 40 byte. 964 00:41:54,040 --> 00:41:57,400 E so che solo perché so un int, sull'apparecchio CS50, almeno, 965 00:41:57,400 --> 00:41:58,060 è quattro byte. 966 00:41:58,060 --> 00:41:59,610 Quindi 10 volte 4 è 40. 967 00:41:59,610 --> 00:42:04,924 Quindi questa è la memorizzazione di un x, l'indirizzo del primo dei 40 int che 968 00:42:04,924 --> 00:42:07,340 sono stati stanziati spazio posteriore, to back, to back, to back. 969 00:42:07,340 --> 00:42:08,470 >> E questo è ciò che è chiave su malloc. 970 00:42:08,470 --> 00:42:11,261 Non ci vuole un po 'di memoria qui, un po 'qui, un po' qui. 971 00:42:11,261 --> 00:42:14,220 Ti dà un pezzo di memoria, contiguo, dal funzionamento 972 00:42:14,220 --> 00:42:15,240 sistema. 973 00:42:15,240 --> 00:42:18,500 >> Ora, che dire di questa, x staffa 10 è uguale a 0? 974 00:42:18,500 --> 00:42:19,470 Linea arbitraria di codice. 975 00:42:19,470 --> 00:42:21,100 Essa non ottiene nulla di utile. 976 00:42:21,100 --> 00:42:26,128 Ma è interessante, perché x staffa 10--? 977 00:42:26,128 --> 00:42:26,628 Sì? 978 00:42:26,628 --> 00:42:27,912 >> PUBBLICO: [incomprensibile]? 979 00:42:27,912 --> 00:42:30,500 >> DAVID J. MALAN: x staffa 10 non deve essere nullo. 980 00:42:30,500 --> 00:42:35,070 Il dettaglio nulla entra in gioco solo con corde, alla fine di una stringa. 981 00:42:35,070 --> 00:42:36,700 Ma un buon pensiero. 982 00:42:36,700 --> 00:42:39,615 >> Quanto è grande questo array, anche se ho assegnata 40 byte? 983 00:42:39,615 --> 00:42:42,560 984 00:42:42,560 --> 00:42:43,690 E 'da 0 a nove, giusto? 985 00:42:43,690 --> 00:42:45,120 E '10 int, totale. 986 00:42:45,120 --> 00:42:48,790 40 byte, ma 10 int, indicizzate da 0 a 0. 987 00:42:48,790 --> 00:42:50,930 >> Così che cosa è che la staffa x 10? 988 00:42:50,930 --> 00:42:53,090 In realtà è un po ' sconosciuta valore spazzatura. 989 00:42:53,090 --> 00:42:54,780 E 'la memoria che non appartiene a me. 990 00:42:54,780 --> 00:42:59,650 Non dovrei toccando che byte numero 41, 42, 43, 44. 991 00:42:59,650 --> 00:43:01,420 Sto andando un po 'troppo lontano. 992 00:43:01,420 --> 00:43:04,490 >> E in effetti, se corro questo programma, potrebbe benissimo bloccarsi. 993 00:43:04,490 --> 00:43:05,790 Ma a volte, ci arriveremo fortunati. 994 00:43:05,790 --> 00:43:07,706 E così, proprio per dimostrare Questa poi e, francamente, 995 00:43:07,706 --> 00:43:11,000 non si sa mai prima di do it-- corriamo questo. 996 00:43:11,000 --> 00:43:12,480 Essa in realtà non crash. 997 00:43:12,480 --> 00:43:15,032 >> Ma se cambio questo, per esempio, di essere come 1000, 998 00:43:15,032 --> 00:43:16,740 per rendere questo veramente deliberata, vediamo 999 00:43:16,740 --> 00:43:18,710 se possiamo ottenere il crash questa volta. 1000 00:43:18,710 --> 00:43:20,070 OK, non è precipitato. 1001 00:43:20,070 --> 00:43:22,600 Come circa 100.000? 1002 00:43:22,600 --> 00:43:25,000 Cerchiamo di rifarlo, e ora eseguirlo nuovamente. 1003 00:43:25,000 --> 00:43:25,500 Ok. 1004 00:43:25,500 --> 00:43:25,960 Uff. 1005 00:43:25,960 --> 00:43:26,460 Bene. 1006 00:43:26,460 --> 00:43:29,090 Quindi, apparentemente, ancora una volta, questi segmenti di memoria, per così dire, 1007 00:43:29,090 --> 00:43:32,660 sono abbastanza grande, in modo che possiamo ottenere ancora e ancora fortunati. 1008 00:43:32,660 --> 00:43:36,510 Ma alla fine, una volta arrivati ​​ridicolo e davvero andare lontano sullo schermo, 1009 00:43:36,510 --> 00:43:39,120 si tocca la memoria che in realtà, in realtà non appartiene a voi. 1010 00:43:39,120 --> 00:43:40,870 >> Ma francamente, questi tipi di insetti stanno andando 1011 00:43:40,870 --> 00:43:43,020 per essere sempre più difficile di capire da soli. 1012 00:43:43,020 --> 00:43:47,880 Ma per fortuna, come i programmatori, abbiamo strumenti che ci permettono di fare questo per noi. 1013 00:43:47,880 --> 00:43:50,140 Quindi questo è, forse, uno dei programmi più brutti, 1014 00:43:50,140 --> 00:43:52,060 anche più brutto di uscita di gdb. 1015 00:43:52,060 --> 00:43:55,670 Ma ha sempre una linea o due che sono super utile. 1016 00:43:55,670 --> 00:44:00,310 >> Valgrind è un programma che aiuta non si esegue il debug di un programma, di per sé, 1017 00:44:00,310 --> 00:44:03,500 ma trovare relative alla memoria problemi, in particolare. 1018 00:44:03,500 --> 00:44:07,590 Verrà eseguito automaticamente il codice per voi e cercate almeno due cose. 1019 00:44:07,590 --> 00:44:10,680 Uno, hai fatto qualcosa accidentale come la memoria di tocco 1020 00:44:10,680 --> 00:44:11,980 che non apparteneva a voi? 1021 00:44:11,980 --> 00:44:13,590 Essa vi aiuterà a trovare quei casi. 1022 00:44:13,590 --> 00:44:15,710 >> E due, che vi aiuterà si trova qualcosa chiamato 1023 00:44:15,710 --> 00:44:19,270 perdite di memoria, che abbiamo completamente ignorato, ingenuamente, 1024 00:44:19,270 --> 00:44:21,380 per qualche tempo e beatamente. 1025 00:44:21,380 --> 00:44:23,140 Ma si scopre, tutto questa volta, ogniqualvolta 1026 00:44:23,140 --> 00:44:26,620 che hai chiamato in getString così molti dei nostri programmi, 1027 00:44:26,620 --> 00:44:28,930 si sta chiedendo il funzionamento sistema per la memoria, 1028 00:44:28,930 --> 00:44:32,070 ma avete alcun ricordo di sempre dando 1029 00:44:32,070 --> 00:44:36,169 indietro, facendo unalloc, o libero, come si chiama. 1030 00:44:36,169 --> 00:44:37,960 No, perché non abbiamo mai ti ha chiesto di farlo. 1031 00:44:37,960 --> 00:44:41,250 >> Ma tutto questo tempo, i programmi hai scritto in C 1032 00:44:41,250 --> 00:44:43,800 sono state perdite di memoria, chiedendo il funzionamento 1033 00:44:43,800 --> 00:44:46,190 Sistema per più memoria per archi e quant'altro, 1034 00:44:46,190 --> 00:44:47,870 ma mai restituirlo. 1035 00:44:47,870 --> 00:44:50,080 E ora questo è un po ' di una semplificazione, 1036 00:44:50,080 --> 00:44:53,550 ma se hai mai eseguito il vostro Mac o il PC per un bel po 'di tempo, l'apertura 1037 00:44:53,550 --> 00:44:55,790 un sacco di programmi, forse chiudere i programmi, 1038 00:44:55,790 --> 00:44:57,795 e anche se la vostra computer non è andato in crash, 1039 00:44:57,795 --> 00:45:01,690 sta diventando così molto più lento, come se fosse davvero 1040 00:45:01,690 --> 00:45:04,290 utilizzando un sacco di memoria o risorse, anche se, 1041 00:45:04,290 --> 00:45:06,070 se non sei nemmeno toccare la tastiera, 1042 00:45:06,070 --> 00:45:10,430 che potrebbe essere-- ma non ci riuscivo always-- essere che i programmi si sta eseguendo 1043 00:45:10,430 --> 00:45:11,920 hanno essi stessi perdite di memoria. 1044 00:45:11,920 --> 00:45:15,645 E loro continuano a chiedere il sistema operativo per sempre più memoria, ma dimenticando che, 1045 00:45:15,645 --> 00:45:18,470 in realtà non usarlo, ma quindi prendendo la memoria di distanza 1046 00:45:18,470 --> 00:45:20,500 da altri programmi che potrebbero desiderare di esso. 1047 00:45:20,500 --> 00:45:23,940 Ecco, questo è una spiegazione comune. 1048 00:45:23,940 --> 00:45:25,940 Ora qui è dove Valgrind di uscita è completamente 1049 00:45:25,940 --> 00:45:29,290 atroce a quelli meno e più confortevole simili. 1050 00:45:29,290 --> 00:45:32,690 Ma l'interessante roba è proprio qui. 1051 00:45:32,690 --> 00:45:37,060 Mi sta dicendo una scrittura non valido dimensione quattro succede in questo programma, 1052 00:45:37,060 --> 00:45:40,640 in particolare, alla riga 21 di memory.c. 1053 00:45:40,640 --> 00:45:45,450 >> Se vado alla riga 21, hm, c'è davvero è una scrittura valida di dimensione quattro. 1054 00:45:45,450 --> 00:45:46,250 Perché quattro dimensioni? 1055 00:45:46,250 --> 00:45:49,500 Beh, questo number-- e potrebbe essere anything-- è un int. 1056 00:45:49,500 --> 00:45:50,450 Quindi è quattro byte. 1057 00:45:50,450 --> 00:45:52,550 Così sto mettendo quattro byte cui non appartengono. 1058 00:45:52,550 --> 00:45:55,080 Questo è ciò che Valgrind è in realtà mi dice. 1059 00:45:55,080 --> 00:45:57,600 Inoltre, sarà anche dimmi, come vedremo, 1060 00:45:57,600 --> 00:46:01,490 come si esegue questo in un futuro pset, se e quando hai trapelare la memoria, che anzi 1061 00:46:01,490 --> 00:46:05,300 Ho, perché ho chiamato malloc, ma io non ho fatto 1062 00:46:05,300 --> 00:46:08,010 chiamato, in questo caso, libero, che vedremo poi vediamo 1063 00:46:08,010 --> 00:46:09,830 è l'opposto di malloc. 1064 00:46:09,830 --> 00:46:10,860 1065 00:46:10,860 --> 00:46:12,930 >> Così ora, penso, un ultimo esempio. 1066 00:46:12,930 --> 00:46:14,050 1067 00:46:14,050 --> 00:46:16,690 Quindi questo è un po 'più arcano, ma è forse 1068 00:46:16,690 --> 00:46:19,180 il più grande motivo di stare attenti con la memoria, 1069 00:46:19,180 --> 00:46:24,490 e la ragione per cui molti programmi e / o server web, anche a questo giorno, 1070 00:46:24,490 --> 00:46:28,200 sono preso da cattivi da qualche parte su Internet che sono in qualche modo 1071 00:46:28,200 --> 00:46:33,390 l'invio di pacchetti falsi al vostro server cercando di compromettere i vostri conti, 1072 00:46:33,390 --> 00:46:36,420 o prendere i vostri dati, o semplicemente generalmente assumere una macchina. 1073 00:46:36,420 --> 00:46:38,910 Buffer overflow, come l' nome suggerisce, mezzi 1074 00:46:38,910 --> 00:46:40,740 traboccante non un int, ma un buffer. 1075 00:46:40,740 --> 00:46:43,490 E un buffer è solo un modo elegante di dire che è un po 'di memoria. 1076 00:46:43,490 --> 00:46:46,710 >> E in effetti, ho chiamato una stringa prima tampone, invece di s. 1077 00:46:46,710 --> 00:46:49,234 Perché se si tratta di un buffer, come nel senso di YouTube, 1078 00:46:49,234 --> 00:46:52,400 o in qualsiasi momento si sta guardando un video, potreste aver visto la parola buffering, 1079 00:46:52,400 --> 00:46:53,040 dot, dot, dot. 1080 00:46:53,040 --> 00:46:54,240 E 'incredibilmente fastidioso. 1081 00:46:54,240 --> 00:46:55,990 E questo significa solo che il vostro lettore video 1082 00:46:55,990 --> 00:46:58,710 sta cercando di scaricare un sacco di byte, un sacco di byte 1083 00:46:58,710 --> 00:47:00,170 da un video da internet. 1084 00:47:00,170 --> 00:47:02,920 Ma è lento, quindi si sta cercando per scaricare un gruppo di loro 1085 00:47:02,920 --> 00:47:06,430 per riempire un buffer, un contenitore, in modo che si dispone di un numero sufficiente di byte che si può poi 1086 00:47:06,430 --> 00:47:09,174 mostrare il video, senza pause costantemente. 1087 00:47:09,174 --> 00:47:11,340 Ma si scopre, è possibile hanno un buffer per questo grande. 1088 00:47:11,340 --> 00:47:15,710 Ma provate a mettere questa quantità di dati in esso, e molto cose brutte possono accadere. 1089 00:47:15,710 --> 00:47:22,780 Così, per esempio, diamo un'occhiata a questo teaser finale di un esempio. 1090 00:47:22,780 --> 00:47:24,720 Questo è un altro programma che, a prima vista, 1091 00:47:24,720 --> 00:47:26,540 non fa nulla super utile. 1092 00:47:26,540 --> 00:47:29,590 Ha una funzione principale che chiama tale funzione, f. 1093 00:47:29,590 --> 00:47:36,640 E che funzione, f, qui, ha un array di char, chiamato C, di dimensione 12. 1094 00:47:36,640 --> 00:47:39,340 E poi si sta usando questo nuova funzione chiamata strncpy. 1095 00:47:39,340 --> 00:47:40,430 1096 00:47:40,430 --> 00:47:45,190 >> Risulta che, con questa semplice, semplice riga di codice, solo due righe, 1097 00:47:45,190 --> 00:47:49,130 abbiamo fatto tutto il mio programma, e, quindi, tutto il mio computer, 1098 00:47:49,130 --> 00:47:54,000 e il mio account, e il mio duro guidare potenzialmente vulnerabili a chiunque 1099 00:47:54,000 --> 00:47:58,170 che conosce ed è abbastanza buono per correre questo programma con una certa linea di comando 1100 00:47:58,170 --> 00:47:58,900 argomentazione. 1101 00:47:58,900 --> 00:48:03,400 In altre parole, se questo cattivo ragazzo mette dentro di argvargv [1] digitando 1102 00:48:03,400 --> 00:48:08,750 alla tastiera molto appositamente predisposto stringa, non abc, 123, ma essenzialmente, 1103 00:48:08,750 --> 00:48:15,180 simboli binari che rappresentano eseguibile codice, un programma che lui o lei ha scritto, 1104 00:48:15,180 --> 00:48:19,190 con questo semplice programma, che è rappresentativo di migliaia di programmi 1105 00:48:19,190 --> 00:48:23,610 che sono vulnerabili allo stesso modo, oserei dire, lui o lei può in ultima analisi, eliminare tutti 1106 00:48:23,610 --> 00:48:26,680 i file sul mio hard disk, ottengono un lampeggiante rapida in modo che lui o lei può 1107 00:48:26,680 --> 00:48:30,170 digitare i comandi per conto proprio, e-mail tutti i file a me. 1108 00:48:30,170 --> 00:48:34,660 Tutto ciò che posso fare, ha o lei può fare con questo codice. 1109 00:48:34,660 --> 00:48:36,575 >> Non abbastanza risolverà questo ancora. 1110 00:48:36,575 --> 00:48:38,700 E in effetti, sta andando a coinvolgere un po 'di foto 1111 00:48:38,700 --> 00:48:41,470 come questo, di cui parleremo presto per capire tutto il meglio. 1112 00:48:41,470 --> 00:48:44,480 Ma per oggi, finiamo su ciò che è, si spera, un po 'più 1113 00:48:44,480 --> 00:48:48,360 comprensibile scherzo XKCD, fino a quando riprendiamo la prossima volta. 1114 00:48:48,360 --> 00:48:51,100 1115 00:48:51,100 --> 00:48:51,600 Bene. 1116 00:48:51,600 --> 00:48:53,446 Ci vediamo il Mercoledì. 1117 00:48:53,446 --> 00:48:54,754 >> [GIOCO MUSICA] 1118 00:48:54,754 --> 00:48:57,790 >> SPEAKER: E ora, profondo pensieri, da Daven Farnham. 1119 00:48:57,790 --> 00:49:00,890 1120 00:49:00,890 --> 00:49:04,770 La memoria è come saltare in un mucchio di foglie d'oro in un pomeriggio di Domenica. 1121 00:49:04,770 --> 00:49:09,000 Vento che soffia, lanciando la vostra hair-- oh, mi mancano i giorni when-- 1122 00:49:09,000 --> 00:49:11,100 1123 00:49:11,100 --> 00:49:12,650 >> [Risate] 1124 00:49:12,650 --> 00:49:13,750