1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Recensione] [Quiz 0] 2 00:00:03,000 --> 00:00:05,000 >> [Lexi Ross, Tommy MacWilliam, Lucas Freitas, Joseph Ong] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 >> [Questo è CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:10,000 >> Ciao a tutti. 5 00:00:10,000 --> 00:00:15,000 Benvenuti alla sessione recensione di Quiz 0, che si sta svolgendo questo Mercoledì. 6 00:00:15,000 --> 00:00:19,000 Quello che andremo a fare questa sera, io sono con 3 TF altri, 7 00:00:19,000 --> 00:00:24,000 e insieme abbiamo intenzione di passare attraverso un giudizio su ciò che abbiamo fatto nel corso finora. 8 00:00:24,000 --> 00:00:27,000 Non sarà al 100% completo, ma dovrebbe darvi un'idea migliore 9 00:00:27,000 --> 00:00:31,000 di ciò che già verso il basso e quello che ancora bisogno di studiare prima di Mercoledì. 10 00:00:31,000 --> 00:00:34,000 E sentitevi liberi di alzare la mano con domande come stiamo andando avanti, 11 00:00:34,000 --> 00:00:38,000 ma di tenere presente che avrete anche un po 'di tempo alla fine- 12 00:00:38,000 --> 00:00:41,000 se vogliamo ottenere attraverso con pochi minuti di scorta per fare domande di carattere generale, 13 00:00:41,000 --> 00:00:47,000 in modo da tenere a mente, e così andremo a cominciare dall'inizio con la settimana 0. 14 00:00:47,000 --> 00:00:50,000 >> [Quiz 0 Commenta!] [Parte 0] [Lexi Ross] Ma prima di farlo che ti permette di parlare di 15 00:00:50,000 --> 00:00:53,000 la logistica del quiz. 16 00:00:53,000 --> 00:00:55,000 >> [Logistica] [Quiz si svolge il Mercoledì 10/10 in sostituzione della lezione] 17 00:00:55,000 --> 00:00:57,000 >> [(Vedi http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf per i dettagli)] E 'il Mercoledì, 10 ottobre. 18 00:00:57,000 --> 00:01:00,000 >> E 'questo Mercoledì, e se andate a questo URL qui, 19 00:01:00,000 --> 00:01:03,000 che è anche accessibile da CS50.net-ci 's un link ad esso, 20 00:01:03,000 --> 00:01:06,000 è possibile visualizzare le informazioni su dove andare in base a 21 00:01:06,000 --> 00:01:10,000 il tuo cognome o affiliazione scuola, così come 22 00:01:10,000 --> 00:01:14,000 si racconta esattamente ciò che il quiz coprirà e le tipologie di domande che si sta andando ad ottenere. 23 00:01:14,000 --> 00:01:19,000 Tenete a mente che avrete anche la possibilità di rivedere il quiz in sezione, 24 00:01:19,000 --> 00:01:21,000 in modo che le TF dovrebbe andare su alcuni problemi pratici, 25 00:01:21,000 --> 00:01:29,000 e questa è un'altra buona occasione per vedere dove hai ancora bisogno di studiare per il quiz. 26 00:01:29,000 --> 00:01:32,000 Cominciamo dall'inizio con Bytes Bits 'n'. 27 00:01:32,000 --> 00:01:35,000 Ricorda un po 'è solo uno 0 o un 1, 28 00:01:35,000 --> 00:01:38,000 ed un byte è una raccolta di 8 di questi bit. 29 00:01:38,000 --> 00:01:42,000 Diamo un'occhiata a questa raccolta di bit proprio qui. 30 00:01:42,000 --> 00:01:44,000 Dovremmo essere in grado di capire quanti bit ci sono. 31 00:01:44,000 --> 00:01:48,000 Dove contiamo c'è solo 8 di loro, otto 0 o 1 unità. 32 00:01:48,000 --> 00:01:51,000 E poiché ci sono 8 bit, questo è 1 byte, 33 00:01:51,000 --> 00:01:53,000 e cerchiamo di convertirlo in esadecimale. 34 00:01:53,000 --> 00:01:58,000 Esadecimale è base 16, ed è abbastanza facile da convertire 35 00:01:58,000 --> 00:02:01,000 in un numero binario, che è ciò che è, ad un numero esadecimale. 36 00:02:01,000 --> 00:02:04,000 Tutto quello che facciamo è guardare a gruppi di 4, 37 00:02:04,000 --> 00:02:07,000 e li converte alla cifra esadecimale appropriato. 38 00:02:07,000 --> 00:02:11,000 Si comincia con il più a destra un gruppo di 4, quindi 0011. 39 00:02:11,000 --> 00:02:16,000 Che sta per essere un 1 e un 2, così insieme che fa 3. 40 00:02:16,000 --> 00:02:19,000 E poi guardiamo l'altro blocco di 4. 41 00:02:19,000 --> 00:02:24,000 1101. Che sta per essere un 1, un 4 e un 8. 42 00:02:24,000 --> 00:02:28,000 Insieme che sta per essere di 13, il che rende D. 43 00:02:28,000 --> 00:02:32,000 E ci ricorda che in esadecimale non ci limitiamo a passare da 0 a 9. 44 00:02:32,000 --> 00:02:36,000 Andiamo da 0 a F, così dopo 9, 10 corrisponde a A, 45 00:02:36,000 --> 00:02:40,000 11 a B, et cetera dove F è 15. 46 00:02:40,000 --> 00:02:44,000 Qui 13 è un D, 47 00:02:44,000 --> 00:02:49,000 in modo da convertirlo in decimale tutto ciò che facciamo è in realtà 48 00:02:49,000 --> 00:02:52,000 trattare ogni posizione di una potenza di 2. 49 00:02:52,000 --> 00:02:58,000 Questo è un 1, un 2, zero 4s, zero 8s, uno 16, et cetera, 50 00:02:58,000 --> 00:03:03,000 ed è un po 'difficile da calcolare nella tua testa, ma se andiamo alla diapositiva successiva 51 00:03:03,000 --> 00:03:05,000 siamo in grado di vedere la risposta a questo. 52 00:03:05,000 --> 00:03:09,000 >> In sostanza stiamo andando di fronte a destra di nuovo a sinistra, 53 00:03:09,000 --> 00:03:14,000 e stiamo moltiplicando ogni cifra per la potenza di 2 corrispondente. 54 00:03:14,000 --> 00:03:19,000 E ricordate, per esadecimale indichiamo questi numeri con 0x all'inizio 55 00:03:19,000 --> 00:03:23,000 in modo da non confondere con un numero decimale. 56 00:03:23,000 --> 00:03:29,000 Proseguendo, si tratta di una tabella ASCII, 57 00:03:29,000 --> 00:03:35,000 e quello che usiamo per ASCII è quello di mappare dai caratteri ai valori numerici. 58 00:03:35,000 --> 00:03:39,000 Ricordate nel pset crittografia abbiamo fatto ampio uso della tabella ASCII 59 00:03:39,000 --> 00:03:43,000 al fine di utilizzare vari metodi di crittografia, 60 00:03:43,000 --> 00:03:47,000 il Cesare e il cifrario di Vigenère, per convertire le lettere diverse 61 00:03:47,000 --> 00:03:52,000 in una stringa secondo la chiave fornita dall'utente. 62 00:03:52,000 --> 00:03:56,000 Diamo un'occhiata a un po 'di matematica ASCII. 63 00:03:56,000 --> 00:04:02,000 Guardando 'P' + 1, in forma di carattere che sarebbe Q, 64 00:04:02,000 --> 00:04:07,000 e ricordate che '5 '≠ 5. 65 00:04:07,000 --> 00:04:10,000 E come esattamente dovremmo convertire tra queste 2 forme? 66 00:04:10,000 --> 00:04:13,000 Non è davvero troppo difficile. 67 00:04:13,000 --> 00:04:16,000 Al fine di ottenere 5 sottraiamo '0 ' 68 00:04:16,000 --> 00:04:20,000 perché ci sono 5 posti tra '0 'e il '5'. 69 00:04:20,000 --> 00:04:23,000 Al fine di andare nella direzione opposta basta aggiungere lo 0, 70 00:04:23,000 --> 00:04:25,000 quindi è un po 'come l'aritmetica normale. 71 00:04:25,000 --> 00:04:29,000 Basta ricordare che quando qualcosa ha virgolette intorno è un personaggio 72 00:04:29,000 --> 00:04:37,000 e corrisponde quindi a un valore nella tabella ASCII. 73 00:04:37,000 --> 00:04:40,000 Trasferirsi in argomenti riguardanti i computer più generali della scienza. 74 00:04:40,000 --> 00:04:43,000 Abbiamo imparato che cosa è un algoritmo e come utilizzare la programmazione 75 00:04:43,000 --> 00:04:45,000 per implementare algoritmi. 76 00:04:45,000 --> 00:04:48,000 Alcuni esempi di algoritmi sono qualcosa di veramente semplice come 77 00:04:48,000 --> 00:04:51,000 verificare se un numero è pari o dispari. 78 00:04:51,000 --> 00:04:54,000 Per questo ricordo che mod il numero per 2 e verificare se il risultato è 0. 79 00:04:54,000 --> 00:04:57,000 Se è così, è ancora. In caso contrario, è strano. 80 00:04:57,000 --> 00:04:59,000 E questo è un esempio di un algoritmo molto di base. 81 00:04:59,000 --> 00:05:02,000 >> Un po 'di uno più coinvolto è ricerca binaria, 82 00:05:02,000 --> 00:05:05,000 quale ci occuperemo più avanti nella sessione di revisione. 83 00:05:05,000 --> 00:05:09,000 E la programmazione è il termine che usiamo per prendere un algoritmo 84 00:05:09,000 --> 00:05:15,000 e la conversione di codificare il computer può leggere. 85 00:05:15,000 --> 00:05:20,000 2 esempi di programmazione Scratch, 86 00:05:20,000 --> 00:05:22,000 che è quello che abbiamo fatto in settimana 0. 87 00:05:22,000 --> 00:05:25,000 Anche se in realtà non digitare il codice è uno strumento di attuazione 88 00:05:25,000 --> 00:05:29,000 questo algoritmo, che sta stampando i numeri 1-10, 89 00:05:29,000 --> 00:05:32,000 e qui noi facciamo lo stesso nel linguaggio di programmazione C. 90 00:05:32,000 --> 00:05:41,000 Questi sono funzionalmente equivalenti, appena scritto in diverse lingue o di sintassi. 91 00:05:41,000 --> 00:05:44,000 Abbiamo poi imparato a conoscere le espressioni booleane, 92 00:05:44,000 --> 00:05:48,000 e un valore booleano è un valore che è true o false, 93 00:05:48,000 --> 00:05:51,000 ed espressioni booleane qui spesso 94 00:05:51,000 --> 00:05:55,000 andare all'interno di condizioni, quindi se (x ≤ 5), 95 00:05:55,000 --> 00:06:00,000 bene, abbiamo già fissato x = 5, in modo che la condizione sta per restituiscono true. 96 00:06:00,000 --> 00:06:03,000 E se è vero, tutto ciò che il codice è sotto la condizione 97 00:06:03,000 --> 00:06:08,000 sarà valutata dal computer, in modo tale stringa sta per essere stampato 98 00:06:08,000 --> 00:06:12,000 sullo standard output, e la condizione di termine 99 00:06:12,000 --> 00:06:16,000 si riferisce a tutto ciò che è all'interno delle parentesi l'istruzione if. 100 00:06:16,000 --> 00:06:20,000 Ricordati di tutti gli operatori. 101 00:06:20,000 --> 00:06:26,000 Ricordatevi che è && e | | quando stiamo cercando di combinare 2 o più condizioni, 102 00:06:26,000 --> 00:06:30,000 == = Non per verificare se 2 cose sono uguali. 103 00:06:30,000 --> 00:06:36,000 Ricordate che è = per l'assegnazione, mentre == è un operatore booleano. 104 00:06:36,000 --> 00:06:41,000 ≤, ≥ e quindi gli ultimi 2 sono auto-esplicativi. 105 00:06:41,000 --> 00:06:45,000 Un riesame generale di logica booleana qui. 106 00:06:45,000 --> 00:06:48,000 E le espressioni booleane sono importanti anche in loop, 107 00:06:48,000 --> 00:06:50,000 che andremo finita. 108 00:06:50,000 --> 00:06:56,000 Abbiamo imparato circa 3 tipi di cicli finora in CS50, for, while e do while. 109 00:06:56,000 --> 00:06:59,000 Ed è importante sapere che, mentre per la maggior parte degli scopi 110 00:06:59,000 --> 00:07:02,000 si può effettivamente utilizzare qualsiasi tipo di loop in generale 111 00:07:02,000 --> 00:07:06,000 ci sono alcuni tipi di scopi o modelli comuni 112 00:07:06,000 --> 00:07:09,000 in programmazione che specificamente richiedono una di queste anse 113 00:07:09,000 --> 00:07:13,000 che lo rendono il più efficiente o elegante per il codice in questo modo. 114 00:07:13,000 --> 00:07:18,000 Andiamo su ciò che ciascuno di questi cicli tende ad essere utilizzato per la maggior parte spesso. 115 00:07:18,000 --> 00:07:21,000 >> In un ciclo for che generalmente già sappiamo quante volte si vuole iterare. 116 00:07:21,000 --> 00:07:24,000 Questo è quello che abbiamo messo nella condizione. 117 00:07:24,000 --> 00:07:28,000 Per, i = 0, i <10, per esempio. 118 00:07:28,000 --> 00:07:31,000 Sappiamo già che vogliamo fare qualcosa di 10 volte. 119 00:07:31,000 --> 00:07:34,000 Ora, per un ciclo while, in genere non necessariamente 120 00:07:34,000 --> 00:07:36,000 sai quante volte vogliamo che il ciclo per l'esecuzione. 121 00:07:36,000 --> 00:07:39,000 Ma sappiamo una sorta di condizione che noi vogliamo che 122 00:07:39,000 --> 00:07:41,000 sempre vera o sempre falsa. 123 00:07:41,000 --> 00:07:44,000 Per esempio, mentre è impostato. 124 00:07:44,000 --> 00:07:46,000 Diciamo che è una variabile booleana. 125 00:07:46,000 --> 00:07:48,000 Anche se è vero che vogliamo il codice di valutare, 126 00:07:48,000 --> 00:07:52,000 quindi un po 'più estensibile, un po' più generale di un ciclo for, 127 00:07:52,000 --> 00:07:55,000 ma per ogni ciclo può anche essere convertito in un ciclo while. 128 00:07:55,000 --> 00:08:00,000 Infine, do while, che possono essere più difficile di comprendere subito, 129 00:08:00,000 --> 00:08:04,000 sono spesso utilizzati quando si vuole valutare il primo codice 130 00:08:04,000 --> 00:08:06,000 prima che la prima volta che si controlla la condizione. 131 00:08:06,000 --> 00:08:09,000 Un caso d'uso comune per un do while 132 00:08:09,000 --> 00:08:12,000 è quando si desidera ottenere l'input dell'utente, e si sa che si desidera chiedere all'utente 133 00:08:12,000 --> 00:08:15,000 per l'ingresso almeno una volta, ma se non ti danno input validi subito 134 00:08:15,000 --> 00:08:18,000 si desidera continuare a chiedere loro fino a quando ti danno l'input bene. 135 00:08:18,000 --> 00:08:21,000 Questo è l'uso più comune di un ciclo Do While, 136 00:08:21,000 --> 00:08:23,000 e guardiamo l'attuale struttura di questi cicli. 137 00:08:23,000 --> 00:08:27,000 Di norma, tendono sempre a seguire questi modelli. 138 00:08:27,000 --> 00:08:30,000 >> Il ciclo per la parte interna si dispone di 3 componenti: 139 00:08:30,000 --> 00:08:35,000 inizializzazione, di solito qualcosa come int i = 0 dove i è il contatore, 140 00:08:35,000 --> 00:08:40,000 condizione, in cui vogliamo dire eseguire questo ciclo for finché questa condizione ancora tiene, 141 00:08:40,000 --> 00:08:44,000 come i <10, e poi finalmente, l'aggiornamento, che è il modo in cui incrementare 142 00:08:44,000 --> 00:08:47,000 la variabile contatore in ogni punto del circuito. 143 00:08:47,000 --> 00:08:50,000 Una cosa comune vedere c'è solo i + +, 144 00:08:50,000 --> 00:08:52,000 che significa incrementare i di 1 ogni volta. 145 00:08:52,000 --> 00:08:55,000 Si potrebbe anche fare qualcosa di simile i + = 2, 146 00:08:55,000 --> 00:08:58,000 il che significa aggiungere 2 per i ogni volta che si passa attraverso il ciclo. 147 00:08:58,000 --> 00:09:03,000 E poi il fare questo si riferisce solo a qualsiasi codice che viene eseguito in realtà come parte del ciclo. 148 00:09:03,000 --> 00:09:09,000 E per un ciclo while, questa volta in realtà abbiamo l'inizializzazione al di fuori del ciclo, 149 00:09:09,000 --> 00:09:12,000 così per esempio, diciamo che stiamo cercando di fare lo stesso tipo di ciclo, come ho appena descritto. 150 00:09:12,000 --> 00:09:16,000 Diremmo int i = 0 prima dell'inizio del ciclo. 151 00:09:16,000 --> 00:09:20,000 Allora potremmo dire, mentre i <10 fare questo, 152 00:09:20,000 --> 00:09:22,000 così lo stesso blocco di codice come prima, 153 00:09:22,000 --> 00:09:26,000 e questa volta la parte di aggiornamento del codice, per esempio, i + +, 154 00:09:26,000 --> 00:09:29,000 va effettivamente all'interno del loop. 155 00:09:29,000 --> 00:09:33,000 E, infine, per un do while, è simile al ciclo while, 156 00:09:33,000 --> 00:09:36,000 ma dobbiamo ricordare che il codice valuterà una volta 157 00:09:36,000 --> 00:09:40,000 prima che la condizione è verificata, quindi ha molto più senso 158 00:09:40,000 --> 00:09:44,000 se la si guarda in ordine di cima a fondo. 159 00:09:44,000 --> 00:09:49,000 In un ciclo Do While il codice di valuta prima ancora di guardare la condizione, mentre, 160 00:09:49,000 --> 00:09:55,000 considerando che un ciclo while, verifica prima. 161 00:09:55,000 --> 00:09:59,000 Le dichiarazioni e le variabili. 162 00:09:59,000 --> 00:10:04,000 Quando si vuole creare una nuova variabile che vuole prima di inizializzarlo. 163 00:10:04,000 --> 00:10:07,000 >> Per esempio, bar int inizializza la barra variabile, 164 00:10:07,000 --> 00:10:10,000 ma non le conferisce un valore, quindi qual è il valore bar adesso? 165 00:10:10,000 --> 00:10:12,000 Non lo sappiamo. 166 00:10:12,000 --> 00:10:14,000 Potrebbe essere qualche valore spazzatura che è stato precedentemente memorizzato lì, 167 00:10:14,000 --> 00:10:16,000 e non si desidera utilizzare tale variabile 168 00:10:16,000 --> 00:10:19,000 fino a quando in realtà dare un valore, 169 00:10:19,000 --> 00:10:21,000 così abbiamo dichiariamo qui. 170 00:10:21,000 --> 00:10:24,000 Poi inizializzarlo ad essere 42. 171 00:10:24,000 --> 00:10:28,000 Ora, naturalmente, sappiamo che questo può essere fatto in una sola riga, int = 42 bar. 172 00:10:28,000 --> 00:10:30,000 Ma proprio per cancellare essere le più passaggi che sono in corso, 173 00:10:30,000 --> 00:10:34,000 la dichiarazione e l'inizializzazione si stanno verificando separatamente qui. 174 00:10:34,000 --> 00:10:38,000 Succede a un passo, e la prossima, int baz = bar + 1, 175 00:10:38,000 --> 00:10:44,000 questa dichiarazione seguente, che baz incrementi, così, alla fine di questo blocco di codice 176 00:10:44,000 --> 00:10:48,000 se dovessimo stampare il valore di baz sarebbe 44 177 00:10:48,000 --> 00:10:52,000 perché dichiarare e inizializzare di essere 1 bar>, 178 00:10:52,000 --> 00:10:58,000 e poi incrementarlo ancora una volta con i tasti + +. 179 00:10:58,000 --> 00:11:02,000 Siamo andati oltre questo breve abbastanza, ma è bene avere un generale 180 00:11:02,000 --> 00:11:04,000 comprensione di ciò che le discussioni e gli eventi sono. 181 00:11:04,000 --> 00:11:06,000 Abbiamo soprattutto fatto in Scratch, 182 00:11:06,000 --> 00:11:09,000 in modo da poter pensare di thread come sequenze multiple di codice 183 00:11:09,000 --> 00:11:11,000 esecuzione contemporaneamente. 184 00:11:11,000 --> 00:11:14,000 In realtà, probabilmente non è in esecuzione al tempo stesso, 185 00:11:14,000 --> 00:11:17,000 ma una sorta di astratto possiamo pensare in quel modo. 186 00:11:17,000 --> 00:11:20,000 >> In Scratch, ad esempio, abbiamo avuto i più sprite. 187 00:11:20,000 --> 00:11:22,000 Si potrebbe eseguire codice diverso allo stesso tempo. 188 00:11:22,000 --> 00:11:26,000 Si potrebbe essere a piedi, mentre l'altro sta dicendo qualcosa 189 00:11:26,000 --> 00:11:29,000 in un'altra parte dello schermo. 190 00:11:29,000 --> 00:11:34,000 Gli eventi sono un altro modo di separare la logica 191 00:11:34,000 --> 00:11:37,000 tra i diversi elementi del codice, 192 00:11:37,000 --> 00:11:40,000 e in Scratch siamo stati in grado di simulare gli eventi utilizzando il Broadcast, 193 00:11:40,000 --> 00:11:43,000 e che in realtà quando ricevo, non quando sento, 194 00:11:43,000 --> 00:11:47,000 ma essenzialmente è un modo per trasmettere informazioni 195 00:11:47,000 --> 00:11:49,000 da uno sprite a un altro. 196 00:11:49,000 --> 00:11:52,000 Ad esempio, si può decidere di trasmettere game over, 197 00:11:52,000 --> 00:11:56,000 e quando un altro sprite riceve game over, 198 00:11:56,000 --> 00:11:58,000 risponde in un certo modo. 199 00:11:58,000 --> 00:12:03,000 Si tratta di un modello importante per capire per la programmazione. 200 00:12:03,000 --> 00:12:07,000 Giusto per andare oltre la settimana di base 0, quello che abbiamo superato finora, 201 00:12:07,000 --> 00:12:10,000 diamo un'occhiata a questo programma in C semplice. 202 00:12:10,000 --> 00:12:14,000 Il testo può essere un po 'piccola da qui, ma io vado su di esso molto veloce. 203 00:12:14,000 --> 00:12:20,000 Siamo tra 2 file di intestazione in alto, cs50.h e stdio.h. 204 00:12:20,000 --> 00:12:23,000 Siamo quindi definire un limite costante chiamata ad essere 100. 205 00:12:23,000 --> 00:12:26,000 Stiamo quindi implementare la nostra funzione principale. 206 00:12:26,000 --> 00:12:29,000 Dal momento che non utilizzare gli argomenti della riga di comando qui abbiamo bisogno di mettere nulla 207 00:12:29,000 --> 00:12:32,000 come gli argomenti per principale. 208 00:12:32,000 --> 00:12:38,000 Vediamo int sopra principale. Questo è il tipo di ritorno, quindi restituire 0 in fondo. 209 00:12:38,000 --> 00:12:41,000 E stiamo usando CS50 funzione di libreria ottenere int 210 00:12:41,000 --> 00:12:45,000 chiedere all'utente per l'input, e conservarla in questa variabile x, 211 00:12:45,000 --> 00:12:51,000 in modo da dichiarare x sopra, e lo inizializza con x = GetInt. 212 00:12:51,000 --> 00:12:53,000 >> Abbiamo poi verificare se l'utente ci ha dato input validi. 213 00:12:53,000 --> 00:12:59,000 Se è LIMITE ≥ vogliamo restituire un codice di errore di 1 e un messaggio di errore. 214 00:12:59,000 --> 00:13:02,000 E, infine, se l'utente ci ha dato input validi 215 00:13:02,000 --> 00:13:08,000 stiamo andando a quadrare il numero e stampare tale risultato. 216 00:13:08,000 --> 00:13:11,000 Giusto per fare in modo che coloro che tutti colpiti a casa 217 00:13:11,000 --> 00:13:17,000 è possibile vedere le etichette di diverse parti del codice qui. 218 00:13:17,000 --> 00:13:19,000 Ho accennato costanti, file di intestazione. 219 00:13:19,000 --> 00:13:21,000 Oh, int x. Assicurati di ricordare che è una variabile locale. 220 00:13:21,000 --> 00:13:24,000 Che contrasta da una variabile globale, che parleremo 221 00:13:24,000 --> 00:13:27,000 un po 'più tardi nella sessione di revisione, 222 00:13:27,000 --> 00:13:30,000 e stiamo chiamando la funzione di libreria printf, 223 00:13:30,000 --> 00:13:34,000 quindi se non avessimo incluso il file di intestazione stdio.h 224 00:13:34,000 --> 00:13:37,000 non saremmo in grado di chiamare printf. 225 00:13:37,000 --> 00:13:42,000 E credo che la freccia che ha tagliato fuori qui si punta al% d, 226 00:13:42,000 --> 00:13:45,000 che è una stringa di formattazione di printf. 227 00:13:45,000 --> 00:13:52,000 Si dice di stampare questa variabile come d% un numero,. 228 00:13:52,000 --> 00:13:58,000 E questo è per la Settimana 0. 229 00:13:58,000 --> 00:14:06,000 Ora Lucas è destinata a continuare. 230 00:14:06,000 --> 00:14:08,000 Ehi, ragazzi. Il mio nome è Lucas. 231 00:14:08,000 --> 00:14:10,000 Sono al secondo anno nel migliore casa nel campus, Mather, 232 00:14:10,000 --> 00:14:14,000 e ho intenzione di parlare un po 'di settimana 1 e 2.1. 233 00:14:14,000 --> 00:14:16,000 [Settimana 1 e 2.1!] [Lucas Freitas] 234 00:14:16,000 --> 00:14:19,000 Come Lexi diceva, quando abbiamo iniziato a tradurre il codice da zero in C 235 00:14:19,000 --> 00:14:23,000 una delle cose che abbiamo notato è che non si può semplicemente 236 00:14:23,000 --> 00:14:26,000 scrivere il codice ed eseguirlo con una bandiera verde più. 237 00:14:26,000 --> 00:14:30,000 In realtà, è necessario utilizzare alcuni passi per rendere il vostro programma C 238 00:14:30,000 --> 00:14:33,000 diventare un file eseguibile. 239 00:14:33,000 --> 00:14:36,000 Fondamentalmente quello che si fa quando si sta scrivendo un programma che è 240 00:14:36,000 --> 00:14:40,000 di tradurre la vostra idea in un linguaggio che un compilatore in grado di capire, 241 00:14:40,000 --> 00:14:44,000 così quando si sta scrivendo un programma in C 242 00:14:44,000 --> 00:14:47,000 quello che stai facendo è in realtà scrivere qualcosa che il compilatore sta per capire, 243 00:14:47,000 --> 00:14:50,000 e poi il compilatore sta per tradurre il codice 244 00:14:50,000 --> 00:14:53,000 in qualcosa che il computer capirà. 245 00:14:53,000 --> 00:14:55,000 >> E la cosa è, il computer è in realtà molto stupido. 246 00:14:55,000 --> 00:14:57,000 Il computer può comprendere solo 0 e 1, 247 00:14:57,000 --> 00:15:01,000 quindi in realtà i primi computer la gente di solito programmato 248 00:15:01,000 --> 00:15:04,000 con 0 e 1, ma ora non più, grazie a Dio. 249 00:15:04,000 --> 00:15:07,000 Non c'è bisogno di memorizzare le sequenze di 0 e 1 250 00:15:07,000 --> 00:15:10,000 per un ciclo for o per un ciclo while e così via. 251 00:15:10,000 --> 00:15:13,000 Questo è il motivo per cui abbiamo un compilatore. 252 00:15:13,000 --> 00:15:17,000 Che cosa fa è un compilatore traduce fondamentalmente il codice C, 253 00:15:17,000 --> 00:15:21,000 nel nostro caso, di un linguaggio che il computer capirà, 254 00:15:21,000 --> 00:15:25,000 che è il codice oggetto, e il compilatore che stiamo usando 255 00:15:25,000 --> 00:15:30,000 si chiama clang, quindi questo è in realtà il simbolo per fragore. 256 00:15:30,000 --> 00:15:33,000 Quando hai il tuo programma, devi fare 2 cose. 257 00:15:33,000 --> 00:15:37,000 In primo luogo, è necessario compilare il programma, e poi avete intenzione di eseguire il programma. 258 00:15:37,000 --> 00:15:41,000 Per compilare il programma si ha un sacco di opzioni per farlo. 259 00:15:41,000 --> 00:15:44,000 Il primo è quello di fare program.c clang 260 00:15:44,000 --> 00:15:47,000 in cui il programma è il nome del programma. 261 00:15:47,000 --> 00:15:51,000 In questo caso si può vedere che stanno solo dicendo "Hey, compilare il mio programma". 262 00:15:51,000 --> 00:15:56,000 Non stai dicendo "voglio questo nome per il mio programma" o qualcosa. 263 00:15:56,000 --> 00:15:58,000 >> La seconda opzione è dare un nome al vostro programma. 264 00:15:58,000 --> 00:16:02,000 Si può dire clang-o e poi il nome che si desidera 265 00:16:02,000 --> 00:16:06,000 il file eseguibile per essere nominato e poi program.c. 266 00:16:06,000 --> 00:16:11,000 E si può anche fare il programma make, e vedere come nei primi 2 casi 267 00:16:11,000 --> 00:16:15,000 Ho messo. C, e nel terzo ho solo programmi? 268 00:16:15,000 --> 00:16:18,000 Si ', in realtà non dovrebbe mettere. C quando si utilizza fare. 269 00:16:18,000 --> 00:16:22,000 In caso contrario, il compilatore è in realtà sta per urlare contro di voi. 270 00:16:22,000 --> 00:16:24,000 E anche, non so se voi ragazzi ricordate, 271 00:16:24,000 --> 00:16:29,000 ma un sacco di volte abbiamo usato anche lcs50-o-LM. 272 00:16:29,000 --> 00:16:31,000 Che è chiamato collegamento. 273 00:16:31,000 --> 00:16:35,000 Si dice solo il compilatore che si intende utilizzare quelle librerie proprio lì, 274 00:16:35,000 --> 00:16:39,000 quindi se si desidera utilizzare cs50.h effettivamente necessario digitare 275 00:16:39,000 --> 00:16:43,000 clang program.c-lcs50. 276 00:16:43,000 --> 00:16:45,000 Se non lo facciamo, il compilatore non ha intenzione di conoscere 277 00:16:45,000 --> 00:16:50,000 che si sta utilizzando queste funzioni in cs50.h. 278 00:16:50,000 --> 00:16:52,000 E quando si desidera eseguire il programma si hanno 2 opzioni. 279 00:16:52,000 --> 00:16:57,000 Se avete fatto program.c clang che non ha dato un nome al programma. 280 00:16:57,000 --> 00:17:01,000 Si deve eseguire usando. / A.out. 281 00:17:01,000 --> 00:17:06,000 A.out è un nome standard che clang restituisce il programma se non dargli un nome. 282 00:17:06,000 --> 00:17:11,000 In caso contrario, si sta andando a fare. / Programma, se ti ha dato un nome al programma, 283 00:17:11,000 --> 00:17:15,000 e anche se avete fatto fare il nome del programma che un programma sta per arrivare 284 00:17:15,000 --> 00:17:23,000 è già in corso da programmare lo stesso nome del file c. 285 00:17:23,000 --> 00:17:26,000 Poi abbiamo parlato di tipi di dati e di dati. 286 00:17:26,000 --> 00:17:31,000 >> Fondamentalmente i tipi di dati sono la stessa cosa, come piccole scatole che utilizzano 287 00:17:31,000 --> 00:17:35,000 per memorizzare i valori, quindi i tipi di dati sono in realtà proprio come Pokemon. 288 00:17:35,000 --> 00:17:39,000 Essi sono disponibili in tutte le dimensioni e tipologie. 289 00:17:39,000 --> 00:17:43,000 Non so se questa analogia ha un senso. 290 00:17:43,000 --> 00:17:46,000 La dimensione dei dati in realtà dipende l'architettura della macchina. 291 00:17:46,000 --> 00:17:49,000 Tutti i formati di dati che ho intenzione di mostrare qui 292 00:17:49,000 --> 00:17:53,000 sono in realtà una macchina a 32 bit, che è il caso del nostro apparecchio, 293 00:17:53,000 --> 00:17:56,000 ma se in realtà si sta scrivere il vostro Mac o in un ambiente Windows anche 294 00:17:56,000 --> 00:17:59,000 probabilmente si sta andando ad avere un computer a 64 bit, 295 00:17:59,000 --> 00:18:03,000 in modo da ricordare che le dimensioni dei dati che ho intenzione di mostrare qui 296 00:18:03,000 --> 00:18:06,000 sono per il 32-bit. 297 00:18:06,000 --> 00:18:08,000 Il primo che abbiamo visto era un int, 298 00:18:08,000 --> 00:18:10,000 che è abbastanza semplice. 299 00:18:10,000 --> 00:18:13,000 È utilizzare int per memorizzare un numero intero. 300 00:18:13,000 --> 00:18:16,000 Abbiamo anche visto il carattere, il carattere. 301 00:18:16,000 --> 00:18:20,000 Se si desidera utilizzare una lettera o un piccolo simbolo probabilmente stai andando ad utilizzare un char. 302 00:18:20,000 --> 00:18:26,000 Un char è 1 byte, il che significa 8 bit, come Lexi ha detto. 303 00:18:26,000 --> 00:18:31,000 In pratica abbiamo una tabella ASCII che dispone di 256 304 00:18:31,000 --> 00:18:34,000 possibili combinazioni di 0 e 1, 305 00:18:34,000 --> 00:18:37,000 e poi quando si digita un carattere che sta per tradurre 306 00:18:37,000 --> 00:18:44,000 il carattere che gli ingressi voi un numero che si ha nella tabella ASCII, come Lexi ha detto. 307 00:18:44,000 --> 00:18:48,000 Abbiamo anche il galleggiante, che si usa per memorizzare i numeri decimali. 308 00:18:48,000 --> 00:18:53,000 Se si desidera scegliere 3.14, per esempio, si sta andando ad utilizzare un galleggiante 309 00:18:53,000 --> 00:18:55,000 o un doppio che ha più precisione. 310 00:18:55,000 --> 00:18:57,000 Un galleggiante dispone di 4 byte. 311 00:18:57,000 --> 00:19:01,000 Un doppio ha 8 byte, quindi l'unica differenza è la precisione. 312 00:19:01,000 --> 00:19:04,000 Abbiamo anche una lunga che viene utilizzato per gli interi, 313 00:19:04,000 --> 00:19:09,000 e si può vedere una macchina a 32 bit di un int e un lungo hanno la stessa dimensione, 314 00:19:09,000 --> 00:19:13,000 quindi non ha molto senso usare un lungo in un computer a 32 bit. 315 00:19:13,000 --> 00:19:17,000 >> Ma se si sta utilizzando un computer Mac e 64-bit, in realtà una lunga ha dimensione 8, 316 00:19:17,000 --> 00:19:19,000 in modo che in realtà dipende l'architettura. 317 00:19:19,000 --> 00:19:22,000 Per la macchina a 32 bit non ha senso usare una lunga davvero. 318 00:19:22,000 --> 00:19:25,000 E quindi un lungo tempo, invece, ha 8 byte, 319 00:19:25,000 --> 00:19:30,000 quindi è molto buona se si vuole avere un maggiore numero intero. 320 00:19:30,000 --> 00:19:34,000 E, infine, abbiamo stringa, che in realtà è un char *, 321 00:19:34,000 --> 00:19:37,000 che è un puntatore ad un char. 322 00:19:37,000 --> 00:19:40,000 E 'molto facile pensare che la dimensione della stringa sta per essere come 323 00:19:40,000 --> 00:19:42,000 il numero di caratteri che hai lì, 324 00:19:42,000 --> 00:19:45,000 ma in realtà la stessa char * 325 00:19:45,000 --> 00:19:49,000 ha la dimensione di un puntatore ad un char, che è 4 byte. 326 00:19:49,000 --> 00:19:52,000 La dimensione di un char * è di 4 byte. 327 00:19:52,000 --> 00:19:56,000 Non importa se si dispone di una piccola parola o una lettera o altro. 328 00:19:56,000 --> 00:19:58,000 E 'intenzione di essere di 4 byte. 329 00:19:58,000 --> 00:20:01,000 Abbiamo anche imparato un po 'di getto, 330 00:20:01,000 --> 00:20:04,000 così come si può vedere, se si ha, ad esempio, un programma che dice 331 00:20:04,000 --> 00:20:08,000 int x = 3 e poi printf ("% d", x / 2) 332 00:20:08,000 --> 00:20:12,000 non sapete cosa sta andando per la stampa su schermo? 333 00:20:12,000 --> 00:20:14,000 >> Qualcuno? >> [Gli studenti] 2. 334 00:20:14,000 --> 00:20:16,000 1. >> 1, si '. 335 00:20:16,000 --> 00:20:20,000 Quando si fare 3/2, sta per arrivare 1.5, 336 00:20:20,000 --> 00:20:24,000 ma dal momento che stiamo usando un intero sta andando a ignorare la parte decimale, 337 00:20:24,000 --> 00:20:26,000 e si sta andando ad avere 1. 338 00:20:26,000 --> 00:20:29,000 Se non vogliamo che ciò accada ciò che si può fare, ad esempio, 339 00:20:29,000 --> 00:20:33,000 si dichiara un float y = x. 340 00:20:33,000 --> 00:20:40,000 Poi x che un tempo 3 è ora sta per essere 3.000 in y. 341 00:20:40,000 --> 00:20:44,000 E poi si può stampare il y / 2. 342 00:20:44,000 --> 00:20:50,000 A dire il vero, dovrei avere un 2. laggiù. 343 00:20:50,000 --> 00:20:55,000 E 'intenzione di fare 3.00/2.00, 344 00:20:55,000 --> 00:20:58,000 e si sta andando ad ottenere 1.5. 345 00:20:58,000 --> 00:21:06,000 E abbiamo questa .2 f solo per chiedere per 2 unità decimali nella parte decimale. 346 00:21:06,000 --> 00:21:12,000 Se si dispone di 0,3 f che sta per avere effettivamente 1.500. 347 00:21:12,000 --> 00:21:16,000 Se è 2 si sarà 1.50. 348 00:21:16,000 --> 00:21:18,000 Abbiamo anche questo caso. 349 00:21:18,000 --> 00:21:22,000 Se lo fai float x = 3.14 e quindi si x printf 350 00:21:22,000 --> 00:21:24,000 si sta andando ad ottenere 3.14. 351 00:21:24,000 --> 00:21:29,000 E se lo fai x = int x, 352 00:21:29,000 --> 00:21:34,000 il che significa che trattano x come un int e si stampa x ora 353 00:21:34,000 --> 00:21:36,000 si sta andando ad avere 3.00. 354 00:21:36,000 --> 00:21:38,000 Ha senso? 355 00:21:38,000 --> 00:21:41,000 Perché sei prima trattando x come un intero, in modo che stai ignorando la parte decimale, 356 00:21:41,000 --> 00:21:45,000 e poi si sta stampando x. 357 00:21:45,000 --> 00:21:47,000 E, infine, si può anche fare questo, 358 00:21:47,000 --> 00:21:52,000 int x = 65, e quindi si dichiara un char c = x, 359 00:21:52,000 --> 00:21:56,000 e poi se si stampa il c si sta effettivamente andando ottenere 360 00:21:56,000 --> 00:21:59,000 A, quindi fondamentalmente quello che stai facendo qui 361 00:21:59,000 --> 00:22:02,000 sta traducendo il numero intero nel personaggio, 362 00:22:02,000 --> 00:22:05,000 proprio come la tabella ASCII fa. 363 00:22:05,000 --> 00:22:08,000 Abbiamo anche parlato di operatori matematici. 364 00:22:08,000 --> 00:22:14,000 La maggior parte di loro sono piuttosto semplici, in modo da +, -, *, /, 365 00:22:14,000 --> 00:22:20,000 e anche abbiamo parlato di mod, che è il resto di una divisione di 2 numeri. 366 00:22:20,000 --> 00:22:23,000 Se si dispone di 10% 3, per esempio, 367 00:22:23,000 --> 00:22:27,000 significa dividere 10 per 3, e ciò che è il resto? 368 00:22:27,000 --> 00:22:30,000 E 'intenzione di essere 1, quindi in realtà è molto utile per un sacco di programmi. 369 00:22:30,000 --> 00:22:38,000 Per Vigenère e Cesare sono abbastanza sicuro che tutti voi ragazzi usato mod. 370 00:22:38,000 --> 00:22:43,000 Informazioni sugli operatori matematici, essere molto attenti quando si combinano * e /. 371 00:22:43,000 --> 00:22:48,000 >> Ad esempio, se si fa (3/2) * 2 cosa hai intenzione di ottenere? 372 00:22:48,000 --> 00:22:50,000 [Gli studenti] 2. 373 00:22:50,000 --> 00:22:54,000 Si ', 2, in quanto 3/2 è sta per essere 1.5, 374 00:22:54,000 --> 00:22:57,000 ma dal momento che si sta facendo le operazioni tra 2 numeri interi 375 00:22:57,000 --> 00:22:59,000 si sta effettivamente solo andando a prendere in considerazione 1, 376 00:22:59,000 --> 00:23:03,000 e quindi 1 * 2 sta per essere 2, in modo da essere molto, molto attenti 377 00:23:03,000 --> 00:23:07,000 quando fare calcoli con numeri interi, perché 378 00:23:07,000 --> 00:23:12,000 si potrebbe ottenere che 2 = 3, in questo caso. 379 00:23:12,000 --> 00:23:14,000 E anche stare molto attenti a precedenza. 380 00:23:14,000 --> 00:23:21,000 Di solito si deve utilizzare le parentesi per essere sicuri di sapere cosa si sta facendo. 381 00:23:21,000 --> 00:23:27,000 Collegamenti utili, naturalmente, si è i + + o + i = 1 382 00:23:27,000 --> 00:23:30,000 o usando + =. 383 00:23:30,000 --> 00:23:34,000 Questa è la stessa cosa che i = i + 1. 384 00:23:34,000 --> 00:23:39,000 È anche possibile che faccio - o i - = 1, 385 00:23:39,000 --> 00:23:42,000 che è la stessa cosa che i = i -1, 386 00:23:42,000 --> 00:23:46,000 qualcosa voi ragazzi l'uso molto in cicli for, almeno. 387 00:23:46,000 --> 00:23:52,000 Inoltre, per *, se si utilizza * = e se lo fai, per esempio, 388 00:23:52,000 --> 00:23:57,000 i * = 2 è la stessa cosa che dire i = i * 2, 389 00:23:57,000 --> 00:23:59,000 e la stessa cosa per la divisione. 390 00:23:59,000 --> 00:24:08,000 Se fate i / = 2 è la stessa cosa che i = i / 2. 391 00:24:08,000 --> 00:24:10,000 >> Ora sulle funzioni. 392 00:24:10,000 --> 00:24:13,000 Voi ragazzi imparato che le funzioni sono una buona strategia per salvare il codice 393 00:24:13,000 --> 00:24:16,000 mentre si sta programmando, quindi se si desidera eseguire lo stesso compito 394 00:24:16,000 --> 00:24:20,000 nel codice più e più volte, probabilmente si desidera utilizzare una funzione 395 00:24:20,000 --> 00:24:25,000 solo così non c'è bisogno di copiare e incollare il codice più e più volte. 396 00:24:25,000 --> 00:24:28,000 In realtà, è una funzione principale, e quando vi mostro il formato di una funzione 397 00:24:28,000 --> 00:24:32,000 si sta andando a vedere che questo è abbastanza evidente. 398 00:24:32,000 --> 00:24:35,000 Usiamo anche le funzioni di alcune librerie, 399 00:24:35,000 --> 00:24:39,000 per esempio, printf, Getin, che è dalla biblioteca CS50, 400 00:24:39,000 --> 00:24:43,000 e altre funzioni come toupper. 401 00:24:43,000 --> 00:24:46,000 Tutte queste funzioni sono effettivamente attuate in altre biblioteche, 402 00:24:46,000 --> 00:24:49,000 e quando si mette quei file legano all'inizio del programma 403 00:24:49,000 --> 00:24:53,000 stai dicendo che si può per favore darmi il codice per le funzioni 404 00:24:53,000 --> 00:24:57,000 quindi non c'è bisogno di attuarle da solo? 405 00:24:57,000 --> 00:25:00,000 E si può anche scrivere le proprie funzioni, in modo che quando si avvia la programmazione 406 00:25:00,000 --> 00:25:04,000 ci si rende conto che le biblioteche non hanno tutte le funzioni di cui avete bisogno. 407 00:25:04,000 --> 00:25:10,000 Per l'pset scorso, per esempio, abbiamo scritto disegnare, corsa, e di ricerca, 408 00:25:10,000 --> 00:25:13,000 ed è molto, molto importante essere in grado di scrivere le funzioni 409 00:25:13,000 --> 00:25:17,000 perché sono utili, e li usiamo per tutto il tempo nella programmazione, 410 00:25:17,000 --> 00:25:19,000 e fa risparmiare un sacco di codice. 411 00:25:19,000 --> 00:25:21,000 Il formato di una funzione è questa. 412 00:25:21,000 --> 00:25:24,000 Abbiamo tipo di ritorno all'inizio. Qual è il tipo di ritorno? 413 00:25:24,000 --> 00:25:27,000 E 'solo quando la funzione sta per tornare. 414 00:25:27,000 --> 00:25:29,000 Se si dispone di una funzione, ad esempio, fattoriale, 415 00:25:29,000 --> 00:25:31,000 che sta per calcolare un fattoriale di un numero intero, 416 00:25:31,000 --> 00:25:34,000 probabilmente sta andando a restituire un numero intero anche. 417 00:25:34,000 --> 00:25:37,000 Poi il tipo di ritorno sarà int. 418 00:25:37,000 --> 00:25:41,000 Printf ha in realtà un vuoto tipo di ritorno 419 00:25:41,000 --> 00:25:43,000 perché non sei niente di ritorno. 420 00:25:43,000 --> 00:25:45,000 Stai solo stampando le cose sullo schermo 421 00:25:45,000 --> 00:25:48,000 e uscire dalla funzione in seguito. 422 00:25:48,000 --> 00:25:51,000 Poi ci sono il nome della funzione che si può scegliere. 423 00:25:51,000 --> 00:25:55,000 Si dovrebbe essere un po 'ragionevole, come non scegliere un nome come xyz 424 00:25:55,000 --> 00:25:58,000 o come X2F. 425 00:25:58,000 --> 00:26:02,000 Provate a fare un nome che abbia un senso. 426 00:26:02,000 --> 00:26:04,000 >> Ad esempio, se si tratta di fattoriale, dicono fattoriale. 427 00:26:04,000 --> 00:26:08,000 Se si tratta di una funzione che sta per disegnare qualcosa, il nome disegnare. 428 00:26:08,000 --> 00:26:11,000 E poi ci sono i parametri, che sono anche chiamati argomenti, 429 00:26:11,000 --> 00:26:14,000 che sono come le risorse che la funzione ha bisogno 430 00:26:14,000 --> 00:26:17,000 dal codice per eseguire il suo compito. 431 00:26:17,000 --> 00:26:20,000 Se si vuole calcolare il fattoriale di un numero 432 00:26:20,000 --> 00:26:23,000 probabilmente è necessario disporre di un numero per calcolare un fattoriale. 433 00:26:23,000 --> 00:26:27,000 Uno degli argomenti che si sta andando ad avere è il numero stesso. 434 00:26:27,000 --> 00:26:31,000 E poi va a fare qualcosa e restituire il valore alla fine 435 00:26:31,000 --> 00:26:35,000 meno che non sia una funzione void. 436 00:26:35,000 --> 00:26:37,000 Vediamo un esempio. 437 00:26:37,000 --> 00:26:40,000 Se voglio scrivere una funzione che somma tutti i numeri in un array di interi, 438 00:26:40,000 --> 00:26:43,000 prima di tutto, il tipo di ritorno sarà int 439 00:26:43,000 --> 00:26:46,000 perché ho un array di interi. 440 00:26:46,000 --> 00:26:51,000 E poi ho intenzione di avere il nome della funzione come sumArray, 441 00:26:51,000 --> 00:26:54,000 e poi sta andando a prendere la matrice stessa, a nums int, 442 00:26:54,000 --> 00:26:58,000 e poi la lunghezza della matrice quindi so quanti numeri devo sommare. 443 00:26:58,000 --> 00:27:02,000 Poi devo inizializzare una somma variabile chiamata, per esempio, a 0, 444 00:27:02,000 --> 00:27:08,000 e ogni volta che vedo un elemento dell'array devo aggiungere alla somma, così ho fatto un ciclo for. 445 00:27:08,000 --> 00:27:15,000 Proprio come Lexi ha detto, si fa int i = 0, i lunghezza 00:27:20,000 E per ogni elemento della matrice che ho fatto somma + = nums [i], 447 00:27:20,000 --> 00:27:24,000 e poi ho restituito la somma, quindi è molto semplice, e fa risparmiare un sacco di codice 448 00:27:24,000 --> 00:27:28,000 se si sta utilizzando questa funzione un sacco di volte. 449 00:27:28,000 --> 00:27:32,000 Poi abbiamo preso uno sguardo a condizioni. 450 00:27:32,000 --> 00:27:38,000 Abbiamo if, else e else if. 451 00:27:38,000 --> 00:27:42,000 Vediamo qual è la differenza tra quelli. 452 00:27:42,000 --> 00:27:45,000 Date un'occhiata a questi 2 codici. Qual è la differenza tra loro? 453 00:27:45,000 --> 00:27:49,000 Il primo è, in fondo i codici che tu dica 454 00:27:49,000 --> 00:27:51,000 se un numero è +, -, o 0. 455 00:27:51,000 --> 00:27:55,000 Il primo dice se è> 0 allora è positivo. 456 00:27:55,000 --> 00:28:00,000 Se è = a 0 allora è 0, e se è <0 allora è negativo. 457 00:28:00,000 --> 00:28:04,000 >> E l'altro sta facendo if, else if, else. 458 00:28:04,000 --> 00:28:07,000 La differenza tra i due è che questo è effettivamente andando 459 00:28:07,000 --> 00:28:13,000 controllare se> 0, <0 = 0 o tre volte, 460 00:28:13,000 --> 00:28:17,000 quindi se avete il numero 2, per esempio, che sta per venire qui e dire: 461 00:28:17,000 --> 00:28:21,000 if (x> 0), e che sta per dire di sì, così mi stampa positiva. 462 00:28:21,000 --> 00:28:25,000 Ma anche se so che è> 0 e non sarà 0 o <0 463 00:28:25,000 --> 00:28:29,000 Sto ancora intenzione di fare è 0, è <0, 464 00:28:29,000 --> 00:28:33,000 quindi sto effettivamente andando dentro di se e che non c'era bisogno di 465 00:28:33,000 --> 00:28:38,000 perché so già che non sta andando a soddisfare una delle seguenti condizioni. 466 00:28:38,000 --> 00:28:41,000 Posso usare il se, else if, else. 467 00:28:41,000 --> 00:28:45,000 Dice in fondo se x = 0 stampare il positivo. 468 00:28:45,000 --> 00:28:48,000 Se non lo è, ho intenzione di provare anche questo. 469 00:28:48,000 --> 00:28:51,000 Se è 2 non ho intenzione di farlo. 470 00:28:51,000 --> 00:28:54,000 In pratica se avessi x = 2 si direbbe 471 00:28:54,000 --> 00:28:57,000 if (x> 0), sì, così stampare questa. 472 00:28:57,000 --> 00:29:00,000 Ora che so che è> 0 e che ha soddisfatto il primo, se 473 00:29:00,000 --> 00:29:02,000 Non ho nemmeno intenzione di eseguire questo codice. 474 00:29:02,000 --> 00:29:09,000 Il codice è più veloce, in realtà, 3 volte più veloce se si utilizza questo. 475 00:29:09,000 --> 00:29:11,000 Abbiamo anche imparato a conoscere e ed o. 476 00:29:11,000 --> 00:29:15,000 Non ho intenzione di passare attraverso questo perché Lexi già parlato di loro. 477 00:29:15,000 --> 00:29:17,000 E 'solo i && e | operator |. 478 00:29:17,000 --> 00:29:21,000 >> L'unica cosa che dirò è stare attenti quando si hanno 3 condizioni. 479 00:29:21,000 --> 00:29:24,000 Utilizzare le parentesi perché è molto confusa quando si ha una condizione 480 00:29:24,000 --> 00:29:27,000 e un altro o un altro. 481 00:29:27,000 --> 00:29:30,000 Utilizzare le parentesi solo per essere sicuri che le vostre condizioni di dare un senso 482 00:29:30,000 --> 00:29:34,000 perché in tal caso, ad esempio, si può immaginare che 483 00:29:34,000 --> 00:29:38,000 potrebbe essere la prima condizione e l'una o l'altra 484 00:29:38,000 --> 00:29:41,000 o le 2 condizioni combinati in e 485 00:29:41,000 --> 00:29:45,000 o il terzo, quindi basta stare attenti. 486 00:29:45,000 --> 00:29:48,000 E, infine, abbiamo parlato di switch. 487 00:29:48,000 --> 00:29:53,000 Un interruttore è molto utile quando si dispone di una variabile. 488 00:29:53,000 --> 00:29:55,000 Diciamo che hai una variabile come n 489 00:29:55,000 --> 00:29:59,000 che può essere 0, 1 o 2, e per ciascuno di questi casi 490 00:29:59,000 --> 00:30:01,000 si sta andando a eseguire un compito. 491 00:30:01,000 --> 00:30:04,000 Si può dire cambiare la variabile, e indica che 492 00:30:04,000 --> 00:30:08,000 il valore è quindi come value1 ho intenzione di fare questo, 493 00:30:08,000 --> 00:30:12,000 e poi mi rompo, il che significa che non ho intenzione di guardare uno qualsiasi degli altri casi 494 00:30:12,000 --> 00:30:15,000 perché abbiamo già soddisfatto questo caso 495 00:30:15,000 --> 00:30:20,000 e poi valore2 e così via, e può anche avere un interruttore predefinito. 496 00:30:20,000 --> 00:30:24,000 Questo significa che se non soddisfa nessuno dei casi che ho avuto 497 00:30:24,000 --> 00:30:29,000 che ho intenzione di fare qualcosa di diverso, ma questo è facoltativo. 498 00:30:29,000 --> 00:30:36,000 Questo è tutto per me. Ora andiamo a Tommy. 499 00:30:36,000 --> 00:30:41,000 Va bene, questo sarà settimana 3-ish. 500 00:30:41,000 --> 00:30:45,000 Questi sono alcuni dei temi che tratteremo, crypto, campo di applicazione, gli array, et cetera. 501 00:30:45,000 --> 00:30:49,000 Solo una breve parola sulla crittografia. Non stiamo andando a battere questa casa. 502 00:30:49,000 --> 00:30:52,000 >> Lo abbiamo fatto in pset 2, ma per il quiz assicurarsi di sapere la differenza 503 00:30:52,000 --> 00:30:54,000 tra il cifrario di Cesare e il cifrario Vigenère, 504 00:30:54,000 --> 00:30:57,000 come sia di quelli di lavoro cifre e cosa vuol dire per crittografare 505 00:30:57,000 --> 00:30:59,000 e decifrare il testo utilizzando questi 2 cifre. 506 00:30:59,000 --> 00:31:03,000 Ricorda, il cifrario di Cesare semplicemente ruota ogni carattere per lo stesso importo, 507 00:31:03,000 --> 00:31:06,000 avendo cura di mod per il numero di lettere dell'alfabeto. 508 00:31:06,000 --> 00:31:09,000 E il cifrario Vigenère, invece, ruota ogni carattere 509 00:31:09,000 --> 00:31:12,000 da un importo diverso, quindi, invece di dire 510 00:31:12,000 --> 00:31:15,000 ogni rotazione di caratteri del 3 Vigenère ruoterà ogni carattere 511 00:31:15,000 --> 00:31:17,000 di una quantità diversa a seconda qualche parola 512 00:31:17,000 --> 00:31:20,000 dove ogni lettera la parola chiave rappresenta una certa quantità differente 513 00:31:20,000 --> 00:31:26,000 per ruotare il testo chiaro. 514 00:31:26,000 --> 00:31:28,000 Parliamo innanzitutto sulla portata variabile. 515 00:31:28,000 --> 00:31:30,000 Ci sono 2 tipi diversi di variabili. 516 00:31:30,000 --> 00:31:33,000 Abbiamo variabili locali, e questi saranno definiti 517 00:31:33,000 --> 00:31:36,000 al di fuori della principale o fuori di ogni funzione o blocco, 518 00:31:36,000 --> 00:31:39,000 e questi saranno accessibili in qualsiasi punto del programma. 519 00:31:39,000 --> 00:31:41,000 Se si dispone di una funzione e in tale funzione è un ciclo while 520 00:31:41,000 --> 00:31:44,000 la grande variabile globale è accessibile ovunque. 521 00:31:44,000 --> 00:31:48,000 Una variabile locale, invece, è nell'ambito del luogo in cui è definita. 522 00:31:48,000 --> 00:31:53,000 >> Se si dispone di una funzione di qui, per esempio, abbiamo questa funzione g, 523 00:31:53,000 --> 00:31:56,000 e all'interno di g è una variabile denominata qui y, 524 00:31:56,000 --> 00:31:58,000 e ciò significa che si tratta di una variabile locale. 525 00:31:58,000 --> 00:32:00,000 Anche se questa variabile si chiama y 526 00:32:00,000 --> 00:32:03,000 e questa variabile si chiama y queste 2 funzioni 527 00:32:03,000 --> 00:32:06,000 non hanno idea di ciò che le variabili locali di ciascuno sono. 528 00:32:06,000 --> 00:32:10,000 D'altra parte, qui diciamo int x = 5, 529 00:32:10,000 --> 00:32:12,000 e questo è fuori della portata di qualsiasi funzione. 530 00:32:12,000 --> 00:32:16,000 E 'al di fuori del campo di applicazione principale, quindi questa è una variabile globale. 531 00:32:16,000 --> 00:32:20,000 Ciò significa che all'interno di queste 2 funzioni quando dico x - x + o + 532 00:32:20,000 --> 00:32:26,000 Sto x l'accesso alla stessa in base al quale questo e questo y y sono variabili diverse. 533 00:32:26,000 --> 00:32:30,000 Questa è la differenza tra una variabile globale e una variabile locale. 534 00:32:30,000 --> 00:32:33,000 Per quanto riguarda il design è interessato, a volte è probabilmente una migliore idea 535 00:32:33,000 --> 00:32:37,000 per mantenere le variabili locali ogni volta che il possibile 536 00:32:37,000 --> 00:32:39,000 dal momento che avere un gruppo di variabili globali può ottenere davvero confuso. 537 00:32:39,000 --> 00:32:42,000 Se hai un po 'di tutte le funzioni modificare la stessa cosa 538 00:32:42,000 --> 00:32:45,000 si può dimenticare ciò che se questa funzione modifica accidentalmente questo mondiale, 539 00:32:45,000 --> 00:32:47,000 e questa funzione altro non può sapere nulla, 540 00:32:47,000 --> 00:32:50,000 e lo fa ottenere abbastanza confuso come si ottiene più codice. 541 00:32:50,000 --> 00:32:53,000 Mantenere le variabili locali ogni volta che il possibile 542 00:32:53,000 --> 00:32:56,000 è il design solo buono. 543 00:32:56,000 --> 00:33:00,000 Array, ricordate, sono semplicemente liste di elementi dello stesso tipo. 544 00:33:00,000 --> 00:33:04,000 All'interno di CI non può avere un elenco come 1, 2.0, ciao. 545 00:33:04,000 --> 00:33:06,000 Noi non possiamo farlo. 546 00:33:06,000 --> 00:33:11,000 >> Quando si dichiara una matrice in C tutti gli elementi devono essere dello stesso tipo. 547 00:33:11,000 --> 00:33:14,000 Qui ho un array di 3 interi. 548 00:33:14,000 --> 00:33:18,000 Qui ho la lunghezza della matrice, ma se sto solo dichiarare in questa sintassi 549 00:33:18,000 --> 00:33:21,000 dove specificare tutti gli elementi che non sono tecnicamente bisogno di questo 3. 550 00:33:21,000 --> 00:33:25,000 Il compilatore è abbastanza intelligente da capire quanto è grande l'array dovrebbe essere. 551 00:33:25,000 --> 00:33:28,000 Ora, quando voglio ottenere o impostare il valore di un array 552 00:33:28,000 --> 00:33:30,000 questa è la sintassi per farlo. 553 00:33:30,000 --> 00:33:33,000 Questo effettivamente modificare il secondo elemento della matrice perché, ricordate, 554 00:33:33,000 --> 00:33:36,000 numerazione parte da 0, non da 1. 555 00:33:36,000 --> 00:33:42,000 Se voglio leggere quel valore che posso dire qualcosa di simile int x = array [1]. 556 00:33:42,000 --> 00:33:44,000 Oppure, se voglio impostare tale valore, come sto facendo qui, 557 00:33:44,000 --> 00:33:47,000 Posso dire array [1] = 4. 558 00:33:47,000 --> 00:33:50,000 Quella volta l'accesso a elementi dal loro indice 559 00:33:50,000 --> 00:33:52,000 o loro posizione o quando sono nella matrice, 560 00:33:52,000 --> 00:33:57,000 e che la quotazione parte da 0. 561 00:33:57,000 --> 00:34:00,000 Possiamo anche avere array di array, 562 00:34:00,000 --> 00:34:03,000 e questo si chiama un array multi-dimensionale. 563 00:34:03,000 --> 00:34:05,000 Quando abbiamo un array multi-dimensionale 564 00:34:05,000 --> 00:34:07,000 questo significa che può avere qualcosa di simile a righe e colonne, 565 00:34:07,000 --> 00:34:11,000 e questo è solo un modo di visualizzare questo o di pensarci. 566 00:34:11,000 --> 00:34:14,000 Quando ho un array multi-dimensionale che significa che ho intenzione di iniziare a dover 567 00:34:14,000 --> 00:34:17,000 più di 1 indice perché se ho una griglia 568 00:34:17,000 --> 00:34:19,000 solo dicendo quello che sei in fila non ci dà un numero. 569 00:34:19,000 --> 00:34:22,000 Questo è in realtà solo ci darà una lista di numeri. 570 00:34:22,000 --> 00:34:25,000 Diciamo che ho questo array qui. 571 00:34:25,000 --> 00:34:30,000 Ho un array denominato griglia, e io sto dicendo che è 2 righe e 3 colonne, 572 00:34:30,000 --> 00:34:32,000 e quindi questo è un modo di visualizzarlo. 573 00:34:32,000 --> 00:34:37,000 Quando dico che voglio ottenere l'elemento in [1] [2] 574 00:34:37,000 --> 00:34:41,000 ciò significa che, poiché si tratta di righe e poi le colonne 575 00:34:41,000 --> 00:34:44,000 Ho intenzione di passare alla riga 1 da quando ho detto 1. 576 00:34:44,000 --> 00:34:49,000 >> Poi ho intenzione di venire qui a colonna 2, e ho intenzione di ottenere il valore 6. 577 00:34:49,000 --> 00:34:51,000 Fai senso? 578 00:34:51,000 --> 00:34:55,000 Array multidimensionali, ricordiamo, sono tecnicamente solo un array di array. 579 00:34:55,000 --> 00:34:57,000 Possiamo avere array di array di array. 580 00:34:57,000 --> 00:35:00,000 Siamo in grado di andare avanti, ma in realtà un modo di pensare 581 00:35:00,000 --> 00:35:03,000 come questo è organizzato e quello che sta succedendo è quello di visualizzarlo 582 00:35:03,000 --> 00:35:09,000 in una griglia come questo. 583 00:35:09,000 --> 00:35:12,000 Quando si passa di array a funzioni, che stanno andando a comportarsi 584 00:35:12,000 --> 00:35:16,000 un po 'diverso rispetto a quando si passa alle funzioni variabili regolari 585 00:35:16,000 --> 00:35:18,000 come passare un int o un float. 586 00:35:18,000 --> 00:35:21,000 Quando si passa in un tipo int o char o uno qualsiasi di questi altri dati 587 00:35:21,000 --> 00:35:24,000 abbiamo appena preso uno sguardo se la funzione modifica 588 00:35:24,000 --> 00:35:28,000 il valore di tale variabile che il cambiamento non sta per propagare fino 589 00:35:28,000 --> 00:35:32,000 alla funzione chiamante. 590 00:35:32,000 --> 00:35:35,000 Con un array, invece, che avverrà. 591 00:35:35,000 --> 00:35:39,000 Se passo in un array ad una funzione e che funzione cambia alcuni elementi, 592 00:35:39,000 --> 00:35:43,000 quando torno fino alla funzione che l'ha chiamata 593 00:35:43,000 --> 00:35:47,000 il mio array è ora di andare a essere diverso, e il vocabolario di tale 594 00:35:47,000 --> 00:35:50,000 è array sono passati per riferimento, come vedremo più avanti. 595 00:35:50,000 --> 00:35:53,000 Questo è legato al modo in cui il lavoro puntatori, dove questi tipi di dati di base, 596 00:35:53,000 --> 00:35:55,000 d'altra parte, sono passati per valore. 597 00:35:55,000 --> 00:35:59,000 >> Si può pensare a questo come fare una copia di una variabile e poi passare nella copia. 598 00:35:59,000 --> 00:36:01,000 Non importa ciò che facciamo con quella variabile. 599 00:36:01,000 --> 00:36:06,000 La funzione chiamante non saranno consapevoli del fatto che è stato cambiato. 600 00:36:06,000 --> 00:36:10,000 Gli array sono solo un po 'diverso al riguardo. 601 00:36:10,000 --> 00:36:13,000 Per esempio, come abbiamo appena visto, principale è semplicemente una funzione 602 00:36:13,000 --> 00:36:15,000 che può prendere in 2 argomenti. 603 00:36:15,000 --> 00:36:20,000 Il primo argomento della funzione principale è argc, o il numero di argomenti, 604 00:36:20,000 --> 00:36:23,000 e il secondo argomento è chiamato argv, 605 00:36:23,000 --> 00:36:27,000 e questi sono i valori effettivi di tali argomenti. 606 00:36:27,000 --> 00:36:30,000 Diciamo che ho un programma chiamato this.c, 607 00:36:30,000 --> 00:36:34,000 e lo dico fare questo, e ho intenzione di eseguire questo nella riga di comando. 608 00:36:34,000 --> 00:36:38,000 Ora per passare alcuni argomenti al mio programma che si chiama questo, 609 00:36:38,000 --> 00:36:42,000 Potrei dire una cosa del genere. / Questa è la cs 50. 610 00:36:42,000 --> 00:36:45,000 Questo è ciò che immaginiamo David a fare tutti i giorni presso il terminale. 611 00:36:45,000 --> 00:36:48,000 Ma ora l'interno funzione principale di tale programma 612 00:36:48,000 --> 00:36:52,000 ha questi valori, quindi argc è 4. 613 00:36:52,000 --> 00:36:56,000 Potrebbe essere un po 'di confusione perché in realtà siamo solo di passaggio in è cs 50. 614 00:36:56,000 --> 00:36:58,000 Questo è solo 3. 615 00:36:58,000 --> 00:37:02,000 Ma ricordate che il primo elemento di argv o il primo argomento 616 00:37:02,000 --> 00:37:05,000 è il nome della funzione stessa. 617 00:37:05,000 --> 00:37:07,190 Quindi questo significa che ci sono 4 cose qui, 618 00:37:07,190 --> 00:37:10,530 e il primo elemento sarà. / questo. 619 00:37:10,530 --> 00:37:12,970 E questo sarà rappresentato come una stringa. 620 00:37:12,970 --> 00:37:18,590 Poi i restanti elementi sono ciò che digitato dopo il nome del programma. 621 00:37:18,590 --> 00:37:22,720 Così come una parte, come abbiamo probabilmente visto in pset 2, 622 00:37:22,720 --> 00:37:28,780 ricordare che la stringa 50 è il numero intero ≠ 50. 623 00:37:28,780 --> 00:37:32,520 Quindi non si può dire una cosa del genere, 'int x = argv 3.' 624 00:37:32,520 --> 00:37:36,470 >> Ma non è solo andare a dare un senso, perché questa è una stringa, e questo è un numero intero. 625 00:37:36,470 --> 00:37:38,510 Quindi, se si desidera convertire tra i 2, ricordate, stiamo andando a 626 00:37:38,510 --> 00:37:40,810 hanno questa funzione magica chiamata atoi. 627 00:37:40,810 --> 00:37:46,270 Che prende una stringa e restituisce il numero intero rappresentato all'interno di quella stringa. 628 00:37:46,270 --> 00:37:48,360 Ecco, questo è un errore facile da fare il quiz, 629 00:37:48,360 --> 00:37:51,590 solo pensare che questo sarà automaticamente il tipo corretto. 630 00:37:51,590 --> 00:37:53,860 Ma è sufficiente sapere che questi saranno sempre essere stringhe 631 00:37:53,860 --> 00:38:00,920 anche se la stringa contiene solo un numero intero o un personaggio o di un galleggiante. 632 00:38:00,920 --> 00:38:03,380 Così ora parliamo di tempo di esecuzione. 633 00:38:03,380 --> 00:38:06,700 Quando abbiamo tutti questi algoritmi che fanno tutte queste cose folli, 634 00:38:06,700 --> 00:38:11,580 diventa davvero utile a porre la domanda: "Quanto tempo hanno preso?" 635 00:38:11,580 --> 00:38:15,500 Noi rappresentiamo che con qualcosa chiamato notazione asintotica. 636 00:38:15,500 --> 00:38:18,430 Quindi questo significa che - beh, diciamo che diamo il nostro algoritmo 637 00:38:18,430 --> 00:38:20,840 alcuni input davvero, davvero, davvero grande. 638 00:38:20,840 --> 00:38:23,840 Vogliamo fare la domanda, "quanto tempo ci vorrà? 639 00:38:23,840 --> 00:38:26,370 Quante misure intende prendere il nostro algoritmo per l'esecuzione 640 00:38:26,370 --> 00:38:29,980 in funzione della dimensione dell'input? " 641 00:38:29,980 --> 00:38:33,080 Quindi il primo modo possiamo descrivere fase di esecuzione è con grande O. 642 00:38:33,080 --> 00:38:35,380 E questo è il nostro caso peggiore tempo di esecuzione. 643 00:38:35,380 --> 00:38:38,590 Quindi, se si desidera ordinare un array, e diamo il nostro algoritmo di un array 644 00:38:38,590 --> 00:38:41,000 che è in ordine decrescente, mentre dovrebbe essere in ordine crescente, 645 00:38:41,000 --> 00:38:43,130 che sta per essere il caso peggiore. 646 00:38:43,130 --> 00:38:49,800 Questo è il nostro limite superiore della lunghezza massima di tempo nostro algoritmo avrà. 647 00:38:49,800 --> 00:38:54,740 D'altra parte, questa Ω sta per descrivere caso migliore tempo di esecuzione. 648 00:38:54,740 --> 00:38:58,210 Quindi, se diamo un array già ordinati ad un algoritmo di ordinamento, 649 00:38:58,210 --> 00:39:00,940 quanto tempo ci vorrà per risolvere la cosa? 650 00:39:00,940 --> 00:39:06,610 E questo, poi, descrive un limite inferiore sul tempo di esecuzione. 651 00:39:06,610 --> 00:39:10,980 Così qui sono solo alcune parole che descrivono alcuni momenti comuni di funzionamento. 652 00:39:10,980 --> 00:39:13,120 Questi sono in ordine crescente. 653 00:39:13,120 --> 00:39:16,060 Il tempo di esecuzione più veloce che abbiamo si chiama costante. 654 00:39:16,060 --> 00:39:19,800 >> Ciò significa che non importa quanti elementi diamo il nostro algoritmo, 655 00:39:19,800 --> 00:39:22,280 non importa quanto grande è la nostra gamma, smistamento 656 00:39:22,280 --> 00:39:26,510 o fare tutto ciò che stiamo facendo per l'array avrà sempre la stessa quantità di tempo. 657 00:39:26,510 --> 00:39:30,270 Quindi possiamo rappresentare che solo con un 1, che è una costante. 658 00:39:30,270 --> 00:39:32,410 Abbiamo anche guardato in fase di esecuzione logaritmico. 659 00:39:32,410 --> 00:39:34,800 Quindi, qualcosa come la ricerca binaria è logaritmica, 660 00:39:34,800 --> 00:39:37,140 dove tagliare il problema a metà ogni volta 661 00:39:37,140 --> 00:39:40,970 e poi le cose solo ottenere più da lì. 662 00:39:40,970 --> 00:39:43,580 E se si sta scrivendo un mai O di qualsiasi algoritmo fattoriale, 663 00:39:43,580 --> 00:39:47,850 probabilmente non dovrebbe considerare questo come il vostro lavoro di giorno. 664 00:39:47,850 --> 00:39:53,910 Quando confrontiamo tempi di esecuzione è importante tenere a mente queste cose. 665 00:39:53,910 --> 00:39:57,760 Quindi, se ho un algoritmo che è O (n), e qualcun altro 666 00:39:57,760 --> 00:40:03,590 è un algoritmo di O (2n) questi sono realmente asintoticamente equivalenti. 667 00:40:03,590 --> 00:40:06,590 Quindi, se immaginiamo di n per essere un numero grande come eleventy miliardi di euro: 668 00:40:06,590 --> 00:40:13,090 così quando stiamo confrontando eleventy miliardi a qualcosa di simile eleventy miliardi + 3, 669 00:40:13,090 --> 00:40:17,640 improvvisamente che tre in realtà non fare una grande differenza più. 670 00:40:17,640 --> 00:40:20,980 È per questo che abbiamo intenzione di cominciare a considerare queste cose equivalenti. 671 00:40:20,980 --> 00:40:24,220 Quindi le cose come queste costanti qui, ci sono 2 x questo, o l'aggiunta di un 3, 672 00:40:24,220 --> 00:40:27,180 queste sono solo costanti, e questi stanno per cadere up. 673 00:40:27,180 --> 00:40:32,480 Ecco perché tutti e 3 di questi tempi di funzionamento sono gli stessi dicendo che sono O (n). 674 00:40:32,480 --> 00:40:37,490 Allo stesso modo, se abbiamo 2 tempi di esecuzione di altri, diciamo O (n + 2n ³ ²), possiamo aggiungere 675 00:40:37,490 --> 00:40:42,070 + N, + 7, e poi abbiamo un altro in fase di esecuzione che è solo O (n ³). 676 00:40:42,070 --> 00:40:46,290 ancora, questi sono la stessa cosa perché questi - questi non sono gli stessi. 677 00:40:46,290 --> 00:40:49,840 Queste sono le stesse cose, mi dispiace. Quindi questi sono gli stessi perché 678 00:40:49,840 --> 00:40:53,090 questa ³ n sta per dominare questa ² 2n. 679 00:40:53,090 --> 00:40:59,130 >> Ciò che non è la stessa cosa è se abbiamo tempi di esecuzione come O (³ n) e O (n ²) 680 00:40:59,130 --> 00:41:02,820 perché questo ³ n è molto più grande di questo ² n. 681 00:41:02,820 --> 00:41:05,470 Quindi, se abbiamo esponenti, improvvisamente questa comincia ad essere importante, 682 00:41:05,470 --> 00:41:08,280 ma quando siamo solo che fare con fattori come noi siamo qui, 683 00:41:08,280 --> 00:41:12,810 quindi non sta andando alla materia perché sono solo andando a cadere fuori. 684 00:41:12,810 --> 00:41:16,760 Diamo uno sguardo ad alcuni degli algoritmi che abbiamo visto fino ad ora 685 00:41:16,760 --> 00:41:19,260 e parlare della loro fase di esecuzione. 686 00:41:19,260 --> 00:41:23,850 Il primo modo di cercare un numero in un elenco, che abbiamo visto, era ricerca lineare. 687 00:41:23,850 --> 00:41:26,950 E l'attuazione della ricerca lineare è super semplice. 688 00:41:26,950 --> 00:41:30,490 Non ci resta che una lista, e stiamo andando a guardare ogni singolo elemento della lista 689 00:41:30,490 --> 00:41:34,260 fino a trovare il numero che stiamo cercando. 690 00:41:34,260 --> 00:41:38,370 In modo che significa che nel caso peggiore, questo O (n). 691 00:41:38,370 --> 00:41:40,860 E il caso peggiore qui potrebbe essere se l'elemento è 692 00:41:40,860 --> 00:41:45,710 l'ultimo elemento, quindi utilizzando ricerca lineare dobbiamo guardare ogni singolo elemento 693 00:41:45,710 --> 00:41:50,180 fino ad arrivare all'ultima, per sapere che era in realtà nella lista. 694 00:41:50,180 --> 00:41:52,910 Non possiamo rinunciare a metà strada e dire: "Probabilmente non è lì." 695 00:41:52,910 --> 00:41:55,980 Con la ricerca lineare, dobbiamo guardare a tutta la faccenda. 696 00:41:55,980 --> 00:41:59,090 Il caso migliore tempo di esecuzione, invece, è costante 697 00:41:59,090 --> 00:42:04,200 perché nel migliore dei casi l'elemento che stiamo cercando è solo il primo della lista. 698 00:42:04,200 --> 00:42:08,930 Quindi sta per portarci esattamente 1 punto, non importa quanto grande l'elenco è 699 00:42:08,930 --> 00:42:12,140 se stiamo cercando il primo elemento ogni volta. 700 00:42:12,140 --> 00:42:15,390 >> Così, quando si esegue una ricerca, ricordate, non è necessario che la nostra lista sia ordinata. 701 00:42:15,390 --> 00:42:19,430 Perché stiamo semplicemente andando a guardare su ogni singolo elemento, e non ha molta importanza 702 00:42:19,430 --> 00:42:23,560 quale ordine questi elementi trovi 703 00:42:23,560 --> 00:42:28,110 Un algoritmo di ricerca più intelligente è qualcosa di simile ricerca binaria. 704 00:42:28,110 --> 00:42:31,500 Ricordate, l'implementazione della ricerca binaria è quando si sta andando a 705 00:42:31,500 --> 00:42:34,320 continuare a guardare il mezzo della lista. 706 00:42:34,320 --> 00:42:38,000 E poiché stiamo guardando al centro, è necessario che l'elenco è ordinato 707 00:42:38,000 --> 00:42:40,580 altrimenti non sappiamo dove al centro è, e dobbiamo guardare oltre 708 00:42:40,580 --> 00:42:44,480 l'intera lista di trovarlo, e poi a quel punto stiamo solo perdendo tempo. 709 00:42:44,480 --> 00:42:48,480 Quindi, se abbiamo una lista ordinata e si trova al centro, andremo a confrontare la media 710 00:42:48,480 --> 00:42:51,590 l'elemento che stiamo cercando. 711 00:42:51,590 --> 00:42:54,640 Se è troppo alta, allora possiamo dimenticare la metà destra 712 00:42:54,640 --> 00:42:57,810 perché sappiamo che se il nostro elemento è già troppo alta 713 00:42:57,810 --> 00:43:01,080 e tutto a destra di questo elemento è ancora più elevata, 714 00:43:01,080 --> 00:43:02,760 allora non c'è bisogno di guardare più lì. 715 00:43:02,760 --> 00:43:05,430 Dove invece, se il nostro elemento è troppo basso, 716 00:43:05,430 --> 00:43:08,700 sappiamo tutto a sinistra di tale elemento è troppo bassa, 717 00:43:08,700 --> 00:43:11,390 quindi non ha molto senso cercare nemmeno lì. 718 00:43:11,390 --> 00:43:15,760 In questo modo, ad ogni passo e ogni volta che guardiamo a metà della lista, 719 00:43:15,760 --> 00:43:19,060 stiamo andando a tagliare il nostro problema in due perché improvvisamente sappiamo 720 00:43:19,060 --> 00:43:23,040 un sacco di numeri che non possono essere quello che stiamo cercando. 721 00:43:23,040 --> 00:43:26,950 >> In pseudocodice questo sarebbe qualcosa di simile, 722 00:43:26,950 --> 00:43:30,990 e perché stiamo tagliando la lista a metà ogni volta, 723 00:43:30,990 --> 00:43:34,920 i nostri nel caso peggiore salta run da lineare a logaritmica. 724 00:43:34,920 --> 00:43:39,260 Così improvvisamente abbiamo log-in fasi, al fine di trovare un elemento in una lista. 725 00:43:39,260 --> 00:43:42,460 Il miglior tempo di esecuzione caso, però, è ancora costante 726 00:43:42,460 --> 00:43:45,180 perché ora, limitiamoci a dire che l'elemento che stiamo cercando è 727 00:43:45,180 --> 00:43:48,380 sempre al centro esatto della lista originale. 728 00:43:48,380 --> 00:43:52,080 Così possiamo far crescere il nostro elenco come grande quanto vogliamo, ma se l'elemento che stiamo cercando è al centro, 729 00:43:52,080 --> 00:43:54,910 allora è solo andare a prendere noi 1 passo. 730 00:43:54,910 --> 00:44:00,920 Ecco perché siamo O (log n) e Ω (1) o costante. 731 00:44:00,920 --> 00:44:04,510 Facciamo effettivamente eseguire ricerca binaria su questa lista. 732 00:44:04,510 --> 00:44:08,020 Quindi diciamo che stiamo cercando per l'elemento 164. 733 00:44:08,020 --> 00:44:11,650 La prima cosa che ci accingiamo a fare è trovare il punto medio di questo elenco. 734 00:44:11,650 --> 00:44:15,060 Si dà il caso che il punto centrale sta per cadere in mezzo a questi 2 numeri, 735 00:44:15,060 --> 00:44:18,960 così facciamo solo arbitrariamente dire, ogni volta che il punto medio è compreso tra 2 numeri, 736 00:44:18,960 --> 00:44:21,150 facciamo solo arrotondare. 737 00:44:21,150 --> 00:44:24,330 Abbiamo solo bisogno di essere sicuri di fare questo ogni passo del cammino. 738 00:44:24,330 --> 00:44:29,040 Quindi stiamo andando a radunare, e stiamo andando a dire che 161 è il centro della nostra lista. 739 00:44:29,040 --> 00:44:34,640 So 161 <164, e ogni elemento a sinistra di 161 740 00:44:34,640 --> 00:44:39,120 è anche <164, quindi sappiamo che non sta andando per aiutare noi a tutti 741 00:44:39,120 --> 00:44:42,690 per iniziare a cercare qui, perché l'elemento che stiamo cercando non può essere lì. 742 00:44:42,690 --> 00:44:47,060 Quindi, ciò che possiamo fare è che possiamo solo dimenticare che la metà tutta a sinistra della lista, 743 00:44:47,060 --> 00:44:51,700 e ora in considerazione solo dalla destra del poi 161. 744 00:44:51,700 --> 00:44:54,050 >> Quindi, di nuovo, questo è il punto centrale, diciamo solo arrotondare. 745 00:44:54,050 --> 00:44:56,260 Ora, 175 è troppo grande. 746 00:44:56,260 --> 00:44:59,180 Quindi sappiamo che non sta andando per aiutarci a guardare qui o qui, 747 00:44:59,180 --> 00:45:06,610 in modo che possiamo semplicemente gettare via tutto, e alla fine ci ha colpito la 164. 748 00:45:06,610 --> 00:45:10,560 Hai domande su ricerca binaria? 749 00:45:10,560 --> 00:45:14,180 Passiamo da ricerca attraverso un elenco già ordinato 750 00:45:14,180 --> 00:45:17,660 a prendere effettivamente una lista di numeri in qualsiasi ordine 751 00:45:17,660 --> 00:45:20,960 e fare l'elenco in ordine crescente. 752 00:45:20,960 --> 00:45:24,060 Il primo algoritmo abbiamo guardato è stato chiamato bubble sort. 753 00:45:24,060 --> 00:45:27,300 E questo sarebbe più semplice degli algoritmi che abbiamo visto. 754 00:45:27,300 --> 00:45:32,970 Bubble sort dice che quando le 2 elementi all'interno della lista sono fuori luogo, 755 00:45:32,970 --> 00:45:36,500 cioè non vi è un numero superiore a sinistra di un numero inferiore, 756 00:45:36,500 --> 00:45:40,190 poi andremo a scambiare, perché questo significa che l'elenco sarà 757 00:45:40,190 --> 00:45:42,860 "Più ordinato" di quanto non fosse prima. 758 00:45:42,860 --> 00:45:45,180 E stiamo solo andando a continuare questo processo di nuovo e ancora e ancora 759 00:45:45,180 --> 00:45:52,100 finché alla fine il tipo elementi di bolla alla loro posizione corretta e abbiamo una lista ordinata. 760 00:45:52,100 --> 00:45:57,230 >> Il tempo di esecuzione di questa sta per essere O (n ²). Perché? 761 00:45:57,230 --> 00:46:00,370 Bene, perché nel peggiore dei casi, stiamo andando a prendere ogni elemento, e 762 00:46:00,370 --> 00:46:04,570 stiamo andando a finire confronto ad ogni altro elemento della lista. 763 00:46:04,570 --> 00:46:08,030 Ma nel migliore dei casi, abbiamo un elenco già ordinato, sorta di bolla 764 00:46:08,030 --> 00:46:12,230 solo andando a passare attraverso una volta, dire "No.. non ho fatto alcuna swap, quindi ho finito." 765 00:46:12,230 --> 00:46:17,410 Quindi abbiamo un caso migliore tempo di esecuzione di Ω (n). 766 00:46:17,410 --> 00:46:20,680 Corriamo a bolle in un elenco. 767 00:46:20,680 --> 00:46:23,560 Oppure, facciamo solo un'occhiata ad alcuni pseudocodice molto velocemente. 768 00:46:23,560 --> 00:46:28,160 Vogliamo dire che vogliamo tenere traccia di, in ogni iterazione del ciclo, 769 00:46:28,160 --> 00:46:32,190 tenere traccia di se o non abbiamo cambiato elementi. 770 00:46:32,190 --> 00:46:37,610 Così la ragione di ciò è, stiamo andando a fermarsi quando non abbiamo scambiato alcun elemento. 771 00:46:37,610 --> 00:46:41,980 Così, alla partenza del nostro ciclo non abbiamo scambiato nulla, quindi dovremo dire che è falso. 772 00:46:41,980 --> 00:46:47,170 Ora, stiamo per scorrere l'elenco e confrontare elementi i per elemento i + 1 773 00:46:47,170 --> 00:46:50,310 e se è il caso che vi è un numero grande a sinistra di un numero minore, 774 00:46:50,310 --> 00:46:52,310 allora stiamo solo andando a scambiarle. 775 00:46:52,310 --> 00:46:54,490 >> E poi andiamo a ricordare che ci siamo scambiati un elemento. 776 00:46:54,490 --> 00:46:58,900 Questo significa che abbiamo bisogno di scorrere l'elenco almeno 1 più tempo 777 00:46:58,900 --> 00:47:02,160 perché la condizione in cui si è fermato quando l'intero elenco è già ordinato, 778 00:47:02,160 --> 00:47:04,890 che significa che non sono state apportate swap. 779 00:47:04,890 --> 00:47:09,960 Ecco perché la nostra condizione quaggiù è 'mentre alcuni elementi sono stati scambiati.' 780 00:47:09,960 --> 00:47:13,720 Quindi ora facciamo solo guardare a questa esecuzione su un elenco. 781 00:47:13,720 --> 00:47:16,640 Ho la lista 5,0,1,6,4. 782 00:47:16,640 --> 00:47:19,850 Bubble sort sta per iniziare tutta la strada a sinistra, e sta andando a confrontare 783 00:47:19,850 --> 00:47:24,700 gli elementi i, in modo da 0 a i + 1, che è l'elemento 1. 784 00:47:24,700 --> 00:47:29,020 Sta andando a dire ben 5> 0, ma in questo momento 5 è a sinistra, 785 00:47:29,020 --> 00:47:32,500 quindi ho bisogno di scambiare il 5 e lo 0. 786 00:47:32,500 --> 00:47:35,470 Quando li scambiano, improvvisamente ho questa lista diversa. 787 00:47:35,470 --> 00:47:38,260 Ora 5> 1, quindi stiamo andando per scambiarle. 788 00:47:38,260 --> 00:47:42,160 5 non è> 6, quindi non abbiamo bisogno di fare nulla qui. 789 00:47:42,160 --> 00:47:46,690 Ma 6> 4, quindi abbiamo bisogno di scambiare. 790 00:47:46,690 --> 00:47:49,740 Ancora una volta, abbiamo bisogno di scorrere l'intera lista per scoprire alla fine 791 00:47:49,740 --> 00:47:52,330 che questi non sono in ordine, li scambiano, 792 00:47:52,330 --> 00:47:57,120 ea questo punto abbiamo bisogno di scorrere l'elenco degli orari altri 1 793 00:47:57,120 --> 00:48:05,390 fare in modo che tutto sia nel suo ordine, e, a questo punto bubble sort è terminato. 794 00:48:05,390 --> 00:48:10,720 Un algoritmo diverso per prendere alcuni elementi e lo smistamento è una sorta di selezione. 795 00:48:10,720 --> 00:48:15,740 L'idea alla base di ordinamento per selezione è che stiamo andando a costruire una parte ordinata della lista 796 00:48:15,740 --> 00:48:18,150 1 elemento alla volta. 797 00:48:18,150 --> 00:48:23,170 >> E il modo in cui abbiamo intenzione di farlo è quello di costruire il segmento sinistro della lista. 798 00:48:23,170 --> 00:48:27,510 E in fondo, tutti - ad ogni passo, stiamo andando a prendere il più piccolo elemento che abbiamo lasciato 799 00:48:27,510 --> 00:48:32,310 che non è stato ancora risolto, e abbiamo intenzione di spostarlo in quel segmento ordinato. 800 00:48:32,310 --> 00:48:35,850 Questo significa che abbiamo bisogno di trovare continuamente l'elemento minimo unsorted 801 00:48:35,850 --> 00:48:40,720 e poi prendere l'elemento minimo e scambiarlo con qualsiasi 802 00:48:40,720 --> 00:48:45,090 più a sinistra elemento che non è ordinato. 803 00:48:45,090 --> 00:48:50,890 Il tempo di esecuzione di questa sta per essere O (n ²), perché nel peggiore dei casi 804 00:48:50,890 --> 00:48:55,070 abbiamo bisogno di confrontare ogni singolo elemento di ogni altro elemento. 805 00:48:55,070 --> 00:48:59,250 Perché stiamo dicendo che se si inizia a metà sinistra della lista, abbiamo bisogno di 806 00:48:59,250 --> 00:49:02,970 passare attraverso l'intero segmento di destra per trovare l'elemento più piccolo. 807 00:49:02,970 --> 00:49:05,430 E poi, ancora una volta, abbiamo bisogno di andare oltre l'intero segmento di destra e 808 00:49:05,430 --> 00:49:08,210 andare avanti oltre che più e più e più volte. 809 00:49:08,210 --> 00:49:11,350 Questo sarà ² n. Stiamo andando a bisogno di un ciclo per interni di un altro ciclo for 810 00:49:11,350 --> 00:49:13,350 che suggerisce ² n. 811 00:49:13,350 --> 00:49:16,530 Nel pensiero migliore dei casi, diciamo che diamo un elenco già ordinato; 812 00:49:16,530 --> 00:49:19,270 in realtà non fare meglio di ² n. 813 00:49:19,270 --> 00:49:21,730 Perché per selezione non ha modo di sapere che 814 00:49:21,730 --> 00:49:25,540 l'elemento minimo è proprio quello che mi capita di essere alla ricerca di. 815 00:49:25,540 --> 00:49:28,970 Si deve ancora fare in modo che questo è in realtà il minimo. 816 00:49:28,970 --> 00:49:31,670 >> E l'unico modo per essere sicuri che sia il minimo, con questo algoritmo, 817 00:49:31,670 --> 00:49:34,640 è quello di esaminare ogni singolo elemento nuovo. 818 00:49:34,640 --> 00:49:38,420 Quindi, in realtà, se si dà - se si dà per selezione di un elenco già ordinato, 819 00:49:38,420 --> 00:49:42,720 non sta andando a fare di meglio che dare un elenco che non è ordinato ancora. 820 00:49:42,720 --> 00:49:46,320 Tra l'altro, se capita di essere il caso che qualcosa è O (qualcosa) 821 00:49:46,320 --> 00:49:50,640 e l'omega di qualcosa, possiamo solo dire più brevemente che si tratta di θ di qualcosa. 822 00:49:50,640 --> 00:49:52,760 Quindi, se si vede che vieni da nessuna parte, questo è ciò che significa semplicemente. 823 00:49:52,760 --> 00:49:57,580 >> Se qualcosa è theta di n ², è al tempo stesso grande O (n ²) e Ω (n ²). 824 00:49:57,580 --> 00:49:59,790 Quindi meglio e caso peggiore dei casi, non fa la differenza, 825 00:49:59,790 --> 00:50:04,400 l'algoritmo sta per fare la stessa cosa ogni volta. 826 00:50:04,400 --> 00:50:06,610 Quindi questo è quello che per pseudocodice per selezione potrebbe sembrare. 827 00:50:06,610 --> 00:50:10,630 Stiamo fondamentalmente per dire che voglio scorrere la lista 828 00:50:10,630 --> 00:50:15,180 da sinistra a destra, e ad ogni iterazione del ciclo, ho intenzione di spostare 829 00:50:15,180 --> 00:50:19,780 l'elemento minimo in questa porzione della lista ordinata. 830 00:50:19,780 --> 00:50:23,260 E una volta che mi muovo qualcosa, non ho mai bisogno di guardare a tale elemento nuovo. 831 00:50:23,260 --> 00:50:28,600 Perché non appena scambiare un elemento per il segmento sinistro della lista, è ordinato 832 00:50:28,600 --> 00:50:32,600 perché stiamo facendo tutto in ordine crescente in base minimi. 833 00:50:32,600 --> 00:50:38,740 Così abbiamo detto, okay, siamo nella posizione i, e abbiamo bisogno di guardare a tutti gli elementi 834 00:50:38,740 --> 00:50:42,260 a destra di i per trovare il minimo. 835 00:50:42,260 --> 00:50:46,150 Quindi significa che vogliamo guardare da i + 1 alla fine della lista. 836 00:50:46,150 --> 00:50:51,610 E ora, se l'elemento che stiamo attualmente esaminando sia inferiore al nostro minimo fino ad ora, 837 00:50:51,610 --> 00:50:54,190 che, ricordiamo, stiamo iniziando la bassa minima per essere solo 838 00:50:54,190 --> 00:50:57,020 qualsiasi elemento che siamo attualmente, darò per scontato che è il minimo. 839 00:50:57,020 --> 00:51:00,270 Se trovo un elemento che è più piccolo di quello, allora io sto per dire, va bene, 840 00:51:00,270 --> 00:51:02,700 bene, ho trovato un nuovo minimo. 841 00:51:02,700 --> 00:51:06,080 Io vado a ricordare dove fosse quel minimo. 842 00:51:06,080 --> 00:51:09,560 >> Così ora, una volta che ho vissuto quel segmento diritto indifferenziati, 843 00:51:09,560 --> 00:51:16,690 Posso dire che sto per scambiare l'elemento minimo con l'elemento che si trova in posizione i. 844 00:51:16,690 --> 00:51:21,100 Che sta per costruire la mia lista, la mia parte ordinata della lista da sinistra a destra, 845 00:51:21,100 --> 00:51:25,190 e non abbiamo mai bisogno di guardare a un elemento ancora una volta che è in quella parte. 846 00:51:25,190 --> 00:51:27,930 Una volta che l'abbiamo scambiato. 847 00:51:27,930 --> 00:51:30,260 Quindi cerchiamo di correre per selezione in questo elenco. 848 00:51:30,260 --> 00:51:38,220 L'elemento blu qui sta per essere la i, e l'elemento rosso sta per essere l'elemento minimo. 849 00:51:38,220 --> 00:51:41,570 Così ho avviato tutta la strada a sinistra della lista, quindi a 5. 850 00:51:41,570 --> 00:51:44,610 Ora abbiamo bisogno di trovare l'elemento minimo indifferenziati. 851 00:51:44,610 --> 00:51:49,480 Quindi diciamo 0 <5, così 0 è il mio nuovo minimo. 852 00:51:49,480 --> 00:51:53,820 >> Ma non riesco a smettere qui, perché, anche se siamo in grado di riconoscere che 0 è il più piccolo, 853 00:51:53,820 --> 00:51:59,390 abbiamo bisogno di correre attraverso ogni altro elemento della lista per essere sicuri. 854 00:51:59,390 --> 00:52:01,760 Quindi 1 è più grande, 6 è più grande, 4 è più grande. 855 00:52:01,760 --> 00:52:05,850 Ciò significa che, dopo aver guardato tutti questi elementi, ho determinato 0 è il più piccolo. 856 00:52:05,850 --> 00:52:09,800 Quindi ho intenzione di scambiare il 5 e lo 0. 857 00:52:09,800 --> 00:52:15,480 Una volta che scambiare, io vado a prendere un nuovo elenco, e so che non ho mai bisogno di guardare ancora una volta che 0 858 00:52:15,480 --> 00:52:19,380 perché una volta ho scambiato, ho risolto e abbiamo finito. 859 00:52:19,380 --> 00:52:22,730 Ora si da il caso che l'elemento blu è di nuovo il 5, 860 00:52:22,730 --> 00:52:26,030 e abbiamo bisogno di guardare l'1, il 6 e il 4 per determinare che 1 861 00:52:26,030 --> 00:52:31,520 è l'elemento più piccolo minimo, quindi dovremo scambiare l'1 e il 5. 862 00:52:31,520 --> 00:52:36,890 Ancora una volta, abbiamo bisogno di guardare - confrontare il 5 al 6 e il 4, 863 00:52:36,890 --> 00:52:39,830 e abbiamo intenzione di scambiare il 4 e il 5, e, infine, confrontare 864 00:52:39,830 --> 00:52:45,740 questi 2 numeri e scambiare loro fino a quando avremo il nostro elenco ordinato. 865 00:52:45,740 --> 00:52:49,730 Hai domande su ordinamento per selezione? 866 00:52:49,730 --> 00:52:56,420 Va bene. Passiamo all'ultimo argomento qui, e che è la ricorsione. 867 00:52:56,420 --> 00:52:59,810 >> Ricorsione, ricordiamo, è davvero cosa meta in cui una funzione 868 00:52:59,810 --> 00:53:02,740 chiama ripetutamente stessa. 869 00:53:02,740 --> 00:53:05,620 Così a un certo punto, mentre il nostro fuction viene ripetutamente che si definisce, 870 00:53:05,620 --> 00:53:10,100 ci deve essere un certo punto in cui ci fermiamo chiamarci. 871 00:53:10,100 --> 00:53:13,670 Perché se non lo facciamo, allora stiamo solo andando a continuare a farlo per sempre, 872 00:53:13,670 --> 00:53:16,660 e il nostro programma non è solo andare a terminare. 873 00:53:16,660 --> 00:53:19,200 Chiamiamo questa condizione il caso base. 874 00:53:19,200 --> 00:53:22,570 E il caso base, dice, piuttosto che chiamare una funzione ancora una volta, 875 00:53:22,570 --> 00:53:25,330 Sto solo andando a restituire un valore. 876 00:53:25,330 --> 00:53:28,080 Quindi, una volta che abbiamo restituito un valore, abbiamo smesso di chiamare noi stessi, 877 00:53:28,080 --> 00:53:32,550 e il resto delle chiamate che abbiamo fatto finora può anche restituire. 878 00:53:32,550 --> 00:53:36,050 L'opposto del caso base è il caso ricorsivo. 879 00:53:36,050 --> 00:53:39,050 E questo è quando si vuole effettuare un'altra chiamata alla funzione che siamo attualmente; 880 00:53:39,050 --> 00:53:44,690 E probabilmente, anche se non sempre, desidera utilizzare argomenti diversi. 881 00:53:44,690 --> 00:53:48,940 >> Quindi, se abbiamo una funzione chiamata f, f e ha chiamato prendere 1 argomento, 882 00:53:48,940 --> 00:53:52,010 e abbiamo appena continuano a chiamare f (1), f (1), f (1), e si dà il caso che 883 00:53:52,010 --> 00:53:56,510 l'argomento 1 cade in caso ricorsivo, stiamo ancora mai intenzione di smettere. 884 00:53:56,510 --> 00:54:01,620 Anche se abbiamo un caso base, abbiamo bisogno di fare in modo che alla fine stiamo andando a colpire quel caso base. 885 00:54:01,620 --> 00:54:04,250 Noi non solo continuare a stare in questo caso ricorsivo. 886 00:54:04,250 --> 00:54:09,870 In generale, quando ci chiamano, noi probabilmente stai andando ad avere un argomento diverso ogni volta. 887 00:54:09,870 --> 00:54:12,700 Ecco una funzione molto semplice ricorsiva. 888 00:54:12,700 --> 00:54:15,090 Quindi questo sarà calcolare il fattoriale di un numero. 889 00:54:15,090 --> 00:54:17,790 Fino all'inizio qui abbiamo il nostro scenario di base. 890 00:54:17,790 --> 00:54:22,330 Nel caso in cui n ≤ 1, non stiamo andando a chiamare fattoriale di nuovo. 891 00:54:22,330 --> 00:54:26,490 Stiamo andando a fermarsi, stiamo solo andando a restituire un valore. 892 00:54:26,490 --> 00:54:30,170 Se questo non è vero, allora stiamo andando a colpire il nostro caso ricorsivo. 893 00:54:30,170 --> 00:54:33,550 Notiamo qui che non stiamo solo chiamando fattoriale (n), perché non sarebbe molto utile. 894 00:54:33,550 --> 00:54:36,810 Stiamo andando a chiamare fattoriale di qualcosa d'altro. 895 00:54:36,810 --> 00:54:40,850 >> E così si può vedere, alla fine se si passa a qualcosa di fattoriale (5) o, 896 00:54:40,850 --> 00:54:45,900 stiamo andando a chiamare fattoriale (4) e così via, e alla fine stiamo andando a colpire tale scenario di base. 897 00:54:45,900 --> 00:54:51,730 Quindi questo sembra buono. Vediamo cosa succede quando in realtà esegue questo. 898 00:54:51,730 --> 00:54:57,840 Questa è la pila, e diciamo che si sta per chiamare questa funzione con un argomento (4). 899 00:54:57,840 --> 00:55:02,200 Quindi, una volta fattoriale vede e = 4, si fattoriale stessa chiamata. 900 00:55:02,200 --> 00:55:05,010 Ora, improvvisamente, abbiamo fattoriale (3). 901 00:55:05,010 --> 00:55:10,780 Quindi queste funzioni stanno per continuare a crescere fino alla fine abbiamo raggiunto il nostro scenario di base. 902 00:55:10,780 --> 00:55:17,830 A questo punto, il valore di ritorno di questo è il ritorno (nx il valore restituito), 903 00:55:17,830 --> 00:55:21,290 il valore di ritorno di questo nx è il valore di ritorno di questo. 904 00:55:21,290 --> 00:55:23,290 Alla fine abbiamo bisogno di colpire un certo numero. 905 00:55:23,290 --> 00:55:26,560 Nella parte superiore qui, diciamo di ritorno 1. 906 00:55:26,560 --> 00:55:30,650 Ciò significa che una volta che torniamo quel numero, siamo in grado di pop questo dallo stack. 907 00:55:30,650 --> 00:55:36,570 Quindi questo fattoriale (1) è fatto. 908 00:55:36,570 --> 00:55:41,190 Quando 1 restituisce, questo fattoriali (1) ritorna, questo ritorno alla 1. 909 00:55:41,190 --> 00:55:46,910 Il valore di ritorno di questo, ricordiamo, era nx il valore di ritorno di questo. 910 00:55:46,910 --> 00:55:50,720 Così improvvisamente, questo ragazzo sa che voglio tornare 2. 911 00:55:50,720 --> 00:55:55,910 >> Quindi ricorda, restituire valore di questo è solo nx il valore di ritorno qui. 912 00:55:55,910 --> 00:56:01,160 Così ora possiamo dire 3 x 2, e infine, qui si può dire 913 00:56:01,160 --> 00:56:04,010 questo è solo andare a essere 4 x 3 x 2. 914 00:56:04,010 --> 00:56:09,570 E una volta che questo ritorna, si arriva fino a un singolo intero all'interno del principale. 915 00:56:09,570 --> 00:56:15,460 Hai domande su ricorsione? 916 00:56:15,460 --> 00:56:17,090 Bene. Quindi c'è più tempo per le domande alla fine, 917 00:56:17,090 --> 00:56:23,360 ma ora Joseph abbraccia i temi rimanenti. 918 00:56:23,360 --> 00:56:25,590 >> [Joseph Ong] Va bene. Quindi, ora che abbiamo parlato di ricorsioni, 919 00:56:25,590 --> 00:56:27,840 parliamo un po 'di quello merge sort è. 920 00:56:27,840 --> 00:56:31,740 Merge sort è fondamentalmente un altro modo di ordinare un elenco di numeri. 921 00:56:31,740 --> 00:56:36,430 E come funziona è, con merge sort si dispone di un elenco e quello che facciamo è 922 00:56:36,430 --> 00:56:39,120 diciamo, cerchiamo di dividere questo in 2 metà. 923 00:56:39,120 --> 00:56:42,750 Ecco ora eseguire merge sort di nuovo sulla metà sinistra, 924 00:56:42,750 --> 00:56:45,040 poi ci eseguire merge sort nella metà destra, 925 00:56:45,040 --> 00:56:50,240 e che ci offre ora 2 tempi che sono ordinati, e ora stiamo andando a combinare questi due metà insieme. 926 00:56:50,240 --> 00:56:55,010 E 'un po' difficile da vedere senza un esempio, quindi andremo con i movimenti e vedere cosa succede. 927 00:56:55,010 --> 00:56:59,590 Quindi si parte da questa lista, abbiamo diviso in 2 metà. 928 00:56:59,590 --> 00:57:02,300 Noi usiamo merge sort sulla metà prima a sinistra. 929 00:57:02,300 --> 00:57:06,660 Ecco, questo è la metà sinistra, e ora che sono eseguiti, attraverso questa lista di nuovo 930 00:57:06,660 --> 00:57:09,800 che viene passato in merge sort, e poi guardiamo, ancora una volta, 931 00:57:09,800 --> 00:57:13,270 sul lato sinistro di questa lista e corriamo merge sort su di esso. 932 00:57:13,270 --> 00:57:15,880 Ora, scendere ad una lista di 2 numeri, 933 00:57:15,880 --> 00:57:19,010 e ora la metà di sinistra è solo 1 elemento a lungo, e non possiamo 934 00:57:19,010 --> 00:57:23,380 dividere un elenco che è solo 1 elemento in mezzo, quindi ci limitiamo a dire, una volta che abbiamo 50, 935 00:57:23,380 --> 00:57:26,400 che dista solo 1 elemento, è già ordinato. 936 00:57:26,400 --> 00:57:29,860 >> Una volta che abbiamo finito con questo, possiamo vedere che possiamo 937 00:57:29,860 --> 00:57:32,230 passare alla parte destra di questa lista, 938 00:57:32,230 --> 00:57:36,480 e 3 è anche ordinata, e ora che le due metà di questa lista sono ordinati 939 00:57:36,480 --> 00:57:39,080 siamo in grado di partecipare a questi numeri di nuovo insieme. 940 00:57:39,080 --> 00:57:45,320 Quindi guardiamo a 50 e 3, 3 è inferiore a 50, in modo che entri per primo e il 50 entra in gioco 941 00:57:45,320 --> 00:57:49,340 Ora, questo è fatto, si risale a quella lista e ordinare è metà di destra. 942 00:57:49,340 --> 00:57:52,440 42 è il suo numero, quindi è già ordinato. 943 00:57:52,440 --> 00:57:57,850 Così ora confrontiamo questi 2 e 3 è inferiore a 42, così che viene messo in prima, 944 00:57:57,850 --> 00:58:02,340 ora 42 viene messo in, e 50 viene messo dentro 945 00:58:02,340 --> 00:58:07,220 Ora, che è ordinato, si va tutta la strada verso l'alto, 1337 e 15. 946 00:58:07,220 --> 00:58:14,560 Bene, ora guardiamo alla metà sinistra della lista; 1337 è di per sé in modo che sia ordinato e lo stesso con 15. 947 00:58:14,560 --> 00:58:19,020 Così ora abbiamo combinare questi 2 numeri per ordinare la lista originale, 15 <1337, 948 00:58:19,020 --> 00:58:23,060 in modo che entri per primo, poi 1337 si trovi a 949 00:58:23,060 --> 00:58:26,640 E ora abbiamo risolto entrambe le metà della lista originale sulla parte superiore. 950 00:58:26,640 --> 00:58:30,440 E tutto quello che dobbiamo fare è combinare questi. 951 00:58:30,440 --> 00:58:36,890 Guardiamo i primi 2 numeri di questo elenco, 3 <15, così si va nella matrice odrina. 952 00:58:36,890 --> 00:58:44,460 15 <42, così si va in Ora, 42 <1337, che va trovi 953 00:58:44,460 --> 00:58:51,010 50 <1337, così si va in E notare che abbiamo appena preso 2 numeri di fuori di questo elenco. 954 00:58:51,010 --> 00:58:53,640 Quindi non stiamo solo alternando le 2 liste. 955 00:58:53,640 --> 00:58:56,050 Stiamo solo guardando l'inizio, e stiamo prendendo l'elemento 956 00:58:56,050 --> 00:59:00,270 che è più piccolo e poi metterlo nel nostro array. 957 00:59:00,270 --> 00:59:04,080 Ora che abbiamo unito tutte le parti e abbiamo finito. 958 00:59:04,080 --> 00:59:07,780 >> Avete domande su merge sort? Sì? 959 00:59:07,780 --> 00:59:14,190 [Studente] Se si tratta di dividere in gruppi diversi, perché non basta una volta divisi 960 00:59:14,190 --> 00:59:19,970 e si dispone di 3 e 2 in un gruppo? [Resto del incomprensibile domanda] 961 00:59:19,970 --> 00:59:24,940 La ragione - quindi la domanda è, perché non possiamo semplicemente si fondono in quel primo passo dopo li abbiamo? 962 00:59:24,940 --> 00:59:29,530 La ragione per cui siamo in grado di fare questo, partono più a sinistra gli elementi di entrambe le parti, 963 00:59:29,530 --> 00:59:33,040 e poi prendere quello più piccolo e metterlo dentro, è che sappiamo che queste 964 00:59:33,040 --> 00:59:35,290 singole liste sono ordinati negli ordini. 965 00:59:35,290 --> 00:59:37,290 Quindi, se io sto guardando più a sinistra gli elementi di entrambe le metà, 966 00:59:37,290 --> 00:59:40,490 So che sta andando ad essere i più piccoli elementi degli elenchi. 967 00:59:40,490 --> 00:59:43,930 Quindi posso metterli in luoghi più piccoli elementi di questo elenco di grandi dimensioni. 968 00:59:43,930 --> 00:59:47,810 D'altra parte, se guardo a quei 2 liste nel secondo livello laggiù, 969 00:59:47,810 --> 00:59:51,640 50, 3, 42, 1337 e 15, quelli che non sono ordinati. 970 00:59:51,640 --> 00:59:55,770 Quindi, se guardo a 50 e il 1337, ho intenzione di mettere 50 nel mio primo elenco. 971 00:59:55,770 --> 01:00:00,130 Ma che in realtà non ha senso, perché 3 è il più piccolo elemento di tutti quelli. 972 01:00:00,130 --> 01:00:04,390 Quindi l'unica ragione per cui siamo in grado di fare questo passo che unisce è perché le nostre liste sono già ordinati. 973 01:00:04,390 --> 01:00:07,010 Ed è per questo che dobbiamo scendere fino al fondo 974 01:00:07,010 --> 01:00:09,800 perché quando abbiamo solo un numero unico, si sa che un solo numero 975 01:00:09,800 --> 01:00:14,120 in sé e per sé è già un elenco ordinato. 976 01:00:14,120 --> 01:00:19,360 >> Hai ancora domande? No? 977 01:00:19,360 --> 01:00:24,260 Complessità? Beh, si può vedere che ad ogni passo ci sono i numeri finali, 978 01:00:24,260 --> 01:00:27,590 e possiamo dividere una lista in mezzo log n volte, 979 01:00:27,590 --> 01:00:31,700 che è dove riusciamo ad ottenere questo log n x n complessità. 980 01:00:31,700 --> 01:00:34,940 E vedrete il caso migliore per il merge sort è n log n, e si da il caso 981 01:00:34,940 --> 01:00:39,340 che il caso peggiore, o Ω là, anche n log n. 982 01:00:39,340 --> 01:00:42,480 Qualcosa da tenere a mente. 983 01:00:42,480 --> 01:00:45,750 Passando, andiamo a qualche lima eccellente di base di I / O. 984 01:00:45,750 --> 01:00:48,830 Se hai guardato Scramble, noterete che abbiamo avuto una sorta di sistema 985 01:00:48,830 --> 01:00:51,270 dove si poteva scrivere in un file di registro se si leggono attraverso il codice. 986 01:00:51,270 --> 01:00:53,730 Vediamo come si potrebbe fare. 987 01:00:53,730 --> 01:00:57,450 Bene, abbiamo fprintf, che si può pensare solo come printf, 988 01:00:57,450 --> 01:01:01,720 ma solo la stampa su un file, e quindi la f all'inizio. 989 01:01:01,720 --> 01:01:07,570 Questo tipo di codice qui, ciò che fa è, come forse avrete già visto in Scramble, 990 01:01:07,570 --> 01:01:12,310 passa attraverso il tuo a 2 dimensioni di stampa su matrice riga per riga quello che i numeri sono. 991 01:01:12,310 --> 01:01:17,850 In questo caso, stampa printf fuori al vostro terminale o quello che noi chiamiamo lo standard output di sezione. 992 01:01:17,850 --> 01:01:22,170 >> Ed ora, in questo caso, tutto quello che dobbiamo fare è sostituire printf con fprintf, 993 01:01:22,170 --> 01:01:26,770 indicare cosa file che si desidera stampare, e in questo caso si limita a stampare fuori a quel file 994 01:01:26,770 --> 01:01:32,230 invece di esso stampare sul terminale. 995 01:01:32,230 --> 01:01:36,500 Beh, allora che pone la domanda: Dove possiamo ottenere questo tipo di file da, giusto? 996 01:01:36,500 --> 01:01:39,840 Passammo accedere a questa fuction fprintf, ma non avevamo idea di dove venisse. 997 01:01:39,840 --> 01:01:43,980 Beh, all'inizio del codice, quello che avevamo era questo pezzo di codice qui, 998 01:01:43,980 --> 01:01:48,340 che in pratica dice che si aprono il file log.txt chiama. 999 01:01:48,340 --> 01:01:53,220 Quello che facciamo dopo che è che dobbiamo fare in modo che il file è in realtà aperto con successo. 1000 01:01:53,220 --> 01:01:57,070 Così potrebbe non riuscire per diverse ragioni, non si ha abbastanza spazio sul vostro computer, per esempio. 1001 01:01:57,070 --> 01:01:59,790 Quindi è sempre importante prima di fare qualsiasi operazione con il file 1002 01:01:59,790 --> 01:02:03,300 che verificare se il file è stato aperto con successo. 1003 01:02:03,300 --> 01:02:09,330 Allora, cosa che una, che è un argomento di fopen, beh, siamo in grado di aprire un file in molti modi. 1004 01:02:09,330 --> 01:02:13,510 Quello che possiamo fare è, possiamo passare w, il che significa che l'override del file se esistono già, 1005 01:02:13,510 --> 01:02:18,070 Siamo in grado di passare un a, che aggiungere alla fine del file, invece di scavalcarlo, 1006 01:02:18,070 --> 01:02:22,730 oppure possiamo specificare r, il che significa che, cerchiamo di aprire il file in sola lettura. 1007 01:02:22,730 --> 01:02:24,890 Quindi, se il programma tenta di apportare modifiche al file, 1008 01:02:24,890 --> 01:02:30,140 urlare contro di loro e non lasciarli fare. 1009 01:02:30,140 --> 01:02:33,320 Infine, una volta che abbiamo finito con il file, finito di fare le operazioni su di esso, 1010 01:02:33,320 --> 01:02:35,860 abbiamo bisogno di essere sicuri di chiudere il file. 1011 01:02:35,860 --> 01:02:38,830 E così, alla fine del programma, che si sta per passare di nuovo 1012 01:02:38,830 --> 01:02:42,120 questo file che è stato aperto, e basta chiuderla. 1013 01:02:42,120 --> 01:02:44,650 Quindi questa è una cosa importante che si deve fare in modo di fare. 1014 01:02:44,650 --> 01:02:47,180 Quindi ricorda è possibile aprire un file, allora si può scrivere nel file, 1015 01:02:47,180 --> 01:02:51,270 fare operazioni nel file, ma poi si deve chiudere il file alla fine. 1016 01:02:51,270 --> 01:02:53,270 >> Hai domande su file di base di I / O? Sì? 1017 01:02:53,270 --> 01:02:58,050 [Domanda Studente, incomprensibile] 1018 01:02:58,050 --> 01:03:02,480 Proprio qui. La domanda è: da dove viene questo file log.txt apparire? 1019 01:03:02,480 --> 01:03:07,890 Beh, se basta dare log.txt, lo crea nella stessa directory del file eseguibile. 1020 01:03:07,890 --> 01:03:10,500 Quindi, se tu sei - >> [domanda Studente, incomprensibile] 1021 01:03:10,500 --> 01:03:18,830 Sì. Nella stessa cartella, o nella stessa directory, come la chiami tu. 1022 01:03:18,830 --> 01:03:21,400 Ora la memoria, stack e heap. 1023 01:03:21,400 --> 01:03:23,400 Così come è la memoria di cui nel computer? 1024 01:03:23,400 --> 01:03:26,270 Beh, si può immaginare come una sorta di memoria di questo blocco qui. 1025 01:03:26,270 --> 01:03:30,260 E in memoria abbiamo quello che si chiama il mucchio bloccato laggiù, e lo stack che è laggiù. 1026 01:03:30,260 --> 01:03:34,480 E l'heap cresce verso il basso e lo stack cresce verso l'alto. 1027 01:03:34,480 --> 01:03:38,620 Così come Tommy detto - oh, bene, e abbiamo questi altri 4 segmenti che ci arriverò in un secondo - 1028 01:03:38,620 --> 01:03:42,890 Come Tommy detto in precedenza, si sa come le sue funzioni si dicono e si chiamano? 1029 01:03:42,890 --> 01:03:44,930 Essi costruire questo tipo di stack frame. 1030 01:03:44,930 --> 01:03:47,360 Beh, se le chiamate principali pippo, pippo viene messa in pila. 1031 01:03:47,360 --> 01:03:52,430 Foo chiama bar, get messa in pila, e che viene messa in pila dopo. 1032 01:03:52,430 --> 01:03:57,040 E tornano, a ciascuno di essi preso dallo stack. 1033 01:03:57,040 --> 01:04:00,140 Cosa ciascuno di questi luoghi e la memoria tenere? 1034 01:04:00,140 --> 01:04:03,110 Ebbene, la parte superiore, che è il segmento di testo, comprende il programma stesso. 1035 01:04:03,110 --> 01:04:06,390 Quindi, il codice macchina, che è lì, una volta che la compilazione del programma. 1036 01:04:06,390 --> 01:04:08,520 Quindi, qualsiasi inizializzate le variabili globali. 1037 01:04:08,520 --> 01:04:12,660 >> In modo da avere le variabili globali nel programma, e si dice come, a = 5, 1038 01:04:12,660 --> 01:04:15,260 che viene messo in questo segmento, e proprio in forza di tale, 1039 01:04:15,260 --> 01:04:18,990 si dispone di tutti i dati non inizializzati globali, che si sta int a, 1040 01:04:18,990 --> 01:04:20,990 ma non dire che è uguale a niente. 1041 01:04:20,990 --> 01:04:23,870 Realizzare questi sono variabili globali, quindi sono al di fuori della principale. 1042 01:04:23,870 --> 01:04:28,560 Quindi questo significa che tutte le variabili globali che vengono dichiarate ma non sono inizializzati. 1043 01:04:28,560 --> 01:04:32,310 Così che cosa è nel mucchio? La memoria allocata con malloc, che ci arriveremo tra un po '. 1044 01:04:32,310 --> 01:04:35,990 E, infine, con lo stack avete qualche variabili locali 1045 01:04:35,990 --> 01:04:39,950 e tutte le funzioni che si potrebbe chiamare in uno qualsiasi dei loro parametri. 1046 01:04:39,950 --> 01:04:43,720 L'ultima cosa, in realtà non è necessario sapere quali sono le variabili di ambiente fare, 1047 01:04:43,720 --> 01:04:46,700 ma ogni volta che si esegue programma, c'è qualcosa di associato, come 1048 01:04:46,700 --> 01:04:49,550 questo è il nome della persona che ha eseguito il programma. 1049 01:04:49,550 --> 01:04:51,550 E che sta per essere una sorta di in fondo. 1050 01:04:51,550 --> 01:04:54,540 In termini di indirizzi di memoria, che sono i valori esadecimali, 1051 01:04:54,540 --> 01:04:58,170 i valori iniziali in alto a 0, e si fanno tutta la strada fino in fondo. 1052 01:04:58,170 --> 01:05:00,440 In questo caso, se siete sul sistema a 32 bit, 1053 01:05:00,440 --> 01:05:05,390 l'indirizzo in fondo sta per essere 0x, seguito da af, perché è a 32 bit, 1054 01:05:05,390 --> 01:05:10,890 che è di 8 byte, e in questo caso 8 byte corrisponde a 8 cifre esadecimali. 1055 01:05:10,890 --> 01:05:20,110 Quindi, qui si sta andando ad avere, come, 0xffffff, e lassù si sta andando ad avere 0. 1056 01:05:20,110 --> 01:05:23,660 Quindi quali sono i puntatori? Alcuni di voi non hanno coperto in questa sezione prima. 1057 01:05:23,660 --> 01:05:26,660 ma abbiamo fatto andare su di esso in conferenza, quindi un puntatore è solo un tipo di dati 1058 01:05:26,660 --> 01:05:34,030 quali negozi, invece di una sorta di valore come 50, memorizza l'indirizzo di qualche posizione nella memoria. 1059 01:05:34,030 --> 01:05:36,020 Come quella memoria [incomprensibile]. 1060 01:05:36,020 --> 01:05:41,120 Quindi, in questo caso, ciò che abbiamo è, abbiamo un puntatore ad un intero o un int *, 1061 01:05:41,120 --> 01:05:46,210 e contiene l'indirizzo esadecimale di 0xDEADBEEF. 1062 01:05:46,210 --> 01:05:50,880 >> Quindi ciò che abbiamo è, ora, questo puntatore punta a un certo indirizzo di memoria, 1063 01:05:50,880 --> 01:05:56,020 e questo è solo uno, il valore di 50 è in questa posizione di memoria. 1064 01:05:56,020 --> 01:06:01,810 Su alcuni sistemi a 32 bit, su tutti i sistemi a 32 bit, i puntatori occupano 32 bit o 4 byte. 1065 01:06:01,810 --> 01:06:06,020 Ma, per esempio, su un sistema a 64 bit, i puntatori sono 64 bit. 1066 01:06:06,020 --> 01:06:08,040 Ecco, questo è qualcosa che si vorrà tenere a mente. 1067 01:06:08,040 --> 01:06:12,310 Quindi, su un end-bit del sistema, un puntatore è bit di fascia lunga. 1068 01:06:12,310 --> 01:06:17,320 I puntatori sono una sorta di difficili da digerire senza cose in più, 1069 01:06:17,320 --> 01:06:20,300 quindi cerchiamo di passare attraverso un esempio di allocazione dinamica della memoria. 1070 01:06:20,300 --> 01:06:25,130 Che allocazione dinamica della memoria fa per voi, o ciò che noi chiamiamo malloc, 1071 01:06:25,130 --> 01:06:29,280 vi permette di assegnare una sorta di dati al di fuori del set. 1072 01:06:29,280 --> 01:06:31,830 Quindi questo tipo di dati è più permanente per la durata del programma. 1073 01:06:31,830 --> 01:06:36,430 Perché, come si sa, se si dichiara x all'interno di una funzione, e che i ritorni di funzione, 1074 01:06:36,430 --> 01:06:40,910 non hai più accesso ai dati che sono stati memorizzati in x. 1075 01:06:40,910 --> 01:06:44,420 Cosa puntatori facciamo è che ci ha lasciato tenere i valori di memoria o un negozio 1076 01:06:44,420 --> 01:06:46,840 in un diverso segmento della memoria, cioè la heap. 1077 01:06:46,840 --> 01:06:49,340 Ora, una volta torniamo fuori della funzione, fino a quando abbiamo un puntatore 1078 01:06:49,340 --> 01:06:54,960 in quella posizione in memoria, quindi quello che possiamo fare è che può solo guardare i valori lì. 1079 01:06:54,960 --> 01:06:58,020 Vediamo un esempio: Questo è il nostro nuovo layout di memoria. 1080 01:06:58,020 --> 01:07:00,050 E noi abbiamo questa funzione principale. 1081 01:07:00,050 --> 01:07:06,870 Ciò che fa è - bene, così semplice, giusto? - Int x = 5, che è solo una variabile sullo stack in main. 1082 01:07:06,870 --> 01:07:12,450 >> D'altra parte, ora si dichiara un puntatore che chiama i giveMeThreeInts funzione. 1083 01:07:12,450 --> 01:07:16,800 E così ora andiamo in questa funzione e creare una nuova cornice dello stack per esso. 1084 01:07:16,800 --> 01:07:20,440 Tuttavia, in questo stack frame, dichiariamo int * temp, 1085 01:07:20,440 --> 01:07:23,210 che in mallocs 3 interi per noi. 1086 01:07:23,210 --> 01:07:25,880 Così dimensione di int ci darà il numero di byte int è questo, 1087 01:07:25,880 --> 01:07:29,620 malloc e ci dà tale numero di byte di spazio sul mucchio. 1088 01:07:29,620 --> 01:07:32,890 Quindi, in questo caso, abbiamo creato spazio sufficiente per 3 interi, 1089 01:07:32,890 --> 01:07:36,830 e l'heap è lassù, è per questo che ho disegnato più in alto. 1090 01:07:36,830 --> 01:07:42,900 Una volta che abbiamo finito, torniamo qui, avete solo bisogno di 3 int restituito, 1091 01:07:42,900 --> 01:07:47,000 e restituisce l'indirizzo, in questo caso oltre che la memoria in cui è. 1092 01:07:47,000 --> 01:07:51,250 E noi ad impostare il puntatore = interruttore, e lì abbiamo solo un altro puntatore. 1093 01:07:51,250 --> 01:07:54,550 Ma che cosa restituisce la funzione è accatastato qui e scompare. 1094 01:07:54,550 --> 01:07:59,250 Così temperatura scompare, ma abbiamo ancora mantengono l'indirizzo del luogo in cui 1095 01:07:59,250 --> 01:08:01,850 quei 3 numeri interi sono dentro di rete. 1096 01:08:01,850 --> 01:08:06,180 Quindi, in questa serie, i puntatori sono limitate a livello locale per il telaio impilati, 1097 01:08:06,180 --> 01:08:09,860 ma la memoria a cui si riferiscono è nell'heap. 1098 01:08:09,860 --> 01:08:12,190 >> Ha senso? 1099 01:08:12,190 --> 01:08:14,960 [Studente] Può ripetere? >> [Joseph] Sì. 1100 01:08:14,960 --> 01:08:20,270 Quindi, se torno solo un po ', si vede che temperatura assegnata 1101 01:08:20,270 --> 01:08:23,500 un po 'di memoria sul mucchio lassù. 1102 01:08:23,500 --> 01:08:28,680 Così, quando questa funzione, giveMeThreeInts restituisce, questo stack qui sta andando a scomparire. 1103 01:08:28,680 --> 01:08:35,819 E con esso qualsiasi variabile, in questo caso, il puntatore che è stata assegnata in cornice impilati. 1104 01:08:35,819 --> 01:08:39,649 Questo sta andando a scomparire, ma dal momento che siamo tornati temperatura 1105 01:08:39,649 --> 01:08:46,330 e impostare il puntatore = temp, puntatore sta ora andando a puntare la stessa memoria di posizione come temperatura era. 1106 01:08:46,330 --> 01:08:50,370 Così ora, anche se si perde temperatura, tale puntatore locale, 1107 01:08:50,370 --> 01:08:59,109 si conservano ancora l'indirizzo di memoria di ciò che stava puntando verso l'interno di quel puntatore variabile. 1108 01:08:59,109 --> 01:09:03,740 Domande? Che può essere una specie di un argomento confusione se non sono andati su di esso nella sezione. 1109 01:09:03,740 --> 01:09:09,240 Siamo in grado, il TF sarà sicuramente andare su di esso e, naturalmente, siamo in grado di rispondere alle domande 1110 01:09:09,240 --> 01:09:11,500 al termine della sessione commenti per questo. 1111 01:09:11,500 --> 01:09:14,220 Ma questa è una sorta di un argomento complesso, e non ho più esempi che stanno per presentarsi 1112 01:09:14,220 --> 01:09:18,790 che aiuterà a chiarire ciò puntatori in realtà sono. 1113 01:09:18,790 --> 01:09:22,500 >> In questo caso, i puntatori sono equivalenti a matrici, 1114 01:09:22,500 --> 01:09:25,229 quindi posso solo utilizzare questo puntatore come la stessa cosa di un array int. 1115 01:09:25,229 --> 01:09:29,840 Quindi sono l'indicizzazione in 0, e cambiando il primo numero intero a 1, 1116 01:09:29,840 --> 01:09:39,689 cambiando il secondo intero per 2, e l'intero terzo a 3. 1117 01:09:39,689 --> 01:09:44,210 Quindi più sui puntatori. Beh, ricordo Binky. 1118 01:09:44,210 --> 01:09:48,319 In questo caso abbiamo assegnato un puntatore, o abbiamo dichiarato un puntatore, 1119 01:09:48,319 --> 01:09:52,760 ma inizialmente, quando ho appena dichiarato un puntatore, non è che punta a dovunque in memoria. 1120 01:09:52,760 --> 01:09:54,930 E 'solo i valori della spazzatura all'interno di esso. 1121 01:09:54,930 --> 01:09:56,470 Quindi non ho idea di dove questo puntatore punta a. 1122 01:09:56,470 --> 01:10:01,630 Esso ha un indirizzo che è appena riempito con 0 e 1, dove è stato inizialmente dichiarato. 1123 01:10:01,630 --> 01:10:04,810 Io non posso fare niente con questo fino a quando non chiama malloc su di esso 1124 01:10:04,810 --> 01:10:08,390 e poi mi dà un po 'di spazio nel mucchio, dove posso mettere i valori al suo interno. 1125 01:10:08,390 --> 01:10:11,980 Poi di nuovo, non so cosa c'è dentro di questa memoria. 1126 01:10:11,980 --> 01:10:16,780 Quindi la prima cosa che devo fare è verificare se il sistema ha memoria sufficiente 1127 01:10:16,780 --> 01:10:20,850 di darmi indietro 1 intero, in primo luogo, che è per questo che sto facendo questo controllo. 1128 01:10:20,850 --> 01:10:25,020 Se il puntatore è nullo, il che significa che essa non dispone di spazio sufficiente o qualche altro errore si è verificato, 1129 01:10:25,020 --> 01:10:26,320 quindi dovrei uscire dal mio programma. 1130 01:10:26,320 --> 01:10:29,400  Ma se così fosse successo, ora posso usare tale puntatore 1131 01:10:29,400 --> 01:10:35,020 e ciò che fa è puntatore * ne consegue in cui l'indirizzo è 1132 01:10:35,020 --> 01:10:38,480 dove tale valore è, e pone uguale ad 1. 1133 01:10:38,480 --> 01:10:41,850 Così qui, stiamo controllando se la memoria esistente. 1134 01:10:41,850 --> 01:10:45,380 >> Una volta che sai che esiste, si può mettere in esso 1135 01:10:45,380 --> 01:10:50,460 quale valore che si desidera mettere in esso, in questo caso 1. 1136 01:10:50,460 --> 01:10:53,060 Una volta che abbiamo finito con esso, è necessario liberare tale puntatore 1137 01:10:53,060 --> 01:10:57,160 perché abbiamo bisogno di tornare al sistema che memoria che hai chiesto, in primo luogo. 1138 01:10:57,160 --> 01:10:59,690 Poiché il computer non sa quando avremo finito con esso. 1139 01:10:59,690 --> 01:11:02,510 In questo caso stiamo dicendo esplicitamente, va bene, abbiamo finito con quel ricordo. 1140 01:11:02,510 --> 01:11:10,780 Se qualche altro processo di cui ha bisogno, un altro programma di cui ha bisogno, sentitevi liberi di andare avanti e prendere. 1141 01:11:10,780 --> 01:11:15,110 Quello che possiamo anche fare è che possiamo solo ottenere l'indirizzo delle variabili locali sul set. 1142 01:11:15,110 --> 01:11:19,080 Quindi x int è all'interno della cornice pila di principale. 1143 01:11:19,080 --> 01:11:23,060 E quando usiamo questo e commerciale, questo e operatore, ciò che fa è 1144 01:11:23,060 --> 01:11:27,310 prende x, ed x è solo alcuni dati in memoria, ma ha un indirizzo. 1145 01:11:27,310 --> 01:11:33,790 Si trova da qualche parte. Quindi chiamando & x, cosa che fa è che ci dà l'indirizzo di x. 1146 01:11:33,790 --> 01:11:38,430 In questo modo, stiamo facendo il punto indicazione di dove x è in memoria. 1147 01:11:38,430 --> 01:11:41,710 Ora dobbiamo solo fare qualcosa di simile a * x, stiamo andando ottenere 5 indietro. 1148 01:11:41,710 --> 01:11:43,820 La stella si chiama deferenziandolo. 1149 01:11:43,820 --> 01:11:46,640 Si segue l'indirizzo e si ottiene il valore di esso memorizzate. 1150 01:11:51,000 --> 01:11:53,310 >> Hai ancora domande? Sì? 1151 01:11:53,310 --> 01:11:56,500 [Studente] Se non si fanno le 3 punte cosa, ha ancora compilato? 1152 01:11:56,500 --> 01:11:59,490 Sì. Se non si esegue il 3-pointer cosa, è ancora in corso di compilazione, 1153 01:11:59,490 --> 01:12:02,720 ma ti faccio vedere cosa succede in un secondo, e senza fare che, 1154 01:12:02,720 --> 01:12:04,860 questo è ciò che noi chiamiamo una perdita di memoria. Lei non è dando il sistema 1155 01:12:04,860 --> 01:12:07,850 sostenere la sua memoria, così dopo un po 'il programma sta andando ad accumularsi 1156 01:12:07,850 --> 01:12:10,940 memoria che non è in uso, e niente altro può utilizzare. 1157 01:12:10,940 --> 01:12:15,750 Se hai mai visto Firefox con 1,5 milioni di kilobyte sul computer, 1158 01:12:15,750 --> 01:12:17,840 nel task manager, questo è quello che sta succedendo. 1159 01:12:17,840 --> 01:12:20,760 Hai una perdita di memoria nel programma che non è la manipolazione. 1160 01:12:23,080 --> 01:12:26,240 Così come puntatore lavoro aritmetica? 1161 01:12:26,240 --> 01:12:29,480 Beh, l'aritmetica dei puntatori è una sorta di indicizzazione, come in una matrice. 1162 01:12:29,480 --> 01:12:36,370 In questo caso, ho un puntatore, e quello che faccio e 'far puntare il puntatore al primo elemento 1163 01:12:36,370 --> 01:12:42,100 di questo array di 3 interi che ho assegnato. 1164 01:12:42,100 --> 01:12:46,670 Così ora che cosa faccio, puntatore stella cambia solo il primo elemento della lista. 1165 01:12:46,670 --> 01:12:49,140 Star Pointer +1 punti qui. 1166 01:12:49,140 --> 01:12:53,140 Così puntatore è qui, puntatore +1 è qui, puntatore +2 è qui. 1167 01:12:53,140 --> 01:12:56,610 >> Quindi, solo l'aggiunta di 1 è la stessa cosa che si muove lungo questa matrice. 1168 01:12:56,610 --> 01:12:59,880 Quello che facciamo è, quando facciamo uno puntatore si ottiene l'indirizzo qui, 1169 01:12:59,880 --> 01:13:04,180 e al fine di ottenere il valore qui, si mette una stella in da l'intera espressione 1170 01:13:04,180 --> 01:13:05,990 per risolvere il riferimento di esso. 1171 01:13:05,990 --> 01:13:09,940 Quindi, in questo caso, sto impostando la prima posizione in questo array a 1, 1172 01:13:09,940 --> 01:13:13,970 seconda posizione a 2, e la terza posizione a 3. 1173 01:13:13,970 --> 01:13:18,180 Allora quello che sto facendo qui è che sto stampando il nostro puntatore +1, 1174 01:13:18,180 --> 01:13:19,970 che dà solo a me 2. 1175 01:13:19,970 --> 01:13:23,650 Ora sto incremento del puntatore, in modo uguale puntatore puntatore +1, 1176 01:13:23,650 --> 01:13:26,780 che si muove in avanti. 1177 01:13:26,780 --> 01:13:30,810 E così ora se stampare puntatore +1, puntatore +1 è ora 3, 1178 01:13:30,810 --> 01:13:33,990 che in questo caso viene stampato 3. 1179 01:13:33,990 --> 01:13:36,560 E per qualcosa di gratuito, il puntatore che ho dato 1180 01:13:36,560 --> 01:13:40,540 deve essere rivolto all'inizio della matrice che sono tornato da malloc. 1181 01:13:40,540 --> 01:13:43,430 Quindi, in questo caso, se dovessi chiamare 3 proprio qui, questo non sarebbe giusto, 1182 01:13:43,430 --> 01:13:45,070 perché è nel mezzo della matrice. 1183 01:13:45,070 --> 01:13:48,820 Devo togliere per raggiungere la posizione originale 1184 01:13:48,820 --> 01:13:50,420 il punto iniziale del nome prima che io possa liberare. 1185 01:13:56,300 --> 01:13:58,450 Quindi, ecco un esempio più coinvolti. 1186 01:13:58,450 --> 01:14:03,360 In questo caso, stiamo assegnando 7 caratteri in un array di caratteri. 1187 01:14:03,360 --> 01:14:06,480 >> E in questo caso quello che stiamo facendo è che stiamo ciclare su il 6 primo di essi, 1188 01:14:06,480 --> 01:14:09,900 e li stiamo impostando alla Z. 1189 01:14:09,900 --> 01:14:13,350 Così, per int i = 0, i> 6, i + +, 1190 01:14:13,350 --> 01:14:16,220 Quindi, puntatore + i sarà solo ci darà, in questo caso, 1191 01:14:16,220 --> 01:14:20,860 puntatore, puntatore 1, 2 pointer, puntatore 3, e così via e così via nel ciclo. 1192 01:14:20,860 --> 01:14:24,040 Che cosa sta andando a fare è diventa tale indirizzo, dereferenziazioni per ottenere il valore, 1193 01:14:24,040 --> 01:14:27,440 e le modifiche che il valore di una Z. 1194 01:14:27,440 --> 01:14:30,350 Poi alla fine ricordate che questo è una stringa, giusto? 1195 01:14:30,350 --> 01:14:33,560 Tutte le stringhe devono terminare con il carattere nullo di terminazione. 1196 01:14:33,560 --> 01:14:38,620 Quindi, quello che faccio è in puntatore 6 Ho messo il carattere nullo di terminazione trovi 1197 01:14:38,620 --> 01:14:43,980 E ora quello che sto praticamente facendo qui sta attuando printf per una stringa, giusto? 1198 01:14:43,980 --> 01:14:46,190 >> Così, quando si printf ora quando è arrivato alla fine di una stringa? 1199 01:14:46,190 --> 01:14:48,230 Quando si colpisce il carattere nullo di terminazione. 1200 01:14:48,230 --> 01:14:52,030 Quindi, in questo caso, i punti puntatore originale fino all'inizio di questa matrice. 1201 01:14:52,030 --> 01:14:56,410 Stampare il primo carattere fuori. La muovo più di un. 1202 01:14:56,410 --> 01:14:58,420 A stampare quel personaggio fuori. Lo muovo sopra. 1203 01:14:58,420 --> 01:15:02,180 E continuare a fare questo fino a raggiungere la fine. 1204 01:15:02,180 --> 01:15:07,750 E ora il puntatore * finale sarà dereference questo e di ottenere il carattere di terminazione null indietro. 1205 01:15:07,750 --> 01:15:11,780 E così il mio ciclo while viene eseguito solo quando tale valore non è il carattere nullo di terminazione. 1206 01:15:11,780 --> 01:15:13,770 Così, ora uscire da questo ciclo. 1207 01:15:18,780 --> 01:15:21,180 E quindi se io sottrarre 6 da questo puntatore, 1208 01:15:21,180 --> 01:15:22,860 Torno fino all'inizio. 1209 01:15:22,860 --> 01:15:27,880 Ricordate, sto facendo questo perché devo andare all'inizio, al fine di liberarlo. 1210 01:15:27,880 --> 01:15:30,270 >> Quindi, so che era un sacco. Ci sono domande? 1211 01:15:30,270 --> 01:15:31,870 Per favore, sì? 1212 01:15:31,870 --> 01:15:36,610 [Incomprensibile domanda lo studente] 1213 01:15:36,610 --> 01:15:38,190 Si può dire che il più forte? Scusi. 1214 01:15:38,190 --> 01:15:44,140 [Studente] Sulla diapositiva a destra prima di liberare il puntatore, 1215 01:15:44,140 --> 01:15:47,300 in cui sono stati effettivamente cambiando il valore del puntatore? 1216 01:15:47,300 --> 01:15:50,370 [Giuseppe] Così, proprio qui. >> [Studente] Oh, va bene. 1217 01:15:50,370 --> 01:15:51,890 [Giuseppe] Così, ho un puntatore meno meno, a destra, 1218 01:15:51,890 --> 01:15:54,140 che si muove la cosa indietro di una, e poi l'ho liberare, 1219 01:15:54,140 --> 01:15:57,000 perché questo puntatore deve essere indicato all'inizio della matrice. 1220 01:15:57,000 --> 01:16:00,420 [Studente] Ma non sarebbe stato necessario se aveste fermato dopo quella linea. 1221 01:16:00,420 --> 01:16:03,130 [Giuseppe] Quindi, se avessi smesso dopo questo, questo sarebbe considerato una perdita di memoria, 1222 01:16:03,130 --> 01:16:04,810 perché non è stata eseguita la libera. 1223 01:16:04,810 --> 01:16:11,290 [Studente] I [incomprensibile] dopo le prime tre righe in cui si doveva puntatore +1 [incomprensibile]. 1224 01:16:11,290 --> 01:16:13,140 [Joseph] Uh-huh. Allora, qual è la domanda lì? 1225 01:16:13,140 --> 01:16:14,780 Scusi. No, no. Andate, andate, per favore. 1226 01:16:14,780 --> 01:16:16,870 [Studente] Quindi, non stai cambiando il valore dei puntatori. 1227 01:16:16,870 --> 01:16:19,130 Non avrebbe dovuto fare puntatore meno meno. 1228 01:16:19,130 --> 01:16:19,730 [Giuseppe] Sì, esattamente. 1229 01:16:19,730 --> 01:16:21,890 Così, quando faccio puntatore puntatore +1 e +2, 1230 01:16:21,890 --> 01:16:24,410 Non sto facendo il puntatore è uguale puntatore +1. 1231 01:16:24,410 --> 01:16:27,260 Quindi, il puntatore rimane semplicemente puntando all'inizio della matrice. 1232 01:16:27,260 --> 01:16:31,460 E 'solo quando lo faccio plus plus che imposta il valore di nuovo dentro il puntatore, 1233 01:16:31,460 --> 01:16:33,550 che si muove in realtà questo insieme. 1234 01:16:36,860 --> 01:16:37,780 Bene. 1235 01:16:40,550 --> 01:16:42,030 Altre domande? 1236 01:16:44,680 --> 01:16:47,790 >> Ancora una volta, se questa è una sorta di travolgente, questo sarà coperto in sessione. 1237 01:16:47,790 --> 01:16:50,710 Chiedi al tuo compagno di insegnare, e siamo in grado di rispondere alle domande alla fine. 1238 01:16:53,510 --> 01:16:56,600 E di solito non ci piace fare questa cosa meno. 1239 01:16:56,600 --> 01:16:59,760 Questo ha a che mi obbligano tenere traccia di quanto ho compensato nella matrice. 1240 01:16:59,760 --> 01:17:04,520 Quindi, in generale, questo è solo per spiegare come funziona aritmetica dei puntatori. 1241 01:17:04,520 --> 01:17:07,970 Ma ciò che di solito piace fare è ci piace creare una copia del puntatore, 1242 01:17:07,970 --> 01:17:11,640 e poi useremo la copia quando ci stiamo muovendo in giro per la stringa. 1243 01:17:11,640 --> 01:17:14,660 Così, in questi casi si utilizza la copia per stampare l'intera stringa, 1244 01:17:14,660 --> 01:17:19,040 ma non c'è bisogno di fare come puntatore meno 6 o tenere traccia di quanto ci siamo trasferiti in questo, 1245 01:17:19,040 --> 01:17:22,700 solo perché sappiamo che il nostro punto di partenza è ancora indicato l'inizio della lista 1246 01:17:22,700 --> 01:17:25,340 e tutto ciò che abbiamo modificato era questa copia. 1247 01:17:25,340 --> 01:17:28,250 Quindi, in generale, alterare copie del puntatore originale. 1248 01:17:28,250 --> 01:17:32,350 Non cercare di specie di - Don 't modificare copie originali. 1249 01:17:32,350 --> 01:17:35,290 Cercando di modificare solo le copie degli originali. 1250 01:17:41,540 --> 01:17:44,870 Quindi, si nota quando si passa la stringa in printf 1251 01:17:44,870 --> 01:17:48,990 non c'è bisogno di mettere una stella di fronte ad essa come abbiamo fatto con tutti gli altri dereferenziazioni, giusto? 1252 01:17:48,990 --> 01:17:54,180 Quindi, se si stampa l'intera stringa% s si aspetta è un indirizzo, 1253 01:17:54,180 --> 01:17:57,610 e in questo caso un puntatore o in questo caso come un array di caratteri. 1254 01:17:57,610 --> 01:18:00,330 >> Personaggi, char * s, e gli array sono la stessa cosa. 1255 01:18:00,330 --> 01:18:03,690 Pointer è quello di caratteri e array di caratteri sono la stessa cosa. 1256 01:18:03,690 --> 01:18:05,720 E così, tutto quello che dobbiamo fare è passare il puntatore. 1257 01:18:05,720 --> 01:18:08,150 Non c'è bisogno di passare come puntatore * o qualcosa di simile. 1258 01:18:13,110 --> 01:18:14,930 Così, vettori e puntatori sono la stessa cosa. 1259 01:18:14,930 --> 01:18:19,160 Quando si sta facendo qualcosa di simile x [y] qui per un array, 1260 01:18:19,160 --> 01:18:21,960 quello che sta facendo sotto il cofano è che sta dicendo, va bene, si tratta di un array di caratteri, 1261 01:18:21,960 --> 01:18:23,690 quindi è un puntatore. 1262 01:18:23,690 --> 01:18:26,510 E così x sono la stessa cosa, 1263 01:18:26,510 --> 01:18:28,650 e così ciò che fa è si aggiunge y a x, 1264 01:18:28,650 --> 01:18:31,820 che è la stessa cosa di andare avanti nella memoria più di tanto. 1265 01:18:31,820 --> 01:18:34,930 E ora x + y ci dà una specie di indirizzo, 1266 01:18:34,930 --> 01:18:37,570 e noi dereference l'indirizzo o seguire la freccia 1267 01:18:37,570 --> 01:18:41,640 al punto in cui quella posizione in memoria è e si ottiene il valore di quella posizione in memoria. 1268 01:18:41,640 --> 01:18:43,720 Così, per cui questi due sono esattamente la stessa cosa. 1269 01:18:43,720 --> 01:18:45,840 E 'solo uno zucchero sintattico. 1270 01:18:45,840 --> 01:18:48,090 Fanno la stessa cosa. Sono solo sintattica diversi uno per l'altro. 1271 01:18:51,500 --> 01:18:57,590 >> Allora, che cosa può andare male con i puntatori? Come, molto. Va bene. Quindi, cose cattive. 1272 01:18:57,590 --> 01:19:02,410 Alcune cose cattive che si possono fare non si verifica se la chiamata malloc restituisce null, giusto? 1273 01:19:02,410 --> 01:19:06,560 In questo caso, mi sto chiedendo il sistema di darmi - qual è quel numero? 1274 01:19:06,560 --> 01:19:11,200 Come 2 miliardi di volte 4, poiché la dimensione di un numero intero di 4 byte. 1275 01:19:11,200 --> 01:19:13,810 Mi sto chiedendo come 8 miliardi di byte. 1276 01:19:13,810 --> 01:19:17,270 Naturalmente il computer non sarà in grado di darmi quella schiena di memoria. 1277 01:19:17,270 --> 01:19:20,960 E non abbiamo fatto controllare se questo è nullo, in modo che quando si cerca di dereferenziarlo laggiù - 1278 01:19:20,960 --> 01:19:24,270 seguite la freccia per dove sta andando a - non abbiamo che la memoria. 1279 01:19:24,270 --> 01:19:27,150 Questo è ciò che noi chiamiamo dereference un puntatore nullo. 1280 01:19:27,150 --> 01:19:29,710 E questo fa sì che essenzialmente di segfault. 1281 01:19:29,710 --> 01:19:31,790 Questo è uno dei modi in cui puoi segfault. 1282 01:19:34,090 --> 01:19:38,090 Altre cose cattive che si possono fare - oh, va bene. 1283 01:19:38,090 --> 01:19:40,650 Questo è stato dereference un puntatore nullo. Va bene. 1284 01:19:40,650 --> 01:19:45,160 Altre cose cattive - bene, per risolvere questo basta mettere un check-in vi 1285 01:19:45,160 --> 01:19:46,980 che controlla se il puntatore è nullo 1286 01:19:46,980 --> 01:19:51,000 e uscire dal programma se accade che malloc restituisce un puntatore nullo. 1287 01:19:55,110 --> 01:19:59,850 Questo è il fumetto xkcd. La gente lo capisco adesso. Più o meno. 1288 01:20:06,120 --> 01:20:09,350 >> Quindi, la memoria. E sono andato su questo. 1289 01:20:09,350 --> 01:20:12,000 Stiamo chiamando malloc in un ciclo, ma ogni volta che chiamiamo malloc 1290 01:20:12,000 --> 01:20:14,370 stiamo perdendo traccia di dove questo puntatore punta a, 1291 01:20:14,370 --> 01:20:15,750 perché stiamo sovrascrivere. 1292 01:20:15,750 --> 01:20:18,410 Quindi, la chiamata iniziale a malloc mi dà la memoria qui. 1293 01:20:18,410 --> 01:20:19,990 I miei puntatori puntatore a questo. 1294 01:20:19,990 --> 01:20:23,020 Ora, io non lo liberare, così ora io chiamo malloc di nuovo. 1295 01:20:23,020 --> 01:20:26,070 Ora che punti qui. Ora la mia memoria è di puntamento sopra qui. 1296 01:20:26,070 --> 01:20:27,640 Indicare qui. Indicare qui. 1297 01:20:27,640 --> 01:20:31,820 Ma ho perso il conto degli indirizzi di tutta la memoria qui che ho assegnato. 1298 01:20:31,820 --> 01:20:35,100 E così ora non ho alcun riferimento a loro più. 1299 01:20:35,100 --> 01:20:37,230 Quindi, non posso liberare al di fuori di questo ciclo. 1300 01:20:37,230 --> 01:20:39,390 E così, al fine di risolvere una cosa del genere, 1301 01:20:39,390 --> 01:20:42,250 se si dimentica di liberare la memoria e si ottiene questa perdita di memoria, 1302 01:20:42,250 --> 01:20:45,810 È necessario liberare la memoria interna di questo ciclo una volta che hai fatto con esso. 1303 01:20:45,810 --> 01:20:51,400 Bene, questo è ciò che accade. So che molti di voi Odio tutto questo. 1304 01:20:51,400 --> 01:20:55,270 Ma ora - yay! Si ottiene come 44.000 kilobyte. 1305 01:20:55,270 --> 01:20:57,110 Quindi, si libera alla fine del ciclo, 1306 01:20:57,110 --> 01:20:59,770 e che sta andando a liberare solo la memoria ogni volta. 1307 01:20:59,770 --> 01:21:03,620 In sostanza, il programma non dispone di una perdita di memoria più. 1308 01:21:03,620 --> 01:21:08,150 >> E ora qualcosa di diverso si può fare è liberare la memoria che hai chiesto per due volte. 1309 01:21:08,150 --> 01:21:11,060 In questo caso, una cosa malloc, cambi il suo valore. 1310 01:21:11,060 --> 01:21:13,140 Lo liberare una volta, perché hai detto che sono stati fatti con esso. 1311 01:21:13,140 --> 01:21:14,940 Ma poi lo abbiamo liberato di nuovo. 1312 01:21:14,940 --> 01:21:16,730 Questo è qualcosa che è piuttosto male. 1313 01:21:16,730 --> 01:21:18,820 E non ha intenzione di segfault inizialmente, 1314 01:21:18,820 --> 01:21:23,350 ma dopo un po 'ciò che questo non fa altro che doppio liberando questo corrompe la struttura heap, 1315 01:21:23,350 --> 01:21:27,200 e potrai imparare un po 'di più su questo se si sceglie di prendere una classe come CS61. 1316 01:21:27,200 --> 01:21:30,000 Ma in sostanza dopo un po 'il computer sta per confondersi 1317 01:21:30,000 --> 01:21:33,010 su ciò che locazioni di memoria in cui sono e dove è memorizzato - 1318 01:21:33,010 --> 01:21:34,800 in cui i dati sono memorizzati nella memoria. 1319 01:21:34,800 --> 01:21:38,080 E così liberare un puntatore è due volte un male che non si vuole fare. 1320 01:21:38,080 --> 01:21:41,600 >> Altre cose che possono andare male non utilizza sizeof. 1321 01:21:41,600 --> 01:21:44,460 Quindi, in questo caso si malloc 8 byte, 1322 01:21:44,460 --> 01:21:46,700 e questa è la stessa cosa di due interi, giusto? 1323 01:21:46,700 --> 01:21:49,580 Quindi, questo è perfettamente sicuro, ma è vero? 1324 01:21:49,580 --> 01:21:52,160 Beh, come Lucas ha parlato su differenti architetture, 1325 01:21:52,160 --> 01:21:54,220 interi sono di lunghezze diverse. 1326 01:21:54,220 --> 01:21:57,970 Così, l 'apparecchio che si sta utilizzando, numeri interi sono circa 4 byte, 1327 01:21:57,970 --> 01:22:02,370 ma su qualche altro sistema potrebbero essere 8 byte o potrebbero essere di 16 byte. 1328 01:22:02,370 --> 01:22:05,680 Quindi, se mi basta usare questo numero qui, 1329 01:22:05,680 --> 01:22:07,310 questo programma potrebbe funzionare l'apparecchio, 1330 01:22:07,310 --> 01:22:10,360 ma non ha intenzione di allocare memoria sufficiente su qualche altro sistema. 1331 01:22:10,360 --> 01:22:14,020 In questo caso, questo è ciò che l'operatore sizeof viene utilizzato per. 1332 01:22:14,020 --> 01:22:16,880 Quando chiamiamo sizeof (int), cosa che fa è 1333 01:22:16,880 --> 01:22:21,910  ci dà la dimensione di un intero nel sistema che il programma è in esecuzione. 1334 01:22:21,910 --> 01:22:25,490 Quindi, in questo caso, sizeof (int) restituisce 4 su qualcosa come l'apparecchio, 1335 01:22:25,490 --> 01:22:29,980 e ora questo 4 * volontà 2, che è 8, 1336 01:22:29,980 --> 01:22:32,330 che è solo la quantità di spazio necessario per due interi. 1337 01:22:32,330 --> 01:22:36,710 Su un sistema diverso, se un int è come 16 byte o 8 byte, 1338 01:22:36,710 --> 01:22:39,380 è solo andare per tornare abbastanza byte per memorizzare tale importo. 1339 01:22:41,830 --> 01:22:45,310 >> E, infine, le strutture. 1340 01:22:45,310 --> 01:22:48,340 Quindi, se si vuole memorizzare una scheda di sudoku in memoria, come potremmo fare? 1341 01:22:48,340 --> 01:22:51,570 Si potrebbe pensare di come una variabile per la prima cosa, 1342 01:22:51,570 --> 01:22:53,820 una variabile per la seconda cosa, una variabile per la terza cosa, 1343 01:22:53,820 --> 01:22:56,420 una variabile per la quarta cosa - male, vero? 1344 01:22:56,420 --> 01:23:00,750 Così, un miglioramento che si può fare al di sopra di questo è di fare un 9 x 9 matrice. 1345 01:23:00,750 --> 01:23:04,480 Va bene, ma cosa succede se si desidera associare l'altro con la scheda di sudoku 1346 01:23:04,480 --> 01:23:06,490 come quello che la difficoltà della scheda è, 1347 01:23:06,490 --> 01:23:11,740 o, ad esempio, che cosa il vostro punteggio è, o quanto tempo ci è voluto voi per risolvere questo forum? 1348 01:23:11,740 --> 01:23:14,970 Beh, cosa si può fare è che si può creare una struttura. 1349 01:23:14,970 --> 01:23:18,910 Quello che sto dicendo è che in fondo sono la definizione di questa struttura qui, 1350 01:23:18,910 --> 01:23:23,230 e io sono la definizione di una scheda di sudoku che consiste in una tavola che è 9 x 9. 1351 01:23:23,230 --> 01:23:26,650 >> E quello che ha che ha puntatori al nome del livello. 1352 01:23:26,650 --> 01:23:30,730 Ha anche x e y, che sono le coordinate di dove mi trovo in questo momento. 1353 01:23:30,730 --> 01:23:35,980 Essa ha anche il tempo trascorso [incomprensibile], ed ha il numero totale di mosse ho immessi finora. 1354 01:23:35,980 --> 01:23:40,010 E così in questo caso, posso raggruppare un insieme di dati in una sola struttura 1355 01:23:40,010 --> 01:23:42,790 invece di averlo come volare in giro come diverse variabili 1356 01:23:42,790 --> 01:23:44,540 che non posso tenere traccia di. 1357 01:23:44,540 --> 01:23:49,720 E questo ci permette di avere solo la sintassi bello per genere di riferimento cose diverse all'interno di questa struttura. 1358 01:23:49,720 --> 01:23:53,430 Posso solo fare board.board, e ho la scheda di sudoku posteriore. 1359 01:23:53,430 --> 01:23:56,320 Board.level, ho capito quanto è difficile. 1360 01:23:56,320 --> 01:24:00,540 Board.x e board.y mi danno le coordinate di dove potrei essere in consiglio di amministrazione. 1361 01:24:00,540 --> 01:24:04,730 E così sto accedendo ciò che noi chiamiamo campi della struct. 1362 01:24:04,730 --> 01:24:08,840 Questo definisce sudokuBoard, che è un tipo che ho. 1363 01:24:08,840 --> 01:24:14,800 E ora siamo qui. Ho una variabile chiamata "asse" di sudokuBoard tipo. 1364 01:24:14,800 --> 01:24:18,820 E così ora posso accedere a tutti i campi che compongono questa struttura qui. 1365 01:24:20,830 --> 01:24:22,450 >> Avete domande su strutture? Sì? 1366 01:24:22,450 --> 01:24:25,890 [Studente] Per int x, y, si sia dichiarato in una riga? >> [Joseph] Uh-huh. 1367 01:24:25,890 --> 01:24:27,400 [Studente] Allora, hai potuto fare con tutti loro? 1368 01:24:27,400 --> 01:24:31,200 Come in x, y volte virgola che il totale? 1369 01:24:31,200 --> 01:24:34,460 [Giuseppe] Sì, si potrebbe sicuramente fare, ma la ragione per cui ho messo x e y sulla stessa linea - 1370 01:24:34,460 --> 01:24:36,330 e la domanda è: perché possiamo solo fare questo sulla stessa linea? 1371 01:24:36,330 --> 01:24:38,600 Perché non basta mettere tutti questi sulla stessa linea è 1372 01:24:38,600 --> 01:24:42,090 X e Y sono legati tra loro, 1373 01:24:42,090 --> 01:24:44,780 e questo è solo stilisticamente più corretto, in un certo senso, 1374 01:24:44,780 --> 01:24:46,600 perché è il raggruppamento due cose sulla stessa linea 1375 01:24:46,600 --> 01:24:49,340 quella specie come di riguardare la stessa cosa. 1376 01:24:49,340 --> 01:24:51,440 E ho appena diviso questi pezzi. E 'solo una cosa stile. 1377 01:24:51,440 --> 01:24:53,720 Si fa funzionalmente alcuna differenza. 1378 01:24:58,150 --> 01:24:59,270 Altre domande su strutture? 1379 01:25:03,030 --> 01:25:06,620 È possibile definire un Pokédex con una struttura. 1380 01:25:06,620 --> 01:25:11,720 Un Pokémon ha un numero ed ha una lettera, un proprietario, un tipo. 1381 01:25:11,720 --> 01:25:16,990 E poi se si dispone di una serie di Pokémon, è possibile effettuare un Pokédex, giusto? 1382 01:25:16,990 --> 01:25:20,810 Ok, fresco. Così, le questioni relative strutture. Questi sono correlate a strutture. 1383 01:25:20,810 --> 01:25:25,270 >> Infine, GDB. Che cosa ti permette di fare GDB? Esso consente di eseguire il debug del programma. 1384 01:25:25,270 --> 01:25:27,650 E se non avete usato GDB, avrei consigliato a guardare il breve 1385 01:25:27,650 --> 01:25:31,250 e solo andando su ciò che GDB è, come si lavora con esso, come si potrebbe utilizzare, 1386 01:25:31,250 --> 01:25:32,900 e provarla su un programma. 1387 01:25:32,900 --> 01:25:37,400 E così quello che GDB permette di fare è permette mettere in pausa il [incomprensibile] il vostro programma 1388 01:25:37,400 --> 01:25:38,920 e una linea pratica. 1389 01:25:38,920 --> 01:25:42,600 Per esempio, io voglio mettere in pausa l'esecuzione come la linea 3 del mio programma, 1390 01:25:42,600 --> 01:25:46,010 e mentre sono in linea 3 Sono in grado di stampare tutti i valori che ci sono. 1391 01:25:46,010 --> 01:25:49,710 E così ciò che noi chiamiamo come pausa in una linea 1392 01:25:49,710 --> 01:25:52,350 è che noi chiamiamo questo mettere un punto di interruzione in quella linea 1393 01:25:52,350 --> 01:25:55,920 e poi siamo in grado di stampare le variabili allo stato del programma in quel momento. 1394 01:25:55,920 --> 01:25:58,990 >> Possiamo poi da lì il passaggio attraverso il programma linea per linea. 1395 01:25:58,990 --> 01:26:03,200 E poi siamo in grado di guardare lo stato dello stack al momento. 1396 01:26:03,200 --> 01:26:08,600 E così, al fine di utilizzare GDB, quello che facciamo è che chiamiamo clang sul file C, 1397 01:26:08,600 --> 01:26:11,290 ma dobbiamo passare il flag-ggdb. 1398 01:26:11,290 --> 01:26:15,850 E una volta che abbiamo finito con questo abbiamo basta eseguire gdb sul file di output risultante. 1399 01:26:15,850 --> 01:26:18,810 E in modo da ottenere un po 'di massa come di testo come questo, 1400 01:26:18,810 --> 01:26:21,990 ma in realtà tutto quello che dovete fare è digitare i comandi all'inizio. 1401 01:26:21,990 --> 01:26:24,250 Rompere principale mette un punto di interruzione principale. 1402 01:26:24,250 --> 01:26:28,470 Lista 400 elenca le righe di codice attorno alla riga 400. 1403 01:26:28,470 --> 01:26:31,410 E così in questo caso si può solo guardarsi intorno e dire: oh, 1404 01:26:31,410 --> 01:26:34,360 Voglio impostare un punto di interruzione alla riga 397, che è questa linea, 1405 01:26:34,360 --> 01:26:37,170 e poi il programma viene eseguito in quella fase e sta andando a rompere. 1406 01:26:37,170 --> 01:26:41,120 E 'intenzione di mettere in pausa lì, ed è possibile stampare, ad esempio, il valore di basso o alto. 1407 01:26:41,120 --> 01:26:46,410 E così ci sono un sacco di comandi che dovete sapere, 1408 01:26:46,410 --> 01:26:48,660 e questo slideshow saliranno sul sito web, 1409 01:26:48,660 --> 01:26:54,000 quindi se si desidera fare riferimento questi o come metterli sul vostro cheat sheet, non esitate. 1410 01:26:54,000 --> 01:27:00,650 >> Cool. Era Quiz Review 0, e si proverà in giro se avete domande. 1411 01:27:00,650 --> 01:27:03,850 Bene. 1412 01:27:03,850 --> 01:27:09,030 >>  [Applausi] 1413 01:27:09,030 --> 01:27:13,000 >> [CS50.TV]