[RIPRODUZIONE DI BRANI MUSICALI] DAVID J. MALAN: Questo è come un seminario matricola oggi. OK. Quindi molto piovoso fuori. Ciò tende ad accadere il mercoledì, ma ancor più opportunità per le domande di oggi. Quindi cerchiamo di cominciare realmente con il film in un momento. Ma inizieremo grandiosamente come sempre. Questo è CS50, e questo è la fine della settimana 4. Quindi, se avete mai visto La TV o un film in cui ci sono alcuni esperti di computer e la polizia, o FBI, o qualche agenzia sta cercando di recuperare un po ' avversario, beh, hai probabilmente sentito l'espressione "migliorare" per cui in qualche modo che tecnico zoom magicamente in infinitamente per vedere i criminali identità o il numero di targa in anche il luccichio di uno specchio o il luccichio degli occhi di qualcuno. Così infatti, diamo uno sguardo a alcune di queste scene di Hollywood. [RIPRODUZIONE VIDEO] -OK, Ora andiamo una buona occhiata a voi. -hold Esso. Eseguire che indietro. -Apetta un minuto. Vai a destra. -Ci, Bloccare quello. -A schermo intero. -OK, Bloccare quello. Stringere più su quella, vero? -vector In su quella tipo per la ruota posteriore. -zoom In proprio qui, in questo punto. -Con La giusta attrezzatura, l'immagine potrebbe essere ampliato e affilato. -Che cos'è? -E 'Un programma di miglioramento. -Puoi Chiaro che qualsiasi? -Non lo so. Cerchiamo di valorizzarlo. Sezione A6 -e la valorizzazione. -I Migliorato dettaglio, e- Penso che ci sia abbastanza per migliorare, rilasciarlo al mio schermo. -I Migliorato la riflessione nel suo occhio. -Let Run questo attraverso miglioramento video. -Edgar, Si può migliorare questo? -Aspetta. -Ho Lavorato su questa riflessione. La riflessione di -Qualcuno. -Reflection. -C'è Un riflesso del volto dell'uomo. -La Riflessione. -C'è Una riflessione. -zoom In sullo specchio. -Si Può vedere un riflesso. -Can A migliorare l'immagine da qui? -Puoi Lo migliorare proprio qui? -Può A migliorare esso? Riesci a valorizzarlo? -Può Potenziamo questo? -Può A migliorare esso? -hold Su un secondo, io miglioro. -zoom In sulla porta. -Times 10. -zoom. -Muovi In. -Di più. Aspetta, stop. -Stop. -PAUSE Esso. Noi -rotate 75 gradi attorno alla verticale, per favore. -Stop. Torna alla parte sulla porta, di nuovo. -Got Un potenziatore immagine che può bitmap? Ehi, forse possiamo usare il Pradeep Metodo Sen per vedere le vetrine. Software -Questo è lo stato dell'arte. -Il Autovalore è spento. -Con Il diritto combinazione di algorithm-- Preso eliminazione di -Ha algoritmi al livello successivo, e io li posso usare per migliorare questa fotografia. -Lock Su e ingrandire l'asse z. -e La valorizzazione. -e La valorizzazione. -e La valorizzazione. FROSTMATIC e valorizzare. [FINE RIPRODUZIONE] DAVID J. MALAN: Va bene, allora Tutti questi sono in realtà parole. Stanno solo legate insieme in un modo che non è in realtà sensibile. E, infatti, CS50 e corsi piace tende a rovinare un sacco di TV e film per te. Perché quando questi esperti di computer sono snocciolare termini e dicendo cose di fantasia come autovettori e l'asse z, e qualsiasi numero di altri in realtà termini più tecnici, stanno in realtà solo la tesatura insieme le parole troppo spesso. È che una delle nostre speranze è che, come effetto collaterale di corsi taking come questo, saranno più persone nel mondo effettivamente in grado di pesare in e appena sempre leggermente influenzare la qualità e la precisione di questi film? In realtà, diamo uno sguardo sulla realtà. Così qui è la foto di personale Mary, uno dei nostri compagni di insegnamento. E supponiamo che lei è sospettato di qualcosa. Eppure, c'è un barlume di qualche pezzo di prova in suo occhio, o nel riflesso dei suoi occhiali. Beh, se facciamo esattamente come i film proporre, in cui abbiamo ZOOM e "miglioriamo", questo è quanto informazioni è sul volto di Maria quando si cattura un'immagine con quella risoluzione originale. E, infatti, è possibile vedere questi punti. E questi sono quelli che sono chiamati pixel, P-I-X-E-L-S, che è solo una piazza tipicamente che è un punto che compone un'immagine. E nel giorno, e in realtà anche oggi con un po 'di TV LED di oggi o TV LCD, se devi uno nella vostra camera o in casa, se si va fino super vicino ad esso, e soprattutto se si tratta di un televisore po 'più vecchio, probabilmente si può anche vedere questi punti ed è quello che compongono un'immagine. E non c'è più Informazioni di questo. Potremmo "migliorare", nel senso di lisciando le cose e una sorta di inferire tipo di, una sorta di cosa colore deve essere il prossimo a occhio di Maria in modo che in realtà non è così pixel. Ma se continuo zoom in, ci è il cattivo nel suo occhio. Come quella è tanto informazioni che abbiamo. Non è possibile creare Informazioni dal nulla. C'è solo un insieme finito numero di bit lì. Quindi, in Set Problema 4, dove si ha l'opportunità giocare con questo tipo di mondo. Nel Problema Set 4, potrai esplorare il mondo della grafica, e forense, ed effettivamente scrivere codice che recupera le immagini perse. Potrai scrivere codice che manipola immagini esistenti e, infine, capire cosa c'è succedendo sotto il cofano. E, si scopre, è in realtà Non poi così complicato. Ad esempio, se volessimo rappresentare una faccina sorridente dove con questi pixel neri, o questi puntini neri, beh, potremmo semplicemente rappresentare come un vero e bitmap. E se tu avessi mai sentito dire che espressione bitmap, forse ora inizia a fare un poco più senso oggi. Sappiamo già quello che un po 'è. È 0 o 1. E una mappa è solo qualcosa come un pezzo di carta che ti dà le indicazioni e ha forse una griglia di xey coordinate. Così qui è una bitmap. Si tratta di una mappa di bit per cui un 1 è apparentemente andando a rappresentare un pixel bianco, e 0 sta per rappresentare un pixel nero. Ma potremmo certamente girare intorno. Realmente non importa così Finché siamo coerenti. Ed ecco come, in binary-- dentro di memoria di un computer, o addirittura all'interno di un file sul disco drive-- è possibile memorizzare la più semplice delle immagini dei volti sorridenti. Ma cosa siamo, naturalmente, privo di questa immagine? Colore, giusto? Si tratta di un evidente passo successivo o potenziamento per migliorare questo con il colore. Così, purtroppo, con un solo bit, 0 o 1, si potrebbe rappresentare il colore. Questo potrebbe essere rosso o blu, o nero, o bianco o verde, o rosa, o qualsiasi coppie di colori. Ma per semplicità, faremo basta assumere in bianco e nero. Allora cosa logicamente abbiamo bisogno se vogliamo desidera implementare colore in un'immagine? Cosa dobbiamo fare? Come se il fattore limitante qui è che con un po 'solamente possibile rappresentano due stati, 0 o 1, bianco o nero, che cosa vuoi fare? Pubblico: più dati. DAVID J. MALAN: più bit, Si 'più dati, più bit. E, in effetti, che è esattamente come immagini a colori sono rappresentati. Invece di utilizzare un singolo bit, un 0 o 1 per ogni pixel, ciascun punto, è sufficiente utilizzare multipla. Forse utilizzare 8, forse, più comunemente utilizzare 24, e anzi, in Problem Set 4, vuoi giocare con un file formato che utilizza 24 bit genere. Ma la maggior parte di voi sono probabilmente familiarità con file JPEG. Se hai mai preso una foto sul tuo telefono, o caricati o visto qualcosa su Facebook, o Flickr, un numero qualsiasi di siti web foto-based, hai probabilmente visto un'immagine JPEG prima. E si scopre, questo è il file formato stiamo andando a utilizzare in PSet 4, per cui si sta andando a devono recuperare le immagini che ho cancellato accidentalmente da un scheda di memoria corrotta nella fotocamera, se vuoi. E si scopre che anche se JPEG è piuttosto sophisticated-- è molto più sofisticato che i punti bianchi e neri abbiamo visto un momento fa, perché non c'è algoritmi realtà di fantasia che sono utilizzati per comprimere un JPEG, così che si può avere una bella, qualità delle immagini ma utilizzando relativamente pochi bit. E torneremo a compressione in breve tempo. Risulta che la prima tre byte in un image-- JPEG non importa quello che hai preso una fotografia di-- sono i valori 255, 216, 255. In altre parole, se si vedere che modello di bit, qui rappresentato come tre byte o 24 bit Totale, con alta probabilità si può dedurre che si sta guardando in questo primi tre byte di un JPEG. E questo è ciò che è noto la firma di un JPEG. Un sacco di formati di file fuori ci tendono ad iniziare con certi modelli di 0 e 1, in modo che Windows e Mac OS, e iOS, e Android sa che tipo di file che sono, oltre al cosiddetto lima estensione che un sacco di file hanno. Se avete .jpg, che è un altro indizio al computer. Quindi cerchiamo di guardare a questo ora un po 'più tecnicamente. Sappiamo che il decimale sistema è da 0 a 9. Sappiamo binario è 0 e 1. E se si ripensa a PSet 0, abbiamo avuto voi lottare con, per un po ', qualcosa chiamato esadecimale, dove si hanno 16 cifre, invece di 10 o invece di 2. E queste cifre, per convenzione, sono da 0 a 9 e poi un attraverso f, dove f rappresenta quello numero decimale, proprio come un rapido sanità mentale controllare? Quindi, 15. E un must rappresentare 10, semplicemente la natura di ordinamento che ho dato. E 'solo una convenzione arbitraria, ma è abbastanza standard. Quindi, se guardiamo a questo modello di tre bytes-- facciamo basta iniziare a guardare in un modo coerente con quanto gli informatici in generale guardare e riflettere sui file. Si può certamente pensare file in 0s e 1s, e decimali, ma in realtà, tendiamo ad usare binario o più tipicamente hexadecimal-- indietro da PSet 0. Permettetemi quindi di propongo 255, 216, e 255 sono proprio questi modelli di 0 e 1. E si può controllare questo se si vogliono fare la matematica dalla settimana 0. Ma, per ora, dare per scontato che questo è effettivamente corretto. Ho appena riscritto tre decimali numeri come tre valori binari. Ora che cosa ho intenzione di fare è basta aggiungere un po 'di spazio bianco, solo per amor di leggibilità. E notate, sto solo andando per spostare le cose a parte. Quindi, prima, dopo, prima, dopo. Sto facendo niente di interessante altro che solo diffondendo le cose così tale avviso ogni serie di otto bit è ora due serie di quattro bit. Questo è utile perché esadecimale è particolarmente di moda perché ogni cifra esadecimale da 0 a f, o più specificamente da 0 a 15, può essere rappresentato esattamente con quattro punte. In altre parole, se in esadecimale vuole rappresentare uno 0, è solo 0000, quattro zeri. E se si vuole rappresentare 15, è 1111, che è quattro bit. E se fate i conti, se questo è il posto quelle, questo è il posto 16s, che sta per dare you-- piuttosto che sta andando a-- dispiace, in binario, che sta per darvi 15, quelli posto, twos posto, a quattro zampe e otto posto. Permettetemi quindi di propongo che set di quattro bit a sinistra è quello che stiamo andando a chiamare f. È il più grande numero può rappresentare con quattro bit. E sappiamo già da esadecimale, f è il più grande cifra esadecimale. Abbiamo un altro f lì, altri due laggiù. E per ora, basta prendere sulla fede che ho fatto il diritto di matematica e che la metà sinistra di quei bit, 1101, è la stessa cosa come d in esadecimale. E la mano destra, 1000, è a soli 8. E questo è uno facile da vedere, giusto? L'8 represents-- è giusto sotto quel luogo otto. Così ne abbiamo una in colonna otto e nulla nelle fours, gruppi di due o quelli. Così ora più convenzionale, gli esseri umani tendono di scrivere cifre esadecimali come questo, appena li squish insieme, e poi li prefisso 0x. Significa altro che un indizio visivo per un human-- ecco che arriva un value-- esadecimale perché non potrebbe essere altrimenti evidente. Vale a dire, in ultima analisi, che il modello di zero e uno, o il modello di esadecimale cifre equivalentemente che sei sta per iniziare la ricerca di nel problema Set 4 è questo-- e il problema Set 4 spec camminerà attraverso questo in più detail-- ma rendersi conto come una sorta di arcana come questo potrebbe sembrare a prima vista, hai intenzione di cominciare a vedere questo molto. Ed infatti, anche in GDB, la debugger abbiamo introdotto il Lunedi e Dan introduce in PSet 3, sta andando per mostrare spesso valori esadecimali solo perché tendono ad essere più convenzionale rispetto decimale o binario nel mondo dei computer. Ora mettiamo questo in contesto. Molti di voi potrebbe ricordare questo immaginare qui, che è venuto da che cosa? Vista, quindi, anche prima di quanto che, Windows XP ha fatto questo debutto. Quindi questo è un bel paesaggio. E infatti, se si frugare online-- Penso che sia un articolo di Wikipedia, in cui qualcuno molto sorprendentemente uscì ha trovato questa posizione nel mondo istituito sua telecamera precisamente il posto-- destra e questo oggi guarda like-- ma è esattamente la stessa impostazione. Questa immagine, però, è in un file formato chiamato bitmap, b-m-p. E stiamo andando a prendere un super rapida occhiata a cosa significa. Ma bitmap è solo un modo diverso di immagini che rappresentano ancora utilizzando pixel a 0 e 1, in ultima analisi. Ma a colpo d'occhio, ha una firma più interessante all'inizio del file. Non si tratta solo di tre byte, piuttosto c'è un sacco di modelli di byte che hanno determinato significato. Ad esempio, da qualche parte nel primi byte di un'immagine bitmap sta per essere la dimensione del immagine, la larghezza dell'immagine, l'altezza dell'immagine, in modo metadati utili, se si vuole. Informazioni utili che Photoshop o qualsiasi programma di grafica che si sta utilizzando potrebbe effettivamente preoccuparsi. Quindi più su questo in Problema Set 4, ma questo è solo per dire che alla fine del giorno tutti i formati di file che avete utilizzato per anni-- file di Microsoft Word, Numeri, file Excel, qualsiasi numero di formati di file che potrebbe avere un po ' estensione di file conosciuti sono solo 0 e 1 sotto il cofano. E gli esseri umani hanno deciso quali le convenzioni sono, quali modelli di 0 e 1 rappresentano un file di Word rispetto a un file di Excel, rispetto a qualsiasi numero di altri formati di file. Quindi, in PSet 4, avrai un opportunità di giocare con quella. Ma che cosa vuol dire avere una struct. Questo è in realtà un bel segue ora in C, che ha solo un paio caratteristiche aggiuntive che di non abbiamo guardato ancora. Si tratta di un grazioso piccolo linguaggio e uno dei le caratteristiche belle di C è una struct. Ad esempio, se si voluto represent-- facciamo dici che voleva avere una variabile che rappresenta uno studente in qualche programma. Forse stavi scrivendo un corso programma di registrazione, o nucleo di shopping strumento, o qualcosa del genere. Quali sono pezzi di dati correlati ad uno studente che vengono in mente? Come uno studente è rappresentato con quali valori? Sì? Si dispone di un nome come studente. Che altro fa un tipico studente ha? PUBBLICO: [incomprensibile] DAVID J. MALAN: Quindi, mi dispiace. PUBBLICO: Età. DAVID J. MALAN: An età o compleanno equivalentemente, sì. Cos'altro? PUBBLICO: numero di identificazione? DAVID J. MALAN: Quindi un numero ID, forse un numero di telefono, forse un dormitorio, o casa, o college, o qualcosa del genere. Qualsiasi numero di pezzi di dati che si potrebbe avere nel tuo elenco di contatti è quello che potremmo definire uno studente. Quindi, se volessimo fare questo, in codice, potremmo fare qualcosa di semplice come questo. Potremmo avere un programma in modo che ha diciamo, int main (void). E se voglio rappresentare un studente Potrei avere, per esempio, una stringa chiamata nome per quello studente, una stringa chiamata dormitorio per quello studente, forse un int chiamato ID per quello studente. E perché sto utilizzando corda, io bisogno di tornare indietro e mettere CS50.h. Forse sto andando ad avere bisogno stdio.h. Così mi permetta di fare preventivamente quelli e sono andando a chiamare questo student.c per ora e salvare questo. E ora posso fare qualcosa con queste variabili. E stiamo solo andando a scrivere che come un commento in pseudo codice, perché non è interessante ciò che facciamo per ora. OK, quindi questo è un programma che in qualche modo memorizza uno studente. Quello che voglio fare se desidera memorizzare due studenti? Quindi il mio primo istinto è andare tutto bene, aspetta un minuto, se ho un altro studente perché non ho basta fare nome corda 2, corda dormitorio 2, int ID2. E abbiamo fatto andato su questa strada prima e ciò che era la nostra soluzione a quello che sembra per essere una specie di copia incolla hackish lavoro qui? PUBBLICO: Un array. DAVID J. MALAN: Sì, si potrebbe utilizzare un array. Proprio in questo molto rapidamente diventa ingombrante. Dovete ordinare arbitrariamente iniziare a nominare tutte queste variabili. E tu, l'umano, tenere traccia che corrisponde OK NAME2 con dorm2 corrisponde con id2. E 'appena diventa un pasticcio. Quindi è molto più facile, recuperare da un paio di settimane fa, a solo dover chiamati nomi di stringa e forse ci danno tre di questi. E allora forse abbiamo dormitori archi e avere tre di questi, o con una costante, int id e avere tre di questi. Ma anche ora questo si sente un po 'sciatto, a destra. Stiamo parlando di studenti e ancora Sono davvero dimora sul basso livello dettagli di implementazione. Lo studente è un nome e un dormitorio e ID. Perché non posso solo dichiarare una variabile chiamato studente e lo chiamano s. E se voglio un altro studente, perchè non solo chiamo t. O se voglio un sacco degli studenti, perché non faccio solo dire che ho un'intera classe di studenti e sono le tre di loro. In altre parole, perché non posso venire con il mio tipo di dati, chiamato Gli studenti, all'interno del quale è un nome, è un ID, è un dormitorio, è un qualsiasi numero di altri campi. E si scopre che può fare esattamente questo. Così C ha questa funzionalità chiamata struct. Questa è una caratteristica del linguaggio che ci permette di fare esattamente questo. Ho intenzione di andare avanti e di aprire structs.h dove stiamo andando a vedere la seguente definizione di uno studente. Si scopre - e questo è ancora semplice di quello che comporta un ID un attimo fa. Se vuoi venire con il tipo di dati di fatto in casa, e in aggiunta a int e char e float e tutti questi altri che esistono, è possibile farlo letteralmente la scrittura typedef struct, poi alcune parentesi graffe, all'interno del quale si elencare le variabili che si desidera associare a questa nuova dati personalizzati digitare come un nome e un dormitorio, e poi, dopo le parentesi graffe si dà un nome al nuovo tipo di dati. Così, per esempio, studenti. E che cosa è bella di questo ora è che se guardiamo il codice corrispondente, la convenzione, prima di tutti, è quello di mettere questo in un file chiamato qualcosa puntino h, un file di intestazione, che non abbiamo iniziato a utilizzare noi stessi troppo. Ma stiamo andando cominciare utilizzando un po 'ora. E che cosa si può fare con questo, in definitiva, in queste poche linee di codice si dichiarano esattamente questo tipo di dati, uno studente. E ora lo si può usare. Ho intenzione di andare in ora un file chiamato structs1.c. E diamo uno sguardo ad un alcune caratteristiche qui. Così la roba qui è per lo più familiare, e faremo tornare a ciò che non è familiare in un attimo. Questo naturalmente è compresa la mia file di intestazione, che è nuovo e, fatta eccezione per PSet 3 dove, richiamo, abbiamo helpers.h. Così si potrebbe ricordare helpers.h #include. Perché anche se sto usando citazioni invece di parentesi angolari? Quando faccio a scegliere tra di loro? Quasi sempre mi sembra per utilizzare le parentesi angolari. E poi, tutto ad un tratto su Linea sei Sto utilizzando doppi apici. Perché potrebbe essere? Sì? PUBBLICO: [incomprensibile] DAVID J. MALAN: Questo è un vero e proprio, che cosa? PUBBLICO: E 'nel vostro IDE. DAVID J. MALAN: Sì, che è in mio IDE reale. E cerchiamo di non soffermarsi su l'IDE, perché questo è solo uno strumento che sto usando. Questo è a mio attuale directory, in particolare. Così structs.h è il mio file non installato nell'IDE, nel sistema operativo stesso, piuttosto è nella mia directory corrente. Così la convenzione è se si vuole per inserire il tuo file di intestazione, si utilizza solo doppi apici. Come chiamiamo questa cosa in linea 8, in generale? Questo è ciò? qualcosa #define. Questo rappresenta costanti, giusto? Se si desidera avere un il valore nel programma di utilizzare un intero mucchio di volte, è buona convenzione di fattore fuori, dichiararlo, con il simbolo di cancelletto definire, quindi, per convenzione, in tutte maiuscolo word-- anche se non è strettamente necessaria, ma è convenzione umana per capitalizzare le costanti in modo che saltano ti visually-- spazio e allora il valore che si desidera essere equivalente a nome di quel costante. Nessun punto e virgola, ma è sufficiente seguire quel modello lì. Allora, cosa ci faccio in questo codice vero e proprio. Quindi, diamo uno sguardo a il programma principale qui. In linea 12 perché io hanno incluso structs.h, Ora ho magicamente al mio disposizione un nuovo tipo di dati. Non mi resta che l'accesso a int, e char, e float e stringhe, e blu e altri. Ora ho l'accesso al un tipo di dati studente. Quindi, in linea 12, sto combinando due ideas-- un un tipo di dati personalizzati e due, utilizzando una matrice. E così in questo programma se Voglio sostenere realmente tre diversi studenti nel mio programma, ho può semplicemente dire darmi una variabile chiamati studenti, ciascuno dei quali è di tipo studenti, che è il mio tipo di dati personalizzati. E, in particolare, dammi tre di questi nel mio allineamento. Così ora che cosa facciamo in questo programma? Ecco solo un ciclo for iterazione da 0 a 3, perché è quale sia il valore di studenti è. Sto solo chiedendo all'utente dammi il nome dello studente. E poi, in linea 17, si avere una linea per lo più familiare. Abbiamo il nostro vecchio amico GetString sulla destra. E quale pezzo di sintassi è apparentemente nuova, se non hai mai programmato in C prima, e non hanno mai usato le struct? Sì? PUBBLICO: Il .name. DAVID J. MALAN: Il .name. Ma questo non è troppo di un salto, perché ora gli studenti staffa I ti dà allo studente i-esimo. E se vuoi immergerti all'interno di tale struttura, è sufficiente utilizzare un solo periodo e quindi il nome della variabile all'interno, o la proprietà all'interno di tale si desidera ottenere l'accesso a. Allo stesso modo, allora, se ho quindi richiedere utente, dammi dormitorio dello studente, Allo stesso modo è possibile memorizzare che stringa nella variabile dormitorio all'interno di tale struttura studente. E ora le cose si fanno un po 'di fantasia. E questo sta a guardare in forse molto molto presto. Ma vedrete questo molto più in PSet 4, così facciamo solo sguardo a ora. Si scopre che in linea 23 attraverso 38, che cosa pensi che sto forse facendo? Ho rimosso i commenti per oggi, ma la versione del codice online riferimento ha tutti i commenti. Che cosa mi sembra di fare? AUDIENCE: Salvare il file con tutti le informazioni che l'utente ha inserito. DAVID J. MALAN: Sì, esattamente, questo è un modo nuovo che stiamo vedendo due, Un'altra caratteristica di C, per cui posso creare i propri file. Finora, quasi ogni programma ti ho scritto è senza stato. Non appena è fatto in esecuzione, questo è tutto. Non c'è memoria o ricordo di essa. Non c'è file salvato. Ma se si vuole salvare input che ha successo, come in un gioco o un programma in questo modo, si scopre che possiamo farlo. E vedrete questo più in PSet 4 e nella Sezione. Ma questa linea 23 essenzialmente crea un file chiamato students.csv. E si potrebbe avere visto prima. Anche se non avete mai studiato CS prima, CSV è variabili separati da virgole. E 'come un povero uomo di versione di un file di Excel, il che significa che può essere aperto in Excel e in Numeri di Apple, e ha righe e colonne. Ma non è un proprietario formato come Microsoft o Apple. E 'solo le virgole che separano la valori che vedremo tra poco. E basta prendere una supposizione. In linea 23, per lo fine, il mio secondo argomento a questa nuova funzione chiamata f aperto per file aperto è w. Che cosa potrebbe denotare w? Sì? PUBBLICO: Esso consente di scrivere il file? DAVID J. MALAN: Permette si scrive il file. Quindi ci sono un paio di varianti che siamo in grado di collegare qui. Ma se volete solo leggere il file, che è guardare a lui e leggere in memoria, basta usare tra virgolette "r". Se si desidera scrivere il il file, è possibile utilizzare tra virgolette "w". C'è anche aggiungere e un paio di altre cose se si desidera modificare i file esistenti. Ora stiamo andando a continuare a vedere questo cosa, allora ci torneremo per la linea 24. NULL, si scopre, è un valore speciale che può essere restituito da alcune funzioni se qualcosa è andato wrong-- se il file non esiste, se si è a corto di memoria, o un gruppo di altri errori. Ma per ora, facciamo solo supporre che questo è il controllo degli errori solo convenzionale. Qui in linea 26, sto iterazione 0-3 su tutti i miei studenti. E questo è una specie di sorta di una nuova funzione, fprintf, ma basta prendere una supposizione. Se printf è solo stampa una stringa formattata, cosa fprintf probabilmente significa? PUBBLICO: Stampa su un file. DAVID J. MALAN: Stampare una stringa formattata in un file. Questo è ciò che l'addizionale mezzi f è il file. E il nuovo primo argomento deve essere la variabile che rappresenta il file. Poi non ci resta che un format stringa come printf. E anche se questo sintassi è nuovo, questo solo significa inserire il nome dello studente, plug-in dormitorio per studenti, e poi con fclose, chiudere il file. E poi questa è una novità lastly-- e ci torneremo a questo prima long-- Sto liberando lo studente per motivi quello che è successo lì sopra. Ma ci torneremo a quella prima long-- che è a causa di come è GetString effettivamente lavorando sotto la cappa. Quindi, diamo un rapido sguardo qui. Se digito ls nella mia directory, Noto che non mi avere un file chiamato students.csv, semplicemente non c'è, non esiste. Quindi, se io ora compilare questo programma, rendere le strutture-1,. / struct-1, e ho intenzione di andare avanti e digitare Andi, che vive a Berkeley a Yale. Stiamo per avere Rob che vive a Thayer questi giorni. E veniamo con cui è, credo, Maria è a Mather, se ho ricordato correttamente. Quindi, nulla sembra accadere. Ma se digito ls ora, c'è students.csv. Andiamo avanti e students.csv aperto. Questo è ancora molto formato di file leggero. Ma ho semplicemente adottato una convenzione che ho due righe e colonne qui. La prima colonna è nomi delle persone. La seconda colonna è lo studente del dormitorio, o l'università, o casa, o roba del genere. E ora ho salvato questo permanentemente in un file. Quindi non è tutto ciò che interessante. Ma questo è solo un trampolino di lancio ora per essere in grado di mantenere le informazioni in modo permanente. Così vediamo ora che cosa di più che possiamo fare con queste e altre caratteristiche. Ma in primo luogo, tutte le domande? E 'stato molto, e che era veloce. Ma vedrete un sacco più in PSet 4, pure. Sì? PUBBLICO: C'è un modo per continuare ad aggiungere nomi a quel file? DAVID J. MALAN: Bella domanda. C'è un modo per continuare l'aggiunta di nomi a quel file? Sì. E, infatti, se si finisce up riaprire il file, si usa preventivo unquote "a" per l'aggiunta, il che è sufficiente aggiungere una nuova linea, un nuova linea ancora e ancora, esattamente. Bella domanda. Altre domande? Sì? PUBBLICO: Se si è eseguito il programma di nuovo in questo momento, sarebbe continuare ad aggiungere nomi al il file o sarebbe aprire un nuovo file? DAVID J. MALAN: Ah, bella domanda. Se è stato eseguito di nuovo a destra il programma Ora, forse digitato nuovi nomi, sarebbe aggiungere al file o sovrascrivere il file? Quest'ultimo, perché io sono Non utilizzando la modalità di aggiunta. E perché io sono solo alla cieca aprire il file per la scrittura, è solo andando a sovrascrivere il file. Quindi vorrei davvero bisogno di fare è aggiungere, se voglio avere in realtà un lungo periodo database. Ora CSV è utile, francamente, anche per come se siete writing-- e noi finalmente vediamo questo più avanti nel semestre, quando usiamo CSVs per altri scopi. Se si desidera memorizzare tutte le persone che hanno registrato per qualche evento, o firmato per il vostro studente gruppo, o qualcosa del genere, memorizzazione dei dati in genere di formato è super conveniente. Perché letteralmente, se io dovevano scaricare questo file. Potrei double-- e facciamo in realtà provare questo se ho Excel o Numbers qui. Ho intenzione di fare clic destro o control-click il mio file. Ops. Pulsante destro del mouse o il controllo del mouse il mio file. Andiamo, il mio mouse non sta collaborando. Download-- ho intenzione di scaricare tutti i file qui così solo così posso prendere questo. E vediamo se questo funziona students.csv-- prima volta Ho attivato. Ora vogliono vedere i miei contatti. Ora, ho bisogno di registrarsi. Vedi come è facile da usare CSV? Sì, tenerlo aggiornato. Ok, ora siamo pronti per la classe. OK, oh, cosa c'è di nuovo? OK, chiudere. E 'stato magico. OK, ora dobbiamo aggiornare. E ora, è dimenticato cosa file originariamente aperto, ma quello che A-- ci andiamo. OK, ora abbiamo un file di Excel. Grazie. Ok, quindi quello che ho fatto è stata la parte facile. Certo avrei potuto pre-installato Excel o Numbers o qualsiasi programma. Ma questo è bello, perché ora posso manipolare i dati in un formato standard. Così ora cerchiamo di contesto passare a dove avevamo interrotto l'ultima volta, che doveva iniziare a decollare ruote di formazione. Ma prima, non l'ha fatto vedere questo pranzo in precedenza sta di nuovo accadendo qui a fuoco e Ghiaccio a Cambridge, Sitar a New Haven. Iscriviti sul sito CS50s ASAP per unire studenti CS50 e personale. Così abbiamo preso ruote di formazione fuori il Lunedi come follows-- stringa è stata dichiarata in Biblioteca CS50s per qualche tempo. Ed è bello, perché permette noi parlare di variabili come parole e frasi complete e altro ancora. Ma si scopre stringa non esiste. Questo è solo un sinonimo o un alias, che abbiamo creato qualcosa che in realtà è un po 'più tecnico chiamato char *. E in effetti, abbiamo visto un esempio di un programma il Lunedi che non si è comportato piuttosto come ci aspettavamo. Questo era il file, confronto-0. E ricordano che confrontare-0, se Io ricompilare il programma di Lunedi ed eseguire confronto-0 e digitare la mamma in minuscolo, e la mamma in minuscolo di nuovo. Il programma ha insistito che tipo cose diverse, anche se mamma, tutto in minuscolo, è identica visivamente. Allora, qual è stata la risposta breve per il motivo per cui il computer pensa queste due stringhe sono diverse? Sì? PUBBLICO: [incomprensibile] DAVID J. MALAN: Giusto. Quindi, la mamma, la prima volta Scriv dentro, è essere memorizzati da qualche parte nel mio computer di memoria, ma in una posizione diversa che la seconda volta che scriv dentro mamma. Ora certamente potrebbe essere ottimizzato. Il computer potrebbe essere intelligente e realizzare queste due stringhe, hey, sono identici. Permettetemi non mi ridondante memorizzarlo. Ma i computer non lo fanno ottimizzazione meno che non si dica loro di. Quindi, per impostazione predefinita, sono solo andando a finire in due posti diversi in memoria. E così, per essere più chiari, quando abbiamo confrontato le due stringhe, Il primo è stato chiamato s, il secondo è stato chiamato t, che cosa in particolare mi è stato confrontando qui sulla linea 13? Già. PUBBLICO: E 'il luogo in memoria che la variabile indicherà. DAVID J. MALAN: Esatto, sono stato confrontando il posto in memoria che tali variabili indicavano. Così in particolare, se la mamma era il numero di byte 1 e 2, e 3, e 4-- perché ricordano il backslash 0 deve essere fino alla fine. E l'altra istanza di mamma, m-o-m, era all'indirizzo 10, 11, 12, e 13. Stavo comparando 1, tale indirizzo, quella posizione nella memoria, contro 10, che è ovviamente non la stessa. 1 non è 10. Quindi questo è bello in quel è abbastanza semplice. Ma è problematico in quanto sembra che non riusciamo a confrontare le stringhe. Così fundamentally-- e a questo basso livello, se si voleva implementare un programma per confrontare due parole separate che il utente ha digitato per la qualità, fanno la fila per char char, solo in termini generali, che cosa dobbiamo fare, a quanto pare? Non è sufficiente solo per guardare quelle due indirizzi. Che cosa dobbiamo fare? Sì? PUBBLICO: Scorrere la stringa [incomprensibile]. DAVID J. MALAN: Sì, andiamo scorrere la stringa. Usiamo un ciclo for, un ciclo while, o qualsiasi cosa tu stai più bene con. E se abbiamo due stringhe da qualche parte nella memoria, diamo un'occhiata a ciascuno di primo carattere, quindi ogni secondo è carattere, poi il terzo, e quarto, e il quinto, fino a quando non ha colpito quale valore speciale sentinella? PUBBLICO: [incomprensibile] DAVID J. MALAN: Sì, il backslash pari a zero, a questo punto in entrambe le stringhe possiamo decidere il gioco è fatto. Abbiamo abbinato ogni singolo personaggio? In caso contrario, restituire false. Se è così, restituisce true. E così questo è esattamente ciò che questa versione del programma di confronto-1.c fa. Si è identico a quello che guardato Lunedi, tranne che ho deciso di eliminare la parola anche se string-- che non ha impact-- funzionale tutto Io sto facendo ora è la rimozione alcune ruote di formazione visivi, ma per vedere chiaramente che s e t sono indirizzi. Ed è quello che la star, l'asterisco, rappresenta è un indirizzo, altrimenti noto più tecnicamente come un puntatore. Così, quando dichiaro s su linea 9 e dire char * s, questo non significa che mi dia una stringa. Ciò significa che mi danno una variabile il cui scopo nella vita è quello di memorizzare un indirizzo. Perché io sto per mettere la indirizzo di una stringa in esso. E in effetti, GetString, per essere chiaro, non restituisce una stringa. Non restituisce mamma backslash zero per sé. Che cosa significa GetString specificamente e precisamente di ritorno? PUBBLICO: [incomprensibile] DAVID J. MALAN: Un indirizzo, il indirizzo del primo carattere in qualche stringa che ha ottenuto. E così ora stiamo vedendo una parola chiave speciale di nuovo. E, ho accennato a questo prima. Questo sta per essere buono convenzione che vedremo di nuovo e di nuovo ora. Sto controllando fare in modo che s non è nullo e t non è nullo. Perché in base alla mia veramente menzione rapido prima, che cosa potrebbe significare se non restituisce GetString un indirizzo ma N-U-L-L, che è di nuovo, un valore speciale? PUBBLICO: Errore. DAVID J. MALAN: Si tratta di un errore. Qualcosa è andato storto. E che di solito potrebbe accadere, soprattutto con strings-- che potrebbe essere di lunghezza sconosciuta in advance-- forse i computer degli la memoria, forse digitato in un tale lungo parola o una frase o incollato un enorme saggio tale c'è solo non abbastanza memoria. E così GetString non può tornare l'indirizzo del tutto, in modo che solo restituisce nulla. E dice un errore è accaduto restituendo il valore speciale NULL. E 'l'indirizzo di zero, per così dire. Ora si scopre C viene fornito con un funzione che lo fa iterazione. Non abbiamo per perseguire questo obiettivo con un ciclo for o di un ciclo while noi stessi. Siamo in grado di utilizzare una funzione, chiamato succintamente, mescolate comp, o una stringa confrontare, il cui scopo nella vita è quello di fare esattamente questo. Si dà due puntatori, due indirizzi, e andrà a quegli indirizzi e quindi confrontare lettera per lettera per lettera per qualità, fermandosi solo quando ciò che è vero? Quando intuitivamente dovrebbe mescolare bozzetto fermata iterazione, tanto per essere chiari? Quando colpisce un backslash 0 in entrambe le stringa, a questo punto si può decidere ha abbinato tutto, o vi è stata una discrepanza? Quindi, se corriamo questo ora e provare il nostro gioco poco capitalizzazione, così rendere confrontare-1, ./compare-1, e digitare mamma in minuscolo entrambe le volte. Ora è la stessa cosa. E se lo faccio di nuovo con minuscolo e poi magari maiuscolo. Ora si distingue infatti tra maiuscole e minuscole. Quindi non così difficile o magica, ma non ora spiega cosa sta succedendo sotto il cofano. Allora, cosa altro possiamo estrarre da questo tipo di lezione? Quindi, diamo uno sguardo a questo. Ho intenzione di andare avanti e scrivere un programma veloce qui chiamato copia-0. E ora andiamo avanti e in realtà facciamolo questo-- con copia-0, dare un'occhiata a quello che ho qui. Desidero innanzitutto dire che l'utente, dire qualcosa. Poi ho una stringa e ho memorizzato in s. Poi controllo se s è uguale è uguale a NULL, appena di ritorno 1. Quindi questo è solo il controllo degli errori standard. Niente di interessante è accaduto. E infatti, se ci liberiamo di errore la verifica, questo sembra settimana 1 codice al momento. Ma ho iniziato a ottenere un po 'meglio di questo. Ora in linea 16, una settimana fa, forse anche un paio di giorni o di ore fa, si potrebbe dire che la linea 16 è la creazione di una variabile chiamata t e copia s in esso. E questo è un perfetto asporto ragionevole. Ma essere più precisi ora. Quello che sta accadendo in linea 16? Ciò che sta ottenendo copiato da destra a sinistra? Sì? PUBBLICO: E 't ottenendo un indirizzo di s? DAVID J. MALAN: Esattamente, t è sempre l'indirizzo di s. Quindi, per essere chiaro ora, se vado di nuovo a quel esempio precedente e traggo fuori la cosa che ho digitato. E quello che ho digitato dentro-- ecco s, e qui è quello che ho digitato qualche parte la memoria, la mamma e quindi una barra rovesciata 0 che viene aggiunto per me. Quello che ho memorizzato qui, ricordare, questo è in posizione 1, 2, 3, 4, questo è ciò che è attualmente in s. Quindi, se sulla linea 16, dico dammi un'altra variabile chiamata t e negozio in al valore di s, cosa viene memorizzato qui non sarà mamma ma piuttosto solo il numero 1. Quindi, se guardiamo avanti in questo programma Ora, che cosa succederà? Quindi notare che non c'è questa funzione si potrebbe hanno usato questo qualche tempo fa per Cesare, o Vigenere, o forse non del tutto. Io rivendico il mio printf, io sono andando a sfruttare la copia t. In prima linea 19, la sanità mentale rapido controllare, i controlli strlen la lunghezza di t. Perché non voglio cercare di capitalizzare qualcosa se non c'è corda lì. Se l'utente solo premere Invio, non c'è niente da capitalizzare. Quindi non voglio fare la linea 21. Così la linea 21 sta capitalizzando quale lettera, a quanto pare, in t? PUBBLICO: m? DAVID J. MALAN: Sembra come se fosse la copia quale? PUBBLICO: m. DAVID J. MALAN: Uh, m. OK, così il primo m, perché nota che sono passando per ToUpper, che se non avete mai visto è solo una funzione di capitalizzare come input. t staffa zero significa dare me il carattere zero di t. E così come fa questo cambio di pagina, per intenderci? Che cosa ha bisogno per avere riscritto o modificato rispetto a s e t e mamma pari a zero backslash. PUBBLICO: [incomprensibile] DAVID J. MALAN: Sì, quindi questo qui semplicemente ha bisogno di avere cambiato a-- fissare questo-- ha bisogno di avere cambiato per la M maiuscola. Ma ora, guarda più avanti nel programma, se stampo fuori s e t come pulisco qui, guardare cosa c'è succederà stampa di s e t. Quindi, fare copia-0, ./copy-0. Lasciami andare avanti e digito a mamma in lettere minuscole. Si noti sia l'originale e la copia sono stati capitalizzati. Perché? Beh, s e t sono entrambi indicando, se si vuole, lo stesso pezzo di memoria. E, francamente, questo è sempre uninteresting-- davvero il fatto che stiamo usando l'indirizzo di zero qui. Voglio dire, non mi interessa dove roba è in memoria. Spiacente Sto cancellando un po 'troppo. Ma non mi interessa dove le cose sono in memoria. E così, in effetti cosa programmatori tendono a pensare è che quando si parla di un indirizzo o un puntatore, chi se ne frega dove è in memoria. Non mi importa se è a byte di uno o di un miliardo. Ho appena interessa che questo variabile è efficace che punta a quel pezzo di memoria. E così, d'ora in poi, invece di cavillare su indirizzi di memoria arbitrari, diamo basta iniziare a disegnare puntatori come puntatori, come frecce. Così che cosa s e t sono davvero, secondo questo programma, a causa di come ho creato t, è solo a due variabili separate indicando nello stesso pezzo di memoria. E non ci importa dove si trovino. Così possiamo astrarre quel dettaglio. Allora, come posso risolvere questo problema? Se voglio scrivere una versione della copia Programma che in realtà copia la stringa e capitalizza solo il copia, solo intuitivamente, ciò che è avuto modo di essere un ingrediente alla nostra soluzione? PUBBLICO: [incomprensibile] DAVID J. MALAN: Abbiamo bisogno di una cosa? PUBBLICO: Bello pezzo di memoria. DAVID J. MALAN: Abbiamo bisogno un altro pezzo della memoria, giusto? Non sappiamo come farlo ma, necessariamente. Ma io tipo di bisogno di questo di accadere così che la mamma originale in minuscolo finisce in quel pezzo extra di memoria. E poi quando cambio la copia, io non vogliono cambiare questa copia qui. Io invece voglio cambiare solo questo copia in modo che l'originale è invariata. Quindi, vediamo come si potrebbe fare questo. In copia-1, che ha già stato spogliato della commento, ma è commentato in linea. Noi invece facciamo il following-- questi le linee sono identiche, mi ottenere una stringa e lo chiamano s. Ma ora diamo un'occhiata a uno dei nostri più complesso ma l'ultimo della complessità per un po ', la linea 16 fa esattamente questo. Quindi, se il vostro comodo con il immagine che abbiamo appena drew-- dammi un nuovo pezzo di memoria, copiare tutto in esso, vediamo come noi traduciamo che di codice. Quindi la linea 16, sul lato sinistro, char * t mi dà questa casella qui. Questo è tutto ciò che fa. Sul lato destro, m alloc o malloc, è l'allocazione della memoria, super elegante, un modo criptico di dire semplicemente dammi un pezzo di memoria. Quanta memoria abbiamo bisogno? Beh, è ​​una specie di grande espressione. Ma vediamo cosa dice qui. Quindi questo, naturalmente, è dare me la lunghezza della stringa di s. Così, la mamma dovrebbe essere cosa? Quindi, solo tre, giusto? mamma è di tre caratteri. Non si contano i backslash zero quando si parlare la lunghezza di una stringa è in realtà le lettere visibili umani. Così la mamma, quindi questo mi dà 3. Ma aspettate un minuto, ora sto aggiungendo 1. Perché Io in realtà voglio allocare 4 byte e non solo 3? Sì? PUBBLICO: Per il valore sentinella? DAVID J. MALAN: Esattamente, per quel valore sentinel. Per il backslash a zero, Ho bisogno totale di 4 byte. Quindi ho bisogno la lunghezza della stringa più 1. E poi per buona measure-- anche se su questo sistema, sta andando sempre essere 1-- sto dicendo moltiplicarlo per la dimensione di un char. Si scopre che è sizeof un operatore in C che solo la dice numero di byte che è necessarie per un certo tipo di dati. Non funziona per gli array, tipicamente, a volte lo fa. Ma nel caso generale, no. Ma mi dirà quanti byte un char è, che si rivela è sempre 1. Quindi questo è come moltiplicare per 1. Così super criptico cercando riga di codice. Ma tutto ciò che fa è dà me un pezzo di memoria. Ma lo fa sembra essere la copia tutto ciò in quella memoria? Non ancora. E così quello che faccio sulla linea 22, e 23, 24, 25, beh, io semplicemente faccio. E questa è una sorta di roba vecchia scuola ora. Questo è come PSet 2, dove si sta appena muovendo le cose giro in memoria, o meglio nelle stringhe. Così sto iterazione da 0 a la lunghezza della stringa s. E sto copiando il carattere i-esimo in s nel personaggio i-esimo in t. E perché io, il programmatore, ha fatto Assicurarsi di assegnare esattamente tanti byte come ho bisogno, è perfetto uno-a-uno. E copio mamma in minuscolo a quello nuovo. E poi, infine, lo faccio questa linea. E così l'effetto è solo di capitalizzare questo t qui. Così un sacco di assorbire, ma se si considera solo quello che sta realmente accadendo sul sotto la cappa sta semplicemente spostando questi byte intorno, tutto ciò che è necessario per risolvere questo problema è solo per darci questo pezzo di memoria. Ora con il rischio di travolgente, mi permetta di mostrare un altro esempio che è quasi identici, tranne per questo linea di codice. Quindi questa è la versione degli hacker di questo programma, se si vuole. Ma facciamo solo distillare in quello che sta succedendo. Linea 24 usato per essere questo t Staffa mi viene s staffa i. Ora, sto cambiando questo a il molto più criptico stella t più 1 uguale stella s più 1. Così che cosa sta accadendo e perché abbiamo un personaggio stella? Abbiamo visto la stella prima, e è in uso in modo diverso qui. Abbiamo in precedenza visto char *, ora sto vedendo Una stella, all'inizio, e va bene. Perché si scopre che può tipo di dedurre solo da quelli prima principi che cosa sta succedendo. Quindi, tanto per essere chiari, che cosa è s? La scorsa settimana, è stata una stringa. Ciò non basta più. Ciò che è s, in particolare? PUBBLICO: [incomprensibile] DAVID J. MALAN: Si tratta di un puntatore. E 'l'indirizzo del primo personaggio abbiamo digitato in. OK, che cosa è t? PUBBLICO: [incomprensibile] DAVID J. MALAN: Il indirizzo del primo byte in t, che pezzo di memoria riassegnati. Così si scopre che quando scorrere da 0 a fino alla stringa lunghezza-- innanzitutto, i inizia fuori a 0, perché di questa vecchia scuola per cosa ciclo. Quindi, solo per semplicità, facciamo supporre che la prima riga di codice è davvero solo questo, a destra. Se i è pari a zero, aggiungendo lo zero a qualcosa di presumibilmente non ha intenzione di avere un effetto. Così che cosa è questa parola? Si scopre che la stella operatore in questo contesto è il dereference operatore, che è solo un modo elegante per dire andare al seguente indirizzo. Quindi, se s è l'indirizzo del primo personaggio in questo pezzo di memoria, mezzi * s andare lì. E perché abbiamo disegnato l'immagine in questo modo, si può adottare la seguente modello mentale. Se questo è s, e tu dici s *, * s un po 'come scivoli e scale, se vi ricordate il gioco fin dall'infanzia, è come seguire quella freccia e andare all'indirizzo. * t è la stessa cosa. Così inizia qui, vai al suo pezzo. Non posso attingere questa schermata in quel modo. * t significa andare qui. E poi, il ciclo for è solo dicendo spostare questo personaggio qui, spostare questo personaggio qui, spostare questo personaggio qui. Ma come faccio a farlo l'incremento? Ho bisogno di disfare ciò che ho appena cancellato. Questo è ciò che generalmente chiamata l'aritmetica dei puntatori, che significa matematica con gli indirizzi. Se, in questo per ciclo, Continuo a incrementare i, ed s è un indirizzo e t è un indirizzo, se io continuo aggiungendo 1, che significa semplicemente andare avanti, e in avanti, e in avanti nella memoria. E 'come Oxford Street, la strada che l'edificio CS è acceso. Gli edifici CS è a 33 Oxford Street. Quindi, se si dovesse fare 33 Oxford Street più 1, che si porta a 34 Oxford Via, quindi 35 Oxford Street, poi 36 Oxford Street, qualunque essi edifici sono in realtà - se esistono. E così, è tutto quello che stiamo facendo qui con l'aritmetica dei puntatori. Quindi è un modo eccellente di arcano di esprimere noi stessi. Ma tutto quello che sta succedendo sotto la cappa sta solo seguendo questi indirizzi, come seguire una mappa, se si vuole, o dopo le frecce come abbiamo disegnato sullo schermo. OK, molto da digerire. Tutta la domanda sulla sintassi, concetti, puntatori, malloc, o simili. Sì, qui prima. PUBBLICO: Allora, dove che dice * t uguale toupper * t, è che andando a capitalizzare tutte le lettere o solo-- DAVID J. MALAN: Ah, davvero bella domanda. Quindi, in questa linea qui, 31, è questa intenzione di capitalizzare la prima lettera o tutte le lettere. Quindi cerchiamo di rispondere che andando torna a principi primi. E primi principi qui voglio dire basta andare alle definizioni di base di ciò che è coinvolto. Quindi toupper è una funzione che capitalizza un char. Questo è tutto. * t significa andare al first-- andare all'indirizzo in t. Così, nella foto, se questo è il pezzo della memoria abbiamo stanziato con malloc, e questo è t, * t significa andare qui. Nel frattempo, si sta passando tale valore, m minuscola a toupper, che stai ricevendo indietro M maiuscola, dove stai mettendo esso? Si sta mettendo in quella stessa posizione. E così da questa logica di quelli definizioni di base è solo capitalizzando la prima lettera a meno che non si scorre con i o un per loop o un ciclo while, non sta andando a fare qualcosa di più di quello che chiedete. Bella domanda. Sì? PUBBLICO: Perché si utilizza il dereference metodo piuttosto che la matrice? DAVID J. MALAN: Ah, bella domanda. Perché si usa il dereference il metodo invece del metodo array? Nessun motivo particolare, ad essere onesti. E, in effetti, per questo tipo di esempio, a destra, Sto solo sostenendo rendendo il programma più complicato, più gli occhi sono vetri sopra, persone stanno controllando perché questo sembra super arcano, ma anche se sta facendo la stessa cosa. E così, francamente, questo è un soluzione inutilmente visivamente complesso al problema. E 'ancora un buon design, cinque su cinque per la progettazione, se è nella staffa Notazione o la notazione puntatore. Ma-- soprattutto quando arriviamo più avanti nel corso di PSet 5 quando implementiamo che dizionario che Ho citato un paio di times-- ci realmente a cuore la indirizzi di memoria di basso livello che abbiamo davvero capire cosa sta succedendo. Ma, per ora, si scopre che questo riga di codice parentesi quadre qui in realtà non esistono. Sono quello che si chiama zucchero sintattico, che è solo un modo stranamente fresco di dire la compilatore converte parentesi quadre siano che espressione matematica. Quindi è una convenzione umana per essere in grado di scrivere solo queste staffe molto user-friendly. Ma ciò che il compilatore, clang, sta realmente facendo qualsiasi momento si scrive ciò che è evidenziato in linea 24, sotto il cofano è davvero convertendolo in questo. E 'solo più piacevole come un essere umano per leggere e scrivere codice come linea 24. Ma alla fine quelli ruote di formazione anche venire fuori quando la propria comodità si fa più forte. Va bene, quindi ricordare poi che questo Era il tipo di problema più grande abbiamo incontrato. Ed è quello che ha scatenato tutto questo conversazione frega niente di puntatori, e indirizzi, e copia le cose. Era perché ci inciampò questo stupido, stupido problema, per cui Ho implementato logically-- con Lauren qui sul demo e il succo d'arancia nel milk-- perfettamente Funzione algoritmicamente corretto per scambiare due variabili ' valori, ma il dannato non ha avuto alcun persistente o permanente, effetto sul mio codice. E perché questo? In poche parole, perché è questo implementazione di scambio logicamente corretto, ma non ha alcun impatto sulle variabili che sono passati ad esso, come xey per principale? Qual era il nocciolo della questione? Sì? PUBBLICO: Perché ha fatto variabile copie della variabile nel passaggio attraverso la funzione. DAVID J. MALAN: Esattamente, quando si passa variabili in funzione, o argomenti in una funzione, sono passò la copia, che significa che per ottenere un identico alla ricerca modello di bit per xey, chiamato qui e b. E si può fare nulla vuoi con quelle copie, ma che stanno andando a non avere effetto sulla funzione chiamante. E, infatti, abbiamo pareggiato che immagine sullo schermo, richiamo l'ultima volta, per cui se si davvero pensare a ciò che è in corso sotto la hood-- se questa è la memoria del computer, e qui è il pezzo di memoria in uso per principale, questo è il pezzo di memoria utilizzata per lo swap, e quindi, anche se principale ha due variabili, xey, di swap potrebbe avere cercando identici valori, che sono entrambi 1 e 2, ma sono completamente diversi blocchi di memoria. Quindi abbiamo bisogno di una soluzione a questo. E, francamente, sembrerebbe che ora avere una soluzione a questo problema, destra. Se ora abbiamo la possibilità di manipolare le cose per mezzo di indirizzi e, sorta di scivoli e scale stile, segui queste frecce e andare ovunque vogliamo in memoria, non potremmo risolvere questo problema passando da principale per scambiare non i valori che vogliamo scambio, ma solo intuitivamente quello che abbiamo potuto passare di scambiare invece? [VOICES interponendo] DAVID J. MALAN: Perché non solo passarlo gli indirizzi, giusto? Perché non diamo una di swap mappa del tesoro, se si vuole, che conduce al valori reali xe y. Facciamo di swap, effettivamente cambiare i bit originali, anziché solo di passaggio le copie dei bit. E così, infatti, che è ciò che è andando a essere la soluzione. Questa versione è qui chiaramente male e imperfetta. E ora, a prima vista, sembra proprio come abbiamo aggiunto un gruppo di stelle in modo casuale e attraversato le nostre dita che avrebbe compilato. Ma, sarebbe ora la compilazione. Ma vediamo che cosa significano queste cose. E, purtroppo, gli autori di C avrebbe potuto scegliere un altro simbolo per rendere questo un po ' chiara, ma l'operatore stella ha significato diverso in due contesti diversi. E abbiamo visto entrambi, ma cerchiamo di distinguere. Così in cima lì, quando ho cambiato A e B dall'essere Int di nella cattiva versione a int stelle, a e b, in precedenza, sono stati interi. Quali sono a e b ora in il bene, versione verde? Sono indirizzi. Indirizzi di ciò che, per essere chiari? Indirizzi di interi. Quindi il fatto che io sono dicendo mezzi int stella questo è l'indirizzo del un numero intero, specificamente. Così ora notare nelle righe di codice, un'altra cosa è cambiato troppo. tmp rimane lo stesso, perché è solo il numero intero temporanea, nessuna memoria magia lì. Ma un ora ha bisogno di una stella. E, infatti, ogni altra menzione di ae b, notare che tutto ciò che è cambia dal rosso al verde è che io sto prefisso le variabili con le stelle. Perché io non voglio copiare a e b. Perché se io copio solo A e B e di scambio A e B, che cosa sono io in realtà scambiando? A soli indirizzi, voglio scambiare cosa c'è in quegli indirizzi. Voglio andare là. E così l'operatore stella all'interno della mia funzione, non all'interno dell'elenco dei parametri, significa che si va a quegli indirizzi ed effettivamente modificare tali valori. Così che cosa l'immagine apparire come invece. Beh, se invece sto passando in per A e B non 1 e 2-- Io in realtà bisogno di aggiungere un altra definizione qui. Quindi supponiamo che questo pezzo di memoria è in posizione 10. Questo è in posizione 11, ma questo è un po 'di una semplificazione, Ora ho due scelte faccio a passare x e y o faccio a passare i loro indirizzi? Se io passo i loro indirizzi in questo modo, ho appena ora bisogno di attuare di swap per il codice verde in modo che quando si vede un e quando b vede, non solo una copia e b e spostare il latte e succo d'arancia. Il latte e succo d'arancia metafora ora si rompe, perché quelli sono coppe mappe di liquidi e non. Abbiamo invece bisogno di andare per affrontare 10 e noi bisogno di andare ad affrontare 11, e quindi eseguire questa logica swapping. Così la logica è lo stesso, ma abbiamo bisogno di un modo leggermente diverso di accedere a tali variabili. E così, alla fine, ciò che il programma deve assomigliare a questo. In swap.ce letteralmente copiato e incollato la versione verde. Ma ho bisogno di fare un cambiamento. Non è sufficiente solo per cambiare swap. Quale altra riga di codice devo cambiare? Sì? PUBBLICO: Dove ci vogliono gli argomenti. DAVID J. MALAN: Dove prende il suo argomento. Quindi, se ho scorrere fino al principale, ho non si può semplicemente passare xey, e, lo prometto, l'ultimo pezzo di nuova sintassi oggi. Ho bisogno di passare a non xe y ma l'indirizzo di xe y. E si scopre, il simbolo che di C gli autori hanno scelto è se si utilizza una e commerciale qui, per non essere confuso con la e commerciale bit per bit, se si utilizza una e commerciale qui e una e commerciale qui, questo capisce per voi, qual è l'indirizzo di x, forse è 10, qual è la indirizzo di y, forse è 11, e passa in quelli invece. Così un sacco di assorbire tutto in una volta. Ma vediamo ora rapidamente i nostri restanti quattro minuti dove le cose possono andare storte. E per inciso, in realtà Ho scattato questa foto, TF ha preso questa immagine di un anno o due fa. Quindi questo è l'angolo posteriore di Eliot Dining Hall. Puntatori sono forse il più difficile argomento che copriamo in CS50. Quindi, se vi preoccupate il tipo di salita è come forse è più di un bastone da hockey in questo modo, realizzare ci stiamo avvicinando tipo di un picco nel termini di complessità concettuale. E io portare questo foto, perché lo giuro a Dio, in autunno 1996, quando ho preso CS50 con il mio compagno di insegnamento, Nishat Mehta, mi si sedette nella angolo del Eliot D. sala durante il pranzo, o cena, o qualcosa da provare per aiutarmi a capire i puntatori. E questo è dove ero settimane dopo è stato introdotto in conferenza quando Ho finalmente capito puntatori. E sono fiducioso che questo si clicca molto prima per voi. Ma realizzare questo assolutamente tra gli argomenti più sofisticati abbiamo esaminato. Ma è tra i più potenti. E quando si arriva, è davvero tutto solo andando a venire finalmente insieme. Quindi state tranquilli non è così bisogno di tutto lavandino in oggi. Quindi, ecco l'ultimo programma stiamo andando a guardare. E stiamo andando a finire con un veloci tre minuti di claymation realizzato dal nostro amico, Nick Parlante. Ecco un programma, che sulla parte superiore di due linee dichiara una variabile xe y. Entrambi i quali sono gli indirizzi di interi, puntatori AKA. Abbiamo poi allocare abbastanza memoria per memorizzare un int e memorizzare l'indirizzo di quella memoria di x. Quindi, è ancora più semplice rispetto all'esempio precedente. Datemi quattro byte di memoria, che è la dimensione di un int, e mettere l'indirizzo di x. Questa riga qui significa andare all'indirizzo di x e mettere il significato di la vita, il numero 42 c'è. Ma questa linea mi preoccupa. A stella Y significa andare all'indirizzo di y, e mettere il numero sfortunato 13 lì. Perché è pericoloso, a questo punto nei tutta-- seppur rapidamente detto nei nostri minuti calante qui-- perché è cattivo per me dire, andare all'indirizzo di y? PUBBLICO: non avete [incomprensibile]. DAVID J. MALAN: non ho mettere qualcosa in a. Allora, qual è il valore di y, a questo punto della storia? Non abbiamo idea. E 'certo valore spazzatura e né sa Binky. Se potessimo finire in questa nota. [RIPRODUZIONE VIDEO] Ehi, Binky, svegliati. E 'il momento per l'indicatore del divertimento. -Che cos'è? Ulteriori informazioni su puntatori? Oh, Goody. -Bene, Per iniziare, credo che siamo andando a bisogno di un paio di puntatori. -OK. Questo codice assegna due puntatori che può puntare a numeri interi. -OK, Beh vedo il due puntatori, ma che non sembrano essere che punta a qualsiasi cosa. -Giusto. Inizialmente puntatori non puntare a nulla. Le cose a cui puntano sono chiamato pointees e impostandole è una fase separata. Oh, giusto, giusto. Sapevo che. I pointees sono separati. Così come si fa assegnare una pointee? -Ok, Anche questo codice alloca un nuovo pointee intero, e questo imposta parte x per puntare ad esso. Ehi, che sembra meglio. Così fargli fare qualcosa. -OK, Io dereference il puntatore x a memorizzare il numero 42 nella sua pointee. Per questo trucco, avrò bisogno la mia bacchetta magica di dereferencing. -La Tua bacchetta magica di dereferencing? Uh, che, che è grande. -Questo È quello che il codice assomiglia. Mi limiterò a impostare il numero di e- [POP SOUND] Ehi, guarda lì si va. Quindi, facendo un dereference su x segue la freccia per accedere sua pointee. In questo caso, per memorizzare 42 lì. Ehi, provare a utilizzare per memorizzare il numero 13 attraverso l'altro puntatore, y. -OK. Vado a qui per y, e ottenere il numero 13 set up. E poi prendere la bacchetta di dereferencing e solo-- [BUZZER AUDIO] Oh, hey che non ha funzionato. Di ', uh, Binky, non lo faccio pensare dereferencing y è una buona idea, perché l'impostazione il pointee è una fase separata. E non credo che abbiamo mai fatto. -Hmm, Buon punto. -Già, Abbiamo assegnato il puntatore, y, ma non abbiamo mai impostiamo a puntare a un pointee. -Hmm, Molto attento. Ehi, stai guardando bene lì, Binky. Riesci a risolvere il problema in modo che i punti y allo stesso pointee come x. -Certo, Io uso la mia bacchetta magica di puntatore assegnazione. -È Che sta per essere un problema, come prima? No, questo non tocca i pointees. Cambia solo un puntatore per puntare allo stesso cosa-- [SCHIOCCANDO SOUND] -come un'altra. -Oh ho visto. Ora y punti allo stesso luogo di x. Quindi, attendere, ora y è fissato. Ha un pointee. Così si può provare la bacchetta di dereferencing di nuovo per inviare il 13 sopra. Oh, OK, qui va. Ehi, guarda che. Ora dereferencing opere a. E poiché i puntatori sono la condivisione che uno pointee, entrambi vedono il 13. -Sì, Condivisione, uh, qualunque cosa. Quindi, abbiamo intenzione di cambiare posti ora? Oh, guarda che siamo fuori tempo massimo. -But-- -Basta Ricordare le tre regole puntatore. Numero 1, la struttura di base è che avete un puntatore, e che punti verso un pointee. Ma il puntatore e pointee sono separati. E l'errore comune è di creare un puntatore ma a dimenticare di dare un pointee. Numero 2, puntatore dereferenziazione inizia al puntatore e segue la sua freccia sopra per accedere alla pointee. Come tutti sappiamo, questo funziona solo se c'è è un pointee, che tipo di ottiene indietro alla regola numero 1. Numero 3, puntatore assegnazione prende un puntatore e lo cambia per puntare al stesso pointee come un altro puntatore. Così, dopo l'assegnazione, i due puntatori punterà alla stessa pointee, a volte che si chiama la condivisione. E questo è tutto ciò che devi fare, davvero. Addio ora. [FINE RIPRODUZIONE] DAVID J. MALAN: Questo è tutto per CS50. Grazie al professor Nick Parlante. Ci vediamo la prossima settimana. [RIPRODUZIONE MUSICA ELETTRONICA]