JASON HIRSCHHORN: Velkommen, alle, til Uge 6. Jeg er glad for at se jer alle i live og godt efter Quiz 0, fordi jeg ved, at var en smule ru. Men heldigvis, jer alle gjorde utroligt godt. Og så er vidunderligt. Hvis du er i min afdeling, jeg har givet de fleste af du sikkerhedskopiere dine quizzer allerede. Et par af jer, jeg møde efter klasse. Og hvis du er en udvidelse studerende og du ikke har modtaget din quiz tilbage endnu, er din TF sandsynligvis arbejder på det og klassificering det, og vil få det tilbage til dig snarest. Så min forlængerledninger studerende, der er ser lige nu - forhåbentlig leve - Jeg vil få dine quizzer kort så godt. Vores dagsorden for i dag er som følger. Først, vi kommer til at gå over nogle ressourcer, CS50 leverer til dig. Vi kommer til at gå over Quiz 0 næste, og Jeg vil besvare eventuelle spørgsmål nogen har omkring særlige problemer. Og så vil vi være at gå over fil I / O og problemet sæt 5. Disse sidste to emner vil tage hovedparten af ​​afsnittet i dag. Jeg sætter denne liste op hver uge som en påmindelse til jer alle, men af ​​kerne sektion, har vi kun 90 minutter - vi er ikke i stand til at dække alt, hvad jeg ville elske at dække for jer. Men vi har et væld af ressourcer til du at trække på, som du kommer til at kende materiale og arbejde gennem dit problem sætter. En påmindelse om, at jeg har online en tekst kasse, sat op for dig at udfylde, hvis du har feedback til mig, både positive og konstruktiv, om sektion. Denne URL ligger lige hernede. Så venligst, tage et øjeblik, hvis du har nogen feedback, uanset under afsnittet eller efter, eller efter at du se videoen online, til at give mig din feedback. Jeg virkelig sætter pris på enhver og alle af det. Så jeg har haft små samtaler med en masse af min studerende i hele ugen - som jeg hånd back quizzer, taler om selvfølgelig, at se, hvordan du gør. Og ét tema er kommet op igen og ovre i at tale om - i særdeleshed - problem sæt. Og jeg har indkapslet dette tema på brættet lige nu. Væsentlige, der er en forskel mellem drejning i noget, der er udført korrekt og noget der er gjort godt. De fleste mennesker har gjort fantastisk i form af korrekthed - 5 s eller 4 s på alle psets. De fleste mennesker bliver dem hele tiden. Men bare fordi du har gjort noget rigtigt betyder ikke, du har gjort noget så elegant, eller effektivt, eller så rent som du kunne have gjort det. Og det er, hvad design - og i mindre grad, stil - akser er til for. Så jeg presser dig alt, og andre TFs presser jer, ikke kun drejning i ting, der er korrekt, men slå i de ting, der er kodet godt. Ikke at gøre unødvendig efter sløjfer, ikke genberegne variabler hvis du behøver ikke at. For eksempel, ser tilbage til problem sæt 4, når du placerer mursten på skærmen, hver række - hver mursten i en given række har samme y-koordinat - samme højde koordinat. Således at y-koordinat ikke behøver at beregnes i det indre indlejret FOR løkke, som du sandsynligvis brugt at sætte disse klodser på skærmen. Det skal kun beregnes hvert gang, du tændte en række, eller flyttet ned træk. Så sige, hvis der er 10 klodser i en træk, kan hver sten har samme y-koordinat, og at y-koordinat kan bare blive beregnet én gang for alle af disse. Det behøver ikke at beregne 10 tider, og heller ikke denne beregning behov ske i den faktiske funktion opkald - det nye gracked funktion opkald. Så hvis der var lidt forvirrende for dig, mere generisk, ting, der behøver ikke at ske hver eneste gang du går gennem en for-løkke, bør ikke være sætte inde for-løkken, og bør ikke ske, hver gang du går gennem for-løkken. Et andet godt design eksempel oplevede vi i uge 3 for 15, kan du holde styr på nul. Så når du initialiserer bord, du spare - i en global variabel, måske - x-og y-koordinat af nul. Og så når du - i dit træk-funktion, når du foretager en vellykket træk, du opdaterer placering af nul. Det ville spare dig fra at skulle gøre indlejret efter sløjfer til at se gennem bord hver gang i din flytte funktionen og finde nul, eller finde fliser, og derefter kontrollere, hvad der er ved siden af. I stedet har du placeringen af nul, kan du bare kigge over, under, og til venstre og højre for den, for at finde den flise, du søgte efter. Så med hensyn til de programmer, vi er skrive, de er aldrig store nok at nogle af disse design beslutninger er virkelig kommer til at hæmme din program, eller gøre det køre langsommere, eller måske endda løbe tør for hukommelse. Men vi er stadig skubber jer at skrive så elegant og effektiv kode som muligt. Så hvis du ender med at skrive tingene der har en væsentlig større anvendelsesområdet, vil de blive skrevet med god designe ud over at være korrekt. Så en række af jer har bragt ud af det. Det er noget, vi leder efter - noget vi kommer til at fortsætte med at skubbe dig fyre på. Hvis du nogensinde har spørgsmål om den design af dit program, er du velkommen at nå ud til mig, og jeg er glad for at gå gennem dit program med dig, og pege på nogle af udformningen beslutninger, du har foretaget, og giver dig nogle forslag til, hvordan man kan gøre selv bedre design beslutninger. Så vi kommer til at bevæge sig på til at tale om Quiz 0. Før vi gør det, gør nogen har spørgsmål om, hvad Jeg har dækket hidtil? [Raslende lyd] JASON HIRSCHHORN: Syv sekunder. OK. Lad os tale om Quiz 0 for lidt. De fleste af jer har din Quiz 0 ryg. Hvis du ikke gør det, forhåbentlig du husker det en smule. Men hvis du har taget Quiz 0, så du også have adgang til PDF-online testopløsningen. Er der nogen har nogen spørgsmål, før vi springer ind i ugens materiale om et særligt problem på Quiz 0 - hvorfor svaret er, hvad det er? Er der nogen forvirret over noget? Selv hvis du fik problemet ret, men bare gerne vil have mig til at forklare det lidt mere, jeg er glad for at gøre det nu. Så jeg har bedt jer til komme forberedt med nogle tanker om Quiz 0. Så hvem vil gerne få os begyndte med et spørgsmål eller kommentar om Quiz 0? [PAPER knitrende] JASON HIRSCHHORN: Ikke alle gjorde perfekt. Så jeg ved, [griner] der være nogle spørgsmål om Quiz 0. OK. Ja. Ompica. OMPICA: Number 10. JASON HIRSCHHORN: Number 10. Hvilken en var nummer 10? OMPICA: The - JASON HIRSCHHORN: I haven't - OMPICA: Den omfatter - JASON HIRSCHHORN: Number 10 var otte til i - at skrive otte til i? OMPICA: Ja. JASON HIRSCHHORN: OK. Så et andet spørgsmål du kunne have spurgte var jeg forudseende? Svaret er ja. I afsnit før quizzen, spurgte jeg jer at kode både Sterling og otte til jeg. Både af dem skete for vises på quizzen. Så forhåbentlig, du har betalt opmærksom på det. Og hvis du havde, så ville du have sandsynligvis gjort godt på de to. Men otte til jeg gjorde vi faktisk ikke kode det i klassen, men det var igen, spurgte på quizzen. Så et par ting at tage Bemærk når kodning otte til jeg. Den første ting, pr spørgsmålet, var at du havde brug for at kontrollere, om strengen var lig med nul. Et par personer forsøgt at kontrollere senere i programmet, hvis s beslag jeg var - så et bestemt tegn på, at snor - var lig med nul. Men husk, at null er væsentlige - det er godt at tænke på null som en nul-pointer - en pointer til nul - et sted i hukommelsen, hvor du kan aldrig få adgang til. Så hvis noget er lig med nul, du ved, at det ikke er blevet initialiseret, eller der er ikke noget der. Så s er en char stjerne, s beslag i er en char. Så det giver mening at sammenligne s til null, men ikke s beslag jeg til null. Men igen - så det var det første, at du skulle gøre - skal du kontrollere, at du rent faktisk fik en reel streng. Næste, du ønskede at gå igennem hvert tegn i strengen. Og så det ville være som en s beslag Jeg, for eksempel, hvis jeg er din iterator. Og tage denne karakter, og få dens faktiske værdi. Du har det gemt som en char, men ASCII-værdien for nul - nul som et tegn - er faktisk det hele tal nul. Det er nogle andre tal, som du kan kigge op i ASCII-tabellen. Så en måde at korrigere for det - nok den bedste måde at korrigere for der - er trække fra det tegnet værdi - nul som et tegn. Så minus enkelt citat, nul, anden enkelt citat. Det vil tage, hvad nummer du har som en char, og få det svarer til nummeret som et virkeligt heltal. Og der er meget lig med den fremgangsmåde, en masse mennesker tog i Problemet sæt 2, med Cæsar og Viginere - disse ciphers, når du blev dreje dem. Så efter at du har det som et nummer fra nul til ni, så - efter hvor det går i den ultimative nummer - du nødt til at formere den ved en effekt på 10. Nogle folk flyttede fra bagsiden til fronten, og multipliceres den enkelte tal med en effekt på 10. Nogle mennesker flyttede fra den front til bag - og så tog de højeste løbenumrene først - og ville spare dem i en global counter variabel. Og så hver gang gennem FOR loop, formere sig, at kæmpe global imødegå variabel ved 10, for at gøre plads til den næste char. Så det var en smule forvirrende uden mig skrive det på tavlen. Men prøveopløsningen er tilgængelig for dig. Men det var de store ting vi ledte efter. Også en kontrol for at sikre, at hver individuel karakter var faktisk en karakter mellem nul og ni, og ikke en anden karakter, som en A, for eksempel. Det var de ting, vi ledte i det spørgsmål. Besvarer det dit spørgsmål? OMPICA: Ja. JASON HIRSCHHORN: OK. Er der andre spørgsmål om Quiz 0? Hvad med at samle? Everybody kompilering ret? Nej. Der var en - [Griner] Eventuelle spørgsmål om kompilering proces? Wow. [PAPER knitrende] JASON HIRSCHHORN: Ja. Michael. MICHAEL: Er nummer 7 - tilfældigt? JASON HIRSCHHORN: Number 7. Nummer 7, var at få et tilfældigt heltal. Excellent. Så du får et heltal a og en heltal b og du vil have en tilfældig heltal mellem a og b. Vi kan faktisk skrive denne ene på bestyrelsen, fordi denne ene var én linje kode - én måde at gøre det. Så vi givet drand som en funktion, vi kunne bruge. Og hvad betyder drand - forudsat det er blevet seedet - hvad betyder drand vende tilbage? MICHAEL: En flyder mellem 0,0 og 1,0. JASON HIRSCHHORN: Et tal - ja. Et tal mellem 0 og 1. Og så vi har B og A. Og så har vi vores tilfældige tal mellem 0 og 1 givet til os af drand. Nogle mennesker forsøgte at sætte b, eller b minus en, eller noget inde dem parenteser. Det ville betyde, at de er argumenter denne funktion. drand ikke tager nogen argumenter - Ligesom getString gør ikke tage nogen argumenter. Så det er bare åbne paren tæt paren - og det i sig selv er funktionen opkald. Og det giver dig en række mellem 0 og 1.. Selvfølgelig har vi en hel række at tal kan være i. Sige, hvis b er 10 og en er 5, vi virkelig ønsker et nummer med en række af 5.. Så den næste ting, vi skal gøre, er multipliceres med den række B minus en. Så under forudsætning af, der er mangedoblet. Og det vil give os en række inden for et givet interval. Og dette specifikke område er den Forskellen mellem B minus en. Og endelig, der vil kun give det fra - sige området mellem b minus en er 5, vil det give os et tal fra 0 til 5. Men hvis en er faktisk 5, er vi nødt til at øge dette område op til, hvor det er faktisk formodes at være, ved at tilføje en. Så får logikken højre. Og så ville du have et andet spørgsmål? MICHAEL: Nej. Jeg bare føler virkelig dum lige nu. [Griner] JASON HIRSCHHORN: Nej. Må ikke føler virkelig dum. Et antal mennesker kæmpet med dette spørgsmål. Og så det andet spørgsmål er, drand, du sagde, giver dig en float - returnerer en float. Men denne funktion faktisk bedt til et helt tal, der skal returneres. Du behøver ikke at kaste dette udtrykkeligt til et heltal, fordi disse operationerne vil behandle det som alle en flyde - som et decimaltal. Som dette vil - også selvom det er et helt tal, vil dette multipliceres korrekt. Alle multiplikation vil arbejde. Du behøver ikke at kaste det her. Faktisk bør du ikke kaste den. Det ville - hvis du vil kaste en række der er mellem 0 og 1 - et tilfældigt tal, en floating point - så vil det enten kun være 0 eller 1, så mister du alt dette præcision. Men i slutningen, når du vender tilbage, det automatisk får sendes tilbage som et heltal. Så du behøver ikke at gøre at støbe selv. Så dette var svaret på dette spørgsmål, nummer 7. Alle andre spørgsmål om Quiz 0? Ja, Annie. ANNIE: Når vi bruger rekursive - når vi bruger iterative loops? JASON HIRSCHHORN: Når bruger du rekursive - så mere generelt fordele og ulemper ved rekursion versus en iterativ fremgangsmåde. Kan nogen give en pro eller en con? Venligst? Ikke kan nogen. Hvem kan tilbyde en pro eller en con? [PAPER knitrende] STUDENT 1: Rekursiv er mindre kodning - mindre skrive? JASON HIRSCHHORN: Så generelt, rekursion især en funktion - eller en algoritme som merge sortere - som egner sig til en rekursiv metode - kunne være mere ligetil at kode rekursivt. Og bare give mere mening at gøre det rekursivt. Så det ville være en pro til rekursion. Andre? Ja? STUDENT 2: Con til rekursion - Det bruger mere hukommelse. JASON HIRSCHHORN: Så præcis højre. En rekursiv funktion vil holde tilføje stakrammer til stakken. Så hvis du opererer på en masse tal, og er nødt til at kalde dette fungere en masse, så vil du helt sikkert fylder mere hukommelse, mens en iterativ tilgang vil kun sætte ét stakrammen på stakken, fordi det hele sker inden for en funktion. Alle andre fordele og ulemper? Ja. STUDENT 3: Fordele for rekursion. Du behøver ikke at bestemme i forhånd, hvor mange gange kode måtte gentages. Du kan have et forudbestemt antal gange, at du er nødt til at gentage, så rekursion er bedre, fordi det tager dette resultat. JASON HIRSCHHORN: Jeg tror, ​​det er rigtigt. Men jeg tror i begge tilfælde du ville aldrig - ville du sikkert få nogle input fra brugeren. Eller denne funktion ville have nogle input der ville bestemme, hvor mange gange det skal køre. Så generelt, ikke ville du hårdt kode - selv i en iterativ tilgang - hvordan mange gange, at løkken skal køres. Har du har en anden, du var tænker, Annie? OK. Så det er nok de to - den største pro og den største con til en rekursiv versus en iterativ fremgangsmåde. OK. Noget andet på Quiz 0? Lad os komme videre. File I / O. Der er en vidunderlig kort denne uge på fil I / O, som forhåbentlig du har set flere tidspunkter, og beundret. En masse arbejde gik ind i det, og jeg har hørte det er sindssygt nyttigt. Jeg har også inkluderet linket på dette dias, hvis du ikke har haft en chance for at se det 10 gange. Så vi kommer til kort gå over vigtige skridt til at åbne og arbejde med filer og derefter vil vi dykke ned i en kodning problem før undersøge problemet sæt. Så igen, vil jeg sætte det op på skærmen, men jeg har tænkt mig at tale om blot et minut om, hvad vi gør her med fil I/O-- hvad betyder det? Det betyder, at vi kan skabe vores programmer, og så har vores programmer exit, og ikke har gjort nogen indvirkning på verden uden for vores program. Men når vi begynder at arbejde med filer - både læse dem i og skabe dem - vi kan have en vis effekt på verden uden for vores program. Ligesom hvis Microsoft Word ikke var i stand at foretage Word-dokumenter, så når Microsoft Word op, alle dine arbejde ville være væk, og det ville virkelig være ubrugelig. Vi har i sidste ende vil være i stand til skrive programmer, der kan påvirke verden omkring dem, både ved at tage i komplekse indgange - i form af filer og via filer, og også skaber interessant og overbevisende udgange - i form af forskellige typer af filer. Så det er derfor, vi er begyndt at lære at arbejde med filer. Mere konkret, hvilke vi gør, er som følger. Det er meget simpelt. Der er kun et par skridt, og de er opført her på denne kode. Så vi kommer til at gå igennem denne kode linje for linje. Først skal du se fremhævet - når du arbejder med en fil, uanset hvilken type fil det er, du nødt til at åbne den. Og det er med en opfordring til fopen - lige her. Du medtage navnet på filen. Hvis filen ikke er i telefonbogen, eller den mappe, hvor dette program liv, så er du også nødt til at omfatte en sti til hvor filen er. Vi kommer til at antage, at dette fil kaldet "text.txt" - en simpel tekst dokument - er i samme mappe som dette program er. Så det er en anden ting at huske på øje - at hvis du ønsker at åbne en fil et andet sted, du faktisk har brug at medtage dens placering. For det andet, kan du overføre et argument for fopen, og det er, hvad du ønsker at gøre med filen. Der er tre vigtigste argumenter, du kommer til at passere til fopen. Hvem kan give mig de tre? Hvem kan give mig en af ​​dem? Ja. STUDENT 4: Filen navn? JASON HIRSCHHORN: Undskyld. Tre væsentligste argumenter du kan passere som det andet argument til fopen. Du har ret - filnavnet er det første argument. Men det andet argument til fopen er generelt tre strygere, og - ja. Aleja. Aleja: A for append. JASON HIRSCHHORN: A, hvis du vil vedlægge en fil, der allerede eksisterer. STUDENT 5: R for at læse. JASON HIRSCHHORN: R hvis du ønsker at læse fra en fil. STUDENT 6: W for write. JASON HIRSCHHORN: Og w hvis du ønsker at skrive til en fil. Så i dette tilfælde, vi skriver til filen, så vi har w. Du åbner den, du også nødt til at gemme fil et eller andet sted, og det er med kode til den venstre side af opgaven operatør - Jeg skaber en pointer til en fil kaldes, i dette tilfælde, fil. Vi kommer ikke til at bekymre dig, hvad denne alle hætter FIL ting er. Det er tilstrækkeligt at sige, det er en lang strøm af nuller og ettaller. Og det er, hvordan vi kommer til at betjene det og forstå det. Den næste ting, vi skal gøre - og dette er utroligt vigtigt - hver gang du åbner en fil - i virkeligheden, når du kalder malloc for eksempel, og få nogle hukommelse, og prøv og gemme det i en pegepind, du altid ønsker at tjekke for at sikre, at der funktion returnerede ikke nul. Så i dette tilfælde, er vi kontrol for at sikker på, at vi faktisk åbnet fil korrekt, og der var ingen fejl i vores program. Næste gang vi har tjekket for at sikre, at vi har en fungerende fil, kan vi skrive til eller læse fra, eller føje til filen. I dette tilfælde er jeg simpelthen udskrive en linje til denne fil. Hvordan kan jeg vide det? Nå, jeg bruger denne funktion kaldet fprintf. Alle de funktioner, du vil bruge når du skriver til eller læsning fra eller manipulere filer vil være magen til funktioner, du har set før, men starter med bogstavet F, stående i filen. Og fprintf, i modsætning til vores normale print app, tager et yderligere argument, og det er den fil, hvor du ønsker at udskrive denne linie til. Jeg har ikke noget at ret ohai. Jeg har ikke den tredje argument til printf - eller det andet argument til printf, den tredje argument til fprintf, fordi jeg ikke har nogen pladsholdere her. Jeg er ikke inklusive eventuelle variabler. Men igen, fprintf og alle disse fil funktioner, der opererer med filer generelt vil få brug for filen som de er i drift. Endelig er den sidste vigtige ting at gøre, er at lukke filen, ligesom med - når vi allokere noget, vi ønsker at frigøre noget, at vi ikke har en hukommelsesfejl - vi vil at lukke vores fil. Hvis programmet forladt uden lukning filen, odds er intet ville gå forkert, især hvis det var en lille fil. Men det er bestemt god kodning stil og praksis altid at lukke din fil når du er færdig med at bruge det. Så det er det grundlæggende i fil I / O. Du har sikkert set det før, eller så det i denne fantastiske kort. Er der nogen har nogen spørgsmål, før vi går ind i nogle praksis kodning problemer, omkring fil I / O eller skridt, jeg gik bare forbi? [TYPING SOUNDS] JASON HIRSCHHORN: Kan du har et spørgsmål, Avi? AVI: Nej. JASON HIRSCHHORN: OK. Jeg har tænkt mig at vente en anden syv sekunder. [Griner] Det er et rigtig godt tip. Du fyre kan bare ikke lide stille spørgsmål. Det er fint. OK. Så vores første praksis problem er, at vi er kommer til at overlappe funktionen af en kommandolinje værktøj, som du sandsynligvis brugt før - copy - kopien værktøjet. Hvis du skriver cp, og derefter sende det to argumenter i din terminal, kan du kopiere en fil. Og det er det, vi går til at skrive lige nu. Så igen, læse ud af dette dias, jeg havde dig til at skrive et program, der tager to og kun to kommando-linje argumenter - en kildefil og en destination fil - og kopierer indholdet af kilden filen til destinationen fil en byte ad gangen. Så det er meget at bede om. Igen, en god tilgang til dette er at ikke gå direkte til C-kode, men bryde det ned i et par trin. Først tænke logikken - præcis hvad jeg beder dig om at gøre - og forstå alle de trin til dette problem. Ikke i C, bare i nogle pseudokode, eller endda en mental model hvad der foregår. Næste gang du har pseudokoden ned, regne ud, hvordan pseudokoden kort på værktøjer og ting, vi har lært at bruge i C. Og endelig, når du har alt, sammen, kan du kode problemet. Tage 5 til 10 minutter for at arbejde på dette problem. Jeg vil sætte instruktionerne tilbage op i et sekund. Og så vil vi gå over pseudokode og kode det lever som en gruppe. Hvis du har spørgsmål, mens du er arbejder på dette, er du velkommen til at hæve din hånd, og jeg vil komme rundt og besvare dem. STUDENT 7: Kan jeg knalde et stykke papir? JASON HIRSCHHORN: Hvad sker der? [TYPING SOUNDS] JASON HIRSCHHORN: OK. Lad os gå over pseudokoden først, og så vil jeg give dig et par mere minutter at afslutte kodning. Hvem vil gerne starte mig med den første linje i pseudokode til denne funktion? STUDENT 8: Kontroller, at du fik to filer. JASON HIRSCHHORN: OK. Og hvis vi ikke? STUDENT 8: Jeg ville vende tilbage 0. JASON HIRSCHHORN: Skal vi vende tilbage 0? STUDENT 8: Return a - afblænding. Undskyld. JASON HIRSCHHORN: Ja. Sandsynligvis ikke 0. Fordi 0 betyder alt var godt. OK. Så det er den første linje af pseudokode. Hvem har den anden linje i pseudokode? STUDENT 9: Åben begge filer? JASON HIRSCHHORN: Åbn begge filer. OK? STUDENT 10: Kontroller hvis filen er NULL? JASON HIRSCHHORN: Kontroller, at at hverken er NULL. Som en sidebemærkning - skråstreg 0 - er, at NUL? STUDENT 11: Nej. JASON HIRSCHHORN: Det er ikke NULL. Det kaldes NULL terminator. Det er faktisk staves med kun én liter. Så kontrollerer noget imod det - der er faktisk et tegn - så kontrol noget imod, der er ikke det samme som kontrol for at se, om det lig NULL. Og nogle mennesker - på deres quizzer og deres problem sæt - har fået to af dem forvirret. Men de to af dem er i virkeligheden forskellige. Man slutter en streng - den ene er en pointer til 0. STUDENT 12: Hvorfor ville du ikke kontrollere Sørg for, at filerne ikke er NULL før du åbner dem? JASON HIRSCHHORN: So åben sparer noget i denne fil. Og hvis du går tilbage her - så denne linje - fopen - vil give dig en adresse og butik at adressen i filen, hvis det virker. Hvis det ikke virker, er det gemmer NULL - STUDENT 12: Oh. OK. Fik dig. JASON HIRSCHHORN: I fil. Så du kan ikke tjekke for NULL før du har åbnet dem. NULL betyder noget ikke gjorde fungere korrekt. OK. Så tjek for at sikre hverken sige? Eller er? Hvad mener vi? Vi vil gå med det. STUDENT 13: Er. JASON HIRSCHHORN: Er? Hverken er? STUDENT 13: Er. JASON HIRSCHHORN: OK. Vi synes at have nogle enighed om det. Hverken NULL. OK, næste linje i pseudokode. Hvem har ikke givet mig en linje endnu? Vi vil vente på dig. Ja. STUDENT 14: Du er nødt til at læse fra den første fil? JASON HIRSCHHORN: OK. STUDENT 14: Eller vi bruger fscanf eller noget som den første fil? JASON HIRSCHHORN: Så vi ønsker at læses fra den første fil, og - lad os sætte det lige her. Læs fra kildefilen. Og så, hvad gør vi, når vi læses fra kildefilen? En anden? STUDENT 15: Skriv ind destinationsfilen? JASON HIRSCHHORN: Vi skriver til destinationsfilen, og - OK. Hvad mangler vi? Nogen andre, der ikke har givet mig en linje kode endnu - af pseudokode. Ja. STUDENT 16: Måske kan du altid tjekke hvorvidt der er noget at læse for, som den næste linje? Det er ligesom den næste linje, se, hvis den findes. [ELEKTRONISK BEEP] JASON HIRSCHHORN: Ups. Det er min journal software. Ja? STUDENT 16: Ja. JASON HIRSCHHORN: Så giv det til mig en gang mere. STUDENT 16: Kontroller, om der er stadig en næste linje fra kildefil at læse. JASON HIRSCHHORN: OK. Så vi ikke læser linier - læste bytes her - men du er korrekte. Vi ønsker at læse og skrive, indtil der ikke er flere bytes. OK. Og så disse bør virkelig være indrykket lidt, fordi de er under der. Right? Indtil vi er ude af bytes, vi kommer til læses fra kildefilen og skrive til destinationen fil. Og så, hvad der er den sidste linje pseudokode? Nogen, der er ikke givet mig endnu noget. STUDENT 17: Luk filerne? JASON HIRSCHHORN: Præcis. Luk filerne. Så der er vores pseudokode. Jeg har tænkt mig at sætte pseudokoden ind gedit, og i et par minutter, vi vil kode det sammen. OK. Lad os komme i gang som en gruppe. Nishant, jeg har min nye fil. Jeg har lige åbnet det op. Untitled document 1. Hvad er det første, jeg skal gøre? Nishant: Medtag bibliotekerne? JASON HIRSCHHORN: OK. Hvilke biblioteker? Nishant: stdio.h, stdlib.h, tror jeg? JASON HIRSCHHORN: OK. Hvad er stdlib efter? Nishant: Jeg har glemt. JASON HIRSCHHORN: OK. Så indeholde stdio. Hvad skal jeg gøre, selv før Jeg starte kodning? Nishant: Skriv en overskrift? JASON HIRSCHHORN: Hvordan får jeg det farvet? [indskyde STEMMER] Nishant: Hvordan får du det farvet? JASON HIRSCHHORN: Hvordan skal jeg Farvekodning? Nishant: Jeg ved det ikke. Oh. Gem. JASON HIRSCHHORN: Gem. Ja. Jeg skulle gemme det som en. Ca. Så gem det på skrivebordet som cp.c. Sød. Og hvis jeg ønsker at få fuld stil punkter, hvad skal jeg omfatte foroven? Nishant: Du kan skrive dit navn, navnet af programmet, og formålet af programmet så godt? JASON HIRSCHHORN: Ser godt ud. Excellent. Så du har startede os perfekt. # Include - vi vil også skrive - OK. Så jeg tror, ​​jeg alle indstillet til at gå. Hvem har den første linje kode for mig - eller de første linjer kode, der det vil tage at tilfredsstille vores første kommentere i pseudokode? Dig. STUDENT 18: Bør det ikke være int argc og derefter char * argv? JASON HIRSCHHORN: Jeg tror du har ret. Lad os ændre det til int main, åbne parentes, int argc, komma, char * argv? Ligesom det? STUDENT 18: Beslag. JASON HIRSCHHORN: Beslag. Åbneparentes tæt beslag, tæt forælder. Perfect. Nu kan jeg tage kommandolinje-argumenter. OK. Sikre, at vi fik to filer. Du kan give mig, at så godt. STUDENT 18: Hvis argc - det man ikke lig 3. JASON HIRSCHHORN: Hvis åbne paren argc ikke lig med 3? STUDENT 18: Ja, du vender tilbage 1 eller noget. JASON HIRSCHHORN: Undskyld. STUDENT 18: Return 1 eller noget. JASON HIRSCHHORN: Tilbage 1. OK? Store. Åbn begge filer. Hvem kan hjælpe mig at åbne begge filer? Hvem har ikke givet mig koden endnu? Kurt? KURT: Så alle caps F-I-L-E stjerne kilde. JASON HIRSCHHORN: Jeg har tænkt mig at tage ud vokaler. Det er cool. Det er ligesom Tumblr. STUDENT 18: Lig fopen - JASON HIRSCHHORN: Lig fopen? STUDENT 18: Åbne parentes, argv, åbneparentes. JASON HIRSCHHORN: Vent. Undskyld. Åben parentes. OK. STUDENT 18: Ja. Argv sub 1.. JASON HIRSCHHORN: Sub 1? STUDENT 18: Ja. Argv åbneparentes 1 - Ja. Og så komma og derefter åbne dobbelt citat, r, dobbelt citat, tætte paren, semikolon. JASON HIRSCHHORN: Sød. Og hvad med den anden? STUDENT 18: Meget lignende, men i stedet af S-R-C, ville du kalde det D-S-T. JASON HIRSCHHORN: Oo! Jeg kan godt lide det. STUDENT 18: Just D-S-T. Ja. Og så argv, åbneparentes, 2.. Ja. Og så w stedet for r.. Ja. JASON HIRSCHHORN: Great. Næste par linjer. Også, hvis nogen har ting at tilføje til linjer, som vi har gjort, er du velkommen til tilføje dem så godt. Kontroller, at ingen af ​​dem er NULL. Hvem kan give mig den kode jeg har brug for at tilfredsstille denne linje af pseudokode? Archer. ARCHER: Hvis src lig ligemænd NULL eller dst lig ligemænd NULL, så du vender tilbage - JASON HIRSCHHORN: Hvad? ARCHER: Return 2? JASON HIRSCHHORN: Return 2. Så hvis åben parentes src lig lig NULL, eller - uanset hvad der thing's - rør? Pipe? Vi kalder det rør. Pipe, rør, dst lig ligemænd NULL, returnere 2. OK? Indtil vi er ude af bytes - vi slags springes over dette skridt fra pseudokoden del til at gå til her. Men indtil vi er ude af bytes - hvad lyder det? Hvilken type C struktur - men jeg bruger ikke ordet struktur, fordi vi kommer til at begynde at bruge at i andre tilfælde - men C værktøj lyder det? STUDENT 19: En løkke. JASON HIRSCHHORN: En løkke. Lyder som en løkke. Så der kan give mig den første linje af løkken kode lige her? Du kan også vælge, hvilken slags loop, du ønsker, hvis du giver mig denne linje kode. Der findes tre typer. Du kommer til at plukke. Jeg vil foreslå en af ​​dem. Avi. Hvilken en vil du have? AVI: FOR. JASON HIRSCHHORN: FOR. AVI: int i er lig med nul. JASON HIRSCHHORN: OK. AVI: Denne del er jeg ikke sikker på om. Men i er mindre end størrelsen af stjerne kilde? Jeg er ikke sikker på. JASON HIRSCHHORN: OK. AVI: Fordi du ønsker, at størrelsen på en fil, right? JASON HIRSCHHORN: Så det vil sandsynligvis ikke giver os størrelsen af ​​den faktiske fil i bytes. Så hvad andet kunne vi gøre? Hvad er en anden type loop? Eller skal vi holde fast i for-løkken? STUDENT 20: Kan du en while-løkke? Og så, hvad du ville gøre, er I ville i stedet - fordi vi har en char * til filen. Så hvis vi bare holde forøgelse at indtil vi ville finde NULL tegn på i slutningen af ​​det? Eller nej, er, at ikke hvordan filer fungerer? JASON HIRSCHHORN: Så vi kan beholde forøgelse af char * indtil vi finder NULL - STUDENT 20: Væsentlige holde ud tegn for tegn, indtil vi ramte slutningen af ​​filen. JASON HIRSCHHORN: Ja. Så det er hvad vi ønsker at gøre. Vi ønsker at holde læsning, karakter af tegn, indtil vi kommer til slutningen af ​​filen. STUDENT 20: Ja. Find - hvad er enden eller stopskilt ved afslutningen af ​​en tekstfil. JASON HIRSCHHORN: OK. Så når vi kommer til slutningen af ​​filen - hvordan kan vi vide, vi har nået slutningen af ​​en fil? Hvis jeg ringer - så lad os træde et skridt tilbage. Hvad er en funktion? Lad os gå til denne linje lige her. Læs fra kildefilen. Hvem kan give mig denne linje kode? STUDENT 21: fscanf? JASON HIRSCHHORN: fscanf. OK. Hvad hvis jeg ønsker at læse, meget specifikt en byte? STUDENT 21: Jeg ved det ikke. JASON HIRSCHHORN: OK. Endnu enklere end fscanf - hvad er en - Jeg ønsker at læse fra en kilde fil? Læse fra en kildefil. Hvad er en funktion - ja. STUDENT 22: Det er fread? JASON HIRSCHHORN: fread. Jeg tror, ​​lad os holde fast i at man for nu. Hvilken slags argumenter betyder fread tage? STUDENT 22: Sandsynligvis den filtype, og derefter placering i filen? JASON HIRSCHHORN: Hvad kan jeg skrive her at finde ud af, hvilken type argumenter fread tager? FLERE STUDERENDE: Man fread. JASON HIRSCHHORN: Man fread og fwrite. Ligner de hænge ud sammen. Så fread tager, hvor mange argumenter? STUDENT 23: Four. JASON HIRSCHHORN: Det tager fire argumenter. Det tager en pointer, en størrelse, og at ting, som er underligt, og nogle fil. OK? Lad os læse om det lige her. "Funktionen fread læser n memb elementer af data, hver størrelse bytes lang, fra strømmen der peges på af streame, opbevare dem på det sted, afgivet pointer. " Så fire argumenter. Hvorfor kan jeg ikke bare kopiere det, og indsæt den lige her. OK. Så der kan begynde at udfylde disse argumenter til mig? Avi. AVI: Tag tomrum. Sæt bare src. Tag pointer og stjernen. Put src. Så - JASON HIRSCHHORN: Så jeg har tænkt mig at stoppe du der, fordi det er forkert. Du har ret med src, men hvor skal src hen? [indskyde STEMMER] JASON HIRSCHHORN: Det bør gå over her. Det er src - vores src er en type. Lad os se her. Dette beder om en type FIL *, vi faktisk normalt se dem sådan. Så dette er at bede om et argument for filtypen * kaldet strøm, der er src. OK? Hvilken størrelse af ting at gøre vi ønsker at læse? Jeg gav dig dette i beskrivelse af problemet. STUDENT 24: En byte ad gangen. JASON HIRSCHHORN: Én byte. Hvor stor er en byte? Dens størrelse er i bytes, så hvad kan jeg sætte lige der? STUDENT 25: One. JASON HIRSCHHORN: One. Right. Dens størrelse er i enhed byte, så 1 er 1 byte. Hvor mange ønsker jeg at læse på et tidspunkt. STUDENT 26: One? JASON HIRSCHHORN: En ting. Jeg ønsker at læse en ting af størrelse 1, en bid ad gangen. Og hvor skal jeg sætte det, når jeg læse det? STUDENT 27: Destination? JASON HIRSCHHORN: Så jeg kan ikke sætte det lige ind destination. STUDENT 28: Du kommer put det ind i en tredje pointer? STUDENT 27: til destinationen. JASON HIRSCHHORN: OK. Ja. STUDENT 29: Du kan erklære noget til fungere som en midlertidig oplagring tidligere. JASON HIRSCHHORN: OK. Giv mig den. STUDENT 29: En anden fil pointer, måske? JASON HIRSCHHORN: OK. Så dette er ugyldig stjerne - det er en type tomrum stjerne, så det ikke være en fil pointer. Og hvis jeg læser en byte, hvor ville være et godt sted at gemme en byte? STUDENT 29: Et array? JASON HIRSCHHORN: An array. OK. Og hvad der ellers er noget, der er bare størrelse en byte? STUDENT 30: Et char *? STUDENT 29: Ja. JASON HIRSCHHORN: En char * er ikke én byte. STUDENT 29: En char. JASON HIRSCHHORN: En char er en byte. Right? Så lad os kalde denne buffer er en generisk betegnelse for disse ting til at gemme noget midlertidigt. Så jeg skabe en buffer. Right? Men det tager en void *. Så måske du har ret, at det bør være en buffer på størrelse 0. Så det gemmer en - højre. Fordi denne ret her - char buffer er et tegn, men det tager en void * - en pointer. Så jeg kunne gøre dette og nu puffer er en pointer. Hvad andet kunne jeg gøre? STUDENT 31: Sæt en stjerne ud til char. JASON HIRSCHHORN: Jeg kunne har skabt det char *. OK. Hvad er en anden ting, jeg kunne gøre? Eller lad os gå med denne ene. Char * buffer, så hvad sætter jeg her? STUDENT 31: Buffer. JASON HIRSCHHORN: Buffer. Buffer er en pointer til en char. Og i den placering, vi sætter en byte noget, vi har læst. Ja. Avi. AVI: Bare et hurtigt spørgsmål. Ønsker du at allokere buffer? JASON HIRSCHHORN: Hvem kan besvare dette spørgsmål? STUDENT 32: Nå, det gør ikke rigtig punkt til noget lige nu, så - JASON HIRSCHHORN: Men gør vi ønsker at allokere det? STUDENT 32: Hvis du skulle gøre det på den måde, tror jeg, ja, fordi du havde behov for nogle sted for det til at pege på. JASON HIRSCHHORN: Har vi nødt til at allokere det? STUDENT 33: Hvis du vil bruge den uden for sløjfen. JASON HIRSCHHORN: Skal vi bruge den uden for loop? STUDENT 34: Ja. STUDENT 35: Vent. Ønsker vi at erklære den i sløjfen til ud? JASON HIRSCHHORN: Så jeg gætte, vi har nogle pseudo MENS løkke her, at vi er forsøger at regne ud, at Vi har ikke fået til endnu. Vi behøver ikke at allokere den. Vi opererer i hovedsagen, er det kun går til brug inden for denne løkke. Det behøver ikke at eksistere uden for dette. Så det kan være en lokal variabel. Du har en pointer til en lokal variabel. STUDENT 36: Men det er ikke peger på noget. JASON HIRSCHHORN: Nej, det er ikke initialiseres til noget. Men vi kommer ikke til at bruge det også. Vi kommer til at sætte noget i det første gang vi bruger den. Så der synes OK. Så vi har ikke brug for malloc her. Og jeg synes, det er OK, som det er. OK. Vi har den fread linje. Lad os gøre den næste linje. Hvis vi ønsker at skrive til en fil, hvad er en god funktion at bruge til at gøre det? STUDENT 37: fwrite? STUDENT 38: fprintf? JASON HIRSCHHORN: fprintf er én. Hvad er en anden? STUDENT 39: fwrite. JASON HIRSCHHORN: fwrite. Og til vores formål, fwrite, som vi så her, er sandsynligvis det bedste valg. Det tager fire argumenter så godt. Nishant, kan du give me argumenterne? Nishant: Den første ens igangværende at være lige puffer. JASON HIRSCHHORN: OK. Nishant: Den anden ens bare at være 1. Tredje man kommer til at være 1. Og den fjerde bliver DST. JASON HIRSCHHORN: Er der nogen, der har spørgsmål om denne linje? Det ser godt ud. OK. Så nu ser det ud som den ene ting, vi er mangler - faktisk, lad os skrive denne sidste linje. Luk filerne. Hvem kan afslutte os op skrivning disse to sidste linjer? Ja. Undskyld, hvad er dit navn? LUCY: Lucy. JASON HIRSCHHORN: Lucy. LUCY: fclose src og derefter fclose destination. JASON HIRSCHHORN: fclose, åben parentes, src, tætte paren, semikolon. Og fclose - ja? LUCY: Åben parenteser, dst og derefter semikolon. JASON HIRSCHHORN: Great. Og hvad skal jeg medtage i slutningen? LUCY: Return 0. JASON HIRSCHHORN: Return 0. Skal jeg? Bare et spørgsmål. Har vi nødt til at medtage tilbagevenden 0? FLERE STUDERENDE: Nej. JASON HIRSCHHORN: Nej. Main gør det automatisk hvis du kommer til enden. Men jeg synes det er rart at medtage den eksplicit. Især når vi vender tilbage en anden ting i hele programmet. OK. Dette er, hvad vi mangler - MENS hvad? Hvem kan tænke på nogle - har en fornemmelse af, hvad tingene kunne gå derind? Selvom det er bare i nogle pseudokode lignende sprog? Hvad er vi egentlig - hvad ønsker vi at gå, indtil? Ja, Lucy. LUCY: Slutningen af ​​filen. JASON HIRSCHHORN: Slutningen af ​​filen. Så hvad mener du med slutningen af ​​filen? LUCY: Når du kommer til slutningen af ​​filen, stop. JASON HIRSCHHORN: OK. Så når vi når til slutningen af ​​filen. Hvordan kan vi vide, når vi har nået slutningen af ​​fil? STUDENT 40: Jeg tror buffer vil blive sat til NULL. STUDENT 41: Buffer er erklæret inde i sløjfen. JASON HIRSCHHORN: Så du tror buffer vil blive sat til NULL. Hvorfor skulle buffer sættes til NULL? STUDENT 40: Fordi når du fread, forsøger du at sætte intet ind i buffer. JASON HIRSCHHORN: OK. Så du tænker fread - når vi har nået slutningen af ​​den fil, hvad der er fread gøre? Jeg tror, ​​det er spørgsmålet vi er nødt til at regne ud. Hvad betyder fread gøre? Er det sat NULL i buffer, eller gør den noget andet? Hvordan kan vi regne ud, hvad det betyder? STUDENT 42: Man. JASON HIRSCHHORN: Man. Så lad os se herovre. Retur værdi. Den succes, fread og fwrite returnere antallet af elementer læses eller skrives. Dette tal er lig med antallet af bytes overføres kun, når størrelsen er 1. Hvis der opstår en fejl, eller afslutningen af ​​den fil er nået, er returværdien en kort post count eller 0. Så for vores formål, hvis fread afkroge slutningen af ​​filen, og læser fra I slutningen af ​​filen, er der intet tilbage at læse, hvad det kommer til at vende tilbage? STUDENT 43: Zero? JASON HIRSCHHORN: Hvad? STUDENT 43: Zero? JASON HIRSCHHORN: Zero. Det kommer til at returnere nul. Så vi ved, at fread, når vi har nået enden af ​​filen, går for at vende tilbage til nul. Hvordan kan vi bruge det til vores fordel? AVI: Du kan erklære en variabel udenfor af løkken kaldes check. Hvis kontrol lig - for nu - én. JASON HIRSCHHORN: OK. AVI: Og så kan du sætte en IF erklæring lige efter fread siger, hvis fread lig nul - no. JASON HIRSCHHORN: Hvem kan hjælpe Avi ud? AVI: Hvad er værdien returneret af fread? JASON HIRSCHHORN: Vi har lige gik over. AVI: Hvordan du repræsenterer det? JASON HIRSCHHORN: Så det vender tilbage - lad os se op her - det returnerer en size_t, der i det væsentlige et heltal. Så det returnerer et heltal. Og i vores tilfælde, vil det returnere 1 eller 0 - 1, hvis den læst én ting - en byte, og 0, hvis vi har nået slutningen. Så hvis fread - ja? STUDENT 45: Kan du ikke bare sætte den fulde fread (buffer, 1, 1, src) i mens loop? JASON HIRSCHHORN: Så du foreslår gøre dette i der? [indskyde STEMMER] JASON HIRSCHHORN: Hold ud. Så vi befri af. Så du foreslår at sætte ind der? fread Hvad skal vi også flytte hvis du ønsker at gøre det? STUDENT 45: buffer udenfor. JASON HIRSCHHORN: Vi bør også flytte ud af dette her. STUDENT 45: Men er der konstant flytte det fremad? [indskyde STEMMER] JASON HIRSCHHORN: OK. Så dette er hvad Okshar foreslået. Vi skaber vores buffer. Vi MENS fread, så vi fwrite. Tanker om dette? STUDENT 46: Mit eneste spørgsmål er, ville det faktisk udføre kommandoen fread? JASON HIRSCHHORN: Great spørgsmål. Når du lægger et funktionskald inde i en tilstand, gør det funktionskald udføre? Vi har set eksempler på dette før. Right? STUDENT 46: OK. Ja. Så det gør udføre. JASON HIRSCHHORN: Vi har set tingene som før, hvor vi har en funktionskald indersiden af ​​en tilstand. Betyder det funktionskald udføre? Ja. Så svaret er ja. Denne funktion indkaldelse vil udføre. Men igen, det er hvad vi ønsker? Hvad er en måde, vi kunne regne ud, hvis det er hvad vi ønsker? FLERE STUDERENDE: Kør det? JASON HIRSCHHORN: Vi kunne køre den. Men før vi gør det, vi kunne også ræsonnere gennem dette. Hvis - sige, at vi har en byte i vores fil, vil vi komme til her, vi får denne kode. Dette vil køre. fread vil returnere en byte og gemme det i bufferen. Og det vil vurdere til 1, højre, efter at han vender tilbage 1. Så mens 1. Betyder det, at koden inde while-løkken vil køre? STUDENT 47: Ja. Det er sandt. JASON HIRSCHHORN: Ja. 1 er sandt. Det er ikke 0. Så kode inde her, vil udføre. Så vi vil skrive det. Vi flytter tilbage til dette linie igen. Nu har vi - vi er i slutningen af ​​vores fil. Vi læser fra slutningen af ​​vores fil, fordi vi kun havde én byte i det. Fread returnerer 0, gemmer noget i puffer. Jeg ved ærligt talt ikke, hvad det gemmer i buffer. Vi kunne sikkert se op at se, hvad det gør. At jeg helt ærligt ikke kender. Vi ved ikke, hvem bekymrer sig, hvad det gemmer i buffer? Men det vender tilbage 0. Og vil mens 0 eksekvere? MENS 0 ikke vil udføre. Så rykker vi ned her. Så lad os få en håndsoprækning, hvis dette er den kode, vi skal køre, eller hvis vi skal gøre ændringer først. Så hvis du tror - du er nødt til at stemme. Hvis du synes, vi skal køre denne kode som det er, skal du hæve din hånd. OK. Der er en - har du et spørgsmål, bekymring? Ja. STUDENT 48: Når vi bevæger buffer uden for løkken, gør vi nødt til at allokere det? JASON HIRSCHHORN: Great spørgsmål. Når vi bevæger buffer uden for loop, vi er nødt til at allokere det? Det er et omfang spørgsmål. Hvis vi initialisere buffer uden af denne sløjfe, vil det findes indersiden af ​​loop? FLERE STUDERENDE: Ja. JASON HIRSCHHORN: Ja. Dens anvendelsesområde dækker indersiden af ​​løkken, og virkelig, noget under det inde af denne kode, herunder ting inde her. Så vi behøver ikke at allokere den. Det er en lokal variabel, og dens omfang stadig indeholder sløjfen. STUDENT 49: Har vi brug for at frigøre det? JASON HIRSCHHORN: Har vi nødt til at fri buffer? STUDENT 49: Ja, hvis vi ikke gør malloc. JASON HIRSCHHORN: Har vi nødt til at fri buffer? Vi gør ikke. Igen, det er en lokal variabel, så vi ikke behøver at frigøre det. OK. Lad os se hvad der sker. Så det er initialiseret. Det var, hvad noget, Marcus foreslog tidligere. Så vi har denne fejl, variabel buffer bliver initialiseret, når det anvendes her. Hvordan kan vi løse dette? STUDENT 50: malloc det? STUDENT 51: Lig NULL? STUDENT 52: Sig buffer lig NULL. JASON HIRSCHHORN: OK. Ser godt ud. Vi har det nu. Lad os skabe noget at forsøge at kopiere. Så vi har vores tekstfil. Hvordan kan vi køre dette program? Ja. STUDENT 53: Du kan gøre dot slash cp, test.txt. Og så kan du navngive en anden fil som den gemmer i. JASON HIRSCHHORN: OK. Vi kalder det out.txt. Cool? Seg fejl. Tanker om seg skyld? Dette er stor. Hvordan kan vi finde ud af, hvor den seg fejlen er? Hvad? STUDENT 54: gdb. JASON HIRSCHHORN: gdb. Vi kører gdb ved at skrive gdb dot skråstreg, navnet på vores program. Ingen kommandolinjeargumenter der. Vi kommer til at sætte en breakpoint på main. Hvis jeg ønsker at starte gdb, hvad gør jeg? STUDENT 55: R. JASON HIRSCHHORN: R. Og hvad så? STUDENT 55: Argumenterne? JASON HIRSCHHORN: Så kommandolinje-argumenter. Lad os gå igennem. N bare at tage mig linje for linje. Jeg har tænkt mig at gå, indtil Jeg får min seg fejl. Der er min seg fejl. Det ligner fread forårsaget min seg fejl. Jeg kender fread forårsagede min seg skyld, fordi det var den linje, vi lige henrettet. Og det eneste, der var sker i denne linje - to ting blev sker. Fread foregik, og så var vi laver nogle mens du tjekker. Jeg er villig til at vædde på, at WHILE kontrol ikke var årsag min seg fejl. Mest sandsynligt, var fread forårsager min seg fejl. Jeg kan også se noget her, memcopy. Hukommelse kopi. Lyder som at flytte hukommelse fra ene sted til det andet. Lyder som noget, der ville ske i fread, måske nogle hukommelse flytter fra her til her. Lad os gå igennem det igen. Hvordan starter jeg det over og køre det igen? Ja. STUDENT 56: Har du brug for at sætte et og-tegn før buffer? JASON HIRSCHHORN: So-tegnet før buffer ville give mig adressen på puffer, som er en char *. Lad os løbe igennem en gang mere. Hvordan kører jeg igennem det en gang til? STUDENT 57: Kan du bare skriv køre igen? JASON HIRSCHHORN: Bare skriv køre igen. Så vi kommer ikke til at udføre denne linje. Så buffer er en NULL-pointer. Ret? Det peger på - lad os se. Hvis vi har vores - tegne et hurtigt billede af det. Kan alle se, om Jeg skriver herovre? Så i stakken, vi har en lokal variabel, og det hedder buffer, og det er en pointer til en char. Hvilken adresse er denne char på? STUDENT 58: 0x0. JASON HIRSCHHORN: Right. Det er, hvad det er. I her inde puffer, lagres 0x0. Det er, hvad vi har - det setup, vi har lige nu. Så denne linje, fread, sætter noget fra kilde, hvor? Ind i denne kasse eller denne boks? Hvilken kasse? Venstre kasse eller højre kasse? Denne ret kassen. Det følger markøren, og sætter det i her. Når vi prøve at røre hukommelse på placering 0, hvad får vi? En segmentering fejl. Det er den fejl, vi har lige nu. Ja. STUDENT 59: Har du ikke at sætte stjerne buffer? Eller nej? For fread? JASON HIRSCHHORN: So fread tager en pointer. Så det går i buffer. Og så vil de-henvisning det andet sted inde fread. Men igen, så vi tager det en pointer. Vi behøver ikke at passere den stjerne buffer. Det ville være forbi det, hvad er her. Og det ville sandsynligvis give os en fejl fordi vi er de-henvisninger det. Right? Når vi de-henvisningen denne pointer, når vi forsøger at få adgang til denne placering, vi får en fejl - vores segmenteringsfejl. Så - oops. Vi kommer til at holde op ud af gdb. Vores linje - vores problem - er ret her på denne linje. Og det er et problem, fordi denne linje. Hvordan kan vi skabe en boks, er tilgængelig i fread. Right? Vi er nødt til at oprette en boks, der er en byte store, størrelsen af ​​en char. Men vi har brug for, at feltet for at være tilgængelige når denne funktion udfører. Så hvor - ja. Nogen idéer? STUDENT 60: Bare sæt den som en tilfældig karakter. Bare gør char buffer ligemænd tegnet. Og så, når du har buffer der - JASON HIRSCHHORN: Vent. Char buffer? Så ingen stjerne? STUDENT 60: Ja. Tag stjernen. Lig en tilfældig karakter. JASON HIRSCHHORN: OK. Så giv mig en. STUDENT 60: Ligesom en eller noget. Og så når du har buffer der bruger du en - STUDENT 61: Star? Åh nej, det tegnet. STUDENT 60: Brug tegnet. JASON HIRSCHHORN: OK. Og hvad i fwrite? STUDENT 60: Brug tegnet igen. JASON HIRSCHHORN: Okay. Så din idé er, at vi skaber en char og sætte noget i det, og derefter skrive til denne char. STUDENT 60: Ja. JASON HIRSCHHORN: Hvad tror folk? STUDENT 62: Det er indviklede. JASON HIRSCHHORN: OK. Lad os trække det ud. Så denne gang, jeg har tænkt mig at trække denne i rød på stakken her, og så vi vil have - ooh! Undskyld. Så denne gang har vi noget, der hedder buffer, og det er på stakken. Ret? Og vi gemmer i det en, i første omgang. Så har vi vores opfordring til fread. Hvad fread gør, er det tager en byte fra vores fil og sætter det et eller andet sted. Det sætter det i uanset ting peger på. Nå, før vi havde denne adresse - 0x0. Nu hvad adresse har vi? STUDENT 63: Whatever adresse buffer. JASON HIRSCHHORN: Whatever adresse buffer. Det er sandsynligvis vil være noget lignende. Sandsynligvis kommer til at starte med en b og en f, og derefter har seks andre hexadecimale cifre. Betyder ikke noget. Nogle adresse. Og vi passerer denne adresse i. Og vi kommer til at sætte vores ene byte ting på denne adresse. Så vi kommer til at sætte vores ene byte ting herinde. Og så vil vi skrive fra hvad der er nogensinde herinde. Er der nogen har nogen spørgsmål om det? Hvem tror denne kode vil arbejde? Løft din hånd, hvis du tror denne kode vil arbejde. Du er nødt til at tage et standpunkt. Og hvem tror denne kode vil ikke arbejde? Løft din hånd. Alle andre bør være hæve deres hånd. OK. Michael, hvor står du? MICHAEL: Jeg kan ikke afgøre. Slags i midten. JASON HIRSCHHORN: Du er i midten. Vælg en. MICHAEL: Jeg har tro og siger, at det vil virke. JASON HIRSCHHORN: OK. Du har tro og sige det virker? Hvad er der sket? [indskyde STEMMER] JASON HIRSCHHORN: Ingen seg fejl. Hvordan kan vi kontrollere, om to ting er lige? To filer er ens. STUDENT 64: Diff. JASON HIRSCHHORN: Diff. Diff checks for forskellene mellem to filer, og hvis det returnerer ingenting, de er identiske. Og hvis vi åbner op, får vi vores fil. Så det var den rigtige løsning. Lad os se tilbage på det en gang mere. Vi har faktisk ikke engang nødt til at initialisere den. Det ville nok se lidt renere, hvis du ikke har bragt noget tilfældigt derinde. Pointen er, du behov for at skabe nogle plads til at gemme noget fra fread og tage noget ud af fwrite. Og at ting skulle være enten en lokal variabel på stakken - du kunne have malloc'd noget plads. Så vi kunne faktisk have skriftlig malloc her, og der ville have fungeret. Og så ville vi have været opbevaring vores ting et sted på bunke. Men det er faktisk, sandsynligvis, den mest elegante løsning. Bare skabe noget plads på stakken for disse ting til at gå. Jeg ville have to andre kommentarer. Hvis du skulle tage tur i dette, og derefter få scoret på dette, mine kommentarer ville være som følger. Disse 1 er her, for mig, se ligesom magiske tal. Denne 1, i form af fread, giver mening. Det er antallet af ting, at læse eller skrive. Men denne ene lige her burde sandsynligvis være noget andet. Så hvad er en løsning? STUDENT 65: størrelse byte. JASON HIRSCHHORN: Ligesom det? STUDENT 65: størrelse char. JASON HIRSCHHORN: Størrelse af char. Ja, byte er ikke en type. Så størrelsen af ​​char værker. Vi kunne have på toppen af vores kode, # definerede det. Kaldet noget BYTE og det er virkelig en char. Faktisk en endnu bedre tilgang kunne have været det - uint. Nogen der ved hvad det er? Undskyld. Jeg har det baglæns. Vent, nej. Hvilken vej går det hen? Nogen der ved hvad det er? Ja. STUDENT 67: formodes at hjælpe standardisere på tværs af systemer ting, har - ligesom unsigned heltal der har 8 byte? JASON HIRSCHHORN: Det er helt rigtigt. På forskellige maskiner, størrelsen af ​​en char - normalt ikke en char. Bogstaver er normalt en byte. Men størrelsen af ​​andre datatyper er forskellige størrelser på en 32-bit maskine versus en 64-bit maskine. En uint8_t er altid 8 bit - altid en byte. Og jeg har brug for at medtage, at standard int header fil. Så nu, dette ville have sandsynligvis været den bedste måde at skrive denne kode. Så jeg slippe af med de magiske tal. Og jeg har også en mere logisk skrive til buffer. Det er ikke blot en char, er det en byte, hvilket er, hvad vi forventer det at være. Og heroppe, vi har faktisk været lidt mere robust. Vi ikke kalde det en char, som - måske, hvem ved - kunne være en anden størrelse på forskellige maskiner. Vi faktisk siger det er præcis en byte, altid, uanset hvad. Og hvis vi ser her, gør vi cp. Uh-oh. Hvad er der sket? STUDENT 68: Det kunne være tændt. JASON HIRSCHHORN: Hvad? STUDENT 69: Er det? STUDENT 70: Du har ikke definere det som en type. STUDENT 71: men det bør skal defineres i standarden. STUDENT 72: Hvad sker der? STUDENT 73: Bør definere være alle hætter? JASON HIRSCHHORN: Så det er ikke # define. Faktisk, i dette tilfælde, er jeg vil bruge typedef. Fordi vi bruger det som en type på ét sted. Så i dette tilfælde, vi rent faktisk ønsker at typedef ligesom vi udskriver en ny type byte, og det er det væsentlige, dette. Det er en smule anderledes end # define. Og nu, vores kode fungerer perfekt. Så igen, # define tager noget, erstatter det overalt med den anden ting. Det er bare en makro - stenografi at slippe af magiske tal. Men i dette tilfælde, fordi vi er bruge det som en type - lige her - for at dette skal fungere, er vi nødt at typedef hvad byte er. Og vi definerer det lige her. Det er ikke en struct, det er faktisk bare en usigneret heltal. Det er én byte lang. Denne kode vil være tilgængelig online, og du bør alle have det lige nu. Så vi har - perfekt - 13 minutter tilbage til at gå løbet problem sæt 5. Jeg ønsker at gå gennem copy.c sammen, og så vil vi tale kort om de andre dele af problemet indstillet. Så lad mig trække op copy.c. Og cool ting er, vi har faktisk allerede skrevet en masse af denne kode. Den kode, vi skrev bogstaveligt talt bare kom ud af her, da jeg var skriver dette på min egen. Men dette er copy.c, danner grundlaget for de to første dele af problemet indstillet til whodunit.c, som du nødt til at skrive, og resize.c. Recover.c, som er den tredje og sidste del af problemet sæt, er ikke baseret ud af denne fil. Du vil få brug for at skrive, at filen vi giver dig en skabelon til at fil, men det har intet at gøre med copy.c. Men fordi copy.c er grundlaget for de to første dele, vi kommer til at gå igennem det nu, så du har en god fornemmelse af, hvad det gør. Og bemærkninger giver noget af det væk. Vi har allerede skrevet nogle af dette. Først gør vi sikker vi får tre argumenter. Næste, vi huske filnavnet. Så vi sprunget over dette trin, når vi kodet vores ting - når vores cp. Men her er de gør det en smule renere. De kontrollerer, at begge filer er gode, i Ud over at åbne dem. Vi skrev alle denne kode lige nu, så jeg er ikke kommer til at dvæle ved denne kode. Næste er nogle ting, der er specifikke for de typer af filer, vi bruger, som er bitmap-filer. Bitmap-filer har nogle metadata forbundet med dem. Så de første par bytes fortælle dig om filen. De er ikke farver pixel i billedet. De fortæller dig om filen. Og hvis du læser igennem problemet sæt, vil du have meget mere information om, hvilke typer af metadata strukturer indgår med bitmaps. Men det er derfor vi har denne første sæt - denne kode lige her. Vi læser metadata - to stykker af metadata - filen header og info header. Og vi tjekker nogle dele af den til sørg for at det er en sand bitmap-fil før du fortsætter. Og igen, disse er detaljer, som vi behøver ikke at gå ind i nu. Hvis du læser gennem problemet sæt, du vil forstå disse. Lang historie kort, er disse bare siger, dette er en bitmap-fil, og bekræfter, at. Næste, vi skriver dem til ud-fil. Vi ser, at her. Vi skriver til den ud pointer. Næste, vi bestemme polstring. Så igen, som er særegne med en bitmap-fil, nogle linjer omfatter polstring i slutningen. Og hvis du læser igennem problemet sæt, du vil lære mere om polstring. Dette er formlen for at finde polstring. Vigtigt at huske på - når du ændrer størrelsen af ​​en bitmap fil, polstring ændringer. Når du ændrer størrelsen på en fil, polstring ændringer. Det er aldrig kommer til at være større end 3 - det vil være 0 til 3 inklusive. Men når du ændrer størrelsen på noget, polstring ændringer. Hvis jeg kun har én pixel i den pågældende række, jeg brug for tre bytes af polstring, fordi hver række skal være et multiplum af fire bytes længe i en bitmap-fil. Men hvis jeg fordoble det, at gå fra én pixel til to pixel, som hver, lad os sige, er en byte, så jeg har brug for to bytes af polstring til at gøre der er lig med fire. Så når jeg ændre størrelsen på noget, Jeg har brug for at ændre beløbet polstring jeg har. Giver det mening for alle? Dernæst vi gentage over hver række, eller gennem alle rækker. Og så skal vi gentage gennem hver kolonne i hver række. Vi behandler denne bitmap ligesom et gitter, ligesom vi har behandlet bestyrelsen i 15.. Ligesom vi behandlet murstenene når vi trykt dem på skærmen. Et gitter af rækker og kolonner. Så - vi oplevede dette. Vi har faktisk lige kodet dette. Vi skabte nogle midlertidige opbevaring. Vi læser i der, og derefter vi skriver det ud. Dette er præcis, hvad vi lige gjorde. Dernæst fordi jeg sagde hver linje ender på polstring, vi springe over, at polstring - den gamle polstring. Og så tilføjer vi det tilbage. I dette tilfælde, vi skaber nøjagtig den samme fil. Vi er bare kopiere det. Så denne linje er lidt fjollet. Vi kunne bogstaveligt talt bare sætte polstring i. Men hvis du ændrer størrelsen af ​​filen, Vil du stadig denne linie? Så hvis vi ændre størrelsen på en fil, gør vi stadig ønsker at springe over den gamle polstring? STUDENT 74: Ja. JASON HIRSCHHORN: Så vi gør. Fordi dette, igen, tilbud med kildefilen. Vi er ligeglade om polstring fra kildefilen. Vi ønsker at gå til den næste linje. Men vi har ikke bare sat tilbage den gamle værdi af polstring. Vi er nødt til at sætte tilbage ny mængde af polstring. Så når vi er ved at ændre størrelsen på en fil, vi stadig ønsker at springe over polstring i den gamle fil - hvad vi læser fra. Men hvad vi skriver til, vi kommer til brug for at sætte tilbage nogle forskellige Antallet af polstring, vi har bestemt. Ja. STUDENT 75: Rækkefølgen af ​​de to linier betyder ikke noget, right? Fordi du håndterer forskellige filer. JASON HIRSCHHORN: Præcis. Rækkefølgen af ​​disse to linjer betyder ikke noget. Vi skriver denne linje. Det er her for filen vi skriver til. Det er vigtigt, så vi får rigtige mængde af polstring. Dette har at beskæftige sig med i filen. Vi ønsker at springe til højre over polstring. Vi ønsker ikke at læse - hvis vi læser en byte ad gangen, vi ligeglad disse Udfyldningsbytes. Vi ønsker at flytte til den næste linje. Endelig ligesom Lucy gav for os, vi lukke filer og returnere 0. Så dette er copy.c. Og vi faktisk skrev - vi brugte det meste af sektion skriver dette væsentlige. Du har lavet dette. Så forhåbentlig har du en god fornemmelse af, hvad der foregår her. Den store forskel, helt ærligt, er blot denne første del, der omhandler særegenheder bitmap-filer. Så jeg har da min næste dias, hvad skal vi gøre? Nå, lad os tænke over krimi. Og for nogen, der læser problemet indstillet, hvad gør vi nødt til at gøre i krimi? Simply. Aleja. Aleja: Kan du tegne den del af hver pixel, der betegner rød. Og så - slags? JASON HIRSCHHORN: OK. Så tag del af hver pixel, der betegner rød. Det er tæt på, men ikke det hele. STUDENT 76: Tja, der er forskellige måder at gøre det. JASON HIRSCHHORN: OK. Giv mig én måde. STUDENT 76: Tag alle de røde, og derefter understrege blå og grøn. JASON HIRSCHHORN: OK. Så givet begge disse måder - det lyder som vi giver det en pixel, er det har en rød, blå og grøn plan. Vi ønsker at ændre de relative niveauer af rød, blå og grøn, afhængigt på denne pixel. Hvor i denne kode, bør vi ændre den relative rød, blå og grøn niveauer af en given pixel. Efter at vi har læst det - før vi skriver det? Giv mig den linje nummer. FLERE STUDERENDE: 83. JASON HIRSCHHORN: 83. Så lige her. For mordmysterium den kode, du har brug for at write bør alle gå lige der. Og det er det eneste kode du nødt til at skrive. Fordi, ligesom vi hørte, alt du behøver at gøre, er at ændre disse relative blå, røde og grønne niveauer fra hver pixel. Du har læst det i, og nu er du kommer til at skrive det ud. Hvordan får jeg - hvis jeg har denne ting kaldet triple, lige her, og det er af skriv RGBTRIPLE - godt, hvis vi kiggede i bmp.h, hvad der er RGBTRIPLE? STUDENT 77: Det er en struct. JASON HIRSCHHORN: RGBTRIPLE er en struct. Vi ser, at lige hernede. Og så hvis jeg ønskede at få adgang, siger, rød niveau af struct, hvordan gør jeg adgang til røde niveau af denne struct? [KLASSE mumler] STUDENT 78: RGBTRIPLE.rgbtred? JASON HIRSCHHORN: Er det korrekt? STUDENT 79: Det bør være tredobbelt dot, i stedet for RGBTRIPLE prik? JASON HIRSCHHORN: Triple. Triple er den lokale variabel, så her, der er ingen henvisninger her. Så vi bare bruge dot notation. Dette vil give mig niveauet af rød. Hvis jeg ønsker at ændre det, jeg bare indstille det lig med noget andet. Så igen, denne linje kode adgange denne variabel inde i denne struct, og vi kan indstille den til noget nyt. Så for mordmysterium, igen, det er, i det væsentlige, hvad vi skal gøre. Meget enkel. Bare ændre nogle relative niveauer, og det er her, at koden går. Ændre størrelse, på den anden side, er en smule tricky. Faktisk størrelsesfeltet er sandsynligvis vanskeligste del af dette problem indstillet. Vi har tre minutter til at gå over det. Men igen, vi har allerede skrevet det meste af denne kode, så vi bør være temmelig bekendt. Hvad er nogle ting, vi ønsker at gøre i ændre størrelse, hvis du har læst i løbet af problem indstillet? Hvis du giver mig dem, vi kan tale om dem. Hvad er nogle ting, vi ønsker at gøre? STUDENT 80: Lodret - så er du nødt til vandret ændre størrelse på det, men lodret resize det så godt? JASON HIRSCHHORN: Så hvis vi er givet et pixel, og vi ønsker at ændre størrelsen på det ved en faktor to, det nu skal være skaleres horisontalt og skaleres lodret. Giver det mening? Ja. Så det er nok det største udfordring. Og vi vil tale om dette i et sek. Ja. STUDENT 81: Den måde, jeg tænkte på det var du havde brug for print det ud - JASON HIRSCHHORN: Vent. Må ikke fortælle os, hvad du gjorde. Vi kommer til at tale i logik. STUDENT 81: OK. Hvad var spørgsmålet? JASON HIRSCHHORN: Du skal bare hævede hånden. Der var ingen spørgsmål. Lad mig præsentere den. Lad mig blot diskutere dette kort. Så vi har en pixel, vi ønsker at kopiere det, både horisontalt og lodret. Så ideelt set, hvad vi gør her er, at vi læse i vores pixel, vi skriver det men mange gange. Men så har vi vores trick her, fordi så ønsker vi at springe til næste linje og skrive det på begyndelsen af ​​næste linje. Så hvis vi ønsker at kopiere både vandret og lodret, hvad er en god måde at gøre det - et godt selv at gøre det? Så vi behøver ikke hele tiden at søge omkring vores fil for at placere ting. Dette spørgsmål har måske ikke gav mening, men jeg tror en besvare det vil hjælpe. STUDENT 82: Opret en array? JASON HIRSCHHORN: Så lad os tænke for hver fil som en række. Lad os tænke i rækker. Hvis vi har vores første række fra vores lille billede, kan vi gøre denne række i en stor række af et stort billede, og derefter replikere rækken imidlertid mange gange det skal blive gentaget, snarere end at gå pixel for pixel, som får forvirrende, når beskæftiger sig med filer. Fordi hvis vi havde - Jeg kører ud af rummet. Hvis dette er vores fil, og vi har at én pixel der, og vi ønsker at sætte det lige der, vi stadig har nogle ting at det er nødvendigt at gå over der, når vi er skrive og skabe vores nye fil - vores fil, der er dobbelt så stor. Men det er virkelig svært med fil-funktioner at springe rundt til nye linjer lignende, og derefter gå tilbage her og sætte ting derinde. Det er næsten umuligt at gøre noget gerne, hvis det giver mening. Så hvis vi tænker i rækker, kan vi tage vores række, og derefter sætte det - replikere rækker vertikalt. Og det er, hvordan vi behandler resizing lodret i stedet for vandret. Det var slags hurtig, og lidt forvirrende. Desværre vores tid er op. Jeg vil stå uden for de af jer, her der har spørgsmål om problem sæt, herunder komme sig. Så lad os udsætte for nu. Og igen, hvis du har spørgsmål, vi kan chatte udenfor.