[Powered by Google Translate] [5. SZAKASZ: kevésbé kényelmes]
[Nate Hardison, Harvard University]
[Ez a CS50.] [CS50.TV]
Szóval szívesen vissza, srácok.
Üdvözöljük a 5. szakasz.
Ezen a ponton, miután befejezte kvíz 0, és miután látta, hogy hogyan tettél,
remélhetőleg úgy érzi, nagyon jó, mert én nagyon lenyűgözött a pontszámok ebben a fejezetben.
Az online nézők, már volt egy pár kérdést
az utolsó két probléma a probléma set - vagy a kvíz, inkább.
Szóval megyek át ezen nagyon gyorsan, hogy mindenki látja, hogy mi történt
és hogyan, hogy menjen át a tényleges megoldás nem csak megtekintők a megoldás is.
Fogunk menni az elmúlt néhány probléma nagyon gyorsan, 32 és 33.
Csak, ismét úgy, hogy az on-line nézők láthatja ezt.
>> Ha viszont a probléma 32, amely a 13. oldalon,
16-ból 13, a probléma 32 szól swap.
Ez volt minden a csere két egész szám.
Ez az a probléma, hogy mi volna ment egy pár alkalommal előadás.
És itt, mit is kér tőled egy gyors memória nyom.
Ahhoz, hogy írja be az értékeket a változók, mivel azok a verem
mivel a kód megy keresztül ez a csere funkciót.
Különösen az, amit keresünk - Megyek, hogy ezt az iPad le -
különösen az, amit keresünk ez a vonal száma pedig 6 itt.
És ez számozott 6 mindössze szomszédsági az előző probléma.
Mit akarunk csinálni a megjelenítéséhez vagy a címkét az állam a memória
mivel abban az időben, amikor végre ezt a sort a 6,
amely gyakorlatilag a visszatérés a mi-swap funkció itt.
Ha lapozzunk ide, láttuk, hogy a cím mindent a memóriában nyújtottak számunkra.
Ez nagyon kulcs, akkor gyere vissza rá, csak egy pillanatra.
És akkor itt lent az alján volt egy kevés memóriát diagram, hogy fogunk hivatkozni.
Én ténylegesen elvégzett ezt ki az én iPad.
Szóval megyek helyettesítheti között oda-vissza az iPad, és ezt a kódot csak a hivatkozás.
>> Kezdjük. Először is, hadd összpontosítani az első pár sor a fő itt.
Elindításához, megyünk inicializálni x 1 és y 2-re.
Tehát van két integer változó, ők mindketten fogják helyezni a verem.
Megyünk, hogy egy 1-es és a 2 bennük.
Szóval, ha átfordítja az én iPad, remélhetőleg, lássuk -
Apple TV tükrözés, és ott is vagyunk. Oké.
Szóval, ha átfordítja az én iPad,
Azt akarom, hogy inicializálni x 1 és y 2-re.
Tesszük, hogy egész egyszerűen írt egy 1 a doboz jelölt x
és a 2-ben a mezőben megjelölt y. Meglehetősen egyszerű.
És most térjünk vissza a laptop, mi történik ezután.
Tehát ez a következő sort, ahol a dolgok trükkös.
Elhaladunk a címét x és címét y, mint a és b paraméterekkel jellemzett, hogy a swap funkciót.
A cím az x és az y címét olyan dolgok, amiket nem tudunk számítani
hivatkozás nélkül ezeket pontokba szedve itt lent.
És szerencsére az első két pontokba szedve mondja el pontosan, mi a válasz.
A címe x memória 10, és címe y memória 14.
Tehát ezek azok az értékek, amelyek teljesen telt el, mint az a és b top up a mi csere funkciót.
Tehát újra, kapcsoló vissza a diagram, írhatok egy 10 egy
és egy 14 b.
Nos, ez a pont, ahol folytathatja a csere.
Szóval essek vissza a laptop újra,
azt látjuk, hogy az utat a csere működik, először dereference a és tárolja az eredményt tmp.
Tehát a dereference üzemeltető azt mondja, "Hé. Kezeljük a változó tartalmának olyan, mint egy cím.
Ide bármit tárolt arra a címre, és töltse azt. "
Mit betölteni ki a változó fogja tárolni a mi tmp változó.
Essek vissza az iPad.
Ha elmegyünk a cím 10, tudjuk, hogy az a cím 10 varible x
mert azt mondták, a mi felsorolási pont, hogy a címét x memória 10.
Tehát ott, hogy az értékét is, amely 1, mint látjuk a mi iPad,
és betölti azt a tmp.
Ismét, ez nem a végleges tartalma.
Elmegyünk séta, és mi lesz a mi végső állapotát a program végén.
De most már az 1-es érték tárolt tmp.
>> És van egy gyors kérdés itt.
[Alexander] Az dereference üzemben -, hogy ez csak a csillag láttára a változó?
>> Igen. Tehát a dereference üzemeltető, ahogy fordítsa vissza a laptop ismét
ez a csillag közvetlenül az épület előtt.
Ebben az értelemben, hogy - ha szembeállítani azt a szorzás operátor
amely előírja két dolgot, a dereference operátor egy egyoperandusú operátor.
Csak alkalmazni egy érték, szemben az egy bináris operátor,
ahol alkalmazni két különböző értékeket.
Szóval ez az, hogy mi történik ebben a sorban.
Mi betöltve az érték 1 és tárolt be mi ideiglenes integer változó.
A következő sorban, tároljuk a tartalmát ab-ba -
vagy inkább tárolunk a tartalmát, hogy b mutat, hogy a hely, ahol az is mutat.
Ha elemezzük ezt a jobbról balra, fogunk dereference b,
fogunk foglalkozni 14, fogunk megragad az egész, hogy ott van,
majd fogunk menni a cím 10,
és mi lesz, hogy dobja az eredmény a mi dereference az ab-ba, hogy a tér.
Flipping vissza az iPad, ha tudjuk, hogy ez egy kicsit konkrétabb,
talán segít, ha írok számokat az összes cím itt.
Tehát tudjuk, hogy y vagyunk címen 14, x címen 10.
Mikor kezdődnek b, akkor b dereference, megyünk, hogy megragad a 2 értéket.
Fogjuk, hogy megragad ez az érték, mert ez az az érték, hogy él címen 14.
És mi lesz, hogy azt a változót, hogy él címen 10,
ami ott van, amely megfelel a változó x.
Így nem tehetünk egy kicsit felülírja itt
ahol megszabadulni a 1-es és helyette írunk a 2.
Szóval minden jó, és jó a világban, még akkor is volna felülírja x most.
Van tárolt x régi értéke a tmp változó.
Így tudjuk befejezni a csere a következő sorban.
Flipping vissza a laptop.
Most minden marad az, hogy a tartalom a mi ideiglenes integer változó
és tárolja őket a változó, hogy él a címen, hogy b tartja.
Szóval megyünk hatékonyan dereference b kap hozzáférést a változó
ez a cím, hogy b tartja benne,
és mi lesz a cucc az érték tmp tartja bele.
Essek vissza az iPad még egyszer.
Tudom törölni ezt az értéket itt, 2,
és ehelyett mi másolja 1 jobb bele.
Aztán a következő sorban, amely végrehajtja, természetesen -
ha fordítsa vissza a laptop - ez a 6 pont,
amely az a pont, amit akartam, hogy a diagram teljesen kitölteni.
Szóval essek vissza az iPad még egyszer, csak így láthatja az elkészült diagram,
akkor láthatjuk, hogy van egy 10-a, a 14-ben b, 1 a tmp, a 2 x-ben, és egy 1-y.
Van bármilyen kérdése van ezzel?
Van ennek több értelme van, miután belépett rajta?
Győződjön kevesebb értelme? Remélhetőleg nem. Oké.
>> Mutatók egy nagyon bonyolult téma.
Az egyik srác, akikkel együtt dolgozunk egy nagyon gyakori mondás:
"Ahhoz, hogy megértsük mutató, először meg kell értenie mutatók."
Ami szerintem nagyon igaz. Ez nem fog egy darabig, hogy szokni.
Rajza sok képeket, sorshúzással memóriát diagramok, mint ez nagyon hasznosnak
és után séta után például Például után például,
ez lesz kezdeni, hogy egy kicsit több értelme van, és egy kicsit több értelme van, és egy kicsit több értelme van.
Végül, egy nap, akkor is mindent teljesen elsajátította.
Van még kérdése mielőtt lépni a következő probléma? Rendben van.
Így fordítsa vissza a laptop.
A következő probléma van a gond 33-a fájl I / O
Nagyítás ezen egy kicsit.
Probléma 33 - Igen?
>> [Daniel] Csak volt egy gyors kérdés. Ez a csillag, vagy a csillag,
ezt hívják dereferencing, ha egy csillag előtt.
Hogy is hívják, amikor a jel előtt?
>> A jel előtt a cím-operátorral.
Szóval lapozzunk vissza.
Hoppá. Én zoom módban, így nem tudok igazán lapozzunk.
Ha megnézzük ezt a kódot nagyon gyorsan itt,
megint ugyanaz a dolog történik.
Ha megnézzük ezt a kódot itt, ezen a vonalon, ahol a hívás a swap,
A jelet éppen azt mondja: "kap a cím, ahol x változó életét."
Amikor a fordító lefordítja a kódot,
azt, hogy ténylegesen fizikailag jelölik ki a helyet a memóriában az összes változót élni.
És igen, mi a fordító ezután csinálni, ha ez összeállított mindent,
tudja: "Ó, tettem x címen 10-ig. raktam y címen 14."
Ez majd töltse ki ezeket az értékeket az Ön számára.
Így aztán - ez azután tovább tudja adni ezt, és át-és y-ban is.
Ezek a srácok a címet, de azt is, amikor át azokat a swap funkciót,
Az ilyen típusú információkat, ez int * itt, azt mondja a fordító,
"Oké, mi lesz tolmácsolás ezt a címet, mint a címe, egy egész változó."
Mivel a címben szereplő Int, amely különbözik a címét egy karakter változó
mert egy int vesz fel, egy 32-bites gép vesz fel 4 byte helyet,
mivel a karakter csak akkor vesz fel 1 byte helyet.
Ezért fontos tudni azt is, mi az -, amit él, milyen típusú értéket
él a címen, hogy van telt be
Vagy a címet, hogy te dolgod.
Így, tudod, hogy hány bájt az információk ténylegesen betölteni ki a RAM.
És akkor, igen, ez dereference operátor, mint te is azt kérdezi,
megy, és hozzáfér információk egy adott címet.
Szóval azt mondja, ezzel a változó van, kezeli a tartalma, mint egy cím,
megy, hogy a cím, és húzza ki töltse be a processzor terhelés egy nyilvántartásba
a tényleges értékek vagy a tartalom élnek az adott címre.
Van még kérdés? Ezek jó kérdések.
Ez egy csomó új terminológia is.
Ez is egyfajta funky, látás-és a * különböző helyeken.
>> Rendben van.
Szóval vissza a probléma 33, Fájl I / O
Ez egyike volt azoknak a problémákat, hogy azt hiszem, egy-két dolog történt.
Az egyik, hogy ez egy viszonylag új témát.
Ezt be hamarosan, mielőtt a kvíz,
és akkor azt gondolom, hogy olyan volt, mint egy ilyen szó problémák matematikai
ahol kapsz egy csomó információt, de valójában nem a végén, hogy használja egy csomó belőle.
Az első része ez a probléma írja le, amit a CSV fájl.
Most, a CSV-fájlt, leírás szerint, egy vesszővel elválasztott értékek fájlt.
Az ok, ezek minden érdekes, és az ok, amiért valaha is használni őket,
van, mert az, hogy sokan közületek már valaha ilyesmi Excel?
Ábra legtöbben, valószínűleg vagy fogja használni bizonyos ponton az életedben.
Majd használja valami ilyesmit Excel.
Annak érdekében, hogy az adatokat az Excel táblázatkezelő, vagy nem bármilyen feldolgozás vele,
ha akarod, hogy írjon egy C program vagy Python program, Java program,
kell kezelni a tárolt adatok ott,
az egyik leggyakoribb módja annak, hogy ki van egy CSV fájlba.
És tudod nyitni az Excel és ha megy a "Mentés másként" párbeszédet,
juthatsz el tényleges CSV-fájlt.
>> Handy tudni, hogyan kell kezelni ezeket a dolgokat.
Ez úgy működik, hogy ez hasonló - Úgy értem, ez lényegében utánozza egy táblázatkezelő,
ahol, mint látjuk itt, az igen bal szélső darab,
mindannyian az utolsó nevet.
Tehát Malan, majd Hardison, majd Bowden, MacWilliam, majd a Chan.
Minden az utolsó neveket. És akkor egy vessző választja el az utolsó neveket az első neveket.
David, Nate, Rob, Tommy és Zamyla.
Én mindig keveredik Robby és Tom.
És végül, a harmadik oszlopban az e-mail címeket.
Ha megértjük, hogy, a többi a program meglehetősen egyszerű megvalósítani.
Mit tettünk annak érdekében, hogy utánozni ugyanezt a struktúrát a C program
az általunk használt szerkezet.
Majd kezdj el játszani ezekkel egy kicsit több is.
Láttuk őket, az első kicsit a probléma készlet 3, amikor mi voltunk foglalkozik a szótárakat.
De ez a személyzeti struktúra tárolja a vezetéknév, a keresztnév, és az e-mail.
Csakúgy, mint a CSV fájl tárolására.
Tehát ez éppen konvertáló egyik formátumból a másikba.
Meg kell átalakítani, a jelen esetben, alkalmazott struct egy vonal,
vesszővel elválasztott line, csak úgy.
Van ennek értelme? Ti mind megtette a kvíz,
így képzeljük el, hogy legalább volt egy kis ideje gondolkodni erről.
>> A bérleti funkció, a probléma azt kéri tőlünk, hogy in - we'll nagyítani kell ezen egy kicsit -
hogy a személyzeti struktúrát, a személyzet struct, névvel s,
és mellékeli annak tartalmát a mi staff.csv fájlt.
Kiderül, hogy ez meglehetősen egyszerű használni.
Majd a fajta játék körül ezeket a funkciókat egy kicsit ma.
De ebben az esetben, a fprintf függvény valóban a kulcs.
Tehát fprintf tudunk nyomtatni, mint ti is használnak printf az egész távon.
Tudod printf egy sort egy fájlba.
Tehát ahelyett, hogy csak így a szokásos printf hívás, ahol adja meg a format string
és akkor cserélje ki az összes változó a következő érveket,
A fprintf, az első argumentum helyett a kívánt fájlt írni.
Ha volt, hogy nézd meg ezt a készüléket, például, férfi fprintf,
látjuk a különbséget printf és fprintf.
Majd zoom itt egy kicsit.
Tehát a printf, akkor adja meg a format string, majd az azt követő érvek
az összes változó csere vagy helyettesítése a mi format string.
Mivel a fprintf, az első érv valóban ezt a fájlt * nevezett patak.
>> Mozgó vissza ide, hogy a bérleti,
mi már megvan a file * patak megnyitotta számunkra.
Ez az, amit az első sorban nem, ez megnyitja a staff.csv fájlt,
megnyitja azt append módban, és minden, ami maradt nekünk kell tennie
írja a személyzeti struktúrát a fájl.
És lássuk, nem szeretném használni az iPad?
Fogom használni az iPad. Van void - Tegyük ezt az asztalra, így tudok írni egy kicsit jobban -
semmisnek bérlet és vesz egy érv, a személyzeti struktúrát nevű s.
Megvan a nadrágtartó, megvan a file * nevű fájlt,
Megvan a fopen vonal adott nekünk,
és én csak annyit írj, mint pont, mivel ez már a PEDIA.
És akkor a mi következő sorban, mi megy, hogy egy hívás fprintf
és megyünk át a fájlban, hogy szeretnénk nyomtatni,
majd a format string, ami -
Majd szólok nektek mondani, hogy néz ki.
Mi a helyzet veled, Stella? Tudod, mi az első része a format string néz ki?
[Stella] nem vagyok benne biztos. >> Nyugodtan kérjen Jimmy.
Tudod, Jimmy?
[Jimmy] lenne csak lenni utoljára? Nem tudom. Nem vagyok teljesen biztos benne.
>> Oké. Mi a helyzet, nem valaki kap ez helyes-e a vizsgát?
No. Rendben.
Kiderül, hogy itt minden, amit meg kell tennie, hogy azt akarjuk, minden egyes részét munkatársaink szerkezet
kell kinyomtatni, mint egy string a fájlt.
Mi csak használja a húr helyettesítő karakter három különböző alkalommal, mert van egy utolsó név
követ vessző, akkor a keresztnév, majd vessző,
és végül az e-mail címet az azt követő - amely nem
felszerelés én képernyőn - de ez egy újsor karaktert.
Szóval fogom írni, hogy csak ott lent.
És akkor a következő format string,
már csak a helyettesítéseket, amit eléréséhez használja a dot jelölés
hogy láttunk problémát készlet 3.
Tudjuk használni s.last, s.first és s.email
helyettesítheti e három érték a mi format string.
Hogy volt? Értelme?
Igen? Nem? Lehetséges? Oké.
>> Az utolsó dolog, amit mi után mi már kinyomtatott és azután, hogy megnyitotta a fájlt:
amikor mi már megnyitott egy fájlt, akkor mindig meg kell emlékezni, hogy zárja be azt.
Mert különben mi a végén szivárog a memória,
használ fel fájlleíró.
Szóval, hogy zárja le, hogy melyik funkció mire használjuk? Daniel?
[Daniel] fclose? >> Fclose, pontosan.
Tehát az utolsó része a probléma az volt, hogy megfelelő módon zárja be a fájlt, használja a fclose függvény
ami csak úgy néz ki, mint ezt.
Nem túl őrült.
Cool.
Szóval ez probléma 33 a kvíz.
Lesz határozottan több fájl I / O jön.
Majd csinál egy kicsit több előadás ma, vagy részben ma,
mert ez az, hogy mi fog alkotják a nagy részét a közelgő Pset.
Menjünk el az a teszt ezen a ponton. Igen?
>> [Charlotte]] Miért fclose (file) helyett fclose (staff.csv)?
>> Ah. Mert kiderül, hogy - így az a kérdés, ami egy nagy ember,
van miért, mikor írunk fclose, vagyunk írásban fclose (file) csillag változó
szemben a fájl nevét, staff.csv? Igaz ez? Igen.
Szóval vessünk egy pillantást. Ha vissza szeretne térni a laptop,
és nézzük meg a fclose funkciót.
Tehát a fclose függvény bezárja egy patak, és úgy a mutatót a patak, hogy szeretnénk zárni,
szemben az aktuális fájl nevét, hogy meg akarjuk zárni.
És ez azért van, mert a színfalak mögött, amikor egy hívás fopen,
amikor megnyitod a fájlt, akkor valójában kiosztása memóriát információkat a fájlt.
Szóval fájl pointer, amely információkat a fájlt,
mint például ez a nyitott, mérete, ahol jelenleg a fájlba,
így lehet, hogy az olvasás és írás hívásokat az adott sor a fájlban.
A végén lezáró mutató helyett bezárása a fájl nevét.
>> Igen? [Daniel] Szóval felhasználása érdekében bérlet, mit mondana - hogyan kap a felhasználói?
Vajon fprintf viselkednek getString abban az értelemben, hogy ez akkor csak várni a felhasználói
és kéri, hogy írja ezt - vagy várni, hogy adja ezt a három dolgot?
Vagy ki kell használni valamit végre bérlet?
>> Igen. Szóval nem vagyunk - a kérdés, hogyan jutunk a felhasználói
végrehajtása érdekében bérlet? És mi van itt a hívó a bérleti,
telt el ez a személyzeti struktúra az összes tárolt adatok a struct már.
Szóval fprintf képes csak írni, hogy az adatokat közvetlenül a fájlt.
Nincs felhasználói bemenetet vár.
A felhasználó által már megadott bemeneti gondosan üzembe azt az e személyzeti struktúra.
És a dolgok, persze, akkor sérül, ha ezek közül bármelyik mutatópálcák null,
úgyhogy lapozzunk vissza ide, és nézd meg a struct.
Van karakterlánc utolsó, string 1., string-mailt.
Azt már tudjuk, hogy az összes ilyen igazán, a motorháztető alatt vannak char * változók.
Hogy lehet, hogy nem mutat null.
Ezek lehetnek mutató memóriát a halom,
talán memóriát a verem.
Nem igazán tudom, de ha ezek a mutatók null, vagy érvénytelen,
hogy akkor biztosan lezuhan a bérleti funkciót.
Ez valami, ami kedves volt túlmutat a vizsga.
Mi nem aggódni emiatt.
Remek. Oké. Így mozog a kvíz.
>> Nézzük zárja ezt a fickót, és fogunk nézni Pset 4.
Tehát, ha srácok megnézi az Pset spec, ha egyszer úgy érheti el, cs50.net/quizzes,
fogunk átmenni néhány szakasz problémák ma.
Én lefelé görgetve - szakasz kérdések kezdődik a harmadik oldalon a Pset spec.
És az első rész arra kéri, hogy menjen, és nézni a rövid szóló átirányítása és a csövek.
Melyik volt egyfajta hűvös rövid, megmutatja, néhány új, cool parancssori trükköket, hogy tudod használni.
És aztán van néhány kérdés az Ön számára is.
Ez az első kérdés patakok, amelynek printf írja alapértelmezés szerint,
azt a fajta érintette egy kicsit egy pillanattal ezelőtt.
Ez fprintf, hogy mi csak beszélünk vesz egy file * patak érvelését.
fclose vesz egy file * patak is,
és a visszatérési érték a fopen ad egy file * patak is.
Az ok nem láttunk e előtt, amikor mi már foglalkozott printf
mert printf egy alapértelmezett stream.
És az alapértelmezett patak, amely azt írja
fogod megtudni, hogy rövid.
Tehát mindenképpen vessünk egy pillantást rá.
>> A mai részben fogunk beszélni egy kicsit a GDB,
mivel az jobban ismerik vagytok vele, annál több gyakorlat kapsz vele,
annál jobban képes leszel ténylegesen levadászni bugs saját kódját.
Ez felgyorsítja az eljárást hibakereső fel rettenetesen.
Tehát a printf, minden alkalommal, amikor ezt teszed, újra kell fordítanod a kódot,
le kell futtatni újra, néha meg kell mozgatni a printf hívás körül,
megjegyzésbe kód, csak eltart egy ideig.
Célunk, hogy megpróbálja meggyőzni, hogy a GDB, akkor lényegében
printf semmit bármely pontján a kódot, és soha nem kell fordítanod azt.
Sosem kell kezdeni, és tartsa találgatás, hogy hol printf következő.
Az első dolog az, hogy másolja ezt a sort, és kap a szakasz kódját le az interneten.
Én másolása ezt a kódsort, hogy azt mondja, "wget ​​http://cdn.cs50.net".
Fogom másolni.
Én megyek át a készüléket, kicsinyítés így láthatja, hogy mit csinálok,
beilleszti azt ott, és amikor Enter, ez wget parancs szó egy web kap.
Ez lesz húzza le ezt a fájlt le az internet,
és ez fogja menteni az aktuális könyvtárban.
Most, ha a listán a jelenlegi könyvtár láthatja, hogy kaptam ezt a fájlt section5.zip jogot ott.
Az út, hogy foglalkozzanak ezzel a fickó, hogy csomagolja ki,
amit tehetünk a parancssorban, mint ez.
Section5.zip.
Ez majd csomagolja ki, a mappa létrehozásához nekem,
fújja az összes tartalom, őket ott.
Így most mehetek az én 5. pontban könyvtárba a cd paranccsal.
Töröljük a képernyőt egyértelmű. Így tisztítsd meg a képernyőt.
Most már van egy szép tiszta terminál foglalkozni.
>> Most, ha tudom kilistázni az összes fájlt, hogy látom ebben a könyvtárban,
látod, hogy kaptam négy fájl: buggy1, buggy2, buggy3 és buggy4.
Én is kaptam a megfelelő. C fájlokat.
Nem fogunk nézni a. C fájlokat most.
Ehelyett fogjuk használni őket, amikor nyitni GDB.
Már tartotta őket körül, hogy mi férhet hozzá az aktuális forráskód, amikor mi a GDB,
de a cél ezen részének a szakasz bütykölni körül GDB
és hogyan tudjuk használni, hogy kitaláljuk, mi baj van mind a négy hibás programokat.
Szóval, csak megy körbe a teremben nagyon gyorsan,
és meg fogom kérni, hogy valaki fut az egyik hibás programok
aztán megyünk, mint egy csoport a GDB, és meglátjuk, mit tehetünk, hogy meghatározza ezeket a programokat,
vagy legalább azonosítani, mi baj mindegyikben.
Kezdjük újra itt Daniel. Fogsz futni buggy1? Lássuk, mi történik.
[Daniel] Azt mondja, van egy alkalmazás hiba. >> Igen. Pontosan.
Tehát, ha futok buggy1, kapok egy seg hiba.
Ezen a ponton, nem tudtam menni, és nyissa ki buggy1.c,
próbálja meg kitalálni, mi folyik itt baj,
de az egyik leginkább visszataszító dolog ez a szegmens hiba hiba
az, hogy nem mondja meg, hogy milyen sorban a program dolgok valóban elromlott és eltörte.
Ha ilyen van, hogy nézd meg a kódot
és kitalálni a találgatás, és ellenőrizze, vagy printf, hogy mi folyik itt baj.
Az egyik legmenőbb dolog GDB, hogy ez nagyon, nagyon egyszerű
, hogy kitaláljuk, a vonal, amelyen a program összeomlik.
Ez teljesen érdemes használni, még ha csak ezt.
Szóval, hogy csomagtartó megjelöl GDB, I írja GDB, aztán adja meg az elérési utat a futtatható hogy szeretnék futtatni.
Itt vagyok gépelni gdb ./buggy1.
Hit Enter billentyűt. Ad nekem mindezt szerzői jogi információkat,
és itt lent meglátja ezt a sort, hogy azt mondja: "Reading szimbólumok / home /
jharvard/section5/buggy1. "
És ha minden jól megy, látni fogod, hogy nyomtassa ki egy üzenetet, hogy így néz ki.
Ez lesz olvasható szimbólumok azt fogja mondani: "Olvasom szimbólumok az Ön végrehajtható fájlt"
és akkor lesz ez a "kész" üzenet itt.
Ha látod egy másik variáció e, vagy látod, nem tudta megtalálni a szimbólumok
vagy valami ilyesmi, hogy ez mit jelent az, hogy egyszerűen még nem fordítottuk le futtatható megfelelően.
Amikor összeállítja programokat használatra GDB, akkor kell használni, hogy különleges g zászló,
és hogy kész az alap, ha úgy összeállítani a programokat, csak írja, hogy
vagy hogy hibás, vagy hogy vissza bármely érintett.
De ha összeállítása manuálisan csenget, akkor kell majd menni, és egy olyan, hogy a-g zászló.
>> Ezen a ponton, most, hogy már a GDB azonnali,
ez elég egyszerű, a program futtatásához.
Mi sem írja távon, vagy mi lehet csak írja r.
A GDB parancsok lehet rövidíteni.
Általában csak egy vagy két betű, ami elég szép.
Tehát Saad, ha Type R, és nyomja meg az Enter, mi történik?
[Saad] Van SIGSEGV, szegmentációs hiba, majd mindezt halandzsa.
>> Igen.
Mint látjuk a képernyőn, most, és mint mondta Saad,
amikor azt írja run vagy r, és nyomja meg az Enter billentyűt, akkor még mindig ugyanazt a szeg hibát.
Tehát a GDB nem oldja meg a problémát.
De ez ad némi halandzsa, és kiderül, hogy ez a halandzsa
valójában azt mondja, ha ez történik.
Ahhoz, hogy elemezni ezt egy kicsit, ez az első bit a funkció, amely minden megy rosszul.
Van ez a __ strcmp_sse4_2, és azt mondja, hogy ez történik ebben a fájlban
nevezett sysdeps/i386 mindez újra, egyfajta rendetlenség -, de sor 254.
Ez elég nehéz értelmezni. Általában, ha látsz dolgokat, mint ez,
ez azt jelenti, hogy ez hibás seg valamelyik rendszer könyvtárak.
Szóval valami köze strcmp. Ti már láttuk strcmp előtt.
Nem túl őrült, de ez azt jelenti, hogy a strcmp sérült vagy, hogy van egy probléma strcmp?
Mit gondolsz, Alexander?
[Alexander] Ez - a 254 a vonal? És - nem a bináris, de ez nem a felső,
és akkor ott van egy másik nyelvet az egyes funkciók. Ez 254-ben, hogy a funkció, vagy -?
>> Ez vonal 254. Úgy néz ki, mint ez. S fájl, így ez az assembly kódot valószínűleg.
>> De, azt hiszem, az egyre sürgetőbb dolog, mert már ütött egy szegmens hiba,
és úgy néz ki, hogy jön a strcmp függvény,
ez jelenti tehát, hogy strcmp van törve?
Ez nem kellene, remélhetőleg. Szóval csak azért, mert van egy szegmentációs hiba
az egyik rendszer funkcióit, általában azt jelenti, hogy az imént még nem nevezték megfelelően.
A leggyorsabb dolog, hogy kitaláljuk, mi folyik itt valójában
ha valami őrült, mint ez, amikor megjelenik egy szegmens hiba,
különösen akkor, ha van egy program, ami a több, mint fő,
az, hogy egy backtrace.
Én rövidítéséhez backtrace írásban bt, szemben a teljes backtrace szót.
De Charlotte, mi történik, ha begépeli bt és megüt Belép?
[Charlotte] Ez azt mutatja, nekem két vonal, a vonal a 0 és 1 sor.
>> Igen. Így sor 0 és 1 sor.
Ezek az aktuális verem kereteket, amelyek jelenleg a játékba, amikor a program összeomlott.
Kezdve a legfelső keret, keret 0, és megy a legalsó, amely keret 1.
A legfelső keret a strcmp keretet.
Azt hiszem ezt hasonló probléma, amit éppen csinál a kvíz, a mutatók,
ahol már cserélni stack frame tetején fő verem keret,
és mi volt a változókat, csere volt a tetején a változók fő használta.
Itt a baleset történt, a mi strcmp funkció, amelynek feladata az volt a mi fő funkciója,
és backtrace ad nekünk nem csak a funkciók, amelyek a dolgok nem sikerült,
de ez is azt mondja, ha mindent hívott.
Szóval, ha én lépjünk át egy kicsit jobbra,
láthatjuk, hogy igen, mi volt on line 254 e strcmp-sse4.s fájlt.
De a hívás tett buggy1.c, 6. sor.
Tehát ez azt jelenti, amit tehetünk - az akkor csak megy nézd meg, hogy mi folyik
A buggy1.c, 6. sor.
Ismét van egy pár módja erre. Az egyik az, hogy lépjen ki a GDB
vagy a kód megnyitni egy másik ablakban és a határokon hivatkozást.
Ez, és önmagában is elég hasznos, mert most ha a munkaidő
és van egy szegmens hiba, és a TF ez vajon, ha mindent törés,
tudod csak mondani, hogy "Ó, 6 vezetéken. Nem tudom, mi folyik itt,
de valami 6-os vonal okoz a program megtörni. "
A másik módja, hogy használja ezt a parancsot nevű listát GDB.
Azt is rövidítéséhez azt l.
Tehát ha megüt l, mit kapunk itt?
Kapunk egy csomó furcsa dolog.
Ez a tényleges assembly kódot
hogy van strcmp_sse4_2.
Ez úgy néz ki a fajta funky,
és az ok vagyunk szerzés ez azért van, mert most,
GDB van nekünk keretben 0.
>> Így bármikor nézzük változók bármikor nézzük forráskódot,
keresünk forráskódot, hogy vonatkozik a verem keret vagyunk jelenleg be
Így annak érdekében, hogy bármi értelmes, van, hogy
költöznek egy verem keret, több értelme van.
Ebben az esetben, a legfontosabb verem keret tenné egy kicsit több értelme,
mert ez volt valójában a kódot, amit írt.
Nem a strcmp kódot.
Az, hogy tudja mozgatni a keretek között, ebben az esetben, mert van két,
van 0 és 1,
te, hogy a fel-és le parancsokat.
Ha feljebb egy képkockával,
most én vagyok a fő stack keretet.
Tudom mozgatni lefelé, hogy menjen vissza, ahol voltam,
menj fel újra, menj le megint, és menj fel újra.
Ha valaha is csinálni a programot GDB, akkor kap egy baleset, akkor kap a backtrace,
és látod, hogy ez néhány fájlt nem tudja, mi folyik itt.
Megpróbálja listáját, a kód nem ismerős neked,
vessen egy pillantást a keretek és kitalálni, hogy hol van.
Te valószínűleg rossz stack keretet.
Vagy legalábbis te egy verem keret, amely nem az egyik, hogy akkor tényleg debug.
Most, hogy mi vagyunk a megfelelő stack frame, mi a fő,
most már fel tudjuk használni a list paranccsal hogy kitaláljuk, mi a vonal volt.
És látod, hogy nyomtatott nekünk itt.
De mi is sújtotta felsorolni az összes azonos, és listát ad nekünk ezt a szép nyomtatás
A tényleges forráskódot, ami folyik itt.
>> Különösen azt nézd meg 6-os vonal.
Látjuk, hogy mi folyik itt.
És úgy néz ki, mint mi, hogy egy karakterlánc-összehasonlítás
között a string "CS50 sziklák" és argv [1].
Valami ezt összeomlik.
Szóval Missy, van valami gondolat, hogy mi lehet folyik itt?
[Missy] Nem tudom, miért ez összeomlik. >> Nem tudom, miért ez összeomlik?
Jimmy, minden gondolat?
[Jimmy] Nem vagyok teljesen biztos benne, de az utoljára használt karakterlánc összehasonlítani,
vagy strcmp, mi volt, mint három különböző esetben alatta.
Nem rendelkezik ==, nem hiszem, jobbra az első sorban.
Ehelyett azt szétválaszthatók három, és egy pedig == 0,
egy volt <0, azt hiszem, és egy volt> 0-ra.
Talán valami ilyesmi? >> Igen. Szóval, itt van ez a probléma
A teszünk az összehasonlítás megfelelő?
Stella? Minden gondolat?
[Stella] nem vagyok benne biztos. >> Nem biztos. Daniel? Gondolatok? Oké.
Kiderült, hogy mi folyik itt, amikor már futott a program
és mi van a szegmens hiba, amikor futott a program az első alkalommal, Daniel,
tudtad, hogy ez bármilyen parancssori argumentumok?
[Daniel] No. No. >> Ebben az esetben, mi az értéke argv [1]?
>> Nincs értéke. >> Rendben.
Nos, nincs megfelelő string értéket.
De van valami érték. Mi az az érték, hogy lesz tárolt ott?
>> A szemetet érték? >> Ez vagy egy szemét értéket, vagy ebben az esetben,
a végén a argv tömb mindig megszűnik a null.
Szóval mi tényleg van tárolva van null.
A másik módszer, hogy megoldja ezt, ahelyett, gondoltam át,
hogy nyomtasson ki.
Ez az, ahol azt mondtam, hogy a GDB nagy,
mert akkor ki kell nyomtatni az összes változót, a kívánt értékeket
Ezzel a praktikus dandy-p parancsot.
Szóval, ha a p és aztán írja be az értéket egy változó, vagy a nevét a változó,
mondjuk argc, látom, hogy argc 1 lehet.
Ha azt szeretnénk, hogy kinyomtatni argv [0], én is ezt csak úgy.
És mint láttuk, argv [0] mindig a neve a program,
mindig a neve a végrehajtható.
Itt látható, hogy van a teljes elérési utat.
Azt is ki kell nyomtatni, argv [1], és meglátjuk, mi történik.
>> Itt van ez a fajta misztikus értéket.
Van ez a 0x0.
Emlékszel elején kifejezés, amikor beszéltünk hexadecimális számok?
Vagy, hogy kis kérdés végén az Pset 0 Körülbelül hogyan képviselje 50 hex?
Az, ahogyan írunk hex számok CS, csak, hogy ne tévesszük össze magunkat
A tizedes pontossággal, az mindig előtag őket 0x.
Tehát ez a 0x előtagot mindig csak azt jelenti, értelmezni a következő szám hexadecimális számként,
nem egy string, nem mint decimális szám, és nem, mint egy bináris számot.
Mivel a szám 5-0 egy érvényes szám hexadecimális.
És ez egy számot decimális, 50.
Tehát ez csak hogyan az egyértelműség.
Így 0x0 eszközök hexadecimális 0, ami szintén decimális 0, bináris 0.
Ez csak a 0 értéket.
Kiderül, hogy ez az, amit null is, valójában a memóriában.
Null csak 0-ra.
Itt az elem tárolt argv [1] null.
Így próbálunk összehasonlítani a "CS50 sziklák" string egy null string.
Szóval dereferencing null, próbál hozzáférni dolgokat null,
ezek jellemzően fog okozni valamilyen szegmentációs hiba vagy egyéb rossz dolgok történni.
És kiderül, hogy strcmp nem ellenőrzi, hogy
e vagy sem, amit átadott érték, ami null.
Inkább csak megy előre, megpróbálja ezt a dolgot,
és ha seg hibát, hogy seg hibák, és ez a probléma. El kell menni kijavítani.
Tényleg gyorsan, hogyan lehet megjavítani ezt a problémát? Charlotte?
[Charlotte] megnézheted a ha.
Tehát, ha argv [1] null, == 0, akkor vissza 1, vagy valami [érthetetlen].
>> Igen. Szóval ez egy nagyszerű módja annak, hogy csinálni, mint tudjuk ellenőrizni látni,
az értéket vagyunk arról, hogy bejut strcmp, argv [1], ugye null?
Ha ez üres, akkor elmondhatjuk, oké, abort.
>> A leggyakoribb módja ennek az, hogy az argc értéket.
Láthatjuk itt az elején fő,
kihagytuk, hogy az első teszt, amit általában csinálni, ha az általunk használt parancssori argumentumok,
amely a tesztelni-e vagy sem a mi argc érték, amit várunk.
Ebben az esetben várunk legalább két érvet,
a program neve, plusz egy másik.
Mert mi vagyunk arról, hogy használja a második érvet itt.
Tehát amelyek valamilyen vizsgálat előzetesen, mielőtt a strcmp hívás
hogy a vizsgálatok e vagy sem argv legalább 2, szintén nem ugyanaz a fajta dolog.
Láthatjuk, ha ez működik, a program futtatása újra.
Bármikor indítani a program keretében GDB, ami nagyon szép.
Futtathat, és ha át az érvet, hogy a program,
adja át őket, ha hívja fut, nem akkor, amikor elindítja GDB.
Így tudod tartani hivatkozva a program különböző érveket minden egyes alkalommal.
Úgy fussatok, vagy újra tudok írja r, és lássuk, mi történik, ha írja be a "hello".
Ez mindig megkérdezi, ha szeretné kezdeni elölről.
Általában, ha akarok kezdeni az elejétől újra.
És ezen a ponton, akkor újraindul újra, akkor kiírja
a programot, hogy mi fut, buggy1, az érvelés hello,
és kiírja ezt a szabványt el; azt mondja: "Kapsz egy D" szomorú arc.
De nem seg hibája. Azt mondta, ez a folyamat kilépett rendesen.
Annak érdekében, hogy jól néz ki.
Nincs több szegmens hiba, azt tette az elmúlt,
így néz ki, hogy valóban a szegmens hiba hiba, hogy mi volt egyre.
Sajnos, ez azt mondja, hogy mi vagyunk egyre a D.
>> Mi lehet visszamenni, és nézd meg a kódot, és megnézze, mi folyik ott
hogy kitaláljuk, mi volt - miért azt mondja, hogy mi van a D.
Lássuk, itt volt ez a printf azt mondta, hogy van egy D.
Ha azt írja be listáról, mivel tartod gépelés listában tartja iterációjával végig a program,
így Megmutatom az első néhány sor a program.
Akkor megmutatom a következő néhány sort, és a következő darab, és a következő darab.
És akkor próbálkozom, hogy menjen le.
És most mi lesz, hogy "sor száma 16 a tartományon kívül van."
Mert csak 15 sor.
Ha kapsz, hogy ezt a pontot, és a kíváncsi: "Mit tegyek?" akkor használja a help parancsot.
Használja Segítse majd adja meg a nevét a parancs.
És látod a GDB ad nekünk ezt a fajta dolgot.
Azt mondja: "Ha nincs érv, felsorolja tíz sor után, vagy annak közelében az előző listát.
List - felsorolja a tíz vonal előtt - "
Szóval próbálja lista mínusz.
És hogy felsorolja a 10 sor előző, akkor játszani körül lista egy kicsit.
Meg tudod csinálni lista, lista -, akkor is adni lista több, mint a listán 8,
és akkor sorolja a 10 körüli vonalak sor 8.
És látod, mi folyik itt van egy egyszerű, ha mást.
Ha gépelni CS50 hintáztatni, hogy kiírja: "Kapsz egy A."
Máskülönben kiírja: "Kapsz egy D."
Dőzsölés város. Rendben van. Igen?
>> [Daniel] Szóval, amikor megpróbáltam ezt CS50 sziklák idézőjelek nélkül,
azt mondja: "Kapsz egy D."
Kellett az idézőjeleket, hogy azt a munkát, miért van ez?
>> Igen. Kiderül, hogy ha - ez egy másik jó kis csemege -
amikor futtatja a programot, ha fut, és mi írja be CS50 hintáztatni,
csakúgy, mint Daniel azt mondta ő, és te Enter,
még mindig azt mondja, hogy a D.
És a kérdés az, hogy miért van ez?
És kiderül, hogy mind a terminál és a GDB elemezze ezeket két külön érveket.
Mert ha van egy hely, ami hallgatólagosan
Az első érv véget ért, a következő érv kezdődik.
Az út, hogy összekapcsolják a két, vagy sajnáljuk, egyetlen érv,
az, hogy az idézetek.
Tehát most, ha betette a idézőjelek és futtassa újra, akkor kap egy A.
Szóval összefoglalva, idézőjelek nélkül, CS50 és kőzetek elemzett két külön érveket.
Az idézetek, ez értelmezhető egy érvet összesen.
>> Láthatjuk ezt a töréspontot.
Eddig már fut a program, és ez már működik
amíg vagy nem seg hibákat vagy látogatottság hiba
vagy amíg kilépett, és minden teljesen rendben volt.
Ez nem feltétlenül a leghasznosabb dolog, mert néha
Van egy hiba a programban, de ez nem okoz szegmentációs hiba.
Ez nem okozza a program, hogy hagyja abba, vagy ilyesmi.
Az út, hogy GDB szüneteltetheti a program egy bizonyos ponton
hogy hozzanak egy töréspont.
Akkor sem Ehhez beállításával töréspont a függvény neve
vagy beállíthatja a töréspontot egy adott sor kódot.
Szeretem, hogy hozzanak töréspontok a függvény nevét, mert - könnyen megjegyezhető,
és ha tényleg megy, és változtassa meg a forráskód egy kicsit,
akkor a töréspont valóban marad ugyanazon a helyen belül a kódot.
Mivel ha a sorszámok, és a sorszámok változik
mert hozzáadni vagy törölni egy kódot, akkor a töréspont mind teljesen elcsesztem.
Az egyik leggyakoribb dolog, amit tennie, hogy megadja a töréspontot a fő funkciója.
Gyakran én indul el GDB, én b-típusú main, Enter, és hogy kell állítani egy töréspontot
a fő funkció, amely csak azt mondja: "Szünet a programot, amint elkezdenek megjelenni,"
és így, amikor fut a program, mondjuk CS50 hintáztatni két érvet
és nyomja meg az Enter, ez lesz a fő funkciót, és megáll jobbra az első sorban,
jobbra előtt értékeli az strcmp funkciót.
>> Mivel én megállt, most már lehet kezdeni mucking körül, és látta, hogy mi folyik itt
minden a különböző változók átment a program.
Itt ki is nyomtathatja argc és meglátjuk, mi folyik itt.
Lásd, hogy argc 3, mert ez van 3 különböző értékeket is.
Ez kapta a nevét a program, ez van az első és a második érvet érv.
Mi lehet nyomtatni azokat ki nézi most argv [0], argv [1], és argv [2].
Szóval most is látni, hogy ez miért strcmp hívást fog sikertelen,
mert látod, hogy nem osztott ki a CS50 és a sziklák két külön érveket.
Ezen a ponton, ha egyszer megüt egy töréspontot, akkor is végig a program
soronként, szemben a kezdő a program újra.
Szóval, ha nem akarod, hogy indítsa el a programot újra, és csak tovább innen,
akkor használja a continue parancsot, és továbbra is fog futni a program végéig.
Ahogy tette ide.
Azonban, ha újra a programot, CS50 hintáztatni, eléri a töréspontot újra,
és ebben az időben, ha nem akarom, hogy csak menjen végig a többi program,
Tudom használni a következő parancs, amit én is rövidítéséhez n.
És ez fokozza a programon keresztül sorról sorra.
Szóval, meg lehet nézni a dolgok végre, mint változók változás, ahogy a dolgok frissítve.
Ami nagyon szép.
A másik jó dolog helyett megismételve ugyanazt a parancsot újra és újra és újra,
ha csak Enter - így itt látom, hogy nem írt be semmit -
ha csak Enter, majd ismételje meg az előző parancsot,
vagy az előző GDB parancs, amiket az imént be
Én folyamatosan üti az Enter és akkor folyamatosan fokozza az én kódot sorról sorra.
Azt javasoljuk, hogy a srácok, hogy menjen nézd meg a többi buggy programok is.
Nincs ideje, hogy végig őket ma szakaszban.
A forráskód van, így Ön milyen látni, mi folyik itt
a színfalak mögött, ha kap tényleg elakad,
de legalábbis, csak gyakorolni indítása GDB,
fut a program, amíg tör rád,
szerzés a backtrace, kitalálni, mi a funkciója a baleset volt,
milyen vonal volt kapcsolva, kinyomtatott néhány változó értékeket,
Csak így kedvet kapjanak rá, mert ez valóban segít jövőre.
Ezen a ponton fogjuk lépni az GDB, melyeket nem használ kilép, vagy csak q.
Ha a program közepén futó is, és ez nem kilépett,
hogy mindig kérdezni: "Biztos vagy benne, hogy tényleg ki akar lépni?"
Akkor csak nyomd meg igen.
>> Most megyünk nézd meg a következő probléma van, ami a macska program.
Ha nézed a rövid szóló átirányításával és a csövek, látni fogod, hogy Tommy használja ezt a programot
hogy alapvetően kinyomtatja a kimeneti fájl a képernyőn.
Tehát, ha elfutok macska, ez valójában egy beépített programot a készülék,
és ha van Macs ezt megteheti a Mac is, ha nyit terminál.
És mi - macska, mondjuk, cp.c, és nyomja meg az Entert.
Mi ez a tett, ha lapozzunk fel egy kicsit, és látni, ahol vezette a sort,
vagy ha már futott a cat parancs, szó szerint csak kinyomtatásra tartalmát cp.c a mi képernyőre.
Mi lehet futni újra, és akkor hozott több fájlt együtt.
Szóval meg tudod csinálni macska cp.c, aztán mi is összefűzi a cat.c fájlt,
amely a program vagyunk arról írni,
és ez lesz nyomtatni mindkét vissza a fájlokat vissza a képernyőre.
Tehát ha felfelé egy kicsit, azt látjuk, hogy amikor futott ez a macska cp.c, cat.c,
először azt nyomtatja ki a cp fájlt, majd alatta, hogy kinyomtatják a fájlt cat.c itt lent.
Fogjuk használni ezt, hogy csak kap a lábunk nedves.
Próbálja ki az egyszerű nyomtatást a terminálhoz, lásd hogyan működik.
Ha a srácok nyit a gedit cat.c, Enter,
láthatjuk a programot, hogy mi vagyunk arról írni.
Már benne ezt a szép kazán lemez, így nem kell időt tölteni gépelési minden ki.
Azt is ellenőrizze az átadott argumentumok számával be
Mi nyomtassa ki egy szép használati üzenetet.
>> Ez az a fajta dolog, hogy megint, mint mi már beszélünk,
ez majdnem olyan, mint az izom memória.
Ne feledd, hogy továbbra is ugyanaz a fajta dolog
és mindig kinyomtatása valamiféle hasznos üzenet
hogy az emberek tudják, hogyan kell futtatni a programot.
A macska, ez elég egyszerű, mi csak megyek végig a különböző érveket
amelyeket át a program, és mi fogunk nyomtatni
azok tartalmát ki a képernyőre egyesével.
Annak érdekében, hogy nyomtassa ki a fájlt a képernyőn, fogunk valamit csinálni nagyon hasonló
hogy mit csináltunk a végén a kvíz.
Végén a kvíz, hogy a bérlet program, meg kellett nyitni egy fájlt,
és akkor kellett nyomtatni rajta.
Ebben az esetben fogunk nyitni a fájlt, és fogjuk olvasni helyette.
Akkor fogunk nyomtatni, ahelyett, hogy egy fájlt, fogunk nyomtatni a képernyőn.
Tehát nyomtatás a képernyőre, amit minden történik, mielőtt a printf.
Szóval ez nem túl őrült.
De olvasni egy fájl furcsa.
Majd megy keresztül, hogy egy kicsit egy időben.
Ha mentek vissza, hogy az utolsó probléma a kvíz, a probléma 33,
Az első sorban, hogy mi csinálunk itt, a fájl megnyitásakor, nagyon hasonló ahhoz, amit csináltunk ott.
Szóval Stella, mit jelent, hogy a vonal néz, amikor megnyit egy fájlt?
[Stella] Capital FILE *, file - >> Oké. >> - Egyenlő fopen. >> Aha.
Amely ebben az esetben az? Ez a komment.
>> Ez a komment? argv [i] és az r?
>> Pontosan. Rendben. Szóval Stella Teljesen igaza van.
Ez az, amit a vonal néz ki.
Mi lesz, hogy egy fájlt patak változó tárolja FILE *, így minden sapkák,
FILE, * és a neve ennek a változó lesz a fájl.
Nevezhetjük azt, amit szeretünk. Nevezhetjük azt first_file vagy file_i, amit szeretnénk.
És akkor a fájl neve fogadták el a parancssorban ezt a programot.
Szóval ez tárolja argv [i], majd fogjuk megnyitni ezt a fájlt olvasási módban.
Most, hogy megnyitotta a fájlt, hogy mi az a dolog, amit mindig emlékezni kell csinálni
amikor mi már megnyitotta a fájlt? Csukd be.
Szóval Missy, hogyan zárja be a fájlt?
[Missy] fclose (file) >> fclose (fájl). Pontosan.
Remek. Oké. Ha megnézzük ezt csinálni komment itt,
azt mondja, "Open argv [i], és nyomtassa ki annak tartalmát az stdout-ra."
>> Szabványos ki egy furcsa név. STDOUT csak magunk módján a mondás
szeretnénk kinyomtatni a terminálra, szeretnénk nyomtatni a szabványos kimeneti stream.
Mi lehet valójában hogy eltűnjön ez a megjegyzés itt.
Fogom másolja és illessze be, mivel ez az, amit tettünk.
Ezen a ponton most már olvasni a fájlt apránként.
Már tárgyalt egy pár módja az olvasás fájlokat.
Melyek a kedvenc eddig?
Milyen módokon láttad, vagy nem emlékszik, hogy olvassa el a fájlokat?
[Daniel] fread? >> Fread? Szóval fread egy. Jimmy, tudod, minden más?
[Jimmy] Nem >> Oké. Nem. Charlotte? Alexander? Bármely többiek? Oké.
Így a többi közül fgetc, az egyik, hogy mi fogjuk használni sokat.
Van még fscanf; srácok látni egy mintát itt?
Minden kezdődik f. Semmi köze a fájlt.
Van fread, fgetc, fscanf. Ez az összes a olvasás funkciókat.
Az írásban már fwrite, van fputc helyett fgetc.
Mi is fprintf szeretne láttuk a kvíz.
Mivel ez egy olyan probléma, amely magában foglalja olvasása fájlból,
megyünk, hogy az egyik a három funkciót.
Nem fogunk használni ezeket a funkciókat itt.
Ezek a funkciók mind megtalálhatók a standard I / O könyvtár.
Tehát, ha megnézi a tetején a program,
akkor láthatjuk, hogy mi már tartalmazza a header fájlt a standard I / O könyvtár.
Ha azt akarjuk, hogy kitaláljuk, melyik akarjuk használni,
mi mindig nyissa meg a man oldalakat.
Tehát írja férfi sdtio
és olvassuk el az argumentum bemeneti és kimeneti funkciók C.
És már látjuk oh, nézd. Ez idéző ​​fgetc, ez idéző ​​fputc.
Szóval lehet bontani egy kicsit, és nézd meg, mondjuk, fgetc
és nézd meg a man oldalt.
Láthatjuk, hogy ez együtt jár egy csomó egyéb funkciók:
fgetc, fgets, getc, getchar, kap, ungetc, és a bemeneti karakterek és karakterláncok.
Tehát ez hogyan olvassuk karakterek és karakterláncok származó fájlokat a szabványos bemenetről,
amely lényegében a felhasználó elől.
És ez az, hogy hogyan csináljuk a tényleges C.
Tehát ez nem a getString és GetChar funkciók
hogy mi használt a CS50 könyvtárból.
Fogjuk tenni ezt a problémát egy pár módon
annak érdekében, hogy látható két különböző módon csinálja.
Mind a fread funkció, amely Daniel említett és fgetc jó módon csinálni.
Azt hiszem, fgetc egy kicsit könnyebb, mert csak, mint látod,
egy paramétert, a FILE *, hogy próbálunk olvasni a karaktert,
és a visszatérési értéke egy int.
És ez egy kicsit zavaró, ugye?
>> Mert a sorstól egy karaktert, miért nem ez a visszatérés a char?
Srácok, van valami ötleted, hogy miért ez talán nem térhet vissza a karakter?
[Missy válaszok, érthetetlen] >> Igen. Szóval Missy Teljesen igaza van.
Ha ez ASCII, akkor ez egész lehetne térképezni, hogy a tényleges karakter.
Lehet, hogy egy ASCII karaktert, és ez igaz.
Pontosan mi történik.
Mi használ int egyszerűen azért, mert több bit.
Ez nagyobb, mint a char, amellyel char csak 8 bites, azaz 1 byte a mi 32-bites gépek.
És egy int az összes 4 byte értékű helyet.
És kiderül, hogy az a mód fgetc működik,
ha lapozzunk lefelé a mi szinopszis ezen man oldal egy kicsit,
lapozzunk egészen. Kiderül, hogy használja ezt a speciális értéket nevezzük EOF.
Ez egy különleges állandó, mint a visszatérési értéke a függvény fgetc
amikor bejön a végén a fájlt, vagy ha kap egy hiba.
És kiderül, hogy kell csinálni ezeket összehasonlítások EOF megfelelően,
azt szeretné, hogy az extra mennyiségű információt, hogy van egy int
szemben egy char változó.
Bár fgetc hatékony kapok egy karaktert egy fájlt,
azt szeretnénk, hogy emlékezzen, hogy vissza valamit, ami a típus int az Ön számára.
Igaz, ez viszonylag könnyen kezelhető.
Ez lesz nekünk egy karaktert, így minden, amit meg kell tennie, hogy folyamatosan azt kérdezi a fájlt,
"Add ide a következő karaktert, add nekem a következő karaktert, add nekem a következő karakter"
amíg nem kap a végén a fájl.
És ez majd húzza egy karaktert egy időben a mi fájl,
és akkor mi is csinálni, amit szeretünk vele.
Mi lehet tárolni, akkor add hozzá a húr, akkor nyomtassa ki.
Tegye ezt.
>> Nagyítás vissza, és megy vissza a cat.c program,
ha fogunk használni fgetc,
hogyan lehetne közeledünk a következő kódsort?
Fogunk használni - fread fog tenni valami kicsit más.
És ez időben, mi csak fogja használni fgetc kap egy karaktert egy időben.
A folyamat teljes fájlt, hogy mi van, mit tegyek?
Hány karakter van egy fájlba?
Van egy csomó. Szóval érdemes kap egy
és akkor kap egy másik, és még egy és még egy.
Milyen algoritmus Mit gondolsz, lehet, hogy használni itt?
Milyen típusú -? [Alexander] A for ciklus? >> Pontosan.
Bizonyos típusú hurok.
A for ciklus valójában nagy, ebben az esetben.
És mint te mondtál, úgy hangzik, mint szeretnénk egy hurkot az egész fájlt,
kapok egy karaktert egy időben.
Minden javaslatokat, hogy mi nézne ki?
[Alexander, érthetetlen]
>> Oké, csak mondd meg angolul, mit akarsz csinálni? [Alexander, érthetetlen]
Tehát ebben az esetben, úgy hangzik, mintha mi csak próbál hurok az egész fájlt.
[Alexander] Szóval i > A méret -?
Azt hiszem, a fájl mérete, ugye? A méret - we'll csak írni, mint ez.
Fájl mérete egyelőre, i + +.
Így kiderül, hogy az a mód akkor ezt a fgetc, és ez az új,
az, hogy nincs egyszerű módja, hogy csak kap a fájlméret
ezzel a "sizeof" típusú konstrukció, amit látott.
Amikor használni, hogy fgetc függvényt, mi bevezetésével valamiféle
új, funky szintaxis ezen a hurok, amikor használata helyett csak egy alap számláló
menni karakterenkénti fogunk húzni egy karaktert egy időben,
egy karaktert egy időben, és ahogyan tudjuk, hogy mi vagyunk a végén
Nem, ha mi már számítani bizonyos számú karakter,
de amikor a karakter már húzza ki, hogy a speciális fájl vége karakter.
Így meg tudjuk csinálni ezt - hívom ezt a ch, és fogunk is inicializálása
a mi első hívást kap az első karakter ki a fájlt.
Szóval, ez a rész itt, ez lesz, hogy egy karakter ki a fájl
és tárolja a változó ch.
Fogjuk tartani ezt, amíg nem kap a végén a fájl,
amelyhez nem tesztelésével a karakter nem volt egyenlő, hogy a különleges EOF karaktert.
Aztán ahelyett, hogy ch + +, ami csak növelni az értéket,
így ha azt olvassuk egy A ki a fájlt, a tőke egy, mondjuk,
ch + + b adna nekünk, és akkor lennék c, majd a d.
Ez nyilvánvalóan nem az, amit akarunk. Mit akarunk itt
ebben az utolsó bit azt akarjuk, hogy a következő karaktert a fájlból.
>> Szóval, hogyan lehet megkapjuk a következő karakter a fájlt?
Hogyan jutunk az első karaktert a fájlból?
[Student] fgetfile? >> Fgetc vagy, sajnálom, te teljesen igaza van.
Elírtam ott ahol van. Szóval igen.
Itt ahelyett, hogy ch + +,
mi csak fog hívni fgetc (file) ismét
és tárolja az eredményt a mi ugyanabban ch változó.
[Student kérdés, érthetetlen]
>> Ez az, ahol ezek a FILE * srácok különleges.
Az, ahogyan dolgoznak, ők azok - amikor először nyit -, amikor először győződjön meg, hogy az fopen hívás,
A FILE * hatékonyan szolgál mutatót a fájl elején.
És akkor minden alkalommal, amikor hívják fgetc, mozog egy karakter át a fájlt.
Szóval, amikor hívják ezt, te növelésével a fájl pointer egy karaktert.
És ha fgetc újra, akkor áthelyezi egy másik karakter
és egy másik karaktert, és egy másik karaktert, és egy másik karakter.
[Student kérdés, érthetetlen] >> És ez - igen.
Elég ez a varázslat a motorháztető alatt.
Csak tartsa növelésével keresztül.
Ezen a ponton, akkor tudja, hogy valóban dolgozni egy karaktert.
Szóval hogyan is tudjuk kinyomtatni ezt ki a képernyőn, most?
Tudjuk használni ugyanazt a printf dolog, amit korábban használt.
Ezt mi már felhasználva minden félévben.
Nevezhetjük printf,
és mi lehet átadni a karakter csak úgy.
Egy másik módja, hogy ahelyett printf és miután ezt format string,
mi is alkalmazza az egyéb funkciókat.
Tudjuk használni fputc, amely kiírja a karakter a képernyőn,
kivéve, ha megnézzük fputc - hadd kicsinyítés egy kicsit.
Látjuk, milyen szép ez vesz a karaktert, hogy mi olvasható ki a fgetc,
de akkor meg kell adni, hogy egy patak nyomtatni.
Azt is használja a putchar funkció, ami fel közvetlenül a szabványos ki.
Tehát van egy csomó különböző lehetőségek, hogy tudjuk használni a nyomtatáshoz.
Ők mind a standard I / O könyvtár.
Ha szeretne nyomtatni - így printf alapértelmezés szerint kiírja a speciális szabványos ki-patak,
amely szerint stdout-ra.
Tehát, csak hivatkoznak rá, mint egyfajta E mágia érték stdout itt.
Hoppá. Tegye a pontosvessző kívül.
>> Ez a sok új, funky információ itt.
Sok ez nagyon nyelvi, abban az értelemben, hogy ez kód
hogy meg van írva így csak azért, mert tiszta olvasni, könnyen olvasható.
Sok különböző módon kell csinálni, sok különböző funkciókat lehet használni,
de hajlamosak vagyunk kövesse ugyanezeket a mintákat újra és újra.
Tehát ne lepődj meg, ha látni kódot, mint ez jön fel újra és újra.
Rendben van. Ezen a ponton meg kell törni a nap.
Köszönöm, hogy eljött. Köszönjük, hogy megnézte ha online. És találkozunk jövő héten.
[CS50.TV]