JASON HIRSCHHORN: Benvenuto, tutti, Settimana 6. Sono felice di vedervi tutti vivi e vegeti dopo Quiz 0, perché so che era un po 'agitato. Ma per fortuna, a tutti voi ha fatto incredibilmente bene. E così che è meraviglioso. Se siete nella mia sezione, ho dato più di voi eseguire i vostri quiz già. Un paio di voi, sto incontro dopo le lezioni. E se sei uno studente interno e non avete ricevuto il vostro quiz schiena Eppure, il tuo TF sta probabilmente lavorando su di esso e classificazione, e otterrà indietro al più presto. Così i miei studenti di estensione che sono guardando proprio ora - si spera vivere - Mi metterò i vostri quiz A breve pure. La nostra agenda per oggi è la seguente. In primo luogo, stiamo per andare oltre alcune risorse che CS50 offre a voi. Stiamo per andare oltre Quiz 0 prossimo, e Risponderò a tutte le domande nessuno ha circa problemi particolari. E poi, andremo oltre file I / O e di problem set 5. Queste ultime due temi prenderanno la massa della sezione di oggi. Ho messo questa lista ogni settimana come un ricordo a tutti voi, ma del core sezione, abbiamo solo 90 minuti - abbiamo non sono in grado di coprire tutto ciò che ho piacerebbe a coprire per voi ragazzi. Ma abbiamo un sacco di risorse per di disegnare su come si arriva a conoscere il materiale e lavoro attraverso il problema imposta. Un ricordo che ho in linea un testo box, impostato per voi a compilare se avere tutte le risposte per me, sia positivi che costruttivo, su sezione. Tale URL è situato proprio qui. Quindi, per favore, prendete un momento se avete qualunque feedback, sia durante la sezione, o dopo, o dopo si guarda il video on-line, di darmi le vostre risposte. Ho davvero apprezzato ogni e qualsiasi di esso. Così ho avuto piccole conversazioni con un sacco di mio gli studenti per tutta la settimana - come ho consegno quiz indietro, parlando del Certo, vedendo come si sta facendo. E un tema ha messo sopra e oltre a parlare - in particolare - problema di imposta. E ho incapsulato quel tema sulla scheda al momento. In sostanza, c'è una differenza tra trasformare in qualcosa che è fatto correttamente e qualcosa che è fatto bene. La maggior parte delle persone hanno fatto fantastico in termini di correttezza - 5 o 4 del su tutti i pset. La maggior parte delle persone sono sempre quelli tutto il tempo. Tuttavia, solo perché hai fatto qualcosa di giusto non vuol dire che hai fatto qualcosa come elegantemente, o efficiente, o in modo pulito, come si avrebbe fatto. Ed è quello che il disegno - e in misura minore, di stile - assi sono per. Così ho tutti voi sto spingendo, e altri TF stanno spingendo voi ragazzi, non solo turno nelle cose che sono corrette, ma si trasformano nelle cose che sono codificati bene. Non fare inutili per cicli, Non ricalcolando le variabili se tu non devi. Ad esempio, guardando indietro al problema posto 4, quando si posiziona i mattoni sul schermo, ogni riga - ogni mattone in un determinata riga ha la stessa coordinata y - coordinata alla stessa altezza. In modo che coordinata y non ha bisogno di calcolata all'interno l'interno nidificato ciclo FOR che probabilmente utilizzato di mettere quei mattoni sullo schermo. Ha solo bisogno di essere calcolato ogni il tempo si è passati una riga, o spostato verso il basso una riga. Quindi dire se ci sono 10 mattoni in un riga, ogni mattone può avere la stessa coordinata y, e che coordinata y può solo essere calcolato una volta per tutti coloro. Essa non deve essere calcolato 10 tempi, né che la necessità di calcolo ad accadere nel reale funzione di chiamata - la nuova chiamata di funzione gracked. Quindi, se questo è stato un po 'di confusione per si, più genericamente, le cose che non è necessario che accada ogni volta si passa attraverso un ciclo FOR non dovrebbe essere inserire all'interno del ciclo FOR, e non dovrebbe accadere ogni volta che si va attraverso il ciclo FOR. Un altro buon esempio di progettazione che abbiamo visto nella Settimana 3 per 15, si potrebbe mantenere traccia dello zero. Così, quando si inizializza la scheda, si salva - in una variabile globale, forse - x e y-coordinate dello zero. E poi ogni volta che - nella funzione mossa, ogni volta che fate una mossa di successo, si aggiorna il posizione dello zero. Che ti farebbe risparmiare da dover fare cicli for nidificati di guardare attraverso il bordo ogni volta che nella funzione mossa e trovare lo zero, o trovare la tessera, e quindi controllare che cosa è accanto ad essa. Invece, si ha la posizione del zero, si può solo guardare sopra, sotto, ed a sinistra ea destra di esso, per trovare la tegola che stavi cercando. Quindi, in termini di programmi che stiamo la scrittura, non sono mai abbastanza grandi che alcune di queste scelte progettuali sono davvero intenzione di ostacolare il vostro programma, o farlo girare più lentamente, o forse anche a corto di memoria. Ma stiamo ancora spingendo ragazzi scrivere come elegante e codice efficiente possibile. Quindi, se si finisce per scrivere cose che hanno una significativamente più grande campo di applicazione, che sarà scritto con buona progettare oltre ad essere corretta. Così alcuni di voi avete portato che fuori. Questo è qualcosa che stiamo cercando - qualcosa che stiamo andando a continuare a ti spingono ragazzi su. Se avete qualunque domande circa l' progettazione del programma, sentiti libero per raggiungere me, e io sono felice di a piedi attraverso il programma con voi, e sottolineare alcune del disegno decisioni che hai fatto, e darvi qualche suggerimenti su come rendere ancora migliori decisioni progettuali. Quindi stiamo andando a passare a parlare Quiz 0. Prima di farlo, lo fa nessuno Per qualsiasi domanda su cosa Ho coperto finora? [Fruscio] JASON HIRSCHHORN: Sette secondi. OK. Parliamo Quiz 0 per un po '. La maggior parte di voi hanno vostra Quiz 0 schiena. Se non, si spera ti ricordi un po '. Ma se hai preso Quiz 0, allora si anche avere accesso al file PDF online le soluzioni campione. Qualcuno ha domande prima saltiamo nel materiale della settimana su un problema particolare Quiz 0 - perché la risposta è quello che è? C'è qualcuno confusi su qualcosa? Anche se hai il problema di destra, ma solo vorrei farmi spiegare un po ' di più, sono felice di farlo ora. Così ho chiesto a voi ragazzi vengono preparati con un po ' pensieri su Quiz 0. Allora, chi vorrebbe farci iniziare con una domanda o commentare Quiz 0? [CARTA STORMIR] JASON HIRSCHHORN: Non tutti ha fatto perfettamente. Quindi so [ride] ci devono essere alcune domande Quiz su 0. OK. Sì. Ompica. OMPICA: Number 10. JASON HIRSCHHORN: Number 10. Quale era il numero 10? OMPICA: The - JASON HIRSCHHORN: I haven't - OMPICA: The includono - JASON HIRSCHHORN: Number 10 aveva otto anni per i - la scrittura otto i? OMPICA: Già. JASON HIRSCHHORN: OK. Quindi un'altra domanda si potrebbe avere Domande era sto preveggente? La risposta è sì. Nella sezione prima del quiz, ho chiesto voi ragazzi per codificare sia Sterling e otto a i. Entrambi successo a apparire sul quiz. Così si spera, hai pagato attenzione. E se tu avessi, allora si avrebbe probabilmente fatto bene su quelle due. Ma otto i, in realtà non abbiamo il codice in classe, ma era, di nuovo, ha chiesto il quiz. Così un paio di cose da prendere nota quando codifica otto a i. La prima cosa, per la domanda, è stato che avevi bisogno di controllare se la stringa è stato pari a null. Un paio di persone hanno cercato di controllare più tardi nel programma se s staffa mi è stato - così un carattere specifico in quanto stringa - è stato pari a null. Ma ricordate, che nulla è sostanzialmente - è bene pensare null come un puntatore nullo - un puntatore a zero - da qualche parte nella memoria in cui non si può mai accedere. Quindi, se qualcosa è uguale a null, sa che non è stata inizializzata, o non c'è niente. Così s è una stella char, s staffa i è un char. Quindi ha senso confrontare s null, ma non s staffa i null. Ma ancora una volta - così che era la prima cosa che si doveva fare - controllare per assicurarsi che effettivamente ottenuto una stringa reale. Successivamente, si voleva andare attraverso ogni carattere della stringa. E così sarebbe come una staffa s Io, per esempio, se i è l'iteratore. E prendere quel personaggio, e ottenere il suo valore effettivo. Avete memorizzato come char, ma il valore ASCII per lo zero - zero come un personaggio - non è in realtà il numero intero zero. E 'un altro numero che è possibile cercare nella tabella ASCII. Quindi un modo per correggere questo - probabilmente il modo migliore per correggere che - è sottrarre da esso il valore del carattere - azzerare come un carattere. Quindi meno sola offerta, pari a zero, un altro singolo preventivo. Ciò prendere qualunque numero che avete come char, e farlo uguale a il numero come un numero intero reale. E che è molto simile all'approccio un sacco di gente ha preso in problema set 2, con Cesare e Viginere - tali cifre, quando si sono stati loro rotazione. Così, dopo aver come un numero da zero a nove, poi - a seconda dove va nel numero finale - è necessario moltiplicare da una potenza di 10. Alcune persone si sono spostate dalla parte posteriore al anteriore, e moltiplicato l'individuo numero per una potenza di 10. Alcune persone si sono spostate da il front to back - e così ha preso il massimo i numeri di ordinazione prima - e avrebbe salvato quelle in variabile contatore globale. E poi ogni volta attraverso FOR loop, moltiplicare quel gigante mondiale contrastare variabile da 10, per rendere spazio per il carattere successivo. Così che era un po 'di confusione, senza me scrivere sulla scheda. Ma la soluzione campione è a vostra disposizione. Ma quelli erano i grandi cose stavamo cercando. Anche un controllo per assicurarsi che ogni carattere individuale era effettivamente un carattere tra zero e nove, e non altri caratteri, come una A, per esempio. Quelle erano le cose che stavamo cercando in tale questione. Questo risponde alla tua domanda? OMPICA: Già. JASON HIRSCHHORN: OK. Ci sono altre domande Quiz su 0? Che dire di compilazione? Tutti compilazione giusto? No. C'erano - [Ride] Tutte le domande circa l' processo di compilazione? Wow. [CARTA STORMIR] JASON HIRSCHHORN: sì. Michael. MICHAEL: E 'il numero 7 - casuale? JASON HIRSCHHORN: numero 7. Numero 7 era ottenere un numero intero casuale. Eccellente. Così si è dato un numero intero a e un intero b, e volete una casuale intero compreso tra ae b. Possiamo effettivamente scrivere questo su il consiglio, perché questo Era una riga di codice - un modo per farlo. Quindi stiamo dato Drand come funzione abbiamo potuto usare. E che cosa Drand - ammesso che è stato seminato - ciò che Drand ritorno? MICHAEL: Un float tra 0.0 e 1.0. JASON HIRSCHHORN: Un numero - sì. Un numero compreso tra 0 e 1. E così abbiamo b e a. E poi abbiamo il nostro numero casuale tra 0 e 1 dato a noi da Drand. Alcune persone hanno cercato di mettere b, oppure b meno una, o qualcosa dentro quelle parentesi. Ciò significherebbe che sono argomenti a questa funzione. Drand non prende alcun argomento - come getString fa Non prendere argomenti. Quindi è solo parentesi aprire, chiudere Paren - e che, a sua volta, è la chiamata di funzione. E che ti dà un numero tra 0 e 1. Certo, abbiamo una vasta gamma che i numeri possono essere in Dire, se b è 10 ed è un 5, abbiamo davvero desiderare un numero con un intervallo di 5. Così la prossima cosa che dobbiamo fare è moltiplicarlo per la gamma b meno una. Quindi, supponendo che è moltiplicato. E che ci darà un numero all'interno di un determinato intervallo. E questo intervallo specifico è il differenza tra b meno una. E, infine, che ti do solo da - dire l'intervallo tra b meno una è 5, che ti do noi un numero da 0 a 5. Ma se a è in realtà 5, abbiamo bisogno di aumentare questo intervallo fino a dove è in realtà dovrebbe essere, con l'aggiunta di una. Così che ottiene il diritto di logica. E poi, avreste un'altra domanda? MICHAEL: No. Mi sento veramente stupido adesso. [Ride] JASON HIRSCHHORN: No. Non si sentono veramente stupido. Un certo numero di persone ha lottato con questa domanda. E poi, l'altra domanda è, Drand, hai detto, ti dà un galleggiante - restituisce un float. Ma questa funzione effettivamente chiesto per un numero intero da restituire. Non è necessario lanciare esplicitamente in un numero intero, perché questi operazioni saranno trattarlo come un tutto float - come un numero in virgola mobile. Ti piace questa volontà - anche se questo è un numero intero, questa volontà essere moltiplicati correttamente. Tutta la moltiplicazione funzionerà. Non c'è bisogno di lanciare qui. In realtà, non si dovrebbe lanciarla. Che sarebbe - se volesse lanciare un numero che è tra 0 e 1 - un numero casuale, a virgola mobile - allora o sarà solo 0 o 1, così perderai tutto ciò precisione. Ma alla fine, quando si torna, diventa automaticamente rispedito come un intero. Quindi non c'è bisogno di fare che la colata te. Quindi questa è stata la risposta di tale questione, il numero 7. Tutte le altre domande su Quiz 0? Sì, Annie. ANNIE: Quando usiamo ricorsiva - quando usiamo loop iterativi? JASON HIRSCHHORN: Quando si usa ricorsiva - in modo più generale, l' pro e contro di ricorsione contro un approccio iterativo. Qualcuno può offrire un pro o un contro? Si prega di? Non è possibile a nessuno. Chi può offrire un pro o un contro? [CARTA STORMIR] STUDENT 1: ricorsiva è meno codifica - meno di battitura? JASON HIRSCHHORN: Quindi in generale, ricorsione soprattutto, una funzione - o un algoritmo simile unione liste - che si presta ad un approccio ricorsivo - potrebbe essere più semplice di codificare in modo ricorsivo. E proprio più senso per farlo in modo ricorsivo. Quindi sarebbe un professionista per ricorsione. Altri? Sì? STUDENTE 2: Con per ricorsione - Esso utilizza più memoria. JASON HIRSCHHORN: So esattamente a destra. Una funzione ricorsiva manterrà aggiungendo dello stack frame nello stack. Quindi, se si opera su un lotto di numeri, e chiamare questo funzionare molto, allora si avrà certamente occupano più memoria, mentre un approccio iterativo solo mettere uno impilare fotogramma sullo stack, perché tutto avviene all'interno di una funzione. Eventuali altri pro ei contro? Già. STUDENTE 3: Pro per ricorsione. Non è necessario determinare in anticipo quante volte l' codice doveva essere ripetuto. Si può avere un numero predeterminato di volte che si deve scorrere, poi ricorsione è meglio, perché prende tale risultato. JASON HIRSCHHORN: Penso che sia vero. Ma credo che in entrambi i casi si farebbe mai - si sarebbe probabilmente ottenere qualche input dall'utente. O questa funzione dovrebbe avere un po 'di ingresso che avrebbe determinare quante volte dovrebbe funzionare. Quindi in generale, non sarebbe codificare - anche in un approccio iterativo - come molte volte che ciclo deve essere eseguito. Hai avuto un altro eri pensando, Annie? OK. Così quelli sono probabilmente i due - il più grande pro e il più grande confermare una ricorsiva contro un approccio iterativo. OK. Tutto il resto su Quiz 0? Andiamo avanti. File I / O. C'è un meraviglioso corto questa settimana sul file I / O che si spera avete visto multiplo volte, e ammirato. Un sacco di lavoro è andato in questo, e ho sentito dire che è follemente disponibile. Ho inserito anche il link in questa diapositiva, nel caso in cui non hai avuto un possibilità di vedere 10 volte. Quindi, ci accingiamo ad andare brevemente il grandi passi verso l'apertura e di lavoro con i file, e quindi ci accingiamo a tuffarsi in un problema di codifica prima esaminare il problema proposto. Quindi, di nuovo, ho intenzione di mettere questo su lo schermo, ma ho intenzione di parlare per appena un minuto su ciò che siamo facendo qui con il file I/O-- che cosa significa? Questo significa che possiamo creare il nostro programmi, e quindi avere i nostri programmi uscita, e non hanno fatto alcun impatto sulla il mondo esterno del nostro programma. Ma quando cominciamo a lavorare con i file - sia la loro lettura e la creazione di loro - possiamo avere qualche effetto sulla al di fuori del nostro programma di mondo. Proprio come se Microsoft Word non era in grado per fare tutti i documenti di Word, quindi una volta Microsoft Word smettere, tutti i tuoi lavoro sarebbe andato, e sarebbe davvero inutile. Facciamo infine vogliamo essere in grado di scrivere programmi che possono influenzare l' mondo che li circonda, sia prendendo in Ingressi complesse - in termini di file e tramite file, e anche la creazione di interessante e uscite convincenti - in termini di diversi tipi di file. Ecco perché stiamo iniziando a imparare a lavorare con i file. Più specificamente, ciò che facciamo è la seguente. E 'molto semplice. Ci sono solo un paio di passi, e sono elencati qui su questo codice. Quindi stiamo per passare attraverso questo codice riga per riga. In primo luogo, si vede evidenziato - quando si lavora con un file, indipendentemente dal tipo di file è, è necessario aprirlo. E cioè con una chiamata a fopen - proprio qui. Di includere il nome del file. Se il file non si trova nella directory, o la cartella in cui questo programma vita, allora si devono anche includere un percorso in cui il file è. Stiamo andando a supporre che questa file chiamato "text.txt" - un semplice documento di testo - è in stessa cartella di questo programma. Quindi, questa è un'altra cosa da tenere in mente - che se si desidera aprire un file da qualche altra parte, hai veramente bisogno per includere la sua posizione. In secondo luogo, è possibile passare un argomento fopen, ed è quello che si vuole fare con il file. Ci sono tre principali argomenti che avete intenzione di passare a fopen. Chi mi può dare quei tre? Chi mi può dare una di loro? Sì. STUDENT 4: Il nome del file? JASON HIRSCHHORN: Mi dispiace. Tre argomenti principali è possibile passare come secondo argomento di fopen. Hai ragione - il nome del file è il primo argomento. Ma il secondo argomento di fopen sono generalmente tre corde, e - sì. Aleja. ALEJA: A per l'aggiunta. JASON HIRSCHHORN: A, se si vuole aggiungere a un file già esistente. STUDENTE 5: R per la lettura. JASON HIRSCHHORN: R, se si vuole leggere da un file. STUDENTE 6: W per la scrittura. JASON HIRSCHHORN: E w, se si voglia di scrivere in un file. Quindi, in questo caso, stiamo scrivendo al file, così abbiamo w. Si apre, si hanno anche per salvare l' file da qualche parte, e questo è il codice alla sinistra delle l'operatore di assegnazione - Sto creando un puntatore a un file chiamato, in questo caso, file. Non stiamo andando a preoccuparsi che cosa questo tutti i tappi cosa FILE è. Basti dire, è un lungo flusso di zero e uno. Ed è così che ci accingiamo a operare e capire. La prossima cosa che dobbiamo fare - e questo è incredibilmente importante - ogni volta che si apre un file - infatti, ogni volta che si chiama malloc, per esempio, e un po 'di memoria e provare e salvarlo in un puntatore, è sempre vuole controllare per assicurarsi che tale funzione non ha restituito nulla. Quindi, in questo caso, stiamo verificando fare certo che abbiamo effettivamente aperto la il file correttamente, e non c'era nessun errore nel nostro programma. Poi, una volta che abbiamo controllato per assicurarsi che abbiamo un file di lavoro, possiamo scrivere o leggere, o aggiungere al file. In questo caso, sto semplicemente stampando una riga a questo file. Come faccio a sapere che? Beh, io sto usando questa funzione chiamato fprintf. Tutte le funzioni si intende utilizzare durante la scrittura o lettura da, o la gestione di file sarà simile a funzioni che hai visto prima, ma inizia con la lettera F, in piedi per il file. E fprintf, a differenza nostra stampa normale app, prende un argomento aggiuntivo, e questo è il file in cui si consiglia di stampare questa linea. Io non ho nulla da il diritto di ohai. Non ho la terza argomento di printf - o il secondo argomento a printf, l' terzo argomento fprintf, perché io non hanno alcun segnaposto qui. Io non sono comprese le eventuali variabili. Ma ancora una volta, fprintf e tutti questi file di funzioni che operano con i file sono generalmente andando ad avere bisogno del file su cui sono operativi. Infine, l'ultima cosa importante fare è chiudere il file, proprio come con - ogni volta che malloc qualcosa, vogliamo liberare qualcosa, per non una perdita di memoria - vogliamo per chiudere il nostro file. Se questo programma esce senza chiusura il file, le probabilità sono niente sarebbe andato sbagliato, soprattutto se era un piccolo file. Ma è certamente un buon stile di codifica e la pratica di chiudere sempre il file quando hai finito di usarlo. In modo che sia le basi di file I / O. Avete probabilmente visto che prima, o guardato in quel fantastico breve. Qualcuno ha domande, prima di andiamo in qualche codifica pratica problemi, circa file I / O o passi che ho appena andato oltre? [DATTILOGRAFIA SUONI] JASON HIRSCHHORN: Ti una domanda, Avi? AVI: No. JASON HIRSCHHORN: OK. Ho intenzione di aspettare un altro sette secondi. [Ride] Questo è davvero un buon suggerimento. Voi ragazzi proprio non mi piace domande. Va bene. OK. Quindi il nostro problema prima pratica è, siamo andando a duplicare la funzione di uno strumento a riga di comando che probabilmente usato prima - copia - lo strumento di copia. Se si digita cp e poi passarlo due argomenti nel vostro terminale, è possibile copiare un file. Ed è quello che stiamo andando scrivere adesso. Quindi, di nuovo, leggendo di questa diapositiva, mi piacerebbe di scrivere un programma che prende due e solo due da riga di comando argomenti - un file di origine e un file di destinazione - e copia il contenuto della sorgente file per il file di destinazione un byte alla volta. Quindi questo è molto da chiedere. Ancora una volta, un buon approccio a questo è di Non andare dritto al codice C, ma scomposizione in un paio di passaggi. In primo luogo, pensare la logica - esattamente quello che ti sto chiedendo di fare - e comprendere tutte le passi per questo problema. Non in C, solo in alcuni pseudocodice, o anche un modello mentale di cosa sta succedendo. Poi, una volta che hai il pseudocodice verso il basso, capire come lo pseudocodice mappe sul strumenti e tutte le cose che abbiamo imparato ad usare in C. E, infine, una volta che avete tutto quello che insieme, è possibile codificare il problema. Prendere 5 a 10 minuti per lavorare su questo problema. Metterò le istruzioni back up in un secondo. E poi stiamo per andare oltre pseudocodice, e codice dal vivo come gruppo. Se avete domande, mentre sei lavorare su questo, sentitevi liberi di aumentare la tua mano, e io verrò intorno e rispondere loro. STUDENTE 7: Posso strisciare un pezzo di carta? JASON HIRSCHHORN: Che cosa succede? [DATTILOGRAFIA SUONI] JASON HIRSCHHORN: OK. Andiamo oltre il pseudocodice prima, e allora ti darò un paio di più minuti per finire la codifica. Chi vorrebbe cominciare fuori di me con la prima linea di pseudocodice per questa funzione? STUDENTE 8: Verificare che vi è stata data due file. JASON HIRSCHHORN: OK. E se non siamo? STUDENTE 8: Vorrei restituire 0. JASON HIRSCHHORN: Dovremmo tornare 0? STUDENTE 8: Ritorno a - tranciatura. Scusi. JASON HIRSCHHORN: Già. Probabilmente no 0. Poiché 0 significa tutto era buono. OK. Ecco, questo è la prima linea di pseudocodice. Chi ha la seconda linea di pseudocodice? STUDENTE 9: Aprire entrambi i file? JASON HIRSCHHORN: Aprire entrambi i file. OK? STUDENTE 10: Verificare se il file è NULL? JASON HIRSCHHORN: Verificare certo non sono NULL. Per inciso - tagliare 0 - è che NULL? STUDENTE 11: No. JASON HIRSCHHORN: Questo non è NULL. Che si chiama il terminatore NULL. In realtà è scritto con una sola l. Quindi la verifica qualcosa contro questo - che in realtà è un personaggio - in modo da controllare qualcosa contro che è non lo stesso controllo per vedere se è uguale a NULL. E alcune persone - sulle loro quiz e il loro problema set - hanno ottenuto l' due di quelli confusi. Ma i due di questi sono infatti differente. Uno finisce una stringa - uno è un puntatore a 0. STUDENTE 12: Perché non si dovrebbe verificare assicurarsi che i file non sono NULL prima di aprirli? JASON HIRSCHHORN: So aperto salva qualcosa in quel file. E se si torna qui - quindi questa linea - fopen - vi darà un indirizzo e negozio tale indirizzo nel file se funziona. Se non funziona, memorizza NULL - STUDENTE 12: Oh. OK. Avete ottenuto. JASON HIRSCHHORN: In file. Così non si può controllare NULL prima di aver aperto. NULL significa qualcosa non ha funzionare correttamente. OK. Quindi, verificare che nessuno dei due è? O sono? Che cosa pensiamo? Andremo con quello. STUDENTE 13: Is. JASON HIRSCHHORN: Is? Nessuno dei due è? STUDENTE 13: Is. JASON HIRSCHHORN: OK. Ci sembra di avere un po ' consenso su questo. Nessuno dei due è NULL. OK, prossima linea di pseudocodice. Chi non mi ha ancora dato una linea? Vi aspettiamo per voi. Già. STUDENTE 14: Devi leggere dal primo file? JASON HIRSCHHORN: OK. STUDENTE 14: O usiamo fscanf o qualcosa di simile al primo file? JASON HIRSCHHORN: Così vogliamo leggere dal primo file e - mettiamo che proprio qui. Leggere dal file di origine. E poi, cosa facciamo dopo che abbiamo leggere dal file di origine? Qualcun altro? STUDENTE 15: Scrivere in il file di destinazione? JASON HIRSCHHORN: Scriviamo a il file di destinazione, e - OK. Che cosa ci manca? Qualcun altro che non mi ha dato una riga di codice ancora - di pseudocodice. Già. STUDENTE 16: Forse si può sempre controllare se c'è qualcosa da leggere per, come la prossima linea? Che sono come la linea successiva, vedere se esiste. [ELETTRONICA BEEP] JASON HIRSCHHORN: Oops. Questo è il mio software journaling. Sì? STUDENTE 16: Già. JASON HIRSCHHORN: Quindi dare a me ancora una volta. STUDENTE 16: Verificare se c'è ancora una riga successiva dal file sorgente da leggere. JASON HIRSCHHORN: OK. Quindi noi non stiamo leggendo righe - leggevano bytes qui - ma siete sulla strada giusta. Vogliamo leggere e scrivere fino a non ci sono più byte. OK. E così questi dovrebbero davvero essere rientrato un po ', perché sono lì sotto. Giusto? Fino a quando siamo fuori di byte, stiamo andando a leggere dal file di origine e scrivere per il file di destinazione. E allora, che cosa è l'ultimo linea di pseudocodice? Qualcuno che non è dato me qualcosa ancora. STUDENTE 17: Chiudere i file? JASON HIRSCHHORN: Esattamente. Chiudere i file. Quindi c'è il nostro pseudocodice. Ho intenzione di mettere il pseudocodice in gedit, e in un paio di minuti siamo sarà codificare questo insieme. OK. Cerchiamo di iniziare come un gruppo. Nishant, ho il mio nuovo file. Ho appena aperto questo. Documento senza titolo 1. Qual è la prima cosa che dovrei fare? Nishant: Includere librerie? JASON HIRSCHHORN: OK. Quali biblioteche? Nishant: stdio.h, stdlib.h, credo? JASON HIRSCHHORN: OK. Che cosa è stdlib per? Nishant: ho dimenticato. JASON HIRSCHHORN: OK. Quindi includere stdio. Cosa devo fare anche prima Comincio codifica? Nishant: Scrivere un colpo di testa? JASON HIRSCHHORN: How posso farlo colorato? [VOCI interponendo] Nishant: Come si ottiene è di colore? JASON HIRSCHHORN: How faccio codifica a colori? Nishant: Non lo so. Oh. Salva. JASON HIRSCHHORN: Salva. Sì. Dovrei salvarlo come. C. Quindi salvarlo sul desktop come cp.c. Dolce. E se voglio ottenere pieno stile punti, cosa dovrei includere in alto? Nishant: Si potrebbe scrivere il vostro nome, il nome del programma, e lo scopo del programma come bene? JASON HIRSCHHORN: Sembra buono. Eccellente. Così ci hai iniziato fuori perfettamente. # Include - faremo anche scrivere - OK. Quindi penso che sto tutto pronto per andare. Chi ha la prima riga di codice per me - o le prime righe di codice che ci vorrà per soddisfare il nostro primo commentare in pseudocodice? Tu. STUDENTE 18: Non dovrebbe essere int argc, e quindi char * argv? JASON HIRSCHHORN: Penso hai ragione. Cambiamo a int main, parentesi aperte, int argc, virgola, char * argv? Ti piace questo? STUDENTE 18: staffe. JASON HIRSCHHORN: staffe. Aprire la staffa, vicino staffa, close genitore. Perfetto. Ora posso prendere gli argomenti della riga di comando. OK. Assicuriamo che stiamo dato due file. Potete darmi anche quello. STUDENTE 18: Se argc - questo non è uguale a 3. JASON HIRSCHHORN: Se parentesi aperte argc non uguale a 3? STUDENTE 18: Sì, si torna 1 o nulla. JASON HIRSCHHORN: Mi dispiace. STUDENTE 18: Ritorno 1 o nulla. JASON HIRSCHHORN: ritorno 1. OK? Grande. Aprire entrambi i file. Chi può aiutarmi ad aprire entrambi i file? Chi non mi ha ancora dato il codice? Kurt? KURT: Quindi tutti i tappi F-I-L-E di origine stelle. JASON HIRSCHHORN: Io vado per eliminare le vocali. Quelli sono cool. E 'come Tumblr. STUDENTE 18: Equals fopen - JASON HIRSCHHORN: Uguale fopen? STUDENTE 18: Aperto parentesi, argv, parentesi aperta. JASON HIRSCHHORN: Aspetta. Scusi. Aperto parentesi. OK. STUDENTE 18: Già. Argv sub 1. JASON HIRSCHHORN: Sub 1? STUDENTE 18: Già. Argv parentesi aperta 1 - Sì. E poi virgola, e quindi aprire doppia citazione, r, doppia citazione, chiudi parentesi, punto e virgola. JASON HIRSCHHORN: Sweet. E per quanto riguarda l'altro? STUDENTE 18: Molto simile, ma invece di S-R-C, che ci chiama D-S-T. JASON HIRSCHHORN: Oo! Mi piace. STUDENTE 18: Just D-S-T. Già. E poi argv, parentesi aperta, 2. Già. E allora w invece di r. Già. JASON HIRSCHHORN: Great. Avanti paio di righe. Inoltre, se qualcuno ha cose da aggiungere linee che abbiamo fatto, sentiti libero di aggiungere anche quelli. Controllare per assicurarsi che nessuno dei due è NULL. Chi mi può dare il codice ho bisogno di soddisfare quella linea di pseudocodice? Archer. ARCHER: Se src uguale uguale NULL o dst uguale uguale NULL, allora si torna - JASON HIRSCHHORN: Cosa? ARCHER: Ritorno 2? JASON HIRSCHHORN: Ritorno 2. Quindi, se parentesi aperta src uguale è uguale a NULL, o - qualunque cosa thing's - pipa? Tubo? Ti chiamiamo tubo. Tubo, tubo, dst uguale uguale NULL, ritorno 2. OK? Fino a quando siamo fuori di byte - abbiamo una sorta di saltato su questo passaggio da la parte pseudocodice di andare a qui. Ma fino a quando siamo fuori di byte - cosa fa quel suono mi piace? Che tipo di struttura C - ma io non uso la struttura della parola, perché stiamo per iniziare a utilizzare che in altri casi - ma strumento C non vi sembra? STUDENTE 19: Un loop. JASON HIRSCHHORN: un loop. Suona come un loop. Allora, chi mi può dare la prima linea del codice ciclo proprio qui? È anche possibile scegliere il tipo di ciclo che vuoi, se mi dai questa riga di codice. Ci sono tre tipi. Si arriva a scegliere. Vorrei suggerire uno di quelli. Avi. Quale vuoi? AVI: PER. JASON HIRSCHHORN: PER. AVI: INT uguale a zero. JASON HIRSCHHORN: OK. AVI: Questa parte non sono sicuro circa. Ma i è minore dimensione di sorgente stella? Non sono sicuro di questo. JASON HIRSCHHORN: OK. AVI: Perché si desidera che il dimensione di un file, giusto? JASON HIRSCHHORN: Quindi questo probabilmente non lo farà diaci la dimensione del reale file in byte. Quindi, che cosa potevamo fare? Che è un altro tipo di ciclo? O dovremmo rimanere con il ciclo FOR? STUDENTE 20: Puoi fare un ciclo WHILE? E allora, che cosa faresti è you'd - perché abbiamo un char * per il file. Quindi, se dobbiamo solo continuare incremento che fino a quando avremmo trovato il carattere NULL a alla fine di esso? Oppure no, è che non è come funzionano i file? JASON HIRSCHHORN: Così possiamo continuare incrementare il char * fino a trovare la NULL - STUDENTE 20: Essenzialmente andare avanti carattere per carattere fino a quando ci ha colpito la fine del file. JASON HIRSCHHORN: sì. Ecco, questo è quello che vogliamo fare. Vogliamo continuare a leggere, carattere per carattere, fino ad arrivare a la fine del file. STUDENTE 20: Già. Find - qual è la fine o stop alla fine di un file di testo. JASON HIRSCHHORN: OK. Così, quando arriviamo alla fine del file - come facciamo a sapere che abbiamo raggiunto la fine di un file? Se sto chiamando - così facciamo un passo indietro. Che cos'è una funzione? Andiamo a questa linea qui. Leggere dal file di origine. Chi mi può dare quella riga di codice? STUDENTE 21: fscanf? JASON HIRSCHHORN: fscanf. OK. Cosa succede se voglio leggere, molto specificamente, un byte? STUDENTE 21: non lo so. JASON HIRSCHHORN: OK. Anche più semplice di fscanf - che è un - Voglio leggere da un file di origine? Leggere da un file di origine. Che cosa è una funzione - sì. STUDENTE 22: E 'fread? JASON HIRSCHHORN: Fread. Penso che cerchiamo di bastone con quella per ora. Che tipo di argomenti Non fread prende? STUDENTE 22: Probabilmente il tipo di file, e poi posizione nel file? JASON HIRSCHHORN: Cosa posso scrivere qui per capire che tipo di argomenti fread prende? STUDENTI PIÙ: Man fread. JASON HIRSCHHORN: Uomo fread e fwrite. Sembra che appendere fuori insieme. Così fread prende come molti argomenti? STUDENTE 23: Four. JASON HIRSCHHORN: Richiede quattro argomenti. Ci vuole un puntatore, una dimensione, e che cosa, che è strano, e qualche file. OK? Leggiamo a questo proposito proprio qui. "La funzione fread legge n memb elementi di dati, ogni formato byte lunga, dal flusso puntato da streaming, la loro memorizzazione nella posizione data dal pointer ". Così quattro argomenti. Perché non basta copiare questo, e incollarlo qui. OK. Allora, chi può iniziare la compilazione questi argomenti per me? Avi. AVI: Estrarre il vuoto. Mettere solo src. Estrarre puntatore e la stella. Mettere src. Poi - JASON HIRSCHHORN: Quindi ho intenzione di smettere lì, perché è errata. Hai ragione con src, ma dove dovrebbe src andare? [VOCI interponendo] JASON HIRSCHHORN: dovrebbe andate qui. Questo è il src - il nostro src è un tipo. Diamo un'occhiata qui. Questo sta chiedendo per un tipo FILE *, abbiamo in realtà di solito li vedi così. Quindi questo chiede un argomento di tipo FILE * chiamato ruscello che è src. OK? Quali sono le dimensioni delle cose fare vogliamo leggere? Ti ho dato questo in descrizione del problema. STUDENTE 24: Un byte alla volta. JASON HIRSCHHORN: Un byte. Quanto è grande un byte? La sua dimensione è in byte, così che cosa posso mettere proprio lì? STUDENTE 25: One. JASON HIRSCHHORN: One. Giusto. La sua dimensione è in unità di byte, così 1 è 1 byte. Quanti voglio leggere alla volta. STUDENTE 26: One? JASON HIRSCHHORN: una cosa. Voglio leggere una cosa di dimensioni 1, un morso alla volta. E dove lo metto, una volta che ho letto? STUDENTE 27: Destinazione? JASON HIRSCHHORN: Quindi non posso mettere dritto in meta. STUDENTE 28: Stai andando mettere in una terza puntatore? STUDENTE 27: Per la destinazione. JASON HIRSCHHORN: OK. Già. STUDENTE 29: È possibile dichiarare qualcosa agire come un deposito temporaneo prima. JASON HIRSCHHORN: OK. Dammi quello. STUDENTE 29: Un altro file puntatore, forse? JASON HIRSCHHORN: OK. Quindi questo è nulla star - è un tipo void stella, in modo che non deve essere un puntatore al file. E se sto leggendo un byte, dove sarebbe un buon posto memorizzare un byte? STUDENTE 29: Un array? JASON HIRSCHHORN: Un array. OK. E che altro è qualcosa che è basta dimensionare un byte? STUDENTE 30: un char *? STUDENTE 29: Già. JASON HIRSCHHORN: A char * non è un byte. STUDENTE 29: A char. JASON HIRSCHHORN: Un char è un byte. Giusto? Quindi chiamiamo questo buffer è un generico nome usato per queste cose da memorizzare qualcosa di temporaneo. Quindi creo un buffer. Giusto? Ma ci vuole un void *. Così forse hai ragione, che dovrebbe essere un buffer di dimensione 0. Così memorizza uno - destra. Perché questo proprio qui - char buffer è un personaggio, ma questo richiede un void * - un puntatore. Così ho potuto farlo e ora buffer è un puntatore. Che altro potevo fare? STUDENTE 31: Metti una stella accanto a char. JASON HIRSCHHORN: potevo hanno creato char *. OK. Cosa c'è un'altra cosa che potevo fare? O andiamo con questo. Char * tampone, così che cosa metto qui? STUDENTE 31: Buffer. JASON HIRSCHHORN: Buffer. Buffer è un puntatore ad un char. E in quella posizione, stiamo mettendo un byte di qualcosa che abbiamo letto. Già. Avi. AVI: Solo una domanda veloce. Vuoi malloc tampone? JASON HIRSCHHORN: Chi può rispondere a questa domanda? STUDENTE 32: Beh, non proprio punto a nulla adesso, quindi - JASON HIRSCHHORN: Ma fare vogliamo malloc esso? STUDENTE 32: Se si dovesse fare in modo che modo, credo, sì, perché avresti bisogno un posto per poter puntare a. JASON HIRSCHHORN: Dobbiamo devono malloc esso? STUDENTE 33: Se avete intenzione di usarlo all'esterno del ciclo. JASON HIRSCHHORN: Stiamo andando a usarlo all'esterno del ciclo? STUDENTE 34: sì. STUDENTE 35: Aspetta. Vogliamo dichiararla nel circuito di là? JASON HIRSCHHORN: Quindi penso che abbiamo Qualche tempo ciclo pseudo qui che siamo cercando di capire, che non abbiamo ancora ottenuto a. Non abbiamo bisogno di malloc esso. Stiamo operando in principale, è solo andare da utilizzare all'interno di questo ciclo. Non ha bisogno di esistere all'esterno di questo. Così può essere una variabile locale. Hai un puntatore a una variabile locale. STUDENTE 36: Ma non è che punta a nulla. JASON HIRSCHHORN: No, non è inizializzato a nulla. Ma noi non stiamo andando a usarlo anche. Stiamo per mettere qualcosa in è la prima volta che lo usano. Così che sembra OK. Quindi non abbiamo bisogno malloc qui. E credo che sia OK come è. OK. Abbiamo la linea fread. Facciamo la riga successiva. Se vogliamo scrivere in un file, quello che è una buona funzione da utilizzare per farlo? STUDENTE 37: fwrite? STUDENTE 38: fprintf? JASON HIRSCHHORN: fprintf è uno. Qual è un altro? STUDENTE 39: fwrite. JASON HIRSCHHORN: fwrite. E per i nostri scopi, fwrite, che abbiamo visto qui, è probabilmente la scelta migliore. Prende quattro argomenti pure. Nishant, si può dare me gli argomenti? Nishant: La prima di uno che va essere solo tampone. JASON HIRSCHHORN: OK. Nishant: Il secondo di solo andando a 1. Terzo sarà 1. E il quarto sta per essere dst. JASON HIRSCHHORN: Qualcuno ha domande su quella linea? Che sembra buono. OK. Così ora sembra che l'unica cosa che siamo mancante - in realtà, scriviamo quest'ultima linea. Chiudere i file. Chi ci può finire di scrittura queste ultime due righe? Sì. Siamo spiacenti, qual è il tuo nome? LUCY: Lucy. JASON HIRSCHHORN: Lucy. LUCY: src fclose e poi destinazione fclose. JASON HIRSCHHORN: fclose, parentesi aperta, src, chiudere parentesi, punto e virgola. E fclose - sì? LUCY: aperta parentesi, dst e poi virgola. JASON HIRSCHHORN: Great. E cosa dovrei includere alla fine? LUCY: di ritorno 0. JASON HIRSCHHORN: ritorno 0. Devo? Solo una domanda. Dobbiamo includere return 0? STUDENTI MULTIPLE: No. JASON HIRSCHHORN: No. Fa Principale automaticamente se si arriva alla fine. Ma penso che è bello includere esplicitamente. Soprattutto quando stiamo tornando altro cose tutto il programma. OK. Questo è ciò che ci manca - MENTRE cosa? Chi può pensare a qualche - ha qualche senso di ciò che le cose potrebbe andare in là? Anche se è solo in alcuni pseudocodice come il linguaggio? Ciò che siamo veramente - quello che vogliamo andare fino a quando? Sì, Lucy. LUCY: La fine del file. JASON HIRSCHHORN: La fine del file. Allora, cosa si intende per fine del file? LUCY: Una volta raggiunta la fine del file, stop. JASON HIRSCHHORN: OK. Quindi, una volta che si raggiunge la fine del file. Come facciamo a sapere quando abbiamo raggiunto la fine del file? STUDENTE 40: Penso tampone sarà impostato a NULL. STUDENTE 41: Buffer è dichiarata all'interno del ciclo. JASON HIRSCHHORN: Quindi pensi buffer verrà impostato su NULL. Perché sarebbe tampone essere impostato a NULL? STUDENTE 40: Perché quando si fread, si sta cercando di mettere nulla nel buffer. JASON HIRSCHHORN: OK. Quindi stai pensando fread - quando abbiamo raggiunto la fine della il file, cosa sta fread intenzione di fare? Penso che sia la domanda dobbiamo capire. Cosa fa fread fare? Ha messo NULL in tampone, o fa fare qualcos'altro? Come possiamo capire che cosa fa? STUDENTE 42: Man. JASON HIRSCHHORN: Uomo. Quindi diamo un'occhiata qui. Valore di ritorno. In caso di successo, fread e fwrite restituire l' numero di articoli letti o scritti. Questo numero è uguale al numero di byte trasferiti solo quando la dimensione è 1. Se si verifica un errore, o alla fine del file viene raggiunto, il valore di ritorno è un breve count articolo o 0. Quindi, per i nostri scopi, se raggiunge fread la fine del file, e legge dalla la fine del file, non c'è niente di sinistra leggere, che cosa sta andando a tornare? STUDENTE 43: Zero? JASON HIRSCHHORN: Cosa? STUDENTE 43: Zero? JASON HIRSCHHORN: Zero. E 'intenzione di restituire zero. Così sappiamo che fread, quando abbiamo raggiunta la fine del file, sta per tornare a zero. Come possiamo usare a nostro vantaggio? AVI: È possibile dichiarare una variabile esterna del ciclo denominato controllo. Se la verifica è uguale - per ora - uno. JASON HIRSCHHORN: OK. AVI: E poi si può mettere un IF dichiarazione subito dopo fread dicendo che se fread uguale a zero - n. JASON HIRSCHHORN: Chi può aiutare Avi fuori? AVI: Qual è il valore restituito da fread? JASON HIRSCHHORN: Abbiamo appena andato oltre quello. AVI: Come si fa a rappresentare questo? JASON HIRSCHHORN: Quindi torna - LET'S cercare qui - restituisce un size_t, che è essenzialmente un numero intero. Quindi restituisce un numero intero. E nel nostro caso, sarà ritorno 1 o 0 - 1 se leggi una cosa - un byte, e 0 se abbiamo raggiunto la fine. Quindi, se fread - sì? STUDENTE 45: non puoi semplicemente mettere il pieno fread (buffer, 1, 1, src) nella ciclo while? JASON HIRSCHHORN: Allora proponete facendo questo in là? [VOCI interponendo] JASON HIRSCHHORN: Aspetta. Quindi stiamo liberare di questo. Quindi stai proponendo di mettere fread in là? Che cosa dovremmo anche muoversi se si vuole fare questo? STUDENTE 45: Il buffer esterno. JASON HIRSCHHORN: Dovremmo anche spostare questa qui. STUDENTE 45: Ma fa che costantemente spostarlo in avanti? [VOCI interponendo] JASON HIRSCHHORN: OK. Quindi questo è ciò che propone Okshar. Creiamo il nostro buffer. Noi MENTRE fread, poi abbiamo fwrite. Pensieri su questo? STUDENTE 46: La mia unica domanda è, sarebbe in realtà eseguire il comando fread? JASON HIRSCHHORN: Ottima domanda. Quando avete deciso di mettere una chiamata di funzione all'interno di una condizione, che fa chiamata di funzione execute? Abbiamo visto esempi di questo prima. Giusto? STUDENTE 46: OK. Già. Così lo fa eseguire. JASON HIRSCHHORN: Abbiamo visto cose come prima, dove abbiamo un chiamata di funzione all'interno di una condizione. Ritiene che la chiamata di funzione esegue? Sì. Quindi la risposta è sì. Questa chiamata di funzione verrà eseguita. Ma ancora una volta, è quello che vogliamo? Qual è un modo siamo riusciti a capire se è quello che vogliamo? STUDENTI PIÙ: Run It? JASON HIRSCHHORN: Potremmo farlo funzionare. Ma prima di farlo, potremmo ragionare anche attraverso questo. Se - dire che abbiamo un byte nella nostra FILE, ci arriveremo qui, ci arriveremo a questo codice. Questo verrà eseguito. fread restituisce un byte e memorizzare nel buffer. E questo restituirà 1, a destra, dopo aver restituisce 1. Così, mentre 1. Questo significa che il codice all'interno il ciclo WHILE viene eseguito? STUDENTE 47: Già. E 'vero. JASON HIRSCHHORN: sì. 1 è vero. Non è 0. Quindi il codice qui dentro verrà eseguito. Quindi noi scriveremo che. Ci spostiamo di nuovo a questo linea ancora una volta. Ora abbiamo - siamo alla fine del nostro file. Leggiamo dalla fine del nostro file, perché avevamo un solo byte in esso. Fread restituisce 0, negozi qualcosa in tampone. Onestamente non so cosa memorizza nel buffer. Potremmo probabilmente guardare in alto per vedere cosa fa. Che onestamente non lo so. Non sappiamo, chi se ne frega cosa memorizza in tampone? Ma non ritorno 0. E sarà mentre 0 execute? MENTRE 0 non verrà eseguito. Allora ci sposteremo qui. Quindi cerchiamo di ottenere per alzata di mano, se questo è il codice che dovremmo correre, o se ci dovrebbe fare le modifiche. Quindi, se si pensa - si deve votare. Se pensi che dovremmo eseguire questo codice come è, per favore alzi la mano. OK. Ce n'è uno - hai una domanda, preoccupazione? Già. STUDENTE 48: Dopo ci spostiamo tampone al di fuori del ciclo, facciamo devono malloc esso? JASON HIRSCHHORN: Ottima domanda. Dopo ci spostiamo tamponare al di fuori del loop, abbiamo di malloc esso? Questa è una domanda ambito. Se si inizializza il buffer esterno di questo ciclo, sarà esisterà all'interno del ciclo? STUDENTI PIÙ: sì. JASON HIRSCHHORN: sì. Il suo campo di applicazione copre all'interno del ciclo, e, in realtà, nulla di sotto di essa all'interno di questo codice, compresa la le cose qui dentro. Quindi non abbiamo bisogno di malloc esso. E 'una variabile locale, e la sua portata comprende ancora il ciclo. STUDENTE 49: Abbiamo bisogno di liberarlo? JASON HIRSCHHORN: Dobbiamo bisogno di buffer libero? STUDENTE 49: Sì, se non lo facciamo malloc. JASON HIRSCHHORN: Dobbiamo bisogno di buffer libero? Noi non lo facciamo. Di nuovo, è una variabile locale, quindi non abbiamo bisogno di liberarlo. OK. Vediamo cosa succede. Così è inizializzata. Questo è ciò che una cosa che Marcus ha proposto in precedenza. Così abbiamo che l'errore, tampone variabile non è inizializzata quando viene utilizzato qui. Come possiamo risolvere questo problema? STUDENTE 50: malloc è? STUDENTE 51: Equals NULL? STUDENTE 52: Say tampone è uguale a NULL. JASON HIRSCHHORN: OK. Sembra buono. Abbiamo ora. Creiamo qualcosa da provare a copiare. Quindi abbiamo il nostro file di testo. Come possiamo eseguire questo programma? Già. STUDENTE 53: È possibile fare punti tagliare cp, test.txt. E poi si può nominare un altro file che si memorizza in. JASON HIRSCHHORN: OK. Ti chiamiamo out.txt. Cool? Guasto Seg. Pensieri sulla guasto seg? Questo è grande. Come possiamo scoprire dove la colpa è seg? Cosa? STUDENTE 54: Gdb. JASON HIRSCHHORN: Gdb. Corriamo gdb scrivendo gdb dot barra, il nome del nostro programma. Nessun argomento della riga di comando lì. Stiamo andando a impostare un punto di interruzione alla principale. Se voglio iniziare gdb, cosa faccio? STUDENTE 55: R. JASON HIRSCHHORN: R. E poi cosa? STUDENTE 55: Gli argomenti? JASON HIRSCHHORN: Poi l' argomenti della riga di comando. Camminiamo attraverso. N è solo prendendo me riga per riga. Ho intenzione di andare fino Ottengo colpa mia seg. Non c'è colpa mia seg. Sembra fread causato colpa mia seg. So fread ha causato la mia colpa seg, perché quello era il linea che abbiamo appena eseguito. E l'unica cosa che era accadendo in quella linea - due cose stavano accadendo. Fread stava andando, e poi siamo stati facendo qualche controllo WHILE. Sono pronto a scommettere che il WHILE controllo non stava causando colpa mia seg. Molto probabilmente, era fread causando colpa mia seg. Vedo anche qualcosa qui, memcopy. Copia in memoria. Suona come muoversi memoria dalla una posizione all'altra. Suona come qualcosa che potrebbe accadere in fread, magari un po 'di memoria muoversi da qui a qui. Andiamo con questo nuovo. Come faccio a iniziare sopra ed eseguirlo di nuovo? Già. STUDENTE 56: Avete bisogno di mettere una commerciale prima che il buffer? JASON HIRSCHHORN: Quindi Ampersand prima tampone mi avrebbe dato l'indirizzo del tampone, che è un char *. Corriamo attraverso questo ancora una volta. Come faccio a eseguire attraverso di essa ancora una volta? STUDENTE 57: si può solo digitare nuovamente Run? JASON HIRSCHHORN: Basta digitare nuovamente esecuzione. Quindi non stiamo andando a eseguire questa linea. Quindi buffer è un puntatore NULL. Correggere? Si sta puntando - vediamo. Se abbiamo il nostro - tracciare un rapido quadro di questo. Chiunque può vedere se Scrivo qui? Così nello stack, abbiamo un locale variabile e si chiama tampone e è un puntatore a char. Che indirizzo è questo char a? STUDENTE 58: 0x0. JASON HIRSCHHORN: Giusto. Ecco di cosa si tratta. In qui, all'interno del buffer, viene memorizzato 0x0. Questo è quello che abbiamo - l' Impostazione abbiamo in questo momento. Così questa linea, fread, mette qualcosa dalla sorgente dove? In questa casella o questa scatola? Quale scatola? Box o box di destra e sinistra? Questa casella a destra. Ne consegue il puntatore, e lo mette in qui. Quando cerchiamo di memoria di tocco a posizione 0, cosa otteniamo? Un errore di segmentazione. Questo è l'errore che abbiamo adesso. Già. STUDENTE 59: Non avete mettere tampone stella? O no? Per fread? JASON HIRSCHHORN: Così fread prende un puntatore. Quindi passa in tampone. E allora sarà de-riferimento da qualche parte dentro fread. Ma ancora una volta, abbiamo visto, ci vuole un puntatore. Non abbiamo bisogno di passare buffer di stelle. Ciò sarebbe passato è tutto ciò che è qui. E che probabilmente ci darà un errore perché stiamo de-riferimento di esso. Giusto? Quando abbiamo de-riferimento questo puntatore, quando proviamo ad accedere a questa posizione, stiamo ottenendo un errore - il nostro segmentation fault. So - oops. Stiamo per uscire da gdb. La nostra linea - il nostro problema - è giusto qui su questa linea. Ed è un problema perché di questa linea. Come possiamo creare una casella che è accessibile in fread. Giusto? Abbiamo bisogno di creare una casella che è uno byte grande, la dimensione di un char. Ma abbiamo bisogno che il dialogo sia accessibile quando questa funzione viene eseguita. Allora, dove - sì. Tutte le idee? STUDENTE 60: Basta impostare come qualsiasi carattere casuale. Basta fare equals char buffer il carattere. E poi, quando hai tampone lì - JASON HIRSCHHORN: Aspetta. Char tampone? Quindi nessuna stella? STUDENTE 60: Già. Estrarre la stella. Uguale un carattere casuale. JASON HIRSCHHORN: OK. Allora dammi uno. STUDENTE 60: Come una o qualcosa del genere. E poi quando hai tampone lì, si utilizza un - STUDENTE 61: Star? Oh no, la commerciale. STUDENTE 60: Utilizzare la e commerciale. JASON HIRSCHHORN: OK. E per quanto riguarda in fwrite? STUDENTE 60: Utilizzare nuovamente la commerciale. JASON HIRSCHHORN: Va bene. Quindi la tua idea è, creiamo un char e mettere qualcosa in esso, e quindi scrivere in quella char. STUDENTE 60: Già. JASON HIRSCHHORN: Cosa pensa la gente? STUDENTE 62: E 'contorta. JASON HIRSCHHORN: OK. Facciamo disegnare fuori. Così questa volta, ho intenzione di disegnare questo rosso in pila qui, e poi avrà - ooh! Scusi. Così questa volta abbiamo qualcosa chiamato tampone, ed è in pila. Correggere? E stiamo risparmiando in una, inizialmente. Poi abbiamo la nostra chiamata a fread. Che fread fa è ci vuole un byte da il nostro file e lo mette da qualche parte. Essa mette in qualunque cosa sta indicando. Bene, prima abbiamo avuto questo indirizzo - 0x0. Ora, quale indirizzo abbiamo? STUDENTE 63: Qualunque buffer di indirizzo è. JASON HIRSCHHORN: Qualunque buffer di indirizzo è. E 'probabilmente sarà qualcosa di simile. Probabilmente intenzione di iniziare con un b and Un F, e quindi avere altri sei cifre esadecimali. Non importa. Qualche indirizzo. E stiamo passando questo indirizzo trovi E stiamo andando a mettere il nostro unico cosa byte a tale indirizzo. Quindi stiamo andando a mettere il nostro unico cosa byte qui dentro. E poi andremo a scrivere dalla che cosa è mai qui dentro. Qualcuno ha domande a tale proposito? Chi pensa questo codice funzionerà? Alzi la mano se si pensa questo codice funzionerà. Dovete prendere una posizione. E chi pensa che questo codice non funziona? Alzi la mano. Tutti gli altri dovrebbero essere alzare la mano. OK. Michael, dove stai in piedi? MICHAEL: Non posso decidere. Tipo di nel mezzo. JASON HIRSCHHORN: Sei nel mezzo. Scegli uno. MICHAEL: Io ho fede e dire che funzionerà. JASON HIRSCHHORN: OK. Avrete fede e dire che funziona? Che cosa è successo? [VOCI interponendo] JASON HIRSCHHORN: Nessun guasto seg. Come possiamo controllare per vedere se due cose sono uguali? Due file sono uguali. STUDENTE 64: Diff. JASON HIRSCHHORN: Diff. Controlli diff per le differenze tra due file, e se restituisce niente, sono identici. E se ci apriamo, otteniamo il nostro file. Così che era la soluzione corretta. Guardiamo indietro ancora una volta. Noi in realtà non ha nemmeno necessario inizializzare. Sarebbe probabilmente cercare un po ' pulito se non hai messo qualcosa di casuale in là. Il punto è, avete bisogno di creare po 'di spazio per memorizzare qualcosa da fread e prendere qualcosa di fwrite. E che cosa doveva essere un locale variabile sullo stack - si potrebbe aver malloc'd po 'di spazio. Così abbiamo effettivamente potuto malloc scritto qui, e che avrebbe funzionato. E poi ci sarebbe stato memorizzando le nostre cose da qualche parte sul mucchio. Ma questo è in realtà, probabilmente, la soluzione più elegante. Basta creare un pò di spazio sullo stack per queste cose vadano. Avrei altre due osservazioni. Se si dovesse prendere in giro questo, e poi vengono segnati su questo, i miei commenti sarebbe come segue. Questi 1 è qui, per me, guardare come numeri magici. Questo 1, in termini di fread, senso. Questo è il numero di cose per leggere o scrivere. Ma questo qui dovrebbe probabilmente qualcos'altro. Allora, qual è una soluzione? STUDENTE 65: Formato di byte. JASON HIRSCHHORN: Ti piace questo? STUDENTE 65: Formato di char. JASON HIRSCHHORN: Formato di char. Sì, byte non è un tipo. Così dimensioni delle opere char. Potremmo avere, in cima nostro codice, # definito che. Chiamato qualcosa BYTE e è davvero un char. In realtà, un approccio ancora migliore avrebbe potuto essere questa - uint. Qualcuno sa di cosa si tratta? Scusi. Ho all'indietro. Aspetta, no. Da che parte va? Qualcuno sa di cosa si tratta? Già. STUDENTE 67: Dovrebbe aiutare a standardizzare attraverso sistemi di cose che hanno - come numeri interi senza segno che hanno 8 byte? JASON HIRSCHHORN: Ecco esattamente a destra. Su macchine diverse, la dimensione di un char - di solito non un char. Caratteri sono di solito un byte. Ma le dimensioni di altri tipi di dati sono diverse dimensioni su una macchina a 32-bit contro una macchina a 64 bit. Un uint8_t è sempre 8 bit - sempre un byte. E ho bisogno di includere tale int file di intestazione standard. Così ora, questo sarebbe stato probabilmente il modo migliore per scrivere questo codice. Così mi libero dei numeri magici. E ho anche un più logico tipo di buffer. Non è semplicemente un char è un byte, che è quello che ci aspettiamo che sia. E qui, abbiamo effettivamente essere un po 'più robusto. Non stiamo definendolo un char, che - forse, chissà - potrebbe essere un diverso Dimensioni su macchine diverse. Noi stiamo in realtà dicendo che questo è esattamente un byte, da sempre, non importa cosa. E se guardiamo qui, facciamo cp. Uh-oh. Che cosa è successo? STUDENTE 68: Potrebbe essere acceso. JASON HIRSCHHORN: Cosa? STUDENTE 69: è vero? STUDENTE 70: Non l'hai fatto definirlo come un tipo. STUDENTE 71: Ma dovrebbe essere definito nella norma. STUDENTE 72: Che cosa sta succedendo? STUDENTE 73: Dovrebbe definire essere tutto maiuscolo? JASON HIRSCHHORN: Quindi non è # define. In realtà, in questo caso, sono intenzione di utilizzare typedef. Poiché stiamo usando come un tipo in una posizione. Quindi, in questo caso, vogliamo davvero typedef che stiamo stampa di un nuovo tipo di byte, ed è, in sostanza, questa. E 'un po' diverso rispetto # define. E ora, il nostro codice funziona perfettamente. Così, ancora una volta, # define prende qualcosa, sostituisce ovunque con l'altra cosa. E 'solo un macro - stenografia per sbarazzarsi di numeri magici. Ma in questo caso, perché siamo usarlo come un tipo - proprio qui - al fine di conseguire tale obiettivo, abbiamo bisogno di a typedef qualunque byte è. E stiamo definendo proprio qui. Non è una struct, in realtà è solo un numero intero senza segno. E 'lunga un byte. Questo codice sarà disponibile on-line, e tutti voi dovreste avere adesso. Così abbiamo - perfetto - 13 minuti lasciati andare problema su set 5. Voglio camminare attraverso copy.c insieme, e poi parleremo brevemente sulle altre parti del problema posto. Così mi permetta di tirare su copy.c. E la cosa interessante è che abbiamo effettivamente già scritto un sacco di codice. Il codice che abbiamo scritto letteralmente appena è venuto fuori di qui quando ero scrivendo questo per conto mio. Ma questo è copy.c, costituisce il fondamento per le prime due parti il problema impostato per whodunit.c, che è necessario scrivere, e resize.c. Recover.c, che è la terza e ultima parte del problema proposto, non è in base al largo di questo file. Stai andando ad avere bisogno di scrivere quel file, vi diamo un modello per tale il file, ma non ha nulla a che fare con copy.c. Ma perché copy.c è il fondamento per le prime due parti, stiamo andando a piedi attraverso di essa ora, in modo da avere un buon senso di ciò che fa. E le osservazioni danno alcuni lontano. Abbiamo già scritto una parte di questo. In primo luogo, stiamo facendo in modo otteniamo tre argomenti. Quindi, stiamo ricordando il nome del file. Così abbiamo saltato questo passaggio quando abbiamo scritto la nostra cosa - quando il nostro cp. Ma qui, stanno facendo un po 'più pulito. Stanno controllo per assicurarsi che entrambi i file sono buoni, in Oltre alla loro apertura. Abbiamo scritto tutto questo codice solo ora, quindi sono non andare a soffermarsi su questo codice. Successivo è certo roba che è specifico per i tipi di file che stiamo usando, che sono file bitmap. File bitmap hanno alcuni metadati essi associati. Quindi, la prima coppia di byte raccontarvi il file. Non sono i colori dei il pixel in quella immagine. Ti dicono sul file. E se leggete attraverso il problema insieme, avrete molte più informazioni su quali tipi di strutture di metadati sono inclusi con le bitmap. Ma è per questo che abbiamo questo primo set di - questo codice proprio qui. Stiamo leggendo i metadati - due pezzi di metadata - il fascicolo intestazione e le informazioni nell'intestazione. E stiamo verificando alcune parti di esso a assicurarsi che sia un file bitmap vero prima di continuare. E ancora, questi sono dettagli che non c'è bisogno di andare in ora. Se leggete attraverso il problema insieme, capirai questi. Per farla breve, questi sono solo dicendo, questo è un file bitmap, e confermando che. Quindi, stiamo scrivendo quelle al file fuori. Vediamo che qui. Stiamo scrivendo al puntatore fuori. Quindi, stiamo determinando imbottitura. Quindi, di nuovo, come è particolarità con un file bitmap, alcune linee comprendono imbottitura alla fine. E se leggete attraverso il problema insieme, per conoscere di più su imbottitura. Questa è la formula per trovare imbottitura. Importante da ricordare - quando si modificano le dimensioni di una bitmap il file, le modifiche imbottitura. Quando si modificano le dimensioni di un il file, le modifiche imbottitura. Non è mai sarà maggiore di 3 - sarà da 0 a 3, compreso. Ma quando si modifica la dimensione del qualcosa, le modifiche imbottitura. Se ho solo un pixel in quella riga, io bisogno di tre byte di padding, perché ogni riga deve essere multipli di quattro byte a lungo in un file bitmap. Ma se faccio doppio che, per andare da un pixel di due pixel, ciascuno dei quali, diciamo, è un byte, quindi ho bisogno due byte di padding per fare che uguale a quattro. Così, quando cambio la dimensione di qualcosa, Ho bisogno di modificare la quantità di imbottitura che ho. Questo fa senso per tutti? Successivamente, abbiamo iterare su ogni riga, o attraverso tutte le righe. E poi iteriamo ogni colonna di ogni riga. Stiamo trattando questa bitmap come una griglia, come abbiamo trattato la scheda in 15. Come abbiamo trattato i mattoni quando li abbiamo stampato sullo schermo. Una griglia di righe e colonne. Poi - abbiamo visto questo. In realtà abbiamo appena codificato questo. Abbiamo creato qualche deposito temporaneo. Leggiamo in là, e poi scriviamo fuori. Questo è esattamente quello che abbiamo appena fatto. Poi, perché ho detto ogni linea finisce in qualche imbottitura, abbiamo saltare quella imbottitura - il vecchio imbottitura. E poi ci aggiungiamo indietro. In questo caso, stiamo creando lo stesso file esatto. Stiamo solo copiarlo. Quindi questa linea è una specie di sciocco. Potremmo letteralmente appena mettere l'imbottitura dentro Ma se si modifica la dimensione del file, Vuoi ancora questa linea? Quindi, se cambiamo la dimensione di un file, Non abbiamo ancora voglia di saltare sopra la vecchia imbottitura? STUDENTE 74: sì. JASON HIRSCHHORN: Così facciamo. Perché questo, ancora una volta, offerte con il file di origine. Non ci preoccupiamo per l'imbottitura dal file di origine. Vogliamo passare alla riga successiva. Ma non basta mettere indietro la vecchia quantità di imbottitura. Abbiamo bisogno di mettere indietro l' nuovo importo di imbottitura. Così, quando stiamo cambiando la dimensione di un dei file, abbiamo ancora voglia di saltare il imbottitura nel vecchio file - cosa stiamo leggendo in da. Ma quello che stiamo scrivendo a, stiamo andando per necessità di rimettere un po 'diverso Numero di riempimento che abbiamo determinato. Già. STUDENTE 75: L'ordine di questi due le linee non importa, giusto? Perché stai movimentazione diversi file. JASON HIRSCHHORN: Esattamente. L'ordine di queste due linee non importa. Scriviamo questa linea. Questo è qui per il file stiamo scrivendo a. Questo è importante, in modo da ottenere la giusta quantità di imbottitura. Questo ha a che fare con il file in. Vogliamo passare direttamente sopra l'imbottitura. Non vogliamo leggere - se stiamo leggendo un byte alla volta, non si preoccupano di quei byte di riempimento. Vogliamo passare alla riga successiva. Infine, proprio come Lucy ha dato per noi, chiudiamo i file e torniamo 0. Quindi questo è copy.c. E abbiamo effettivamente scritto - abbiamo trascorso la maggior parte sezione di scrivere questo, in sostanza. Hai fatto questo. Quindi spero di avere un buon senso di quello che sta succedendo qui. La grande differenza, onestamente, è solo questa prima parte che si occupa di peculiarità di file bitmap. Così ho la mia diapositiva successiva, che cosa dobbiamo fare? Beh, pensiamo giallo. E per qualcuno che lesse il problema set, cosa facciamo bisogno di fare in giallo? Semplicemente. Aleja. ALEJA: Riesci a prendere la parte di ogni pixel che denota rosso. E poi - tipo? JASON HIRSCHHORN: OK. Quindi prendere la parte di ogni pixel che denota rosso. Che è vicino, ma non tutto. STUDENTE 76: Beh, c'è diversi modi per farlo. JASON HIRSCHHORN: OK. Dammi un modo. STUDENTE 76: Estrarre tutto il rosso, e poi sottolineare il blu e il verde. JASON HIRSCHHORN: OK. Quindi, dato entrambi i modi - suona come diamo un pixel, ha un livello di rosso, blu e verde. Vogliamo cambiare i relativi livelli di il rosso, blu e verde, a seconda su quel pixel. Se in questo codice dovremmo cambiare la relativa rosso, blu e verde livelli di un dato pixel. Dopo che abbiamo letto è - prima che noi scriviamo? Dammi il numero di riga. STUDENTI PIÙ: 83. JASON HIRSCHHORN: 83. Quindi, proprio qui. Per il giallo, il codice è necessario scrittura dovrebbe andare tutti lì. E questo è l'unico codice è necessario scrivere. Perché, come abbiamo sentito, tutto è necessario fare è cambiare queste relativa blu, i livelli di rosso e verdi da ogni pixel. Avete letto in, e ora sei intenzione di scrivere fuori. Come faccio a ottenere - se ho questa cosa chiamato tripla, proprio qui, ed è di tipo RGBTRIPLE - bene, se abbiamo guardato in bmp.h, ciò è RGBTRIPLE? STUDENTE 77: E 'una struct. JASON HIRSCHHORN: RGBTRIPLE è una struct. Vediamo che proprio qui. E così, se volevo accedere, ad esempio, il Livello rosso della struttura, come faccio accedere al livello rosso di questa struttura? [CLASS mormora] STUDENTE 78: RGBTRIPLE.rgbtred? JASON HIRSCHHORN: E 'esatto? STUDENTE 79: Dovrebbe essere triplo dot, invece di RGBTRIPLE dot? JASON HIRSCHHORN: Triple. Triple è la variabile locale, quindi Qui, non ci sono puntatori qui. Così abbiamo appena usato la notazione del punto. Questo mi darà il livello di rosso. Se voglio cambiare, ho appena impostato uguale a qualcosa di diverso. Quindi, di nuovo, questa riga di codice accessi questa variabile all'interno di questa struttura, e possiamo impostare a qualcosa di nuovo. Così per giallo, ancora una volta, questo è, in sostanza, quello che dobbiamo fare. Molto semplice. Basta cambiare alcuni livelli relativi, e è qui che il codice va. Ridimensionare, d'altra parte, è un po 'più complicato. In realtà, il ridimensionamento è probabilmente l' parte più difficile di questo problema set. Abbiamo tre minuti per andare su di esso. Ma ancora una volta, abbiamo già scritto la maggior parte di questo codice, in modo da dovrebbe essere abbastanza familiare. Quali sono alcune cose che vogliamo fare in ridimensionare, se avete letto sopra il set problema? Se li dai a me, si può parlare di loro. Quali sono alcune cose che vogliamo fare? STUDENTE 80: verticale - quindi bisogna orizzontale ridimensionarlo, ma verticalmente ridimensionarla come bene? JASON HIRSCHHORN: Quindi se stiamo dato una pixel, e vogliamo ridimensionarlo da un fattore due, la guida deve essere ridimensionata orizzontalmente e ridimensionato verticalmente. Ritiene che senso? Già. Ecco, questo è probabilmente il sfida più grande. E noi parleremo in un secondo. Già. STUDENTE 81: Il modo in cui ho pensato che era il necessario stampare fuori - JASON HIRSCHHORN: Aspetta. Non dirci che cosa hai fatto. Stiamo per parlare di logica. STUDENTE 81: OK. Qual era la domanda? JASON HIRSCHHORN: Hai appena alzato la mano. Non c'era alcun dubbio. Fammi presento. Vorrei solo discutere brevemente. Così abbiamo un pixel, vogliamo replicare, sia in orizzontale che verticalmente. Quindi idealmente quello che facciamo qui è, si leggere nella nostra pixel, lo scriviamo tuttavia molti di volte. Ma poi abbiamo il nostro trucco, perché poi vogliamo passare al riga successiva e scrivere al inizio della riga successiva. Quindi, se vogliamo replicare sia orizzontalmente e verticalmente, ciò che è un buon modo per farlo - uno buono, anche se per farlo? Quindi non abbiamo bisogno di cercare costantemente intorno al nostro file per mettere le cose. Tale questione potrebbe non avere aveva un senso, ma penso che un rispondere ad esso sarà di aiuto. STUDENTE 82: Creare un array? JASON HIRSCHHORN: Quindi cerchiamo di pensare di ogni file come una riga. Pensiamo in termini di righe. Se abbiamo la nostra prima fila dal nostro piccolo foto, possiamo fare la riga in un grande riga da una grande immagine, e quindi replicare quella riga però molte volte ha bisogno di essere replicati, piuttosto che andare pixel per pixel, che ottiene confusa quando la gestione dei file. Perché se avessimo - Sono a corto di spazio. Se questo è il nostro file, e abbiamo che un pixel lì, e vogliamo metterlo proprio lì, abbiamo ancora alcune cose che hanno bisogno di andare lì quando siamo scrivere e creare il nostro nuovo file - il nostro file che è due volte più grande. Ma è davvero difficile con funzioni di file per saltare intorno per nuove linee così, e poi tornare qui e mettere le cose in là. E 'quasi impossibile fare qualcosa che, se questo ha un senso. Quindi, se pensiamo in termini di righe, possiamo prendere la nostra fila, e poi metterlo - replicare le righe in verticale. Ed è così che abbiamo a che fare con il ridimensionamento verticale anziché in orizzontale. Quella era una sorta di rapida e un po 'di confusione. Purtroppo il nostro tempo è scaduto. Io starò fuori per quelli di voi qui che hanno domande circa la set problema, compresi recuperare. Quindi cerchiamo di rinviare per ora. E ancora, se avete domande, possiamo chiacchierare fuori.