[Powered by Google Translate] [UKE 5]
[David J. Malan, Harvard University]
[Dette er CS50.] [CS50.TV]
[Voksen] Han lyver, om hva, vet jeg ikke.
[Man] Så hva vet vi?
[Woman] That på 9:15, Ray Santoya var på ATM.
[Man] Så spørsmålet er, hva han gjorde på 9:16?
[Kvinne] Skyting på 9 mm på noe.
Kanskje han så snikskytter.
[Man] Eller han jobbet med ham.
[Voksen] Vent. Gå tilbake ett.
[Man] Hva ser du?
[♫ Spennende musikk ♫]
[Voksen] Ta ansiktet opp. Full skjerm.
[Man] brillene. >> Det er en refleksjon.
[♫ Spennende musikk ♫]
[Man] Det er Nuevita baseball team. Det er deres logo.
[Kvinne] Og han snakker til den som har på seg den jakken.
>> [David Malan] Så dette er CS50 uke 5, og i dag har vi ødelegge litt av TV og film for deg.
Så når du ser et show som dette her,
og politiet sier "Kan du rydde opp?" eller "Forbedre"
det er ingen styrke i den virkelige verden.
Faktisk, hva du egentlig får er en litt noe sånt som dette.
Jeg har trukket opp en av de ansatte bildene fra siden.
Dette er et program som heter Photoshop. Dette er en av to Bowdens,
1 av 3 Bowdens faktisk, i dag, fordi vi har Mrs. Bowden her også, med Rob og Paul.
Men her er Rob på skjermen, og hvis vi zoomer inn på den glimt han har alltid hatt i øyet,
hva du faktisk ser er at det du ser er hva du får.
Dette er "forbedret", så "CSI" har det litt galt.
Det er en annen klipp, hvis vi kan plukke på "CSI" bare litt lenger.
Dette er en fin setning å ytre heretter hvis du ønsker å
høres teknisk med vennene dine når, egentlig, du sier absolutt ingenting.
>> [Man] For ukene har jeg vært å undersøke Cabby Killer drapene
med en viss morbid fascinasjon.
[Woman # 1] Dette er i sanntid.
[Woman # 2] Jeg skal lage et GUI-grensesnitt ved hjelp av Visual Basic, se om jeg kan spore en IP-adresse.
>> [Malan] Så lyd ute av sync side, skaper en GUI grensesnitt ved hjelp av Visual Basic
å spore en IP-adresse er fullstendig meningsløst.
Disse dager du ikke ville bruke Visual Basic,
Det er ikke behov for en GUI, og IP-adresse var en teknisk nøyaktige betegnelsen.
Så hold et øye for disse, og en av mine favoritter:
Dette er litt mer uforståelige, fordi du trenger å vite et annet språk.
Det er et språk som kalles Objective-C, som er et overordnet C.
Noe som betyr at det er C pluss noen ekstra funksjoner, blant dem objektorientert programmering.
Og dette er det språket som Apple har popularisert for iOS programmering.
Og så her et klipp fra et annet program helt, fra "Numbers"
at hvis du faktisk ser nøye på TiVo og pause på riktig tidspunkt,
vil du se at det de ser på er ikke helt hva som blir beskrevet.
Og la meg prøve en annen lydkontakt her og se om vi ikke kan
holde lyden i sync denne gangen.
Jeg gir deg "Numbers".
>> [Man # 1] Det er en 32-bit IPv4-adresse.
[Man # 2] IP, som er Internett. >> Privat nettverk. Det er Anita private nettverk.
[Malan] Okay. Dette er Objective-C, og det er for noen gutt coloring program,
som du kan kanskje antyde fra navnet på variabelen der.
Slik at da var "Numbers". Så i dag og denne uken introduserer vi
en liten bit av verden forensics og konteksten i problemene derfor.
I dag vil være en forkortet foredrag fordi det er en spesiell hendelse her
etterpå, så vi får ta en titt, og erte både elever og foreldre alike dag
med noen av de tingene som er på horisonten.
Blant dem, og med mandag, vil du ha noen flere klassekamerater.
EDX, Harvard og MITs nye online initiativ for åpen courseware
og mer, lanserer på Harvard campus på mandag.
Noe som betyr kommer mandag vil du ha - som i forrige telling,
86000 flere klassekamerater skal følge sammen med CS50 foredrag
og seksjoner og gjennomgang og øvingsoppgaver.
Og som en del av dette, vil du bli medlemmer av innvielses klasse
CS50 og nå CS50x.
>> Som en del av dette, nå skjønner at det vil være noen oppsider også.
Å bli klar for dette, for det massive antall studenter,
nok det å si at selv om vi har 108 TFS og CAS,
ikke helt den beste student / lærer ratio når vi treffer 80000 andre studenter.
Så vi kommer ikke til å bli gradering så mange problem setter manuelt.
Så introduserte denne uken i oppgavesettet vil være CS50 Check,
som kommer til å bli en kommandolinje verktøy i apparatet
at du får når du oppdatere den senere denne helgen,
og du vil være i stand til å kjøre en kommando, sjekk 50,
på din egen pset, og du får noen tilbakemelding på om programmet er
riktig eller feil i henhold til ulike design spesifikasjoner som vi har gitt.
Så mer på det, og problemet sett spesifikasjonen og
de CS50x klassekamerater skal bruke dette også.
>> Så problemet sett 4 handler om etterforskning.
Og dette stykket var inspirert av noen virkelige ting,
der da jeg var i gradsstudier, internert jeg for en stund med
Middlesex Countys statsadvokat kontor gjør rettsmedisin
med sin leder rettsmedisinske etterforsker, og hva dette utgjorde
er, jeg tror jeg nevnte et par uke fortid, er massen State politiet eller andre
ville komme inn, ville de slippe av ting som harddisker og CDer og disketter
og lignende, og deretter mål forensics kontoret var å fastslå om
det var eller ikke var bevis av noe slag.
Dette var den Special Investigations Unit, så det var økonomisk kriminalitet,
det var mer problematisk slags forbrytelser,
noe som involverer noen form for digitale medier, viser seg at ikke så mange mennesker
skrive en e-post som sier "jeg gjorde det."
Så ganske ofte disse etterforskning søk ikke skru opp så mye frukt,
men noen ganger folk ville skrive slike e-poster.
Så noen ganger innsatsen ble belønnet.
>> Men å lede opp til dette rettsmedisinske pset, vil vi innføre i pset 4 litt grafikk.
Så du sannsynligvis ta disse tingene for gitt, JPEG, GIF og lignende i disse dager,
men hvis du virkelig tenker over det, et bilde, omtrent som Rob ansikt,
kunne bli modellert som en sekvens av punkter eller piksler.
Nå, i tilfelle av Rob ansikt, er det alle slags farger,
og vi begynte å se de enkelte punkter, otherwide kjent som piksler,
når vi begynte å zoome inn
Men hvis vi forenkle verden litt, og bare si at dette her er Rob
i svart-hvitt, vel, til å representere svart og hvitt kan vi bare bruke binær.
Og hvis vi kommer til å bruke binære, 1 eller 0, kan vi uttrykke dette samme bildet
av Rob smilende ansikt med dette mønsteret av biter: 11000011 representerer
hvit, hvit, svart, svart, svart, svart, hvit.
Og så det er ikke et stort sprang, da, for å begynne å snakke om fargerike fotografier.
Ting som du ville se på Facebook eller ta med et digitalt kamera,
men, sikkert, når det kommer til farger, trenger du flere biter.
Og ganske vanlig i verden av fotografier er å bruke ikke 1-bit farge,
da dette antyder, men 24-bits farger, hvor du faktisk får millioner av farger.
Så som i tilfelle når vi zoomet inn på Rob øye,
det var en rekke av millioner av forskjellige fargerike muligheter.
>> Så vi vil innføre dette i oppgavesettet 4 samt i walkthrough,
som vil være i dag kl 03:30 i stedet for den vanlige 02:30 på grunn av fredagens foredrag her.
Men videoen vil være online, som vanlig, i morgen.
Vi vil også introdusere deg til et annet filformat.
Så dette er bevisst ment å se skremmende i starten,
men dette er bare noen dokumentasjon for en C struct.
Det viser seg at Microsoft, år siden, hjalp popularisere dette formatet,
kalt bitmap filformat, BMP, og dette var en super-enkel,
fargerike grafiske filformat som ble brukt i ganske lang tid
og noen ganger fortsatt for bakgrunnsbilder på stasjonære maskiner.
Hvis du tenker tilbake til Windows XP og bølgende åser og blå himmel,
som var typisk en BMP, eller punktgrafikkbilde, og punktgrafikk
er moro for oss fordi de har litt mer kompleksitet.
Det er ikke fullt så enkelt som dette rutenettet av 0 og 1-ere;
stedet, har du ting som en overskrift i begynnelsen av en fil.
Så med andre ord, inne i en. Bmp-fil er en hel haug av 0 og 1-ere,
men det er litt ekstra 0 og 1-ere der.
Og det viser seg at det vi har sikkert tatt for gitt i mange år,
filformater som. doc eller. xls eller. mp3 eller. mp4,
uansett filformater som du er kjent med.
Vel, hva betyr det også bety å være et filformat?
Fordi på slutten av dagen, alle disse filene vi bruker har bare 0 og 1-ere
og kanskje de 0 og 1-ere representerer a, b, c, gjennom ASCII eller lignende,
men gjennom slutten av dagen, er det bare 0 og 1-ere.
>> Så mennesker bare sporadisk bestemmer seg for å oppfinne et nytt filformat
hvor de standardisere hva punktmønstre faktisk vil bety.
Og i dette tilfellet her, folk som designet bitmap filformat
sa at i det første byte i en bitmap fil, som vist ved offset 0, der,
det kommer til å være noen kryptisk navngitt variabel kalt bfType,
som står bare for bitmap filtype, hva slags bitmap fil dette er.
Du kan antyde, kanskje, fra den andre raden at offset 2, byte nummer 2,
har et mønster av 0 og 1-ere som representerer hva?
Størrelsen på noe, og det går derfra.
Så i oppgavesettet 4, vil du bli gått gjennom noen av disse tingene.
>> Vi vil ikke ende opp å bry seg om dem alle, men merker det begynner å bli interessant
rundt linje eller byte 54, rgbtBlue, grønn og rød.
Hvis du noen gang har hørt forkortelsen RGB, rød grønn blå, dette er en referanse til det.
Fordi det viser seg at du kan male alle farger i regnbuen
med en kombinasjon av rødt og blått og grønt.
Og, faktisk, kan foreldrene i rommet husker noen av de tidligste projektorer.
I disse dager, du bare se en lys kommer ut av en linse.
Men tilbake i dag, hadde du rødt lykteglass, den blå linsen, og den grønne linse
og sammen rettet mot skjermen og dannet et fargerikt bilde.
Og ganske ofte ungdomsskoler og videregående skoler vil ha disse linsene
aldri så litt skjevt, så du var liksom se doble eller triple bilder,
men det var ideen. Du hadde rød og grønn og blå lys male et bilde.
Og at samme prinsipp er benyttet i datamaskiner.
>> Så blant de utfordringene, da, for deg i problemet sett 4
kommer til å være et par ting, den ene er å faktisk endre størrelsen på et bilde.
Å ta i et mønster av 0 og 1-ere,
finne ut hvilke biter av 0 og 1-ere representerer det i en struktur som dette,
og deretter finne ut hvordan man kan gjenskape piksler: røde, blues, greener
innsiden slik at når et bilde ser slik ut i utgangspunktet, kan se ut som dette i stedet etter det.
Blant de andre utfordringene, også kommer til å være at du vil bli overlevert
en rettsmedisinsk bilde av en faktisk fil fra et digitalt kamera
og på det kameraet, en gang i tiden var en hel haug med bilder.
Problemet er, vi slettet ved et uhell eller hadde bildet ødelagt eller annen måte.
Dårlige ting skje med digitale kameraer, og så vi raskt kopiert alle 0 og 1-ere
ut av dette kortet for deg, lagret dem alle i en stor fil, og vi vil overlate dem til deg
i problemet sett 4, slik at du kan skrive et program i C som å gjenopprette
alle disse JPEG, ideelt.
Og det viser seg at JPEG, selv om de er litt av en kompleks filformat,
de er mye mer komplisert enn dette smilende ansikt her.
Det viser seg at hver JPEG starter med de samme mønstre av 0 og 1-ere.
Så bruke en stund sløyfe eller en for løkke eller lignende,
du kan iterere over alle 0 og 1-ere i denne rettsmedisinske bilde
og hver gang du ser den spesielle mønster som er definert i oppgavesettet spesifikasjoner,
du kan anta, 'Oh, her er, med svært høy sannsynlighet
starten på en JPEG ", og så snart du finner det samme mønsteret,
et antall byte eller kilobyte eller megabyte senere,
du kan anta, 'Ooh! Her er en annen JPEG, bildet jeg tok etter den første.
La meg slutte å lese den første filen, begynner å skrive denne nye. '
Og resultatet av programmet for pset 4 kommer til å være så mange som 50 JPEG-bilder.
Og hvis det ikke er 50 JPEG-bilder, har du litt av en loop.
Hvis du har et uendelig antall JPEG, har du en uendelig loop.
Slik at også vil være en ganske vanlig sak.
Det er hva som skjer på horisonten.
>> Quiz 0, bak oss. Realiser, per e-posten min, som alltid er det folk
som er både glade, liksom nøytral, og trist rundt quiz 0 time.
Og vennligst nå ut til meg, hodet TFS, Zamyla, din egen TF
eller en av de sertifikatutstedere som du vet om du ønsker å diskutere hvordan det gikk.
>> Så for å imponere foreldrene her i rommet,
hva er CS50 biblioteket? God jobb.
Hva er CS50 biblioteket? Ja? [Student svar, uforståelig]
>> Ok, bra. Så det er en forhåndsskrevet sett med kode som vi, de ansatte, skrev
vi gir deg, for å gi noen vanlige funksjoner.
Ting som får meg en streng, få meg en int, alle funksjoner som er oppført her.
Starter nå, begynner vi å virkelig ta disse trening hjul av.
Så vi kommer til å begynne å ta bort en "streng" fra deg,
som husker, var bare et synonym for hva som faktisk datatype? char *.
Så for foreldre, som var trolig - det er bra, så char * vi vil begynne å se
på skjermen desto mer som vi fjerner "streng" fra vårt vokabular,
i hvert fall når det gjelder å faktisk skrive kode.
Tilsvarende vil vi slutte å bruke noen av disse funksjonene så mye,
fordi våre programmer kommer til å få mer sofistikert
snarere enn å bare skrive programmer som sitter der med en rask blinkende,
venter for brukeren å skrive noe i.
Du får dine innspill fra andre steder.
For eksempel, vil du få dem fra en rekke biter på den lokale harddisken.
Du vil i stedet få dem i fremtiden fra en nettverkstilkobling, noen nettside eller annet sted.
Så la oss skrelle tilbake dette laget for første gang, og trekk opp CS50 apparatet
og denne filen som heter CS50.h, som du har vært skarp inkludert i ukevis.
>> Men la oss faktisk se hva som er på innsiden av dette.
Så toppen av filen i blått er bare en hel haug med kommentarer,
garanti samt lisensiering. Dette er liksom en felles paradigme
i programvare, fordi mye av programvaren i disse dager er det som kalles "open source"
noe som betyr at noen har skrevet inn koden
og gjorde det fritt tilgjengelig, ikke bare for å kjøre og å bruke,
men faktisk lese og endre og integrere i ditt eget arbeid.
Så det er hva du har brukt, åpen kildekode,
riktignok i en svært liten form.
Hvis jeg ruller nedover forbi kommentarene, men vil vi begynne å se noen mer kjente ting.
Så merker på toppen her, at CS50.h filen inneholder en hel haug med header filer.
Nå er de fleste av disse vi ikke har sett før, men en er
kjent; hvilke av disse har vi sett, om enn kort, så langt?
Ja, standard biblioteker. Stdlib.h har malloc,
så når vi begynte å snakke om dynamisk minne allokering,
som vi vil komme tilbake til neste uke også, begynte vi med den filen.
Det viser seg at bool og sant og usant ikke egentlig eksisterer i C, per se,
med mindre du inkluderer denne filen her.
Så vi har, i uker, vært inkludert standard bool.h
slik at du kan bruke tanken om en bool, sant eller usant.
Uten dette, ville du må sortere av falske det og bruke en int
og bare vilkårlig anta at 0 er falsk og en er sant.
>> Nå, hvis vi blar ned ytterligere, her er vår definisjon av en streng.
Det viser seg, som vi har sagt før, at der dette * er ikke virkelig betyr noe.
Du kan selv ha plass rundt.
Vi, dette semesteret, har vært fremme det som dette for å gjøre det klart at den * har å gjøre med typen.
Men innser, akkurat som vanlig, om ikke litt mer vanlig, er å sette den der
men funksjonelt er det det samme.
Men nå, hvis vi leser ned ytterligere, la oss ta en titt på si, GetInt,
fordi vi brukte det, kanskje, før noe annet dette semesteret.
Og her er GetInt. Dette er hva?
Dette er prototypen. Så ofte, har vi satt prototyper på toppen av vår. C-filer,
men du kan også sette prototyper i header-filer,. h-filer,
som en dette her, slik at når du skriver noen funksjoner
at du vil at andre skal kunne bruke, som er akkurat det tilfellet med CS50 bibliotek,
du ikke bare implementere dine funksjoner i noe som CS50.c,
du også sette prototypene ikke på toppen av denne filen, men på toppen av en header-fil,
da at header-fil er hva venner og kolleger inkluderer,
med skarpe inkludere i sin egen kode.
Så hele denne tiden har du blitt inkludert alle disse prototypene
effektivt på toppen av filen, men ved hjelp av denne skarpe inkluderer mekanismen
at vesentlig kopierer og limer denne filen til din egen.
Nå, her er noen ganske detaljert dokumentasjon.
>> Vi har ganske mye tatt for gitt at GetInt får en int,
men det viser seg at det er noen hjørne tilfeller, ikke sant?
Hva om brukeren skriver inn et tall som er altfor stor?
En kvintillioner, som bare ikke kan passe inn i en int?
Hva er forventet oppførsel? Vel, ideelt sett, er det forutsigbart.
Så i dette tilfellet, hvis du faktisk lese de fine print,
vil du se at hvis linjen ikke kan leses, dette returnerer INT_MAX.
Vi har aldri snakket om dette, men basert på kapitalisering sin,
hva er det, sannsynligvis?
Det er en konstant, så det er noen spesiell konstant som sannsynligvis erklært
i en av disse header-filer som er opp høyere i filen,
og INT_MAX er sannsynligvis noe sånt som, omtrent, 2 milliarder kroner.
Tanken er at fordi vi trenger å liksom bety at noe gikk galt,
Vi, ja, har 4000 millioner tallene til rådighet,
negative 2 milliarder på opptil 2 milliarder kroner, gi eller ta.
Vel, hva er vanlig i programmering er du stjeler bare ett av disse tallene.
Kanskje 0, kanskje 2 milliarder kroner, kanskje negative 2 milliarder kroner.
Så du bruke en av dine mulige verdier, slik at du kan forplikte seg til hele verden
at hvis noe går galt, vil jeg returnere denne super-stor verdi.
Men du ikke vil at brukeren skrive noe kryptisk som "2, 3, 4 ..."
av virkelig store tall, der du generalisere stedet som en konstant.
Så egentlig, hvis du var å være anal de siste ukene,
når du kaller GetInt, bør du ha vært sjekke med en hvis tilstanden.
Gjorde brukeren skriver inn INT_MAX, eller mer spesifikt,
gjorde GetInt tilbake INT_MAX? Fordi hvis det gjorde,
som faktisk betyr at de ikke skriver det, noe gikk galt i dette tilfellet.
Så dette er hva som vanligvis kjent som en "sentinel" verdi, noe som betyr bare spesiell.
>> Vel, la oss nå slå inn til. C-filer.
C-filen har eksistert i apparatet i lengre tid,
og, faktisk, har apparatet den ferdigbygd for deg
inn i den tingen som kalles vi "objektkode"
men det bare ikke noe for deg hvor det er fordi systemet vet,
i dette tilfellet, hvor det er, apparatet.
Men la oss rulle ned nå for å GetInt, og se hvordan GetInt har jobbet hele tiden.
Så her har vi lignende kommentarer fra før.
La meg zoome inn på akkurat den koden delen,
og hva vi har for GetInt er følgende.
Det tar ingen innspill og den returnerer en int, while (true), så vi har en bevisst uendelig loop
men, formodentlig, vil vi bryte ut av dette liksom, eller returnere fra innenfor dette.
Så la oss se hvordan dette fungerer. Vel, vi synes å bruke GetString
i denne første linje inne i sløyfen, 166.
Dette er nå god praksis fordi under hvilke omstendigheter
kunne GetString returnere denne spesielle søkeord, NULL?
Hvis noe går galt. Hva som kan gå galt når du kaller noe som GetString?
Ja? [Student svar, uforståelig] >> Ja. Så kanskje malloc mislykkes.
Somewhere under panseret GetString ringer malloc,
som tildeler minne, som lar datamaskinen butikken
alle de tegnene som brukeren skriver inn i tastaturet.
Og anta at brukeren hadde en hel masse ledig tid
og skrevet mer, for eksempel enn 2000000000 tegn.
Flere tegn enn datamaskinen har selv RAM.
Vel, har GetString å kunne betegne det til deg,
selv om dette er en super, super uvanlig hjørne saken.
Det har å liksom være i stand til å håndtere dette, og så GetString,
hvis vi går tilbake og lese dokumentasjonen, betyr faktisk tilbake NULL.
Nå hvis GetString mislykkes ved å returnere NULL, er GetInt kommer til å mislykkes
ved å returnere INT_MAX, akkurat som en vaktpost.
Dette er bare menneskelige konvensjoner. Den eneste måten du ville vite dette er tilfelle
er ved å lese dokumentasjonen.
Så la oss bla ned til der int er faktisk GotInt.
>> Så hvis jeg ruller nedover et stykke, i tråd 170 har vi en kommentar ovenfor disse linjene.
Så vi erklærer i 172, en int n og en røye c, og deretter den nye funksjonen
som noen av dere har snublet over før, men sscanf.
Dette står for streng scan f.
Med andre ord, gi meg en streng og jeg vil skanne den for opplysninger av interesse.
Så hva betyr det? Vel, antar at jeg skriver i, bokstavelig talt, 1 2 3 på tastaturet,
og deretter trykk enter. Hva er datatypen for 1 2 3 da tilbake etter GetString?
Det er åpenbart en streng, ikke sant? Jeg fikk en streng, så 1 2 3 er virkelig "1 2 3"
med \ 0 på slutten av den. Det er ikke en int.
Det er ikke et tall. Det ser ut som et tall, men det er faktisk ikke.
Så hva har GetInt å gjøre? Det har å skanne strengen venstre til høyre,
1 2 3 \ 0, og noe konvertere den til en faktisk heltall.
Nå kan du finne ut hvordan du gjør dette.
Hvis du tenker tilbake til pset 2, har du antagelig fått litt behagelig
med Caesar eller vigenere slik at du kan iterere over en streng,
du kan konvertere tegn til ints med hakke. Det er en hel masse arbeid.
Hvorfor ikke kalle en funksjon som sscanf som gjør det for deg?
Så sscanf forventer et argument, i dette tilfellet kalles linje, som er en streng.
Du kan deretter angi, i anførselstegn, svært lik printf,
hva gjør du forventer å se i denne strengen?
Hva jeg sier her er, forventer jeg å se et desimaltall og kanskje et tegn.
Og vi vil se hvorfor dette er tilfellet i bare et øyeblikk.
Det viser seg at denne notasjonen er nå minner om ting
vi begynte å snakke om litt over en uke siden.
>> Hva er & n og & c gjør for oss her? [Student svar, uforståelig]
>> Ja. Det gir meg adressen til n og adresse c.
Nå, hvorfor er det viktig? Vel, du vet at med funksjoner i C
du kan alltid gå tilbake en verdi eller ingen verdi i det hele tatt.
Du kan returnere en int, en streng, en flåte, en røye, uansett.
Eller du kan gå tilbake ugyldig, men du kan bare returnere en ting maksimalt.
Men her vi ønsker sscanf å returnere meg kanskje en int, et desimaltall,
og også en røye, og jeg skal forklare hvorfor røye i et øyeblikk.
Så du effektivt vil f å returnere to ting, det er bare ikke mulig i C.
Så du kan omgå det ved å sende inn 2 adresser,
fordi så snart du hånden en funksjon 2 adresser, hva kan denne funksjonen gjøre med dem?
Det kan skrive til disse adressene. Du kan bruke * drift og "gå dit" til hver av disse adressene.
Det er liksom dette bakdør mekanisme, men veldig vanlig for å endre verdiene av variablene
i mer enn bare en sted, i dette tilfellet to.
Nå merker jeg sjekker for == to1, og deretter returnere n hvis det ikke faktisk vurdere å true.
Så hva er det som skjer? Vel, teknisk sett, er alt vi virkelig ønsker å skje i GetInt dette.
Vi ønsker å analysere, så å si, vi ønsker å lese strengen
"1 2 3" og hvis det ser ut som det er en rekke det,
hva vi forteller sscanf å gjøre er å sette det nummeret, 1 2 3, i denne variabelen n for meg.
Hvorfor da, jeg har dette også?
Hva er rollen til også å si, sscanf, kan du også få en karakter her.
[Student sett uforståelig] >> Ikke - desimaltegn kunne fungere.
La oss holde det trodde et øyeblikk. Hva annet?
[Student, uforståelig] >> Så god tanke, kan det være den NULL karakter.
Det er faktisk ikke i dette tilfellet. Ja? [Student, uforståelig]
>> >> ASCII. Eller, la meg generalisere ytterligere.
Den% c det er bare for feil-sjekking.
Vi ønsker ikke at det skal være tegnet etter tallet,
men hva dette tillater meg å gjøre er følgende:
Det viser seg at sscanf foruten lagring verdier i n og C, i dette eksemplet her,
hva det også gjør er det returnerer antall variabler det satt verdier i.
Så hvis du bare skrive inn 1 2 3, da bare% d kommer til å matche
og bare n blir lagret med en verdi som 1 2 3 og ingenting blir satt i c;
c fortsatt en søppel verdi, så å si.
Søpla fordi det er aldri blitt initialisert som noen verdi.
Så i det tilfellet, returnerer sscanf 1 fordi jeg befolket en av disse markørene,
i så fall, flott. Jeg har en int, så befri jeg linjen for å frigjøre minne
som GetString faktisk tildelt, og da jeg kommer tilbake n.
Annet, hvis du noen gang lurt på hvor den retry uttalelsen kommer fra, kommer fra høyre her.
Hvis derimot, skriver jeg i 1 2 3 foo,
bare noen tilfeldig rekkefølge av tekst, er sscanf kommer til å se,
ooh, nummer, ooh, nummer, ooh, nummer, ooh - f.
Og det kommer til å sette 1 2 3 i n.
Det kommer til å sette f i c, og deretter tilbake to.
Så vi har, bare ved hjelp av grunnleggende definisjonen av scanf atferd,
en svært enkel måte - vel, kompleks ved første øyekast, men på slutten av dagen,
ganske enkel mekanisme for å si, er det en int, og hvis så, er at det eneste som jeg fant?
Og det hvite området her er bevisst. Hvis du leser dokumentasjonen for sscanf,
det forteller deg at hvis du inkluderer et stykke hvit mellomrom på begynnelsen eller slutten,
sscanf vil også tillate brukeren, uansett grunn, å treffe mellomromstasten 1 2 3, og som vil være legitime.
Det vil ikke kjefte på brukeren bare fordi de treffer mellomromstasten på begynnelsen eller slutten,
som er bare litt mer brukervennlig.
>> Eventuelle spørsmål, da, på GetInts? Ja?
[Student spørsmål, uforståelig]
>> Godt spørsmål. Hva om du nettopp skrev i en røye, som f, og trykk enter
uten noen gang å skrive 1 2 3, hva tror du oppførselen til denne linjen med kode vil da være?
Så sscanf kan dekke det også, fordi i så fall,
det er ikke til å fylle n eller c, det kommer til å i stedet returnere 0.
I så fall, er jeg også oppsiktsvekkende at scenario, fordi den forventede verdien jeg ønsker er en.
Jeg vil bare ha en, og bare en ting å bli fylt. Godt spørsmål. Andre?
>> All right, så la oss gå ikke gjennom alle funksjonene i her,
men den som synes å være, kanskje, av gjenværende interesse
er GetString fordi det viser seg at GetFloat, GetInt,
GetDouble, GetLongLong alle punt mye av sin funksjonalitet til GetString.
Så la oss ta en titt på hvordan han er implementert her.
Dette ser litt komplisert, men det bruker de samme grunnleggende
at vi begynte å snakke om forrige uke. Så i GetString,
som tar ingen argument som per tomrommet her oppe,
og den returnerer en streng, så jeg erklære en streng som heter buffer.
Jeg vet egentlig ikke hva som kommer til å bli brukt til ennå, men vi får se.
Ser ut som kapasiteten er som standard 0; ikke helt sikker på hvor dette går.
Ikke sikker på hva n kommer til å bli brukt til ennå.
Men nå er det å få en litt mer interessant, så i tråd 243,
Vi erklærer en int c, dette er liksom en dum detalj.
En røye er 8 bits, og 8 bits kan lagre hvor mange ulike verdier?
256. Problemet er, hvis du ønsker å ha 256 forskjellige ASCII-tegn,
som det er, hvis du tenker tilbake, og dette er ikke noe å huske.
Men hvis du tenker tilbake til den store ASCII diagrammet vi hadde uker siden,
Det var i så fall, 128 eller 256 ASCII-tegn.
Vi brukte alle mønstre av 0 og 1-ere opp.
Det er et problem hvis du ønsker å være i stand til å oppdage en feil.
Fordi hvis du allerede bruker 256 verdier for figurene dine,
du egentlig ikke planlegge, fordi nå har du ingen måte å si,
"Dette er ikke en legit karakter, dette er noen feilaktige meldingen."
Så hva verden gjør er, de bruker den neste største verdien,
noe sånt som en int, slik at du har en sprø antall biter,
32 for 4000 millioner mulige verdier, slik at du kan bare ende opp med å bruke,
hovedsak, 257 av dem, en av dem har noen spesiell betydning som en feil.
>> Så la oss se hvordan dette fungerer. I tråd 246, har jeg denne store mens loop
som ringer fgetc f mening fil, getc, og deretter stdin.
Det viser seg at dette er bare mer presis måte å si "lese inndata fra tastaturet."
Standard inngang betyr tastatur, betyr standard ut skjermen,
og standard feil, som vi vil se i pset 4 betyr skjermen,
men en spesiell del av skjermen, slik at det ikke er smeltet sammen
med den faktiske produksjonen som du hadde tenkt til å skrive ut, men mer om det i fremtiden.
Så fgetc betyr bare lese ett tegn fra tastaturet, og lagre det der?
Oppbevar den i c, og deretter sjekke, så jeg bare bruker noen logiske konjunksjoner her,
sjekk at den ikke er lik \ n, slik at brukeren har rammet inn.
Vi ønsker å stoppe på dette punktet, slutten av løkken, og vi ønsker også å sjekke
for den spesielle konstant, EOF, som hvis du vet eller antar - Hva står det for?
Slutten av filen. Så dette er slags nonsens, fordi hvis jeg skriver på tastaturet,
det er egentlig ingen fil som er involvert i dette,
men dette er liksom bare av den generelle termen brukes til å bety
at ingenting annet kommer fra menneskelige fingre. EOF. Slutten av filen.
Som en side, hvis du noen gang har truffet kontroll d på tastaturet,
ikke at du ville ha ennå, du har truffet kontroll c.
Men kontroll d sender denne spesielle konstant kalt EOF.
>> Så nå er det bare noen dynamisk minne allokering.
Så hvis n + 1> kapasitet, nå skal jeg forklare n.
n er bare hvor mange byte er for tiden i buffer,
strengen som du bygger opp fra brukeren.
Hvis du har flere tegn i buffer din enn du har kapasitet i buffer,
intuitivt, hva vi trenger å gjøre da tildele mer kapasitet.
Jeg kommer til å skumme over noen av aritmetiske her
og fokusere bare på denne funksjonen her.
Du vet hva malloc er, eller i det minste generelt kjent.
Ta en gjetning hva RealLOC gjør. [Student svar, uforståelig]
>> Ja. Og det er ikke helt legge til minne, det reallocates minne som følger:
Hvis det fortsatt er plass på slutten av strengen for å gi deg mer av det minne
enn det opprinnelig gir deg, så du får det ekstra minne.
Så du kan bare sette strenger tegn rygg mot rygg til rygg mot rygg.
Men hvis det ikke er tilfelle, fordi du ventet for lenge
og noe tilfeldig fikk plopped i minnet der, men det er ekstra
minne her nede, det er greit. RealLOC kommer til å gjøre alle de tunge løftene for deg,
flytte strengen du har lest i så langt herfra,
legge det ned der, og deretter gi deg noen mer rullebanen på det tidspunktet.
Så med en bølge av hånden, la meg si at det GetString gjør
er det å starte med en liten buffer, kanskje en enkelt karakter,
og hvis brukeren skriver inn 2 tegn, ender GetString opp
ringer RealLOC og sier: «Ooh, var en karakter ikke nok.
Gi meg 2 tegn. Så hvis du leser gjennom logikken i loop,
det kommer til å si: "Ooh, brukeren har skrevet i tre tegn.
Gi meg nå ikke 2, men 4 tegn, og deretter gi meg 8, og deretter gi meg 16 og 32 ".
Det faktum at jeg dobler kapasiteten hver gang
betyr at bufferen ikke kommer til å vokse langsomt.
Det kommer til å vokse super rask, og hva som kan være fordelen av det?
Hvorfor jeg doble størrelsen på bufferen, selv om brukeren
kanskje bare trenger en ekstra tegn på tastaturet?
[Student svar, uforståelig]. >> Hva er det?
Akkurat. Du trenger ikke å dyrke den så ofte.
Og dette er bare en slags - du sikring dine spill her.
Tanken er at du ikke ønsker å kalle RealLOC mye, fordi det har en tendens til å være treg.
Hver gang du spør operativsystemet for hukommelse, så vil du snart se
i en fremtidig problem sett, pleier det å ta litt tid.
Så minimere den tiden, selv om du kaster bort litt plass, har en tendens til å være en god ting.
>> Men hvis vi leser gjennom den avsluttende delen av GetString her,
og igjen, forstå hver enkelt linje her er ikke så viktig i dag.
Men merker at det til slutt kaller malloc igjen, og den fordeler
akkurat som mange bytes som det er behov for streng
og kaster deretter bort ved å ringe gratis, for stor buffer,
hvis det faktisk ble doblet for mange ganger.
Kort sagt, det er hvordan GetString har jobbet hele tiden.
Alt den gjør er lest ett tegn om gangen igjen og igjen og igjen
og hver gang det er behov for noen ekstra minne, spør den operativsystemet for det ved å kalle RealLOC.
Eventuelle spørsmål? OK.
>> Et angrep. Nå som vi forstår pekere, eller i det minste
blir stadig kjent med pekere,
la oss vurdere hvordan hele verden begynner å kollapse
Hvis du ikke helt forsvare seg mot fiendtlige brukere,
folk som prøver å hacke seg inn i systemet ditt.
Folk som prøver å stjele programvare ved å omgå noen registreringskode
at de kanskje ellers å skrive i.
Ta en titt på dette eksempelet her, som er bare C-kode
som har en funksjon main nederst, anrop som en funksjon foo,
og hva er det passerer til foo? [Student] Et enkelt argument.
>> Enkelt argument. Så argv [1], som betyr det første ordet som brukeren skrev
på kommandolinjen etter a.out eller hva programmet heter.
Så foo, på toppen, tar i et char *, men char * er akkurat hva?
Streng. Det er ikke noe nytt her, og at strengen er vilkårlig å bli kalt bar.
I denne linjen her, røye c [12], i form av semi-teknisk engelsk, hva denne linjen gjør?
Array of -? Tegn. Gi meg en rekke 12 tegn.
Så vi kan kalle dette en buffer. Det er teknisk kalt c, men en buffer i programmering
betyr bare en haug med plass som du kan sette noen ting i.
>> Så til slutt, memcpy, har vi ikke brukt før.
Men du kan sikkert gjette hva det gjør. Det kopierer minnet.
Hva gjør den? Vel, det tilsynelatende kopierer bar, sin inngang, i c,
men bare opp til lengden av linjen.
Men det er en feil her.
Ok, så teknisk vi skal virkelig gjøre strlen (bar) x sizeof (char), det er riktig.
Men i verste tilfelle her, la oss anta at that - så greit.
Så er det to feil. Så sizeof (char), greit, la oss gjøre dette litt bredere.
Så nå er det fortsatt en bug, som er hva?
[Student svar, uforståelig] >> Se etter hva? Ok, så vi bør sjekke
for NULL, fordi dårlige ting skje når pekeren er NULL,
Fordi du kan ende opp med å gå der, og du bør aldri gå til NULL
ved dereferencing den med * operatør.
Så det er bra, og hva annet gjør vi? Logisk det er en feil her også.
[Student svar, uforståelig]
>> Så sjekk om argc ≥ 2?
Ok, så det er 3 feil i dette programmet her.
Vi er ikke sjekker om brukeren faktisk skrevet i noe inn argv [1], bra.
Så hva er den tredje bug? Ja?
[Student svar, uforståelig] >> Good.
Så vi sjekket ett scenario. Vi implisitt sjekket ikke kopiere mer minne
enn det som ville overskride lengden bar.
Så hvis strengen brukeren skrev inn er 10 tegn lang,
dette sier, 'Kun kopiere 10 tegn.
Og det er greit, men hva om brukeren har skrevet inn et ord når du får beskjeden
som en 20 tegn ord, dette er, sier kopiere 20 tegn fra bar til hva?
c, ellers kjent som buffer vår, noe som betyr at du nettopp skrev data
til 8 byte steder som du ikke eier,
og du ikke eier dem i den forstand at du aldri tildelt dem.
Så dette er hva som vanligvis kjent som buffer overflow angrep,
eller bufferoverløp angrep, og det angrep i den forstand at dersom brukeren
eller programmet som kaller din funksjon gjør dette skadelig,
hva skjer egentlig neste kan være ganske ille.
>> La oss ta en titt på dette bildet her.
Dette bildet representerer bunke med minne.
Og huske at hver gang du ringer en funksjon,
du får denne lille rammen på stakken og deretter en annen og deretter en annen og deretter en annen.
Og så langt vi har bare slags abstrahert disse bort som rektangler
enten det på tavlen eller på skjermen her.
Men hvis vi zoomer inn på en av disse rektangler,
når du ringer en funksjon foo, viser det seg at det er mer på stakken
innsiden av rammen og at rektangelet
enn bare x-og y-og a og b, som vi gjorde snakker om swap.
Det viser seg at det er noen lavere nivå detaljer,
blant dem returadressen.
Så det viser seg når main kaller foo, har viktigste å informere Foo
hva main adresse er i datamaskinens minne.
Fordi ellers er så snart Foo gjort utfører, som i dette tilfelle her,
når du kommer så nær krøllete brace på slutten av foo,
hvordan pokker vet foo hvor kontroll av programmet er ment å gå?
Det viser seg at svaret på det spørsmålet er i den røde rektangelet her.
Dette representerer en peker, og det er opp til datamaskinen for å lagre, midlertidig,
på den såkalte stabel adressen main slik at så snart Foo gjøres utfører,
maskinen vet hvor og hvilken linje i hoved å gå tilbake til.
Lagret ramme pekeren vedrører tilsvarende til dette.
Char * bar her representerer hva?
Vel, nå denne blå segmentet her er Foo ramme, hva er bar?
Ok, så bar bare argumentet til foo funksjonen.
>> Så nå er vi tilbake på det kjente bildet.
Det er flere ting og flere distraksjoner på skjermen
men dette lyseblå segmentet er det vi har vært tegning på tavla for noe sånt swap.
Det er rammen for foo og det eneste i det akkurat nå er bar,
som er denne parameteren.
Men hva annet bør være i bunken, ifølge denne koden her?
Char c [12]. Så vi bør også se 12 ruter minne,
allokert til en variabel kalt c.
Og faktisk vi har det på skjermen.
Helt øverst er det c [0], og deretter forfatteren av dette diagrammet
ikke bry tegne alle kvadrater, men det er faktisk 12 der
fordi hvis du ser nederst til høyre, c [11], hvis du teller fra 0, er de 12 slike byte.
Men her er problemet: I hvilken retning er c vokser?
Sortering av toppen og ned, ikke sant? Hvis det begynner øverst og vokser til bunnen,
ser ikke ut som vi forlot oss mye rullebane her i det hele tatt.
Vi har slags malt oss inn i et hjørne,
og at c [11] er helt opp mot bar, som ligger rett opp mot bunken ramme pekeren,
som er rett opp mot returadresse, det er ikke mer plass.
Så hva er konsekvensen, da, hvis du skru opp,
og du prøver å lese 20 bytes i en 12-byte buffer?
Hvor er de åtte flere byte kommer til å gå?
Inne alt annet, er noen av dem super viktig.
Og det viktigste, potensielt, er den røde boksen der, returadresse.
Fordi anta at du er enten ved et uhell eller adversarially
overskrive de 4 bytes, som peker adresse,
ikke bare med søppel, men med et nummer som skjer for å representere en faktisk adresse i minnet?
Hva er implicaiton, logisk?
[Student svar, uforståelig] >> Nettopp. Når Foo returnerer
og treff som krøllete brace, er programmet kommer til å fortsette å ikke gå tilbake til hovedsiden,
det kommer til å gå tilbake til hva adressen er i det røde boksen.
>> Nå, i tilfelle av omgå programvare registrering,
hva er adressen som blir returnert til er funksjonen
som normalt blir kalt etter at du har betalt for programvaren og lagt inn din registreringskode?
Du kan sortere på lure datamaskinen i å ikke gå her, men i stedet går opp her.
Eller, hvis du er virkelig flink, kan en motstander faktisk skrive på tastaturet,
for eksempel, ikke en faktisk ord, ikke 20 tegn, men antar han eller hun
typer i enkelte tegn som representerer koden?
Og det kommer ikke til å være C-kode, kommer det til å være tegn
som representerer binære maskinen koder, 0 og 1-ere.
Men antar at de er smarte nok til å gjøre det, å liksom lime inn i GetString spør
noe som er egentlig kompilert kode,
og de siste 4 byte overskrive returadresse, og hva adressen ikke at innspill gjøre?
Den lagrer i denne røde rektangelet adressen til den første byte i buffer.
Så du må være veldig flink, og dette er en mye prøving og feiling
for dårlige mennesker der ute, men hvis du kan finne ut hvor stor denne bufferen er,
slik at de siste få byte i inngangen som du gir til programmet
skje for å være tilsvarende adressen til starten av bufferen din,
du kan gjøre dette. Hvis vi sier, normalt, hallo, og \ 0, er at hva som ender opp i bufferen.
Men hvis vi er mer flink, og fylle vi at buffer med hva vi vil generelt kaller angrep kode,
A, A, A, A: Attack, angrep, angrep, angrep, der dette er bare noe som gjør noe dårlig.
Vel, hva skjer hvis du er virkelig flink, kan du gjøre dette:
I den røde boksen her er en sekvens av tall: 80, CO, 35, 08.
Legg merke til at det samsvarer med tall som er her oppe.
Det er i motsatt rekkefølge, men mer om det en annen gang.
Legg merke til at denne avkastningen adressen er bevisst endret
til lik adresse her oppe, ikke adressen til main.
Så hvis skurken er super smart, er han eller hun kommer til å inkludere i det angrepet kode
noe sånt som "Slett alle brukerens filer.
Eller "Kopier passord" eller "Opprett en brukerkonto som jeg kan logge inn. '
Noe i det hele tatt, og dette er både faren og kraften i C.
Fordi du har tilgang til minnet via pekere
og du kan derfor skrive alt du vil inn i en datamaskin minne.
Du kan lage en datamaskin gjøre hva du vil bare ved
ha det hopper rundt i sin egen plass i minnet.
Og så til denne dag, så mange programmer og så mange nettsteder som er kompromittert
koke ned til folk som tar seg av dette.
Og dette kan virke som en super-avansert angrep,
men det ikke starter alltid på den måten.
>> Realiteten er at det dårlige mennesker vil vanligvis gjør er,
enten det er et program på en kommandolinje eller et GUI-program eller et nettsted,
er du bare begynne å tilby tull.
Du skriver i en virkelig store ord i søkefeltet og trykk enter,
og du vente å se om nettstedet krasjer.
Eller du vente å se om programmet manifesterer noen feilmelding.
Fordi hvis du får heldig, som bad guy,
og du gi noen sprø innspill som krasjer programmet,
det betyr at programmereren ikke forutse din dårlig oppførsel
som betyr at du kan sannsynligvis, med nok innsats,
nok prøving og feiling, finne ut hvordan å føre en mer presis angrep.
Så like mye en del av sikkerhet er ikke bare å unngå disse angrepene helt, men registrerer dem
og faktisk ser på loggene og se hva gale innganger har folk skrevet inn i din webside.
Hvilke ord har folk skrevet inn i din webside i håp om overfylte noen buffer?
Og alt dette koker ned til det enkle grunnleggende for hva som er en matrise,
og hva betyr det å allokere og bruke minne?
Og relatert til det også, er dette.
>> Så la oss bare se innsiden av en harddisk enda en gang.
Så du husker fra en uke eller to siden at når du drar filer
til papirkurven eller papirkurven kan, hva skjer?
[Student] Ingenting. >> Ja, absolutt ingenting. Slutt hvis du kjører lite
diskplass, vil Windows eller Mac OS begynne å slette filene for deg.
Men hvis du drar noe der, så er det ikke i det hele tatt trygt.
All romkompis, venn eller familiemedlem har å gjøre er å klikke dobbel, og voila.
Det er alle de sketchy filer som du prøvde å slette.
Så de fleste av oss i det minste vite at du må høyreklikke eller Kontroll-klikk
og tømme papirkurven, eller noe sånt.
Men selv da, som ikke helt gjøre triks.
For hva skjer når du har en fil på harddisken din
som representerer noen word-dokument eller noen JPEG?
Og dette representerer harddisken din, og la oss si at dette sliver her representerer den filen,
og det er sammensatt av en hel haug av 0 og 1-ere.
Hva skjer når du ikke bare dra den filen til søppelbøtte eller papirkurven,
men også tømme den?
Sortering av ingenting. Det er ikke absolutt ingenting nå.
Nå er det bare ingenting, fordi et lite noe som skjer i form av denne tabellen.
Så det er en slags database eller tabell på innsiden av en datamaskin minne
som har vesentlig en kolonne for filer navn,
og 1 kolonne for filens plassering, hvor dette kan være plassering 123, bare et tilfeldig nummer.
Slik at vi kan ha noe sånt X.jpg og plassering 123.
Og hva skjer da, når du tømmer papirkurven?
Det går unna. Men hva går ikke bort er 0 og 1-ere.
>> Så hva er da den forbindelse pset 4?
Vel, med pset 4, bare fordi vi har slettet ved et uhell
Compact Flash-kort som hadde alle disse bildene,
eller bare fordi det ved uflaks ble ødelagt,
betyr ikke at 0 og 1-ere er ikke der ennå.
Kanskje noen av dem er tapt fordi noe ble ødelagt
i den forstand at noen 0-tallet ble en og 1-ere ble 0-tallet.
Dårlige ting kan skje på grunn av buggy programvare eller defekt maskinvare.
Men mange av disse bitene, kanskje 100% av dem er fortsatt der,
det er bare at datamaskinen eller kameraet ikke vet hvor JPEG 1 startet
og hvor JPEG 2 startet, men hvis du, programmerer,
vet, med litt peiling, hvor disse JPEG er eller hvordan de ser ut,
du kan analysere 0 og 1-ere og si: "Ooh. JPEG. Ooh, JPEG.
Du kan skrive et program med egentlig bare en for eller mens loop
som gjenoppretter hver og en av disse filene.
Så leksjonen da, er å starte "sikkert" slette filene dine
Hvis du ønsker å unngå dette helt. Ja?
[Student spørsmål, uforståelig]
>> Har mer minne enn du gjorde før -
Oh! Godt spørsmål. Så hvorfor da etter tømming av søppel,
forteller datamaskinen du at du har mer ledig plass enn du gjorde før?
I et nøtteskall, fordi det lyver. Mer teknisk, har du mer plass.
Fordi du nå har sagt, kan du sette andre ting der filen en gang var,
men det betyr ikke at de biter går bort,
og det betyr ikke at bitene blir endret hele 0-tallet, for eksempel, for å beskytte deg.
Derimot, hvis du "sikkert" slette filer, eller fysisk ødelegge enheten,
det er virkelig den eneste måten noen ganger, rundt det.
Så hvorfor ikke vi la på at semi-skremmende notat, og vi vil se deg på mandag.
CS50.TV