[Powered by Google Translate] [ODJELJAK 5: manje udoban]
[Nate Hardison, Sveučilište Harvard]
[Ovo je CS50.] [CS50.TV]
Dakle, dobrodošli natrag, momci.
Dobrodošli na sekciji pet.
U ovom trenutku, nakon što je završio kviz 0 i nakon što su vidjeli kako ste to učinili,
nadamo se osjećam jako dobro jer sam bio vrlo impresioniran rezultatima u tom dijelu.
Za naše online gledatelja, imali smo nekoliko pitanja
o posljednja dva problema na problem seta - ili na kvizu, a.
Tako da ćemo ići preko onih jako brzo, tako da svatko vidi ono što se dogodilo
i kako to ide kroz stvarne rješenje nego samo gledanje rješenje sama.
Mi ćemo ići u posljednjih nekoliko problema jako brzo, 32 i 33.
Samo, opet, tako da on-line gledatelji mogu vidjeti.
>> Ako ste okrenuti vaš problem 32, koji se nalazi na stranici 13,
13 od 16, 32 Problem je sve o swapova.
To je sve o zamjeni dva prirodna broja.
To je problem koji mi je otišao preko nekoliko puta u predavanju.
I ovdje, ono što smo molili da učinite je brzo memorije trag.
Za popuniti vrijednostima varijabli kao što su oni na stog
kao kod prolazi kroz ove zamjenske funkcije.
Konkretno, ono što gledamo - Idem staviti ovaj ipad dolje -
posebno, ono što gledamo je ova linija brojevima 6 pravo ovdje.
I to je brojevima 6 za samo dodirne s prethodnim problemom.
Ono što želimo učiniti je prikazati ili natpis na stanje memorije
kao što je to u vrijeme kada smo izvršiti ovu linije broj 6,
što je zapravo povratak iz naše zamjenske funkcije ovdje.
Ako smo dođite ovamo, vidjeli smo da su sve adrese u memoriji je predviđeno za nas.
To je vrlo ključ, vratit ćemo se na to u samo jednom trenutku.
I onda ovdje dolje na dnu, imali smo malo memorije dijagram koji ćemo odnose.
Ja sam zapravo su to učinili na mom iPad.
Tako ću izmjenjivati ​​natrag i naprijed između ipad i ovaj kod samo za referencu.
>> Počnimo. Prvo, ajmo se fokusirati na prvih nekoliko redaka glavni ovdje.
Za početak, da ćemo inicijalizirati x na 1 i y 2.
Dakle, imamo dvije cjelobrojne varijable, oni oboje će biti stavljen na stog.
Mi ćemo staviti jedan i dva u njima.
Dakle, ako sam flip preko na moj ipad, nadamo se, ajmo vidjeti -
Apple TV zrcaljenje, i tamo ćemo ići. Ok.
Dakle, ako sam flip preko na moj ipad,
Želim inicijalizirati x na 1 i y 2.
Mi to vrlo jednostavno pisanje jedan u okvir označen x.
i dva u okvir označen y. Prilično jednostavan.
Dakle, sad idemo nazad na laptop, vidjeti što će se dogoditi sljedeći.
Dakle, ovo je sljedeći redak u kojem se stvari dobiti lukav.
Prolazimo adresu x i adresu y kao parametara i b za swap funkciji.
Adresu x i adresa y su stvari koje ne možemo izračunati
bez pozivanja na tim točkama pravo ovdje dolje.
I na sreću, prve dvije bullet bodova nam točno reći što su odgovori.
Adresa xu memorije je 10, a adresa yu memorije je 14.
Dakle, oni su vrijednosti koje se prenose kao i B vrh u našoj zamjenu funkciji.
Pa opet, vratite se u našoj shemi, ja mogu napisati 10 u
i 14 u B.
Sada, to je točka gdje smo nastavili s swapa.
Dakle, flipping natrag na laptop opet,
vidimo da je način swap radi je sam prvi dereference i pohraniti rezultat u tmp.
Dakle dereference operater kaže, "Hej. Liječiti sadržaj varijable kao adresu.
Idite na ono što je pohranjena na toj adresi, i to učitavanje. "
Što ste učitati iz varijable će biti pohranjeni u našoj tmp varijable.
Flipping natrag na iPad.
Ako idemo na adresu 10, znamo da je adresa 10 je varible x
jer nam je rečeno od strane naše tocke da je adresa x memorije je 10.
Dakle, možemo otići tamo, dobili vrijednost toga, što je jedan, kao što smo vidjeli na našem iPad,
i opterećenje koje u tmp.
Opet, to nije konačni sadržaj.
Mi idemo šetati, a mi ćemo doći do našeg konačnog stanja programa na kraju.
Ali sada, imamo vrijednost jedne pohranjene u tmp.
>> I tu je brzo pitanje ovdje.
[Aleksandar] Jeli dereference operater - to je samo zvijezda ispred varijable?
>> Da. Dakle dereference operater, kao što smo okrenuti leđa naše laptop opet,
je ova zvijezda ispred.
U tom smislu, to je - da ga usporediti s množenja operatora
koji zahtijeva dvije stvari; dereference operator je unarni operator.
Samo primijeniti na jednoj vrijednosti, za razliku od binarnog operatora,
gdje se primjenjuje na dvije različite vrijednosti.
Dakle, to je ono što se događa u ovoj liniji.
Mi učitava vrijednost 1 i pohranjeni u našoj privremenog integer varijable.
U sljedećem retku, spremamo sadržaj b u -
ili, bolje rečeno, mi spremiti sadržaj koji b se upućuju na na mjestu gdje se pokazuje na.
Ako ćemo analizirati ovaj s desna na lijevo, mi ćemo dereference b,
idemo na adresu 14, mi ćemo ugrabiti cijeli broj koji je tamo,
i onda ćemo ići na adresu 10,
a mi ćemo baciti rezultat našeg dereference od b u tom prostoru.
Flipping natrag na naš ipad, gdje možemo napraviti to malo konkretniji,
to bi moglo pomoći ako sam pisati brojeve na sve adrese ovdje.
Dakle, mi znamo da je na y, mi smo na adresi 14, x je na adrese 10.
Kada smo započeli na b, mi dereference b, idemo da iskoristite vrijednost dva.
Mi ćemo zgrabiti ovu vrijednost, jer to je vrijednost koja živi na adresi 14.
I mi ćemo ga staviti u varijablu koja živi na adresi 10,
što je tamo, što odgovara našim varijabla x.
Tako možemo učiniti malo prepisati ovdje
gdje smo dobili osloboditi od naše jedne i umjesto toga napisati dvije.
Dakle, sve je dobro i dobro u svijetu, iako mi smo prepisati x sada.
Mi smo pohranjeni X staru vrijednost u našoj tmp varijable.
Dakle, možemo završiti swap sa sljedeći redak.
Flipping natrag na naš laptop.
Sada sve što ostaje je da se sadržaj iz našeg privremenog integer varijable
te ih pohraniti u varijablu koja živi na adresi koja b drži.
Dakle, idemo učinkovito dereference b da biste dobili pristup varijabla
da je na adresu koja b drži u njoj,
i idemo u stvari vrijednost koja se drži tmp u njega.
Flipping natrag na iPad još jednom.
Ja mogu izbrisati ove vrijednosti ovdje, 2,
i umjesto ćemo kopirati jedan pravo u nju.
Zatim sljedeća linija koja izvršava, naravno -
ako smo okrenuti leđa na laptop - je li to točka 6,
koja je točka na kojoj smo htjeli imati naš dijagram potpunosti ispuniti.
Dakle, flipping natrag na iPad još jednom, samo tako možete vidjeti ispunjenu dijagram,
možete vidjeti da imamo 10 u, 14 u B, jedan u tmp, dva u x, a jedan u y.
Ima li kakvih pitanja o tome?
Znači li to više smisla, nakon što je prošao kroz njega?
Napravite manje smisla? Nadam se da ne. Ok.
>> Pokazivači su vrlo lukav subjekt.
Jedan od dečki s kojima surađujemo ima vrlo čest poslovicu:
"Da bi razumjeli naputke, prvo morate razumjeti naputke."
Koji mislim da je vrlo istinito. To ne potrajati naviknuti na njega.
Crtanje puno slika, crtež puno memorije dijagrama kao što je ovaj jedan su vrlo korisne,
i nakon što hoda kroz primjer nakon primjerice nakon, primjerice,
to će početi da bi malo više smisla i malo više osjećaja i malo više smisla.
Konačno, jednog dana, imat ćete sve to u potpunosti ovladali.
Sva pitanja prije nego što smo prešli na sljedeći problem? U redu.
Tako okrenuti leđa na laptop.
Sljedeći problem koji imamo je problem broj 33 na datoteku I / O.
Povećavanje na ovoj malo.
Problem 33 - Da?
>> [Daniel] Upravo sam imao brzo pitanje. Ova zvijezda, ili asterisk,
to se zove dereferencing kada koristite zvjezdicu prije.
Što je to zove kad koristite ampersand prije?
>> Je pečatni znak prije je adresa-od operatera.
Dakle, neka je pomicanje natrag gore.
Ups. Ja sam u zoom modu, tako da ne mogu stvarno pomicanje.
Ako gledamo na ovom kodeksu stvarno brzo ovdje,
opet, ista stvar se događa.
Ako gledamo na ovom kodeksu ovdje, na ovoj liniji gdje ćemo napraviti poziv za swap,
Ampersand samo govori "dobili adresu na koju varijabla x živote."
Kada vaš prevodilac sastavlja svoj kôd,
to je zapravo fizički označiti mjesto u memoriji za sve svoje varijabli da žive.
I tako što prevodilac onda možete učiniti nakon što je sastavio sve,
ona zna, "Oh, ja sam stavio x na adresu 10. sam stavio y na adresu 14."
To onda može ispuniti ovih vrijednosti za vas.
Pa onda možete - to može onda proći to i proći & Y u, kao dobro.
Ovi dečki dobili adresu, ali oni su također, kada ih proći u zamjenu funkciju,
ova vrsta informacije, ovaj int * ovdje, govori prevodilac,
"Dobro, idemo se tumačenje ovu adresu kao adresu integer varijable."
Kao adresu int, što je različito od adresi znakova varijable
jer int zauzima, na 32-bitni stroj, zauzima 4 byte prostora,
dok je lik samo zauzima 1 byte prostora.
Dakle, važno je znati i što je - što živi, ​​što tip od vrijednosti
živi na adresi koja je dobio prošlo u.
Ili je adresa da ste se bave.
Na taj način, vi znate koliko bajtova informacija zapravo učitati iz vašeg RAM-a.
I onda, da, to dereference operater, poput tebe su postavljali,
ide i pristupa informacijama na određenu adresu.
Tako je, kaže, s ovim varijable ovdje, liječenje sadržaj kao adresu,
ići na tu adresu, i izvucite, učitati u procesoru, opterećenja u registar
stvarne vrijednosti ili sadržaja koji žive na toj adresi.
Svaki više pitanja? Ovo su dobra pitanja.
To je puno novih terminologije previše.
To je također vrsta funky, gledajući & a * u različitim mjestima.
>> U redu.
Dakle, natrag na problemu 33, podnijeti I / O.
To je bio jedan od onih problema koje ja mislim par stvari dogodilo.
Jedan od njih, to je relativno nova tema.
To je bio predstavljen uskoro pred kvizu,
i onda mislim da je to vrsta kao jedna od onih riječi problema u matematici
gdje su vam dati puno informacija, ali zapravo ne završiti potrebe da koriste tonu njega.
Prvi dio ovog problema opisuje što CSV datoteka je.
Sada, CSV datoteka, prema opisu, je odvojen zarezom vrijednosti datoteka.
Razlog su uopće zanimljiva, a razlog što ih je ikada koristiti,
je, jer, kako su mnogi od vas ikada koristiti stvari kao što su Excel?
Slika većina vas, vjerojatno, ili će se koristiti u nekom trenutku u vašem životu.
Vi ćete koristiti nešto poput Excela.
Da bi dobili podatke iz Excel spreadsheet-ovima ili učiniti bilo kakve obrade s njim,
ako si htio napisati C program ili Python program, Java programa,
nositi s podacima koje ste pohranjenih tamo,
jedan od najčešćih načina da ga izaći u CSV datoteku.
A možete otvoriti Excel i kad idete na "Save As" dijalog,
možete izaći stvarni CSV datoteku.
>> Handy znati kako se nositi s tim stvarima.
Način na koji to radi je da je sličan - Mislim, to u suštini je oponaša tablicu,
gdje je, kao što smo vidjeli ovdje, u vrlo lijevo-najveći komad,
imamo sve prezimena.
Dakle, imamo Malan, zatim Hardison, a zatim Bowden, MacWilliam, a zatim Chan.
Sva prezimena. A onda zarez razdvaja prezimena iz prvih imena.
David, Nate, Rob, Tommy, i Zamyla.
Uvijek sam se miješati Robby i Toma.
I onda, konačno, treći stupac je e-mail adrese.
Jednom kad shvatite da je ostatak programa je prilično jednostavan za implementaciju.
Što smo učinili kako bi oponašati ovu istu strukturu u našem C programu
je smo koristili strukturu.
Mi ćemo početi igrati s njima malo više, kao dobro.
Vidjeli smo ih na prvom malo u problematiku skupa tri godine, kada smo se bavi rječnika.
Ali ovo osoblje struct sprema posljednju ime, prezime, samo ime i e-mail.
Baš kao što je naš CSV datoteku je spremanje.
Dakle, ovo je samo pretvaranje iz jednog oblika u drugi.
Moramo pretvoriti, u ovom slučaju, a osoblje struct u liniji,
odvojenih zarezom linija, baš kao da je.
Ima li to smisla? Vi svi su se kviz,
pa pretpostavljam da su barem imali malo vremena za razmišljanje o tome.
>> U najam funkciji, problem traži od nas da se u - hrapavi uvećanje na ovoj malo -
uzeti u strukturi osoblja, osoblje struct, s ime je,
i dodati svoj sadržaj na naš staff.csv datoteku.
Ispada da je to prilično jednostavan za korištenje.
Mi ćemo vrsta poigrati s tim funkcijama malo više danas.
No, u ovom slučaju, fprintf funkcija je stvarno ključ.
Dakle, s fprintf, možemo ispisati, baš kao i vi ste koristili printf cijeli ovaj termin.
Možete printf linija u datoteku.
Dakle, umjesto da samo što je uobičajeni printf poziv gdje mu dati niz formata
i onda zamijeniti sve varijable sa sljedećim argumentima,
s fprintf, tvoj prvi argument je umjesto datoteku koju želite pisati.
Ako smo bili pogledati to u aparatu, na primjer, čovjek fprintf,
možemo vidjeti razliku između printf i fprintf.
Ja ću povećavanje ovdje malo.
Dakle, s printf, dajemo mu niz formata, a zatim kasniji argumenti
su sve varijable za zamjenu ili zamjenu u našem format string.
Dok s fprintf, prvi argument je doista ovu sliku * zove stream.
>> Premještanje natrag ovamo na naš najam,
već smo dobili naša datoteka * potok otvorena za nas.
To je ono što ovaj prvi red ne, to otvara staff.csv datoteku,
on ga otvara u append modu, a sve što je lijevo za nas učiniti je
napisati osoblje strukturu datoteke.
I, neka se vidi, ne želim koristiti iPad?
Ja ću koristiti ipad. Imamo prazninu - neka je stavi ovo na stolu, tako da mogu napisati nešto bolje -
poništiti najam, a to vodi u jedan argument, a osoblje strukturu nazvanu a.
Imaš naše aparatić, mi imamo našu datoteke * zove datoteka,
mi imamo fopen liniju s obzirom na nas,
i samo ću ga pisati kao točke budući da je već u PEDIA.
A onda na našem sljedećem retku, idemo napraviti poziv fprintf
i da ćemo proći u spisu koje želimo ispisati,
i onda naša format string, koji -
Pustit ću ti dečki recite mi kako to izgleda.
Kako o vama, Stella? Znate li što je prvi dio format string izgleda?
[Stella] nisam siguran. >> Slobodno pitajte Jimmy.
Znate li, Jimmy?
[Jimmy] Bi li to biti samo zadnji? Ne znam. Nisam posve siguran.
>> Ok. Kako o, da li se itko dobiti to točno na ispitu?
No redu.
Ispada da je ovdje sve što morate učiniti je želimo svaki dio našeg osoblja strukture
biti tiskan kao niz u našoj datoteci.
Mi samo koristiti karakter supstitucije Gudački tri različita puta, jer imamo prezime
slijedi zarez, a zatim ime slijedi zarez,
i onda na kraju e-mail adresa koje slijede - koji nije
ugradnju na mom ekranu - ali to je popraćen newline karaktera.
Dakle, ja ću ga napisati samo tamo dolje.
A onda slijedi naš format string,
samo mi imamo zamjene, koje smo pristupili pomoću dot notacija
koje smo vidjeli u problematiku skupa tri.
Možemo koristiti s.last, s.first i s.email
zamjena u te tri vrijednosti u našem format string.
Pa kako je to ići? Smisla?
Da? Ne? Možda? Ok.
>> Konačna stvar da radimo nakon što smo tiskan i nakon što smo otvorili našu sliku:
kad smo otvorili datoteku, uvijek moramo imati na umu da ga zatvoriti.
Jer inače ćemo završiti curi memorije,
koristeći se datoteka deskriptora.
Tako da ga zatvorili, koji funkcija ne možemo koristiti? Daniel?
[Daniel] fclose? >> Fclose, točno.
Dakle, posljednji dio ovog problema je da pravilno zatvorite datoteku, koristeći fclose funkciju,
koji samo izgleda kao da.
Ne previše ludo.
Cool.
Tako da je problem 33 na kvizu.
Morat ćemo definitivno više datoteka I / O dolazi.
Učinit ćemo malo više u predavanju danas, ili u sekciji danas,
jer to je ono što se događa da se formira većinu ove nadolazeće pset.
Idemo na iz kviza u ovom trenutku. Da?
>> [Charlotte]] Zašto fclose (datoteka) umjesto fclose (staff.csv)?
>> Ah. Jer ispada da - pa se postavlja pitanje, što je jedan veliki,
je razlog zašto, kada pišemo fclose, pišemo fclose (file) zvijezda varijablu
za razliku od naziva datoteke, staff.csv? Je li to točno? Da.
Dakle, neka je pogledati. Ako sam se vratiti na moj laptop,
i pogledajmo na fclose funkciji.
Dakle fclose funkcija zatvara tok i to traje u pokazivač do potoka koji želimo zatvoriti,
za razliku od stvarnog naziva datoteke koje želimo zatvoriti.
A to je zato što iza kulisa, kada upućivanje poziva fopen,
kada otvorite datoteku, zapravo dodjele memorije za pohranu informacija o datoteci.
Dakle, imate datoteke pokazivač koji ima informacije o datoteci,
kao što je otvoren, njegova veličina, gdje ste trenutno u spisu,
tako da možete napraviti čitanje i pisanje poziva na tom mjestu u datoteci.
Možete završiti zatvaranjem pokazivač umjesto zatvaranja naziv datoteke.
>> Da? [Daniel] Dakle, kako bi se koristiti najam, će vam reći - kako to dobiti korisničkog unosa?
Da li fprintf djelovati kao GetString u smislu da ću samo čekati korisničkog unosa
i pitati da upišete ovo - ili čekati za vas da upišite ove tri stvari u?
Ili ne morate koristiti nešto za provedbu najam?
>> Da. Dakle, mi nismo - pitanje je, kako smo dobili korisničkog unosa
u cilju provođenja najam? A što imamo ovdje je pozivatelj od najma,
donesen u ovom osoblja struct sa svim podacima pohranjenim u struct već.
Dakle fprintf je u stanju samo napisati da podatke izravno u datoteku.
Nema čekanja za unos korisnika.
Korisnik je već dao doprinos po ispravno stavljajući ga u ovom osoblja struct.
A stvari, naravno, ako će razbiti bilo koju od tih pokazivače bili null,
pa smo pomicali natrag ovdje i gledamo naše struct.
Imamo niz posljednji, string prvi, niz e-mail.
Mi sada znamo da su svi oni stvarno, ispod haube, su char * varijable.
To ne može ili može biti ukazujući na nulu.
Oni mogu biti ukazujući na spomen na hrpi,
možda memorije na stogu.
Mi stvarno ne znam, ali ako bilo koji od ovih pokazivače su nula, ili je nevažeći,
da da definitivno ću srušiti našu najam funkciju.
To je nešto što je vrsta izvan opsega ispita.
Mi ne brinući se o tome.
Izvrsno. Ok. Tako se kreće od kviza.
>> Ajmo zatvoriti ovaj momak, a mi ćemo gledati na pset 4.
Dakle, ako vi pogledate pset spec., jednom možete pristupiti, cs50.net/quizzes,
ćemo proći kroz nekoliko sekcija problema danas.
Ja sam pomicanjem prema dolje - dio pitanja počinje na trećem stranici pset spec..
I prvi dio vas pita da ide i gledati kratko o preusmjeravanju i cijevi.
Koja je vrsta super kratka, pokazuje neke nove, cool trikove naredbenog retka koje možete koristiti.
I onda imamo nekoliko pitanja za vas kao dobro.
Ovo prvo pitanje o potocima, na koje printf piše po defaultu,
smo vrsta dotaknuo samo malo trenutak prije.
Ovo fprintf da smo upravo raspravljali uzima u struji datoteke * kao svoj argument.
fclose uzima u struji datoteke * kao dobro,
i povratak vrijednost fopen vam daje tok datoteke * kao dobro.
Razlog nismo vidjeli one prije kad smo se bavila printf
je zbog printf ima zadani tok.
I zadani potok na kojem piše
ćete saznati u kratko.
Dakle, definitivno pogledati njega.
>> U današnjem odlomku, idemo razgovarati malo o GDB,
budući da je više upoznati ste s njim, više praksa da se s njom,
bolje mogućnosti ćete biti zapravo uloviti greške u vlastitom kodu.
To ubrzava proces debugging se strahovito.
Dakle, pomoću printf, svaki put kad to morate rekompiliranje svoj kôd,
morate ga ponovno pokrenuti, ponekad morate premjestiti printf poziv okolo,
komentirati se kod, to traje samo neko vrijeme.
Naš cilj je pokušati uvjeriti da je s GDB, možete biti
printf ništa u bilo kojem trenutku u vašem kodu, a da nikada ne morate ga rekompiliranje.
Vi nikada nećete morati početi i zadržati guessing gdje printf sljedeći.
Prva stvar za učiniti je da kopirate ovu liniju i dobiti odjeljak kod off webu.
Ja sam kopiranje ovu liniju koda koji kaže, "wget ​​http://cdn.cs50.net".
Ja ću ga kopirati.
Ja ću ići preko moje aparata, zoom out, tako da možete vidjeti što radim,
zalijepiti tamo, i kad sam pogodio Enter, ovo wget naredba doslovno je web dobili.
To će srušiti ovu sliku s interneta,
i to će ga spremiti u trenutnoj imenik.
Sada, ako sam popis moj trenutni katalog možete vidjeti da sam dobio ovu section5.zip datoteku upravo tamo.
Na način da se bave tim tipom je da ga unzip,
što možete učiniti u zapovjednoj liniji, baš kao što je ovaj.
Section5.zip.
To će ga unzip, stvarati mape za mene,
napuhati sve sadržaje, stavite ih tamo.
Dakle, sada mogu ići u moj odjeljak 5 direktorij pomoću cd naredbu.
Prazni zaslon koristeći jasno. Dakle, brisanje zaslona.
Sada imam lijep čist terminal da se bave.
>> Sada, ako sam popis svih datoteka koje vidim u ovaj direktorij,
vidiš da sam dobio četiri datoteke: buggy1, buggy2, buggy3 i buggy4.
Također sam dobio svoje odgovarajuće. C datoteke.
Nećemo gledati na c. Datoteka za sada.
Umjesto toga, mi ćemo ih koristiti kad smo otvoriti gdb.
Mi smo ih čuva okolo, tako da imamo pristup stvarnog izvornog koda kada smo pomoću gdb,
ali cilj ovog dijela poglavlja je prtljati oko s GDB
i vidjeti kako ga možemo koristiti shvatiti što se događa u redu sa svakom od tih četiri Buggy programa.
Dakle, mi smo samo ide po sobi jako brzo,
i ja ću pitati nekoga za pokretanje jednog od Buggy programa,
i onda ćemo ići kao skupina kroz GDB, pa ćemo vidjeti što možemo učiniti kako bi riješili ove programe,
ili barem utvrditi što se događa krivo u svakoj od njih.
Počnimo ovamo s Danielom. Hoćete li pokrenuti buggy1? Idemo vidjeti što se događa.
[Daniel] Ona kaže da je primjena kriv. >> Da. Točno.
Dakle, ako sam pokrenuti buggy1, ja dobiti SEG kvar.
U ovom trenutku, mogao sam otići i otvoriti buggy1.c,
pokušati shvatiti što se zbiva u krivu,
ali jedan od najvažnijih antipatičan stvari o tom segmentu kvara pogreške
je da se ne govori o tome što linija programskih stvari zapravo otišao u krivu i razbio.
Vi vrsta morati pogledati koda
i shvatiti pomoću pogodak i provjeriti ili printf da vidim što se događa u krivu.
Jedna od najboljih stvari o GDB je da je to stvarno, stvarno lako
shvatiti liniju na kojoj je vaš program ruši.
Totalno je vrijedan da ga koristiti, čak i ako je samo za to.
Dakle dignuti gdb, ja upišite gdb, a onda sam mu dati put do izvršnu da želim pokrenuti.
Ovdje sam tipkati gdb ./buggy1.
Hit Enter. Daje mi sve ove informacije o autorskim pravima,
i ovdje dolje vidjet ćete ovu liniju koja kaže, "Čitanje simbola iz / home /
jharvard/section5/buggy1. "
A ako sve ide dobro, vidjet ćete ga ispisati poruku da izgleda ovako.
To ću čitati simbole, to će reći: "Čitam simbole iz izvršnu datoteku"
i onda će se ovaj "Gotovo" poruku ovdje.
Ako vidite neke druge varijacije toga, ili ste vidjeli da nije mogao pronaći simbole
ili nešto slično, što to znači je da jednostavno nije sastavio svoju izvršnu ispravno.
Kada smo sastaviti programe za korištenje s GDB, moramo koristiti taj poseban-g zastavu,
te da je učinjeno po defaultu ako prevesti svoje programe, samo upisivanjem napraviti
ili napraviti buggy ili napraviti oporaviti, bilo onih.
Ali, ako ste izradu ručno zveka, onda ćete morati ići i uključuju da-g zastavu.
>> U ovom trenutku, da sada imamo gdb redak,
to je prilično jednostavan za pokretanje programa.
Mi može upisati stazu, ili možemo samo upišite r.
Većina naredbi GDB može biti skraćeno.
Obično se samo jednom ili nekoliko pisama, koje je prilično lijepo.
Dakle Saad, ako Type R i pritisnite Enter, što se događa?
[Saad] Imam SIGSEGV, segmentacije greška, a onda sve to črčkarija.
>> Da.
Kao što smo vidjeli na ekranu upravo sada, i kao Saad je rekao,
kad smo upišite stazu ili R i pritisnite Enter, mi još uvijek dobiti istu grešku SEG.
Dakle, koristite gdb ne riješi naš problem.
No, to nam daje neku gobbledygook, a ispada da je ova črčkarija
zapravo nam govori gdje se to događa.
Da analizirati ovaj malo, ovaj prvi malo je funkcija u kojem će sve u redu.
Tu je ovaj __ strcmp_sse4_2, a to nam govori da se to događa u ovoj datoteci
zove sysdeps/i386, sve to, opet, vrsta nered - ali linija 254.
To je vrsta teško analizirati. Obično kada vidite stvari kao što je ovaj,
to znači da je SEG rasjedanja u jednom od sustava knjižnica.
Tako nešto učiniti s strcmp. Vi ste vidjeli strcmp prije.
Ne previše ludo, ali znači li to da strcmp slomljena ili da postoji problem s strcmp?
Što mislite, Alexander?
[Aleksandar] Je li to - je 254 linija? I - ne binarni, ali to nije njihova stropovi,
i onda tu je još jedan jezik za svaku funkciju. Je li to 254 u toj funkciji, ili -?
>> To je linija 254. To izgleda kao u ovoj. S. datoteku, tako da je sklop kod vjerojatno.
>> Ali, valjda više dobilo je stvar, jer smo stečen SEG kvar,
i to izgleda kao da dolazi iz strcmp funkciju,
to znači, dakle, da je strcmp je slomljen?
To ne bi trebao, nadamo se. Dakle, samo zato što imaju segmentacije grešku
u jednoj od funkcija sustava, obično to znači da jednostavno nisu ga zove ispravno.
Najbrži stvar za učiniti kako bi se shvatiti što se zapravo događa
kad vidite nešto ludo ovako, kad god vidim SEG kvar,
pogotovo ako imate program koji je koristeći više nego samo glavni,
je koristiti povratno praćenje.
Ja skratiti povratno praćenje pišući BT, za razliku do pune Povratno praćenje riječi.
No, Charlotte, što se događa kad upišete BT i pogodak Ulaziti?
[Charlotte] To mi pokazuje dvije linije, linija 0 i 1. redak.
>> Da. Dakle linija između 0 i 1. redak.
To su stvarni stack okviri koji su trenutno u igri kada je vaš program srušio.
Počevši od najvišem okvira, frame 0, a ide na dno-većina, što je okvir 1.
Naš vrhunski okvir je strcmp okvir.
Možete misliti o tome što slično za taj problem smo samo radili na kvizu s pokazivačima,
gdje smo zamijenili stog okvir na vrhu glavne stog okvira,
i imali smo varijable koje Swap je koristite na vrhu varijabli koje glavni je koriste.
Evo naša nesreća dogodila u našoj strcmp funkciju, koju je sazvao naš glavni funkciji,
i povratno praćenje daje nam ne samo funkcije u kojoj stvari propustio,
ali to je također nam reći gdje je sve bio pozvan od.
Dakle, ako sam pomicanje preko malo više na desno,
možemo vidjeti da, da, bili smo na liniji 254 ovog strcmp-sse4.s datoteku.
No, upućen je poziv na buggy1.c, linije 6.
Dakle, to znači da možemo učiniti je - možemo ići provjeriti i vidjeti što se događa
na buggy1.c, linije 6.
Opet, postoji nekoliko načina da to učinite. Jedan od njih je za izlazak iz GDB
ili imaju svoj kod otvoriti u drugom prozoru i cross reference.
To, samo po sebi, je prilično zgodan, jer sada, ako ste u uredovno vrijeme
i imaš SEG kvar i vaš TF je pitate gdje je sve nego,
možete samo reći: "Oh, linija 6. Ne znam što se događa,
ali nešto o liniji šest uzrokuje moj program za break. "
Drugi način da to učinite je možete koristiti ovu naredbu zove popis u GDB.
Također ga možete skratiti sa l.
Dakle, ako smo pogodak l, što smo dobili ovdje?
Mi smo dobili hrpu čudne stvari.
Ovo je stvarni sklop kod
koji je u strcmp_sse4_2.
Ovo izgleda vrsta funky,
i razlog da smo uzimajući to je zato što upravo sada,
GDB nas ima u kadru 0.
>> Dakle, bilo gledamo varijabli, svaki put gledamo izvornog koda,
gledamo izvornog koda koji se odnosi na stog okvir smo trenutno u.
Dakle, kako bi dobili ništa smisleno, moramo
premjestiti na stog okvir koji čini više smisla.
U ovom slučaju, glavni okvir stog bi malo više smisla,
jer to je zapravo kod koji smo pisali.
Ne strcmp broj.
Način na koji se može kretati između okvira, u ovom slučaju, jer imamo dva,
imamo 0 i 1,
li to učiniti s gore i dolje naredbi.
Ako sam se pomaknuli jednu okvir,
sada sam u glavnom izlazu okvira.
Ja mogu pomaknuti prema dolje da se vrati na mjesto gdje sam bio,
ići gore opet, ići dolje opet, i opet ići gore.
Ako ste ikada učiniti svoj program u GDB, možete dobiti sudar, možete dobiti povratno praćenje,
i vidjet ćete da je to u nekom datotekom da ne zna što se događa.
Možete pokušati popis, broj ne izgleda upoznat s tobom,
pogledati svoje okvire i shvatiti gdje se nalazite.
Vjerojatno si u krivom stog okvira.
Ili barem si u stog okvir koji nije onaj koji ti stvarno mogu debug.
Sada smo u odgovarajućem stog okvira, mi smo u glavni,
Sada možemo koristiti naredbu popisa shvatiti što je linija bila.
A možete ga vidjeti, to je tiskan za nas ovdje.
No, možemo udariti popis svi isti, a popis daje nam ovu lijepu ispis
od stvarnog izvornog koda koji je ovdje događa.
>> Konkretno, možemo pogledati liniji šest.
Možemo vidjeti što se ovdje događa.
I to izgleda kao da smo izradu string usporedbu
između niza "CS50 stijena" i argv [1].
Nešto o tome je pad.
Dakle, Missy, imate bilo kakve misli na ono što bi moglo biti događa ovdje?
[Missy] Ne znam zašto je pad. >> Ne znam zašto se to pad?
Jimmy, sve misli?
[Jimmy] Nisam posve siguran, ali zadnji put kad smo koristili niz usporediti,
ili strcmp, kao što smo imali tri različita slučaja pod njim.
Nismo imati ==, ne mislim, jel u toj prvoj liniji.
Umjesto toga, on je bio podijeljen u tri, a jedan je bio == 0,
jedan je <0, mislim, i jedan je> 0.
Dakle, možda nešto kao što je to? >> Da. Dakle, tu je taj problem
od činimo usporedbu ispravno?
Stella? Bilo misli?
[Stella] nisam siguran. >> Ne znam. Daniel? Misli? Ok.
Ispada ono što se događa ovdje je kada smo trčali program
i dobili smo SEG kvar, kada ste pokrenuli program za prvi put, Daniel
jesi li mu dati nikakve argumente naredbenog retka?
[Daniel] No >> broj U tom slučaju, ono što je vrijednost argv [1]?
>> Nema vrijednost. >> Točno.
Pa, ne postoji odgovarajući string vrijednost.
No, tu je neke vrijednosti. Što je vrijednost koja dobiva pohranjen unutra?
>> Smeća vrijednost? >> To je bilo smeća vrijednost ili, u ovom slučaju,
kraj argv niz uvijek prestaje sa null.
Dakle, ono što je zapravo dobio pohranjeni u tu je nula.
Drugi način da se riješi to, nego ga razmišljanja kroz,
je pokušati ga ispišete.
Ovo je mjesto gdje sam rekao da koristite gdb je super,
jer možete ispisati sve varijable, sve vrijednosti za koje želite
Korištenjem ove ruci-Dandy p naredbu.
Dakle, ako sam tip P i onda sam upisati vrijednost varijable ili naziv varijable,
recimo, argc, vidim da argc je jedan.
Ako želim isprintati argv [0], ja mogu učiniti baš kao da.
I kao što smo vidjeli, argv [0] je uvijek ime svog programa,
Uvijek naziv izvršne datoteke.
Ovdje možete vidjeti da je dobio punu put ime.
Ja također može ispisati iz argv [1] i vidjeti što se događa.
>> Ovdje smo dobili ovu vrstu mistične vrijednosti.
Dobili smo ovu 0x0.
Sjetite se na početku mandata, kada smo razgovarali o heksadecimalni brojevi?
Ili da malo pitanje na kraju pset 0 o tome da predstavljaju 50 u hex?
Način na koji smo pisati heksadecimalni brojevi u CS, samo ne sebe zbuniti
s decimalnim brojevima, je da smo ih uvijek prefiks s 0x.
Dakle, ovo 0x prefiks uvijek samo znači interpretirati sljedeći broj kao heksadecimalni broj,
ne kao niz, a ne kao decimalni broj, a ne kao binarni broj.
Budući da je broj 5-0 je ispravan broj u heksadecimalnom.
I to je broj u decimalu, 50.
Dakle, ovo je samo koliko smo disambiguate.
Dakle, 0x0 znači heksadecimalni 0, što je također decimalni 0, binarni 0.
To je samo vrijednost 0.
Ispada da je to ono što null je, zapravo, u sjećanju.
Nula je samo 0.
Ovdje, element pohranjeni na argv [1] je null.
Dakle, mi pokušavamo usporediti našu "CS50 stijene" niz u prazan niz.
Dakle dereferencing null, pokušavate pristupiti stvari na null,
oni obično idu izazvati neku vrstu segmentacije kvara ili drugih loših stvari događaju.
I ispada da strcmp ne provjeriti
da li ili ne ste prošli u vrijednosti koja je nula.
Umjesto toga, ona samo ide naprijed, pokušava učiniti svoj posao,
i ako SEG grešaka, to SEG grešaka, i to je tvoj problem. Morate ići to popraviti.
Stvarno brzo, kako bismo mogli riješiti ovaj problem? Charlotte?
[Charlotte] možete provjeriti pomoću li.
Dakle, ako argv [1] je null, == 0, a zatim se vratiti 1, ili nešto [nerazumljiv].
>> Da. Dakle, to je jedan sjajan način da to učinite, kao što možemo provjeriti,
vrijednost smo o proći u strcmp, argv [1], je li null?
Ako je to nula, onda možemo reći ok, pobaciti.
>> Češći način da to učinite je da koristite argc vrijednost.
Možete vidjeti ovdje na početku glavne,
smo izostavili taj prvi test koji se obično učiniti kada ćemo koristiti argumente naredbenog retka,
koji je za testiranje da li ili ne naša argc vrijednost je ono što smo očekivali.
U ovom slučaju, mi smo očekivali barem dva argumenta,
Naziv programa plus jedan drugoga.
Budući da smo o tome kako koristiti drugi argument ovdje.
Tako da nekakvu testa unaprijed, prije našeg poziva strcmp
da testovi li ili ne argv je najmanje dva, također će učiniti istu vrstu stvari.
Možemo vidjeti ako to radi tako da pokrenete program.
Uvijek možete ponovno pokrenuti programa unutar GDB, što je jako lijepo.
Možete pokrenuti, a kada prođe u argumente za svoj program,
ih proći prilikom poziv pokrenuti, a ne kada se dignuti gdb.
Na taj način možete zadržati pozivajući svoj program s različitim argumentima svaki put.
Tako trčite, ili opet, mogu upisati r, pa da vidimo što će se dogoditi ako upišete "halo".
Uvijek će vas pitati želite li ga početi iz početka.
Obično, vi ne želite da ga početi iz početka.
I u ovom trenutku, to ponovno opet, to ispisuje
program koji smo trčanje, buggy1, s argumentom Hello,
i ispisuje ovaj standardni out, ona kaže: "Ti dvojku", tužno lice.
Ali mi nije SEG kvar. On je rekao da je proces izašao normalno.
Tako da izgleda prilično dobro.
Nema više segmenata kriv, mi je napravio to prošlost,
tako da izgleda kao da je doista segment kriv bug koji smo dobivali.
Nažalost, to nam govori da smo uzimajući D.
>> Možemo se vratiti i pogledati kôd i vidjeti što se događa tamo
shvatiti što je - zašto je nam govori da imamo D.
Hajdemo vidjeti, ovdje je to printf rekavši da imaš D.
Ako upišite popis, kao što držati tipkanjem popisa, on drži Ponavljanje kroz svoj program,
tako da ću vam pokazati prvih nekoliko redaka svom programu.
Tada ću vam pokazati sljedećoj nekoliko redaka, a sljedeći blok i sljedeći komad.
I to ću zadržati pokušava ići dolje.
A sada ćemo doći do "postroje broj 16 je izvan dometa."
Budući da ima samo 15 redaka.
Ako dođete do ove točke i vaš pitate, "Što da učinim?" možete koristiti naredbu pomoć.
Koristite pomoći, a zatim dati mu ime naredbe.
A vidiš GDB nam daje sve ovu vrstu stvari.
Ona kaže, "Bez argumenta, navodi deset više linija nakon ili oko prethodnom popisu.
Popis - navodi deset linije prije - "
Dakle, pokušajmo pomoću popisa minusa.
I to navodi u 10 redaka natrag, možete se poigrati s popisa malo.
Možete napraviti popis, popis -, možete čak i dati popis nekoliko, kao što je popis 8,
i to ću navesti 10 linije oko linija 8.
A možete vidjeti što se ovdje događa je da ste je dobio jednostavan ako drugdje.
Ako ste upisali u CS50 stijenama, ona ispisuje "Vi dobijete A."
Inače ga ispisuje "Vi dobiti D."
Sori grad. U redu. Da?
>> [Daniel] Dakle, kada sam pokušao raditi CS50 stijene bez navodnika,
ona kaže: "Vi dobiti D."
Morao sam citati da bi to raditi, zašto je to?
>> Da. Ispada da kada - to je još jedna zabavna mala poslastica -
kada pokrenete program, ako ćemo ga pokrenuti i mi upisati u CS50 stijenama,
baš kao i Daniel je rekao što je učinio, a vi pritisnite Enter,
to još uvijek kaže da smo dobili D.
A pitanje je, zašto je ovo?
I ispada da su oba naša terminal i GDB analizirati ih kao dvije zasebne argumenata.
Jer kada postoji prostor, koji je podrazumijevao kao
Prvi argument je završio, sljedeći argument je oko za početak.
Način da kombiniraju one u dva, ili oprostite, u jednog argumenta,
je koristiti citati.
Tako sada, ako smo ga staviti u navodnike i pokrenite ga opet, dobivamo A.
Dakle, samo da podsjetimo, bez navodnika, CS50 i stijene se raščlaniti kao dvije zasebne argumenata.
S navodnicima, to je analiziran kao jedan argument uopce.
>> Možemo vidjeti ovo s prelomne tačke.
Do sada smo bili trčanje naš program, i to je bio trčanje
dok bilo to SEG grešaka ili pogodaka pogrešku
ili dok je izašao i sve je potpuno u redu.
To ne mora nužno biti najkorisnija stvar, jer ponekad
imate grešku u svom programu, ali to ne uzrokuje segmentaciju grešku.
To nije uzrok svoj program da se zaustavi ili bilo što slično.
Način da se GDB pauzirati vaš program u određenom trenutku
je postaviti točke prekida.
Možete to učiniti postavljanjem točke prekida na naziva funkcije
ili možete postaviti točke prekida na određenoj liniji koda.
Volim da postavite prijelomnih točaka na funkciju imena, jer - lako zapamtiti,
i ako zaista otići i promijeniti svoj izvorni kod se malo,
onda tvoj prijelomna točka zapravo će ostati na istom mjestu u kodu.
Dok ako koristite brojeve redaka, a linija brojevi promijeniti
zato što dodati ili izbrisati neki kod, a zatim svoje prijelomnih točaka su svi totalno zeznuo.
Jedan od najčešćih stvari koje sam učiniti je postaviti točke prekida na glavnoj funkciji.
Često ću dignuti gdb, ja ću Tip B Main, pritisnite Enter, i da ću postaviti točke prekida
na glavnoj funkciji koja samo kaže, "Pauza program čim početi prikazivati"
i na taj način, kada sam se pokreću moj program sa, recimo, CS50 stijenama kao dva argumenta
i pritisnite Enter, ona dobiva glavnu funkciju i to prestaje pravo na vrlo prvoj liniji,
pravo prije nego što ga ocjenjuje strcmp funkciju.
>> Budući da sam zastao, sada mogu početi mucking oko sebe i vidjeti što se događa
sa svim različitim varijablama koje su prošli u mom programu.
Ovdje mogu ispisati argc i vidjeti što se događa.
Pogledajte kako argc je 3, jer ima tri različite vrijednosti u njemu.
To je dobio naziv programa, to je dobio prvi argument i drugi argument.
Možemo ispisati one od strane gleda na argv [0], argv [1], a argv [2].
Dakle, sada možete vidjeti zašto se to strcmp poziv će uspjeti,
jer vidiš da je podijeljen do CS50 i stijene u dvije zasebne argumenata.
U ovom trenutku, nakon što ste pogoditi točke prekida, možete nastaviti na korak kroz svoj program
redak po redak, za razliku od pokretanja programa ponovno.
Dakle, ako ne želite pokrenuti svoj program i opet samo dalje od ovog,
možete koristiti naredbu nastaviti i dalje će pokrenuti program do kraja.
Baš kao što je to učinio ovdje.
Međutim, ako sam ponovno pokrenuti program, CS50 stijene, pogodi moje točke prekida opet,
i ovaj put, ako ja ne želim samo ići sve na putu kroz ostatak programa,
Ja mogu koristiti slijedeću naredbu, koji sam također skratiti s n.
I ovaj će korak kroz program liniju po liniju.
Tako možete gledati kao stvari izvršiti, kao varijable promjene, kao što se stvari ažuriraju.
Koji je prilično lijepo.
Druga super stvar je nego ponavlja istu naredbu iznova i iznova i iznova,
ako samo pritisnite Enter - pa evo vidite nisam upisali u ništa -
ako sam pogodio Enter, to će ponoviti prethodne naredbe,
ili prethodnu naredbu GDB da sam samo staviti u.
Ja mogu držati udarajući Unesite i to ću zadržati koračni kroz moje koda liniju po liniju.
Ja bi potaknuti vi ići provjeriti druge lud programe kao dobro.
Mi nemamo vremena da se kroz sve njih danas u sekciji.
Izvorni kod je tamo, tako da možete nekako vidjeti što se događa
iza scene ako stvarno zapeti,
ali barem, samo vježbati čizma gore gdb,
pokretanja programa sve dok se lomi na vas,
uzimajući povratno praćenje, figuring out ono što funkcionira sudar je bio u,
ono linija je bila na, ispis neke promjenjive vrijednosti,
samo tako da ćete dobiti osjećaj za to, jer je to stvarno će vam pomoći da ide naprijed.
U ovom trenutku, mi ćemo prestati iz GDB, koje ne koristite prestati ili samo q.
Ako je vaš program u sredini radi i dalje, a to nije izašao,
uvijek će vas pitati "Jeste li sigurni da stvarno želite prestati?"
Možete samo pogoditi da.
>> Sada ćemo pogledati na sljedećem problema koje imamo, a to je mačka programa.
Ako gledate na kratko preusmjeravanje i cijevi, vidjet ćete da je Tommy koristi ovaj program
da je u osnovi ispisuje sve izlaz u datoteku na zaslonu.
Dakle, ako sam pokrenuti mačka, to je zapravo izgrađen-in program za aparata,
i ako imate Mac možete to učiniti na vašem Macu, ako vam se otvoriti terminal.
A mi - mačka, recimo, cp.c, i pritisnite Enter.
Što je to učinio, ako mi pomicanje gore malo i vidjeti gdje smo trčali liniju,
ili gdje smo trčali mačka naredbu, to doslovno samo ispisati sadržaj cp.c našem zaslonu.
Možemo ga ponovno pokrenuti i možete staviti u više datoteka zajedno.
Dakle, što možete učiniti mačka cp.c, a onda možemo spojite na cat.c datoteku,
koji je program smo napisati,
i to će ispisati obje datoteke natrag na leđa našoj zaslonu.
Dakle, ako smo se pomicali gore malo, vidimo da, kada smo trčali ovaj mačka cp.c, cat.c,
prvi je tiskan CP datoteku, a zatim ispod njega, to ispisati iz cat.c datoteku upravo ovdje dolje.
Mi ćemo koristiti to samo dobiti naše noge mokro.
Poigrajte se s jednostavnim ispis na terminalu, vidjeti kako se to radi.
Ako ti dečki otvaraju sa gedit cat.c, pritisnite Enter,
možete vidjeti program da smo o tome pisati.
Uključili smo ovu lijepu kotao ploča, tako da ne morate trošiti vrijeme tipkati sve da van.
Također smo provjeriti broj argumenata prošao i.
Mi ispisati lijep običaj poruku.
>> To je vrsta stvar koja, opet, kao što smo razgovarali o tome,
to je gotovo kao mišića memorije.
Dovoljno je sjetiti se držati događaj istu vrstu stvari
i uvijek ispisuje nekakav korisne poruke
tako da ljudi znaju kako pokrenuti vaš program.
Sa mačka, to je prilično jednostavan, samo mi ćemo proći kroz sve različite argumente
koji su doneseni na našem programu, a mi idemo za ispis
njihov sadržaj van na zaslonu jedna na vrijeme.
Kako bi se ispisati datoteke iz na zaslonu, idemo napraviti nešto vrlo slično
na ono što je na kraju kviza.
Na kraju kviza, da unajmi program, morali smo otvoriti datoteku,
i onda smo imali za ispis na njega.
U tom slučaju, mi ćemo otvoriti datoteku, a mi ćemo čitati iz njega umjesto.
Onda ćemo ispisati, umjesto u datoteku, idemo za ispis na zaslonu.
Dakle, ispis na ekranu svi ste učinili prije s printf.
Dakle, to nije previše ludo.
No, čitanje datoteke je vrsta čudno.
Mi ćemo proći kroz taj malo na vrijeme.
Ako vi vratiti taj zadnji problema na kvizu, problematičnom 33,
prvi red da ćemo učiniti ovdje, otvaranje datoteka, vrlo slično onome što smo radili tamo.
Dakle, Stella, što se tu liniju izgledati, kada smo otvorili datoteku?
[Stella] Kapital SLIKA *, datoteka - >> Dobro. >> - Je jednaka fopen. >> Yup.
Koja je u ovom slučaju? To je u komentaru.
>> To je u komentaru? argv [i] i R?
>> Točno. Pravo na. Dakle, Stella je totalno u pravu.
To je ono što izgleda kao linija.
Idemo dobiti varijablu datoteke potok, spremite ga u datoteku *, tako da sve kape,
SLIKA, *, a ime ove varijable će biti datoteka.
Mogli bismo ga nazvati ono što smo željeli. Mogli bismo ga nazvati first_file, ili file_i, ono što smo željeli.
I onda ime datoteke je prošao u na naredbenog retka za ovaj program.
Dakle, to je pohranjen u argv [i], a zatim ćemo otvoriti ovu datoteku u modu čitanja.
Sada kada smo otvorili datoteku, što je stvar da uvijek moramo imati na umu da to
kad smo otvorili datoteku? Zatvorite ga.
Dakle, Missy, kako ćemo zatvoriti datoteku?
[Missy] fclose (datoteka) >> fclose (datoteka). Točno.
Izvrsno. Ok. Ako gledamo na to učiniti komentar ovdje,
ona kaže, "Otvoreno argv [i] i ispisati svoje sadržaje na stdout."
>> Standardni out je čudno ime. Stdout je samo naš način da se kaže
želimo ispisati ga na terminal, želimo ga ispisati na standardni izlaz potoka.
Mi zapravo mogu dobiti osloboditi od ovaj komentar ovdje.
Ja ću ga kopirati i zalijepiti jer to je ono što smo učinili.
U ovom trenutku, sada moramo pročitati datoteku malo po malo.
Mi smo razgovarali nekoliko načina čitanja datoteka.
Koje su vaši favoriti dosad?
Koji načini ste vidjeli ili sjećaš, čitati datoteke?
[Daniel] fread? >> Fread? Dakle fread je jedan. Jimmy, znaš li druge?
[Jimmy] No >> Ok. Ne. Charlotte? Alexander? Bilo drugi? Ok.
Dakle, one druge su fgetc, je onaj koji ćemo koristiti puno.
Tu je i fscanf; vi vidite uzorak ovdje?
Oni počinju s f. Sve to učiniti s datotekom.
Tu je fread, fgetc, fscanf. To su sve funkcije čitanja.
Za pisanje imamo fwrite, imamo fputc umjesto fgetc.
Mi također fprintf su željeli smo vidjeli na kvizu.
Budući da je to problem koji uključuje čitanje iz datoteke,
idemo koristiti jednu od ove tri funkcije.
Nećemo koristiti ove funkcije ovdje dolje.
Ove funkcije su svi nalazi u standardnoj I / O knjižnici.
Dakle, ako pogledate na vrhu ovog programa,
možete vidjeti da smo već uključeni u header datoteku za standardni I / O knjižnici.
Ako želimo shvatiti što jednom želimo koristiti,
uvijek možemo otvoriti stranice man.
Tako možemo upisati čovjek stdio
i pročitati sve o stdio ulaznih i izlaznih funkcija u C.
I već možemo vidjeti oh, izgleda. To je spomena fgetc, to je spomenuti fputc.
Dakle, možete izbušiti dolje malo i pogledati, recimo, fgetc
i gledati na čovjeka stranici.
Možete vidjeti da to ide uz cijela hrpa drugih funkcija:
fgetc, fgets, getc, getchar, dobiva, ungetc, a njegov unos znakova i gudače.
Pa to je, kako čitamo u likovima i gudače iz datoteka iz standardnog ulaza,
koji je u suštini od korisnika.
A to je kako ćemo to učiniti u stvarnom C.
Dakle, to ne koristi GetString i getchar funkcije
da smo koristili od CS50 knjižnici.
Mi ćemo učiniti ovaj problem u nekoliko načina
tako da možete vidjeti dva različita načina radi.
Oba fread funkcija da Daniel spominje i fgetc su dobri načine kako to učiniti.
Mislim fgetc je malo lakše, jer ima samo, kao što vidite,
jedan argument, SLIKA * da smo težak za čitanje lik iz,
i njegova povratna vrijednost je int.
I ovo je malo konfuzno, zar ne?
>> Budući da smo uzimajući karakter, pa zašto ne taj povratak char?
Vi imate ideje o tome zašto to ne bi mogli vratiti char?
[Missy odgovori, nerazumljivo] >> Da. Dakle, gospođica je potpuno u pravu.
Ako je ASCII, onda je to cijeli bi se preslikati u stvarni char.
Mogao bi biti ASCII, i to je točno.
To je upravo ono što se događa.
Mi smo pomoću int jednostavno zato što ima više bitova.
To je veći od char; naš char ima samo osam bitova, da jedan bajt na našim 32-bitnim strojevima.
I int ima sve 4 bajta u vrijednosti prostora.
I ispada da način fgetc radi,
ako mi se pomaknite prema dolje u našem sinopsisa u tom čovjeku stranici malo,
pomaknite dokraja. Ispada da su oni koristili ovu posebnu vrijednost pod nazivom EOF.
To je posebno konstanta kao povratnu vrijednost od fgetc funkcije
kad god pogoditi kraj datoteke ili ako dobijete pogrešku.
I ispada da to učiniti ove usporedbe s EOF ispravno,
želite imati taj dodatni iznos od informacija koje imate u int
za razliku od korištenja char varijablu.
Iako fgetc učinkovito dobivanje znaka iz datoteke,
Želite li se sjetiti da je povratak nešto što je tipa int za vas.
To je rekao, to je prilično jednostavan za korištenje.
To će nam dati karakter, tako da sve što morate učiniti je držati molba datoteku,
"Daj mi sljedeći znak, daj mi sljedeći znak, daj mi sljedeći znak"
dok ne dođemo do kraja datoteke.
I da će se povući u jedan lik u isto vrijeme iz naše datoteke,
a onda možemo raditi što god mi se sviđa s njom.
Možemo ga pohraniti, možemo ga dodati na string, možemo ga ispisati.
Učinite nešto od toga.
>> Zumiranje natrag i ide natrag u naše cat.c programa,
ako ćemo koristiti fgetc,
kako bismo mogli pristupiti ovu sljedeću liniju koda?
Mi ćemo koristiti - fread će učiniti nešto malo drugačiji.
I ovaj put, samo mi ćemo koristiti fgetc dobiti jedan lik u isto vrijeme.
Za obradu cijelu sliku, što bismo mogli učiniti?
Koliko likovi postoje u datoteci?
Postoji puno. Dakle, vjerojatno želite dobiti jedan
i onda se još i dobiti još i dobiti drugi.
Kakav algoritma misliš da možda ćete morati koristiti ovdje?
Koji tip -? [Aleksandar] za petlje? >> Točno.
Neki tip petlje.
For petlja je zapravo super, u ovom slučaju.
I kao što ste rekli, to zvuči kao da želite petlju nad cijelom datotekom,
uzimajući lik u isto vrijeme.
Bilo koji sugestija o tome što bi moglo izgledati?
[Alexander, nerazumljivo]
>> Ok, samo mi reci na engleskom jeziku što pokušavaš učiniti? [Alexander, nerazumljivo]
Dakle, u ovom slučaju, to zvuči kao da smo samo pokušavamo petlji preko cijele datoteke.
[Aleksandar] Pa ja > Veličina -?
Valjda veličinu datoteke, zar ne? Veličina - hrapavi samo napisati ovako.
Veličina datoteke za sada, ja + +.
Tako ispada da je način na koji to učiniti koristeći fgetc, a to je nova,
je da ne postoji jednostavan način da samo dobiti veličinu datoteke
s ovim "sizeof" tipa konstruirati da ste vidjeli prije.
Kada smo koristiti taj fgetc funkciju, uvodimo neke vrste
nova, funky sintaksa bi to za petlje, gdje se umjesto koristeći samo osnovnu brojač
ići slovo po slovo, idemo izvući jedan lik u isto vrijeme,
jedan lik u isto vrijeme, i način na koji znamo da smo na kraju
ne kad smo broje određeni broj znakova,
ali kad lik mi izvadi je da se posebna kraj datoteke karaktera.
Dakle, možemo to učiniti - Ja ovaj ch, a mi ćemo ga inicijalizirati
s našeg prvog poziva da se prvi znak iz datoteke.
Dakle, ovaj dio ovdje, ovo će dobiti lik iz datoteke
i pohraniti u varijablu ch.
Mi ćemo zadržati to dok ne dođemo do kraja datoteke,
koje smo učiniti testiranje na lik ne bude jednak toj posebnoj EOF karaktera.
I onda, umjesto da radiš ch + +, koji bi samo povećajte vrijednost,
pa ako čitamo A iz spisa, kapitala, kažu,
ch + + će nam dati b, a zatim bismo dobili C i zatim d.
To je očito nije ono što želimo. Ono što želimo ovdje
u ovom posljednjem malo se želimo dobiti sljedeći znak iz datoteke.
>> Dakle, kako bismo mogli dobiti sljedeći lik iz spisa?
Kako smo dobili prvi znak iz datoteke?
[Studentski] fgetfile? >> Fgetc, ili, žao mi je, da si potpuno u pravu.
Ja ga pogrešno tamo. Pa da.
Ovdje umjesto da radiš ch + +,
mi smo samo ide na poziv fgetc (file) ponovno
i pohraniti rezultat u našoj istoj ch varijable.
[Studentski pitanje, nerazumljivo]
>> Ovo je mjesto gdje ti SLIKA * dečki su posebna.
Način oni rade je da - kad ste prvi put otvorili - kada se prvi put napraviti taj fopen poziv,
datoteku * učinkovito služi kao pokazivač na početku datoteke.
I onda svaki put kad poziv fgetc, ona kreće jedan lik kroz datoteku.
Dakle, kad god to zovu, ti si povećavanjem datoteke pokazivač po jedan karakter.
A kada fgetc opet, znači da se krećete na drugi lik
a drugi lik, a drugi lik, a drugi lik.
[Studentski pitanje, nerazumljivo] >> I that's - da.
To je vrsta ove magije ispod haube.
Vi samo držati povećavanjem putem.
U ovom trenutku, vi ste u mogućnosti da zapravo rade s karakterom.
Dakle, kako bismo mogli ispisati ovo na ekranu, sada?
Možemo koristiti isti printf stvar da smo koristili prije.
To smo koristili sve semestar.
Možemo to nazvati printf,
i možemo proći u liku baš kao da je.
Drugi način da to učinite je radije nego da koristite printf i što učiniti ovaj format string,
možemo koristiti jednu od druge funkcije.
Možemo koristiti fputc, koji ispisuje karakter na zaslonu,
osim ako gledamo fputc - neka me udaljili malo.
Mi vidimo ono što je lijepo je to potrebno u znak da smo očitati pomoću fgetc,
ali onda moramo mu dati struju za ispis na.
Mi također može koristiti Putchar funkciju, koja će se staviti izravno na standardne van.
Dakle, postoje cijela hrpa različitih opcija koje možemo koristiti za ispis.
Oni su svi u standardnoj I / O knjižnici.
Kad god želite ispisati - tako printf, po defaultu, ispisati će se posebnom standardu iz potoka,
što je to stdout.
Dakle, mi samo može odnositi na njega kao vrsta ovog čarobnog vrijednosti, stdout ovdje.
Ups. Stavite zarez izvan.
>> To je puno novih, funky informacija ovdje.
Puno toga je vrlo idiomatski, u smislu da je to kod
koja je napisana na ovaj način samo zato što je čista čitati, jednostavan za čitanje.
Postoji mnogo različitih načina kako to učiniti, mnoge različite funkcije koje možete koristiti,
ali mi imaju tendenciju da slijedite ove iste obrasce iznova i iznova.
Dakle, nemojte se iznenaditi ako vidite kod ovako dolaze opet i opet.
U redu. U ovom trenutku, moramo razbiti za taj dan.
Hvala za dolazak. Hvala za gledanje, ako ste online. A mi ćemo vas vidjeti sljedeći tjedan.
[CS50.TV]