[Powered by Google Translate] [ARTIKEL 5: minder gemaklike]
[Nate Hardison, Harvard Universiteit]
[Hierdie is CS50.] [CS50.TV]
So welkom terug, ouens.
Welkom by artikel 5.
Op hierdie punt, quiz 0 voltooi en gesien hoe jy gedoen het,
hopelik jy voel regtig goed, want ek was baie beïndruk deur die tellings in hierdie afdeling.
Vir ons aanlyn kykers, het ons het 'n paar vrae
oor die laaste twee probleme op die probleem te stel - of op die quiz, eerder.
So ons gaan om te gaan oor dié wat regtig vinnig, sodat almal sien wat gebeur het
en hoe om te gaan deur middel van die werklike oplossing eerder as net die lees van die oplossing self.
Ons gaan om te gaan oor die laaste paar probleme regtig vinnig, 32 en 33.
Net weer, sodat die aanlyn-kykers kan sien.
>> As jy aan jou probleem 32, wat is op bladsy 13,
13 uit 16, probleem 32 is al oor die swaps.
Dit was alles oor die uitruiling van twee heelgetalle.
Dit is die probleem wat ons gaan oor 'n paar keer in die lesing.
En hier, wat ons vra jou om te doen is 'n vinnige geheue spoor.
Te vul in die waardes van die veranderlikes soos hulle is op die stapel
as die kode gaan deur middel van hierdie swap funksie.
In die besonder, wat ons op soek na - Achievement gaan hierdie iPad neer te sit -
in die besonder, wat ons is op soek na hierdie lyn genommer 6 reg hier.
En dit is genommer 6 vir net aanraking met die vorige probleem.
Wat ons wil doen, is die toestand van die geheue te vertoon of benoem
as dit is op die oomblik wanneer ons uitvoer hierdie lyn nommer 6,
wat effektief 'n opbrengs van ons swap funksie reg hier.
As ons scroll down hier, het ons gesien dat die adresse van alles in die geheue is vir ons.
Dit is 'n baie belangrike, ons sal terug kom om dit in net 'n oomblik.
En dan af hier aan die onderkant, ons het 'n bietjie geheue diagram dat ons gaan om te verwys na.
Ek het eintlik gedoen op my iPad.
So ek gaan om heen en weer te wissel tussen die iPad en hierdie kode net vir verwysing.
>> Kom ons begin. Eers, laat se fokus op die eerste paar lyne van die belangrikste reg hier.
Om mee te begin, gaan ons x te inisialiseer 1 en y 2.
So ons het twee integer veranderlikes, is hulle albei gaan word op die stapel geplaas.
Ons gaan 'n 1 en 'n 2 te sit in hulle.
So as ek draai op my iPad, hopelik, laat ons sien -
Apple TV mirroring, en daar gaan ons. Okay.
So as ek draai op my iPad,
Ek wil x te inisialiseer 1 en y 2.
Ons doen dit eenvoudig deur die skryf van 'n 1 in die boks gemerk x
en 'n 2 in die boks gemerk y. Redelik eenvoudig.
So nou, laat ons gaan terug na die laptop, kyk wat gebeur volgende.
So die volgende lyn is waar dinge lastig.
Ons ry verby die adres van x en die adres van y as die parameters a en b die swap funksie.
Die adres van die x en die adres van y is dinge wat ons nie kan bereken
sonder om te verwys na hierdie bullet wys hier regs af.
En gelukkig, die eerste twee bullet punte vir ons vertel presies wat die antwoorde is.
Die adres van x in die geheue is 10, en die adres van y in die geheue is 14.
So dit is die waardes wat in geslaag kry as A en B tot bo in ons swap funksie.
Dit weer doen, skakel terug na ons diagram, kan ek skryf 'n 10 in 'n
en 'n 14 in b.
Nou, hierdie punt is waar ons voortgaan met die ruiltransaksie.
So daarby terug weer aan die laptop,
sien ons dat die manier waarop die swap werk, is ek die eerste keer dereference a en stoor die resultaat in tmp.
So sê die dereference operateur, "Hey. Behandel die inhoud van die veranderlike 'n as 'n adres.
Gaan na alles wat by daardie adres gestoor, en laai dit. "
Wat jy laai van die veranderlike gaan word gestoor in ons tmp veranderlike.
Daarby terug na die iPad.
As ons gaan om 10 aan te spreek, weet ons dat adres 10 is die varible x
want ons is vertel deur ons bullet punt dat die adres van x in die geheue is 10.
Sodat ons kan daar gaan, kry die waarde van dit, wat is 1, soos ons sien op ons iPad,
en laai dit in tmp.
Weereens, dit is nie die finale inhoud.
Ons gaan om te loop deur en ons sal kry om ons finale toestand van die program aan die einde.
Maar nou, ons het die waarde 1 gestoor in tmp.
>> En daar is 'n vinnige vraag hier.
[Alexander] Is die dereference operateur - dit is net die ster reg in die voorkant van die veranderlike?
>> Ja. So het die dereference operateur, as ons draai terug na ons laptop weer,
is hierdie ster reg in die voorkant.
In daardie sin, dit is - jy kontrasteer dit met die vermenigvuldiging operateur
wat vereis dat twee dinge, die dereference operateur is 'n Unêre operateur.
Net toegepas op een waarde as gekant teen 'n binêre operateur,
waar jy aansoek doen om twee verskillende waardes.
So dit is wat gebeur in hierdie lyn.
Ons laai die waarde 1 en dit in ons tydelike heelgetal veranderlike gestoor.
Die volgende lyn, slaan ons die inhoud van b in
of, eerder, slaan ons die inhoud wat b wys in die plek waar 'n wys.
As ons analiseer dit van regs na links, gaan ons dereference b,
ons gaan 14 aan te spreek, gaan ons die heelgetal wat daar is om te gryp,
en dan gaan ons om te gaan na die adres 10,
en ons gaan die gevolg van ons dereference van b in daardie ruimte te gooi.
Daarby terug na ons iPad, waar ons kan maak dit 'n bietjie meer konkrete,
dit kan help as ek skryf nommers op al die adresse hier.
Dus weet ons dat, ons is by y by adres 14, x is by adres 10.
Wanneer ons begin by b, ons dereference b, ons gaan die waarde 2 aan te gryp.
Ons gaan hierdie waarde te gryp, want wat is die waarde wat woon by adres 14.
En ons gaan om dit in die veranderlike wat woon by adres 10,
wat reg is, wat ooreenstem met ons veranderlike x.
Sodat ons kan doen om 'n bietjie van die vervang hier
waar ons ontslae te raak van ons 1 en in plaas daarvan het ons skryf 'n 2.
So was dan al is goed en goed in die wêreld, selfs al het ons nou oorskryf x.
Ons het x se ou waarde in ons tmp veranderlike gestoor.
Sodat ons dit kan die ruiltransaksie voltooi met die volgende reël.
Daarby terug aan ons laptop.
Nou al wat oorbly is om die inhoud uit te neem van ons tydelike heelgetal veranderlike
en stoor dit in die veranderlike wat woon by die adres wat b hou.
So ons gaan om effektief dereference b toegang te kry tot die veranderlike
wat by die adres wat b hou dit,
en ons gaan die waarde wat tmp hou in dit te stop.
Daarby terug na die iPad weer.
Ek kan hierdie waarde hier vee, 2,
en in plaas daarvan sal ons die 1 reg kopieer dit.
Dan die volgende lyn wat voer, natuurlik -
as ons draai terug na die laptop - is hierdie punt 6,
wat is die punt waar ons wou hê ons diagram heeltemal ingestuur.
So daarby terug na die iPad weer, net sodat jy kan sien die voltooide diagram,
kan jy sien dat ons het 'n 10 in 'n, 'n 14 in b, 'n 1 in tmp, 'n 2 in x, en 'n 1 in y.
Is daar enige vrae het oor hierdie?
Maak dit meer sin te wandel deur dit?
Maak minder sin? Hopelik nie. Okay.
>> Pointers is 'n baie moeilike onderwerp.
Een van die ouens wat ons werk met 'n baie algemene gesegde:
"Pointers te verstaan, moet jy eers verstaan ​​wysers."
Wat ek dink is baie waar. Dit neem 'n rukkie om daaraan gewoond te raak.
Loting van die foto's, trek baie van die geheue diagramme soos hierdie een baie nuttig,
en nadat jy loop deur die voorbeeld op voorbeeld na voorbeeld,
dit sal begin om 'n bietjie meer sin en 'n bietjie meer sin en 'n bietjie meer sin te maak.
Ten slotte, 'n dag, jy het dit alles heeltemal bemeester.
Enige vrae voor ons beweeg aan na die volgende probleem? Alles reg.
So terug flip na die laptop.
Die volgende probleem wat ons het, is probleem nommer 33 op lêer I / O.
Zoom in op hierdie 'n bietjie.
Probleem 33 - Ja?
>> [Daniel] Ek het net 'n vinnige vraag het. Hierdie ster, of die asterisk,
dit genoem ontwysing wanneer jy voor 'n asterisk.
Wat is Dit is dan wanneer jy die ampersand voor?
>> Die ampersand voor die adres van die operateur.
So laat scroll back-up.
Oeps. Ek is in die soom af so ek kan nie regtig scroll.
As ons kyk na hierdie kode regtig vinnig reg hier,
weer, dieselfde ding gebeur.
As ons kyk na die kode hier, op hierdie lyn waar ons die oproep om te ruil,
die ampersand word net gesê: "kry die adres waar veranderlike x lewens."
Wanneer jou samesteller stel jou kode,
dit het eintlik fisies merk 'n plek in die geheue vir al jou veranderlikes om te lewe.
En wat die vertaler kan doen nadat dit opgestel is alles,
dit weet, "O, ek het x by adres 10 Ek het y by adres 14."
Dit kan dan in te vul hierdie waardes vir jou.
Sodat jy kan dan - dit kan dan slaag en slaag en y in sowel.
Hierdie ouens kry die adres, maar ook hulle sal, as jy slaag hulle in die swap funksie,
hierdie tipe inligting, hierdie int * reg hier, sê die samesteller,
"Okay, ons gaan na die interpretasie van hierdie adres as 'n adres van 'n heelgetal veranderlike."
As 'n adres van 'n int, wat verskil van die adres van 'n karakter veranderlike
omdat 'n int neem op 'n 32-bis masjien, neem 4 grepe van die ruimte,
terwyl 'n karakter neem slegs 1 greep van die ruimte.
Daarom is dit belangrik om ook te weet wat is - wat leef, watter tipe van waarde
woon by die adres wat het geslaag.
Of die adres wat jy met.
Op dié manier, jy weet hoeveel bytes van inligting om werklik te laai van jou geheue.
En dan, ja, is hierdie dereference operateur, soos jy vra,
gaan en toegang tot inligting by 'n spesifieke adres.
So dit sê, met hierdie 'n veranderlike hier, behandel die inhoud van 'n as 'n adres,
gaan na die adres, en trek uit, laai in die verwerker, laai in 'n register
die werklike waardes of die inhoud wat by daardie adres woon.
Nog meer vrae? Hierdie is goeie vrae.
Dit is 'n baie nuwe terminologie.
Dit is ook soort van funky, aangesien & * in verskillende plekke.
>> Alles reg.
So terug na die probleem 33, lêer I / O.
Dit was een van die probleme wat ek dink 'n paar van die dinge wat gebeur.
Een, dit is 'n redelik nuwe onderwerp.
Dit was 'n bietjie gou voor die aangesig van die quiz,
En dan dink ek dit was soort van soos een van daardie woord probleme in wiskunde
waar hulle gee jou 'n baie inligting, maar jy eintlik eindig nie met 'n ton van dit te gebruik.
Die eerste deel van die probleem beskryf wat 'n CSV-lêer is.
Nou, 'n CSV-lêer, volgens die beskrywing, is 'n deur kommas geskei waardes lêer.
Die rede waarom hierdie is by al die interessante, en die rede waarom jy altyd gebruik,
is, want, hoeveel van julle het al ooit gebruik om dinge soos Excel?
Figuur die meeste van julle het, waarskynlik, of sal gebruik om op 'n sekere punt in jou lewe.
Jy gebruik iets soos Excel.
Ten einde die data te kry uit 'n Excel spreiblad of enige soort van verwerking met dit,
as jy wou 'n C program of Python program, Java program te skryf,
om te gaan met die data wat jy daar gestoor het,
een van die mees algemene maniere om dit uit te kry, is in 'n CSV-lêer.
En jy kan oopmaak Excel en wanneer jy na die 'Save As 'n dialoog,
wat jy kan kry 'n werklike CSV.
>> Handig om te weet hoe om te gaan met hierdie dinge.
Die manier waarop dit werk, is dat dit is soortgelyk aan - ek bedoel, is dit in wese nabootsen van 'n sigblad,
waar, soos ons hier sien, in die mees linkse stuk,
ons het al die laaste name.
So ons het Malan, dan Hardison, en dan Bowden, MacWilliam, en dan Chan.
Al die laaste name. En dan 'n komma skei die laaste name van die eerste name.
Dawid, Nate, Rob, Tommy, en Zamyla.
Ek het altyd meng Robby en Tom.
En dan, uiteindelik, die derde kolom is die e-pos adresse.
Sodra jy verstaan ​​dat die res van die program is redelik eenvoudig om te implementeer.
Wat ons gedoen het ten einde hierdie selfde struktuur na te boots in die C-program
is dat ons het wat gebruik word om 'n struktuur.
Ons sal begin speel met hierdie 'n bietjie meer as well.
Ons het gesien dat hulle vir die eerste bietjie in die probleem stel 3, wanneer ons te doen het met die woordeboeke.
Maar hierdie personeel struct slaan 'n laaste naam, 'n eerste naam, en 'n e-pos.
Net soos ons CSV-lêer stoor.
So dit is net die omskakeling van een formaat na 'n ander.
Ons het om te sit, in hierdie geval, 'n personeel struct in 'n lyn,
'n komma-geskeide lyn, net soos wat.
Maak dit sin? Julle het al die quiz,
so ek dink jy het ten minste 'n tyd om te dink oor hierdie.
>> In die huur-funksie, die probleem vra om ons te neem in - we'll zoom in op hierdie 'n bietjie -
neem in 'n personeel struktuur, 'n personeel struct, met die naam s,
en voeg die inhoud daarvan aan ons staff.csv lêer.
Dit blyk dat dit is redelik eenvoudig om te gebruik.
Ons sal soort van rondom speel met hierdie funksies 'n bietjie meer vandag.
Maar in hierdie geval, die fprintf funksie is regtig die sleutel.
So met fprintf, kan ons druk, net soos julle ouens printf hierdie hele term is deur.
Jy kan printf 'n lyn na 'n lêer.
So in plaas van net die gewone printf oproep waar jy dit die formaat string
en dan kan jy al die veranderlikes vervang met die volgende argumente,
met fprintf, jou heel eerste argument is in plaas van die lêer wat jy wil skryf.
As ons kyk na dit in die toestel, byvoorbeeld, man fprintf,
ons kan die verskil sien tussen printf en fprintf.
Ek sal hier 'n bietjie zoom.
So met printf, ons gee dit 'n formaat string, en dan die daaropvolgende argumente
is al die veranderlikes vir die vervanging of vervanging in die formaat string.
AANGESIEN dit met fprintf, die eerste argument is inderdaad hierdie lêer * 'n stroom.
>> Beweeg terug hier by ons huur,
ons het reeds ons lêer * stroom vir ons oopgegaan.
Dit is wat die eerste lyn nie, maar dit maak die staff.csv lêer,
dit maak dit in append af, en al wat oorbly vir ons te doen is
skryf die personeel struktuur na die lêer.
En, laat ons sien, wil ek die iPad te gebruik?
Ek sal gebruik maak van die iPad. Ons het nietig - laat dit is op die tafel sit sodat ek kan 'n bietjie beter te skryf -
nietig huur en neem dit in 'n argument, 'n personeel struktuur genoem s.
Het ons draadjies, ons het ons lêer * genoem lêer,
ons het ons fopen lyn wat aan ons gegee is,
en ek sal net skryf dit as kolletjies, want dit is reeds in die Pedia.
En dan op ons volgende lyn, ons gaan 'n oproep te maak fprintf
en ons gaan om te slaag in die lêer wat ons wil uit te druk,
en dan is ons formaat string, wat -
Ek sal jou laat julle ouens my vertel hoe dit lyk.
Hoe gaan jy, Stella? Weet jy wat die eerste deel van die formaat string lyk?
[Stella] Ek is nie seker nie. >> Voel vry om Jimmy om te vra.
Weet jy, Jimmy?
[Jimmy] Sou dit net die laaste? Ek weet nie. Ek is nie heeltemal seker nie.
>> Goed. Hoe gaan, het iemand dit korrek op die eksamen?
Nee Alle regte.
Dit blyk dat hier al wat ons hoef te doen, is ons wil hê dat elke deel van ons personeel struktuur
word uitgedruk as 'n string in ons lêer.
Ons moet net gebruik maak van die string vervanging karakter drie verskillende tye, want ons het 'n laaste naam
gevolg deur komma, dan 'n eerste naam gevolg deur 'n komma,
en dan uiteindelik die e-pos adres wat gevolg word - wat nie
pas op my skerm - maar dit is gevolg deur 'n newline karakter.
So ek gaan dit net af daar skryf.
En dan na ons formaat string,
ons het net die substitusies, wat ons toegang tot die gebruik van die dot-notasie
wat ons gesien het in die probleem stel 3.
Ons kan gebruik s.last, s.first en s.email
te vervang in dié drie waardes in ons formaat string.
So hoe het dit gaan? Sin maak?
Ja? Nie? Moontlik? Okay.
>> Die laaste ding wat ons doen nadat ons het gedruk en nadat ons ons lêer oopgemaak het:
wanneer ons het 'n lêer oopmaak, kry ons altyd moet onthou om dit te sluit.
Want anders sal ons uiteindelik die lek van die geheue,
gebruik lêer beskrywers.
So om dit te sluit, welke funksie gebruik ons? Daniel?
[Daniel] fclose? >> Fclose, presies.
So het die laaste deel van die probleem was om behoorlik te sluit van die lêer, met behulp van die fclose funksie,
wat lyk net soos daardie.
Nie te gek.
Cool.
So wat is probleem 33 op die quiz.
Ons sal beslis meer lêer I / O kom.
Ons sal 'n bietjie meer vandag in die lesing te doen, of in artikel vandag,
want dit is wat gaan die grootste deel te vorm van hierdie komende pset.
Kom ons gaan van die quiz op hierdie punt. Ja?
>> [Charlotte]] Hoekom fclose (lêer) in plaas van fclose (staff.csv)?
>> Ah. Omdat dit blyk dat - so die vraag, wat is 'n groot een,
is die rede waarom, wanneer ons skryf fclose, ons skryf fclose (lêer) ster veranderlike
in teenstelling met die lêernaam, staff.csv? Is dit korrek? Ja.
So laat ons neem 'n blik. As ek skakel terug na my laptop,
en laat ons kyk by die fclose funksie.
So het die fclose funksie sluit 'n stroom en neem dit in die wyser na die stroom wat ons wil om te sluit,
in teenstelling met die werklike lêernaam wat ons wil maak.
En dit is omdat agter die skerms, wanneer jy 'n oproep tot fopen,
wanneer jy 'n lêer oop te maak, moet jy eintlik die toekenning van geheue inligting oor die lêer te stoor.
So jy het lêer pointer wat inligting oor die lêer,
soos dit is oop, sy grootte, waar jy tans in die lêer,
sodat jy dit kan lees en skryf oproepe na daardie spesifieke plek in die lêer.
Jy uiteindelik die sluiting van die muis in plaas van die sluiting van die lêernaam.
>> Ja? [Daniel] So om huur te gebruik, sou jy sê - hoe werk dit die toevoer van die gebruiker kry?
Is fprintf tree soos GetString in die sin dat dit net sal wag vir die toevoer van die gebruiker
en vra om dit te tik - of wag vir jou hierdie drie dinge in te tik?
Of het jy nodig om iets te gebruik om huur te implementeer?
>> Ja. So ons is nie - die vraag is hoe kry ons die toevoer van die gebruiker
om huur te implementeer? En wat ons hier het, is die oproeper van die huur,
geslaag in hierdie staf struct met al die data wat gestoor word in die struct reeds.
So is fprintf staat is om net te skryf dat die data direk na die lêer.
Daar is geen wag vir toevoer van die gebruiker.
Die gebruiker se reeds die insette deur behoorlik om dit in hierdie personeel struct.
En dinge, natuurlik, sou breek indien enige van daardie wysers was null,
sodat ons blaai terug hier en ons kyk na ons struct.
Ons het string laaste string eerste, string e-pos.
Ons weet nou dat almal van diegene wat werklik onder die kap, is 'n char * veranderlikes.
Wat mag of nie mag nie wys wees aan nul.
Hulle kan wys word die geheue op die hoop,
miskien geheue op die stapel.
Ons nie regtig weet nie, maar indien enige van hierdie wenke is null of ongeldige
dat dit sal beslis ons huur funksie crash.
Dit was iets wat dit was soort van buite die omvang van die eksamen.
Ons is nie bekommerd te wees oor dat.
Groot. Okay. So beweeg van die quiz.
>> Kom ons sluit hierdie man, en ons gaan om te kyk na pset 4.
So as jy ouens kyk na die pset spec, sodra jy dit kan oopmaak, cs50.net/quizzes,
ons gaan om te gaan deur middel van 'n paar van die artikel probleme vandag.
Ek blaai af - afdeling van vrae begin op die derde bladsy van die pset spec.
En die eerste deel vra dat jy om te gaan en die kort kyk op redirecting en pype.
Dit was soort van 'n koel kort, wys jou 'n paar nuwe, cool command line truuks wat jy kan gebruik.
En dan het ons het 'n paar vrae vir jou so goed.
Die eerste vraag oor strome, waarin printf skryf by verstek,
ons soort van net 'n bietjie aangeraak 'n oomblik gelede.
Dit fprintf wat ons nou net bespreek neem in 'n lêer * stroom as sy argument.
fclose neem in 'n lêer * stroom so goed,
en die terugkeer waarde van fopen gee jou 'n lêer * stroom as well.
Die rede waarom ons nie die voorheen gesien wanneer ons het gehandel met printf
is omdat printf 'n standaard stroom.
En die verstek stroom wat dit skryf
jy sal vind meer uit oor in die kort.
So beslis neem 'n blik op dit.
>> In vandag se artikel, gaan ons 'n bietjie om te praat oor GDB,
sedert die meer vertroud is jy met dit, die meer oefening jy met dit,
beter in staat sal wees om werklik te jag af foute in jou eie kode.
Dit versnel die proses van ontfouting geweldig.
Dus, deur die gebruik van printf, elke keer as jy doen wat jy het om jou kode te hercompileren,
jy het dit weer uit te voer, soms moet jy die printf oproep om rond te beweeg,
kommentaar kode, dit neem net 'n rukkie.
Ons doel is om te probeer en jy oortuig dat met GDB, kan jy in wese
printf enigiets op enige punt in jou kode en jy nooit weer hoef dit te hercompileren.
Jy hoef nooit weer te begin en hou raai waar om te printf volgende.
Die eerste ding om te doen is om hierdie lyn te kopieer en die afdeling kode van die web af.
Ek die kopiëring van hierdie lyn van kode wat sê, "wget ​​http://cdn.cs50.net".
Ek gaan om dit te kopieer.
Ek gaan om te gaan na my toestel, uitzoomen sodat jy kan sien wat ek doen,
plak dit in daar, en toe ek druk Enter hierdie wget opdrag letterlik is om 'n web te kry.
Dit gaan hierdie lêer af te trek van die Internet af,
en dit gaan en stoor dit in die huidige gids.
Nou as ek my huidige gids lys kan jy sien dat ek hierdie section5.zip lêer het reg daar.
Die manier om te gaan met daardie man is om dit oop te rits,
wat jy kan doen in die command line, net soos hierdie.
Section5.zip.
Dat dit sal Pak, die skep van die gids vir my,
blaas al die inhoud, sit hulle in daar.
So nou kan ek gaan in my artikel 5 directory deur gebruik te maak van die cd opdrag.
Duidelik dat die skerm met behulp van duidelike. So duidelik die skerm.
Nou het ek 'n mooi skoon terminale om te hanteer.
>> Maar as ek n lys van al die lêers wat ek sien in hierdie gids,
jy sien dat ek vier lêers het: buggy1, buggy2, buggy3 en buggy4.
Ek het ook 'hul ooreenstemmende c lêers.
Ons gaan nie om te kyk na die c-lêers. Vir nou.
In plaas daarvan, ons gaan om dit te gebruik wanneer ons oopmaak GDB.
Ons het het hulle rondom, sodat ons toegang tot die werklike bronkode wanneer ons gebruik GDB,
maar die doel van hierdie deel van die artikel is om te geknoei rondom met GDB
en kyk hoe ons dit kan gebruik om uit te vind wat verkeerd gaan met elk van hierdie vier buggy programme.
Sodat ons net gaan regtig vinnig in die kamer rond,
en ek gaan om iemand te vra om een ​​van die karretjie programme uit te voer,
en dan sal ons as 'n groep deur GDB, en ons sal sien wat ons kan doen om hierdie programme te los,
of ten minste identifiseer wat verkeerd gaan in elkeen van hulle.
Kom ons begin hier met Daniël. Sal jy hardloop buggy1? Kom ons kyk wat gebeur.
[Daniel] Dit sê daar is 'n aansoek skuld. >> Ja. Presies.
So as ek hardloop buggy1, ek kry 'n seg skuld.
Op hierdie punt, kan ek gaan en maak buggy1.c,
probeer uitvind wat verkeerd gaan,
maar een van die mees aanstootlike dinge oor hierdie seg fout
is dat dit nie vertel op watter lyn van die program dinge verkeerd geloop het en gebreek het.
Jy soort van om te kyk na die kode
en uit te vind met behulp van raaiskoot en kyk of printf om te sien wat verkeerd gaan.
Een van die coolste dinge oor GDB is dat dit regtig, regtig maklik
die lyn om uit te vind wat jou program crashes.
Dit is heeltemal die moeite werd om dit te gebruik, selfs al is net vir daardie.
So om te laat selflaai GDB, ek tik GDB en dan gee ek dit die pad na die uitvoer wat ek wil uit te voer.
Hier is ek tik gdb ./buggy1.
Druk Enter. Gee my al hierdie inligting oor kopiereg,
en af ​​hier, sien jy hierdie lyn wat sê, "Lees simbole van / home /
jharvard/section5/buggy1. "
En as alles goed gaan, sien jy druk dit uit 'n boodskap wat lyk soos hierdie.
Dit simbole sal lees, sal dit sê: "Ek simbole is op die lees van jou uitvoerbare lêer"
en dan sal dit hierdie "gedoen" boodskap hier.
As jy sien 'n ander variasie van hierdie, of jy sien dit nie kon vind die simbole
of iets soos dit, wat dit beteken, is dat jy net nie jou uitvoerbare saamgestel behoorlik.
Wanneer ons programme vir gebruik met GDB stel, ons het daardie spesiale g vlag te gebruik,
en dit is by verstek as jy jou programme stel, net deur te tik maak
of buggy of herstel, enige van daardie.
Maar as jy dit handmatig opstel met kletteren, dan sal jy het om te gaan en dat-g vlag insluit.
>> Op hierdie punt, nou dat ons ons GDB prompt,
dit is redelik maklik om die program uit te voer.
Ons kan óf tik hardloop, of ons kan net tik r.
Meeste GDB opdragte kan afgekort word.
Gewoonlik net een of 'n paar letters, wat is redelik nice.
So Saad, as jy tik r en druk Enter, wat gebeur?
[Saad] Ek het SIGSEGV, segmentering skuld, en dan sal al hierdie codes.
>> Ja.
Soos ons sien op die skerm op die oomblik, en soos Saad het gesê,
wanneer ons tik run of r en druk Enter, ons kry nog steeds dieselfde seg skuld.
Sodat die gebruik GDB nie ons probleem op te los.
Maar dit gee ons 'n paar codes, en dit blyk dat hierdie codes
eintlik vertel vir ons waar dit gebeur.
Dit 'n bietjie te verwerk, hierdie eerste bietjie is die funksie wat alles verkeerd gaan.
Daar is dit __ strcmp_sse4_2, en dit vertel ons dat dit gebeur in hierdie lêer
genoem sysdeps/i386, al hierdie, weer, soort van 'n gemors, maar line 254.
Dit is soort van moeilik om te ontleed. Gewoonlik wanneer jy sien dinge soos hierdie,
wat beteken dat dit seg verskuiwings in een van die stelsel biblioteke.
So iets te doen met strcmp. Julle het gesien strcmp voor.
Nie te gek, maar dit beteken nie dat strcmp is gebreek of dat daar is 'n probleem met strcmp?
Wat dink jy, Alexander?
[Alexander] Is dit - is 254 die lyn? En die nie die binêre, maar dit is nie hul plafonne,
en dan is daar ander taal vir elke funksie. Is dat 254 in die funksie, of -?
>> Dis line 254. Dit lyk soos in hierdie s-lêer, so dit is gemeente-kode waarskynlik.
>> , Maar ek dink die meer dringende ding is, want ons het 'n seg skuld gekry,
en dit lyk asof dit kom van die strcmp funksie,
impliseer dit, dan is daardie strcmp gebreek?
Dit behoort nie, hopelik. So net omdat jy 'n segmentering skuld
in een van die stelsel funksioneer, tipies wat beteken dat jy net nie genoem dit korrek.
Die vinnigste ding om te doen om uit te vind wat werklik aangaan
wanneer jy iets sien wat mal soos hierdie, wanneer jy sien 'n seg skuld,
veral as jy 'n program wat die gebruik van meer as net die hoof,
is 'n sleepspoor te gebruik.
Ek afkorten sleepspoor deur die skryf van BT, in teenstelling met die volle sleepspoor woord.
Maar Charlotte, wat gebeur wanneer jy tik bt en druk Enter?
[Charlotte] Dit wys my twee lyne, lyn 0 en lyn 1.
>> Ja. So lyn 0 en line 1.
Dit is die werklike stapel rame wat tans in die spel wanneer jou program neergestort het.
Begin van die boonste raam, raam 0, en gaan na die onderste, wat is raam 1.
Ons boonste raam is die strcmp raam.
Jy kan dink van hierdie as soortgelyk aan dat die probleem wat ons net op die quiz met die wysers,
waar ons het op die top van die belangrikste stapel stapel ruil,
en ons het die veranderlikes wat swap gebruik op die top van die veranderlikes wat die belangrikste is die gebruik van.
Hier om ons ongeluk gebeur het in ons strcmp funksie, wat deur ons belangrikste funksie genoem is,
en sleepspoor gee ons nie net die funksies wat dinge misluk,
maar dit is ook om ons te vertel waar alles is, geroepe uit.
So as ek scroll oor 'n bietjie meer na regs,
kan ons sien dat ja, ons on line 254 van hierdie strcmp-sse4.s lêer.
Maar die oproep was gemaak by buggy1.c, line 6.
Dus beteken dit dat ons kan doen - ons kan net gaan check en kyk wat aangaan
by buggy1.c, line 6.
Weereens, daar is 'n paar maniere om dit te doen. Een daarvan is om af te sluit van GDB
of jou kode in 'n ander venster oopmaak en kruisverwysing.
Dat, in en van die self, is redelik handig want nou as jy by kantoorure
en jy het 'n seg skuld en jou TF wonder waar alles breek,
jy kan net sê, "O, lyn 6. Ek weet nie wat gaan aan,
maar iets oor line 6 veroorsaak dat my program om te breek. "
Die ander manier om dit te doen, is wat jy kan gebruik maak van hierdie opdrag genoem lys in GDB.
Jy kan ook afkorten dit met l.
So as ons getref l, wat ons hier kry?
Ons kry 'n hele klomp van die vreemde dinge.
Dit is die werklike vergadering kode
wat in strcmp_sse4_2.
Dit lyk soort van funky,
en die rede waarom ons kry is omdat right now,
GDB het ons in raam 0.
>> Dit doen wanneer ons kyk na die veranderlikes, enige tyd wat ons kyk na die bronkode,
ons is op soek na die bronkode wat betrekking het op die stapel raam ons tans is.
So om iets betekenisvol te kry, moet ons
skuif na 'n stapel raam wat meer sin maak.
In hierdie geval, sou die belangrikste stapel raam 'n bietjie meer sin maak,
want dit was eintlik die kode wat ons geskryf het.
Nie die strcmp kode.
Die manier waarop jy kan beweeg tussen rame, in hierdie geval, want ons het twee,
ons het 0 en 1,
jy dit doen met die up en down opdragte.
As ek beweeg op 'n raam,
nou is ek in die belangrikste stapel raam.
Ek kan beweeg om terug te gaan na waar ek was,
weer nader trek, gaan af weer, en gaan weer.
As jy ooit jou program in GDB doen, kry jy 'n ongeluk, kry jy die sleepspoor
en jy sien dat dit in sommige lêer dat jy nie weet wat gaan aan.
Jy probeer lys, die kode nie kyk aan jou bekend,
neem 'n blik op jou rame en uit te vind waar jy is.
Is jy waarskynlik in die verkeerde stapel raam.
Of ten minste jy in 'n stapel raam dit is nie die een wat jy werklik kan ontfout.
Nou dat ons in die toepaslike stapel raam, ons is in die hoof,
nou kan ons die lys opdrag gebruik om uit te vind wat die lyn was.
En jy kan sien dit, dit druk dit vir ons hier.
Maar ons kan Hit List almal dieselfde, en die lys gee ons hierdie mooi uitdruk
van die werklike bron kode wat gaan hier.
>> In die besonder, kan ons kyk na line 6.
Ons kan sien wat hier aangaan nie.
En dit lyk asof ons die maak van 'n string vergelyking
tussen die string "CS50 rotse" en bevat SPASIES [1].
Iets omtrent hierdie is gekraak.
So Missy, het jy enige gedagtes oor wat gaan hier aan?
[Missy] Ek weet nie waarom dit gekraak. >> Jy weet nie hoekom dit gekraak?
Jimmy, enige gedagtes?
[Jimmy] Ek is nie heeltemal seker nie, maar die laaste keer wat ons gebruik string te vergelyk,
of strcmp, het ons soos drie verskillende gevalle onder dit.
Ons het nie 'n ==, ek dink nie, reg in daardie eerste lyn.
In plaas daarvan was verdeel in drie en een was == 0,
een was <0, dink ek, en 'n mens was> 0.
So miskien iets soos dit? >> Ja. So daar is hierdie kwessie
van doen ons die vergelyking korrek?
Stella? Enige gedagtes?
[Stella] Ek is nie seker nie. >> Nie seker nie. Daniel? Gedagtes? Okay.
Dit blyk uit wat gebeur hier is wanneer ons hardloop die program
en ons het die seg skuld, wanneer jy hardloop die program vir die eerste keer, Daniel,
het jy gee dit 'n command line argumente?
[Daniel] No >> No. In daardie geval, wat is die waarde van [1] bevat SPASIES?
>> Daar is geen waarde nie. >> Reg.
Wel, daar is geen geskikte string waarde.
Maar daar is 'n paar waarde. Wat is die waarde wat daar gestoor kry?
>> 'N gemors waarde? >> Dit is óf 'n gemors waarde of, in hierdie geval,
die einde van die bevat SPASIES skikking is altyd beëindig met null.
So, wat eintlik het gestoor in daar is null.
Die ander manier om dit op te los, eerder as om te dink dit deur,
is om te probeer om druk dit uit.
Dit is waar ek het gesê dat die gebruik van GDB is 'n groot,
want jy kan druk uit al die veranderlikes, al die waardes wat jy wil
die gebruik van hierdie handy-dandy p opdrag.
So as ek tik p en dan het ek tik die waarde van 'n veranderlike of die naam van 'n veranderlike,
sê, die argc, ek sien dat argc is 1.
As ek wil uit te druk bevat SPASIES [0], kan ek dit doen net soos wat.
En soos ons gesien het, bevat SPASIES [0] is altyd die naam van jou program,
altyd die naam van die uitvoerbare.
Hier sien jy die volle padnaam het.
Ek kan ook druk bevat SPASIES [1] en sien wat gebeur.
>> Hier het ons het hierdie soort van mistieke waarde.
Ons het hierdie 0x0.
Onthou om die begin van die kwartaal, toe ons gepraat oor heksadesimale getalle?
Of daardie klein vraag oor hoe om 50 te verteenwoordig in blok aan die einde van pset 0?
Die manier waarop ons skryf blok getalle in CS, net om nie verwar onsself
met desimale getalle, is dat ons altyd prefix hulle met 0x.
So hierdie 0x voorvoegsel beteken net altyd interpreteer die volgende nommer as 'n heksadesimale getal,
nie as 'n string, nie as 'n desimale getal, nie as 'n binêre getal.
Aangesien die getal 5-0 is 'n geldige nommer in heksadesimaal.
En dit is 'n aantal desimale, 50.
So dit is net hoe ons disambiguate.
So 0x0 middel heksadesimale 0, wat ook desimale 0, binêre 0.
Dit is net die waarde 0.
Dit blyk dat dit is wat null is, eintlik, in die geheue.
Null is net 0.
Hier is die element gestoor op [1] bevat SPASIES null.
Dus het ons probeer om ons "CS50 rotse" string te vergelyk met 'n null string.
So ontwysing null, probeer dinge om toegang te verkry tot null,
dit word gewoonlik gaan om 'n soort van segmentering skuld of ander slegte dinge gebeur te veroorsaak.
En dit blyk dat strcmp nie kyk om te sien
of jy in 'n waarde wat null geslaag het.
Inteendeel, dit gaan net vorentoe, probeer om sy ding te doen,
en indien dit seg foute, dit seg foute, en dit is jou probleem. Jy het om te gaan regmaak.
Regtig vinnig, kan hoe ons hierdie probleem op te los? Charlotte?
[Charlotte] Jy kan die gebruik van as.
So as bevat SPASIES [1], is van nul, == 0, dan terug 1, of iets [onverstaanbaar].
>> Ja. So dit is 'n goeie manier om dit te doen, as ons kan kyk om te sien,
die waarde wat ons is om te slaag in strcmp, bevat SPASIES [1], is dit nul?
As dit null, dan moet ons kan sê okay, aborteer.
>> 'N meer algemene manier om dit te doen, is om die argc waarde te gebruik.
Jy kan hier aan die begin van die hoof sien,
ons dat die eerste toets weggelaat wat ons gewoonlik doen wanneer ons gebruik command line argumente,
wat is om te toets of ons argc waarde is wat ons verwag.
In hierdie geval, ons verwag dat ten minste twee argumente,
die naam van die program, plus een ander persoon.
Want ons is oor die tweede argument hier gebruik.
So 'n soort van die toets vooraf voor ons strcmp oproep
dat toetse of bevat SPASIES is ten minste 2, sou ook die dieselfde soort van ding doen.
Ons kan sien of dit werk deur die loop van die program weer.
Jy kan altyd herlaai program binne GDB, wat is regtig mooi.
Jy kan hardloop, en wanneer jy in argumente na jou program,
jy slaag hulle in wanneer jy bel hardloop, nie wanneer jy opstart GDB.
Die manier wat jy kan hou oproep van jou program met verskillende argumente elke keer.
So hardloop, of weer, ek kan tik r, en laat ons sien wat gebeur as ons tik "hallo".
Dit sal altyd vra as jy wil dit van die begin af weer te begin.
Gewoonlik wil jy dit van die begin af weer te begin.
En op hierdie punt, is dit weer begin dit weer, dit druk uit
die program dat ons hardloop, buggy1, met die argument hallo,
en dit druk hierdie standaard uit, dit sê, "Jy kry 'n D," hartseer gesig.
Maar ons het nie seg skuld. Daar word gesê dat die proses gewoonlik opgewonde.
So dit lyk redelik goed.
Geen meer seg fout, ons het dit verlede,
sodat dit lyk soos dit was inderdaad die seg fout fout wat ons kon kry.
Ongelukkig is dit vir ons sê dat ons 'n D. kry
>> Ons kan terug gaan en kyk na die kode en kyk wat daar aangaan
om uit te vind wat was - waarom dit is om ons te vertel dat ons 'n D.
Kom ons kyk, hier is hierdie printf sê dat jy 'n D.
As ons tik lys, as jy hou tik lys, dit hou deur jou program iterating,
so dit sal wys jy die eerste paar lyne van jou program.
Dan sal dit wys dat jy die volgende paar lyne, en die volgende stuk en die volgende stuk.
En dit sal aanhou probeer om af te gaan.
En nou het ons kry "lyn nommer 16 is buite bereik."
Want dit het slegs 15 lyne.
As jy op hierdie punt en jou wonder, "Wat moet ek doen?" jy kan gebruik om die hulp opdrag.
Gebruik help en dan gee dit die naam van 'n opdrag.
En jy sien die GDB gee ons al hierdie soort van dinge.
Dit sê, "Met geen argument, lys van tien lyne na of rondom die vorige lys.
Lys - bevat 'n lys van die tien lyne voor "
So laat ons probeer om met behulp van lys minus.
En 'n lys van die 10 lyne vorige, kan jy speel 'n bietjie rond met lys.
Jy kan lys, lys doen - jy kan selfs gee noem 'n aantal, soos die lys 8,
en dit sal n lys van die 10 lyne rondom line 8.
En jy kan sien wat gaan hier aan jy het 'n eenvoudige as anders.
As jy tik in CS50 rotse, druk dit uit "Jy kry 'n A."
Andersins is dit druk uit "Jy kry 'n D."
Bummer dorp. Alles reg. Ja?
>> [Daniel] En toe ek probeer doen CS50 rotse sonder die aanhalingstekens,
dit sê: "Jy kry 'n D."
Ek nodig het om die kwotasies te kry om dit te werk, hoekom is dit?
>> Ja. Dit blyk dat wanneer - dit is 'n prettige klein versnapering -
wanneer jy die program, as ons hardloop en ons tik in CS50 rotse,
net soos Daniël het gesê hy gedoen het, en jy druk Enter,
dit sê nog steeds kry ons 'n D.
En die vraag is hoekom nie, is dit?
En dit blyk dat beide ons terminale en GDB parse dit as twee afsonderlike argumente.
Want wanneer daar 'n ruimte, wat geïmpliseer is as
die eerste argument geëindig, die volgende argument is om te begin.
Die manier waarop dié in twee te kombineer, of jammer, in 'n argument,
is die aanhalingstekens te gebruik.
So as ons nou, sit dit in aanhalingstekens en loop dit weer, kry ons 'n A.
So net om te Kortom, geen aanhalings, CS50 en rotse as twee afsonderlike argumente ontleed.
Met aanhalings, dit ontleed as 'n argument heeltemal.
>> Ons kan dit met 'n breekpunt.
Tot dusver het ons is die uitvoer van ons program, en dit is al
totdat dit óf seg foute of hits 'n fout
of totdat dit het 'n opgewonde en alles was heeltemal fyn.
Dit is nie noodwendig die mees nuttige ding, want soms
jy het 'n fout in jou program, maar dit is nie veroorsaak dat 'n segmentering skuld.
Dit is nie veroorsaak dat jou program te stop of iets soos dit.
Die manier waarop GDB te kry om te breek jou program op 'n bepaalde punt
is 'n breekpunt te stel.
Jy kan dit doen deur die opstel van 'n breekpunt op 'n funksie naam
of jy kan 'n breekpunt te stel op 'n spesifieke lyn van kode.
Ek hou van inspeksiepunte op die funksie name te stel, omdat - maklik om te onthou,
en as jy eintlik gaan in en verander jou bron-kode 'n bietjie,
dan sal jou breekpunt eintlik bly op dieselfde plek in jou kode.
AANGESIEN dit as jy reëlnommers gebruik, en die lyn nommers verander
omdat jy byvoeg of verwyder een of ander kode, dan is jou inspeksiepunte is heeltemal al screwed up.
Een van die mees algemene dinge wat ek doen is 'n breekpunt op die belangrikste funksie.
Dikwels het ek sal selflaai GDB, sal ek tik b hoof, druk Enter, en dit sal 'n breekpunt te stel
op die hooffunksie wat net sê, "Stop die program so gou as jy begin hardloop,"
en dat die pad, toe ek my program met, sê, CS50 rotse loop as twee argumente
en druk Enter, dit raak aan die hoofprogram en dit stop regs by die heel eerste lyn,
reg voor dit evalueer die strcmp funksie.
>> Aangesien ek gestop, nou kan ek begin mucking rond en sien wat gaan aan
met al die verskillende veranderlikes wat in my program geslaag word.
Hier kan ek druk argc en kyk wat gaan aan.
Sien dat argc is 3 nie, want dit het 3 verskillende waardes in.
Dit die naam van die program het, dit het die eerste argument en die tweede argument.
Ons kan druk wat uit deur te kyk by bevat SPASIES [0], bevat SPASIES [1], en bevat SPASIES [2].
So nou kan jy ook sien waarom hierdie strcmp oproep gaan om te misluk,
omdat julle sien dat dit het verdeel die CS50 en die rotse in twee afsonderlike argumente.
Op hierdie punt, as jy het 'n breekpunt getref, kan jy voortgaan om te stap vir stap deur jou program
reël vir reël, eerder as aan die begin van jou program weer.
So as jy nie wil hê om jou program te weer en net begin voortgaan om van hier,
kan jy die continue opdrag gebruik en voortgaan sal die program loop tot die einde toe.
Net soos dit hier gedoen het.
Maar as ek die program, CS50 rotse herlaai, is dit treffers weer my breekpunt,
en hierdie keer, as ek wil nie om net te gaan al die pad deur die res van die program,
Ek kan gebruik om die volgende opdrag, wat Ek ook afkorten met n.
En dit sal stap vir stap deur die program lyn deur die lyn.
Sodat jy kan sien as dinge uit te voer, as veranderlikes, soos dinge opgedateer.
Wat is redelik nice.
Die ander cool ding is, eerder as dieselfde opdrag herhaal oor en oor en oor weer,
as jy net Enter tref - so hier is julle sien dat Ek het nie in enigiets getik -
as ek net druk Enter, sal dit die vorige opdrag herhaal,
of die vorige GDB bevel gegee het dat ek net sit.
Ek kan hou Enter en dit sal aanhou versterk deur my kode reël vir reël.
Ek wil julle aanmoedig om te gaan check out die ander buggy programme sowel.
Ons het nie tyd om te kry deur almal van hulle vandag in artikel.
Die bron-kode is daar, sodat jy kan soort van kyk wat gaan aan
agter die skerms as jy regtig vashaak,
maar op die heel minste, net oefen selflaai GDB,
die uitvoer van die program totdat dit breek op jou,
om die sleepspoor, uitzoeken wat funksioneer die ongeluk was,
watter lyn dit was op sommige veranderlike waardes uit te druk,
net sodat jy kry 'n gevoel vir dit, want dit sal regtig help om die pad vorentoe.
Op hierdie punt, ons gaan uit GDB om op te hou, wat jy met behulp van stop of net q.
As jou program is in die middel van die bestuur nog steeds, en dit het nie opgewonde,
dit sal altyd vra jou, "Is jy seker dat jy regtig wil om te stop?"
Jy kan net getref ja.
>> Nou gaan ons kyk na die volgende probleem wat ons het, wat is die kat.
As jy kyk na die kort redirecting en pype, sal jy sien dat Tommy gebruik maak van hierdie program
wat druk basies al die uitset van 'n lêer op die skerm.
So as ek hardloop kat, dit is eintlik 'n ingeboude in die program aan die apparaat,
en as jy 'n Mac, kan jy dit doen op jou Mac, as jy oopmaak terminale.
En ons kat, laat ons sê, cp.c, en druk Enter.
Wat dit gedoen het, as ons 'n bietjie scroll en kyk waar ons die lyn gehardloop,
of waar ons die kat opdrag gehardloop, het dit letterlik net gedruk uit die inhoud van cp.c na ons skerm.
Ons dit weer kan hardloop en jy kan sit in veelvuldige lêers saam.
Sodat jy kan kat cp.c doen, en dan kan ons ook koppel die cat.c lêer,
wat is die program wat ons oor te skryf,
en dit sal beide lêers druk rug aan rug na ons skerm.
So as ons 'n bietjie scroll, sien ons dat wanneer ons hierdie kat cp.c, cat.c gehardloop,
dit eerste gedruk die cp lêer, en dan hier, is dit druk die cat.c lêer regs af hier.
Ons gaan om dit te gebruik om net ons voete nat.
Speel rond met 'n eenvoudige druk op die terminale, sien hoe dit werk.
As julle oop te maak met gedit cat.c, druk Enter
jy kan sien die program dat ons oor te skryf.
Ons het hierdie mooi ketel plaat het, sodat ons nie tyd het om te bestee tik alles wat uit.
Ons gaan ook die aantal argumente geslaag.
Ons druk 'n mooi gebruik boodskap.
>> Dit is die soort van ding wat, weer, soos ons het gepraat oor,
dit is amper soos spier-geheue.
Net onthou om te hou die dieselfde soort van dinge te doen
en altyd 'n soort van nuttige boodskap uit te druk
sodat mense weet hoe om jou program te begin.
Met kat, dit is redelik maklik, ons is net gaan om te gaan deur al die verskillende argumente
wat geslaag is aan ons program, en ons gaan te druk
hul inhoud op die skerm een ​​op 'n tyd.
Om die lêers na die skerm te druk, gaan ons iets baie soortgelyk aan
wat ons gedoen het aan die einde van die quiz.
Aan die einde van die quiz, wat huur program, het ons 'n lêer oop te maak,
en dan het ons het om dit uit te druk.
In hierdie geval, ons gaan 'n lêer oop te maak, en ons gaan in plaas van dit te lees.
Daarna het ons gaan uit te druk, in plaas van na 'n lêer, gaan ons na die skerm te druk.
So druk op die skerm wat jy al voorheen gedoen met printf.
So dit is nie te gek.
Maar die lees van 'n lêer is 'n soort van weird.
Ons gaan deur dat 'n bietjie op 'n tyd.
As jy ouens gaan terug na daardie laaste probleem op jou quiz, probleem 33,
die eerste lyn wat ons gaan doen, die opening van die lêer, is baie soortgelyk aan wat ons daar het.
So Stella, wat beteken dat die lyn lyk soos wanneer ons 'n lêer oopmaak?
[Stella] Capital FILE *, lêer - >> Goed. >> - Is gelyk aan fopen. >> Yup.
Wat in hierdie geval is? Dit is in die kommentaar.
>> Dit is in die kommentaar? bevat SPASIES [i] en r?
>> Presies. Reg op. Stella is dus heeltemal reg.
Dit is wat die lyn so lyk.
Ons gaan 'n lêer stroom veranderlike te kry, stoor dit in 'n lêer *, sodat alle pette,
FILE, *, en die naam van hierdie veranderlike sal wees lêer.
Ons kan dit noem wat ons wil. Ons kan dit noem first_file, of file_i, wat ons ook al wil.
En dan die naam van die lêer is op die command line tot hierdie program geslaag.
So dit is gestoor in bevat SPASIES [i] en dan gaan ons om hierdie lêer oop te maak in die lees af.
Nou dat ons die lêer oopgemaak het, wat is die ding wat ons altyd moet onthou om te doen
wanneer ons 'n lêer geopen het? Sluit dit.
So Missy, hoe ons 'n lêer sluit?
[Missy] fclose (lêer) >> fclose (lêer). Presies.
Groot. Okay. As ons kyk na hierdie kommentaar hier doen,
dit sê, "Open bevat SPASIES [i] en druk die inhoud na stdout."
>> Standard out is 'n vreemde naam. Stdout is net ons manier om te sê
ons wil om dit te druk tot die terminale, ons wil om dit te druk om die standaard produksie stroom.
Ons kan eintlik ontslae te raak van hierdie kommentaar hier.
Ek gaan om dit te kopieer en plak dit want dit is wat ons gedoen het.
Op hierdie punt, nou het ons om te lees van die lêer bietjie vir bietjie by.
Ons het 'n paar van die maniere van lees lêers bespreek.
Watter is jou gunsteling tot dusver?
Watter maniere het jy al gesien of onthou jy, lêers te lees?
[Daniel] fread? >> Fread? So fread is een. Jimmy, weet jy enige ander?
[Jimmy] No >> Goed. Nope. Charlotte? Alexander? Enige ander? Okay.
Sodat die ander kinders is fgetc, is een wat ons sal gebruik maak van 'n baie.
Daar is ook fscanf; julle sien 'n patroon hier?
Hulle het almal begin met f. Om iets te doen met 'n lêer.
Daar is fread, fgetc, fscanf. Dit is al van die lees van funksies.
Vir die skryf van ons het fwrite, ons het in plaas van fgetc fputc.
Ons het ook graag fprintf het ons op die quiz gesien het.
Want dit is 'n probleem wat behels die lees van 'n lêer,
ons gaan een van hierdie drie funksies te gebruik.
Ons gaan nie hierdie funksies te gebruik hier neer.
Hierdie funksies is almal in die standaard I / O biblioteek.
So as jy kyk na die top van hierdie program,
kan jy sien dat ons alreeds die header-lêer vir die standaard I / O biblioteek ingesluit.
As ons wil hê om uit te vind watter een ons wil gebruik,
ons kan altyd die man bladsye oop te maak.
Sodat ons kan tik man Wiskunde Streek Leuven B.
en lees alles oor die Wiskunde Streek Leuven B. inset en uitset funksies in C.
En ons kan reeds sien oh, kyk. Dit fgetc noem, is dit waarin fputc.
Sodat jy kan boor 'n bietjie af en kyk na, sê, fgetc
en kyk op sy man bladsy.
Jy kan sien dat dit gaan saam met 'n hele klomp van die ander funksies:
fgetc, fgets, AOOS, getChar, kry, ungetc, en sy insette van karakters en stringe.
So dit is hoe ons lees in karakters en stringe van lêers van standaard insette,
wat is in wese van die gebruiker.
En dit is hoe ons dit doen in die werklike C.
Dit is dus nie die gebruik van die GetString en getChar funksies
wat ons gebruik van die CS50 biblioteek.
Ons gaan hierdie probleem op te doen in 'n paar van die maniere
sodat jy kan sien twee verskillende maniere om dit te doen.
Beide die fread funksie wat Daniël genoem en fgetc is goeie maniere om dit te doen.
Ek dink fgetc is 'n bietjie makliker, omdat dit net, soos jy kan sien,
een argument, die lêer * dat ons probeer om die karakter te lees,
en sy terugkeer waarde is 'n int.
En dit is 'n bietjie verwarrend, reg?
>> Omdat ons om 'n karakter, so hoekom nie hierdie opgawe 'n kar?
Julle ouens het enige idees oor hoekom dit dalk nie terugkeer nie 'n kar?
[Missy antwoorde, onverstaanbare] >> Ja. Missy is dus heeltemal reg.
As dit is ASCII, dan is hierdie heelgetal kan gekarteer word om 'n werklike karakter.
Kan 'n ASCII-karakter wees, en dit is reg.
Dit is presies wat gebeur.
Ons is met behulp van 'n int bloot omdat dit meer stukkies.
Dit is groter as 'n char, ons kar net bestaan ​​uit 8 bisse, dat 1 greep op ons 32-bit masjiene.
En 'n int het al 4 bytes waarde van die ruimte.
En dit blyk dat die manier fgetc werk,
as ons scroll down in ons sinopsis in hierdie man 'n bietjie,
blaai al die pad af. Dit blyk dat hulle gebruik maak van hierdie spesiale waarde genoem EOF.
Dit is 'n spesiale konstante as die terugkeer waarde van die fgetc funksie
wanneer jy druk op die einde van die lêer of as jy 'n fout.
En dit blyk dat hierdie vergelykings te doen met EOF behoorlik,
jy wil daardie ekstra bedrag van die inligting wat jy in 'n int
in teenstelling met die gebruik van 'n char veranderlike.
Selfs al fgetc is effektief om 'n karakter uit 'n lêer,
jy wil om te onthou dat dit iets wat van tipe int vir julle terugkeer.
Dit gesê, dit is redelik maklik om te gebruik.
Dit gaan ons 'n karakter te gee, sodat al wat ons hoef te doen, is hou om die lêer te vra,
"Gee my die volgende karakter, gee my die volgende karakter, gee my die volgende karakter,"
totdat ons aan die einde van die lêer.
En dit sal trek in een karakter op 'n tyd uit ons lêer,
en dan sal ons kan doen wat ons wil met dit.
Ons kan dit stoor, kan ons voeg dit na 'n string, kan ons druk dit uit.
Het enige van daardie.
>> Inzoomen terug en terug te gaan na ons cat.c program,
as ons gaan te gebruik fgetc,
hoe kan ons nader aan die volgende lyn van die kode?
Ons gaan om te gebruik - fread sal iets anders doen.
En hierdie keer, ons net gaan fgetc te gebruik om een ​​karakter te kry op 'n tyd.
'N hele lêer te verwerk, kan dit wat ons het om te doen?
Hoeveel karakters is daar in 'n lêer?
Daar is 'n baie. So het jy waarskynlik wil om een ​​te kry
en dan kry 'n ander en kry 'n ander en kry 'n ander.
Watter soort van die algoritme dink jy ons kan hê om hier te gebruik?
Watter tipe? [Alexander] A vir lus? >> Presies.
'N soort van loop.
'N lus is eintlik groot, in hierdie geval.
En soos jy sê, dit klink asof jy wil 'n lus oor die hele lêer,
om 'n karakter op 'n tyd.
Enige voorstelle oor wat dit kan lyk?
[Alexander, onverstaanbaar]
>> Goed, vertel my net in Engels wat jy probeer om te doen? [Alexander, onverstaanbaar]
Dus, in hierdie geval, dit klink asof ons net probeer om te loop oor die hele lêer.
[Alexander] So i > Die grootte van?
Ek dink dat die grootte van die lêer, reg? Die grootte - sal ons net skryf dit soos hierdie.
Grootte van die lêer wat vir die oomblik, i + +.
So dit blyk dat die manier waarop jy dit doen met fgetc, en dit is 'n nuwe,
is dat daar is geen maklike manier om net die grootte van 'n lêer
met hierdie "sizeof" tipe konstrueer wat jy nog nooit gesien.
Wanneer gebruik ons ​​dat fgetc funksie, is ons die invoering van 'n soort van
nuwe, funky sintaksis te lus, waar in plaas van die gebruik van net 'n basiese counter
karakter deur karakter om te gaan, gaan ons een karakter op 'n tyd om te trek,
een karakter op 'n tyd, en die manier waarop ons weet ons is aan die einde
is nie wanneer het ons getel word om 'n sekere aantal van karakters,
maar wanneer die karakter wat ons trek uit daardie spesiale einde van die lêer karakter.
Sodat ons kan dit doen deur - ek noem dit ch, en ons gaan om dit te inisialiseer
met ons eerste oproep om die eerste karakter te kry uit van die lêer.
So hierdie gedeelte reg hier, dit gaan om 'n karakter te kry uit van die lêer
en stoor dit in die veranderlike ch.
Ons gaan om te hou om dit te doen totdat ons aan die einde van die lêer,
wat ons doen deur te toets vir die karakter wat nie gelyk is aan daardie spesiale EOF karakter.
En dan in plaas van doen ch + +, wil net wat inkrementeer die waarde,
so as ons lees 'n A-out van die lêer, 'n hoofletter A, sê,
ch + + sou gee ons b, en dan ons wil kry c en dan d.
Dit is duidelik nie wat ons wil hê. Wat wil ons hier
in hierdie laaste bietjie wil ons die volgende karakter te kry uit die lêer.
>> So, hoe kan ons die volgende karakter van die lêer?
Hoe kry ons die eerste karakter van die lêer?
[Studente] fgetfile? >> Fgetc, of, jammer, jy is heeltemal reg.
Ek verkeerd gespel dit reg daar. So ja.
Hier in plaas van doen ch + +,
ons net gaan fgetc (lêer) weer te noem
en stoor die resultaat in ons dieselfde ch veranderlike.
[Student vraag, onverstaanbaar]
>> Dit is waar hierdie FILE * ouens is spesiaal.
Die manier waarop hulle werk is hulle - wanneer jy die eerste keer oopmaak wanneer jy die eerste keer dat die fopen oproep maak,
Die lêer * dien effektief as 'n wyser na die begin van die lêer.
En dan elke keer as jy bel fgetc, is dit een karakter beweeg deur middel van die lêer.
So wanneer jy noem dit, jy die verhoog van die lêer wyser deur een karakter.
En wanneer jy weer fgetc, jy beweeg dit 'n ander karakter
en 'n ander karakter en 'n ander karakter en 'n ander karakter.
[Student vraag, onverstaanbaar] >> En that's - ja.
Dit is soort van hierdie magie onder die kap.
Jy hou net verhoog van deur.
Op hierdie punt, is jy in staat om werklik te werk met 'n karakter.
So, hoe kan ons print dit uit op die skerm, wat nou?
Ons kan gebruik maak van die dieselfde printf ding wat ons gebruik voor.
Wat ons het is die gebruik van al die semester.
Ons kan printf noem,
en ons kan net soos wat in die karakter.
Nog 'n manier om dit te doen is eerder as die gebruik van printf en met hierdie formaat string te doen,
Ons kan ook gebruik maak van een van die ander funksies.
Ons kan gebruik fputc, wat 'n karakter op die skerm druk,
behalwe as ons kyk by fputc - laat my 'n bietjie uit te zoem.
Ons sien wat mooi is, is wat dit neem om in die karakter wat ons lees met behulp van fgetc,
maar dan moet ons om te gee dit 'n stroom te druk.
Ons kan ook gebruik maak van die putchar funksie, wat direk aan die standaard uit.
So daar is 'n hele klomp van die verskillende opsies wat ons kan gebruik vir die druk.
Hulle is almal in die standaard I / O-biblioteek.
Wanneer jy wil uit te druk - so printf, by verstek, sal die spesiale standaard uit stroom druk,
wat is dat stdout.
Sodat ons kan net verwys na dit as soort van hierdie magic waarde, stdout hier.
Oeps. Sit die kommapunt buite.
>> Dit is 'n baie nuwe, funky inligting hier.
Baie van hierdie is baie idiomatiese, in die sin dat dit is die kode
wat geskryf is op hierdie manier net omdat dit skoon te lees, maklik om te lees.
Daar is baie verskillende maniere om dit te doen, baie verskillende funksies wat jy kan gebruik,
maar ons is geneig om net dieselfde patrone volg oor en oor.
So moenie verbaas wees as jy sien kode soos hierdie kom weer en weer.
Alles reg. Op hierdie punt, ons nodig het om te breek vir die dag.
Dankie vir die komende. Dankie vir jou kyk as jy aanlyn is. En ons sal jou volgende week sien.
[CS50.TV]