1 00:00:00,000 --> 00:00:06,030 >> [RIPRODUZIONE DI BRANI MUSICALI] 2 00:00:06,030 --> 00:00:08,390 >> DOUG LLOYD: puntatori, eccoci qui. 3 00:00:08,390 --> 00:00:11,080 Questo è probabilmente andando a essere l'argomento più difficile 4 00:00:11,080 --> 00:00:12,840 che si parla in CS50. 5 00:00:12,840 --> 00:00:15,060 E se avete letto nulla di puntatori 6 00:00:15,060 --> 00:00:19,080 prima si potrebbe essere un po ' intimidatorio andando in questo video. 7 00:00:19,080 --> 00:00:21,260 E 'vero i puntatori Sei consentire la possibilità 8 00:00:21,260 --> 00:00:23,740 a vite forse fino piuttosto male quando sei 9 00:00:23,740 --> 00:00:27,450 lavorare con variabili e dati, e causando il crash del programma. 10 00:00:27,450 --> 00:00:30,490 Ma sono in realtà davvero utile e ci ha davvero un ottimo modo permettono 11 00:00:30,490 --> 00:00:33,340 per passare i dati avanti e indietro tra le funzioni, 12 00:00:33,340 --> 00:00:35,490 che siamo comunque in grado di fare. 13 00:00:35,490 --> 00:00:37,750 >> E così ciò che realmente vuole fare qui è il treno 14 00:00:37,750 --> 00:00:41,060 di avere un buon indicatore disciplina, così che è possibile utilizzare in modo efficace i puntatori 15 00:00:41,060 --> 00:00:43,850 per rendere i vostri programmi che molto meglio. 16 00:00:43,850 --> 00:00:48,220 Come ho detto puntatori ci danno un diverso modo per passare i dati tra le funzioni. 17 00:00:48,220 --> 00:00:50,270 Ora, se vi ricordate da un video di prima, quando 18 00:00:50,270 --> 00:00:53,720 stavamo parlando portata variabile, ho detto 19 00:00:53,720 --> 00:01:00,610 che tutti i dati che si passa tra funzioni in C sono passati per valore. 20 00:01:00,610 --> 00:01:03,070 E io non ho usato che termine, quello che volevo dire lì 21 00:01:03,070 --> 00:01:07,170 era che stiamo passando copie di dati. 22 00:01:07,170 --> 00:01:12,252 Quando si passa una variabile a una funzione, non stiamo realmente passando la variabile 23 00:01:12,252 --> 00:01:13,210 alla funzione, giusto? 24 00:01:13,210 --> 00:01:17,670 Stiamo passando una copia che i dati alla funzione. 25 00:01:17,670 --> 00:01:20,760 La funzione fa quello che vuole e calcola un valore, 26 00:01:20,760 --> 00:01:23,180 e forse usiamo quel valore quando dà indietro. 27 00:01:23,180 --> 00:01:26,700 >> C'era una sola eccezione a questa regola di passaggio per valore, 28 00:01:26,700 --> 00:01:31,210 e torneremo a quello che è un po 'più avanti in questo video. 29 00:01:31,210 --> 00:01:34,880 Se usiamo puntatori invece di utilizzo di variabili, 30 00:01:34,880 --> 00:01:38,180 o invece di utilizzare le variabili stessi o copie delle variabili, 31 00:01:38,180 --> 00:01:43,790 ora siamo in grado di passare le variabili intorno tra le funzioni in un modo diverso. 32 00:01:43,790 --> 00:01:46,550 Ciò significa che se facciamo un cambiamento in una funzione, 33 00:01:46,550 --> 00:01:49,827 che il cambiamento avrà effettivamente effettuare in una funzione diversa. 34 00:01:49,827 --> 00:01:52,160 Di nuovo, questo è qualcosa che non abbiamo potuto fare in precedenza, 35 00:01:52,160 --> 00:01:56,979 e se avete mai provato a scambiare il valore delle due variabili in una funzione, 36 00:01:56,979 --> 00:01:59,270 hai notato questo problema sorta di strisciante, giusto? 37 00:01:59,270 --> 00:02:04,340 >> Se vogliamo scambiare X e Y, e passarli a una funzione chiamata di swap, 38 00:02:04,340 --> 00:02:08,680 all'interno della funzione scambiare la variabili fanno valori di scambio. 39 00:02:08,680 --> 00:02:12,600 Si diventa due, due diventa uno, ma non lo facciamo davvero 40 00:02:12,600 --> 00:02:16,890 cambiare nulla in originale funzione, con il chiamante. 41 00:02:16,890 --> 00:02:19,550 Perché non possiamo, siamo solo lavorare con copie di essi. 42 00:02:19,550 --> 00:02:24,760 Con i puntatori, però, possiamo in realtà passare X e Y di una funzione. 43 00:02:24,760 --> 00:02:26,960 Tale funzione può fare qualcosa con loro. 44 00:02:26,960 --> 00:02:29,250 E quei valori variabili può effettivamente cambiare. 45 00:02:29,250 --> 00:02:33,710 Ecco, questo è un bel cambiamento di la nostra capacità di lavorare con i dati. 46 00:02:33,710 --> 00:02:36,100 >> Prima di tuffarsi in puntatori, penso che valga la pena 47 00:02:36,100 --> 00:02:38,580 prendendo pochi minuti tornare alle origini qui. 48 00:02:38,580 --> 00:02:41,000 E dare un'occhiata a come lavori di memoria per computer 49 00:02:41,000 --> 00:02:45,340 perché questi due soggetti sono in corso di essere in realtà piuttosto interconnessi. 50 00:02:45,340 --> 00:02:48,480 Come probabilmente sapete, sul vostro sistema informatico 51 00:02:48,480 --> 00:02:51,310 si dispone di un disco rigido o forse un disco a stato solido, 52 00:02:51,310 --> 00:02:54,430 una sorta di percorso di archiviazione di file. 53 00:02:54,430 --> 00:02:57,950 Di solito è in qualche parte del quartiere di 250 gigabyte 54 00:02:57,950 --> 00:02:59,810 per forse un paio di terabyte ora. 55 00:02:59,810 --> 00:03:02,270 Ed è dove tutti i tuoi file in ultima analisi dal vivo, 56 00:03:02,270 --> 00:03:04,870 anche quando il computer è spento disattivata, è possibile riattivarla 57 00:03:04,870 --> 00:03:09,190 e troverete i file sono lì di nuovo quando si riavvia il sistema. 58 00:03:09,190 --> 00:03:14,820 Ma le unità disco, come un disco rigido, un HDD o un disco a stato solido, un SSD, 59 00:03:14,820 --> 00:03:16,050 sono solo lo spazio di archiviazione. 60 00:03:16,050 --> 00:03:20,400 >> Non possiamo effettivamente fare nulla con i dati che sono in hard disk, 61 00:03:20,400 --> 00:03:22,080 o in un disco a stato solido. 62 00:03:22,080 --> 00:03:24,950 Per cambiare effettivamente dati o spostarla, 63 00:03:24,950 --> 00:03:28,800 dobbiamo spostarlo RAM, memoria ad accesso casuale. 64 00:03:28,800 --> 00:03:31,170 Ora RAM, hai un sacco meno di un computer. 65 00:03:31,170 --> 00:03:34,185 Si può avere da qualche parte nel quartiere di 512 megabyte 66 00:03:34,185 --> 00:03:38,850 se si dispone di un vecchio computer, a forse due, quattro, otto, 16, 67 00:03:38,850 --> 00:03:41,820 forse anche un po ' di più, gigabyte di RAM. 68 00:03:41,820 --> 00:03:46,390 Ecco, questo è molto più piccolo, ma questo è dove tutti i dati volatili esiste. 69 00:03:46,390 --> 00:03:48,270 Ecco dove siamo in grado di cambiare le cose. 70 00:03:48,270 --> 00:03:53,350 Ma quando ci rivolgiamo il nostro computer spento, tutti i dati nella RAM viene distrutto. 71 00:03:53,350 --> 00:03:57,150 >> Ecco perché abbiamo bisogno di hard disk per la posizione più permanente di esso, 72 00:03:57,150 --> 00:03:59,720 in modo che exists- sarebbe essere davvero male se ogni volta che 73 00:03:59,720 --> 00:04:03,310 trasformato il nostro computer spento, ogni il file nel nostro sistema è stato cancellato. 74 00:04:03,310 --> 00:04:05,600 Quindi lavoriamo all'interno di RAM. 75 00:04:05,600 --> 00:04:09,210 E ogni volta che stiamo parlando di la memoria, più o meno, a CS50, 76 00:04:09,210 --> 00:04:15,080 stiamo parlando di RAM, disco rigido non. 77 00:04:15,080 --> 00:04:18,657 >> Così, quando ci muoviamo le cose in memoria, occupa un certo spazio. 78 00:04:18,657 --> 00:04:20,740 Tutti i tipi di dati abbiamo lavorato con 79 00:04:20,740 --> 00:04:23,480 prendere diverso quantità di spazio nella RAM. 80 00:04:23,480 --> 00:04:27,600 Così ogni volta che si crea un intero variabili, quattro byte di memoria 81 00:04:27,600 --> 00:04:30,750 sono accantonati in RAM in modo da può lavorare con quello intero. 82 00:04:30,750 --> 00:04:34,260 È possibile dichiarare il numero intero, cambiarlo, assegnarla 83 00:04:34,260 --> 00:04:36,700 ad un valore 10 incrementato per uno, così via e così via. 84 00:04:36,700 --> 00:04:39,440 Tutto ciò che deve accadere in RAM, e si ottiene quattro byte 85 00:04:39,440 --> 00:04:42,550 lavorare per ogni numero intero che si crea. 86 00:04:42,550 --> 00:04:45,410 >> Ogni personaggio si creare ottiene un byte. 87 00:04:45,410 --> 00:04:48,160 Questo è solo la quantità di spazio necessaria per memorizzare un carattere. 88 00:04:48,160 --> 00:04:51,310 Ogni galleggiante, un vero e proprio numero, ottiene quattro byte 89 00:04:51,310 --> 00:04:53,390 a meno che non si tratta di un doppio virgola mobile di precisione 90 00:04:53,390 --> 00:04:56,510 numero, che consente di avere cifre più precise o più 91 00:04:56,510 --> 00:04:59,300 dopo la virgola senza perdere di precisione, 92 00:04:59,300 --> 00:05:01,820 che prendono otto byte di memoria. 93 00:05:01,820 --> 00:05:06,730 Anela lunghe, davvero grande interi, anche prendere otto byte di memoria. 94 00:05:06,730 --> 00:05:09,000 Quanti byte di memoria si stringhe occupano? 95 00:05:09,000 --> 00:05:12,990 Beh diciamo mettere uno spillo a questa domanda per ora, ma torneremo ad esso. 96 00:05:12,990 --> 00:05:17,350 >> Ma torniamo a questa idea della memoria come una grande matrice di celle byte dimensioni. 97 00:05:17,350 --> 00:05:20,871 Questo è davvero tutto ciò che è, è solo una vasta gamma di celle, 98 00:05:20,871 --> 00:05:23,370 proprio come qualsiasi altro array si ha familiarità con e vedere, 99 00:05:23,370 --> 00:05:26,430 salvo ogni elemento è largo un byte. 100 00:05:26,430 --> 00:05:30,030 E proprio come un array, ogni elemento ha un indirizzo. 101 00:05:30,030 --> 00:05:32,120 Ogni elemento di un array ha un indice, e 102 00:05:32,120 --> 00:05:36,302 può utilizzare tale indice per fare cosiddetto accesso casuale sull'array. 103 00:05:36,302 --> 00:05:38,510 Non abbiamo iniziare a l'inizio della matrice, 104 00:05:38,510 --> 00:05:40,569 scorrere ogni unico elemento della stessa, 105 00:05:40,569 --> 00:05:41,860 per trovare quello che stiamo cercando. 106 00:05:41,860 --> 00:05:45,790 Possiamo solo dire, voglio arrivare al 15 ° elemento o l'elemento 100. 107 00:05:45,790 --> 00:05:49,930 E si può solo passare a quel numero e ottenere il valore che stai cercando. 108 00:05:49,930 --> 00:05:54,460 >> Allo stesso modo ogni posizione nella memoria ha un indirizzo. 109 00:05:54,460 --> 00:05:57,320 Così la memoria potrebbe simile a questo. 110 00:05:57,320 --> 00:06:01,420 Ecco un piccolo pezzo di memoria, questo è di 20 byte di memoria. 111 00:06:01,420 --> 00:06:04,060 I primi 20 byte perché il mio affronta lì in fondo 112 00:06:04,060 --> 00:06:08,890 sono 0, 1, 2, 3, e così su tutto il percorso fino a 19. 113 00:06:08,890 --> 00:06:13,190 E quando mi dichiaro variabili e quando inizio a lavorare con loro, 114 00:06:13,190 --> 00:06:15,470 il sistema sta per impostare a parte un pò di spazio per me 115 00:06:15,470 --> 00:06:17,595 in questa memoria di lavoro con le mie variabili. 116 00:06:17,595 --> 00:06:21,610 Quindi potrei dire, char c è uguale a capitale H. E che cosa succederà? 117 00:06:21,610 --> 00:06:23,880 Beh, il sistema sta andando a mettere da parte per me un byte. 118 00:06:23,880 --> 00:06:27,870 In questo caso ha scelto il numero di byte quattro, il byte all'indirizzo quattro, 119 00:06:27,870 --> 00:06:31,310 e sta andando a memorizzare il lettera H maiuscola in là per me. 120 00:06:31,310 --> 00:06:34,350 Se allora io dico velocità int limite uguale 65, è 121 00:06:34,350 --> 00:06:36,806 andando a mettere da parte quattro byte di memoria per me. 122 00:06:36,806 --> 00:06:39,180 E sta andando a trattare quelli quattro byte come una singola unità 123 00:06:39,180 --> 00:06:41,305 perché ciò che stiamo lavorando con è un intero qui. 124 00:06:41,305 --> 00:06:44,350 E sta andando a memorizzare 65 in là. 125 00:06:44,350 --> 00:06:47,000 >> Ora già Sono un po ' che ti dice un po 'di una bugia, 126 00:06:47,000 --> 00:06:50,150 a destra, perché sappiamo che computer lavorano in binario. 127 00:06:50,150 --> 00:06:53,100 Non capiscono necessariamente quello che un capitale H è 128 00:06:53,100 --> 00:06:57,110 o quello che un 65 è, ma solo capire binari, zero e uno. 129 00:06:57,110 --> 00:06:59,000 E così in realtà ciò che stiamo memorizzazione in là 130 00:06:59,000 --> 00:07:03,450 non è la lettera H e il numero 65, ma piuttosto la rappresentazione binaria 131 00:07:03,450 --> 00:07:06,980 dello stesso, che guarda un po 'di qualcosa di simile. 132 00:07:06,980 --> 00:07:10,360 Ed in particolare nel contesto della variabile intera, 133 00:07:10,360 --> 00:07:13,559 non sta andando a sputare solo in, non sta andando a trattarlo come un quattro 134 00:07:13,559 --> 00:07:15,350 Byte pezzo necessariamente, in realtà è in corso 135 00:07:15,350 --> 00:07:19,570 di trattarlo come un quattro blocchi di byte, che potrebbe essere simile a questa. 136 00:07:19,570 --> 00:07:22,424 E anche questo non è tutto vero o, 137 00:07:22,424 --> 00:07:24,840 a causa di qualcosa chiamato un endianness, che non siamo 138 00:07:24,840 --> 00:07:26,965 intenzione di entrare in ora, ma se siete curiosi di sapere, 139 00:07:26,965 --> 00:07:29,030 si può leggere su poco e grande endianness. 140 00:07:29,030 --> 00:07:31,640 Ma per il bene di questo argomento, per il bene di questo video, 141 00:07:31,640 --> 00:07:34,860 facciamo solo supporre che è, in Infatti, come il numero 65 sarebbe 142 00:07:34,860 --> 00:07:36,970 essere rappresentato in memoria su ogni sistema, 143 00:07:36,970 --> 00:07:38,850 anche se non è del tutto vero. 144 00:07:38,850 --> 00:07:41,700 >> Ma andiamo in realtà solo get liberarsi di tutti binario del tutto, 145 00:07:41,700 --> 00:07:44,460 e basta pensare a come H e 65, è molto più facile 146 00:07:44,460 --> 00:07:47,900 a pensarci come che come un essere umano. 147 00:07:47,900 --> 00:07:51,420 Va bene, così sembra anche forse un poco casuali che I've- mio sistema 148 00:07:51,420 --> 00:07:55,130 non mi ha dato byte 5, 6, 7, e 8 per memorizzare il numero intero. 149 00:07:55,130 --> 00:07:58,580 C'è una ragione per questo, anche, che non otterremo in questo momento, ma è sufficiente 150 00:07:58,580 --> 00:08:00,496 per dire che ciò che la computer sta facendo qui 151 00:08:00,496 --> 00:08:02,810 è probabilmente una buona mossa da parte sua. 152 00:08:02,810 --> 00:08:06,020 Per non mi danno la memoria che è necessariamente back to back. 153 00:08:06,020 --> 00:08:10,490 Anche se è intenzione di farlo ora se voglio ottenere un'altra stringa, 154 00:08:10,490 --> 00:08:13,080 Chiamai il cognome, e voglio mettere Lloyd in là. 155 00:08:13,080 --> 00:08:18,360 Ho intenzione di bisogno di montare uno carattere, ogni lettera che è 156 00:08:18,360 --> 00:08:21,330 andare a richiedere un carattere, un byte di memoria. 157 00:08:21,330 --> 00:08:26,230 Quindi, se ho potuto mettere Lloyd nella mia matrice come questo sono abbastanza bravo per andare, giusto? 158 00:08:26,230 --> 00:08:28,870 Cosa manca? 159 00:08:28,870 --> 00:08:31,840 >> Ricordate che ogni corda lavoriamo con in C termina con backslash pari a zero, 160 00:08:31,840 --> 00:08:33,339 e non possiamo omettere che qui, sia. 161 00:08:33,339 --> 00:08:36,090 Abbiamo bisogno di mettere da parte un byte di memoria per contenere che così noi 162 00:08:36,090 --> 00:08:39,130 sapere quando la nostra stringa è terminato. 163 00:08:39,130 --> 00:08:41,049 Quindi, di nuovo questa disposizione di come le cose 164 00:08:41,049 --> 00:08:42,799 comparire in memoria potrebbe essere un po 'casuale, 165 00:08:42,799 --> 00:08:44,870 ma in realtà è come la maggior parte dei sistemi sono progettati. 166 00:08:44,870 --> 00:08:48,330 Per allinearli su multipli di quattro, per ragioni di nuovo 167 00:08:48,330 --> 00:08:50,080 che non abbiamo bisogno di entrare in questo momento. 168 00:08:50,080 --> 00:08:53,060 Ma questo, quindi basti dire che dopo queste tre righe di codice, 169 00:08:53,060 --> 00:08:54,810 questo è ciò che la memoria potrebbe essere simile. 170 00:08:54,810 --> 00:08:58,930 Se ho bisogno di locazioni di memoria 4, 8, e 12 per tenere i miei dati, 171 00:08:58,930 --> 00:09:01,100 questo è ciò che la mia memoria potrebbe essere simile. 172 00:09:01,100 --> 00:09:04,062 >> E proprio essere particolarmente pedante qui, quando 173 00:09:04,062 --> 00:09:06,020 stiamo parlando di memoria indirizzi Noi di solito 174 00:09:06,020 --> 00:09:08,390 farlo utilizzando notazioni esadecimali. 175 00:09:08,390 --> 00:09:12,030 Allora perché non ci si converte tutti questi da decimale in esadecimale 176 00:09:12,030 --> 00:09:15,010 proprio perché è generalmente Come ci si riferisce alla memoria. 177 00:09:15,010 --> 00:09:17,880 Così, invece di essere da 0 a 19, quello che abbiamo è pari a zero 178 00:09:17,880 --> 00:09:20,340 x zero a tre a zero x1. 179 00:09:20,340 --> 00:09:23,790 Questi sono i 20 byte di memoria che abbiamo abbiamo o stiamo guardando in questa immagine 180 00:09:23,790 --> 00:09:25,540 giusto qui. 181 00:09:25,540 --> 00:09:29,310 >> Quindi, tutto ciò che viene detto, cerchiamo di allontanarsi dalla memoria per un secondo 182 00:09:29,310 --> 00:09:30,490 e di nuovo a puntatori. 183 00:09:30,490 --> 00:09:32,420 Qui è il più importante cosa da ricordare 184 00:09:32,420 --> 00:09:34,070 , come si comincia a lavorare con i puntatori. 185 00:09:34,070 --> 00:09:36,314 Un puntatore è nulla più di un indirizzo. 186 00:09:36,314 --> 00:09:38,230 Io dirò di nuovo perché è così importante, 187 00:09:38,230 --> 00:09:42,730 un puntatore è nulla più di un indirizzo. 188 00:09:42,730 --> 00:09:47,760 I puntatori sono indirizzi alle posizioni in memoria in cui le variabili vivono. 189 00:09:47,760 --> 00:09:52,590 Sapendo che diventa spera, un po 'più facile lavorare con loro. 190 00:09:52,590 --> 00:09:54,550 Un'altra cosa che mi piace di fare è di avere sorta 191 00:09:54,550 --> 00:09:58,510 di diagrammi che rappresentano visivamente ciò che è accadendo con varie linee di codice. 192 00:09:58,510 --> 00:10:00,660 E faremo questo un paio di volte in puntatori, 193 00:10:00,660 --> 00:10:03,354 e quando si parla di dinamica allocazione memoria. 194 00:10:03,354 --> 00:10:06,020 Perché penso che questi diagrammi può essere particolarmente utile. 195 00:10:06,020 --> 00:10:09,540 >> Quindi, se io dico, per esempio, int k nel mio codice, cosa sta succedendo? 196 00:10:09,540 --> 00:10:12,524 Beh, quello che sta accadendo è fondamentalmente Sto diventando memoria riservata per me, 197 00:10:12,524 --> 00:10:14,690 ma non ho neanche piace penso così, io 198 00:10:14,690 --> 00:10:16,300 piace pensare a questo proposito come una scatola. 199 00:10:16,300 --> 00:10:20,090 Ho una scatola ed è di colore verde perché io 200 00:10:20,090 --> 00:10:21,750 può mettere interi in scatole verdi. 201 00:10:21,750 --> 00:10:23,666 Se fosse un personaggio che potrebbe avere una scatola blu. 202 00:10:23,666 --> 00:10:27,290 Ma io dico sempre, se sto creando una scatola che può contenere interi 203 00:10:27,290 --> 00:10:28,950 quella casella è colorata di verde. 204 00:10:28,950 --> 00:10:33,020 E mi prendo un pennarello indelebile e scrivo k sul lato di essa. 205 00:10:33,020 --> 00:10:37,590 Così ho un box chiamato k, in cui posso mettere interi. 206 00:10:37,590 --> 00:10:41,070 Quindi, quando dico int k, che è ciò che accade nella mia testa. 207 00:10:41,070 --> 00:10:43,140 Se dico k è uguale a cinque, che cosa sto facendo? 208 00:10:43,140 --> 00:10:45,110 Beh, sto mettendo cinque nella casella, a destra. 209 00:10:45,110 --> 00:10:48,670 Questo è abbastanza semplice, se Dico int k, creare una casella denominata k. 210 00:10:48,670 --> 00:10:52,040 Se dico k è uguale a 5, mettere cinque nella scatola. 211 00:10:52,040 --> 00:10:53,865 Speriamo che non sia troppo di un salto. 212 00:10:53,865 --> 00:10:55,990 Qui è dove le cose vanno un poco interessante però. 213 00:10:55,990 --> 00:11:02,590 Se dico int * pk, bene anche se non lo faccio sa che cosa questo significa necessariamente, 214 00:11:02,590 --> 00:11:06,150 è chiaramente ha qualcosa a che fare con un numero intero. 215 00:11:06,150 --> 00:11:08,211 Quindi ho intenzione di colorare questo scatola verde-ish, 216 00:11:08,211 --> 00:11:10,210 Lo so che ha qualcosa a che fare con un numero intero, 217 00:11:10,210 --> 00:11:13,400 ma non è un numero intero sé, perché è un int stella. 218 00:11:13,400 --> 00:11:15,390 C'è qualcosa di un po ' diverso su di esso. 219 00:11:15,390 --> 00:11:17,620 Così coinvolto di un numero intero, ma per il resto è 220 00:11:17,620 --> 00:11:19,830 non troppo diversa da cosa stavamo parlando. 221 00:11:19,830 --> 00:11:24,240 Si tratta di una scatola, la sua ha una etichetta, si indossa una pk un'etichetta, 222 00:11:24,240 --> 00:11:27,280 ed è capace di partecipazione Stelle INT, qualunque essi siano. 223 00:11:27,280 --> 00:11:29,894 Essi hanno qualcosa a che fare con numeri interi, chiaramente. 224 00:11:29,894 --> 00:11:31,060 Ecco l'ultima riga però. 225 00:11:31,060 --> 00:11:37,650 Se dico pk = & k, whoa, cosa è successo, giusto? 226 00:11:37,650 --> 00:11:41,820 Quindi questo numero casuale, apparentemente casuale numero, si butta nella casella di lì. 227 00:11:41,820 --> 00:11:44,930 Tutto ciò che è, è pk ottiene l'indirizzo di k. 228 00:11:44,930 --> 00:11:52,867 Così sto attaccando dove k vive nella memoria, il suo indirizzo, l'indirizzo della sua byte. 229 00:11:52,867 --> 00:11:55,200 Tutto quello che sto facendo è che sto dicendo tale valore è quello che ho intenzione 230 00:11:55,200 --> 00:11:59,430 a mettere dentro la mia scatola chiamato pk. 231 00:11:59,430 --> 00:12:02,080 E perché queste cose sono puntatori, e perché guardando 232 00:12:02,080 --> 00:12:04,955 in una stringa come pari a zero x otto a zero c sette quattro otto 233 00:12:04,955 --> 00:12:07,790 due zero è probabilmente non molto significativo. 234 00:12:07,790 --> 00:12:12,390 Quando abbiamo generalmente visualizziamo puntatori, abbiamo effettivamente facciamo come puntatori. 235 00:12:12,390 --> 00:12:17,000 Pk ci dà le informazioni abbiamo bisogno di trovare k in memoria. 236 00:12:17,000 --> 00:12:19,120 Quindi, fondamentalmente pk ha una freccia in esso. 237 00:12:19,120 --> 00:12:21,670 E se camminiamo la lunghezza di quella freccia, immaginare 238 00:12:21,670 --> 00:12:25,280 è qualcosa che si può camminare su, se si camminare lungo la lunghezza della freccia, 239 00:12:25,280 --> 00:12:29,490 sulla punta estrema di quella freccia, abbiamo troverà la posizione nella memoria 240 00:12:29,490 --> 00:12:31,390 dove k vive. 241 00:12:31,390 --> 00:12:34,360 E questo è davvero importante perché una volta che sappiamo dove abita k, 242 00:12:34,360 --> 00:12:37,870 possiamo iniziare a lavorare con i dati all'interno di tale posizione di memoria. 243 00:12:37,870 --> 00:12:40,780 Anche se stiamo ottenendo un teeny bit avanti di noi stessi, per ora. 244 00:12:40,780 --> 00:12:42,240 >> Così che cosa è un puntatore? 245 00:12:42,240 --> 00:12:45,590 Un puntatore è un elemento di dati il ​​cui valore è un indirizzo di memoria. 246 00:12:45,590 --> 00:12:49,740 Quello era che lo zero x otto roba a zero in corso, che è stato un indirizzo di memoria. 247 00:12:49,740 --> 00:12:52,060 E 'stata una locazione di memoria. 248 00:12:52,060 --> 00:12:55,080 E il tipo di un puntatore descrive il tipo 249 00:12:55,080 --> 00:12:56,930 dei dati troverai a quell'indirizzo di memoria. 250 00:12:56,930 --> 00:12:58,810 Quindi c'è la parte destra int stella. 251 00:12:58,810 --> 00:13:03,690 Se seguo quella freccia, è andando a mi portano a una posizione. 252 00:13:03,690 --> 00:13:06,980 E quella posizione, quello che ho troveranno lì nel mio esempio, 253 00:13:06,980 --> 00:13:08,240 è una scatola di colore verde. 254 00:13:08,240 --> 00:13:12,650 Si tratta di un numero intero, questo è quello che troveranno se vado a tale indirizzo. 255 00:13:12,650 --> 00:13:14,830 Il tipo di dati di un puntatore descrive cosa 256 00:13:14,830 --> 00:13:17,936 troverete a questo indirizzo di memoria. 257 00:13:17,936 --> 00:13:19,560 Quindi, ecco la cosa veramente interessante comunque. 258 00:13:19,560 --> 00:13:25,090 Puntatori ci permettono di passare variabili tra funzioni. 259 00:13:25,090 --> 00:13:28,520 E in realtà passare variabili e non passare copie di essi. 260 00:13:28,520 --> 00:13:32,879 Perché se sappiamo esattamente dove in memoria per trovare una variabile, 261 00:13:32,879 --> 00:13:35,670 non abbiamo bisogno di fare una copia di esso, possiamo solo andare in quella posizione 262 00:13:35,670 --> 00:13:37,844 e lavorare con quella variabile. 263 00:13:37,844 --> 00:13:40,260 Quindi, in puntatori essenza sorta di rendere un ambiente informatico 264 00:13:40,260 --> 00:13:42,360 molto più simile al mondo reale, a destra. 265 00:13:42,360 --> 00:13:44,640 >> Quindi, ecco un'analogia. 266 00:13:44,640 --> 00:13:48,080 Diciamo che ho un quaderno, a destra, ed è pieno di note. 267 00:13:48,080 --> 00:13:50,230 E mi piacerebbe che aggiorna. 268 00:13:50,230 --> 00:13:53,960 Tu sei una funzione che aggiorna le note, a destra. 269 00:13:53,960 --> 00:13:56,390 Nel modo in cui siamo stati lavorando finora, cosa 270 00:13:56,390 --> 00:14:02,370 succede è si prende il mio notebook, andrai al negozio di copia, 271 00:14:02,370 --> 00:14:06,410 potrai fare una copia di Xerox ogni pagina del notebook. 272 00:14:06,410 --> 00:14:09,790 Lascerai mio notebook schiena sulla mia scrivania quando hai finito, 273 00:14:09,790 --> 00:14:14,600 andrai e attraversare le cose nella mia notebook che non sono aggiornati o sbagliato, 274 00:14:14,600 --> 00:14:19,280 e poi si passa di nuovo a me la pila di pagine Xerox 275 00:14:19,280 --> 00:14:22,850 che è una replica del mio notebook con le modifiche apportate ad esso. 276 00:14:22,850 --> 00:14:27,040 E a quel punto, tocca a me come la funzione di chiamata, come il chiamante, 277 00:14:27,040 --> 00:14:30,582 a decidere di prendere le note e integrarli di nuovo nel mio taccuino. 278 00:14:30,582 --> 00:14:32,540 Quindi c'è un sacco di passi questione qui, a destra. 279 00:14:32,540 --> 00:14:34,850 Come non sarebbe meglio se mi limito a dire, ehi, si può 280 00:14:34,850 --> 00:14:38,370 aggiornare il mio notebook per me, consegno il mio notebook, 281 00:14:38,370 --> 00:14:40,440 e si prendono le cose e letteralmente barrare 282 00:14:40,440 --> 00:14:42,810 e aggiornare i miei appunti sul mio taccuino. 283 00:14:42,810 --> 00:14:45,140 E poi mi danno il mio notebook schiena. 284 00:14:45,140 --> 00:14:47,320 Questo è il genere di cosa puntatori consentono di fare, 285 00:14:47,320 --> 00:14:51,320 rendono questo ambiente un sacco più simile a come operiamo nella realtà. 286 00:14:51,320 --> 00:14:54,640 >> Va bene così questo è quello che un puntatore si, parliamo 287 00:14:54,640 --> 00:14:58,040 di come funzionano i puntatori in C, e come possiamo iniziare a lavorare con loro. 288 00:14:58,040 --> 00:15:02,550 Quindi c'è un semplice puntatore in C chiamata puntatore nullo. 289 00:15:02,550 --> 00:15:04,830 Il puntatore punti nulli a niente. 290 00:15:04,830 --> 00:15:08,310 Questo probabilmente sembra come se fosse in realtà non è una cosa molto utile, 291 00:15:08,310 --> 00:15:10,500 ma come vedremo un poco più tardi, il fatto 292 00:15:10,500 --> 00:15:15,410 che questo puntatore nullo esiste in realtà può davvero tornare utile. 293 00:15:15,410 --> 00:15:19,090 E ogni volta che si crea un puntatore, e non si imposta il suo valore immediatamente: 294 00:15:19,090 --> 00:15:21,060 un esempio di impostazione il suo valore subito 295 00:15:21,060 --> 00:15:25,401 sarà un paio di scivoli indietro dove ho detto pk uguale a & k, 296 00:15:25,401 --> 00:15:28,740 pk ottiene l'indirizzo di k, come vedremo che cosa significa, 297 00:15:28,740 --> 00:15:32,990 vedremo come codificare che shortly- se non fissiamo il suo valore a qualcosa 298 00:15:32,990 --> 00:15:35,380 significativo subito, si dovrebbe sempre 299 00:15:35,380 --> 00:15:37,480 impostare il puntatore per puntare a null. 300 00:15:37,480 --> 00:15:40,260 Si dovrebbe impostare per puntare a nulla. 301 00:15:40,260 --> 00:15:43,614 >> Questo è molto diverso da quello lasciando solo il valore così com'è 302 00:15:43,614 --> 00:15:45,530 e poi dichiarare un puntatore e solo assumendo 303 00:15:45,530 --> 00:15:48,042 è nullo perché è raramente vero. 304 00:15:48,042 --> 00:15:50,000 Per questo si deve sempre impostare il valore di un puntatore 305 00:15:50,000 --> 00:15:55,690 null se non si imposta il suo valore a qualcosa di significativo immediatamente. 306 00:15:55,690 --> 00:15:59,090 È possibile controllare se il valore di un puntatore è nullo utilizzando l'operatore di uguaglianza 307 00:15:59,090 --> 00:16:05,450 (==), Proprio come si confronta qualsiasi intero valori o valori di carattere che utilizzano (==) 308 00:16:05,450 --> 00:16:06,320 anche. 309 00:16:06,320 --> 00:16:10,994 Si tratta di una specie particolare di costante valore che è possibile utilizzare per verificare. 310 00:16:10,994 --> 00:16:13,160 Così che era un molto semplice puntatore, il puntatore nullo. 311 00:16:13,160 --> 00:16:15,320 Un altro modo per creare un puntatore è quello di estrarre 312 00:16:15,320 --> 00:16:18,240 l'indirizzo di una variabile hai già creato, 313 00:16:18,240 --> 00:16:22,330 e si esegue questa operazione utilizzando il & Estrazione indirizzo dell'operatore. 314 00:16:22,330 --> 00:16:26,720 Che abbiamo già visto in precedenza nel primo esempio di schema ho mostrato. 315 00:16:26,720 --> 00:16:31,450 Quindi, se x è una variabile che abbiamo già creato di tipo intero, 316 00:16:31,450 --> 00:16:35,110 allora e x è un puntatore a un numero intero. 317 00:16:35,110 --> 00:16:39,810 & x è- ricordate, e sta per estrarre l'indirizzo della cosa sulla destra. 318 00:16:39,810 --> 00:16:45,350 E poiché un puntatore è solo un indirizzo, di & X è un puntatore ad un intero 319 00:16:45,350 --> 00:16:48,560 il cui valore è dove in memoria di x vite. 320 00:16:48,560 --> 00:16:50,460 E 'l'indirizzo di x. 321 00:16:50,460 --> 00:16:53,296 Così & x è l'indirizzo di x. 322 00:16:53,296 --> 00:16:55,670 Prendiamo questo un passo ulteriormente e connettersi a qualcosa 323 00:16:55,670 --> 00:16:58,380 Ho accennato in un video precedente. 324 00:16:58,380 --> 00:17:06,730 Se arr è un array di double, poi & parentesi quadra arr i è un puntatore 325 00:17:06,730 --> 00:17:08,109 in doppio. 326 00:17:08,109 --> 00:17:08,970 OK. 327 00:17:08,970 --> 00:17:12,160 arr parentesi quadra i, se arr è un array di doppio, 328 00:17:12,160 --> 00:17:19,069 poi arr parentesi quadra i è l'elemento i-esimo di tale matrice, 329 00:17:19,069 --> 00:17:29,270 e & arr parentesi quadra i è dove nel memoria l'elemento i-esimo arr esiste. 330 00:17:29,270 --> 00:17:31,790 >> Allora, qual è l'implicazione qui? 331 00:17:31,790 --> 00:17:34,570 Un nome array, l'implicazione di tutta questa faccenda, 332 00:17:34,570 --> 00:17:39,290 è che il nome di un array è in realtà esso stesso un puntatore. 333 00:17:39,290 --> 00:17:41,170 Hai lavorato con puntatori tutti lungo 334 00:17:41,170 --> 00:17:45,290 ogni volta che avete usato un array. 335 00:17:45,290 --> 00:17:49,090 Ricordate dall'esempio su scope delle variabili, 336 00:17:49,090 --> 00:17:53,420 verso la fine del video che presento un esempio in cui abbiamo una funzione 337 00:17:53,420 --> 00:17:56,890 chiamato int set e un funzione chiamata di matrice set. 338 00:17:56,890 --> 00:18:00,490 E la vostra sfida di determinare o meno, o che il 339 00:18:00,490 --> 00:18:03,220 valori che abbiamo stampato la fine della funzione, 340 00:18:03,220 --> 00:18:05,960 alla fine del programma principale. 341 00:18:05,960 --> 00:18:08,740 >> Se vi ricordate da quell'esempio o se hai guardato il video, 342 00:18:08,740 --> 00:18:13,080 si sa che quando la chiamata a te- set int non fa effettivamente nulla. 343 00:18:13,080 --> 00:18:16,390 Ma la chiamata per impostare matrice fa. 344 00:18:16,390 --> 00:18:19,280 E io sorta di sorvolato perché che era il caso al momento. 345 00:18:19,280 --> 00:18:22,363 Ho appena detto, beh è un array, è speciale, sapete, c'è una ragione. 346 00:18:22,363 --> 00:18:25,020 Il motivo è che una matrice di nome è in realtà solo un puntatore, 347 00:18:25,020 --> 00:18:28,740 e c'è questa speciale sintassi Parentesi quadra che 348 00:18:28,740 --> 00:18:30,510 rendere le cose molto più gradevole per lavorare. 349 00:18:30,510 --> 00:18:34,410 E fanno l'idea di un puntatore molto meno intimidatorio, 350 00:18:34,410 --> 00:18:36,800 ed è per questo che sono specie di presentato in quel modo. 351 00:18:36,800 --> 00:18:38,600 Ma in realtà gli array sono solo puntatori. 352 00:18:38,600 --> 00:18:41,580 Ed è per questo che quando ci fatto un cambiamento alla matrice, 353 00:18:41,580 --> 00:18:44,880 quando siamo passati un array come parametro ad una funzione o come argomento 354 00:18:44,880 --> 00:18:50,110 a una funzione, il contenuto della matrice effettivamente cambiato sia il chiamato 355 00:18:50,110 --> 00:18:51,160 e con il chiamante. 356 00:18:51,160 --> 00:18:55,846 Che per ogni altro tipo di variabili che abbiamo visto non era il caso. 357 00:18:55,846 --> 00:18:58,970 Ecco, questo è solo qualcosa da tenere a mente quando si lavora con i puntatori, 358 00:18:58,970 --> 00:19:01,610 è che il nome di un matrice in realtà un puntatore 359 00:19:01,610 --> 00:19:04,750 al primo elemento di tale matrice. 360 00:19:04,750 --> 00:19:08,930 >> OK, ora abbiamo tutto questi fatti, cerchiamo di andare avanti, a destra. 361 00:19:08,930 --> 00:19:11,370 Perché ci preoccupiamo per dove vive qualcosa. 362 00:19:11,370 --> 00:19:14,120 Beh, come ho detto, è piuttosto utile sapere dove abita qualcosa 363 00:19:14,120 --> 00:19:17,240 in modo da poter andare lì e di modificarlo. 364 00:19:17,240 --> 00:19:19,390 Lavora con esso e in realtà avere la cosa che voi 365 00:19:19,390 --> 00:19:23,710 vuole fare in tal senso prendere variabile, e non ha effetto su alcuni copia di esso. 366 00:19:23,710 --> 00:19:26,150 Questo si chiama dereferencing. 367 00:19:26,150 --> 00:19:28,690 Andiamo al riferimento e cambiamo il valore lì. 368 00:19:28,690 --> 00:19:32,660 Quindi, se abbiamo un puntatore e si chiama pc, e che punti a un personaggio, 369 00:19:32,660 --> 00:19:40,610 allora possiamo dire * * pc e pc è il nome di ciò che troveremo se andiamo 370 00:19:40,610 --> 00:19:42,910 al pc indirizzo. 371 00:19:42,910 --> 00:19:47,860 Che cosa troveremo c'è un personaggio e * pc è come ci si riferisce ai dati in quel 372 00:19:47,860 --> 00:19:48,880 posizione. 373 00:19:48,880 --> 00:19:54,150 Così potremmo dire qualcosa di simile * pc = D o qualcosa del genere, 374 00:19:54,150 --> 00:19:59,280 e ciò significa che qualunque era a indirizzo di memoria del pc, 375 00:19:59,280 --> 00:20:07,040 qualunque personaggio era in precedenza lì, è ora D, se diciamo * PC = D. 376 00:20:07,040 --> 00:20:10,090 >> Quindi qui si va di nuovo con qualche C cose strane, a destra. 377 00:20:10,090 --> 00:20:14,560 Così abbiamo visto in precedenza come * in qualche modo parte del tipo di dati, 378 00:20:14,560 --> 00:20:17,160 e ora è utilizzato in un contesto leggermente diverso 379 00:20:17,160 --> 00:20:19,605 per accedere ai dati in una posizione. 380 00:20:19,605 --> 00:20:22,480 Lo so che è un po 'di confusione e che in realtà è parte di questo tutto 381 00:20:22,480 --> 00:20:25,740 come, perché i puntatori hanno questa mitologia attorno a loro come essere così complessa, 382 00:20:25,740 --> 00:20:28,250 è una specie di un problema di sintassi, onestamente. 383 00:20:28,250 --> 00:20:31,810 Ma * è usato in entrambi i contesti, sia come parte del nome del tipo, 384 00:20:31,810 --> 00:20:34,100 e vedremo un po ' più tardi anche qualcos'altro. 385 00:20:34,100 --> 00:20:36,490 E proprio ora è il operatore dereference. 386 00:20:36,490 --> 00:20:38,760 Così va al riferimento, accede ai dati 387 00:20:38,760 --> 00:20:43,000 in corrispondenza della posizione del puntatore, e consente di manipolare a piacimento. 388 00:20:43,000 --> 00:20:45,900 >> Ora questo è molto simile a visita il tuo vicino di casa, a destra. 389 00:20:45,900 --> 00:20:48,710 Se si sa che cosa il vostro vicino di casa vive, sei 390 00:20:48,710 --> 00:20:50,730 non uscire con il vostro vicino di casa. 391 00:20:50,730 --> 00:20:53,510 Sai che capita di sapere dove vivono, 392 00:20:53,510 --> 00:20:56,870 ma ciò non significa che, virtù di avere quella conoscenza 393 00:20:56,870 --> 00:20:59,170 si interagisce con loro. 394 00:20:59,170 --> 00:21:01,920 Se si vuole interagire con loro, si deve andare a casa loro, 395 00:21:01,920 --> 00:21:03,760 si deve andare a dove vivono. 396 00:21:03,760 --> 00:21:07,440 E una volta fatto questo, allora si può interagire 397 00:21:07,440 --> 00:21:09,420 con loro proprio come si vorrebbe. 398 00:21:09,420 --> 00:21:12,730 E allo stesso modo con le variabili, avete bisogno di andare al loro indirizzo 399 00:21:12,730 --> 00:21:15,320 se si desidera interagire loro, non si può solo conoscere l'indirizzo. 400 00:21:15,320 --> 00:21:21,495 E il modo di andare per l'indirizzo è da usare *, l'operatore dereference. 401 00:21:21,495 --> 00:21:23,620 Cosa ne pensi succede se cerchiamo di risolvere il riferimento 402 00:21:23,620 --> 00:21:25,260 un puntatore il cui valore è nullo? 403 00:21:25,260 --> 00:21:28,470 Ricordiamo che il nulla puntatore punta a nulla. 404 00:21:28,470 --> 00:21:34,110 Quindi, se si cerca di risolvere il riferimento nulla o andare ad un indirizzo nulla, 405 00:21:34,110 --> 00:21:36,800 cosa pensi che succeda? 406 00:21:36,800 --> 00:21:39,630 Segmentazione Beh, se avete indovinato colpa, avreste ragione. 407 00:21:39,630 --> 00:21:41,390 Se si tenta di risolvere il riferimento un puntatore nullo, 408 00:21:41,390 --> 00:21:43,140 si soffre una segmentazione colpa. Ma aspetta, 409 00:21:43,140 --> 00:21:45,820 Non ti ho detto, che se non si sta andando 410 00:21:45,820 --> 00:21:49,220 per impostare il valore della vostra puntatore a qualcosa di significativo, 411 00:21:49,220 --> 00:21:51,000 si dovrebbe impostare a null? 412 00:21:51,000 --> 00:21:55,290 Ho fatto e in realtà la segmentazione colpa è una specie di buon comportamento. 413 00:21:55,290 --> 00:21:58,680 >> Avete mai dichiarato una variabile e non assegnato subito il suo valore? 414 00:21:58,680 --> 00:22:02,680 Quindi hai appena detto int x; non fare in realtà assegnarlo a nulla 415 00:22:02,680 --> 00:22:05,340 e poi in seguito nel codice, di stampare il valore di x, 416 00:22:05,340 --> 00:22:07,650 non avendo ancora assegnato a nulla. 417 00:22:07,650 --> 00:22:10,370 Spesso si otterrà pari a zero, ma a volte si 418 00:22:10,370 --> 00:22:15,000 potrebbe ottenere un po 'di numeri casuali, e non avete idea di dove venisse. 419 00:22:15,000 --> 00:22:16,750 Allo stesso modo è possibile le cose accadere con i puntatori. 420 00:22:16,750 --> 00:22:20,110 Quando si dichiara un puntatore int * pk per esempio, 421 00:22:20,110 --> 00:22:23,490 e non si assegna a un valore, si ottiene quattro byte per la memoria. 422 00:22:23,490 --> 00:22:25,950 Qualunque siano le quattro byte di memoria di sistema può 423 00:22:25,950 --> 00:22:28,970 scoprire che hanno un certo valore significativo. 424 00:22:28,970 --> 00:22:31,760 E ci sarebbe stato qualcosa di già lì che 425 00:22:31,760 --> 00:22:34,190 non è più necessario da un'altra la funzione, quindi basta avere 426 00:22:34,190 --> 00:22:35,900 qualsiasi dato era lì. 427 00:22:35,900 --> 00:22:40,570 >> Che cosa succede se si è tentato di fare dereference qualche indirizzo che non- c'erano 428 00:22:40,570 --> 00:22:43,410 già byte e informazioni lì, che è ora nel tuo puntatore. 429 00:22:43,410 --> 00:22:47,470 Se si tenta di risolvere il riferimento che il puntatore, si potrebbe essere pasticciano con una certa memoria 430 00:22:47,470 --> 00:22:49,390 che non si intendeva a pasticciare con tutto. 431 00:22:49,390 --> 00:22:51,639 E in effetti si poteva fare qualcosa di veramente devastante, 432 00:22:51,639 --> 00:22:54,880 come rompere un altro programma, o rompere un'altra funzione, 433 00:22:54,880 --> 00:22:58,289 o fare qualcosa di dannoso che non hai intenzione di fare a tutti. 434 00:22:58,289 --> 00:23:00,080 Ed ecco perché è in realtà una buona idea 435 00:23:00,080 --> 00:23:04,030 per impostare i puntatori a null se non li impostato su qualcosa di significativo. 436 00:23:04,030 --> 00:23:06,760 E 'probabilmente meglio a fine della giornata per il vostro programma 437 00:23:06,760 --> 00:23:09,840 crash poi per consentirle di operare qualcosa che le viti fino 438 00:23:09,840 --> 00:23:12,400 un altro programma o un'altra funzione. 439 00:23:12,400 --> 00:23:15,207 Questo comportamento è probabilmente ancora meno ideali che solo schiantarsi. 440 00:23:15,207 --> 00:23:17,040 Ed ecco perché è in realtà una buona abitudine 441 00:23:17,040 --> 00:23:20,920 per entrare in per impostare i puntatori null se non li imposta 442 00:23:20,920 --> 00:23:24,540 ad un valore significativo immediatamente, un valore che si sa 443 00:23:24,540 --> 00:23:27,260 e che si può tranquillamente il dereference. 444 00:23:27,260 --> 00:23:32,240 >> Così torniamo ora e dare un'occhiata la sintassi generale della situazione. 445 00:23:32,240 --> 00:23:37,400 Se dico int * p ;, quello che ho appena fatto? 446 00:23:37,400 --> 00:23:38,530 Quello che ho fatto è questo. 447 00:23:38,530 --> 00:23:43,290 Conosco il valore di p è un indirizzo perché tutti i puntatori sono solo 448 00:23:43,290 --> 00:23:44,660 indirizzi. 449 00:23:44,660 --> 00:23:47,750 Posso dereference p utilizzando l'operatore *. 450 00:23:47,750 --> 00:23:51,250 In questo contesto qui, per lo top richiamare il * è parte del tipo. 451 00:23:51,250 --> 00:23:53,510 Int * è il tipo di dati. 452 00:23:53,510 --> 00:23:56,150 Ma posso dereference p utilizzando l'operatore *, 453 00:23:56,150 --> 00:24:01,897 e se lo faccio, se vado a tale indirizzo, quello che posso trovare a questo indirizzo? 454 00:24:01,897 --> 00:24:02,855 Troverò un numero intero. 455 00:24:02,855 --> 00:24:05,910 Così int * p è fondamentalmente dicendo, p è un indirizzo. 456 00:24:05,910 --> 00:24:09,500 Posso dereference p e se Lo faccio, mi troverò un intero 457 00:24:09,500 --> 00:24:11,920 in tale posizione di memoria. 458 00:24:11,920 --> 00:24:14,260 >> OK, ho detto che c'era un altro cosa fastidiosa con le stelle 459 00:24:14,260 --> 00:24:17,060 e qui è dove che cosa fastidiosa con le stelle è. 460 00:24:17,060 --> 00:24:21,640 Avete mai provato a dichiarare più variabili dello stesso tipo 461 00:24:21,640 --> 00:24:24,409 sulla stessa riga di codice? 462 00:24:24,409 --> 00:24:27,700 Così, per un secondo, finta che la linea, il codice che in realtà ci ho in verde 463 00:24:27,700 --> 00:24:29,366 non c'è e si dice solo int x, y, z ;. 464 00:24:29,366 --> 00:24:31,634 465 00:24:31,634 --> 00:24:34,550 Cosa che sarebbe fare è effettivamente creare tre variabili intere per voi, 466 00:24:34,550 --> 00:24:36,930 uno chiamato x, uno chiamato y, e uno chiamato z. 467 00:24:36,930 --> 00:24:41,510 E 'un modo per farlo senza dover spaccare su tre linee. 468 00:24:41,510 --> 00:24:43,890 >> Qui è dove ottengono stelle fastidioso di nuovo, però, 469 00:24:43,890 --> 00:24:49,200 perché il * è in realtà parte sia il nome del tipo e parte 470 00:24:49,200 --> 00:24:50,320 del nome della variabile. 471 00:24:50,320 --> 00:24:56,430 E così, se io dico int * px, py, pz, quello che ho effettivamente ottenere è un puntatore ad un intero 472 00:24:56,430 --> 00:25:01,650 chiamato px e due interi, py e pz. 473 00:25:01,650 --> 00:25:04,950 E questo non è quello che è probabilmente vogliamo, che non va bene. 474 00:25:04,950 --> 00:25:09,290 >> Quindi, se voglio creare più puntatori sulla stessa linea, dello stesso tipo, 475 00:25:09,290 --> 00:25:12,140 e le stelle, quello che ho effettivamente bisogno a fare è dire int * pa, * pb, * pc. 476 00:25:12,140 --> 00:25:17,330 477 00:25:17,330 --> 00:25:20,300 Ora, avendo appena detto che e ora si dice questo, 478 00:25:20,300 --> 00:25:22,170 probabilmente non potrà mai farlo. 479 00:25:22,170 --> 00:25:25,170 Ed è probabilmente una buona cosa onestamente, perché si potrebbe inavvertitamente 480 00:25:25,170 --> 00:25:26,544 omettere una stella, una cosa del genere. 481 00:25:26,544 --> 00:25:29,290 E 'probabilmente meglio a dichiarare forse indicazioni su singole linee, 482 00:25:29,290 --> 00:25:31,373 ma è solo un altro uno di quelli sintassi fastidiosi 483 00:25:31,373 --> 00:25:35,310 le cose con le stelle che fanno puntatori così difficile lavorare con. 484 00:25:35,310 --> 00:25:39,480 Perché è proprio questo sintattico pasticcio si deve lavorare. 485 00:25:39,480 --> 00:25:41,600 Con la pratica si fa davvero diventare una seconda natura. 486 00:25:41,600 --> 00:25:45,410 Ho ancora fare errori con ancora dopo la programmazione per 10 anni, 487 00:25:45,410 --> 00:25:49,630 in modo da non essere turbato se succede qualcosa per te, abbastanza comune onestamente. 488 00:25:49,630 --> 00:25:52,850 E 'davvero tipo di un difetto della sintassi. 489 00:25:52,850 --> 00:25:54,900 >> OK così io il genere di promisi che avremmo rivisitare 490 00:25:54,900 --> 00:25:59,370 il concetto di quanto grande è una stringa. 491 00:25:59,370 --> 00:26:02,750 Beh, se vi dicessi che un stringa, abbiamo davvero tipo di 492 00:26:02,750 --> 00:26:04,140 mentito a voi per tutto il tempo. 493 00:26:04,140 --> 00:26:06,181 Non c'è nessun tipo di dati denominato stringa, e infatti io 494 00:26:06,181 --> 00:26:09,730 menzionato questo in uno dei nostri Video prime sui tipi di dati, 495 00:26:09,730 --> 00:26:13,820 tale stringa è un tipo di dati è stato creato per voi in CS50.h. 496 00:26:13,820 --> 00:26:17,050 Dovete #include CS50.h al fine di utilizzarlo. 497 00:26:17,050 --> 00:26:19,250 >> Beh stringa è in realtà solo un alias per qualcosa 498 00:26:19,250 --> 00:26:23,600 chiamato char *, un puntatore a un carattere. 499 00:26:23,600 --> 00:26:26,010 Beh puntatori, richiamo, sono solo gli indirizzi. 500 00:26:26,010 --> 00:26:28,780 Allora, qual è la dimensione in byte di una stringa? 501 00:26:28,780 --> 00:26:29,796 Beh, è ​​di quattro o otto. 502 00:26:29,796 --> 00:26:32,170 E la ragione dico quattro o otto è perché in realtà 503 00:26:32,170 --> 00:26:36,730 dipende dal sistema, Se stai usando CS50 ide, char * è la dimensione di un char 504 00:26:36,730 --> 00:26:39,340 * È di otto, si tratta di un sistema a 64 bit. 505 00:26:39,340 --> 00:26:43,850 Ogni indirizzo in memoria è di 64 bit. 506 00:26:43,850 --> 00:26:48,270 Se stai usando apparecchio CS50 o utilizzando una macchina a 32 bit, 507 00:26:48,270 --> 00:26:51,640 e avete sentito questo termine a 32 bit la macchina, che cosa è una macchina a 32 bit? 508 00:26:51,640 --> 00:26:56,090 Beh, significa solo che ogni indirizzo in memoria è lungo 32 bit. 509 00:26:56,090 --> 00:26:59,140 E così 32 bit è di quattro byte. 510 00:26:59,140 --> 00:27:02,710 Quindi un char * è di quattro o otto byte a seconda del sistema. 511 00:27:02,710 --> 00:27:06,100 E infatti qualsiasi tipo di dati, e un puntatore a qualsiasi dato 512 00:27:06,100 --> 00:27:12,030 tipo, poiché tutti i puntatori sono solo indirizzi, sono quattro o otto byte. 513 00:27:12,030 --> 00:27:14,030 Quindi cerchiamo di rivisitare questo Diagramma e cerchiamo di concludere 514 00:27:14,030 --> 00:27:18,130 questo video con un po 'di esercizio qui. 515 00:27:18,130 --> 00:27:21,600 Quindi, ecco lo schema abbiamo lasciato con proprio all'inizio del video. 516 00:27:21,600 --> 00:27:23,110 Che cosa succede ora se dico * pk = 35? 517 00:27:23,110 --> 00:27:26,370 518 00:27:26,370 --> 00:27:30,530 Che cosa significa quando dico, * pk = 35? 519 00:27:30,530 --> 00:27:32,420 Prendete un secondo. 520 00:27:32,420 --> 00:27:34,990 * pk. 521 00:27:34,990 --> 00:27:39,890 Nel contesto qui, è * operatore dereference. 522 00:27:39,890 --> 00:27:42,110 Così, quando il dereference operatore viene utilizzato, 523 00:27:42,110 --> 00:27:48,520 andiamo all'indirizzo puntato da PK, e cambiamo ciò che troviamo. 524 00:27:48,520 --> 00:27:55,270 Così * pk = 35 in modo efficace fa questo per l'immagine. 525 00:27:55,270 --> 00:27:58,110 Quindi è fondamentalmente sintatticamente identico al di aver detto k = 35. 526 00:27:58,110 --> 00:28:00,740 527 00:28:00,740 --> 00:28:01,930 >> Uno di più. 528 00:28:01,930 --> 00:28:05,510 Se dico int m, creo una nuova variabile chiamata m. 529 00:28:05,510 --> 00:28:08,260 Una nuova scatola, è una scatola verde perché è andare a tenere un intero, 530 00:28:08,260 --> 00:28:09,840 e è etichettato m. 531 00:28:09,840 --> 00:28:14,960 Se dico m = 4, ho messo un intero in quella scatola. 532 00:28:14,960 --> 00:28:20,290 Se diciamo pk = & m, come fa questo cambiamento schema? 533 00:28:20,290 --> 00:28:28,760 Pk = & m, non ti ricordi quello che il Operatore & fa o si chiama? 534 00:28:28,760 --> 00:28:34,430 Ricorda che e qualche nome di variabile è l'indirizzo di un nome di variabile. 535 00:28:34,430 --> 00:28:38,740 Quindi quello che stiamo dicendo è pk ottiene l'indirizzo di m. 536 00:28:38,740 --> 00:28:42,010 E così efficacemente che cosa succede la diagramma è che pk punti non è più 537 00:28:42,010 --> 00:28:46,420 k, ma punta a m. 538 00:28:46,420 --> 00:28:48,470 >> Ancora puntatori sono molto difficile da lavorare con 539 00:28:48,470 --> 00:28:50,620 e prendono un sacco di pratica, ma perché 540 00:28:50,620 --> 00:28:54,150 della loro capacità di consentire per passare i dati tra le funzioni 541 00:28:54,150 --> 00:28:56,945 e in realtà hanno quelli modifiche hanno effetto, 542 00:28:56,945 --> 00:28:58,820 ottenere la vostra testa intorno è veramente importante. 543 00:28:58,820 --> 00:29:02,590 Probabilmente è il più complicato argomento discutiamo in CS50, 544 00:29:02,590 --> 00:29:05,910 ma il valore che si ottenere da usando puntatori 545 00:29:05,910 --> 00:29:09,200 supera di gran lunga le complicazioni che provengono da loro apprendimento. 546 00:29:09,200 --> 00:29:12,690 Quindi vi auguro buona fortuna conoscere i puntatori. 547 00:29:12,690 --> 00:29:15,760 Sono Doug Lloyd, questo è CS50. 548 00:29:15,760 --> 00:29:17,447