[MUSIC SPILLE] DAVID J. MALAN: Dette er som en førsteårsstudent seminar i dag. OK. Så veldig regnfull ut. Dette har en tendens til å skje på onsdager, men desto mer mulighet for spørsmål i dag. Så la oss begynne faktisk med filmen i bare et øyeblikk. Men vi begynner grandly som alltid. Dette er CS50, og denne er i slutten av uke 4. Så hvis du noen gang har sett TV eller en film, hvor det er noen dataeksperter og politiet eller FBI, eller noen byrå prøver å fange noen motstander, vel, har du sikkert hørt uttrykket "forbedre" der som tekniker eller annen måte zoomer magisk i uendelig mye til å se de kriminelle identitet eller registreringsnummeret i og med shimmer et speil eller glimt av noens øyne. Så ja, la oss ta en titt på noen få slike scener fra Hollywood. [VIDEO PLAYBACK] -OK, Nå la oss få en god titt på deg. -Hold den. Kjør det tilbake. -Vent et minutt. Gå til høyre. -Det, Fryse det. -Full skjerm. -OK, Fryse det. -Tighten Opp på det, vil du? -Vector Inn på det fyr ved bakhjulet. Zoome inn her på dette stedet. -Med Riktig utstyr, bildet kan bli utvidet og skjerpet. -Hva er det? -Det Er en forbedring program. -Kan Du klare det opp noe? -Jeg Vet ikke. La oss forbedre det. -Enhance Delen A6. -Jeg Forbedret detalj, og-- Jeg tror det er nok til å forbedre, slipper den til skjermen min. -Jeg Forbedret refleksjonen i øyet. -La Oss kjøre dette gjennom video ekstrautstyr. -Edgar, Kan du forbedre dette? -Vent litt. -Jeg Har jobbet med denne refleksjonen. -noen Refleksjon. Lysreflekterende. -Det Er en refleksjon av mannens ansikt. -Den Refleksjon. -Det Er en refleksjon. Zoome inn på speilet. -Du Kan se en refleksjon. -Kan Du forbedre bildet herfra? -Kan Du forbedre ham akkurat her? -Kan Du forbedre det? Kan du forbedre det? -Kan Vi forbedre dette? -Kan Du forbedre det? -Hold På et sekund, jeg vil forbedre. Zoome inn på døren. -Times 10. Zoome. -Flytte inn. -Mer. -Wait, Stopp. Stop. -Pause Det. -Rotate Oss 75 grader rundt den vertikale, takk. Stop. Gå tilbake til den delen om døren igjen. -Fikk Et bilde enhancer som kan bitmap? -Hei, Kanskje vi kan bruke Pradeep Sen metode for å se inn vinduene. -Dette Programvare er state of the art. -The Egenverdi er av. -Med Den rette Kombinasjonen av algorithm-- -Han Er tatt eliminering algoritmer til det neste nivå, og jeg kan bruke dem til forbedre dette fotografiet. -Lock På og forstørre z-aksen. -Enhance. -Enhance. -Enhance. -Freeze Og forbedre. [END PLAYBACK] DAVID J. MALAN: Greit, så alle av dem er faktisk ord. De er bare satt sammen i en måten det er faktisk ikke fornuftig. Og faktisk, CS50 og kurs som det tendens til å ødelegge mye av TV og filmer for deg. Fordi når disse dataeksperter er lire av vilkår og si fancy ting som egenvektorer, og z-aksen, og hvilket som helst antall annen faktisk mer tekniske termer, de er egentlig bare strenger ord sammen alt for ofte. Er at en av våre håp er at, som en bivirkning av å ta kurs som dette, vil flere mennesker i verden faktisk være i stand til å veie inn og bare aldri så litt påvirke kvaliteten og nøyaktigheten av disse filmene? Faktisk, la oss ta en titt på virkeligheten. Så her er de ansatte bilde Mary, en av våre undervisnings medmennesker. Og antar hun er mistenkt for noe. Og likevel, det er et glimt av noen del av bevis i øyet, eller ved refleksjon av hennes briller. Vel, hvis vi gjør akkurat som filmene foreslår, hvor vi zoome og "styrke", dette er hvor mye informasjon er i Marias ansikt når du tar et bilde med det opprinnelige oppløsningen. Og, faktisk, kan du se disse prikkene. Og dette er hva er kalt piksler, P-I-X-E-L-S, som er bare en firkantet typisk som er en prikk som komponerer et bilde. Og tilbake i dag, og faktisk enda i dag med noen av dagens LED-TVer eller LCD TV-er, hvis du har en i rommet ditt eller hjemme, hvis du går opp super nær den, og spesielt hvis det er en litt eldre TV, du kan sikkert også se disse prikkene og det er det å komponere et bilde. Og det er ikke mer Informasjon om enn dette. Vi kunne "styrke", i den forstand glatting tingene om og liksom dedusere slags, liksom hva Fargen skal være ved siden av Mary øye slik at det er faktisk ikke så kornete. Men hvis jeg fortsetter å zoome inn, er det er skurken i hennes øyne. Sånn er alle informasjonen vi har. Du kan ikke opprette informasjon ut av ingenting. Det er bare en begrenset antall bits der. Så i Problem Set 4, hvor du har en mulighet å spille med denne slags verden. I Problem Set fire, vil du utforske verden av grafikk og dataanalyse, og faktisk skrive kode som gjenoppretter tapte bilder. Du skal skrive kode som manipulerer eksisterende bilder og til slutt forstår hva som er skjer under panseret. Og, viser det seg, det er faktisk ikke så komplisert. For eksempel, hvis vi ønsket å representerer et smilefjes der med disse sorte piksler, eller disse sorte prikker, vel, vi kan bare representere dem som virkelig et bitmap. Og hvis du noen gang hadde hørt at uttrykk bitmap, kanskje det nå begynner å lage en litt mer fornuftig i dag. Vi vet allerede hva litt er. Det er 0 eller 1. Og et kart er bare noe som et stykke papir som gir deg retninger og har kanskje et rutenett av x- og y-koordinater. Så her er et bitmap. Det er et kart over biter der en en tilsynelatende kommer til å representere en hvit piksel, og en 0 kommer til å representere en svart piksel. Men vi kan sikkert snu det rundt. Det spiller egentlig ingen rolle så lenge vi er konsekvente. Og her er hvordan, i binary-- inne av datamaskinens minne, eller inne av en fil på hard drive-- kan du lagre den enkleste av smiley face bilder. Men hva er vi, selvfølgelig, mangler i dette bildet? Farge, ikke sant? Det er en åpenbar neste trinn eller ekstrautstyr for å forbedre denne med farge. Så dessverre med bare en enkelt bit, 0 eller 1, kan vi representere farge. Det kan være rød eller blå, eller svart eller hvit, eller grønn, eller rosa, eller andre par av farger. Men for enkelhets skyld, vil vi bare anta svart og hvitt. Så hva logisk trenger vi hvis vi ønsker å implementere farge i et bilde? Hva har vi å gjøre? Som hvis den begrensende faktor her er at med en bit du kan bare representerer to tilstander, 0 eller 1, hvit eller svart, hva ønsker du å gjøre? Målgruppe: Mer data. DAVID J. MALAN: Flere biter, Yeah mer data, flere biter. Og, ja, det er akkurat hvordan fargebilder er representert. I stedet for å bruke en enkelt bit, en 0 eller 1 for hver piksel, hver prikk, du bare bruke flere. Kanskje bruke åtte, kanskje, oftere bruke 24, og faktisk i oppgavesettet 4, vil du spille med en fil format som bruker 24 bits typisk. Men de fleste av dere er sikkert kjent med JPEG. Hvis du noensinne har tatt et bilde på telefonen, eller lastes opp eller sett noe på Facebook eller Flickr, et tall av fotobaserte nettsteder, har du sikkert sett et JPEG-bilde før. Og det viser seg, dette er filen format vi kommer til å bruke i PSet 4, hvor du kommer til å må gjenopprette bilder som jeg har slettet ved et uhell fra en ødelagte minnekort i kameraet, Hvis du vil. Og det viser seg at selv om JPEG er ganske sophisticated-- det er mye mer sofistikert enn de svarte og hvite prikker vi så en stund siden, fordi det er faktisk fancy algoritmer som brukes til å komprimere en JPEG, så at du kan ha en veldig fin, bildekvalitet, men bruker relativt få biter. Og vi vil komme tilbake til komprimering før lenge. Det viser seg at den første tre bytes i en JPEG image-- uansett hva du har tatt et bilde of-- er verdiene 255, 216, 255. Med andre ord, hvis man bare se at mønster av biter, her representert som tre byte, eller 24 biter totalt, med høy sannsynlighet kan du antyde at du ser på det på denne tre første byte av en JPEG. Og dette er hva som er kjent som signaturen til en JPEG. Mye av filformater der ute har en tendens til å starte med visse mønstre av 0'er og 1'ere, slik at Windows og Mac OS, og iOS, og Android vet hva slags fil de er, i tillegg til den såkalte file utvidelse som mange filer har. Hvis du har .jpg, det er en annen ledetråd til datamaskinen. Så la oss nå se på dette litt mer teknisk. Vi kjenner desimal Systemet er 0 til 9. Vi vet er binær 0 og en. Og hvis du tenker tilbake til PSet 0, hadde vi du kjempe med, for en liten bit, noe kalt heksadesimal, der du har 16 siffer, i stedet for 10 eller i stedet for to. Og disse tallene, etter konvensjonen, er 0 til 9 og deretter en gjennom f, hvor f representerer det desimaltall, akkurat som en rask sunn fornuft sjekk? Så, 15. Og en må representere 10, bare ved natur bestilling som jeg har gitt. Det er bare en vilkårlig konvensjon, men det er ganske standard. Så hvis vi ser på dette mønsteret tre bytes-- la oss bare begynne å se på det i en måte som er forenlig med hvordan dataforskere generelt se på og tenke på filer. Du kan sikkert tenke på filer i 0s og 1s, og desimal, men i virkeligheten, vi pleier å bruke binær eller mer typisk hexadecimal-- tilbake fra PSet 0. Så la meg foreslå at 255, 216, og 255 er nettopp disse mønstrene av 0'er og 1'ere. Og du kan sjekke dette hvis du ønsker å gjøre regnestykket fra uke 0. Men for nå, bare anta at dette er faktisk riktig. Jeg har nettopp omskrevet tre desimaler tall som tre binære verdier. Nå hva jeg skal gjøre er bare legge litt tomrom, bare for lesbarhet skyld. Og legg merke til, jeg skal bare å flytte ting fra hverandre. Så før, etter, før, etter. Jeg gjør ikke noe interessant andre enn bare å spre ting ut så at innkalling hvert sett av åtte bits er nå to sett av fire bits. Dette er nyttig fordi heksadesimal er spesielt fasjonable fordi hver heksadesimalt siffer fra 0 til f, eller mer spesifikt fra 0 til 15, kan representeres med nøyaktig fire biter. Med andre ord, i heksadesimale hvis du ønsker å representere en 0, det er bare 0000, fire nuller. Og hvis du ønsker å representere 15, Det er 1111, noe som er fire bits. Og hvis du gjør regnestykket, hvis dette er de sted, Dette er 16s sted, som kommer til å gi you-- snarere som kommer to-- sorry, i binær, som kommer til å gi deg 15, som sted, Toere sted, firere og åttere sted. Så la meg foreslå at det sett med fire biter til venstre er hva vi skal kalle f. Det er det største tallet du kan representere med fire biter. Og vi allerede kjenner fra heksadesimale, f er den største siffer i heksadesimale. Vi har fått en annen f der, to mer enn det. Og for nå, bare ta på tro at jeg har gjort regnestykket riktig og at den venstre halvdelen av disse bitene, 1101, er det samme som d i heksadesimal. Og høyre hånd, 1000, er bare åtte. Og at man er lett å se, ikke sant? Den 8 represents-- er riktig under som åttere sted. Så vi har en i åttere kolonne og ingenting i firere, toere eller de. Så nå mer konvensjonelt, mennesker har en tendens å skrive heksadesimalsifre som dette, du bare squish dem sammen, og deretter du prefiks dem med 0x. Det betyr ingenting annet enn en visuell ledetråd til en human-- her kommer en heksadesimale value-- fordi det ellers kanskje ikke ville være opplagt. Som er å si, til slutt, at mønsteret av nuller og enere, eller mønsteret av heksadesimale Sifrene equivalently at du er kommer til å begynne å lete etter i oppgave Set fire er dette-- Og problemet Set fire spec vil gå deg gjennom dette i mer detail-- men innser som slags uforståelige som Dette kan se ut ved første øyekast, du kommer til å begynne å se dette mye. Og i virkeligheten, selv i GDB, den debugger vi introdusert på mandag og Dan introduserer i PSet tre, kommer å ofte vise deg heksadesimale verdier bare fordi de har en tendens til å være mer konvensjonell enn desimal eller binær i verden av datamaskiner. Nå la oss sette dette i sammenheng. Mange av dere husker kanskje dette bildet her, som kom fra hva? Vista, så selv tidligere enn at Windows XP gjorde dette debut. Så dette er et vakkert landskap. Og faktisk, hvis du rote rundt online-- Jeg tror det er en Wikipedia-artikkel, hvor noen veldig utrolig gikk ut fant dette stedet i verden å sette opp hans eller hennes kamera nøyaktig riktig sted-- og dette i dag ser like-- men det er nøyaktig den samme innstillingen. Dette bildet, men er i en fil format kalt bitmap, b-m-p. Og vi kommer til å ta en super raskt blikk på hva det betyr. Men bitmap er bare en annen måte å representerer bildene fortsatt bruker piksler i 0'er og 1'ere, til slutt. Men på raskt blikk, har det en mer interessant signatur ved begynnelsen av filen. Det er ikke bare tre bytes, snarere er det en hel haug med mønstre av bytes som har bestemt mening. For eksempel, et sted i første byte med et bitmap bilde kommer til å være på størrelse med den bilde, bredden av bildet, høyden av bildet, så nyttige metadata, hvis du vil. Nyttig informasjon som Photoshop eller grafikk program du bruker kan faktisk bryr seg om. Så mer om dette i Problem Set fire, men dette er bare å si at på slutten av dagen alle filformatene du har brukt for years-- Microsoft Word-filer, Tall filer, Excel-filer, en rekke filformater som kanskje har noen kjent filtype er bare 0'er og 1'ere under panseret. Og mennesker har bestemt seg hva konvensjonene er, hva mønstre av 0'er og 1'ere representerer en Word-fil kontra en Excel-fil, versus en rekke andre filformater. Så i PSet 4, vil du ha en muligheten til å spille med det. Men hva betyr det å ha en struct. Dette er faktisk en fin naturlig overgang nå til C, som bare har et par ekstra funksjoner som vi har ikke sett på ennå. Det er en ganske lite språk, og en av de fine funksjoner om C er en struct. For eksempel, hvis du ønsket å represent-- la oss si at du ønsket å ha en variabel som representerer en student i noen program. Kanskje du skulle skrive et kurs registrering program, eller kjernehandle verktøyet, eller noe sånt. Hva er biter av data relatert til en student som kommer til tankene? Som en student er representert med hvilke verdier? Yeah? Du har et navn som en student. Hva andre gjør en typisk student ha? PUBLIKUM: [uhørbart] DAVID J. MALAN: Så, beklager. PUBLIKUM: Age. DAVID J. MALAN: En alder eller bursdag equivalently, Jepp. Hva annet? PUBLIKUM: ID-nummer? DAVID J. MALAN: Så et ID-nummer, kanskje et telefonnummer, kanskje en sovesal, eller hus, eller høyskole, eller noe sånt. Ethvert antall biter av data som du kan ha i kontaktlisten er hva som kan definere en student. Så hvis vi ønsket å gjøre dette, i kode, vi kan gjøre noe enkelt som dette. Vi kan ha et program slik at har la oss si, int main (void). Og hvis jeg ønsker å representere en student jeg kanskje har, for eksempel, en streng som heter navn som student, en streng kalt dorm for at student, kanskje en int kalt ID for at studenten. Og fordi jeg bruker string, jeg trenger å gå tilbake og sette opp CS50.h. Kanskje jeg kommer til å trenge stdio.h. Så la meg preemptively gjør de, og jeg er kommer til å kalle dette student.c for nå og lagre dette. Og nå kan jeg gjøre noe med disse variablene. Og vi skal bare skrive det som en kommentar i pseudo-kode, fordi det ikke er interessant hva vi gjør for nå. OK, slik at dette er et program som liksom lagrer en student. Hva ønsker jeg å gjøre hvis jeg ønsker å lagre to studenter? Så mitt første instinkt kommer å være all right, vent litt, hvis jeg har en annen student hvorfor ikke jeg bare gjøre string navn 2, string dorm 2, int ID2. Og vi har gjort borte ned denne veien før og hva som var vår løsning på hva som virker å være en slags hackish kopiere lime jobb her? PUBLIKUM: En rekke. DAVID J. MALAN: Ja, vi kunne bruke en matrise. Høyre dette svært raskt blir uhåndterlig. Du må sortere av vilkårlig begynne å navngi alle disse variablene. Og du som menneske, må holde spor som OK NAME2 tilsvarer med Dorm2 korresponderer med ID2. Det blir bare et rot. Så det er mye enklere, husker fra et par uker siden, å bare måtte kalles strengnavn og kanskje gi oss tre av disse. Og så kanskje vi har string sovesaler og har tre av disse, eller med en konstant, int IDer og har tre av dem. Men selv nå dette føles litt slurvete, ikke sant. Vi snakker om studenter og ennå Jeg er virkelig bolig på lavt nivå gjennomføring detaljer. Studenten er et navn og en sovesal og ID. Hvorfor kan jeg ikke bare erklære en variabel kalt student og kalle det s. Og hvis jeg vil ha en annen student, hvorfor ikke jeg bare kalle det t. Eller hvis jeg vil ha en hel haug av studenter, hvorfor gjør jeg ikke bare si at jeg har en hel klasse av studenter, og det er tre av dem. Med andre ord, hvorfor kan ikke jeg komme opp med min egen datatype, kalt Studenter, innsiden av noe som er et navn, er en ID, er en dorm, er en rekke andre felter. Og det viser seg at du kan gjøre akkurat det. Så C har denne funksjonen kalles struct. Det er et språk funksjon som tillater oss å gjøre akkurat dette. Jeg kommer til å gå videre og åpne opp structs.h hvor vi kommer til å se følgende definisjon av en student. Det viser seg - og dette er enda enklere enn den som involverer en ID et øyeblikk siden. Hvis du ønsker å komme opp med din hjemmelagde datatype, og i tillegg til int og røye og flyte og alle disse andre som eksisterer, du kan gjøre det ved å bokstavelig talt skriver typedef struct, deretter noen klammeparentes, innsiden av som du liste de variablene du vil forbinder med denne nye skikken data skriver ut et navn og en sovesal, og deretter etter klammeparentes du gi et navn til den nye datatype. Så, for eksempel, student. Og hva er fint om dette nå er at hvis vi ser på den tilsvarende koden, konvensjonen, første av alt, er å sette dette i en fil som heter noe dot h, en header fil, som vi ikke har begynte å bruke oss selv for mye. Men vi kommer til å starte bruker ganske mye nå. Og hva vi kan gjøre med dette, til slutt, i disse få linjer med kode er erklære akkurat det datatype, en student. Og nå kan vi bruke den. Jeg skal nå gå inn en fil som heter structs1.c. Og la oss ta en titt på en noen kjennetegn her. Så ting her oppe er stort sett kjent, og vi vil komme tilbake til hva som ikke er kjent i bare et øyeblikk. Dette er selvfølgelig inkludert min egen header fil, som er ny i tillegg, bortsett PSet tre der, husker, har vi helpers.h. Så du kanskje husker # include helpers.h. Hvorfor selv bruker jeg sitater i stedet for vinklede brak? Da velger jeg mellom dem? Nesten alltid synes jeg å bruke vinklede parentes. Og så, plutselig på seks Jeg bruker anførselstegn. Hvorfor kan det være? Yeah? PUBLIKUM: [uhørbart] DAVID J. MALAN: Det er en faktisk, hva? PUBLIKUM: Det er i IDE. DAVID J. MALAN: Ja, det er i min faktiske IDE. Og la oss ikke dvele ved IDE, fordi det er bare et verktøy som jeg bruker. Det er i min nåværende katalog, spesielt. Så structs.h er min egen fil ikke installert i IDE, i selve operativsystemet, snarere er det i min nåværende katalog. Så konvensjonen er hvis du vil å inkludere din egen header fil, du bare bruke anførselstegn. Hva kaller vi denne tingen i linje 8, generelt sett? Dette er hva? #define noe. Dette representerer konstanter, ikke sant? Hvis du ønsker å ha en verdi i programmet at du bruker en hel haug med ganger, er det god konvensjon å faktor det ut, erklære den, med hash symbol definere, da, etter konvensjonen, i alt store bokstaver word-- om det ikke strengt nødvendig, men det er menneskelig konvensjonen å kapital konstanter slik at de hopper ut på deg visually-- plass og da verdien du ønsker å være tilsvarende som konstant navn. Ingen semikolon, men du bare følger det mønsteret der. Så hva skal jeg gjøre i dette selve koden. Så la oss ta en titt på hovedprogrammet her. I linje 12 fordi jeg har tatt structs.h, Jeg har nå magisk på min disposisjon en ny datatype. Jeg har ikke bare har tilgang til int, og røye, og dupp, og streng, og blått og andre. Jeg har nå tilgang til en student datatype. Så i linje 12, jeg kombinere to ideas-- man en tilpasset datatype og to, ved hjelp av en matrise. Og så i dette programmet hvis Jeg vil faktisk støtte tre forskjellige studenter i mitt program, jeg kan bare si gi meg en variabel kalt studenter, som hver er av typen studenter, som er min egendefinert datatype. Og spesielt gi meg tre av dem i min array. Så nå hva skal vi gjøre i dette programmet? Her er bare en for loop itera fra 0 til 3, fordi det er hva verdien av studentene er. Jeg er bare å spørre brukeren gi meg studentens navn. Og så i linje 17, vi har en stort sett kjent linje. Vi har vår gamle venn GetString til høyre. Og hva stykke syntaks er tydeligvis ny, Hvis du aldri har programmert i C før, og har aldri brukt structs? Yeah? PUBLIKUM: The .name. DAVID J. MALAN: The .name. Men dette er ikke for mye av et sprang, fordi nå studentene brakett jeg gir deg den i-te student. Og hvis du ønsker å dykke innsiden av denne strukturen, du bare bruke en enkelt periode og så navnet på den variable innsiden, eller eiendommen innsiden som du ønsker å få tilgang til. Tilsvar da, hvis jeg da be den bruker, gi meg studentens dorm, du kan tilsvarende lagre som strengen i dorm variable inne av at studenten struktur. Og nå ting blir litt fancy. Og dette kommer til å se på kanskje mye ganske snart. Men du vil se dette langt mer i PSet 4, så la oss bare blikk på det nå. Det viser seg at i linje 23 gjennom 38, hva tror du jeg kanskje gjør? Jeg har fjernet kommentarene for i dag, men den versjonen av koden online for referanse har alle kommentarer. Hva gjør jeg synes å være å gjøre? PUBLIKUM: Lagre filen med alle den informasjon som brukeren har angitt. DAVID J. MALAN: Ja, nøyaktig, er det en ny vei at vi ser to, en annen funksjon i C, der jeg kan lage mine egne filer. Så langt, nesten hvert program du har skrevet er statsløs. Så snart den er ferdig å kjøre, det er det. Det er ingen hukommelse eller erindring om det. Det finnes ingen fil lagres. Men hvis du ønsker å lagre innspill som har skjedde, som i et spill eller et program som dette, viser det seg at vi kan gjøre det. Og du vil se dette mer i PSet 4 og i kapittel. Men denne linjen 23 essensielt oppretter en fil som heter students.csv. Og du kanskje har sett dette før. Selv om du aldri har studert CS før, CSV er kommaseparert variabler. Det er som en svært fattig mann versjon av en Excel-fil, noe som betyr at det kan åpnes i Excel og Apple Numbers, og det har rader og kolonner. Men det er ikke en proprietær format som Microsoft eller Apple. Det er bare komma skille verdier som vi vil se i et øyeblikk. Og bare ta en gjetning. I tråd 23, i det slutt, mitt andre argument til den nye funksjonen kalles f åpen for fil åpen er w. Hva kan w betegne? Yeah? PUBLIKUM: Det lar deg skrive til filen? DAVID J. MALAN: Det lar du skrive til filen. Så det er et par varianter at vi kan plugge inn her. Men hvis du bare vil lese filen, er at ser på det og lese den inn i minnet, du bare bruke quote unquote "r". Hvis du ønsker å skrive til fil, bruker du quote unquote "w". Det er også føye og et par andre ting Hvis du ønsker å endre eksisterende filer. Nå kommer vi til å fortsette å se dette ting, så får vi komme tilbake til linje 24. NULL, det viser seg, er en spesiell verdi som kan returneres ved visse funksjoner hvis noe har gått wrong-- hvis filen ikke eksisterer, hvis du har kjørt ut av minnet, eller en haug med andre feil. Men for nå, la oss bare anta at dette er bare vanlig feilsjekking. Her i linje 26, jeg gjentar fra 0 til 3 i løpet av alle mine studenter. Og dette er slags sort av en ny funksjon, fprintf, men bare ta en gjetning. Hvis printf er bare print en formatert streng, hva betyr fprintf trolig bety? PUBLIKUM: Skriv ut til en fil. DAVID J. MALAN: Print et formatert streng til en fil. Det er det ekstra f midler er fil. Og den nye første argumentet må være variabelen som representerer filen. Så vi må bare et format strengen akkurat som printf. Og selv om denne syntaks er ny, dette er bare betyr plugge i studentens navn, plug-in student dorm, og deretter med fclose, lukke filen. Og så lastly-- dette er nytt og vi vil komme tilbake til dette før long-- Jeg frigjør studenten grunner som skjedde opp over det. Men vi vil komme tilbake til at før long-- det er på grunn av hvordan GetString er faktisk jobber under panseret. Så la oss ta en rask titt her. Hvis jeg skriver ls i katalogen min, Legg merke til at jeg ikke har en fil som heter students.csv, bare ikke der, ikke eksisterer. Så hvis jeg nå kompilere dette programmet, gjøre structs-1,. / structs-1, og jeg kommer til å gå videre og skriv inn Andi, som bor i Berkeley ved Yale. Vi kommer til å ha Rob som bor i Thayer i disse dager. Og la oss komme opp med hvor er, tror jeg, er Maria i Mather, hvis jeg har husket riktig. Så ingenting ser ut til å skje. Men hvis jeg skriver ls nå, det er students.csv. La oss gå videre og åpne students.csv. Dette er igjen en meget lett filformat. Men jeg har bare vedtatt en konvensjon at jeg har to rader og kolonner her. Den første kolonnen er folks fornavn. Den andre kolonnen er studentens dorm, eller høyskole, eller hus, eller whatnot. Og nå har jeg lagret denne permanent i en fil. Så det er ikke alle som interessant. Men dette er bare et springbrett nå å være i stand til å vedvare informasjon permanent. Så la oss se nå hva mer vi kan gjøre med disse og andre funksjoner. Men først noen spørsmål? Det var mye, og det ble raskt. Men du vil se mye mer i PSet 4, så vel. Yeah? PUBLIKUM: Er det en måte å fortsette å legge til navn til denne filen? DAVID J. MALAN: Godt spørsmål. Er det en måte å fortsette legge navn til denne filen? Ja. Og, faktisk, hvis du ender opp re-åpne filen, du ville bruke quote unquote "a" for append, som ville bare legge til en ny linje, en ny linje igjen og igjen, akkurat. Godt spørsmål. Andre spørsmål? Yeah? PUBLIKUM: Hvis du kjørte programmet på nytt akkurat nå, ville det holde å legge navn til fil eller ville det åpne opp en ny fil? DAVID J. MALAN: Ah, godt spørsmål. Hvis du kjørte programmet igjen rett nå, kanskje skrevet i nye navn, vil det legge til filen eller overskrive filen? Sistnevnte, fordi jeg er ikke bruker tilføyningsmodus. Og fordi jeg er bare blindt åpne filen for skriving, det bare kommer til å overskrive filen. Så jeg ville faktisk trenger å gjøre er å legge til, hvis jeg vil faktisk ha en langsiktig database. Nå CSV er nyttig, ærlig, selv for som om du er writing-- og vi vil etter hvert se dette senere i semesteret når vi bruker CSVs til andre formål. Hvis du vil lagre alle mennesker som har registrert seg for noen hendelse, eller registrerte deg for student gruppe, eller noe sånt, lagring av data i et slikt av formatet er super praktisk. Fordi bokstavelig talt, hvis jeg var å laste ned denne filen. Jeg kunne double-- og la oss faktisk prøve dette hvis jeg har Excel eller Numbers på her. Jeg kommer til å høyreklikke eller kontroll-klikk filen min. Uff da. Høyreklikk eller Kontroll-klikk filen min. Kom igjen, er min mus ikke samarbeider. Download-- Jeg kommer til å laste ned alle filene her så bare så jeg kan ta denne. Og la oss se om dette fungerer students.csv-- første gang Jeg har aktivert. Nå ønsker de å se mine kontakter. Nå trenger jeg å registrere. Se hvor enkelt det er å bruke CSVs? Ja, holde det oppdatert. OK, nå er vi klar for klassen. OK, oh, hva er nytt? OK, i nærheten. Det var magisk. OK, nå må vi oppdatere. Og nå, det glemte hva fil jeg opprinnelig åpnet, men hva a-- der vi går. OK, så nå har vi en Excel-fil. Takk. OK, så det jeg gjorde var den enkle delen. Selvfølgelig kunne jeg ha forhåndsinstallert Excel, eller Numbers, eller hva programmet. Men dette er hyggelig, fordi Nå kan jeg manipulere dataene i et standard format. Så nå la oss kontekst bytte til der vi slapp forrige gang, som var å starte å ta av støttehjulene. Men først, det gjorde du ikke se dette tidligere lunsj er igjen skjer her på Brann og Is i Cambridge, Sitar i New Haven. Meld deg på CS50s nettstedet ASAP å bli med CS50 studenter og ansatte. Så vi tok trening hjul off på mandag som follows-- strengen har blitt erklært i CS50s bibliotek for en stund. Og det er fint, fordi det gir oss for å snakke om variabler som fullstendige ord og setninger og mer. Men det viser seg at strengen ikke eksisterer. Det er bare et synonym, eller et alias, at vi har skapt for noe som faktisk er litt mer teknisk kalles en char *. Og ja, vi så et eksempel av et program på mandag som ikke oppfører seg helt som vi forventet. Dette var den filen, sammenligne-0. Og minner om at sammenligne-0, hvis Jeg rekompilere mandagens program og kjøre sammenligne-0 og skriv inn mamma små bokstaver, og mamma med små bokstaver igjen. Programmet insisterte jeg skriv forskjellige ting, selv om mamma, alt i små bokstaver, er identisk visuelt. Så hva var det korte svaret for hvorfor datamaskinen mener disse to strenger er annerledes? Yeah? PUBLIKUM: [uhørbart] DAVID J. MALAN: Høyre. Så, mamma, første gang Jeg skriver det inn, blir lagret et sted i min datamaskin minne, men på et annet sted enn den andre gangen jeg skriver i mamma. Nå er det sikkert kunne optimaliseres. Datamaskinen kan være smart og realisere disse to strenger, hey, de er identiske. La meg ikke redundant lagre det. Men datamaskiner ikke gjør det optimalisering mindre du forteller dem til. Så, som standard, er de bare kommer til å ende opp på to forskjellige steder i minnet. Og så for å være mer tydelig, når vi sammenlignet de to strenger, Den første ble kalt s, den andre ble kalt t, hva som konkret var jeg sammenligne her på linje 13? Yeah. PUBLIKUM: Det er stedet i minnet at variabelen vil peke på. DAVID J. MALAN: Akkurat, var jeg sammenligning av plassen i minnet at disse variablene peker til. Så spesielt hvis mor var på byte nummer 1 og 2, og 3, og 4-- fordi huske backslash 0 må være helt på slutten. Og den andre forekomst av mamma, m-o-meter, var på adresse 10, 11, 12, og 13. Jeg var sammenligne en, som adresse, det sted i minnet, mot 10, som er åpenbart ikke den samme. 1 er ikke 10. Så dette er fint i at det er ganske grei. Men det er problematisk i den utstrekning vi kan ikke synes å sammenligne strenger. Så fundamentally-- og på dette lave nivå, hvis du ønsket å implementere et program for å sammenligne to separate ord at brukeren har tastet inn for kvalitet, gjøre de stiller seg opp char for røye, bare i generelle vendinger, Hva trenger vi å gjøre, tydeligvis? Det er ikke tilstrekkelig bare å se på disse to adressene. Hva trenger vi å gjøre? Yeah? PUBLIKUM: Reagere gjennom strengen [uhørbart]. DAVID J. MALAN: Ja, la oss iterere gjennom strengen. La oss bruke en for loop, en stund loop, eller uansett hva du er mest komfortabel med. Og hvis vi har to strenger sted i minnet, la oss se på hver sin første tegnet, så hver er andre karakter, deretter tredje og fjerde, og femte, før vi treffer hvilke spesielle sentinel verdi? PUBLIKUM: [uhørbart] DAVID J. MALAN: Ja, backslash null, ved hvilket punkt i hver streng vi kan avgjøre det er det. Har vi matchet hver eneste karakter? Hvis ikke, returnerer false. I så fall returnere true. Og så det er akkurat hva denne versjonen av programmet sammenligne-1.c gjør. Det er identisk med det vi så på mandag, bortsett fra at jeg har blitt kvitt ordet string-- skjønt som ikke har noen funksjonell impact-- alle Jeg gjør nå er å fjerne noen visuelle trening hjul, men for å se klart at s og t er adresser. Og det er det stjernen, stjernen, representerer er en adresse, ellers kjent mer teknisk som en peker. Så når jeg erklærer s på linje 9 og si char * s, det betyr ikke gi meg en streng. Det betyr gi meg en variabel med hensikt i livet er å lagre en adresse. Fordi jeg er i ferd med å sette adressen til en streng inn i den. Og ja, GetString, for å være klart, ikke returnerer en streng. Det går ikke tilbake mamma backslash null, per se. Hva gjør GetString spesifikt og presist tilbake? PUBLIKUM: [uhørbart] DAVID J. MALAN: En adresse, Adressen til det første tegnet i noen streng det har fått. Og så nå ser vi en spesiell søkeord igjen. Og, antydet jeg til dette tidligere. Dette kommer til å bli bra konvensjonen at vi vil se igjen og igjen nå. Jeg sjekker for å sørge for at s er ikke null, og t er ikke null. Fordi basert på min virkelig rask omtale tidligere, hva kan bety hvis GetString returnerer ikke en adresse, men N-U-L-L, som er igjen, noen spesiell verdi? PUBLIKUM: Feil. DAVID J. MALAN: Det er en feil. Noe gikk galt. Og hva typisk kan skje, spesielt med strings-- som kan være av ukjent lengde i advance-- kanskje datamaskinene ' ut av minnet, kanskje du skrev på en slik lange ord eller en setning eller limt inn et så stort essay det er bare ikke nok minne. Og så GetString ikke kan gå tilbake adressen til hele greia, så det bare returnerer ingenting. Og det sier en feil som har skjedd ved å returnere den spesielle NULL verdi. Det er null adresse, så å si. Nå viser det seg C kommer med en funksjon som gjør at iterasjon. Vi trenger ikke å gjennomføre dette med en for løkke eller en stund loop oss selv. Vi kan bruke en funksjon, kalt konsist, røre comp, eller streng sammenligne, hvis hensikt i livet er å gjøre akkurat det. Du gir den to pekere, to adresser, og det vil gå til disse adressene og deretter sammenligne brev for bokstav for bokstav for kvalitet, stopper bare når det er sant? Når intuitivt skulle røre komp slutter itera, bare for å være klar? Når den treffer en backslash 0 i enten streng, ved hvilket punkt det kan bestemme har alt matchet, eller har det vært en uoverensstemmelse? Så, hvis vi kjører dette nå og prøver vår lille kapitalisering spill, så sørg sammenligne-en, ./compare-1, og skriver mamma med små bokstaver begge ganger. Nå er det det samme. Og hvis jeg gjør det igjen med små bokstaver og deretter kanskje store bokstaver. Nå er det faktisk skiller mellom store og små bokstaver. Så det er ikke alt som er vanskelig eller magisk, men det gjør nå forklare hva som skjer under panseret. Så hva mer kan vi trekke ut fra denne type lekse? Så la oss ta en titt på dette. Jeg kommer til å gå videre og skrive en rask program her kalt kopi 0. Og nå la oss gå videre og faktisk la oss gjøre dette-- med kopi-0, ta en titt på hva jeg har her. Jeg først fortelle brukeren, si noe. Så får jeg en streng og jeg lagret den i s. Så sjekker jeg om s er lik lik NULL, bare returnere en. Så dette er bare standard feilsjekking. Noe interessant som har skjedd. Og faktisk, hvis vi blir kvitt feilen sjekker, dette ser ut som uke en kode for øyeblikket. Men jeg har begynt å få en litt bedre om det. Nå i linje 16, en uke siden, kanskje enda et par dager eller minutter siden, du kan si linje 16 er å skape en variabel kalt t og kopiering er inn i den. Og det er en helt rimelig takeaway. Men være mer presis nå. Hva skjer i tråd 16? Hva er å bli kopiert fra høyre til venstre? Yeah? PUBLIKUM: Er t få en adresse av s? DAVID J. MALAN: Akkurat, t blir adressen til s. Så for å være klart nå, hvis jeg går tilbake til det tidligere eksempel og jeg trekker ut det jeg har skrevet i. Og det jeg har skrevet in-- her er s, og her er det jeg har skrevet i et sted i minne, mor og deretter en backslash 0 som er lagt for meg. Hva jeg lagret her, husker, dette er i posisjon 1, 2, 3, 4, Dette er hva som er i dag i s. Så hvis du er på linje 16, sier jeg gi meg en annen variabel kalt t og butikk i at verdien av s, hva blir lagret her vil ikke mamma men heller bare nummer en. Så hvis vi ser fremover i dette programmet nå, hva kommer til å skje? Så merker at det er denne funksjonen du kanskje har brukt dette for en tid siden for Caesar, eller Vigenère, eller kanskje ikke i det hele tatt. Jeg hevder med min printf, jeg er kommer til å kapitalisere kopien t. Først i linje 19, rask tilregnelighet sjekker, StrLen kontrollerer lengden av t. Fordi jeg ønsker ikke å prøver å kapitalisere noe Hvis det er ingen streng der. Hvis brukeren bare trykke Enter, det er ingenting å kapitalisere. Så jeg ønsker ikke å gjøre linje 21. Så linje 21 er å utnytte som brev, tilsynelatende, i t? PUBLIKUM: m? DAVID J. MALAN: Det ser ut som det er kopiering hvilken? PUBLIKUM: m. DAVID J. MALAN: Uh, m. OK, så den første m, fordi merke til at jeg er passerer til toupper, som Hvis du aldri har sett det det er bare for en funksjon for å kapitalisere som sin inngang. t brakett null betyr gi meg null karakter t. Og så hvordan dette Bildet endring, for å være klar? Hva som må bli omskrevet eller endret med hensyn til s og t og mamma backslash null. PUBLIKUM: [uhørbart] DAVID J. MALAN: Ja, så dette her rett og slett behov for å få endret to-- fikse dette-- trenger å få endret til en kapital m. Men nå, se senere i program, hvis jeg skrive ut s og t som jeg rydde her, se på hva som er kommer til å skje skrive ut s og t. Så gjør copy-0, ./copy-0. La meg gå videre og skriv i mamma i små bokstaver. Legg merke til både den opprinnelige og kopien er aktivert. Hvorfor? Vel, s og t er begge peker til, om du vil, samme mengde minne. Og ærlig talt, dette er å få virkelig uninteresting-- det faktum at vi bruker adresse null her. Jeg mener, jeg egentlig ikke bryr seg hvor ting er i minnet. Sorry jeg slette litt for mye. Men jeg egentlig ikke bryr seg hvor ting er i minnet. Og så, ja hva programmerere har en tendens til å tenke på er at når du snakker om en adresse, eller en peker, hvem bryr seg hvor det er i minnet. Jeg bryr meg ikke om det er på byte en eller én milliard. Jeg bare bryr seg om at dette variabelen er effektivt peker på at mengde minne. Og så, fra nå av, i stedet for uenighet i løpet av vilkårlige minneadresser, la oss bare begynne å tegne pekere som pekere, som piler. Så hva s og t egentlig er, i henhold til dette program, på grunn av hvordan jeg laget t, det er bare to separate variabler peker på den samme mengde minne. Og vi ikke bryr seg hvor de er. Så vi kan abstrakt bort at detalj. Så hvordan løser jeg dette? Hvis jeg ønsker å skrive en versjon av kopien Program som faktisk kopierer streng og kapitaliserer bare kopi, bare intuitivt, hva må være en ingrediens til vår løsning? PUBLIKUM: [uhørbart] DAVID J. MALAN: Vi trenger en hva? PUBLIKUM: Chunk minne. DAVID J. MALAN: Vi trenger en annen del av minne, ikke sant? Vi vet ikke hvordan de skal gjøre det ennå, nødvendigvis. Men jeg slags trenger dette skal skje så at den opprinnelige mor med små bokstaver ender opp i at ekstra mengde minne. Og så når jeg endre kopien, jeg ønsker ikke å endre denne kopien her. Jeg i stedet bare vil endre denne kopien slik at originalen er uendret. Så, la oss se hvordan vi kan gjøre dette. I copy-1, som allerede har blitt strippet for kommentar, men er kommentert online. Vi i stedet gjøre following-- disse linjene er identiske, få meg en streng og kaller det s. Men la oss nå se på en av våre mest kompleks, men den siste av kompleksiteten for en stund, gjør linje 16 akkurat dette. Så hvis din comfy med Bildet vi bare drew-- gi meg en ny del av minnet, kopiere alt inn i det, La oss se hvordan vi oversette det til koden. Så linje 16, på venstre side, char * t gir meg denne boksen over her. Det er alt den gjør. På høyre side, m Alloc, eller malloc, er minnetildeling, super fancy, en kryptisk måte å bare si gi meg en blings av minne. Hvor mye minne trenger vi? Vel, er slag av en stor uttrykk. Men la oss se hva det står her. Så dette, selvfølgelig, er å gi meg strengen lengde s. Så, mamma det bør være hva? Så bare tre, ikke sant? Moren er tre tegn. Du trenger ikke telle backslash null når du snakk om lengden av en streng er det faktisk den menneskelige synlige bokstaver. Så mamma, så dette gir meg tre. Men vent litt, jeg nå å legge en. Hvorfor må jeg faktisk ønsker å bevilge 4 byte og ikke bare tre? Yeah? PUBLIKUM: For sentinel verdi? DAVID J. MALAN: Akkurat, for at sentinel verdi. For backslash null, Jeg trenger 4 byte totalt. Så jeg trenger lengden av strengen, pluss en. Og så bare for god measure-- selv om på dette systemet, det er alltid kommer til å være 1-- jeg sier multiplisere dette med størrelsen på en char. Det viser seg at sizeof er operatør i C som bare forteller deg antall byte som er som kreves for en bestemt datatype. Det fungerer ikke for arrays, typisk, noen ganger det gjør. Men i det generelle tilfelle, no. Men det vil fortelle meg hvor mange byte en røye er, som viser seg er alltid en. Så dette er som å multiplisere med en. Så super kryptiske jakt linje med kode. Men alt den gjør er gir meg en blings av minne. Men synes det å være å kopiere noe inn som minne? Ikke enda. Og så hva gjør jeg på linje 22, og 23, 24, 25, vel, jeg bare gjør dette. Og dette er liksom old school stuff nå. Dette er som PSet 2, der du bare flytte ting rundt i minnet, eller snarere i strenger. Så jeg gjentar fra 0 til lengden av strengen s. Og jeg kopierer den i-te karakter i s inn i i-te karakter i t. Og fordi jeg, programmerer, gjort Pass på å fordele nøyaktig like mange bytes som jeg trenger, er det perfekt en-til-en forhold. Og jeg kopiere mamma små bokstaver til den nye. Og så til slutt, jeg gjør denne linjen. Og så effekten er bare å utnytte denne t her. Så mye til å absorbere, men hvis du bare vurdere hva som egentlig skjer på under panseret er bare å flytte disse bytes rundt, alt er nødvendig for å løse dette problemet er bare for å gi oss denne del av minnet. Nå i fare for å overveldende, la meg vise ett annet eksempel som er nesten identiske, bortsett fra denne ene linje med kode. Så dette er hacker versjon av dette programmet, hvis du vil. Men la oss bare destillere det inn i hva som skjer. Linje 24 brukes til å bli: T braketten jeg får s brakett i. Nå, jeg endre dette til den mye mer kryptiske stjerne t pluss en er lik stjerne s pluss 1. Så hva som skjer og hvorfor har vi en stjerne karakter? Vi har sett stjernen før, og det blir brukt annerledes her. Vi tidligere så char *, nå jeg ser En stjerne i begynnelsen, og det er OK. Fordi det viser seg at vi kan slags antyde bare fra de første prinsippene hva som skjer. Så bare for å være klar, hva er s? I forrige uke var det en streng. Som ikke nok lenger. Hva er s, spesielt? PUBLIKUM: [uhørbart] DAVID J. MALAN: Det er en peker. Det er adressen til første tegnet vi skrevet i. OK, hva er t? PUBLIKUM: [uhørbart] DAVID J. MALAN: The adressen til den første byte i t, som del av minnet omfordelt. Så det viser seg at når vi veksle fra 0 på opp til strengen length-- først av alt, jeg starter på 0, fordi av denne gamle skolen for loop ting. Så bare for enkelhet, la oss anta at den første linjen i kode er egentlig bare dette, ikke sant. Hvis jeg er null, og legger til null til noe formodentlig ikke kommer til å ha en effekt. Så hva er dette ord? Det viser seg at stjernen Operatøren i denne sammenheng er dereferanse operatør, som er like en fancy måte å si gå til følgende adresse. Så hvis s er adressen til den første karakter i denne del av minnet, * s betyr gå dit. Og fordi vi har trukket bildet på denne måten du kan adoptere Følgende mental modell. Hvis dette er s, og du sier * s, * s typen som renner og stiger, hvis du husker kampen fra barndommen, er som følge at pilen og gå til adressen. * t er den samme. Så starter her, gå til sin del. Jeg kan ikke bare trekke på denne skjermen på den måten. * t betyr å gå her. Og så, er bare for loop sier flytte denne karakter her, flytte denne karakter her, flytte denne karakter her. Men hvordan gjør jeg det incrementation? Jeg trenger å angre det jeg nettopp slettet. Dette er det som vanligvis kalles pekeren aritmetikk, som betyr matematikk med adresser. Dersom det i denne for sløyfen, Jeg fortsetter å økes i, og s er en adresse og t er en adresse, hvis jeg bare fortsette å legge en, det betyr bare holde fremover, og fremover, og fremover i minnet. Det er som Oxford Street, den gaten som CS bygningen er på. CS bygningene er på 33 Oxford Street. Så hvis du skulle gjøre 33 Oxford Street pluss 1, som bringer deg til 34 Oxford Gaten, deretter 35 Oxford Street, deretter 36 Oxford Street, uansett hva de bygningene faktisk er - hvis de finnes. Og så, det er alt vi gjør her med pekeren aritmetikk. Så det er en super uforståelige måte uttrykke oss selv. Men alt som skjer under panseret er bare å følge disse adressene, som følge et kart, om du vil, eller etter piler som vi har tegnet på skjermen. OK, til en masse fordøye. Eventuelle spørsmål om syntaks, konsepter, pekere, malloc, eller lignende. Ja, over her først. PUBLIKUM: Så hvor som sier * t tilsvarer toupper * t, kommer det til å kapital alle bokstavene eller just-- DAVID J. MALAN: Ah, veldig godt spørsmål. Så i denne linjen her, 31, dette kommer til å kapitalisere den første bokstaven eller alle bokstavene. Så la oss svare på det ved å gå tilbake til første prinsipper. Og første prinsippene her jeg mener bare gå til de grunnleggende definisjoner av hva som er involvert. Så toupper er en funksjon som kapitaliserer en char. Det er alt. * t betyr gå til first-- gå til adressen i t. Så, i bildet, hvis dette er blings minne vi tildelt med malloc, og dette er t, * t betyr gå her. I mellomtiden, du passerer denne verdien, små bokstaver m til toupper, du får tilbake kapital M, hvor er du setter den? Du setter den i den samme sted. Og så ved at logikken i de grunnleggende definisjoner det er bare utnytte den første bokstaven med mindre du reagere med jeg eller en for loop eller en stund loop, er det ikke kommer å gjøre noe mer enn du ber om det. Godt spørsmål. Yeah? PUBLIKUM: Hvorfor gjorde du bruke deferanseoperasjon metoden heller enn rekken? DAVID J. MALAN: Ah, godt spørsmål. Hvorfor vil du bruke dereferanse metoden i stedet for matrisen metoden? Ingen spesiell grunn, for å være ærlig. Og, faktisk, for denne form av et eksempel, til høyre, Jeg bare kranglet gjøre program mer komplisert, flere øyne er glass over, folk sjekker ut fordi dette ser super uforståelige, men selv om det gjør det samme. Og så, ærlig, er dette en unødvendig visuelt kompleks løsning på problemet. Det er fortsatt god design, fem av fem for design, enten det er i braketten notasjon eller pekeren notasjon. Men-- spesielt når vi får senere i kurset i PSet 5 når vi implementerer det ordbok som Jeg har nevnt et par times-- vi vil faktisk bryr seg om lavt nivå minneadresser at vi virkelig forstår hva er det som skjer. Men, for nå, viser det seg at dette kodelinje her hakeparenteser vet egentlig ikke eksisterer. De er det som kalles syntaktisk sukker, som er bare en nifs kul måte å si det kompilatoren konverterer hakeparenteser til å være som matematisk uttrykk. Så det er en menneskelig konvensjonen å være i stand til å bare skrive disse svært brukervennlige parentes. Men hva kompilatoren, klang, er virkelig gjør helst du skrive hva som fremhevet i tråd 24, det er virkelig under panseret å konvertere det til denne. Det er bare mer behagelige som et menneske å lese og skrive kode som linje 24. Men til slutt de trening hjul også komme av når ens egen komfort blir sterkere. Greit, så husker da at dette var slags største problemet vi kjørte inn. Og det er det som utløste hele denne jævla samtale om pekere, og adresser, og kopiering av ting. Det var fordi vi snubler over dette dum, dum sak, der Jeg implementert logically-- med Lauren her oppe på demo og appelsinjuice i milk-- en perfekt algoritmisk riktig funksjon for å bytte to variabler ' verdier, men den jævla ting har ikke noe vedvarende, eller permanent, effekt på min kode. Og hvorfor var det? I et nøtteskall, hvorfor er dette implementering av swap logisk korrekt, men har ingen innvirkning på de variablene som sendes til det, som x og y for main? Hva var hovedinnholdet i saken? Yeah? PUBLIKUM: Fordi variable laget kopier av variable i pass gjennom funksjon. DAVID J. MALAN: Akkurat, når du passerer variablene i en funksjon, eller argumenter inn i en funksjon, de er vedtatt av kopi, som betyr at du får en identisk jakt mønster av biter for både x og y, heter her a og b. Og du kan gjøre noe du vil med disse eksemplarene, men de kommer til å ha noen effekt på kall funksjonen. Og, faktisk, vi trakk det bilde på skjermen, tilbakekalling siste gang, der hvis du virkelig tenke på hva som er skjer under hood-- hvis Dette er datamaskinens minne, og her nede er den del av minne som brukes for main, Dette er den mengde minne som brukes for swap, og så selv om hoved har to variabler, x og y, swap kan ha identisk ute verdier, som begge er 1 og 2, men de er helt forskjellige biter av minne. Så vi trenger en løsning på dette. Og ærlig talt, ville det virke som vi nå har en løsning på dette problem, til høyre. Hvis vi nå har evnen til å manipulere ting ved hjelp av adresser og, liksom renner og stiger stil, følg disse pilene og gå hvor som helst vi ønsker i minne, kunne ikke vi løse dette problemet ved å går fra hoved å bytte ikke de verdiene vi ønsker å swap, men bare intuitivt hva kan vi passere å bytte i stedet? [Interposing VOICES] DAVID J. MALAN: Hvorfor gjør vi ikke bare passerer den adressene, ikke sant? Hvorfor kan ikke vi gi swap en skattekart, om du vil, som fører den til faktiske verdier x og y. La oss swap, faktisk endre de opprinnelige biter, i stedet for bare passerer kopier av biter. Og så, faktisk, det er hva som er kommer til å være løsningen. Denne versjonen her er klart dårlig og feil. Og nå, ved første øyekast, det bare ser som vi har lagt en haug med stjerner tilfeldig og krysset fingrene at det ville kompilere. Men, ville det nå kompilere. Men la oss se hva dette skal bety. Og, dessverre, forfatterne av C kunne ha valgt et annet symbol for å gjøre dette litt klarere, men stjernen operatør har annen betydning i to ulike sammenhenger. Og vi har sett begge, men la oss skille. Så opp på toppen der, når jeg har forandret a og b fra å være int er i dårlig versjon til int stjerner, a og b, tidligere, var heltall. Hva er a og b nå i den gode, grønne versjonen? De er adresser. Adresser til hva, for å være klar? Adresser til heltall. Så det faktum at jeg er sier int stjerners hjelp Dette er adressen til et helt tall, spesielt. Så nå merke i linjer med kode, noe annet har endret seg også. tmp forblir den samme, fordi det er bare midlertidig heltall, ingen minne magi der. Men en trenger nå en stjerne. Og, faktisk enhver annen omtale av a og b, Legg merke til at alt som er endre fra rødt til grønt er at jeg prefixing disse variablene med stjerner. Fordi jeg ikke ønsker å kopiere en og b. Fordi hvis jeg bare kopiere en og b og swap a og b, hva jeg faktisk å bytte? Bare adresser, jeg ønsker å bytte hva som står på disse adressene. Jeg ønsker å gå dit. Og så stjernen operatør innsiden av min funksjon, ikke på innsiden av parameterlisten betyr at du går til disse adressene og faktisk endre disse verdiene. Så hva gjør bildet nå ser ut i stedet. Vel, hvis stedet jeg passert in for a og b ikke en og 2-- Jeg faktisk trenger å legge en annen definisjon her. Så antar at dette blings minne er på stedet 10. Dette er på stedet 11, men denne er litt av en forenkling, Jeg har nå to valg har jeg passerer x og y eller må jeg sende sine adresser? Hvis jeg passerer deres adresser som dette, jeg bare nå må implementere swap per den grønne koden slik at når den ser en, og når det Sees b, betyr det ikke bare kopiere en og b og flytte melk og appelsinjuice. Melk og appelsinjuice metafor bryter nå ned, fordi de er kopper av flytende og ikke-kart. Vi trenger i stedet for å gå å ta opp 10, og vi trenger å gå for å løse 11, og deretter utføre det bytte logikk. Så logikken er den samme, men vi trenger en litt annen måte av tilgang til disse variablene. Og så til slutt, hva Programmet har til å se ut som dette er. I swap.c bokstavelig kopiert og limt den grønne versjonen. Men jeg trenger å gjøre en endring. Det er ikke tilstrekkelig bare å endre swap. Hvilke andre kodelinje må jeg endre? Yeah? PUBLIKUM: Hvor det tar argumentene. DAVID J. MALAN: Hvor det tar sin argumentasjon. Så hvis jeg blar opp til hoved, jeg kan ikke bare passere i x og y, og, jeg lover, den siste stykke ny syntaks i dag. Jeg trenger å passere i ikke x og y men adressen av x og y. Og det viser seg, symbolet at forfatterne av C valgte er hvis du bruker en tegnet her, for ikke å forveksles med bitvis ampersand, hvis du bruker et ampersand her og en ampersand her, Dette tallene ut for deg, hva er adressen til x, kanskje det er 10, hva er Adressen y, kanskje det er 11, og passerer de i stedet. Så mye til å absorbere alt på en gang. Men la oss se nå raskt i våre resterende fire minutter hvor ting kan gå galt. Og som en digresjon, faktisk Jeg tok dette bildet, TF tok dette bildet et år eller to siden. Så dette er bak hjørnet av Eliot Dining Hall. Pekere er kanskje den vanskeligste tema som vi dekker i CS50. Så hvis du bekymre sorterings av skråningen er som kanskje det er mer av en hockeykølle som dette, innser vi er slags nærmer seg en topp i gjelder det konseptuelle kompleksitet. Og jeg tar opp dette bilde, fordi jeg sverger til Gud, i høst 1996, da jeg tok CS50 med min undervisning stipendiat, Nishat Mehta, satte han meg ned i hjørne av Eliot D. Hall over lunsj, eller middag, eller noe å prøve å hjelpe meg å forstå pekere. Og det er her jeg var uker etter den ble introdusert i forelesningen når Jeg endelig forstått pekere. Og jeg er håpefull at dette vil klikke langt raskere for deg. Men innser dette absolutt blant de mer avanserte emner vi har sett på. Men det er blant de kraftigste. Og når du får det, det er egentlig alt bare kommer til å endelig komme sammen. Så trygg på det gjør ikke må all vask i dag. Så her er det siste programmet vi kommer til å se på. Og vi kommer til å ende med en raske tre minutter av claymation laget av vår venn, Nick Parlante. Her er et program, som på de to øverste linjer erklærer en variabel x og y. Som begge er adresser av heltall, AKA pekere. Vi bevilger nok minne til å lagre en int og lagre adressen av at minnet i x. Så, er det enda enklere enn eksempelet før. Gi meg fire byte minne, som er på størrelse med en int, og sette den adressen i x. Denne linjen betyr her gå til adressen i x og sette betydningen av livet, nummer 42 der. Men denne linjen bekymrer meg. Stjerners y betyr gå til adressen i y, og sette uheldig nummer 13 der. Hvorfor er det farlig, på dette punktet i story-- riktignok raskt fortalt i våre avtagende minutter her-- hvorfor er det dårlig for meg å si, gå til adressen i y? PUBLIKUM: Du har ikke [uhørbart]. DAVID J. MALAN: Jeg har ikke sette noe i y. Så hva er verdien av y, på dette punktet i historien? Vi har ingen anelse. Det er noen søppel verdi og heller ikke Binky vite. Hvis vi kan ende på dette notatet. [VIDEO PLAYBACK] -Hei, Binky, våkn opp. Det er tid for pekeren moro. -Hva er det? Lær om pekere? Oh, goody. -Vel, For å komme i gang, tror jeg vi er kommer til å trenge et par tips. -OK. Denne koden tildeler to pekere som kan vise til heltall. -OK, Vel jeg se to pekere, men de ikke synes å være å peke på noe. -Det er riktig. Opprinnelige pekere ikke peke på noe. De tingene de peker på er kalt pointees og sette dem opp er et separat trinn. -Å, Høyre, høyre. Jeg visste det. De pointees er atskilt. Så hvordan bevilge du en pointee? -OK, Vel dette kode allokerer et nytt heltall pointee, og denne delen sett x å peke på det. -Hei, Ser det bedre. Så gjør det ikke noe. -OK, Vil jeg dereference pekeren x til lagre nummeret 42 i sin pointee. For dette trikset, jeg trenger min tryllestav av dereferencing. -Din Tryllestav av dereferencing? Uh,, det er så stor. -Dette Er hva koden ser ut. Jeg skal bare sette opp antall og-- [POP SOUND] -Hei, Se der det går. Så, gjør en deferanseoperasjon på x følger pilen for å få tilgang til sin pointee. I dette tilfellet, for å lagre 42 i der. Hei, prøve å bruke den til å lagre nummeret 13 gjennom den andre markøren, y. -OK. Jeg vil bare gå over her til y, og få nummer 13 satt opp. Og deretter ta wand av dereferencing og just-- [Alarmlyd] -Å, Hei det ikke fungerte. Si, eh, Binky, gjør jeg ikke tror dereferencing y er en god idé, fordi innstillingen opp pointee er et separat trinn. Og jeg tror ikke vi noen gang gjorde det. -hmm, Godt poeng. -Ja, Bevilget vi pekeren, y, men vi aldri sett den til å peke på en pointee. -hmm, Veldig observant. -Hei, Du ser bra der, Binky. Kan du fikse det slik at y-punkter til samme pointee som x. -Sure, Jeg bruker min tryllestav av pekeren oppdrag. -Er Det kommer til å bli en Problemet, som før? -Nei, Dette betyr ikke berøre pointees. Det endrer bare én pekeren å peke på den samme thing-- [Hvesing] --as annen. -Oh jeg skjønner. Nå y peker på samme sted som x. Så, vent, nå y er fast. Den har en pointee. Så du kan prøve staven av dereferencing igjen for å sende 13 over. -Å, OK, her går. -Hei, Se på det. Nå dereferencing fungerer på y. Og fordi de pekere deler at man pointee, de begge se 13. -Ja, Deling, uh, uansett. Så, skal vi bytte plass nå? -Å, Ser vi ikke mer tid. -But-- -Bare Husk de tre pekeren regler. Nummer 1, den grunnleggende struktur er at du har en peker, og den peker over til en pointee. Men pekeren og pointee er atskilt. Og den vanligste feilen er å sette opp en peker men å glemme å gi den en pointee. Nummer to, peker dereferencing starter på pekeren og følger sin pil løpet å få tilgang til sin pointee. Som vi alle vet, dette fungerer bare hvis det er en pointee, hvilken type får tilbake til regel nummer en. Nummer 3, peker Oppdraget tar ett pekeren og endrer det til å peke på samme pointee som en annen pekeren. Så etter oppdraget, de to pekere vil peke på samme pointee, noen ganger som kalles deling. Og det er alt som skal til, egentlig. Bye-bye nå. [END PLAYBACK] DAVID J. MALAN: Det er det for CS50. Takk til professor Nick Parlante. Vi sees neste uke. [Elektronisk musikk SPILLE]