[Powered by Google Translate] [ODDELEK 5: manj udoben]
[Nate Hardison, Harvard University]
[To je CS50.] [CS50.TV]
Torej, dobrodošli nazaj, fantje.
Dobrodošli v 5. poglavju.
Na tej točki, ki so končali kviz 0 in ko je videl, kako ste naredili,
upajmo, da se počutim res dobro, ker sem bil zelo navdušen nad rezultati v tem oddelku.
Za naše spletne gledalcev, imeli smo nekaj vprašanj
O zadnjih dveh problemov na problem set - ali na kvizu, ne.
Tako smo šli čez tiste res hitro, tako da vsi vidijo, kaj se je zgodilo
in kako iti skozi dejanske rešitve in ne samo gledate rešitev sama.
Mi smo šli v zadnjih nekaj težav, zelo hitro, 32 in 33.
Samo, še enkrat, tako da so spletne gledalci videli to.
>> Če obrnete na vašo težavo 32, ki je na strani 13,
13 od 16, 32 Problem je vse o zamenjavah.
To je vse o menjavi dve celi števili.
To je problem, da bomo šli čez nekaj časa na predavanju.
In tukaj, kaj smo spraševali vas je hitro spomin sled.
Za zapolnitev v vrednosti spremenljivk, kot so na kupu
kot je koda gre skozi to swap funkcijo.
Še posebej tisto, kar smo si ogleduje - Jaz bom dal to iPad dol -
zlasti to, kar smo iskali na to vrstica oštevilčena 6 prav tukaj.
Pa tud če je oštevilčena 6 za samo bližino s prejšnjim problema.
Kaj želite storiti, je prikazati ali označujejo stanje pomnilnika
saj je v času, ko bo ta številka vrstice 6,
, ki je učinkovit donos iz naše swap funkcijo tukaj.
Če smo se pomaknite navzdol tukaj, smo videli, da je bilo vse naslove v spominu iz nas.
To je zelo ključnega pomena, se bomo vrnili k njim vsak trenutek.
In potem sem dol na dnu, smo imeli malo pomnilnika diagram, bomo nanašajo.
Pravzaprav sem to naredil na moj iPad.
Torej bom izmenično naprej in nazaj med iPad in to kodo samo za referenco.
>> Začnimo. Najprej naj se osredotoči na prvih nekaj vrstic glavni tukaj.
Če želite začeti, bomo za inicializacijo za 1 x in y za 2.
Torej imamo dve integer spremenljivk, oni tako bo treba dati na kup.
Bomo dal 1 in 2 v njih.
Torej, če sem preklopil na mojem iPad, upajmo, da vidimo -
Apple TV zrcaljenje, in tam gremo. Ok.
Torej, če sem preklopil na mojem iPad,
Želim inicializacijo x in y za 1 do 2.
Mi, ki preprosto tako, da napišete 1 v polju označenem x
in 2 v škatli označeni y. Dokaj preprost.
Torej, zdaj gremo nazaj v laptop, kaj se bo zgodilo naslednje.
Torej, to next line je, če se stvari zapleteno.
Peljemo naslov x in y naslov kot parametrov a in b na swap funkcijo.
Naslov x in y naslovom So stvari, ki jih ne moremo izračunati
brez sklicevanja na te alinejah prav tukaj.
In na srečo, prva dva zaporedna točki nam povejte, kaj so odgovori.
Naslov x v spomin je 10 in naslov y v spomin je 14.
Torej, to so vrednote, ki se opravili v kot in b se uvrščajo v sam vrh naše swap funkcijo.
Torej, še enkrat, prehod nazaj na naši sliki, lahko napišem v 10
in 14 v b.
No, to je točka, kjer bomo nadaljevali z zamenjavo.
Torej lahkota nazaj na laptop spet,
vidimo, da je način zamenjave dela je najprej dereference in trgovina rezultat v tmp.
Torej dereference operater reče: "Hej. Privoščite vsebino spremenljivke kot naslov.
Pojdi na vse, kar je shranjena na tem naslovu, in jo naložite. "
Kaj boste naložili iz spremenljivke se bo shranjeni v našem tmp spremenljivko.
Flipping nazaj na iPad.
Če gremo v reševanje 10, vemo, da je naslov 10 x varible
ker so nam povedali naše točki, da je naslov v pomnilniku x je 10.
Torej, lahko gremo tja, se vrednost tega, kar je 1, kot smo videli na naši iPad,
in obremenitev, ki v tmp.
Še enkrat, to ni končna vsebina.
Gremo na sprehod skozi in bomo prišli do našega končnega stanja programa na koncu.
Toda zdaj imamo shranjeno v vrednosti 1 tmp.
>> In tukaj je hitro vprašanje tukaj.
[Aleksander] Je dereference subjekt - to je samo zvezda tik pred spremenljivko?
>> Da. Torej dereference subjekt, kot smo flip nazaj na našo prenosnik še enkrat,
je ta zvezda tik pred.
V tem smislu je - jo primerjal z multiplikacijskim operaterja
ki zahteva dvoje; dereference upravljavec Predznak.
Tako velja za eno vrednost v primerjavi z binarno operaterja,
kjer se uporabljajo za dve različni vrednosti.
Torej, to je tisto, kar se dogaja v tej vrstici.
Mi naložen vrednost 1 in ga shrani v svojo začasno celo spremenljivko.
V naslednjih vrsticah hranimo vsebino b v -
ali, bolje rečeno, hranimo vsebino, ki se kažejo na b na kraju, kjer se kaže.
Če analiziramo ta od desne proti levi, se bomo, da b dereference,
bomo obravnavali 14, bomo zagrabiti celo število, ki je tam,
in potem smo šli na naslov 10,
in bomo vrgli rezultat naše ciljne datoteke z B, v tem prostoru.
Flipping nazaj k naši iPad, kjer lahko naredimo to malo bolj konkretno,
to bi pomagalo, če sem napisal številke na vse naslove tukaj.
Torej vemo, da je y, smo na naslov 14, x je na naslovu 10.
Ko smo začeli na b, da dereference b, bomo zgrabi vrednost 2.
Mi se bomo, da zgrabite to vrednost, ker je to vrednost, ki ne živi na naslovu 14.
In bomo, da ga v spremenljivko, ki živi na naslovu 10,
, ki je tam, ki ustrezajo našim spremenljivke x.
Tako lahko naredimo malo prepisal tukaj
kjer smo znebiti našega 1 in namesto tega napišite 2.
Torej, vse je lepo in prav na svetu, čeprav smo se prečrtanih x zdaj.
Imamo hranijo stare vrednosti X je v našem tmp spremenljivko.
Torej lahko zaključimo zamenjave z naslednjo vrstico.
Flipping nazaj v naš laptop.
Zdaj ne preostane je, da vsebine iz našega začasno celo spremenljivko
in jih shranimo v spremenljivko, ki živi na naslovu, ki je b holdinga.
Torej bomo učinkovito dereference b, da bi dobili dostop do spremenljivko
da je na naslovu, ki b ima v njej,
in bomo stvari vrednost, ki je v lasti tmp vanjo.
Flipping nazaj na iPad še enkrat.
Ne morem izbrisati to vrednost tukaj, 2,
in namesto tega bomo kopirati 1 pravico vanjo.
Nato naslednjo vrstico, ki izvrši, seveda -
če želimo obrniti nazaj v laptop - je ta točka 6,
kar je točka, na kateri smo želeli, da imamo načrt v celoti izpolnili.
Torej lahkota nazaj na iPad še enkrat, le tako boste lahko videli izpolnjen diagram,
boste videli, da imamo pri 10, 14 in b, 1 v NTU, 2 X, in 1 v y.
Ali obstajajo vprašanja o tem?
Ali je to bolj smiselno, ko je šel skozi to?
Naredite manj smiselna? Upam, da ne. Ok.
>> Kazalci so zelo kočljiva tema.
Eden od fantov, s katerimi delamo ima zelo pogosti pregovor:
"Da bi razumeli namig, morate najprej razumeti namig."
Mislim, da je zelo res. To pa bo trajalo nekaj časa, da se navadiš.
Risba veliko slik, žrebanjem pomnilniških diagrami, kot je ta, so zelo koristno,
in potem greste skozi primer po primer po primer,
da bomo začeli, da bi malo več pameti in malo več občutka in malo več občutka.
Končno en dan, boste imeli vse popolnoma obvlada.
Vsa vprašanja, preden gremo na naslednjo težavo? V redu.
Torej flip nazaj na laptop.
Naslednji problem imamo, je problem številka 33 na datoteko I / O.
Povečajte o tem malo.
Problem 33 - Da?
>> [Daniel] sem moral hitro vprašanje. Ta zvezda, ali zvezdica,
to se imenuje Dereferenciranje ko uporabite zvezdico prej.
Kako se imenuje, ko uporabite znak '& prej?
>> Ta znak je pred-naslov izvajalca.
Torej se pomaknete nazaj.
Ups. Jaz sem v načinu povečave, tako da ne morem pomikanje.
Če pogledamo te kode zelo hitro tukaj,
spet ista stvar dogaja.
Če pogledamo to kodo tukaj, na tej progi, kjer naredimo razpis za zamenjavo,
Ta znak je samo rekel "dobil naslov, na katerem spremenljivke x življenj."
Ko je vaš prevajalnik prevede kodo,
to je dejansko fizično označili iz prostora v pomnilniku za vse vaše spremenljivk, ki živijo.
In kaj lahko naredite, ko prevajalnik je bilo zbrati vse,
ve, "Oh, sem dal na naslovu x 10. sem dal y na naslovu 14".
Nato lahko izpolnite te vrednote za vas.
Tako lahko potem - lahko nato mimo in to smučarsko & Y, kot dobro.
Ti fantje so dobili naslov, pa tudi, ko jih preide v swap funkcijo
ta vrsta informacij, to int * tukaj, pove prevajalnik,
"Ok, gremo se razlagajo ta naslov kot naslov celoštevilski spremenljivki."
Kot naslov notr, ki se razlikuje od naslova za znakovni spremenljivke
ker int zavzema, na 32-bitnih računalnikih, zavzema 4 bajte prostora,
ker je znak samo povzema 1 bajt prostora.
Zato je pomembno, da vedo, kaj je prav - kar živi, ​​kakšno vrednost
živi na naslovu, da imam noter opravljenem
Ali je naslov, ki ste se ukvarjajo s.
Tako boste vedeli, koliko bajtov informacij za dejansko obremenitev iz vašega RAM-a.
In potem, ja, to dereference operater, tako kot vi spraševali,
gre in dostopa do informacij na določenem naslovu.
Torej se pravi, s tem spremenljivko tukaj, zdravljenje vsebino kot naslov,
pojdi na ta naslov in je potegnil ven, vstavite v procesor, obremenitve v register
Dejanske vrednosti ali vsebin, ki živijo na tem naslovu.
Vse več vprašanj? To so dobra vprašanja.
To je veliko novi terminologiji, preveč.
To je tudi neke vrste funky, videnje & * in na različnih mestih.
>> V redu.
Torej nazaj k problemu 33, vložite I / O.
To je bil eden od tistih problemov, ki mislim, da nekaj stvari se je zgodilo.
Ena, je dokaj nova tema.
Predstavljen je bil kmalu pred kviza,
in potem mislim, da je nekako kot eden od tistih besednih problemov v matematiki
če vam veliko informacij, vendar pa dejansko ne končajo ob uporabi tone tega.
Prvi del tega problema, ki opisuje, kaj je datoteka CSV.
Sedaj datoteko CSV, v skladu z opisom, je z vejico ločene vrednosti datoteko.
Razlog za to so sploh zanimiva in razlog, da si jih kdaj uporabiti,
je, ker je, koliko od vas kdaj uporabili stvari, kot so Excel?
Slika je večina od vas, verjetno bo ali uporabljati na neki točki v svojem življenju.
Boste uporabite nekaj podobnega Excelu.
Da bi dobili podatke iz Excelove preglednice, ali pa kakršno koli obdelavo z njo,
če bi želel napisati program C ali Python program, Java program,
ravnati s podatki, ki ste jih shranjene tam,
eden od najbolj pogostih načinov, da ga ven, je v datoteki CSV.
In lahko odprli Excel in ko greš na "Shrani kot" dialog,
lahko dobite od dejanskega datoteko CSV.
>> Handy, da vedo, kako ravnati s temi stvarmi.
Kako deluje, je, da je podobno - mislim, da je v bistvu posnemajo preglednice,
če so, kot vidimo tukaj v zelo levo večino del,
imamo vse priimke.
Torej imamo Malan, nato Hardison, nato pa Bowden MacWilliam in nato Chan.
Vse zadnjih imena. In potem vejica ločuje priimke iz prvih imen.
David, Nate, Rob, Tommy in Zamyla.
Vedno sem pomešajo Robby in Toma.
In potem, na koncu, tretji stolpec je e-poštni naslov.
Ko boste razumeli, da je preostali del programa je dokaj enostaven za uporabo.
Kaj smo storili, da bi posnemajo to isto strukturo v našem programu C
se smo uporabili strukturo.
Bomo začeli igrati z njimi malo več kot dobro.
Smo jih videli prvič malo v nizu problemov 3, ko smo se ukvarjajo s slovarji.
Ampak to osebje struct shrani priimek, prvo ime in e-pošto.
Tako kot naši datoteki CSV je shranjevanje.
Torej, to je samo pretvorbi iz ene oblike v drugo.
Moramo spremeniti, v tem primeru, da uslužbenec struct v vrstici,
ločene z vejico line, kar tako.
Ima to smisel? Fantje so naredile kviz,
Mislim, da ste vsaj imeli nekaj časa za razmislek o tem.
>> V najem funkcijo, problem nas prosi, naj se - Bomo povečaj o tem malo -
sprejmejo v kadrovsko strukturo, osebje, struct, ki je ime,
in dodajte njeno vsebino na našo datoteko staff.csv.
Izkazalo se je, da je to precej enostavno za uporabo.
Bomo nekako igral s temi funkcijami malo več danes.
Toda v tem primeru je funkcija ovrednotenj je res ključnega pomena.
Torej, z ovrednotenj, lahko natisnete, tako kot fantje so bili z uporabo printf ves ta mandat.
Lahko printf vrstica v datoteki.
Torej, namesto da bi samo običajni printf klic, če mu daš format niz
potem pa zamenjal vse spremenljivke z naslednjimi argumenti,
z ovrednotenj, vaš zelo prvi argument je, namesto da bi datoteko, ki jo želite napisati, da.
Če smo bili, da pogled na to napravo, na primer, človek ovrednotenj,
lahko vidimo razliko med printf in ovrednotenj.
Jaz bom povečavo tukaj malo.
Torej, z printf smo ji oblikovnega niza, nato pa nadaljnje trditve
so vse spremenljivke za nadomestitev ali zamenjavo v našem formatu nizu.
Ker je z ovrednotenj, prvi argument je res to sliko * imenujemo tok.
>> Premikanje nazaj sem na naše najem,
smo že dobili naše datoteke * tok odprl za nas.
To je tisto, kar ta prva vrstica pa, da odpre datoteko staff.csv,
jo odpre v načinu dodajanje in vse, kar je ostalo za nas, da to ni
napišite kadrovsko strukturo v spis.
In poglejmo, ali želim uporabiti iPad?
Uporabil bom iPad. Imamo ničnost - Dajmo to na mizi, tako da lahko pišem malo bolje -
nična najem in je potrebno v enem argumentu, kadrovsko strukturo, imenovano s.
Imam svoje naramnice, imamo našo datoteko * imenovano datoteko
imamo fopen linijo, ki nam,
in jaz sem jo napisal kot pike, saj je že v občestva.
In potem na našo naslednjo vrstico, bomo za klic v ovrednotenj
in bomo prehod iz spisa, ki ga želimo tiskati,
in potem naša formatni niz, ki je -
Jaz bom pustil vi povej mi, kako izgleda.
Kaj pa ti, Stella? Ali veste, kaj je prvi del niza formatu izgleda?
[Stella] Nisem prepričan. >> Feel free to ask Jimmy.
Ali veste, Jimmy?
[Jimmy] bi bilo samo se zadnja? Ne vem. Nisem povsem prepričan.
>> Redu. Kaj pa, je kdo dobil to pravilno na izpit?
Ne redu.
Izkazalo se je, da je tukaj vse, kar moramo storiti je, da želimo, da vsak del našega kadrovske strukture
se natisne kot niz v naši datoteki.
Samo uporabite niz Nadomeščanje značaj tri različne čase, ker imamo priimek
sledi vejica, nato ime vejice,
in na koncu je e-poštni naslov, ki je sledil -, ki ni
vgradnjo na mojem zaslonu - vendar je sledil znak za novo vrstico.
Tako bom napisala samo tam.
In potem po našem oblikovnega niza,
smo pravkar imeli zamenjave, ki imamo dostop z uporabo notacije dot
ki smo jih videli v kompletu problema 3.
Mi lahko uporabite s.last, s.first in s.email
nadomestiti v teh treh vrednosti v našem formatu nizu.
In kako je bilo? Smiselno?
Ja? Ne? Predvidoma? Ok.
>> Končni stvar, ki jo naredimo, ko smo natisnejo in po tem, ko smo odprli datoteko:
ko smo odprli datoteko, moramo vedno zapomniti, da jo zaprete.
Ker drugače bomo na koncu pušča spomin,
porabo datoteke deskriptorjev.
Torej, da ga zapre, katero funkcijo bomo uporabili? Daniel?
[Daniel] fclose? >> Fclose, točno.
Torej, zadnji del tega problema je, da ustrezno zapreti datoteko z uporabo fclose funkcijo,
ki samo izgleda tako.
Ne preveč noro.
Kul.
Torej, to je problem 33 na kvizu.
Imeli bomo zagotovo več datoteko I / O prihajajo.
Naredili bomo malo bolj na predavanju danes ali v oddelku danes
ker to je tisto, kar se dogaja, da so večino tega prihajajoči pset.
Gremo naprej s kvizom na tej točki. Ja?
>> [Charlotte]] Zakaj fclose (datoteka) namesto fclose (staff.csv)?
>> Ah. Ker se je izkazalo, da je - tako je vprašanje, ki je eno veliko,
zakaj, ko smo napisali fclose, smo pisno fclose (datoteka) zvezdicami spremenljivko
v nasprotju z imenom datoteke, staff.csv? Je to res? Ja.
Torej poglejmo. Če sem preklopil nazaj na moj laptop,
in poglejmo na fclose funkcijo.
Torej fclose funkcija zapre tok in je potrebno v kazalca do potoka, ki ga želite zapreti,
v nasprotju z dejanskim imenom datoteke, ki jo želimo zapreti.
In to zato, ker v ozadju, ko kličete na fopen,
ko odprete datoteko, ki ste ga dejansko dodelitev pomnilnika za shranjevanje informacij o datoteki.
Torej imate datotečnega kazalca, ki ima informacije o datoteki,
kot je to odprto, njegova velikost, če ste trenutno v spisu,
tako da boste lahko branje in pisanje klicev na tem mestu v datoteki.
Boste na koncu zaprtje kazalec namesto zapiranja ime datoteke.
>> Ja? [Daniel] Torej, da bi uporabili najem, bi rekli - kako to dobiti vnos uporabnika?
Ali ovrednotenj delujejo kot GetString v smislu, da bo to šele čakati uporabniškega vnosa
in vas prosim, da ta tip - ali počakajte, da vnesete te tri stvari?
Ali pa boste morali uporabiti nekaj za izvajanje najem?
>> Ja. Torej nismo -, je bilo vprašanje, kako bomo dobili navodilo za vnos
Za izvajanje najem? In kaj imamo tukaj je klicatelj najemna
mimo tega osebja struct z vsemi podatki, ki so shranjeni v struct že.
Torej ovrednotenj lahko samo napisati, da podatke neposredno v datoteko.
Ni vam treba čakati na vnos uporabnika.
Uporabnik je že glede na vložek z ustrezno ga je dala v tem struct zaposlenih.
In stvari, seveda bi prekinil, če katerikoli od teh kazalcev je bilo null,
tako da se pomaknete nazaj gor in se ozremo na naše struct.
Imamo niz nazadnje, 1. niz, niz sporočilo.
Zdaj vemo, da vse tiste, res pod pokrovom motorja, so spremenljivke char *.
To je lahko ali pa tudi ne kaže na null.
Lahko se kaže v spomin na kup,
Mogoče spomin na kupu.
Ne vem, ampak če kateri od teh kazalcev je nična ali neveljavna,
, da boste zagotovo crash našo najema funkcijo.
To je bilo nekaj, kar je nekako izven obsega izpit.
Mi ne skrbi glede tega.
Čudovito. Ok. Torej oddaljujejo od kviza.
>> Naj blizu tega tipa, in gremo pogledati pset 4.
Torej, če vi pogled na spec pset, ko lahko dostopate do njega, cs50.net/quizzes,
smo šli skozi nekaj problemov rubriki danes.
Jaz sem se pomaknete - Del vprašanj se začne na tretji strani pset spec.
In prvi del vas vpraša, da gredo in pazi na kratko preusmerjanje in cevi.
Ki je nekako kul Skratka, prikazuje nekaj novih, zanimivih trikov ukazne vrstice, ki jih lahko uporabite.
In potem imamo nekaj vprašanj za vas.
To prvo vprašanje o tokovih, ki printf piše privzeto
smo nekako dotaknila le malo pred nekaj trenutki.
Ta ovrednotenj, da sva samo razpravljamo se v toku datoteke * kot svoje trditve.
fclose se v toku datotek *, kot tudi,
in vrnitev vrednost fopen vam tok datoteke * kot dobro.
Razlog nismo videli tisti prej, ko smo obravnavali printf
zato, ker ima privzeto printf tok.
In privzeto tok, ki ga piše
boste izvedeli v kratkem.
Torej, definitivno si na njem.
>> V oddelku današnji bomo govorili malo o gdb,
ker je bolj seznanjeni boste z njim, bolj praksa dobiš z njim,
bolje se boste dejansko lovil hrošče v svojem kodeksu.
To pospeši proces debugging up strašen.
Torej, z uporabo printf, vsakič, ko boste to storili, da boste morali ponovno prevesti kodo,
boste morali teči znova, včasih moraš premakniti printf klic v okolici,
zakomentirajte kodo, potrebujem samo nekaj časa.
Naš cilj je, da preizkusite in vas prepričali, da z gdb, lahko bistveno
printf karkoli kjerkoli v kodi, in nikoli ne bo, da ga prevedem.
Nikoli ne začeti in voditi ugibati, kam printf naprej.
Prva stvar je, da kopirate to vrstico in dobili odsek kode off spletu.
Jaz sem to kopiranje kode, ki pravi, "wget ​​http://cdn.cs50.net".
Grem ga kopirajte.
Jaz grem na mojo napravo, pomanjšate, tako da lahko vidite, kaj počnem,
prilepite tja, in ko sem pritisnite tipko Enter, ta ukaz wget dobesedno spletni dobili.
To se dogaja, da bi se odprl te datoteke off interneta,
in to se dogaja, da ga shranite na trenutni imenik.
Zdaj, če sem seznam moj trenutni imenik, lahko vidite, da sem dobil to datoteko section5.zip prav tam.
Način za reševanje tega tipa je, da jo razširite,
ki jih lahko naredite v ukazni vrstici, tako kot to.
Section5.zip.
To bo razširite ustvarite mapo za mene,
napihne vse vsebine, ki jih v njem.
Torej, zdaj lahko grem v mojo oddelku 5 imenika z ukazom cd.
Počistite zaslon z jasno. Torej, počistite zaslon.
Zdaj imam lepo čisto terminal za obravnavo.
>> Zdaj, če sem seznam vseh datotek, ki sem ga videl v tem imeniku,
boste videli, da imam štiri datoteke: buggy1, buggy2, buggy3 in buggy4.
Prav tako sem dobil njihove ustrezne. C datotek.
Ne bomo, da pogled na. Files C, za zdaj.
Namesto tega se bomo, da jih uporabijo, ko smo odprli GDB.
Imamo jih hranijo okoli, tako da imamo dostop do dejanske kode, ko smo z GDB,
a cilj tega dela odseka je Lemiti okrog z gdb
in videli, kako ga lahko uporabite, da ugotovimo, kaj je narobe z vsakim od teh štirih buggy programov.
Torej smo le, da bo po prostoru zelo hitro,
in jaz bom prosil nekoga, da delo z enim od buggy programov,
in potem bova šla v skupini z gdb, pa bomo videli, kaj lahko storimo, da se določi teh programov,
ali vsaj ugotoviti, kaj je šlo narobe, so v vsaki od njih.
Začnimo tukaj z Danielom. Bo naletite buggy1? Poglejmo, kaj se zgodi.
[Daniel] To pravi, da je uporaba kriv. >> Ja. Točno tako.
Torej, če sem teči buggy1, dobim SEG napako.
Na tej točki, lahko grem in odprli buggy1.c,
poskusite ugotoviti, kaj je šlo narobe,
ampak ena od najbolj gnusen stvari o tem SEG napake napake
je, da ne pove o tem, kaj vrstica programa stvari dejansko šlo narobe in si zlomil.
Si nekako morali pogledati na oznako
in ugotoviti, s ugibati in preverite, ali printf da vidim, kaj je narobe.
Ena izmed najboljših stvari približno gdb je, da je zelo, zelo enostavno
razbrati linijo, na kateri je vaš program zruši.
To je popolnoma vredno, da bi ga uporabili, pa čeprav samo za to.
Torej zagnati GDB, sem tip GDB, potem pa sem ji pot do izvedljive datoteke, ki jih želim teči.
Tukaj sem tipkanje gdb ./buggy1.
Pritisnite tipko Enter. Daje mi vse te informacije o avtorskih pravicah,
in tukaj boste videli to vrstico, ki pravi, "branje simbolov iz / home /
jharvard/section5/buggy1. "
In če bo šlo vse dobro, boste videli, da natisnete sporočilo, da je videti takole.
To bom prebral simbole, bo rekel "Berem simbole iz vašega izvedljivo datoteko,"
in potem bo imela ta "Končano" sporočilo tukaj.
Če vidite kakšno drugo različico tega, ali vidiš, da ni bilo mogoče najti simbolov
ali kaj podobnega, kaj to pomeni, da ste jo pravkar ne pripravljajo svoje izvedljivo pravilno.
Ko smo sestaviti programe za uporabo s gdb, moramo uporabiti, da se posebne g zastavo,
in je naredil, da je privzeto, če zbere svoje programe, tako da z vnosom
ali bi Otroški voziček ali da si opomore, vsak od njih.
Ampak, če ste ročno izdelavo z Jek, potem boste morali iti in tudi, da je g-zastavo.
>> Na tej točki, sedaj imamo GDB poziv,
to je zelo preprost za zagon programa.
Mi lahko vnesete tek, ali mi lahko samo tip r.
Večina ukazov GDB lahko skrajša.
Ponavadi na samo enega ali nekaj pisem, ki je zelo lepo.
Torej Saad, če vtipkate r in pritisnite tipko Enter, kaj se zgodi?
[Saad] Imam SIGSEGV, segmentacija napako in nato vse to klobasanje.
>> Ja.
Kot vidimo na zaslonu takoj, in kot Saad je dejal,
ko smo vnesite tek ali r in pritisnite tipko Enter, smo še vedno zaslužiti isto napako SEG.
Torej z GDB ne reši naš problem.
Ampak to nam daje neko klobasanje in se izkaže, da je to klobasanje
dejansko ne pove, kje se dogaja.
Razčleniti to malo, ta prvi bit je funkcija, pri kateri gre vse narobe.
Tam je to __ strcmp_sse4_2, in to nam pove, da se to dogaja v tej datoteki
imenovano sysdeps/i386, vse to spet neke vrste nered - ampak postavka 254.
To je nekako težko razčleniti. Ponavadi, ko vidiš stvari, kot je ta,
to pomeni, da je seg prelomnicah v eni od sistemskih knjižnic.
Torej, kaj storiti s strcmp. Fantje so videli strcmp prej.
Ne preveč noro, toda ali to pomeni, da je strcmp pokvarjen ali da je problem z strcmp?
Kaj misliš, Alexander?
[Aleksander] Je to - je 254 meja? In - ne binarna, vendar to ni njihova zgornje meje,
in potem je tukaj še en jezik, za vsako funkcijo. Je to 254 v tej funkciji, ali -?
>> To je linija 254. Izgleda, da v tej datoteki. Ih, zato je montaža številka verjetno.
>> Ampak, mislim, bolj pereče je to, ker smo gotten SEG napako
in izgleda, kot da prihaja iz strcmp funkcija,
ali to pomeni, potem je pokvarjen, da strcmp?
To ne bi smel, upam. Torej, samo zato, ker imate Napaka pri razčlenjenosti
v eni od sistemskih funkcij, običajno to pomeni, da ste jo pravkar ne imenuje pravilno.
Najhitrejša stvar, da ugotovimo, kaj se pravzaprav dogaja
ko boste videli nekaj norega, kot je ta, ko vidiš SEG napako
še posebej, če imate program, ki je z več kot samo glavni,
je uporaba povratno sledenje.
Jaz Skrajšati povratno sledenje s pisanjem bt, v nasprotju s celotno besedo povratno sledenje.
Ampak Charlotte, kaj se zgodi, ko vnašate bt in pritisnite tipko Enter?
[Charlotte] To mi pokaže dve liniji, linija 0 in 1 vrstica.
>> Ja. Torej linija 0 in 1 vrstica.
To so dejanski odvodnikom okviri, ki so trenutno v igri, ko je vaš program sesul.
Izhajajoč iz vrhunskega okvirja, okvir 0, in bo v spodnjem največ, kar je okvir 1.
Naša vrhunska okvir je strcmp okvir.
Si lahko zamislite, da je to podobno tega problema smo pravkar počne na kvizu s kazalci,
, kjer smo zamenjali žetonov okvir na vrhu glavnim dimnik,
in smo imeli spremenljivke, ki se je s pomočjo zamenjave na vrhu spremenljivk, ki je bila glavna uporabljajo.
Tu naša nesreča se je zgodilo v naši strcmp funkcija, ki je bila sklicana za naše delovanje,
in 'backtrace nam daje ne samo funkcije, ki stvari ni uspela,
ampak to je tudi nam pove, kje vse je klical.
Torej, če sem se pomaknite čez Malo bolj na desno,
lahko vidimo, da ja, bili smo na liniji 254 tega strcmp-sse4.s datoteke.
Vendar je bil poziv na buggy1.c, linija 6.
Torej to pomeni, da ne moremo storiti - je lahko greva pogledat in videl, kaj se dogaja
V buggy1.c, linija 6.
Again, obstaja nekaj načinov, da to storijo. Ena je, da izhod iz gdb
ali ima vaša koda odprla v novem oknu in navzkrižno sklicevanje.
To pa samo po sebi, je zelo priročno, saj zdaj, če ste na uradnih ur
in imaš SEG napako in vaše TF se je spraševal, kje vse je bil zlom,
lahko samo rečem: "Oh, linija 6. Ne vem, kaj se dogaja,
ampak nekaj linije 6, ki povzroča moj program, da bi prekinil. "
Drugi način za to je, da lahko uporabite ta ukaz, imenovano seznam gdb.
Prav tako ga lahko skrči v l.
Torej, če smo zadeti l, na kaj smo prišli sem?
Smo dobili cel kup čudnih stvari.
To je dejansko montažo koda
, ki je v strcmp_sse4_2.
To zgleda funky,
in zato smo dobili to zato, ker prav zdaj,
GDB nam je v okvirju 0.
>> Torej, kadarkoli pogledamo spremenljivk, kadar koli se ozremo na izvorno kodo,
smo iskali na kodi, ki se nanaša na dimnik okvirja smo trenutno noter
Torej, da bi dobili ničesar pomembnega, moramo
premakniti na kup okvir, ki omogoča bolj smiselno.
V tem primeru bi bila glavni okvir sklad bi malo bolj smiselno,
ker je to dejansko kodo, ki smo pisali.
Ne strcmp kodo.
Tako boste lahko premikate med okvirji, v tem primeru, saj imamo 2,
imamo 0 in 1,
vam, da s gor in dol ukazov.
Če sem premakniti za eno okvir,
Zdaj sem v glavnem okvirju dimnika.
Ne morem premakniti navzdol, da gredo tja, kjer sem bil,
šel spet nazaj dol in se znova dvignila.
Če boste kdaj narediti svoj program v gdb, boste dobili crash, boste dobili povratno sledenje,
in boste videli, da je v neki datoteki, ki ne veste, kaj se dogaja.
Poiskusite seznam koda ne izgleda poznano,
da pogled na vaše okvirjev in ugotoviti, kje se nahajate.
Verjetno si na napačnem okviru dimnika.
Ali pa vsaj, da si v okviru dimnik, ki ni tista, ki lahko zares debug.
Zdaj, ko smo v okviru ustreznega dimnika, smo v glavnem
Zdaj lahko uporabite seznam ukaz, da ugotovimo, kaj je bila črta.
In lahko vidite, jo natisne za nas tukaj.
Lahko pa smo zadeli seznam vseh enak, in seznam daje nam to lepo izpisa
dejanske izvorne kode, ki se dogaja v tukaj.
>> Še posebej, smo lahko ogledate na liniji 6.
Vidimo lahko, kaj se dogaja tukaj.
In izgleda, da delamo niz primerjavo
Med niz "CS50 skale" in argv [1].
Nekaj ​​o tem je bil treskav.
Torej, Missy, imate kakšne misli o tem, kaj bi se tukaj dogaja?
[Missy] Ne vem, zakaj se treskav. >> Ne vem, zakaj se treskav?
Jimmy, vse misli?
[Jimmy] Nisem povsem prepričan, ampak nazadnje, ko smo uporabili niz primerjavo,
ali strcmp smo imeli kot treh primerih v skladu s tem.
Nismo imeli ==, jaz ne mislim, prav v tej prvi vrstici.
Namesto tega je bil razdeljen na tri, ena pa je bila == 0,
eden je bil <0, mislim, ena pa je bila> 0.
Mogoče kaj takega? >> Ja. Torej je to vprašanje
z dne delamo primerjave pravilno?
Stella? Vsak misli?
[Stella] Nisem prepričan. >> Ne vem. Daniel? Misli? Ok.
Izkazalo se je, kaj se dogaja tukaj, ko smo zagnali program,
in imamo SEG napako, ko ste zagnali program za prvič, Daniel
si ji vse argumente v ukazni vrstici?
[Daniel] No No >> V tem primeru, kaj je vrednost argv [1]?
>> Ni vrednota. >> Desno.
No, ni primerno vrednost niza.
Vendar pa obstaja nekaj vrednosti. Kakšna je vrednost, ki se shrani v tam?
>> Smeti vrednost? >> To je bodisi smeti vrednost ali, v tem primeru,
konec niza argv se vedno zaključi z nično.
Torej, kaj se je dejansko dobil shranjene tam je nična.
Drugi način za reševanje tega, namesto da bi razmišljal prek
je, da ga poskusite tiskanje.
To je, če sem rekel, da je uporaba gdb je super,
saj si lahko natisnete vse spremenljivke, vse vrednosti, ki jih želite
uporabo te priročne-Dandy p ukaz.
Torej, če sem tip P in potem vnesite vrednost spremenljivke ali ime spremenljivke,
pravijo, argc, vidim, da argc je 1.
Če hočem izpisati argv [0], lahko to storite kar tako.
In kot smo videli, argv [0], je vedno ime vašega programa,
Vedno je ime izvršljiv.
Tukaj lahko vidite, da je dobil polno ime poti.
Lahko tudi natisnete argv [1], in videli, kaj se bo zgodilo.
>> Tu imamo takšno mistične vrednosti.
Imamo to 0x0.
Ne pozabite na začetku mandata, ko smo govorili o šestnajstiških številk?
Ali pa, da malo vprašanje na koncu pset 0 o tem, kako se predstavljajo 50 v hex?
Pot smo napisali hex številke v CS, samo, da ne bomo zamenjali
z decimalno številko, je, da smo jih vedno predpono 0x.
Torej, to 0X vedno pomeni le razlago naslednjo številko kot šestnajstiško število,
ne kot niz in ne kot decimalno število, ne pa kot binarno število.
Ker je število 5-0 je veljavna številka v šestnajstiško.
In to je število v decimalni, 50.
Torej, to je samo, kako bomo nerazdvoumljajo.
Torej 0x0 pomeni šestnajstiško 0, kar je tudi decimalno 0, 0 binarni.
To je samo vrednost 0.
Izkazalo se je, da je to tisto, kar je nična, pravzaprav v spominu.
Nič je samo 0.
Tu element shranjen v argv [1], je nična.
Torej bomo poskušali primerjati naše "CS50 kamenje" niz v ničelni niz.
Torej Dereferenciranje nično, poskuša dostopati do stvari null,
ki se običajno dogaja, da povzročajo neke vrste napake segmentacije ali drugih slabih stvari dogajajo.
In izkazalo se je, da strcmp ne preverite
ali ste opravili v vrednosti, ki je nična.
Nasprotno, gre samo naprej, poskuša narediti svoje stvari,
in če seg napake, je seg napake, in to je tvoj problem. Moraš iti popraviti.
Res hitro, kako bi lahko rešili ta problem? Charlotte?
[Charlotte] lahko preverite, če uporabljate.
Torej, če argv [1], null, == 0, vrne 1, ali kaj [nerazumljivo].
>> Ja. Torej, to je en odličen način, da to storite, saj bomo lahko preverite,
Vrednost bomo kmalu preide v strcmp, argv [1], je null?
Če je nična, potem lahko rečemo, ok, prekine.
>> Pogostejši način za to je, da uporabite argc vrednost.
Ogledate si lahko tukaj na začetku main,
Izpustili smo, da je prvi poskus, ki smo ponavadi storite, ko bomo uporabili argumente v ukazni vrstici,
ki je preizkusiti, ali ni naša argc vrednost je tisto, kar smo pričakovali.
V tem primeru smo pričakovali vsaj dva argumenta,
ime programa in en drugega.
Ker smo tik pred uporabo drugega argumenta tukaj.
Torej imajo neke vrste preizkus vnaprej, pred našim klicem strcmp
da se preizkusi, ali je argv najmanj 2, bi tudi storijo enako stvari.
Vidimo lahko, če to deluje tako, da zaženete program.
Vedno lahko ponovno zagnati program v gdb, ki je res lepo.
Lahko bežiš, in ko se boste peljali v argumentih v vaš program,
jih prenese v trenutku, ko zaženete klic, ne, ko škorenj ki gre gor GDB.
Na ta način lahko obdržite sklicuje svoj program z različnimi argumenti vsakič.
Torej teči, ali še lahko vpišem r, in poglejmo, kaj se zgodi, če vpišemo "zdravo".
To bo vedno vas prosim, če želite, da ga začeti od začetka znova.
Ponavadi, če res želite, da ga začeti od začetka znova.
In na tej točki se znova zažene znova, se natisne
Program, ki ga uporabljate, buggy1, z argumentom, zdravo,
in natisne te standardne ven, pravi: "Dobiš D," žalostno podobo.
Toda nismo seg napake. To je dejal, da je proces izstopilo običajno.
Tako, da izgleda precej dobro.
Nič več seg napake, smo pa preteklost,
tako da izgleda kot da je res kriv segment napako, da smo dobili.
Žal pa nam pove, da smo dobili D.
>> Lahko gremo nazaj in pogledate kodo in videli, kaj se dogaja tam
da ugotovimo, kaj je - zakaj je nam povedali, da imamo D.
Pa poglejmo, tu je ta printf rekel, da imaš D.
Če vpišemo seznama, kot ste obdržati tipkanje seznam, ohranja ponavljanjem navzdol po programu,
tako da bomo vam pokaže prvih nekaj vrstic vašega programa.
Potem pa je pokazal v naslednjih nekaj vrstic in naslednji in naslednji kos kos.
In da bomo trudili, da gredo dol.
In sedaj bomo prišli do "linijo številka 16 je izven območja."
Ker ima le 15 vrstic.
Če prideš do te točke in da je vaš sprašujete: "Kaj naj storim?" lahko uporabite ukaz za pomoč.
Uporabite pomoč, nato pa ji je ime ukaza.
In vidite GDB nam vse te vrste stvari.
Pravi: "brez argumentov, navaja 10 več linij po ali okoli prejšnji seznam.
Seznam - seznam 10 vrstic, preden - "
Torej poskusite s seznama minus.
In da našteva 10 vrstic prejšnji, si lahko igral s seznamom malo.
To lahko naredite seznam, seznam opravil -, lahko celo dal seznam številke, kot je seznam 8,
in da bomo seznam 10 vrstic okoli 8. vrstici.
In si lahko ogledate, kaj se dogaja tu imaš preprost, če drugje.
Če vnesete v CS50 skalah, da natisne "Dobiš A."
V nasprotnem primeru se izpiše "Dobiš D."
Škoda mesto. V redu. Ja?
>> [Daniel] Torej, ko sem se potrudil početje CS50 kamenje brez narekovajev,
pravi: "Dobiš D."
Potreboval sem narekovaje, da dobim delo, zakaj je to?
>> Ja. Izkazalo se je, da ko - to je še ena zabavna malo Malčice -
Ko zaženete program, če ga vodijo in vpišemo v CS50 skale,
tako kot je rekel Daniel je naredil, in ga pritisnite tipko Enter,
je še vedno pravi, da smo dobili D.
In vprašanje je, zakaj je to?
In izkazalo se je, da sta naš terminal in GDB razčleniti to v obliki dveh ločenih argumentov.
Ker, ko obstaja prostor, ki je pomenila, kot
Prvi argument je končalo, je naslednji argument se bo kmalu začela.
Pot do kombinirate na dva dela, ali pa nam v eno trditev,
je uporaba narekovajev.
Torej, zdaj, če bi ga dal v narekovaje in ga ponovno zagnati, dobimo A.
Torej, samo da povzamem, so brez narekovajev, CS50 in čeri razčleniti kot dve ločeni argumentov.
Z narekovaji, to je razčlenjen kot en argument v celoti.
>> To lahko vidimo z mejnimi vrednostmi.
Do sedaj smo bili teče naš program, in to je bilo tekmovanje v teku
dokler se bodisi seg napak ali Zadetkov napako
ali, dokler se ne prekine in vse je bilo povsem v redu.
To ni nujno najbolj koristna stvar, ker včasih
imate napako v programu, vendar je ne povzroča segmentacijo napako.
To ne povzroča vaš program ustaviti ali kaj podobnega.
Način, da dobite GDB, da prekinete vaš program na določenem mestu
je določiti odmerka.
Lahko naredite tako, da nastavite prekinitveno točko na ime funkcije
ali si lahko nastavite prekinitveno točko na nekem kode.
Všeč mi je, da nastavite prekinitvene točke na funkcijo imen, ker - težko zapomniti,
in če si dejansko šel in ga spremenite izvorno kodo gor malo,
potem bo vaš Ustavljanje dejansko bivanje na istem mestu v kodi.
Ker če uporabljate številke vrstic in številke vrstic sprememb
ker si dodati ali izbrisati nekaj kode, potem so vaši Prelomne točke vsi popolnoma zajebali.
Eden od najpogostejših stvari, ki sem storiti, je nastaviti odmerka za glavno funkcijo.
Pogosto bom zagnati GDB, bom tipa B Main, pritisnite tipko Enter, in da bomo nastavite prekinitveno točko
o glavnih funkcij, ki samo pravi, "zaustavite program takoj, ko se začnejo izvajati,"
in na ta način, ko sem teči moj program z, recimo, CS50 skale dva argumenta
in pritisnite tipko Enter, da postane na glavno funkcijo in se ne ustavi takoj na zelo prvi vrstici,
tik preden se ocenjuje strcmp funkcijo.
>> Ker sem jaz zaustavljena, zdaj lahko začnem mucking okoli in videli, kaj se dogaja
z vsemi različnimi spremenljivkami, ki pride v mojem programu.
Tu lahko natisnete argc in videli, kaj se dogaja.
Glej, da argc je 3, saj ima 3 različne vrednosti v njem.
To je dobil ime programa, to je dobil prvi argument in drugega argumenta.
Mi lahko natisnete tistih, ki jih je videti na argv [0], argv [1], in argv [2].
Sedaj lahko vidite tudi, zakaj ta klic strcmp se dogaja, da ne,
saj vidiš, da se je to razdelilo CS50 in kamenje v dveh ločenih argumentov.
Na tej točki, ko ste zadeli odmerka, lahko nadaljujete s korakom po programu
Po vrsticah, v primerjavi z začetkom vaš program znova.
Torej, če ne želite, da začnete program znova in samo nadaljujemo od tukaj,
lahko uporabite ukaz še naprej in še bo potekal program do konca.
Tako kot je to storila tukaj.
Vendar, če sem ponovno zagnati program, CS50 kamenje, se dotakne mojega odmerka enkrat,
in tokrat, če ne želim, da pojdi vso pot skozi preostanek programa,
Lahko uporabite naslednji ukaz, ki je prav tako skrajšujejo s n.
In ta korak v celotnem programskem po vrsticah.
Torej si lahko ogledate v stvari, izvajajo, kot spremenljivke sprememb, saj se posodablja stvari.
Kar je zelo lepo.
Druga stvar je kul, ne pa ponavljanje istega ukaz znova in znova in znova,
Če pritisnite tipko Enter - tako da tukaj vidite, nisem vnesli v nič -
če sem pritisnite tipko Enter, se bo ponovil prejšnji ukaz,
ali prejšnji ukaz GDB, da sem dal noter
Lahko da pritisnemo Enter in se bomo še naprej okrepiti z mojo kodo po vrsticah.
Spodbudil bi vi iti preverite druge programe buggy kot dobro.
Nimamo časa, da bi se skozi vse od njih danes v oddelku.
Izvorna koda je tam, tako da lahko nekako videli, kaj se dogaja
V zakulisju, če se res zaljubljen,
ampak vsaj, vadili le škorenj ki gre gor GDB,
vodenje programa, dokler se ne zlomi na vas,
dobili povratno sledenje, poskušal ugotoviti, kaj deluje crash bil,
kaj postavka je bila na, tiskanje na nekatere spremenljive vrednosti,
samo zato, da boste dobili občutek za to, ker bo to res pomagalo greš naprej.
Na tej točki se bomo nehal iz gdb, ki vam z uporabo prenehati ali pa q.
Če je vaš program sredi teče vedno, in je ni zapustil,
da bo vedno vprašajte: "Ali ste prepričani, da res želite končati?"
Lahko samo zadeti ja.
>> Zdaj bomo pogled na naslednjo težavo imamo, ki je mačka program.
Če si gledal na kratko preusmerjanje in cevi, boste videli, da je Tommy uporablja ta program
da v bistvu natisne vse izhod v datoteko na zaslon.
Torej, če sem teči mačko, to je dejansko vgrajen program za naprave,
in če imate Mac, lahko to na vašem Mac Tudi, če ste odprli terminal.
In mi - mačka, recimo, cp.c in pritisnite tipko Enter.
Kaj je to storil, če se pomaknite malo nazaj in videli, kje smo zagnali linijo,
ali kadar smo naleteli ukaza cat, je dobesedno samo izpisal vsebino cp.c naše zaslonu.
Lahko ga ponovno zaženete in jo lahko dal v več datotek skupaj.
Torej, lahko to storite mačka cp.c, in potem bomo lahko tudi spenjanje cat.c datoteko
katere je program bomo o tem pisati,
in ti jo natisne obe datoteki na hrbtni strani naše zaslonu.
Torej, če se pomaknete navzgor malo vidimo, da ko sva tekla ta mačka cp.c, cat.c,
Sprva je natisnjen CP datoteko, in nato pod njo, je natisnjen ven cat.c datoteko prav tukaj.
Bomo uporabite to le dobili naše noge mokre.
Poigrajte se z enostavnim tiskanje na terminalu, da vidite, kako deluje.
Če vi odprli z gedit cat.c, pritisnite tipko Enter,
si lahko ogledate program, da smo o tem pisati.
Vključili smo to lepo kotla ploščo, tako da nam ni treba izgubljati časa tipkanje vse to.
Prav tako preverite število argumentov opravili noter
Mi natisnete lepo navada sporočilo.
>> To je reč, da spet, kot smo se pogovarjali o tem,
to je skoraj tako, kot podzavestno.
Zapomnite si, da delaš isto vrsto stvari
in vedno tiskanje neke vrste koristnih sporočilo
tako da ljudje vedo, kako teči vaš program.
Z mačko, to je zelo preprost, da smo le, da bo treba iti skozi vse različne argumente
, ki so bili sprejeti v naš program, in gremo za tiskanje
poudarja, da je njihova vsebina na zaslonu 1 naenkrat.
Za tiskanje datotek ven na zaslonu, da bomo narediti nekaj zelo podobnega
s tem, kar smo naredili na koncu kviza.
Na koncu kviza, ki zaposlujejo programa, smo morali odpreti datoteko,
in potem smo morali tiskati z njim.
V tem primeru, bomo odprli datoteko, in gremo brati iz nje namesto tega.
Potem bomo natisniti, namesto v datoteko, bomo za tiskanje na zaslonu.
Torej, tiskanje na zaslonu, ki ste jih opravili vse prej z printf.
Tako, da to ni preveč nor.
Toda branje datoteke je čudno.
Šli bomo skozi to malo naenkrat.
Če greste nazaj na ta zadnji problem na kvizu, problemski 33,
v prvi vrstici, da bomo na tem mestu, da odprete datoteko, je zelo podobno temu, kar smo tam.
Torej, Stella, kaj to linijo izgledal, ko smo odprli datoteko?
[Stella] Capital FILE * datoteka - >> redu. >> - Je enako fopen. >> Ja.
Ki je v tem primeru? To je v komentarju.
>> To je v komentarju? argv [i] in r?
>> Točno tako. Tako. Torej, Stella je popolnoma v redu.
To je tisto, kar je linija izgleda.
Bomo dobili spremenljivko datoteko tok, ga shranite v datoteko *, tako da so vsi pokrovčki,
Slika, *, in ime te spremenljivke bo datoteka.
Lahko bi ga pokličete, kar smo želeli. Temu bi lahko rekli, da first_file ali file_i, kar bi radi.
In potem je ime datoteke, sprejet v ukazni vrstici na ta program.
Torej je shranjena v argv [i,] in potem bomo odprli to datoteko v načinu branja.
Zdaj, ko smo odprli datoteko, v čem je stvar, ki jo moramo vedno pozabite narediti
ko smo odprli datoteko? Zapri.
Torej, Missy, kako bomo zaprli datoteko?
[Missy] fclose (datoteka) >> fclose (datoteka). Točno tako.
Čudovito. Ok. Če pogledamo to storiti komentar tukaj,
pravi: "Odpri argv [i] in tiskanje vsebine na stdout."
>> Standardna ven je čudno ime. Stdout je samo naš način rek
želimo, da ga natisnete na terminalu, želimo, da ga natisnete na standardni izhodni tok.
Mi lahko dejansko znebiti tega komentarja tukaj.
Bom ga kopirajte in prilepite, ker to je tisto, kar smo storili.
Na tej točki moramo zdaj, preberite datoteko korak za korakom.
Smo razpravljali nekaj načinov za branje datotek.
Katere so vaše priljubljene tako daleč?
Kateri način ste videli, ali se spomnite, da se glasi datoteke?
[Daniel] fread? >> Fread? Torej fread je ena. Jimmy, veš vse druge?
[Jimmy] No >> redu. Ne. Charlotte? Alexander? Vsi ostali? Ok.
Torej, ostale pa so fgetc, je tisti, ki bomo uporabili veliko.
Tam je tudi fscanf, vi vidite vzorec tukaj?
Vsi so začeli s f. Kaj storiti z datoteko.
Tam je fread, fgetc, fscanf. To so vse funkcije branja.
Za pisanje smo fwrite, imamo fputc namesto fgetc.
Imamo tudi ovrednotenj, kot smo videli na kvizu.
Ker je to težava, ki vključuje branje iz datoteke,
bomo z enim od teh treh nalog.
Ne bomo Te funkcije tukaj.
Te funkcije so vsi na voljo v standardni knjižnici I / O.
Torej, če pogledaš na vrhu tega programa,
Kot lahko vidite, smo že vključeni v glavi datoteko za standardne knjižnice I / O.
Če želimo ugotoviti, katero želimo uporabiti,
vedno lahko odprli man strani.
Tako smo lahko vnesete človek izravnalnik stdio
in preberete vse o izravnalnik stdio vhodnih in izhodnih funkcij v C.
In smo lahko že videli Oh, poglej. To je omeniti fgetc pa je omeniti fputc.
Tako boste lahko v globino malo in poglej, recimo, fgetc
in pogled na njegovo delovno strani.
Vidite lahko, da gre skupaj z cel kup drugih funkcij:
fgetc, fgets, getc, getchar, gets, ungetc in njegov vnos znakov in godala.
Torej, to je, kako beremo v črkah in godala iz datotek iz standardnega vhoda,
ki je v bistvu od uporabnika.
In to je, kako to počnemo v dejanskem C.
Torej, to se ne uporablja GetString in GetChar funkcije
ki smo ga uporabili pri CS50 knjižnice.
Mi smo naredili te težave v nekaj načinov
tako da boste videli dva različna načine za njihovo početje.
Tako fread funkcija, ki Daniel omenil in fgetc dobri poti, da to storite.
Mislim, da fgetc je malo lažje, ker je le, kot vidite,
en argument, FILE * da poskušamo prebrati znak iz,
in njene vrnitve vrednost int.
In to je malo zmedeno, kajne?
>> Ker smo dobili znak, zakaj ne tak donos char?
Vi imate ideje o tem, zakaj to ni mogoče vrniti char?
[Missy odgovori, nerazumljiv] >> Ja. Torej, Missy je popolnoma v redu.
Če je ASCII, potem bi to celo treba razporediti na dejansko char.
Lahko bi bila ASCII, in to je prav.
To je točno to, kar se dogaja.
Mi smo z uporabo int preprosto zato, ker ima več bitov.
To je večje kot znak, naš znak ima samo 8 bitov, da je 1 bajt na naše 32-bitne računalnike.
In int je vredno vsega 4 bajti "prostora.
In izkazalo se je, da je način fgetc dela,
če se pomaknite navzdol na naši strnjen v tem človekom strani malo,
pomaknite vso pot navzdol. Izkazalo se je, da jih uporabljajo te posebne vrednosti, imenovano EOF.
To je posebna konstantne povratno vrednost fgetc funkcije
ko ste zadeli konec datoteke, ali če se pojavi napaka.
In izkazalo se je, da se teh primerjav z EOF pravilno,
želite imeti, da ekstra količino informacij, ki jih imate v notr
v nasprotju z uporabo char spremenljivko.
Čeprav fgetc dejansko dobili znak iz datoteke,
hočeš, da se spomnimo, da se vrača nekaj, kar je int tip za vas.
To je dejal, da je dokaj enostaven za uporabo.
To se dogaja, da nam značaj, tako da je vse, kar moramo storiti je, da asking datoteko
"Daj mi naslednji znak, da mi naslednji znak, da mi naslednji znak"
dokler ne pridemo do konca datoteke.
In to bo potegnite v en znak naenkrat iz naše dokumentacije,
in potem bomo lahko delali, kar smo želeli z njim.
Lahko ga shranite, ga lahko dodate v nizu, lahko ga natisnete.
Ali nič od tega.
>> Povečevanje nazaj in šel nazaj na našo cat.c programa,
če hočemo uporabljati fgetc,
kako bi lahko začeli reševati ta naslednjo vrstico kode?
Bomo za uporabo - fread bo naredil nekaj malo drugačnega.
In tokrat smo le, da bo uporabila fgetc, da bi dobili en znak naenkrat.
Za obdelavo celotno sliko, kaj bi mi morali narediti?
Koliko znaki obstajajo v datoteki?
Obstaja veliko. Torej, boste verjetno želeli, da bi dobili eno
nato pa dobil drugo in dobil drugo in dobil drugo.
Kakšen algoritem misliš, da bi moral tukaj uporabljati?
Kakšne vrste -? [Aleksander] za zanko? >> Točno tako.
Nekatere vrste zanke.
Zanka se je pravzaprav velika, v tej zadevi.
In kot si rekel, to zveni kot želite zanko čez celoten spis,
dobili znak naenkrat.
Vse predloge o tem, kaj bi lahko izgledal?
[Alexander, nerazumljiv]
>> Ok, povej mi v angleščini, kaj hočeš, da storim? [Alexander, nerazumljiv]
Torej v tem primeru, to zveni, kot da smo samo poskušam zanko skozi celoten spis.
[Aleksander] Torej i > Velikost -?
Mislim, da je velikost datoteke, kajne? Velikost - Bomo samo napisati, da, kot je ta.
Velikost datoteke zaenkrat, i + +.
Tako se izkaže, da je način, kako to narediti z fgetc in je to novo,
je, da ni enostaven način, da bi dobili samo velikost datoteke
s tem "tipa", tip gradnje, ki ste jih videli.
Ko bomo uporabili, da fgetc funkcijo, bomo uvedbo neke vrste
Nova, funky sintakso za ta zanka, kjer namesto samo osnovno števec
iti po znakih, bomo vleči en znak naenkrat,
en znak naenkrat, in način, kako vemo, da smo na koncu
ne, ko smo se šteje določeno število znakov,
ko pa smo znak potegnite je, da se posebna konec značaja datoteke.
Tako bomo lahko storite tako, da - Kličem te ch, in gremo za inicializacijo
Naš prvi poziv, da bi dobili prvi znak iz datoteke.
Torej, ta del prav tukaj, to se dogaja, da bi dobili znak iz datoteke
in ga shranite v spremenljivko ch.
Bomo vztrajati početje to, dokler ne pridemo do konca datoteke,
ki mi jih testiranje za lik ni bila enaka tisti posebni znak EOF.
In potem namesto da delaš ch + +, ki bi samo prirastek vrednosti,
tako da, če bomo prebrali A financiran iz spisa, kapital, recimo,
ch + + bi nam b, nato pa sva se C in nato d.
To seveda ni tisto, kar si želimo. Kaj hočemo tukaj
v tem zadnjem bit želimo, da bi dobili naslednji znak iz datoteke.
>> Torej, kako bi lahko dobili naslednji znak iz datoteke?
Kako bomo prišli prvi znak iz datoteke?
[Študent] fgetfile? >> Fgetc, ali je žal, da si popolnoma prav.
Sem jo napačno črkovana tam. Torej, ja.
Tu namesto opravljanja ch + +,
smo le, da bo poklical fgetc (datoteka) znova
in shrani rezultat v našem iste spremenljivke pogl.
[Student vprašanje, nerazumljiv]
>> To je, če ti fantje * FILE nekaj posebnega.
Tako se dela, da je - ko ste prvič odprli - ko prvič daste to fopen klic,
FILE * dejansko služi kot kazalec na začetek datoteke.
In potem vsakič, ko pokličeš fgetc, premakne za en znak z datoteke.
Torej, ko praviš temu, da ste povečevanje datoteke kazalec za en znak.
In ko si enkrat fgetc, ste se gibljejo ga drug znak
in še en znak in še en znak in znak.
[Student vprašanje, nerazumljiv] >> In that - ja.
To je nekako te čarovnije pod pokrovom.
Vi se samo delajte povečevanje skozi.
Na tej točki, ste lahko dejansko delajo z naravo.
Torej, kako bi lahko natisnete ven na zaslonu, ki je zdaj?
Mi lahko uporabite isti printf stvar, ki smo uporabljali.
To smo se z vsemi semester.
Lahko pokličete printf,
in se peljemo v naravi kar tako.
Drug način za to je, namesto z uporabo printf in da bi morali to storiti oblikovnega niza,
lahko uporabite tudi eno od drugih funkcij.
Mi lahko uporabite fputc, ki natisne znak na zaslonu,
razen če se ozremo na fputc - Naj pomanjšanje malo.
Bomo videli, kaj je lepo, je potrebno v naravi, ki jih je prebral z fgetc,
ampak potem moramo dati tok, da tiskati.
Lahko uporabite tudi putchar funkcijo, ki bodo neposredno postavi na izhod standardne.
Torej, obstaja cel kup različnih možnosti, ki jih lahko uporabimo za tiskanje.
Vsi so v standardni knjižnici I / O.
Kadar želite natisniti - tako printf, ki ga privzeto, bo tiskanje na posebnem standardu od potoka,
to je, da stdout.
Tako smo lahko samo sklicujejo nanj kot na nekakšno te čarobne vrednosti, stdout tukaj.
Ups. Daj podpičje zunaj.
>> To je veliko novega, funky informacij tukaj.
Veliko tega je zelo idiomatičen, v smislu, da je to koda
, ki je napisana na ta način samo zato, ker je čista, da se glasi, enostaven za branje.
Obstaja veliko različnih načinov, da to storite, več različnih funkcij, ki jih lahko uporabite,
ampak smo nagnjeni k sledite tem iste vzorce znova in znova.
Zato ne bodite presenečeni, če boste videli kodo, kot je ta prihajajo znova in znova.
V redu. Na tej točki moramo prekiniti za ta dan.
Hvala za obisk. Hvala za ogled, če ste v spletu. In se vidimo prihodnji teden.
[CS50.TV]