>> [Musikk spilles]
>> DAVID J. MALAN: All right.
>> [Latter]
>> Velkommen tilbake.
Dette er CS50.
Og dette slutten av uke fem.
Og frem til nå, har vi ganske mye tatt for gitt at det
eksisterer denne kompilatoren, Clang, at du har blitt påkalle ved hjelp av denne
andre verktøy kalt Gjør som liksom magisk konverterer kildekoden
til objektkode, nuller og enere at datamaskinene CPU, sentral
processing unit, forstår faktisk.
Men det viser seg at det er et tall som er skjer under panseret i
mellom inngang og utgang.
>> Og jeg ønsker å foreslå at vi kjøtt at ut i litt mer detalj i
disse fire trinnene, har noe som kalles pre-prosessering, noe
kalles kompilering, som vi har sett, noe som kalles montering, og
noe som kalles linking.
Så frem til nå, i noen av våre programmer, har vi hatt skarpe omfatter.
Mer nylig har vi hatt noen skarpe definerer for konstanter.
Så det viser seg at de tingene som er prefiks med hash symbol eller
pundet symbolet er pre-prosessor direktiver.
Det er bare en fancy måte å si det en linje med kode som faktisk er
omgjort til noe annet før datamaskinen selv prøve å konvertere
programmet inn nuller og enere.
>> For eksempel inneholder skarp standard I / O. H, ganske mye betyr bare gå
fremover, ta tak i innholdet i filene stdio.h og lime dem rett der.
Så ingen nuller og enere på det tidspunktet ennå.
Det er egentlig bare et bytte.
Og det er gjort under den såkalte pre-prosessering stadium, når du
faktisk kjøre Clang eller spesifikt Lag i de fleste tilfeller.
Så alt dette har skjedd første automatisk så langt.
>> Så kommer kompilering trinn.
Men vi har vært unyansert kompilering.
Kompilere et program betyr egentlig å ta det fra noe sånt som C, den
kildekoden vi har skrevet, ned til noe som kalles montering.
Assembly er et lavere nivå språk som, heldigvis, vil vi ikke
har mye anledning til å skrive dette semesteret.
Men det er på det laveste nivået i forstand at du bokstavelig talt begynner å skrive
legge til og trekke fra og multiplisere og laste fra minnet og lagre i minnet, den
svært grunnleggende instruksjoner som en datamaskin, under panseret,
faktisk forstår.
>> Til slutt, tar montere dette språket til de nuller og enere som vi har vært
beskriver så langt.
Og virkelig slutt, det er den såkalte linking fasen, som vi vil
se på bare et øyeblikk, som kombinerer dine nuller og enere med nuller og
som andre mennesker før du har opprettet.
>> Så vurdere dette super enkelt program.
Det var fra uke 1.
Det sa bare: Hello World, på skjermen.
Vi kjørte dette gjennom Clang.
Eller vi kjørte det gjennom Pass som kjørte Clang.
Og sendes ut på det tidspunkt hvor noen nuller og enere.
Men det viser seg at det er et mellomliggende trinn.
Hvis jeg går over her - oops, gjorde ikke ønsker å se ham ennå.
Hvis jeg går over her til apparatet mitt og jeg åpner opp hello.c, her
er det samme programmet.
Og hva jeg skal gjøre i terminalen min vinduet her er jeg kommer til å
kjøre Clang snarere enn Gjør som automatiserer alle fire
disse trinnene for oss.
Og jeg kommer til å gjøre klang-S og deretter hello.c og deretter inn.
>> Og jeg får en blinkende melding igjen, noe som er godt.
Og nå i en litt større vindu, Jeg kommer til å åpne opp gedit her.
Og jeg kommer til å åpne opp en fil som, viser seg, kalles hello.s dette
inneholder det assembly Jeg refererte til tidligere.
Og dette er det som kalles montering språk, ganske lavt nivå
instruksjoner du Intel CPU eller hva det er som er inni
forstår.
Og mov er for trekk. samtalen er for ringer, et meget lavt nivå funksjon.
sub er for trekke fra.
>> Så når du har en spesiell CPU inne av datamaskinen, hva som gjør det
distinkte, versus andre CPUer på markedet, som instruksjoner det
forstår og ofte hvor effektiv den er, hvor fort det er på kjøre noen
av disse instruksjonene.
Nå for mer om dette, kan du ta neste høst CS61 ved høgskolen.
Men her har vi, for eksempel, noen identifikatorer som kan se kjent.
hello.c er navnet på programmet.
>> . Tekst -
det er ikke mye av interesse der bare nå, husker at teksten
segment, som av mandag, er hvor i minne programmet ender faktisk opp.
Så det er i hvert fall vagt kjent der.
Her er naturligvis en nevne av våre viktigste funksjon.
Bla nedover, disse refererer til ting såkalte registre, svært små biter av
minne innsiden av selve CPU.
Og hvis jeg ruller ned enda videre, ser jeg en slags
indirekte omtale av ASCII.
Og der, ja, det er streng, hallo, komma, verden.
>> Så lang historie kort, dette har vært skjer for deg, automatisk,
under panseret hele denne tiden.
Og hva har skjedd er virkelig en gang du har kjørt Clang, eller i form av
Lag, du får først, fra kildekoden, jo
såkalt assembly.
Deretter Clang er å konvertere denne forsamlingen språk ned til nuller og enere.
Og dette er lysbildet som vi startet vår diskusjon i uke 0 på -
og deretter Uke 1 på.
Og så til slutt, de nuller og enere er kombinert med nuller og enere
fra disse bibliotekene har vi tatt for gitt som standard I / O eller
String Library eller den CS50 biblioteket.
>> Så for å male dette bildet mer visuelt, har vi hello.c.
Og det, selvfølgelig, bruker printf fungere å si, hallo verden.
Sammenstillingen trinnet tar den ned til den filen vi nettopp så hello.s, selv
selv om det er typisk slettet automatisk for deg.
Men det er assemblerkode i midten trinn.
Og så når vi monterer forsamlingen språk, så å si, er at når du
få disse nuller og enere.
Så vi har zoomet inn effektivt i dag på det vi har tatt for gitt,
betyr å gå kildekoden til å protestere kode.
>> Men til slutt, nå som samme bilde - la oss skyve den over til
venstre side.
Og vær oppmerksom på at toppen er det Jeg nevnte stdio.h.
Det er en fil som vi har inkludert i nesten alle av de
programmene vi har skrevet.
Og det er den filen der innholdet få kopi limes,
effektivt toppen koden din.
Men det viser seg at, på en datamaskin systemet et sted, er det antagelig en
stdio.c fil som noen skrev år siden som implementerer all
funksjonene som ble erklært i stdio.h.
>> Nå i virkeligheten er det sannsynligvis ikke på Mac-en eller PC-en eller i
CS50 apparatet er en rå C-kode.
Noen allerede samlet det og inkludert . O-fil for objekt-kode eller. En
fil, som refererer til en felles bibliotek som er blitt forhåndsinstallert og
pre-kompilert for deg.
Men anta at det faktisk finnes på vår datamaskin stdio.c parallelt
med Clang.
Koden som blir kompilert og montert.
stdio.c 's koden blir kompilert og montert, slik at dette siste
trinn, her nede, må vi liksom link, så å si, dine nuller og enere
med hans eller hennes nuller og enere i ett enkelt program som til slutt er
kalt bare Hello.
>> Så det er all den magien som er skjedd så langt.
Og vil fortsette å ta disse prosesser for gitt, men innser
det er mye av saftige detaljer skjer under der.
Og dette er det som gjør din datamaskin med Intel inne
spesielt tydelig.
>> Så på dette notatet, hvis du ønsker å bli med oss ​​til lunsj denne fredagen, går
til den vanlige plassen cs50.net/rsvp, 13:15 denne fredagen.
Og nå noen kunngjøringer.
Så vi har noen gode nyheter.
Og vi har noen dårlige nyheter.
Starte med noen gode nyheter her.
>> [Tenker:]
>> OK.
Vel, det er teknisk sett en ferie, så det er ikke så mye en gave fra oss.
Men da de dårlige nyhetene selvfølgelig.
>> [Tenker:]
>> Jeg brukte mye tid på disse animasjonene.
>> [Latter]
>> Det vil bli en gjennomgang session førstkommende mandag.
Det kommer til å være på 05:30.
Vi vil minne deg om alle disse detaljene via e-post på kursets
nettsiden i løpet av et par dager tid.
Det vil bli filmet og gjort tilgjengelig kort tid etterpå.
Så hvis du ikke kan gjøre det mandag natt slot, ikke bekymre deg.
Seksjoner denne kommende uken vil også fokus på vurdering for quiz.
Hvis delen er på mandag, som er faktisk universitet ferie, vil vi
fortsatt møtes i seksjonen.
Hvis du bare ikke kan gjøre det delen fordi du kommer
borte, det er fint.
Delta på en søndag eller tirsdag seksjon eller tune-in til Jasons delen, som er
tilgjengelig på nettet.
>> Så, flere dårlige nyheter.
Så i henhold til pensum, vi har forelesning neste fredag.
Men den gode nyheten -
klart, jeg har brukt for mye tid på dette.
>> [Latter]
>> Vi vil avbryte neste fredag ​​forelesninger.
Så det vil være en gave til oss, slik at du kan virkelig ha en fin frist i
mellom denne uken og to uker frem i tid.
Så ingen forelesninger neste uke, bare en liten liten quiz, som du bør være
får stadig mer spent.
>> Så la oss nå vende oppmerksomheten mot noe som faktisk er mer visuell
og mer spennende, og for å sette scenen for hva som kommer til å være på horisonten
i løpet av et par ukers tid.
Etter den første quiz, vil vi snu fokusere på våre oppgavesett til en annen
domene spesifikt problem, nemlig etterforskning eller sikkerhet mer generelt.
>> Faktisk, tradisjonen med dette problemet sett er for meg en av de
undervisning stipendiat eller CAer å gå over campus å ta noen bilder av
identifiserbare, men ikke åpenbare mennesker, steder, eller ting, deretter hvert år jeg
eller annen måte klarer å ved et uhell sletter eller ødelegge digital media kortet
det er innsiden av kameraet vårt.
Men ingen big deal.
Jeg kan gå videre og koble som inn i datamaskinen min.
Jeg kan lage en rettsmedisinsk bilde av det, så å snakke, ved å kopiere nuller og
de av av at minnekortet, enten sin et SD-kort eller Compact Flash-kort eller
hva du er kjent med.
Og så kan vi overlate den ut.
>> Og så utfordringen fremover, blant annet ting for deg, vil være å skrive
C-kode som gjenoppretter en hel haug med JPEG-bilder for meg og avslørt vil være
disse personer, steder eller ting.
Og vi vil også snakke, i dette problemet satt, og i dagene som kommer, om
Grafikken mer generelt.
Vi har brukt dem, et kurs, for å bryte ut.
Men du har liksom tatt for gitt det finnes disse høye nivå forestillinger
av rektangler og ovaler.
Men under panseret det er piksler.
Og du har måttet starte tenker om dem.
Eller vil du for p-set fire må tenke om gapet mellom mursteinene, hvordan
raskt du ball beveger seg på tvers skjermen for å bryte ut.
Så det er denne forestillingen om den prikker på skjermen som er
kommer inn i bildet allerede.
>> Nå hva du ser, er imidlertid hva du får på en dataskjerm.
Hvis du noen gang har sett noen gode eller dårlig TV, oddsen er de ganske mye
behandle publikum som teknofober som ikke egentlig
vet mye om databehandling.
Og så det er svært enkelt for politiet detektiv å si, kan du
rydde det opp for meg?
Eller forbedre, ikke sant?
Forbedre er som den buzz ordet i de fleste noen forbrytelse relatert show.
Og realiteten er hvis du tar en svært uskarpt bilde av en mistenkt gjøre
noe dårlig, kan du ikke bare forbedre den.
Du kan ikke zoome inn uendelig.
Du kan ikke se i glimt av noens øye som begikk at
Særlig kriminalitet, til tross for Forekomsten av dette på TV.
>> Og så med det la oss motivere at kommende problem satt med et glimt i
noen show som du kan bli kjent.
>> [VIDEOAVSPILLING]
>> -OK.
Nå, la oss få en god titt på deg.
>> -Hold det.
Kjør den tilbake.
>> -Vent litt.
Gå rett.
>> -Det.
Fryse det.
>> -Full skjerm.
>> -OK.
Fryse det.
>> -Stram opp på det, vil ya?
>> -Vector inn på den fyren av bakhjulet.
>> -Zoom inn her på dette stedet.
>> -Med det rette utstyret, avbildes kan forstørres og skjerpet.
>> -Hva er det?
>> -Det er en forbedring program.
>> -Kan du klare det opp noe?
>> -Jeg vet ikke.
La oss forbedre den.
>> -Forbedre seksjon A-6.
>> -Jeg forbedret detaljer og -
>> -Jeg tror det er nok til å øke.
Slipper den til skjermen min.
>> -Forbedre refleksjonen i øyet hennes.
>> -La oss kjøre dette gjennom video ekstrautstyr.
>> -Edgar, kan du forbedre dette?
>> -Vent.
>> -Jeg har jobbet med denne refleksjonen.
>> -Noens refleksjon.
>> -Refleksjon.
>> -Det er en refleksjon av mannens ansikt.
>> -The refleksjon.
>> -Det er en refleksjon.
>> -Zoom inn på speilet.
>> Du kan se en refleksjon.
>> -Kan du forbedre bildet herfra?
>> -Kan du forbedre ham akkurat her?
>> -Kan du forbedre den?
>> -Kan vi forbedre dette?
>> -Kan du forbedre den?
>> -Vent litt, jeg skal forbedre.
>> -Zoom inn på døren.
>> -X10.
>> -Zoom.
>> [Latter]
>> -Flytt i.
>> -Vent, stopp.
>> -Stopp.
>> -Pause det.
>> -Roter en 75 grader rundt den vertikale behage.
>> [Latter]
>> -Stopp, og tilbake til den delen om døren igjen.
>> -Fikk et bilde Enhancer som kan punktgrafikk?
>> -Kanskje vi kan bruke Pradeep Sen metode for å se inn vinduene.
>> -Denne programvaren er state of the art.
>> -Ikonet verdi er av.
>> -Med den rette kombinasjonen av algoritmer.
>> -Han har tatt belysning algoritmer for å neste nivå, og jeg kan bruke dem til å
forsterke dette bildet.
>> -Lås på og forstørre z-aksen.
>> -Forbedre.
>> -Fryse og forbedre.
>> [END VIDEOAVSPILLING]
>> DAVID J. MALAN: Så Problem Set 5 er hva som ligger foran der.
Så vi vil snart få en bedre forståelse av når og hvorfor du kan
og vår ikke kan forbedre på den måten.
Men først, la oss gå tilbake vår oppmerksomhet til noen av de byggesteinene vi vil
må være i stand til å fortelle denne historien.
>> Så husker at vi trakk dette bildet på Mandag og litt forrige uke.
Og dette beskriver oppsettet av ting i datamaskinens minne når
kjører noen program.
Den tech segment opp toppen, tilbakekalling, henviser til selve nuller og enere
som komponerer programmet.
Det er, under det, noen initialisert eller uinitialiserte data, som typisk
refererer til ting som konstanter eller strenger eller globale variabler som har
blitt erklært på forhånd.
Det er haugen, men vi vil komme tilbake til den i en bit.
>> Og så er det stabelen.
Mye som en stabel med magasiner i kafeteria, dette er hvor minnet blir
lagdelt og lagvis når du gjør det i et program?
Hva er bunken bruk for?
>> Yeah?
>> Call of funksjon.
Hver gang du kalle en funksjon, er det gitt til flis av minnet for sin
lokale variabler eller dets parametre.
Og billedlig, ser vi at med hver suksessiv funksjon kalles, når A
samtaler B syner C syner D, de bli lagvis på bunken.
Og innenfor hver av disse skiver minne er egentlig et unikt omfang
for denne funksjon, som selvsagt er problematisk hvis du ønsker å levere
fra en funksjon til en annen Et stykke av data som du vil ha det
å mutere eller endre.
>> Så hva var vår løsning for å aktivere En funksjon representert ved en stabel
ramme for å endre minnet inne av en annen stack ramme?
Hvordan disse to snakke med hverandre?
Så ved hjelp av pekere eller adresser, som, igjen, bare beskrive hvor i
hukommelse, i form av en spesifikk bit nummer, den bestemte
verdi kan bli funnet.
Så husker sist også vi fortsatte historien og så på en
ganske buggy program.
Og dette programmet er buggy for noen grunner, men den mest bekymringsfulle er ett
fordi den ikke klarer å kontrollere hva?
>> Ja, ikke det å kontrollere kilden.
Sorry?
>> Hvis det er mer enn 12 tegn.
Så veldig smart, når du ringer memcopy, som, som navnet antyder, bare
kopier minne fra sin andre argument inn i sin første argumentet.
Det tredje argumentet, veldig smart, er kontrolleres for å forsikre deg om at du ikke
kopiere mer enn, i dette tilfellet lengden av bar, antall tegn,
inn i målet, er der denne matrise C. Men problemet er at det
hvis C i seg selv er ikke stor nok å håndtere det?
Du kommer til å kopiere antallet bytes som du har fått.
Men hva gjør du egentlig har mer bytes enn du har plass til?
>> Vel, dette programmet veldig tåpelig bare blindt fortsetter å ta hva det er
gitt, er hallo backslash 0 flott hvis strengen er kort
nok, som fem tegn.
Men hvis det er faktisk 12 tegn eller 1200 tegn, så vi forrige gang
at du bare kommer til helt overskrive minnet som
ikke tilhører deg.
Og verste fall, hvis du overskrive røde delen der som vi kalte
returadresse -
Dette er nettopp der datamaskinen automatisk, for deg, bak
scener, tucks unna en 32-bits verdi som minner det til hvilken adresse det skal
tilbake når foo, denne annen funksjon, gjøres utføring.
Det er et brød smule av sorterer til hvilken den returnerer.
Hvis du overskriver at det potensielt hvis du er skurken, kan kunne
potensielt ta over noens datamaskin.
Og du vil ganske sikkert krasjer den i de fleste tilfeller.
>> Nå er dette problemet ble bare forverret så vi begynte å snakke om hukommelse
forvaltning mer generelt.
Og malloc, for hukommelse tildeling, er en funksjon som vi kan bruke til å tildele
minne når vi ikke vet på forhånd at vi kanskje trenger noen.
Så, for eksempel, hvis jeg går tilbake til apparatet her.
Og jeg åpner opp fra forrige gang hello2.c, husker dette programmet her, som så
litt noe sånt som dette, bare tre linjer -
oppgi navn, deretter string navn, til venstre, lik getstring.
Og da vi skrive den ut, brukerens navn.
>> Så dette var en super enkelt program.
Å være klar, la meg gå videre og gjøre hallo-2.
Jeg kommer til å gjøre dot slash hallo-2.
Oppgi navn -
David.
Enter.
Hei David.
Det ser ut til å fungere OK.
Men hva som egentlig skjer under panseret her?
Først la oss skrelle tilbake noen lag.
String er bare et synonym vi har realisert for hva?
Char stjerne.
Så la oss gjøre det litt mer uforståelige men mer teknisk korrekt at dette
er en char stjerne, som betyr at navn, ja, er en variabel.
Men hva navn butikker er adressen til en røye, som føles litt rart
fordi jeg får tilbake en streng.
Jeg får tilbake flere chars ikke en røye.
>> Men selvfølgelig, trenger du bare den første røye adresse å huske hvor
Hele streng er fordi hvorfor?
Hvordan finne du ut hvor enden av strengen er å vite i begynnelsen?
Den omvendte skråstreken null.
Så med disse to ledetråder du regne ut før begynnelsen og slutten av
noen streng er, så lenge de er skikkelig dannet med at null
terminator, som backslash null.
>> Men dette er ringer getstring.
Og det viser seg at getstring hele denne tiden har vært litt
juks for oss.
Det har gjort dette arbeidskraft, for å være sikker, får en streng fra brukeren.
Men hvor er det minne kommet fra?
Hvis vi går tilbake til bildet her og gjelder definisjonen fra bare en
øyeblikk siden, at bunken er der minnet går når funksjonene kalles,
den logikken, når du ringer getstring, og da jeg skriver i
D-A-V-I-D Enter, der er D-A-V-I-D skråstrek null lagres, utgangspunkt i
historie vi har fortalt oss langt?
>> Det synes å være i bunken, ikke sant?
Når du ringer får streng du får en lite stykke minne på stakken.
Så det står til grunn at D-A-V-I-D backslash null lagres
der i bunken.
Men vent litt, getstring avkastning strengen, så å si, som betyr
det er skuffen fra kantina er tatt av stabelen.
Og vi sa sist gang at så snart en funksjonen returnerer, og du tar det
skuffen, så å si, av stabelen, hva kan du anta om restene av
som minne?
Jeg slags redrew dem som spørsmålstegn fordi de effektivt blir
ukjente verdier.
De kan gjenbrukes når noen neste funksjonen kalles.
>> Med andre ord, hvis vi tilfeldigvis å være lagring -
Jeg skal tegne et raskt bilde her av stabelen.
Hvis vi måtte være tegning bunnen av min hukommelse segment, og vi vil si
at dette er stedet for minne okkupert av hoved-og kanskje arg c og
arg v og alt annet i programmet, når getstring kalles,
formodentlig getstring får en del av minnet her.
Og deretter D-A-V-I-D liksom ender opp i denne funksjonen.
Og jeg kommer til å overforenkle.
Men la oss anta at D-A-V-I-D backslash null.
Så dette mange byte brukes i rammen for getstring.
>> Men så snart getstring avkastning, vi sa sist gang at dette minnet i løpet
her hele blir - woops! -
alt blir effektivt slettet.
Og vi kan tenke på dette nå som spørsmålet karakterer fordi hvem vet
hva kommer til å bli av dette minnet.
Faktisk, jeg veldig ofte kaller funksjoner annet enn getstring.
Og så snart jeg ringe noen andre funksjon enn getstring, kanskje ikke i
dette programmet vi har nettopp sett på, men noen andre, sikkert noen andre
Funksjonen kan ende opp med å bli gitt dette neste sted i bunken.
>> Så det kan være at getstring butikker D-A-V-I-D på stabelen fordi jeg ville
umiddelbart miste tilgang til den.
Men vi vet at de getstring returnerer bare hva?
Det er ikke tilbake til meg seks tegn.
Hva er det virkelig tilbake gjorde vi konkludere siste gang?
Adressen til den første.
Så en eller annen måte, når du ringte getstring, det er tildeling av en del av minnet for
strengen at brukerne skriver og deretter returnere adressen til det.
Og det viser seg at når du ønsker å fungere å allokere minne i denne
måte og gå tilbake til personen som ringte at funksjon, adressen
som del av minnet, absolutt du kan ikke sette den i bunken på
bunn, fordi funksjonelt er det bare skal ikke bli din veldig
raskt, så du kan sikkert gjette hvor vi sannsynligvis kommer til å kaste den
stedet, den såkalte haug.
>> Så mellom bunnen av hukommelsen sin layout og toppen av hukommelsen sin
layout er en hel haug med segmenter.
Den ene er stabelen, og rett ovenfor er det haugen.
Og heap er bare en annen del av minne som ikke brukes for funksjoner
når de blir kalt.
Det er brukt for lengre sikt minne, når du vil ha en funksjon for å hente noen
minne og være i stand til å henge på den uten å miste kontroll over det.
>> Nå kan du kanskje umiddelbart se at dette ikke er
nødvendigvis en perfekt design.
Som programmet tildelte minnet på bunken, eller som du kaller mer og
flere funksjoner, eller som du tildele minne på haugen med malloc av som
getstring gjør, hva klart synes å være uunngåelig problem?
>> Høyre.
Liker det faktum at disse pilene peker mot hverandre
lover ikke godt.
Og ja, vi kunne svært raskt krasje et program i en rekke måter.
Faktisk tror jeg vi kan ha gjort dette ved et uhell en gang.
Eller hvis ikke, la oss gjøre det bevisst nå.
La meg gå videre og skrive super raskt et program som heter dontdothis.c.
Og nå skal jeg gå inn her og ikke skarp inkluderer stdio.h.
La oss erklære funksjon foo tar ingen argumenter, som er
betegnes som godt av tomrommet.
>> Og det eneste foo kommer til å gjøre er samtale foo, som trolig ikke er den
smarteste ideen, men så bli det.
Ent viktigste ugyldig.
Nå er den eneste tingen viktigste kommer å gjøre er å ringe foo også.
Og bare for morro skyld, jeg kommer til å gå fremover her og si printf "Hello from
foo. "
>> OK.
Så hvis jeg ikke gjør noen feil, Gjør dontdothis dot slash.
Og la oss gjøre det i et større vindu -
dot slash, dontdothis.
Kom igjen.
Uh oh.
Angivelig, kan du gjøre dette.
Pokker.
OK.
Vent.
Stand by.
Har vi -
Vi brukte det med Gjør.
>> [Sukk]
>> Jeg vet, men jeg tror vi bare slettet det.
Uh, ja.
Pokker.
Løs dette Rob.
Hva?
Det er veldig enkelt.
Ja, snudde vi optimalisering av.
OK, stå bye.
Nå føler jeg meg bedre.
OK.
>> Så la oss rekompilere denne -
Gjør du dontdothis.
Du må kanskje endre navn på denne til dothis.c på bare et øyeblikk.
Det vi går.
Takk.
OK.
Så det faktum at jeg var utskrift noe ut var faktisk bare
sakker den prosessen som vi ville ha nådd det punktet.
OK.
Phew!
>> Så hva som faktisk skjer?
Grunnen til at det, akkurat som en side, er gjør noe i form av innspill og
utgang tendens til å bli tregere fordi du må skrive tegn til
skjermen, har det å rulle.
Så lang historie kort, jeg hadde faktisk skjedd så utålmodig, ville vi ha
sett dette sluttresultat også.
Nå som jeg fikk ri av print-ups, vi ser det med en gang.
Så hvorfor skjer dette.
Vel, den enkle forklaringen selvsagt er at foo sannsynligvis burde ikke
være å kalle seg selv.
>> Nå i generelle termer, dette er rekursjon.
Og vi tenkte et par uker siden rekursiv er bra.
Rekursjon er denne magiske måten uttrykke deg super konsist.
Og det bare virker.
Men det er en viktig funksjon i alle de rekursive programmer vi har snakket
om og sett på hittil, som var at de hadde det?
En base tilfellet, som var noen hardkodet sak at nevnte i enkelte situasjoner
kaller ikke foo, som er klart ikke tilfelle her.
>> Så hva som egentlig skjer i forhold til dette bilde?
Vel, når main kaller foo, det får en bit av minne.
Når foo kaller foo, det blir en bit av minne.
Når foo kaller foo, det blir en skive.
Det blir en skive.
Fordi foo aldri tilbake.
Vi kommer aldri slette en av dem rammer fra bunken.
Så vi blåser gjennom haugen, ikke å nevne hvem vet hva annet, og
vi overskridelser grensene for vår så-kalt segment av hukommelse.
Feil gå segmentering falsk.
>> Så løsningen er det tydelig ikke gjør dette.
Men jo større implikasjon er at, ja, det er absolutt en grense,
selv om det ikke er godt definert, med hensyn til hvordan mange funksjoner du kan ringe i en
program, hvor mange ganger en funksjon kan kalle seg.
Så selv om vi forkynte rekursjon da dette potensielt magisk ting en
par uker siden for sigma funksjon, og når vi får data
strukturer og CS50, vil du se andre applikasjoner for det, er det ikke
nødvendigvis det beste.
Fordi hvis en funksjon kaller seg, kaller seg, selv om det er en base
tilfelle, hvis du ikke treffer som base case for 1000 anrop eller 10.000 anrop, ved å
den tiden du kan ha kjørt ut av rommet på såkalte stack og hit
noen andre deler av minnet.
Så det er for et design trade-off mellom eleganse og mellom
robusthet av din spesielle gjennomføring.
>> Så det er en annen ulempe eller en annen fikser til hva vi har
gjort så langt.
Når jeg ringte getstring -
la meg gå tilbake til hei-2.
Legg merke til at jeg ringer getstring, som blir tilbake en adresse.
Og vi hevder i dag at adresse er fra haugen.
Og nå er jeg skrive ut string på denne adressen.
Men vi har aldri kalt motsatte av getstring.
Vi har aldri hatt å calll en funksjon som ungetstring, hvor du leverer tilbake
dette minnet.
Men ærlig vi trolig skulle ha vært.
Fordi hvis vi fortsette å spørre datamaskinen for hukommelse, i form av en som
getstring men aldri gi den tilbake, sikkert som er for bundet til å føre til
problemer der vi går tom for minne.
>> Og faktisk, kan vi se etter disse problemer med det nye verktøyet hvis bruken
er litt kryptisk å skrive.
Men la meg gå videre og sprute det opp på skjermen i løpet av et øyeblikk.
Jeg kommer til å gå videre og kjøre Valgrind med parameter som første kommando
-argumentet er navnet av programmet hallo-2.
Og dessverre er det produksjonen er atrociously
komplisert for ingen god grunn.
Så vi ser alt det rotet.
David er oppgi navnet mitt.
Så det er programmet faktisk kjører.
Og nå får vi denne utgangen.
>> Så Valgrind er lik i ånden til GDB.
Det er ikke en debugger per se.
Men det er et minne brikke.
Det er et program som vil kjøre programmere og fortelle deg om du spurte en
datamaskin for hukommelse og aldri ga den tilbake, og dermed noe som betyr at du har
en minnelekkasje.
Og minnelekkasjer tendens til å være dårlig.
Og du er brukere av datamaskiner har sannsynligvis følt dette, om du har en
Mac eller en PC.
Har du noen gang brukt datamaskinen for mens og ikke startet på nytt i flere
dager, eller du nettopp har fått en mye programmer som kjører, og den jævla ting
bremser til en sliping stoppe, eller i det minste det er super irriterende å bruke, fordi
alt bare fikk super slow.
>> Nå som kan være en rekke årsaker.
Det kan være en uendelig loop, en bug i noens kode, eller ganske enkelt, det
kan bety at du bruker mer minne, eller prøver å, enn din
Datamaskinen har faktisk.
Og kanskje det er en bug i noen program at holde ber om minne.
Nettlesere for årene var beryktet for dette, ber om mer og mer minne
men aldri levere det tilbake.
Sikkert, hvis du bare har en begrenset mye minne, kan du ikke be
uendelig mange ganger for noe av det minnet.
>> Og så det du ser her, selv om igjen Valgrind produksjon er
unødvendig komplisert å titte på først, dette er den interessante delen.
Heap -
i bruk ved avkjørsel.
Så her er hvor mye minne var i bruk i haug på
min tid program gått ut -
tilsynelatende seks bytes i en blokk.
Så jeg kommer til å vinke hendene mine på hva en blokk.
Tenk på det er bare en blings, en mer teknisk ord for blings.
Men seks bytes -
hva som er de seks byte som var fortsatt i bruk?
>> Nettopp.
D-A-V-I-D null skråstrek, fem bokstav navn pluss null terminator.
Så dette programmet Valgrind merke til at jeg ba om seks bytes, tilsynelatende, etter
måte getstring, men aldri ga dem tilbake.
Og faktisk, dette kan ikke være så tydelig hvis mitt program er ikke tre
linjer, men det er 300 linjer.
Så vi kan faktisk gi en annen kommando -argumentet til Valgrind til
gjøre det mer ordrik.
Det er litt irriterende å huske.
Men hvis jeg gjør -
la oss se.
Lekke -
Ble det lekke -
selv jeg ikke husker hva det er av hånden.
>> - Lekkasje-sjekk tilsvarer full.
Jepp, takk.
- Lekkasje-sjekk tilsvarer full.
Enter.
Samme programmet kjører.
Skriver i David igjen.
Nå ser jeg litt mer detalj.
Men under haugen sammendraget, hvilken er identisk med fire - ah,
dette er slags hyggelig.
Nå Valgrind faktisk ser litt hardere i koden min.
Og det er å si det, tilsynelatende, malloc på line -
vi zoome ut.
På line -
vi ikke ser hvilken linje det er.
Men malloc er den første skyldige.
Det er en blogg i malloc.
>> Greit?
OK, nei.
Høyre?
Jeg ringte getstring.
getstring kaller tilsynelatende malloc.
Så hva kodelinje er tilsynelatende på feil for å ha
allokert dette minnet?
La oss anta at den som skrev malloc har eksistert lenge nok til at det er
ikke deres feil.
Så det er nok mine.
getstring i cs50.c - så det er en fil et sted på datamaskinen -
på linje 286 ser ut til å være den skyldige.
Nå la oss anta at CS50 har vært rundt for anstendig tid, så
også vi er ufeilbarlige.
Og så det er sannsynligvis ikke i getstring at feilen ligger, men snarere i
hallo-2.c linje 18.
>> Så la oss ta en titt på hva som linje 18 var.
Oh.
Somehow denne linjen er ikke nødvendigvis avlytting, per se, men det er grunnen
bak at minnelekkasje.
Så super enkelt, hva ville intuitivt være løsningen her?
Hvis vi ber for hukommelse, var aldri å gi den tilbake, og som synes å være en
problem fordi det over tid datamaskinen min kanskje går tom for minne, kan bremse
ned, kan dårlige ting skje, vel, hva er den enkle intuitive løsningen?
Bare gi den tilbake.
>> Hvordan frigjøre dere opp som minne?
Vel, heldigvis er det ganske enkelt å bare si fri navn.
Og vi har aldri gjort dette før.
Men du kan egentlig tenke på gratis som det motsatte av malloc.
fri er det motsatte av tildele minne.
Så nå la meg rekompilere dette.
Gjør hallo-2.
La meg kjøre den på nytt. hallo-2 David.
Så det ser ut til å fungere i nøyaktig samme måte.
Men hvis jeg går tilbake til Valgrind og re-run den samme kommandoen på min nylig
kompilert program, skrive i mitt navn som før -
hyggelig.
Heap oppsummering -
i bruk ved avkjørsel -
null byte i null blokker.
Og dette er super hyggelig, alle heap blokker ble frigjort.
Ingen lekkasjer er mulig.
>> Så kommer opp, ikke med Problem Set 4, men med Problem Set 5, de dataanalyse
og videre, også dette vil bli en mål på riktigheten av
program, om du har eller ikke har minnelekkasjer.
Men heldigvis, ikke bare kan du resonnere gjennom dem intuitivt, som
er, uten tvil, lett for små programmer men vanskeligere for store programmer
Valgrind, for de større programmer, kan hjelpe deg med å identifisere
det spesielle problemet.
>> Men det er en annen problem som kan oppstå.
La meg åpne opp denne filen her, som er, igjen, en noe enkelt eksempel.
Men la oss fokusere på hva dette programmet gjør.
Dette kalles memory.c.
Vi vil legge dette senere i dag i zip dagens kildekode.
Og legg merke til at jeg har en funksjon som heter f som tar ingen argumenter og
returnerer ingenting.
I tråd 20, jeg tydeligvis erklære en pekeren til en int og kaller det x.
Jeg tilordne er avkastningen Verdien av malloc.
Og bare for å være klar, hvor mange byte am Jeg sannsynligvis komme tilbake fra malloc
i denne situasjonen?
>> Sannsynligvis 40.
Hvor får du det fra?
Vel, hvis du husker at en int er ofte 4 bytes, i hvert fall det er i
apparatet, er 10 ganger 4 åpenbart 40 år.
Så malloc returnerer en adresse en del av minne og lagring som
ta slutt i x.
Så for å være klar, hva da skjer?
Vel, la meg bytte tilbake til vår bilde her.
La meg ikke bare trekke bunnen av mitt datamaskinens minne, la meg gå videre og
trekke hele rektangelet som representerer alle RAM min.
>> Vi vil si at bunken er på bunnen.
Og det er en tekst segment i de uinitialiserte data.
Men jeg skal bare abstrakte de andre ting unna som prikk, prikk prikk.
Jeg kommer bare til å referere til dette som haugen på toppen.
Og deretter ved bunnen av dette bildet, å representere viktigste, jeg kommer
å gi den en skiver minne på stabelen.
For f, jeg skal gi det en skive minne på stakken.
Nå fikk jeg kontakt med min kildekoden igjen.
Hva er de lokale variablene for main?
Tilsynelatende ingenting, slik at skive er effektivt tom eller ikke engang så stor
som jeg har tegnet det.
Men i f, jeg har en lokal variabel, som kalles x.
Så jeg kommer til å gå videre og gi f en del av minnet, og kaller det x.
>> Og nå malloc av 10 ganger 4, Så 40 malloc, hvor det er
minne kommer fra?
Vi har ikke tegnet et bilde liker dette før.
Men la oss anta at det er effektivt kommer fra her, så en,
to, tre, fire, fem.
Og nå trenger jeg 40 av disse.
Så jeg vil bare gjøre prikk, prikk, prikk til å foreslå at det er enda mer minne
kommer tilbake fra haugen.
Nå hva er adressen?
La oss velge vår vilkårlig adresse som alltid -
Ox123, selv om det sannsynligvis kommer å være noe helt annet.
Det er adressen til den første byte i minne som jeg ber malloc for.
>> Så kort sagt, når linjen 20. utfører, hva er bokstavelig talt
lagret inne i x her?
Ox123.
Og Ox er uinteressant.
Det betyr bare her er en heksadesimalt tall.
Men kjernen er at det jeg har butikken i x, som er en lokal variabel.
Men dens datatype, igjen, er en adresse til en int.
Vel, jeg kommer til å lagre Ox123.
Men igjen, hvis det er litt for komplisert unødvendig, hvis jeg ruller
tilbake, kan vi abstrakte dette bort ganske rimelig og bare si at x er en
peker til denne del av minnet.
>> OK.
Nå er spørsmålet på hånden er følgende -
linje 21, det viser seg, er buggy.
Hvorfor?
>> Sorry?
Det har ikke -
si at når mer.
Vel, det gjør det ikke gratis.
Så det er den andre men.
Så det er en annen, men spesielt på linje 21..
>> Nettopp.
Denne enkle kodelinje er bare en buffer overflow, en buffer overkjørt.
En buffer betyr bare en del av minnet.
Men det del av minnet er på størrelse 10, 10 heltall, som betyr at hvis vi
indeksen inn det ved hjelp av syntaktisk sukker av matrise notasjon, torget
parentes, har du tilgang til x brakett 0 x brakett 1 x,
brakett prikk, prikk, prikk.
x brakett 9 er den største.
Så hvis jeg gjør x 10 brakett, hvor Jeg faktisk kommer i minnet?
>> Vel, hvis jeg har 10 int -
la oss faktisk trekke alle av disse ut her.
Så det var de første fem.
Her er de fem andre ints.
Så x brakett 0 er her. x trinn 1 er her. x brakett 9 er her. x brakett
10 er her, noe som betyr at jeg forteller, i linje 21, til datamaskinen sette
nummer der?
Tallet 0 der?
Vel, det er 0, ja.
Men bare det faktum at dens 0 er litt av en tilfeldighet.
Det kan være antall 50, for alt vi bryr oss.
Men vi prøver å sette den på x brakett 10, som er hvor denne
spørsmålstegnet er trukket, som er ikke en god ting.
Dette programmet kan godt krasje som resultat.
>> Nå, la oss gå videre og se om dette er, faktisk, hva skjer.
Lag hukommelse, siden filen kalles memory.c.
La oss gå videre og kjøre programmet minne.
Så vi hadde flaks, faktisk, synes det.
Vi hadde flaks.
Men la oss se om vi nå kjøre Valgrind.
Ved første øyekast, mitt program makt synes å være helt korrekt.
Men la meg kjøre Valgrind med - Lekkasje-sjekk tilsvarer full på hukommelse.
>> Og nå når jeg kjører dette -
interessant.
Ugyldig skrive av størrelse 4 på linje 21 av memory.c.
Linje 21 av memory.c er hvilken?
Oh, interessant.
Men vent.
Størrelse 4, hva er det snakk om?
Jeg bare gjorde en skriver, men det er av størrelse 4.
Hvorfor er det fire?
Det er fordi det er en int, som er, igjen, fire byte.
Så Valgrind funnet en bug som jeg, skotter på koden min, gjorde det ikke.
Og kanskje din TF ville eller ikke ville.
Hva Men Valgrind sikkert funnet ut at vi har gjort en feil der, selv
selv om vi hadde flaks, og datamaskinen besluttet, eh, jeg kommer ikke til å krasje
bare fordi du rørt en byte, en int er verdt av minne som du ikke
faktisk eier.
>> Vel, hva annet er buggy her.
Adresse -
Dette er en sprø jakt adresse i heksadesimal.
Det betyr at bare et sted i haugen er null byte etter en blokk med størrelse 40
er tildelt.
La meg zoome ut her og se om dette er litt mer nyttig.
Interessant.
40 bytes er definitivt tapt i tap rekord 1 av 1.
Igjen er flere ord enn nyttig her.
Men basert på de markerte linjer, hvor skal jeg sannsynligvis fokusere min
oppmerksomhet for en annen bug?
Ser ut som en linje 20 av memory.c.
>> Så hvis vi går tilbake til linje 20, som er den en som du identifiserte tidligere.
Og det er ikke nødvendigvis buggy.
Men vi har dette snudd dens virkninger.
Så hvordan retter jeg minst en av disse feilene?
Hva kan jeg gjøre etter linje 21?
Jeg kunne gjøre uten x, er så å gi tilbake som minne.
Og hvordan fikser jeg dette feil?
Jeg bør definitivt gå ikke lenger enn 0.
Så la meg prøve og kjøre dette.
Beklager, definitivt gå ikke lenger enn ni.
Gjør minne.
La meg reprise Valgrind i et større vindu.
Og nå ser.
Nice.
Alle haug blokker ble frigjort.
Ingen lekkasjer er mulig.
Og opp over her, det er ingen omtale noe mer av det ugyldige høyre.
>> Bare for å bli grådig, og la oss se om en annen demonstrasjon
ikke går som forutsatt -
Jeg fikk heldig for et øyeblikk siden.
Og det faktum at dette er 0 er kanskje unødvendig misvisende.
La oss bare gjøre 50, en noe vilkårlig nummer, få minne dot slash minne -
fortsatt ha flaks.
Ingenting å krasje.
Tenk om jeg bare gjøre noe virkelig tåpelig, og jeg gjør 100.
La meg remake minne, dot slash minne -
hadde flaks igjen.
Hva med 1000?
ints utover, omtrent, der jeg skal være?
Gjør minne -
faen.
>> [Latter]
>> OK.
La oss ikke rote rundt lenger.
Reprise minne.
Det vi går.
OK.
Så tilsynelatende du indekserer 100.000 ints bortenfor der du skulle ha vært i
minne, dårlige ting skje.
Så dette er åpenbart ikke en hard, fast regel.
Jeg var litt hjelp rettssaken og feiling for å komme dit.
Men dette er fordi, lang historie kort, datamaskinens minne er også delt
inn i disse tingene kalles segmenter.
Og noen ganger, datamaskinen faktisk har gitt deg litt mer minne
enn du ber om.
Men for effektivitet, er det bare enklere å få mer minne, men bare fortelle deg
at du får en del av det.
>> Og hvis du får heldig noen ganger, derfor kan du være i stand til å røre
minne som ikke tilhører deg.
Du har ingen garanti for at det verdi du setter det vil bo der, fordi
datamaskinen fortsatt mener det ikke er din, men det er ikke nødvendigvis kommer
å treffe et annet segment av minne i datamaskin og indusere en feil som
denne her.
OK.
Eventuelle spørsmål deretter på minne?
>> OK.
La oss ta en titt her, da, noe vi har tatt for
innvilget i ganske lang tid, noe som er i denne filen som heter cs50.h.
Så dette er en fil.
Dette er bare en hel haug av kommentarene opp topp.
Og du har kanskje sett på dette hvis du stakk rundt på apparatet.
Men det viser seg at hele tiden, da vi pleide å bruke streng som en
synonym, de midler som vi erklærte som synonym var med denne
søkeord typedef, for type definisjon.
Og vi egentlig sier, gjør strengen en synonym for røye stjerne.
At den måte hvorved stabelen skapte disse trening hjul kjent som
strengen.
>> Nå her er bare en prototype for getchar.
Vi har kanskje sett det før, men det er faktisk hva den gjør. getchar
tar ingen argumenter, returnerer en røye.
getdouble tar ingen argumenter, returnerer en dobbel.
getfloat tar ingen argumenter, returnerer en flottør, og så videre.
getint er her inne. getlonglong er her inne.
Og getstring er her inne.
Og det er det.
Denne lilla linjen er en annen preprocessor direktiv på grunn av
hashtag på begynnelsen av det.
>> OK.
Så nå la meg gå inn cs50.c.
Og vi vil ikke snakke for lenge på dette.
Men for å gi deg et glimt av hva som er pågått alt dette
tid, la meg gå til -
la oss gjøre getchar.
Så getchar er for det meste kommentarer.
Men det ser ut som dette.
Så dette er den faktiske funksjon getchar at vi har vært
tar for gitt eksisterer.
Og selv om vi ikke har bruk denne ene som ofte, om noen gang, er det minst
relativt enkel.
Så det er verdt å ta en rask titt på her.
>> Så getchar har en uendelig loop, bevisst slik tilsynelatende.
Det krever da - og dette er en type fin gjenbruk av kode vi selv skrev.
Det kaller getstring.
Fordi det gjør det bety å få en røye?
Vel, kan du like godt prøve å få en Hele tekstlinje fra brukeren og
så bare se på ett av disse tegnene.
I tråd 60, her er litt litt av en mental helse sjekk.
Hvis getstring returneres null, la oss ikke fortsette.
Noe gikk galt.
>> Nå er dette litt irriterende, men konvensjonelle i C. røye maks trolig
representerer det bare basert på navnet sitt?
Det er en konstant.
Det er som den numeriske verdien av største røye du kan representere med
en matbit, som sannsynligvis er antallet 255, som er den største nummeret du
representerer åtte bits, starter fra null.
Så jeg har bruker dette, i denne funksjonen, når skrive denne koden, bare fordi
hvis noe går galt i getchar men sitt formål i livet er å returnere en
røye, må du liksom kunne å signalisere til brukeren om at
noe gikk galt.
Vi kan ikke returnere null.
Det viser seg at null er en peker.
Og igjen, har getchar å returnere en røye.
>> Så konvensjonen, hvis noe går galt, er du som programmerer, eller i
dette tilfellet meg med biblioteket, hadde jeg en bare bestemme vilkårlig, hvis
noe går galt, kommer jeg til å returnere antall 255, som er virkelig
betyr at vi kan ikke, kan ikke brukeren skriver tegnet representert ved
nummer 255 fordi vi hadde en stjele den som en såkalt fast punkt verdi til
representere et problem.
Nå viser det seg at karakteren 255 er ikke noe du kan skrive på
tastaturet, så det er ingen big deal.
Brukeren merker ikke at Jeg har stjålet denne karakter.
Men hvis du noen gang ser i man-sidene på en datasystem noen henvisning til en
alle caps konstant som dette som sier, i tilfeller av feil dette konstant makt
bli returnert, det er alt noen mennesker gjorde år siden ble vilkårlig besluttet å
returnere denne spesielle verdi og kaller det en konstant i tilfelle
noe går galt.
>> Nå magien skjer her nede.
Først, jeg erklære på linje 67 to tegn, C1 og C2.
Og så i tråd 68, det er faktisk en linje med kode som minner om
vår venn printf, gitt at det har prosent Cs i anførselstegn.
Men legg merke til hva som skjer her. sscanf betyr streng scan -
betyr skanne en formatert string, ergo sscanf.
Hva betyr det?
Det betyr at du passerer å sscanf en streng.
Og linjen er uansett brukeren skriver i.
Du passerer til sscanf et format streng som dette som forteller scanf hva er
du håper at brukeren har skrevet i.
Deretter passerer-i adressene til to biter av hukommelse, i dette tilfellet,
fordi jeg har to plassholdere.
Så jeg kommer til å gi den adressen av C1 og adressen til C2.
>> Og minner om at du gir en funksjon adressen til noen variable, hva er
implikasjonen?
Hva kan denne funksjonen gjøre som et resultat for å gi den adressen til en
variabel, i motsetning til variabelen selv?
Det kan endre det, ikke sant?
Hvis du hadde noen et kart til en fysisk adresse, kan de gå der og gjøre
hva de vil på denne adressen.
Samme ideen her.
Hvis vi passerer til sscanf, adressen til to biter av minne, selv disse ørsmå
små biter av minne, C1 og C2, men vi forteller det adressen til dem,
sscanf kan endre det.
>> Så sscanf hensikt i livet, hvis vi leser man-siden, er å lese hva
brukeren har skrevet inn, håpe på at brukeren trenger skrevet i en karakter og kanskje
en annen karakter, og hva brukeren skrevet, går det første tegnet
her går det andre tegnet her.
Nå, som en side, dette, og du ville bare vet dette fra dokumentasjonen,
det faktum at jeg setter en tom plass der betyr bare at jeg bryr meg ikke om
brukeren treffer på mellomromstasten noen ganger før han eller hun tar en
karakter, kommer jeg til å ignorere noen hvite felt.
Så det vet jeg fra dokumentasjonen.
>> Det faktum at det er en annen% c etterfulgt av mellomrom er faktisk
bevisst.
Jeg ønsker å være i stand til å oppdage om brukeren skrudd opp eller ikke samarbeide.
Så jeg håper at brukeren kun har skrevet i ett tegn, derfor jeg håper
at sscanf er bare kommer til å returnere verdien 1 fordi, igjen, hvis jeg leser
dokumentasjonen, sscanf hensikt i liv er å gå tilbake til antallet
variabler som var fylt med brukerundersøkelser.
>> Jeg gikk i to variabler adresser, C1 og C2.
Jeg håper imidlertid at bare én av dem blir drept fordi hvis sscanf
returnerer 2, hva er formodentlig implikasjonen logisk?
At brukeren ikke bare gi meg en karakter som jeg fortalte ham eller henne.
De sannsynligvis skrevet på minst to tegn.
Så hvis jeg i stedet hadde ikke den andre % C, måtte jeg bare en, som
ærlig ville være mer intuitivt tilnærming, jeg tror en første øyekast,
du kommer ikke til å være i stand til å oppdage hvis brukeren har vært å gi deg mer
innspill enn du egentlig ønsket.
Så dette er et implisitt skjema av feilsjekking.
>> Men legg merke til hva jeg gjør her.
Når jeg er sikker på at brukeren ga meg en karakter, frigjøre jeg linjen, gjør
det motsatte av getstring, som i sin tur bruker malloc, og da jeg kommer tilbake
C1, tegnet som jeg håpet Brukeren gitt og bare gitt.
Så en rask skimtet bare, men spørsmål om getchar?
Vi vil komme tilbake til noen av de andre.
>> Vel, la meg gå videre og gjøre dette - anta nå, bare for å motivere våre
diskusjon i en uke pluss tid, dette er en fil som heter structs.h.
Og igjen, dette er bare en forsmak av noe som ligger foran oss.
Men legg merke til at mye av dette er kommentarene.
Så la meg markere bare interessante delen for nå.
typedef -
det er det samme søkeordet igjen.
typedef vi bruker til å erklære string som en spesiell datatype.
Du kan bruke typedef å lage helt nye datatyper som ikke fantes da
C ble oppfunnet.
For eksempel, kommer int med C. char kommer med C. dobbel kommer med C. Men
det er ingen forestilling om en student.
Og likevel det ville være ganske nyttig å være stand til å skrive et program som lagrer
i en variabel, en student ID-nummer, deres navn, og huset deres.
Med andre ord, tre stykker av data, som en int og en
streng og en annen streng.
>> Med typedef, er det ganske kraftig om dette og søkeordet sturct for
struktur, du som programmerer i 2013, faktisk kan definere din egen på
datatyper som ikke fantes år siden, men som passer ditt formål.
Og så her, i linjene 13 til 19, vi erklære en ny datatype, som
en int, men kaller det student.
Og inne i denne variabelen kommer til å være tre ting - en int, en streng,
og en streng.
Så du kan tenke på hva som er virkelig skjedde her, selv om dette er en
litt av en forenkling for i dag, en student er i hovedsak går
å se ut som dette.
Den kommer til å være en del av minne med en ID, et navn
feltet, og et hus feltet.
Og vi vil være i stand til å bruke disse biter av minne og få tilgang til dem som følger.
>> Hvis jeg går inn struct0.c, her er en forholdsvis lang, men etter en
mønster, med kode som bruker denne nye triks.
Så først, la meg trekke oppmerksomheten din til de interessante delene opp topp.
Sharp definerer studenter 3, erklærer en konstant kalt studenter og stedfortredere
det vilkårlig nummer 3, bare så jeg har tre studenter bruker
dette programmet for nå.
Her kommer Main.
Og legg merke til, hvordan kan jeg erklære en rekke studenter?
Vel, jeg bare bruke samme syntaks.
Ordet student er tydeligvis ny.
Men studentlivet, klasse, brakett studenter.
>> Så dessverre er det mye av gjenbruk av begreper her.
Dette er bare et tall.
Så dette er som å si tre.
Klasse er akkurat hva jeg vil å kalle variabelen.
Jeg kan kalle det studenter.
Men klasse, dette er ikke en klasse i en objektorientert Java slags måte.
Det er bare en klasse av studenter.
Og datatypen for hvert element i denne matrisen er student.
Så dette er litt annerledes og fra å si noe
som dette, er det bare -
Jeg sier gi meg tre studenter og kaller denne matrisen klassen.
>> OK.
Nå her en fire loop.
Denne fyren er kjent - iterasjon fra null på opp til tre.
Og her er den nye stykke syntaks.
Programmet kommer til å spørre meg, mennesket, for å gi den en student
ID, som er en int.
Og her er syntaksen som du kan lagre noe i ID-feltet på
plassering klasse brakett I. Så denne syntaksen er ikke ny.
Dette betyr bare gi meg den åttende elev i klassen.
Men dette symbolet er nytt.
Frem til nå har vi ikke brukt prikk, i det minste i kode som dette.
Dette betyr gå til struct kjent som en student og sette noe der.
Tilsvarende, i denne neste linje, 31, går fremover og plassere hva brukeren skriver
etter et navn her og hva de gjør for en huset, det samme, gå videre og
sette den inn. huset.
>> Så hva gjør dette programmet til slutt gjøre?
Du kan se en liten teaser der.
La meg gå videre og gjør structs 0 dot slash struct 0, student ID-en,
sier David Mather, student ID to.
Rob Kirkland, student ID tre.
Lauren Leverit -
og det eneste dette programmet gjorde, som bare er helt vilkårlig, blir
Jeg ønsket å gjøre noe med disse dataene, nå som jeg har lært oss hvordan vi skal
bruke structs, er jeg bare måtte denne ekstra sløyfe her.
Jeg iterere over rekken av studenter.
Jeg brukte vår, kanskje nå velkjente venn, string sammenligne, stircomp til
sjekk er åttende student hus lik Mather?
Og hvis så, bare skrive noe vilkårlig liker, ja, det er det.
Men igjen, bare gi meg muligheter å bruke og gjenbruke og
gjenbruke denne nye dot notasjon.
>> Så hvem bryr seg, ikke sant?
Kommer opp med en student programmet er noe vilkårlig, men det viser seg
at vi kan gjøre nyttige ting med denne, for eksempel på følgende måte.
Dette er en mye mer komplisert struct i C. Det har et dusin eller flere felt,
noe kryptisk heter.
Men hvis du noen gang hørt om en grafikk filformat kalt bitmap, BMP, det
viser seg at bitmap filformat pen ser mye ut som dette.
Det er en dum liten Smileansikt.
Det er et lite bilde som jeg har zoomet inn på ganske stor slik at jeg kunne se hver
av de enkelte punkter eller piksler.
Nå viser det seg at vi kan representere en svart prikk med, si, antall 0.
Og en hvit dot med tallet 1.
>> Så med andre ord, å hvis du vil tegne en Smilefjes og lagre det bildet i en
datamaskin, er det nok til å lagre nuller og de som ser ut som dette, hvor,
igjen, de er hvite og nuller er svart.
Og sammen, hvis du effektivt har en omgjord av enere og nuller, har du en
rutenett av piksler, og hvis du legger dem ut, har du en søt
Litt Smileansikt.
Nå er bitmap filformat, BMP, effektivt at under panseret,
men med flere piksler sot som du kan faktisk representere farger.
>> Men når du har mer sofistikert filformater som BMP og JPEG og GIF
som du kanskje bli kjent, de filer på disken vanligvis ikke bare
har nuller og enere for piksler, men de har noen metadata samt -
meta i den forstand som egentlig ikke er data, men det er nyttig å ha.
Så disse feltene her er noe som tyder på, og vi får se dette i mer detalj i P-set
5, som før nuller og enere som representerer piksler i et bilde,
det er en haug av metadata som størrelsen av bildet og den
bredden av bildet.
Og legg merke til jeg plukker ut noen vilkårlige ting her -
bredde og høyde.
Bit teller og noen andre ting.
Så er det noen metadata i en fil.
>> Men ved å forstå hvordan filer er lagt ut på denne måten, kan du faktisk
deretter manipulere bilder, gjenopprette bilder fra disk, endre størrelsen på bilder.
Men du kan ikke nødvendigvis forbedre dem.
Jeg trengte et fotografi.
Så jeg gikk tilbake til RJ her, som du så på skjermen en stund siden.
Og hvis jeg åpner opp Keynote her, er dette hva skjer hvis du prøver å zoome inn og
forbedre RJ.
Han er ikke få noe bedre egentlig.
Nå Keynote er slags uskarphet det en litt, bare for å glatte over
At RJ ikke får særlig forbedret når du zoomer inn
Og hvis gjør det på denne måten, se rutene?
Ja, kan du definitivt se rutene på en projektor.
>> Det er hva du får når du forbedre.
Men i å forstå hvordan vår RJ eller Smilefjes er implementert vil la oss
faktisk skrive kode som manipulerer disse tingene.
Og jeg trodde jeg ville ende på dette notatet, med 55 sekunder av en styrke som er,
Jeg tør si ganske misvisende.
>> [VIDEOAVSPILLING]
>> -Han lyver.
Om hva, vet jeg ikke.
>> -Så hva vet vi?
>> -Det at 9:15 Ray Santoya var ved minibanken.
>> -Så spørsmålet er hva gjorde han på 9:16?
>> -Skyting de ni millimeter på noe.
Kanskje han så snikskytter.
>> -Eller jobbet med ham.
>> -Vent.
Gå tilbake ett.
>> -Hva ser du?
>> -Ta med ansiktet opp, full skjerm.
>> -Hans briller.
>> -Det er en refleksjon.
>> -Det er Neuvitas baseball team.
Det er deres logo.
>> -Og han snakker til den som er iført den jakken.
>> [END VIDEOAVSPILLING]
>> DAVID J. MALAN: Dette vil være Problem Set 5.
Vi vil se deg neste uke.
>> MALE SPEAKER: Ved neste CS50.
>> [Sirisser kvitret]
>> [Musikk spilles]