[Powered by Google Translate] [ODDIEL 5: menej komfortné]
[Nate Hardison, Harvard University]
[To je CS50.] [CS50.TV]
Tak vitaj späť, chlapci.
Vitajte v sekcii 5.
V tomto bode, mať dokončil kvíz 0 a keď bola svedkom, ako si urobil,
dúfajme, že budete cítiť naozaj dobre, pretože som bol veľmi zaujatý skóre v tejto sekcii.
Pre naše on-line divákov, mali sme pár otázok
o posledných dvoch problémov na problém súboru - alebo na teste, ale.
Takže sme ísť cez tie naozaj rýchlo, takže každý vidí, čo sa stalo
a ako prejsť skutočné riešenie, skôr než len prezeranie riešenie sám.
Budeme ísť za posledných pár problémov naozaj rýchlo, 32 a 33.
Len, znova, aby bolo možné v elektronickej diváci vidieť.
>> Ak sa obrátite na vášho problému 32, ktorý je na strane 13,
13 z 16, problém 32 je o swapov.
Bolo to všetko o výmene dve celé čísla.
Je to problém, ktorý sme si už za pár časov v prednáške.
A tu, čo sme sa pýtali vás urobiť, je rýchlo pamäťová stopa.
Ak chcete vyplniť v hodnotách premenných tak, ako sú vo fronte
ako kód prechádza týmto odkladacie funkciu.
Najmä, čo sa pozeráme na - Idem dať túto iPad dole -
najmä, čo sa pozeráme na to je rada číslované 6 práve tu.
A to očíslované 6 len za kontinuitu s predchádzajúcim problémom.
To, čo chceme urobiť, je zobraziť alebo označiť stav pamäte
ako je to v čase, keď sa vykonanie tohto riadku číslo 6,
ktorý je účinne návrate z našej odkladacie funkciu tu.
Ak by sme posunúť dole tu, sme videli, že adresy všetko v pamäti bola poskytnutá pre nás.
To je veľmi kľúčový, budeme sa k nej vráti za chvíľu.
A potom tu dole na dne, sme mali trochu pamäti diagram, ktorý budeme odkazovať.
Som vlastne urobil sa na mojej Prípade.
Takže budem striedať tam a späť medzi iPad a tento kód len pre referenciu.
>> Poďme začať. Po prvé, poďme zamerať na prvých pár riadkov hlavného tady.
Ak chcete začať, budeme inicializovať x na 1 a Y 2.
Takže máme dve celočíselné premenné, oni obaja bude umiestnený na zásobníku.
Budeme dať 1 a 2 v nich.
Takže keď som otočiť k môjmu iPad, dúfajme, uvidíme -
Apple TV zrkadlenie, a tam ideme. Dobre.
Takže keď som otočiť k môjmu iPad,
Chcem inicializovať x na 1 a Y 2.
Robíme to jednoducho tým, že píše 1 do poľa označeného x
a 2 v poli označené y. Pomerne jednoduché.
Takže teraz sa vráťme k notebooku, uvidíme, čo sa bude diať ďalej.
Takže to ďalší riadok je miesto, kde sa veci zložitejšie.
Míňame adresu X a adresu y ako parametre a a b na odkladaciu funkciu.
Sídlo x a adresou y sú veci, ktoré nemôžeme vypočítať
bez odkázal na tieto bodoch tu dole.
A našťastie, prvé dve zarážky nám presne to, čo sú odpovede.
Sídlo x v pamäti je 10, a adresa y v pamäti je 14.
Takže to sú hodnoty, ktoré sa dostanú odovzdaná ako a, b až hore v našej virtuálnej funkcie.
Takže znova, prepnutie späť do nášho schémy, môžem napísať 10 v
a 14 v b.
Teraz, tento bod je miesto, kde budeme pokračovať s swapu.
Tak obracející späť k prenosnému počítaču znova,
vidíme, že spôsob, akým swap funguje, je som sa prvýkrát dereferencia a obchod výsledok v tmp.
Takže dereferencia operátor hovorí, "Hey. Doprajte obsah premenné ako adresa.
Prejsť na všetko, čo je uložené na tejto adrese, a tak ho nahrá. "
Čo načítať z premennej sa bude uložený do nášho tmp premennej.
Prehodiť späť na iPad.
Ak pôjdeme k riešeniu 10, vieme, že adresa 10 je premenná x
pretože nám bolo povedané, náš zarážky, že adresa x v pamäti je 10.
Takže môžeme ísť tam, získať hodnotu toho, ktorý je 1, ako ich vidíme na našej iPad,
a nahrať to do tmp.
Opäť, toto nie je konečné obsah.
Budeme prechádzať a my Vás budeme do nášho konečného stavu programu na konci.
Ale teraz, máme hodnotu 1 uložené v tmp.
>> A je tu rýchly dotaz tu.
[Alexander] Je dereferencia prevádzkovateľ - to je len hviezda priamo pred premenné?
Áno >>. Takže dereferencia prevádzkovateľ, ako sme otočiť späť do nášho notebooku znovu,
Je to hviezda priamo pred hotelom.
V tomto zmysle, to je - kontrastovať s operátorom násobenie
ktoré si vyžaduje dve veci, dereferencia operátor je unární operátor.
Len aplikovaný na jednej hodnoty na rozdiel od binárneho operátora,
kde sa vzťahujú na dvoch rôznych hodnôt.
Takže to je to, čo sa deje v tomto riadku.
Naložili sme hodnotu 1 a uložené do našej dočasnej celočíselné premenné.
Na ďalší riadok, uložíme obsah B do -
alebo skôr, uložíme obsah, ktorý b ukazuje na do miesta, kde sa ukazuje.
Analyzujeme Ak tento sprava doľava, budeme dereferencia b,
budeme riešiť 14, budeme chytiť celé číslo, ktoré je tam,
a potom sme sa ísť na adresu 10,
a budeme hádzať výsledok našej dereferencia z B do tohto priestoru.
Prehodiť späť k nášmu iPad, kde môžeme urobiť to trochu konkrétnejšie,
to by mohlo pomôcť, keď napíšem čísla na všetky adresy tu.
Takže vieme, že v y, sme na adrese 14, x je na adrese 10.
Keď začneme u b, sme dereferencia b, budeme chytiť hodnotu 2.
Budeme sa chytiť túto hodnotu, pretože to je hodnota, ktorá žije na adrese 14.
A budeme dávať to do premennej, ktorá žije na adrese 10,
ktorý je tu, zodpovedajúce našim premennej x.
Takže môžeme urobiť trochu prepísanie tu
kde sme sa zbaviť nášho 1 a namiesto toho sme napísať 2.
Takže všetko je v poriadku a dobre na svete, aj keď máme prepisované X teraz.
Máme uložené x starú hodnotu v našom tmp premennej.
Takže môžeme dokončiť swapu s ďalším riadkom.
Prehodiť späť k nášmu notebooku.
Teraz všetko, čo zostáva, je, aby sa obsah z nášho dočasného celočíselné premenné
a uložiť ich do premennej, ktorá žije na adresu, ktorá b drží.
Takže budeme účinne dereferencia b získať prístup k premennej
, Ktorý je na adrese, b drží v ňom,
a budeme napchať hodnotu, ktorá tmp drží do neho.
Prehodiť späť na iPad ešte raz.
Môžem vymazať túto hodnotu tu, 2,
a namiesto toho budeme kopírovať 1 právo do neho.
Potom ďalší riadok, ktorý vykonáva, samozrejme -
ak by sme otočiť späť do notebooku - je to bod 6,
čo je bod, v ktorom sme chceli, aby naša schéma úplne vyplnené.
Tak mizerný späť na iPad ešte raz, len tak môžete vidieť dokončenú diagram,
môžete vidieť, že máme 10 v, 14 v B, 1 vo tmp, 2 v X, a 1 v y.
Sú nejaké otázky ohľadom tohto?
Dáva to väčší zmysel, keď išiel cez neho?
Urobte menší zmysel? Dúfajme, že nie. Dobre.
>> Ukazovatele sú veľmi zradné tému.
Jeden z chalanov, s ktorými spolupracujeme má veľmi časté príslovie:
"Aby sme pochopili ukazovatele, musíte najprv pochopiť ukazovatele."
Čo myslím, že je to pravda. To robí to chvíľu trvať zvyknúť si na to.
Kreslenie veľa obrázkov, losovanie pamäťových diagramov, ako je tento sú veľmi užitočné,
a potom, čo prejdete napríklad po napríklad po príklade,
to začnem robiť niečo väčší zmysel a trochu viac rozum a trochu väčší zmysel.
A konečne, jeden deň, budete mať všetko úplne zvládol.
Akékoľvek otázky skôr než prejdeme k ďalšiemu problému? Dobrá.
Takže otočiť späť do notebooku.
Ďalší problém, ktorý máme, je problém číslo 33 na súbor I / O.
Zväčšenie na tomto trochu.
Problém 33 - Áno?
>> [Daniel] som mal rýchlu otázku. Táto hviezda, alebo hviezdička,
je to tzv dereferencing pri použití hviezdičku pred.
Ako sa to volá, keď použijete ampersand predtým?
>> Znak ampersand skôr, než je adresa-prevádzkovateľa.
Takže poďme sa posunúť späť.
Chybička sa vlúdila. Som v režime zoom, takže nemôžem naozaj scroll.
Ak sa pozrieme na tento kód naozaj rýchlo priamo tu,
znovu, to isté sa deje.
Ak sa pozrieme na tento kód priamo tu, na tomto riadku, kde robíme volanie vymeniť,
ampersand len hovorí "dostať adresu, na ktorej premennej x životy."
Keď váš kompilátor kompiluje kód,
má skutočne fyzicky vytýčiť miesto v pamäti pre všetky vaše premenných žijú.
A tak to, čo kompilátor potom môže robiť, keď je to všetko zostavený,
to vie, "Oh, som dal x na adrese 10. som dal Y na adrese 14."
To potom môže vyplniť tieto hodnoty pre vás.
Takže si potom môžete - to potom odovzdať to v priechode a & y v i
Títo chalani si adresu, ale tiež, keď je odovzdávať do odkladacej funkcie,
tento typ informácií, to int * tu, hovorí kompilátora,
"Dobre, budeme sa výkladu túto adresu ako adresu celočíselné premenné."
Ako adresu int, ktorá je odlišná od adresy premennej znak
pretože int zaberá, na 32-bit stroje, zaberá 4 bajty priestoru,
vzhľadom k tomu, postava iba preberá 1 bajt priestoru.
Takže je to dôležité vedieť aj to, čo je - to, čo žije, aký typ hodnoty
žije na adresu, ktorú dostal prešla dovnútra
Alebo adresu, ktorú čo do činenia.
Tak, viete, koľko bytov informácií skutočne načítať z pamäte RAM.
A potom, áno, to dereferencia operátor, ako vy ste sa pýtal,
ide a pristupuje k informáciám na konkrétnu adresu.
Tak to hovorí, s týmto premennou tu, liečiť obsah ako adresa,
prejsť na túto adresu, a vytiahnuť, vložte do procesora, zaťaženie do registra
skutočné hodnoty alebo obsah, ktoré žijú na tejto adrese.
Nejaké ďalšie otázky? To sú dobré otázky.
Je to veľa novej terminológie príliš.
Je to tiež trochu funky, vidieť a a * na rôznych miestach.
>> Dobrá.
Takže späť k problému 33, súbor I / O.
To bol jeden z tých problémov, ktoré si myslím, že pár vecí sa stalo.
Jeden, že je to celkom novú tému.
To bol predložený čoskoro pred kvízu,
a potom som, že to bolo niečo ako jeden z tých slovných úloh v matematike
kde vám veľa informácií, ale v skutočnosti nechcete skončiť museli použiť veľa nej.
Prvá časť tohto problému popisuje, čo súbor CSV je.
Teraz, súbor CSV, podľa popisu, je oddelený čiarkami hodnoty súboru.
Dôvodom sú vôbec zaujímavé, a dôvod, prečo ste niekedy použiť,
je, pretože, ako mnohí z vás niekedy používajú veci, ako je Excel?
Obrázok väčšina z vás, pravdepodobne bude alebo použitie pri určitom okamihu svojho života.
Budete používať niečo ako Excel.
S cieľom získať dáta z tabuľky programu Excel alebo robiť nejaký druh spracovania s ním,
ak by ste chceli napísať program v jazyku C alebo Python program, Java programu,
vysporiadať sa s dátami ste uložili tam,
jedným z najčastejších spôsobov, ako dostať to je v súbore CSV.
A môžete otvoriť Excel a keď idete na "Uložiť ako" dialóg,
sa môžete dostať von skutočný súbor CSV.
>> Handy vedieť, ako sa vysporiadať s týmito vecami.
Spôsob, akým to funguje tak, že je to podobné - myslím, že to v podstate napodobňovanie tabuľky,
kde, ako vidíme tu, vo veľmi najviac naľavo kus,
máme všetky posledné názvy.
Takže máme Malan, potom Hardison, a potom Bowden, MacWilliam, a potom Chan.
Všetky posledné mená. A potom čiarka oddeľuje priezvisko z krstných mien.
David, Nate, Rob, Tommy, a Zamyla.
Vždy som zmiešať Robby a Toma.
A potom, konečne, tretí stĺpec e-mailovej adresy.
Akonáhle pochopíte, že zvyšok programu je pomerne jednoduché implementovať.
Čo sme urobili, aby sa napodobniť rovnaký štruktúru v našom programe C
je, že sme použili štruktúru.
Začneme hrať s nimi trochu viac rovnako.
Videli sme ich na prvý trochu v problému sade 3, keď sme boli zaoberajúca sa slovníky.
Ale tento personál struct ukladá priezvisko, krstné meno, a e-mail.
Rovnako ako náš súbor CSV bol skladovanie.
Takže je to len konverzia z jedného formátu do druhého.
Máme previesť, v tomto prípade, je personál struct do linky,
oddelený čiarkami line, rovnako ako to.
Dáva to zmysel? Vy všetci vziať kvíz,
tak som si predstaviť, že máte aspoň nejaký čas na premýšľanie o tom.
>> V prenájmu funkciu, problém nás žiada, aby sme sa v - Dáme snímke v tomto trochu -
sa v personálu štruktúry, personálu struct, s meno s,
a pripojiť jeho obsah do nášho súboru staff.csv.
Ukazuje sa, že toto je pomerne jednoduchá na použitie.
Budeme trochu pohrať s týmito funkciami trochu viac dnes.
Avšak v tomto prípade, je fprintf funkcia je skutočne kľúčom.
Takže s fprintf, môžeme tlačiť, rovnako ako vy boli pomocou printf celý tento termín.
Môžete printf riadok do súboru.
Takže namiesto toho, aby jednoducho robiť obvyklé printf hovor, kde si dať formátovací reťazec
a potom nahradiť všetky premenné s nasledujúcimi tvrdeniami,
s fprintf, vaše prvé tvrdenie je miesto toho súbor, ktorý chcete napísať.
Ak by sme sa pozreli na to v zariadení, napríklad, človek fprintf,
môžeme vidieť rozdiel medzi printf a fprintf.
Budem priblížiť tu trochu.
Takže s printf, dáme formátovací reťazec, a potom nasledujúce argumenty
sú všetky premenné pre výmenu alebo nahradenie do nášho formátu reťazca.
Vzhľadom k tomu, s fprintf, prvý argument je skutočne tento súbor * nazýva potok.
>> Presun späť sem do nášho prenájmu,
sme už dostali náš súbor * otvorený stream pre nás.
To je to, čo tento prvý linka robí, že otvorí súbor staff.csv,
sa otvorí v režime append, a všetko, čo zostalo pre nás urobiť, je
napísať zamestnancov štruktúru do súboru.
A uvidíme, nechcem používať iPad?
Budem používať iPad. Máme za neplatné - poďme dať to na stôl, takže môžem napísať trochu lepšie -
neplatnosť kolies a trvá do jedného argumentu, má personál štruktúru nazvanú s
Mám naše rovnátka, máme náš súbor * s názvom súboru,
máme fopen linku ktoré ste nám poskytli,
a ja budem len písať ako bodky, pretože je už v pedia.
A potom na naše ďalšie riadok, ak budeme volať do fprintf
a budeme prechádzať v súbore, ktorý chceme tlačiť,
a potom sa naše formátovací reťazec, ktorý -
Nechám ste mi povedať, ako to vyzerá.
Ako o vás, Stella? Viete, čo je prvá časť formátovacieho reťazca vyzerá?
[Stella] Nie som si istý. >> Nebojte sa opýtať na Jimmyho.
Viete, Jimmy?
[Jimmy] Bolo by to jednoducho byť posledný? Neviem. Nie som si úplne istý.
Dobre >>. Ako o tom, to niekto si to správne na skúšku?
Nie poriadku.
Ukazuje sa, že tu všetko, čo musíme urobiť, je chceme každú časť nášho personálu štruktúry
ktoré majú byť vytlačené ako reťazec do nášho súboru.
Práve sme použiť reťazec substitučná znaku tri rôzne časy, pretože máme priezvisko
nasleduje čiarka, potom meno nasledovaný čiarkou,
a potom konečne adresa, ktorá nasleduje - čo nie je
montáž na mojej obrazovke - ale je to nasleduje znakom nového riadku.
Takže budem písať to len tam.
A potom po našej formátovací reťazec,
jednoducho majú náhrady, ktoré sme prístup pomocou bodkovaný notácie
ktorú sme videli v problému sade 3.
Môžeme použiť s.last, s.first, a s.email
nahradiť v týchto troch hodnôt do nášho formátovacieho reťazca.
Tak ako to išlo? Zmysel?
Áno? Nie? Možno? Dobre.
>> Posledná vec, že ​​my potom, čo sme vytlačiť a potom, čo sme otvorili našu súbor:
keď sme otvorili súbor, musíme vždy pamätať na jeho zatvorenie.
Pretože inak skončíme úniku pamäte,
použitie sa deskriptory súborov.
Takže zatvorte ho, ktoré funkcie budeme používať? Daniel?
[Daniel] fclose? >> Fclose, presne.
Takže posledná časť tohto problému bolo riadne zatvorte súbor, pomocou fclose funkcie,
ktorý práve vyzerá.
Nie je príliš šialené.
Cool.
Tak to je problém 33 o teste.
Budeme mať určite väčší súbor I / O prísť.
Urobíme trochu viac v prednáške dnes, alebo v sekcii dnes,
pretože to je to, čo sa deje tvoriť časť tejto nadchádzajúcej PSet.
Poďme ďalej od testu v tomto bode. Áno?
>> [Charlotte]] Prečo fclose (súbor) miesto fclose (staff.csv)?
>> Ah. Vzhľadom k tomu, že sa ukáže, že - tak otázka, ktorá je veľký,
je dôvod, prečo, keď píšeme fclose, píšeme fclose (súbor) star premennú
na rozdiel od názvu súboru, staff.csv? Je to správne? Jo.
Takže poďme sa pozrieť. Ak by som prejsť späť na mojom notebooku,
a poďme sa pozrieť na fclose funkciu.
Takže fclose funkcie uzatvára prúd a trvá na ukazovateľ na prúde, ktorý chceme uzavrieť,
na rozdiel od skutočného názvu súboru, ktorý chceme uzavrieť.
A to je preto, že v zákulisí, keď urobíte volanie fopen,
keď si otvoríte súbor, ste vlastne prideľovanie pamäte pre ukladanie informácií o súbore.
Takže máte súbor ukazovateľ, ktorý má informácie o súbore,
ako je to otvorené, jeho veľkosť, kde sa v súčasnosti v súbore,
takže si môžete urobiť čítanie a písanie volaní daného miesta v súbore.
Môžete skončiť uzavretím ukazovateľ namiesto uzavretia názov súboru.
>> Áno? [Daniel] Tak aby bolo možné používať prenájom, povedali by ste - ako to dostať užívateľský vstup?
Má fprintf správať ako GetString v tom zmysle, že to bude len čakať na vstup od používateľa
a požiadať, aby ste zadajte tento - alebo počkať na zadanie tieto tri veci?
Alebo potrebujete použiť niečo realizovať prenájom?
Jo >>. Takže nie sme - otázka bola, ako sa dostať vstup od používateľa
za účelom vykonania nájom? A to, čo tu máme, je volajúci o prenájme,
prešla v tomto pracovníkov struct so všetkými z dát uložených v struct už.
Takže fprintf je schopný len napísať, že dáta priamo do súboru.
Nie je potrebné čakať na vstup od užívateľa.
Užívateľ je už daná vstup riadne vložením do tohto zamestnanca struct.
A veci, samozrejme, by rozbiť, ak niektorý z týchto ukazovateľov boli null,
tak sme sa posunúť späť a my pozrieť na našu struct.
Máme reťazec naposledy, string prvý, string email.
Teraz vieme, že všetci tí, naozaj, pod kapotou, sú char * premenné.
To môže alebo nemusí byť nasmerovaná na null.
Môžu smerovať do pamäte na halde,
Možno pamäť na zásobníku.
My naozaj nevieme, ale ak niektorý z týchto ukazovateľov sú null, alebo neplatné,
že to určite havárii naša požičovňa funkciu.
To bolo niečo, čo bolo trochu nad rámec skúšky.
Nie sme starosti, že.
Great. Dobre. Takže sa presunul od kvízu.
>> Poďme zavrieť toho chlapa, a budeme sa pozerať na PSet 4.
Takže ak ste sa pozrieť na spec PSet, akonáhle k nemu máte prístup, cs50.net/quizzes,
sme ísť cez niekoľko sekcií problémov dnes.
Ja rolovanie dole - časť otázok začína na tretej strane PSet špec.
A prvá časť vás požiada ísť a pozerať sa na krátky na presmerovanie a potrubí.
Čo bolo docela v pohode krátky, zobrazí niekoľko nových cool triky príkazového riadku, ktoré môžete použiť.
A potom máme niekoľko otázok pre vás rovnako.
Táto prvá otázka prúdy, ktoré printf píše v predvolenom nastavení,
sme trochu dotkli len trochu pred chvíľou.
To fprintf, že sme práve diskutovali berie v prúde súboru * ako jeho argument.
fclose berie v prúde súboru * i,
a návratová hodnota funkcie fopen vám súboru * prúd rovnako.
Dôvod, prečo sme nevideli tie predtým, keď sme sa zaoberal printf
Je tomu tak preto printf má predvolenú prúd.
A predvolené prúd, na ktoré sa píše
zistíš asi v krátkej.
Takže určite sa na neho pozrieť.
>> V dnešnej časti budeme hovoriť trochu o GDB,
od viac ste oboznámení s tým, viac praxe dostanete s ním,
lepšie schopný budete skutočne stopovať chyby vo vašom vlastnom kódu.
To urýchľuje proces ladenia hore ohromne.
Takže pomocou printf, zakaždým, keď to, že budete musieť rekompilovat kód,
budete musieť spustiť znova, niekedy budete musieť presunúť printf hovor okolo,
komentár mimo kód, zaberie to len chvíľku.
Naším cieľom je pokúsiť sa presvedčiť, že s GDB, môžete v podstate
printf niečo na ľubovoľnom mieste v kóde a už nikdy nebudete musieť prekompilovať ho.
Už nikdy nebudete musieť začať a udržať hádať, kde printf ďalšie.
Prvá vec, ktorú musíte urobiť, je skopírovať tento riadok a získať časť kódu preč webu.
Som kopírovanie tento riadok kódu, ktorý hovorí, "wget ​​http://cdn.cs50.net".
Budem ho kopírovať.
Chystám sa ísť na moju spotrebiče, oddialenie, takže môžete vidieť, čo robím,
vložiť to tam, a keď som stlačte klávesu Enter, táto wget príkaz doslova je web dostať.
Bude to búrať tento súbor preč na internete,
a bude to uložiť do aktuálneho adresára.
Teraz, keď som zoznam svoju aktuálnu adresár môžete vidieť, že som dostal túto section5.zip súbor priamo tam.
Spôsob, ako sa s tým vysporiadať chlap je rozbaliť ho,
ktoré môžete urobiť v príkazovom riadku, rovnako ako to.
Section5.zip.
To bude rozbaľte ho, vytvorte zložku pre mňa,
nafúknuť všetok obsah, dal ich tam.
Takže teraz môžem ísť do môjho sekcie 5 adresára pomocou príkazu cd.
Zrušte obrazovku pomocou jasné. Takže vyčistiť obrazovku.
Teraz mám pekný čistý terminál riešiť.
>> Teraz, keď som vypísať všetky súbory, ktoré vidím v tomto adresári,
vidíte, že mám štyri súbory: buggy1, buggy2, buggy3, a buggy4.
Ja som tiež dostal svoje zodpovedajúce. C súbory.
Nebudeme sa pozerať na. Súbory C pre túto chvíľu.
Namiesto toho, budeme používať je, keď sme sa otvoriť GDB.
Sme držali je asi tak, že máme prístup k aktuálne zdrojový kód, keď sme pomocou GDB,
ale cieľom tejto časti sekcie je pohrať si s GDB
a uvidíte, ako môžeme použiť zistiť, čo sa deje zle s každou z týchto štyroch kočíka programov.
Takže sme len tak po izbe naozaj rýchlo,
a budem sa opýtať niekoho spustiť jednu z kočíka programov,
a potom pôjdeme ako skupina prostredníctvom GDB, a uvidíme, čo môžeme urobiť pre to opraviť tieto programy,
alebo aspoň zistiť, čo sa deje zle v každej z nich.
Poďme začať znovu tu s Danielom. Spustíme buggy1? Poďme sa pozrieť, čo sa stane.
[Daniel] To hovorí, že je to chyba aplikácie. Jo >>. Presne tak.
Takže, keď spustím buggy1, dostanem seg poruchu.
V tomto bode, som mohol ísť a otvoriť buggy1.c,
vyskúšať a zistiť, čo sa deje zle,
ale jeden z najviac nepríjemnými vecí na tomto seg poruchy chybe
je to, že nemôžem povedať o tom, čo mnohé z programových vecí skutočne pokazilo a zlomil.
Tak nejako sa pozrieť na kód
a zistiť pomocou odhad a kontrolu alebo printf vidieť, čo sa deje zle.
Jedna z najlepších vecí, o GDB je, že je to naozaj, ale naozaj jednoduché
prísť na to, riadok, v ktorom váš program zrúti.
Je to absolútne stojí za to ju používať, aj keď len na to.
Takže naštartovať GDB, som typ GDB, a potom som jej dávajú cestu k spustiteľného súboru, ktorý chcem spustiť.
Tu píšem gdb ./buggy1.
Stlačte Enter. Dáva mi to všetko informácie o autorských právach,
a tu uvidíte tento riadok, ktorý hovorí, "Čítanie symbolov z / home /
jharvard/section5/buggy1. "
A ak všetko pôjde dobre, uvidíte, že vytlačiť správu, ktorá vyzerá takto.
Bude to čítať symboly, bude to hovoriť "Ja čítam symboly z vášho spustiteľného súboru,"
a potom to bude mať tento "Hotovo" správa tu.
Ak vidíte iný variant tohto, alebo vidíte, že sa nepodarilo nájsť symboly
alebo niečo také, čo to znamená, je to, že ste práve neboli pripravené na spustiteľný správne.
Keď sme kompilovať programy pre použitie s GDB, musíme použiť túto špeciálnu g vlajkou,
a že sa to robí v predvolenom nastavení, ak si skompilovať vaše programy, jednoduchým zadaním, aby
alebo si kočík alebo sa zotaviť, každý z nich.
Ale ak ste kompilácie ručne s Clang, potom budete musieť ísť a patrí to-g vlajkou.
>> V tomto bode, teraz, keď máme GDB riadku,
je to celkom jednoduché spustiť program.
Môžeme buď zadať beh, alebo môžeme len typ R.
Väčšina gdb príkazy môžu byť skrátené.
Obvykle len na jednej alebo niekoľkých písmen, čo je docela pekné.
Takže Saad, ak zadáte r a stlačte klávesu Enter, čo sa stane?
[Saad] Mám SIGSEGV, Segmentation fault, a potom to všetko hatmatilka.
Jo >>.
Rovnako ako vidíme na obrazovke práve teraz, a ako Saad povedal,
keď napíšeme beh alebo r a stlačte klávesu Enter, stále s rovnakou seg poruchu.
Takže pomocou GDB nie je vyriešiť náš problém.
Ale to nám dáva určité hatmatilka, a ukázalo sa, že to hatmatilka
vlastne nám hovorí, kde sa to deje.
Ak chcete analyzovať tento trochu, tento prvý bit je funkcia, v ktorej všetko zle.
Tam je to __ strcmp_sse4_2, a to nám hovorí, že sa to deje v tomto súbore
volal sysdeps/i386, to všetko opäť trochu neporiadok - ale linka 254.
To je trochu ťažké analyzovať. Zvyčajne, keď vidíte veci, ako je tento,
to znamená, že je to seg chyba v jednom z knižnice systému.
Takže niečo do činenia s strcmp. Vy ste videl strcmp skôr.
Nie je príliš bláznivé, ale znamená to, že strcmp je rozbité, alebo že je tu problém s strcmp?
Čo si myslíte, Alexander?
[Alexander] Je to - je 254 riadok? A - nie binárne, ale nie je to ich stropy,
a potom je tu iný jazyk pre každú funkciu. Je to 254 v tejto funkcii, alebo -?
>> Je to linka 254. Vyzerá to, že v tomto súbore. S., tak to je kód assembleri pravdepodobne.
>> Ale myslím, že naliehavejšie vec je, pretože sme dostali seg poruchu,
a vyzerá to, že to prichádza z strcmp funkcie,
to neznamená, potom, je zle, že strcmp?
To by nemalo, snáď. Takže len preto, že máte Segmentation fault
v jednej z funkcií systému, zvyčajne to znamená, že ste práve Nevolal správne.
Najrýchlejší vec urobiť, aby zistili, čo sa vlastne deje
keď vidíte niečo šialeného, ​​ako to, keď vidíte seg poruchu,
najmä ak máte program, ktorý je pomocou viac než len hlavné,
je použiť backtrace.
Aj skrátiť backtrace písaním BT, ako protichodný k plnému backtrace slovo.
Ale Charlotte, čo sa stane, keď zadáte BT a stlačte klávesu Enter?
[Charlotte] Ukazuje mi dva riadky, riadok 0 a 1. riadok.
Jo >>. Takže riadok 0 a 1. riadok.
Jedná sa o skutočné zásobníka zábery, ktoré sa v súčasnej dobe v hre, keď váš program havaroval.
Počnúc najvyššej rámu, rámu 0, a bude k najspodnejšej, ktorá je rám 1.
Naša najvyššia rám je strcmp rámu.
Môžete myslieť na to, ako podobný k tomuto problému sme robili len to, na teste s ukazovateľmi,
kde sme vymeniť zásobník rám na hornej časti hlavného zásobníka rámu,
a my sme museli premenné tak, že prehodí sa pomocou na vrchole premenných, že hlavné je používať.
Tu naše crash stalo v našej strcmp funkcie, ktoré sa hovorilo o našej hlavnou funkciou,
a backtrace nám dáva nielen funkcie, v ktorých veci zlyhala,
ale je to tiež nám hovorí, kde bolo všetko len z
Takže ak som prejdite trochu viac vpravo,
môžeme vidieť, že jo, my sme boli na linke 254 tohto strcmp-sse4.s súboru.
Ale hovor bol robený na buggy1.c, riadok 6.
Takže to znamená, že môžeme urobiť - je, že sme si jednoducho ísť pozrieť a zistiť, čo sa deje
na buggy1.c, riadok 6.
Opäť, existuje niekoľko spôsobov, ako to urobiť. Jedným z nich je ukončenie z GDB
alebo mať váš kód otvorí v inom okne a cross referencie.
To samo o sebe, je celkom užitočné, pretože teraz, keď ste na úradných hodín
a máte seg poruchu a vaše TF sa divila, kde všetko bolo porušenie,
stačí povedať, "Oh, linka 6. Neviem, čo sa deje,
ale niečo riadku 6 je príčinou môj program prerušiť. "
Iný spôsob, ako to urobiť, je, môžete použiť tento príkaz s názvom zoznam v GDB.
Môžete tiež skrátiť s l
Takže ak sme narazili l, čo sme sa sem dostali?
Dostávame veľa podivné veci.
To je skutočná zostava kód
že je v strcmp_sse4_2.
To vyzerá druh funky,
a dôvod, prečo sme stále je to preto, že práve teraz,
GDB má nás v ráme 0.
>> Takže kedykoľvek sa pozrieme na premenné, kedykoľvek sa pozrieme na zdrojový kód,
pozeráme zdrojového kódu, ktorý sa vzťahuje k zásobníku rámu sme práve nachádzate
Tak, aby si niečo zmysluplného, ​​musíme
prejsť na zásobníku rámu, ktorý dáva väčší zmysel.
V tomto prípade by hlavný zásobník rám, aby trochu väčší zmysel,
pretože to bol vlastne kód, ktorý sme napísali.
Nie je strcmp kód.
Spôsob, akým sa môžete pohybovať medzi snímky, v tomto prípade, pretože máme dve,
máme 0 a 1,
robíte, že sa hore a dole príkazov.
Ak by som posunúť o jednu snímku,
teraz som v hlavnom zásobníku ráme.
Môžem sa pohybovať dole ísť tam, kde som bol,
ísť znovu, ísť zase dole, a ísť znovu.
Ak ste niekedy robiť program v GDB, dostanete havárii, získate backtrace,
a zistíte, že je to v nejakom súbore, ktorý nevie, čo sa deje.
Môžete skúsiť zoznamu, kód nevyzerá poznáte,
pozrite sa na zoznam snímok a zistiť, kde ste.
Pravdepodobne ste v zlom rámca frontu.
Alebo aspoň, že si v zásobníku ráme, ktorý nie je ten, ktorý si môžete naozaj ladiť.
Teraz, keď sme v príslušnej rámca frontu, sme v hlavnom,
Teraz môžeme použiť príkaz list sa zistiť, čo linka bola.
A vidíte to, to vytlačil pre nás tu.
Ale môžeme zasiahnuť zoznam všetkých rovnaké, a zoznam nám dáva toto pekné výtlačok
skutočného zdrojového kódu, čo sa deje tu.
>> Najmä, môžeme sa pozrieť na riadku 6.
Môžeme vidieť, čo sa deje tu.
A vyzerá to, že robíme nákupný reťazcov
medzi reťazcami "CS50 skál" a ArGV [1].
Niečo o tom padal.
Takže Missy, máte nejaké myšlienky na to, čo by mohlo byť to tu deje?
[Missy] Ja neviem, prečo to zhadzovať. >> Neviete prečo to zhadzovať?
Jimmy, nejaké myšlienky?
[Jimmy] Nie som si úplne istý, ale v poslednej dobe sme použili reťazec nákupný,
alebo strcmp, mali sme ako tri rôzne prípady podľa nej.
Nemali sme k ==, nemyslím si, že priamo v tej prvej línii.
Namiesto toho bol rozdelený do troch a jedna == 0,
jeden bol <0, myslím, a jeden bol> 0.
Takže možno niečo také? Jo >>. Takže tam je to problém
z robíme porovnaní správne?
Stella? Akékoľvek myšlienky?
[Stella] Nie som si istý. >> Nie som si istý. Daniel? Myšlienky? Dobre.
Ukázalo sa, že to, čo sa deje tu, je, keď sme bežali program
a my sme dostali seg poruchu, pri spustení programu po prvýkrát, Daniel,
ste ho žiadne argumenty príkazového riadku?
[Daniel] No >> č V tomto prípade, čo je hodnota ArGV [1]?
>> Nie je žiadna hodnota. Právo >>.
No, nie je vhodné hodnota reťazca.
Ale tam je nejaká hodnota. Aká je hodnota, ktorá je uložená v tam?
>> Odpadky hodnota? >> Je to buď odpadky hodnota alebo, v tomto prípade,
koniec poľa ArGV je vždy ukončený s null.
Takže, čo vlastne dostal v nich uložené, je null.
Ďalší spôsob, ako vyriešiť tento, skôr ako myslenie cez,
je pokúsiť vytlačiť to.
To je miesto, kde som si hovoril, že používanie GDB je skvelé,
pretože si môžete vytlačiť všetky premenné, všetky hodnoty, ktoré chcete
pomocou tohto handy-dandy p príkazu.
Takže ak som typ p a potom som zadajte hodnotu premennej alebo názov premennej,
hovoria, argc, vidím, že argc je 1.
Ak chcem vytlačiť ArGV [0], môžem tak urobiť len tak.
A ako sme videli, ArGV [0] je vždy názov programu,
vždy názov spustiteľného súboru.
Tu môžete vidieť, že má úplný názov.
Môžem tiež vytlačiť ArGV [1], a uvidíme, čo sa stane.
>> Tu sme dostali tento druh mystickej hodnoty.
Máme túto 0x0.
Nezabudnite na začiatku semestra, kedy sme hovorili o hexadecimálne čísla?
Alebo že malá otázka na konci PSet 0 o tom, ako reprezentovať 50 v hex?
Spôsob, akým píšeme hex čísla v SK, len nepliesť sami
s desatinnými číslami, je, že sme vždy prefix im 0x.
Tak toto 0x prefix vždy len rozumie interpretovať nasledujúce číslo ako hexadecimálne číslo,
nie ako reťazec, nie ako desatinné číslo, nie ako binárne číslo.
Pretože počet 5-0 je platné číslo v šestnástkovej sústave.
A to je číslo v desiatkovej sústave, 50.
Takže to je to, ako sme disambiguate.
Takže 0x0 prostriedky hexadecimálne 0, čo je tiež desatinné 0, binárne 0.
Je to len hodnota 0.
Ukazuje sa, že to je to, čo je null, vlastne, v pamäti.
Null je len 0.
Tu prvok uložený v ArGV [1] je nulový.
Takže sa snažíme tieto naše "CS50 skaly" reťazec nulový reťazec.
Takže dereferencing null, pokuse o prístup k veci na null,
tie sú zvyčajne bude spôsobovať nejaké Segmentation fault alebo iné zlé veci sa dejú.
A ukázalo sa, že strcmp nekontroluje vidieť
či ste prešiel v hodnote, ktorá je null.
Skôr to len ide dopredu, snažia sa robiť svoju vec,
a ak seg chyby, to seg chyby, a je to tvoj problém. Musíš ísť opraviť.
Naozaj rýchlo, môže ako tento problém vyriešiť? Charlotte?
[Charlotte] môžete skontrolovať pomocou, ak.
Takže ak ArGV [1] je null, == 0, potom sa vráťte 1, alebo niečo [nezrozumiteľné].
Jo >>. Takže to je jedna skvelý spôsob, ako to urobiť, ako môžeme skontrolovať,
hodnota sa chystáme prejsť do strcmp, ArGV [1], je null?
Ak je to null, potom môžeme povedať, v poriadku, potratiť.
>> Bežnejšie spôsob, ako to urobiť, je použiť argc hodnotu.
Môžete vidieť priamo tu na začiatku main,
Vynechali sme, že prvý test, ktorý sme zvyčajne robiť, keď budeme používať argumenty príkazového riadku,
ktorý je otestovať, či nie je naša argc hodnota je to, čo očakávame.
V tomto prípade, čakáme najmenej dva argumenty,
názov programu plus jeden ďalší.
Pretože sa chystáme použiť druhý argument tu.
Takže má nejaký skúšky vopred, pred naším strcmp hovoru
že testy tiež ArGV je najmenej 2, by tiež urobiť rovnaký druh veci.
Môžeme zistiť, či to funguje, spustením programu znovu.
Vždy sa môžete reštartovať program do GDB, čo je naozaj pekné.
Môžete spustiť, a pri odovzdaní v argumentoch do vášho programu,
odovzdáte je, keď hovoríte spustenie, nie pri štarte GDB.
Týmto spôsobom môžete mať vyvolanie programu s rôznymi argumentmi zakaždým.
Tak bežte, alebo znovu, môžem Type R, a uvidíme, čo sa stane, keď napíšeme "ahoj".
To bude vždy spýta, či chcete spustiť znova od začiatku.
Obvykle si chcete spustiť znova od začiatku.
A v tomto bode, to reštartuje to znovu, to vytlačí
program, ktorý sme beh, buggy1, s argumentom ahoj,
a vytlačí tento štandard von, hovorí, "Dostanete D," smutný tvár.
Ale my sme to seg chyba. To hovoril, že proces ukončený normálne.
Takže to vyzerá celkom dobre.
Žiadne ďalšie seg chyba, sme to minulosť,
takže to vyzerá, že je skutočne seg chyba chyba, že sme sa dostať.
Bohužiaľ, to nám hovorí, že sme stále na D.
>> Môžeme sa vrátiť a pozrieť sa na kód a vidieť, čo sa tam deje
zistiť, čo bolo - prečo sa to nám hovorí, že máme D.
Poďme sa pozrieť, tu bola táto printf hovorí, že máš D.
Ak napíšeme zoznam, ako si udržať písanie zoznamu, udržuje iterácia sa prostredníctvom svojho programu,
tak to vám ukážem niekoľko prvých riadkov programu.
Potom vám ukážem niekoľko ďalších riadkov, a ďalší kus a ďalší kus.
A to bude ďalej snažiť ísť dole.
A teraz sa dostaneme "linku číslo 16 je mimo rozsah."
Vzhľadom k tomu, že má len 15 riadkov.
Ak sa dostanete do tohto bodu a vaše premýšľal, "Čo mám robiť?" môžete použiť príkaz help.
Použite nápovedu a potom to meno príkazu.
A vidíte, GDB nám dáva všetky takéto veci.
To hovorí: "S žiadnym argumentom, uvádza ďalších desať liniek po alebo okolo predchádzajúceho zoznamu.
Zoznam - uvádza desať riadky pred - "
Tak poďme skúsiť pomocou zoznamu mínus.
A, ktorý uvádza, že 10 riadkov predchádzajúcej, môžete pohrať so zoznamom trochu.
Môžete to urobiť zoznam, zoznam -, môžete si dokonca dať vypísať číslo, ako je zoznam 8,
a to bude zoznam 10 riadkov po riadku 8.
A vidíte, čo sa tu deje je máš jednoduché, ak iný.
Ak zadáte CS50 skalách, vypíše "Získate A."
Inak to vytlačí "Dostanete D."
Bummer mesto. Dobrá. Áno?
>> [Daniel] Takže keď som sa snažil robiť CS50 kamene bez úvodzoviek,
hovorí, že "Dostanete D."
Potreboval som úvodzovky sa dostať do práce, prečo to je?
Jo >>. Ukazuje sa, že keď - to je ďalší trochu zábavy lahôdku -
pri spustení programu, ak by sme ho spustiť a my zadajte CS50 skalách,
rovnako ako Daniel bol povedal, že áno, a stlačíte kláves Enter,
stále hovorí, že sme si D.
A otázka je, prečo to je?
A ukázalo sa, že ako naše terminál a GDB analyzovať tieto ako dve samostatné argumenty.
Vzhľadom k tomu, keď je priestor, ktorý je vyjadrený
Prvý argument skončila, ďalší argument je asi začať.
Spôsob skombinovať tie do dvoch, alebo ľúto, do jedného argumentu,
je použiť úvodzovky.
Takže teraz, keď dáme do úvodzoviek a spustite ho znova, dostaneme A.
Takže len zhrnúť, žiadne citácie, CS50 a skaly analyzovať ako dve samostatné argumenty.
S citáciami, je to analyzovať ako jeden argument úplne.
>> Vidíme to s zarážka.
Zatiaľ sme boli beží náš program, a to bol spustený
kým buď seg závady alebo narazí na chybu
alebo kým bol ukončený a všetky boli úplne v pohode.
To nie je nevyhnutne najužitočnejšie vec, pretože niekedy
Máte chybu v programe, ale to nie je spôsobenie Segmentation fault.
Nie je to spôsobuje váš program zastaviť alebo niečo podobné.
Spôsob, ako sa dostať GDB pozastaviť váš program na určitom mieste
je nastaviť zarážku.
Môžete buď vykonať nastavením zarážka na názov funkcie
alebo môžete nastaviť zarážku na konkrétny riadok kódu.
Páči sa mi nastaviť zarážky na názvy funkcií, pretože - ľahko zapamätateľné,
a ak si skutočne ísť a zmeniť zdrojový kód do trochu,
potom sa vaše breakpoint bude skutočne zostať na rovnakom mieste vo vašom kóde.
Vzhľadom k tomu, ak používate čísla riadkov, a čísla riadkov zmení
pretože pridáte alebo odstránite nejaký kód, potom sa vaše zarážky sú úplne posral.
Jedným z najčastejších vecí, ktoré som urobiť, je nastaviť zarážku na hlavnú funkciu.
Často som si naštartovať GDB, budem písať B Hlavné, stlačte klávesu Enter, a ktoré vám nastaviť zarážku
na hlavnou funkciou, ktorú práve hovorí, "Pozastavenie programu, akonáhle začnú,"
a to tak, keď som spustiť svoj program, povedzme, CS50 skaly ako dva argumenty
a stlačte klávesu Enter, sa dostane do hlavnej funkcie a zastaví sa na prvom riadku,
tesne pred vyhodnocuje strcmp funkcie.
>> Vzhľadom k tomu, som sa zastavil, teraz môžem začať odťaženia okolo a videl, čo sa deje
so všetkými rôznymi premennými, ktoré sú odovzdávané do môjho programu.
Tu môžem vytlačiť argc a vidieť, čo sa deje.
Vidieť, že argc je 3, pretože je to má 3 rôzne hodnoty v ňom.
Je to tu na názov programu, je to má prvý argument a druhý argument.
Môžeme tlačiť tie z pohľadu na ArGV [0], ArGV [1], a ArGV [2].
Takže teraz môžete vidieť, prečo táto výzva strcmp bude na neúspech,
pretože vidíte, že sa rozdelil CS50 a skaly do dvoch samostatných argumentov.
V tomto okamihu, akonáhle ste hit zarážku, môžete pokračovať na krok prostredníctvom programu
riadok po riadku, na rozdiel od spustenia programu znovu.
Takže ak nechcete začať svoj program znovu a jednoducho pokračovať ďalej,
môžete použiť príkaz continue a pokračovať bude spustite program až do konca.
Rovnako ako to urobil tu.
Avšak, keď som reštartovať program, CS50 skaly, to zasiahne moju zarážku znova,
a tentoraz, keď nechcem, aby jednoducho ísť celú cestu cez zvyšok programu,
Môžem použiť nasledujúci príkaz, ktorý som tiež skratka s n
A to bude krok prostredníctvom programu riadok po riadku.
, Takže môžete sledovať, ako sa veci vykonávať, ako zmeniť premenné, ako sa veci sa aktualizácie.
Čo je celkom pekné.
Druhá super vec je, skôr než opakovať rovnaký príkaz znova a znova a znova,
ak ste jednoducho stlačiť Enter - tak tu vidíte, ja som napísal v ničom -
keď som jednoducho stlačiť Enter, bude opakovať predchádzajúci príkaz,
alebo predchádzajúci GDB príkaz, ktorý som dal dovnútra
Môžem mať stlačení klávesu Enter a nechám krokovanie môj kód riadok po riadku.
Chcel by som povzbudiť vy ísť pozrieť na ďalšie buggy programy rovnako.
Nemáme čas sa dostať cez všetky z nich dnes v oddiele.
Zdrojový kód je tam, takže môžete trochu vidieť, čo sa deje
v zákulisí, ak vám naozaj prilepené,
ale prinajmenšom, len cvičiť bootovanie GDB,
spustenie programu, kým sa zlomí na vás,
získanie backtrace, prísť na to, akú funkciu zrážka bola v,
aký postoj to bolo na, tlač na niektoré hodnoty premenných,
len tak budete mať pocit, pre to, pretože to bude naozaj pomôže do budúcnosti.
V tomto bode, budeme ukončiť z GDB, ktorý sa pomocou skončiť, alebo len q.
Ak váš program je uprostred behu stále, a to nie je ukončený,
bude to vždy spýtať, "Ste si istí, že naozaj chcete skončiť?"
Môžete stačí kliknúť áno.
>> Teraz budeme pozerať na ďalší problém, ktorý máme, čo je mačka program.
Ak sa budete pozerať krátky na presmerovanie a potrubia, uvidíte, že Tommy používa tento program
že v podstate vytlačí všetky výstup súboru na obrazovku.
Takže ak som bežať mačku, toto je vlastne vstavaný program spotrebiče,
a ak budete mať Macintosha, môžete to urobiť na počítači Mac taky, ak si otvoríte terminál.
A my - mačka, povedzme, cp.c, a stlačte klávesu Enter.
Čo to urobili, keby sme posunúť hore trochu a pozrite sa, kde sme spustili linku,
alebo tam, kde sme bežali príkazu cat, doslova len vytlačiť obsah cp.c našej obrazovke.
Môžeme spustiť znovu a vy môžete dať do viacerých súborov dohromady.
Takže si môžete urobiť mačacie cp.c, a potom môžeme tiež zreťaziť cat.c súbor,
čo je program, chystáme písať,
a to bude tlačiť na obe súbory späť k sebe do nášho obrazovku.
Takže ak budeme pohybovať hore trochu, vidíme, že keď sme bežali túto mačka cp.c, cat.c,
Najskôr to vytlačiť na cp súbor, a potom pod ním, to vytlačiť na cat.c súbor tu dole.
Budeme používať toto len dostať naše nohy mokré.
Pohrajte sa s jednoduchým potlačou na termináli, pozri, ako to funguje.
Ak ste otvorení s gedit cat.c, Enter,
môžete vidieť program, že sme o tom písať.
Sme súčasťou toto pekné kotla dosku, takže nemusíte tráviť čas písať všetky tie von.
Sme tiež skontrolovať počet argumentov odovzdaných palcov
Sme vytlačiť pekné správu o použití.
>> To je jedna z tých vecí, ktoré opäť, rovnako ako sme sa bavili,
je to skoro ako svalovej pamäte.
Len pamätajte, že robia rovnaký druh vecí
a vždy vytlačiť nejaký užitočných správy
tak, aby ľudia vedeli, ako spustiť svoj program.
S mačkou, je to celkom jednoduché, my sme len ísť cez všetky rôzne argumenty
, Ktoré boli odovzdané do nášho programu, a budeme tlačiť
ich obsah na obrazovku po jednom.
Ak chcete tlačiť súbory na obrazovku, budeme robiť niečo veľmi podobného
čo sme na konci testu.
Na konci kvízu, že najať programu, museli sme otvoriť súbor,
a potom sme museli tlačiť.
V tomto prípade, budeme otvoriť súbor, a budeme čítať z neho miesto.
Potom budeme tlačiť, miesto do súboru, budeme tlačiť na obrazovku.
Takže tlače na obrazovku, ktorú ste všetci urobil predtým s printf.
Takže to nie je príliš bláznivé.
Ale čítanie súboru je trochu divný.
Prejdeme to trochu v čase.
Ak ste sa vrátiť k poslednému problému na kvíz, problém 33,
prvý riadok, ktorý budeme robiť tu, otvorenie súboru, je veľmi podobný tomu, čo sme robili tam.
Takže Stella, čo robí, že riadok vyzerá takto, keď sme sa otvoriť súbor?
[Stella] Capital FILE *, súbor - >> Dobre. >> - Je rovný fopen. Jo >>.
Čo je v tomto prípade? Je to v komentári.
>> Je to v komentári? ArGV [i] a r?
Presne >>. Právo na. Takže Stella je úplne pravdu.
To je to, čo linka vyzerá.
Budeme si súbor prúd premenné, uložte ich do súboru *, takže všetky čiapky,
FILE, *, a meno tejto premennej bude súbor.
Sme mohli nazvať, čo sa nám páči. Mohli by sme hovoriť first_file, alebo file_i, čo sme chceli.
A potom názov súboru bol prijatý v na príkazovom riadku k tomuto programu.
Tak to sú uložené v ArGV [i,] a potom budeme tento súbor otvoriť v režime na čítanie.
Teraz, keď sme otvorili súbor, čo je tá vec, že ​​musíme vždy pamätať na to
keď sme otvorili súbor? Zatvorte ho.
Tak Missy, ako sme zatvorenie súboru?
[Missy] fclose (súbor) >> fclose (súbor). Presne tak.
Great. Dobre. Ak sa pozrieme na to, aby to komentár tu,
hovorí, "Open ArGV [i] a vytlačiť obsah na štandardný výstup."
>> Štandardné out je divné meno. Stdout je len náš spôsob, ako povedať
chceme tlačiť do terminálu, chceme vytlačiť na štandardné výstupný prúd.
Môžeme skutočne zbaviť tento komentár tu.
Budem skopírovať a vložiť ho pretože to je to, čo sme urobili.
V tomto bode, teraz máme čítať súbor kúsok po kúsku.
Sme diskutovali niekoľko spôsobov čítania súborov.
Ktoré z nich sú vaše obľúbené tak ďaleko?
Akými spôsobmi ste videli, alebo si pamätať, čítať?
[Daniel] fread? >> Fread? Takže fread je jeden. Jimmy, viete nejaké ďalšie?
[Jimmy] No >> Dobre. Nie. Charlotte? Alexander? Nejaké ďalšie? Dobre.
Takže tie ostatné sú fgetc, je ten, ktorý budeme používať veľa.
K dispozícii je tiež fscanf; vy vidieť vzor tu?
Všetci začínajú s f Čokoľvek, čo robiť so súborom.
Tam je fread, fgetc, fscanf. Toto sú všetky čítacích funkcií.
Pre písanie máme fwrite, máme fputc miesto fgetc.
Máme tiež fprintf ako sme videli na kvíz.
Keďže sa jedná o problém, ktorý sa týka čítania zo súboru,
budeme používať jeden z týchto troch funkcií.
Nebudeme používať tieto funkcie tu dole.
Tieto funkcie sú všetky nájdené v štandardnom I / O knižnice.
Takže keď sa pozriete na hornej časti tohto programu,
môžete vidieť, že sme už zahrnuté hlavičkový súbor pre štandardné I / O knižnice.
Ak chceme zistiť, ktorý z nich chceme použiť,
môžeme vždy otvoriť manuálové stránky.
Takže môžeme písať man štádiách
a prečítajte si všetko o štádiách vstupných a výstupných funkcií v C
A už môžeme vidieť oh, pozri. Je to spomenúť fgetc, to spomenúť fputc.
Takže môžete vŕtať sa trochu a pozrite sa na, povedzme, fgetc
a pozrite sa na jeho manuálové stránke.
Môžete vidieť, že to ide ruka v ruke s celou partiou ďalších funkcií:
fgetc, fgets, getc, getchar, dostane, ungetc, a jeho vstupné postáv a reťazce.
Tak to je, ako čítame v znakoch a reťazce zo súboru zo štandardného vstupu,
ktorý je v podstate od užívateľa.
A to je, ako to robíme v skutočnom C.
Takže to nie je pomocou GetString a getchar funkcií
že sme použili z CS50 knižnice.
Budeme robiť tento problém v niekoľkými spôsobmi
takže môžete vidieť dva rôzne spôsoby, ako robiť to.
Ako fread funkcie, ktoré Daniel spomenul a fgetc sú dobré spôsoby, ako to urobiť.
Myslím, že fgetc je trochu jednoduchšie, pretože je to len má, ako vidíte,
jeden argument, súbor *, že sa snažíme čítať znak z,
a jeho návratová hodnota je int.
A to je trochu mätúce, že jo?
>> Pretože sme stále charakter, tak prečo nie je tento návrat char?
Vy máte nejaké nápady, prečo je toto nemusí vrátiť char?
[Missy odpovede, nezrozumiteľné] >> Jo. Takže Missy je úplnú pravdu.
Ak je to ASCII, potom celé číslo môže byť mapovaná na skutočné char.
Mohlo by to byť ASCII znak, a to je pravda.
To je presne to, čo sa deje.
Používame int jednoducho preto, že má viac bitov.
Je to väčšie ako char; naše char má iba 8 bitov, ktoré 1 byte na našich 32-bitových strojoch.
A int má hodnotu všetkých 4 bytov "priestoru.
A ukázalo sa, že spôsob, akým fgetc funguje,
ak by sme posunúť nadol v našom prehľade v tejto manuálové stránke trochu,
rolovať celú cestu dole. Ukazuje sa, že použitie tohto osobitného hodnotu s názvom EOF.
Je to zvláštne konštantná ako návratová hodnota fgetc funkcie
zakaždým, keď narazí na koniec súboru, alebo ak sa vyskytne chyba.
A ukázalo sa, že robiť takéto porovnanie s EOF správne,
Ak chcete mať extra množstvo informácií, ktoré máte v int
na rozdiel od použitia char premenné.
Aj keď fgetc je skutočne dostať znak zo súboru,
si chcete zapamätať, že sa vracia niečo, čo je typu int na vás.
To znamená, že je to celkom jednoduché.
Je nám dá charakter, takže všetko, čo musíte urobiť, je stále pýtajú súbor,
"Daj mi ďalší znak, daj mi ďalší znak, daj mi ďalší znak,"
kým sa na koniec súboru.
A to bude ťahať v jednom znaku v dobe od nášho súboru,
a potom môžeme robiť, čo chceme s ňou.
Môžeme uložiť, môžeme pridať na reťazec, môžeme ju vytlačiť.
Robiť nič z toho.
>> Zväčšenie staré a ísť späť do nášho cat.c programu,
ak budeme používať fgetc,
ako by sme mohli pristupovať k tomuto ďalší riadok kódu?
Budeme používať - ​​fread bude robiť niečo trochu iné.
A tentoraz, sme len tak použiť fgetc dostať jeden znak v čase.
Ak chcete spracovať celý súbor, možno to, čo máme robiť?
Koľko znakov je tam v súbore?
Existuje mnoho. Takže budete pravdepodobne chcieť, aby si jeden
a potom sa ďalšie a získať ďalšie a získať ďalšie.
Aký druh algoritmu si myslíš, že možno budeme musieť použiť tú?
Aký typ -? [Alexander] pre sláčiky? Presne >>.
Nejaký typ slučky.
Pre slučky, je v skutočnosti veľký, v tomto prípade.
A ako si hovoril, že to znie ako chcete slučku cez celý súbor,
dostať po znakoch.
Nejaké návrhy na to, čo by mohla vyzerať?
[Alexander, nezrozumiteľným]
Dobre >>, len mi povedz, v angličtine to, čo sa snažíte urobiť? [Alexander, nezrozumiteľným]
Takže v tomto prípade, to znie, ako by sme len snažíte slučky cez celý súbor.
[Alexander] Tak aj > Veľkosť -?
Myslím, že veľkosť súboru, nie? Veľkosť - Dáme len napísať to takto.
Veľkosť súboru pre bytie času, i + +.
Tak to dopadá, že spôsob, akým to urobíte pomocou fgetc, a to je nové,
je to, že neexistuje žiadny jednoduchý spôsob, ako len dostať veľkosť súboru
s týmto "sizeof" typu konštrukcie, ktoré ste predtým nevideli.
Keď použijeme túto fgetc funkciu, sme zavádza nejaký
nové, funky syntax to pre sláčiky, kde namiesto použitia len základné počítadlo
ísť znak po znaku, budeme ťahať jeden znak v čase,
jeden znak v čase, a spôsob, akým my vieme, že sme na konci
nie, keď sme napočítali určitý počet znakov,
ale keď postava sa vytiahnuť, je, že osobitné koniec súboru znak.
Tak sme to urobiť - ja ju nazývam túto ch, a budeme ju inicializovať
s našou prvou výzvy, aby si prvý znak z súboru.
Takže tejto časti priamo tu, to dostane znak z súboru
a uložiť ho do premennej ch.
Budeme to robiť tak dlho, kým sa dostaneme na koniec súboru,
ktoré robíme pri testovaní na charaktere nesmie je rovná k tejto osobitnej povahe OSZ.
A potom namiesto toho, aby robil ch + +, ktorý by len zvyšovať hodnotu,
takže ak čítame o A von k súboru, kapitál, povedzme,
ch + + by nám b, a potom by sme si C a potom d
To zjavne nie je to, čo chceme. To, čo chceme tu
v tomto poslednom bitu ich chceme získať ďalší znak zo súboru.
>> Tak ako by sme mohli získať ďalší znak zo súboru?
Ako sa dostať na prvý znak zo súboru?
[Študent] fgetfile? >> Fgetc, alebo, je mi ľúto, že si úplnú pravdu.
Aj chybne to tam. Tak jo.
Tu miesto uskutočňovania ch + +,
sme len tak zavolať fgetc (súbor) znovu
a uložiť výsledok v našej rovnakom ch premenné.
[Študent otázka, nezrozumiteľným]
>> To je miesto, kde títo ľudia súbor * sú zvláštne.
Spôsob ich práce je, že - pri prvom otvorení - pri prvom robiť, že fopen volanie,
FILE * účinne slúži ako ukazovateľ na začiatok súboru.
A potom zakaždým, keď volanie fgetc, to sa pohybuje jeden znak v súbore.
Takže zakaždým, keď hovoríš, že ste zvyšovanie ukazovateľ súboru o jeden znak.
A keď fgetc znova, sa sťahujete to iný charakter
a iný charakter a iný charakter a iný znak.
[Študent otázka, nezrozumiteľné] >> A to je - áno.
Je to druh tejto mágie pod kapotou.
Stačí držať zvyšovanie prostredníctvom.
V tomto bode, ste schopní skutočne pracovať s charakterom.
Tak ako by sme mohli vytlačiť na obrazovku, teraz?
Môžeme použiť rovnaký printf vec, ktorú sme použili predtým.
To sme boli s využitím všetkých semester.
Môžeme zavolať printf,
a môžeme odovzdať v charakteru, rovnako ako to.
Ďalším spôsobom, ako to urobiť, je skôr než pomocou printf a majú čo do činenia tento formát reťazca,
môžeme tiež použiť jeden z ďalších funkcií.
Môžeme použiť fputc, ktorá tlačí znak na obrazovke,
s výnimkou, ak sa pozrieme na fputc - dovoľte mi vzdialite trochu.
Vidíme to, čo je pekné, je to má v povahe, že čítame s použitím fgetc,
ale potom musíme dať jej prúd sa bude tlačiť.
Môžeme tiež použiť putchar funkciu, ktorá bude klásť priamo na štandardný výstup.
Takže tam sú celá partia rôznych možností, ktoré môžeme použiť pre tlač.
Všetci sú v štandardnom I / O knižnice.
Kedykoľvek budete chcieť vytlačiť - to printf, v predvolenom nastavení, bude tlačiť na špeciálny normy von prúdu,
ktorý je, že stdout.
Takže môžeme len odkazovať sa na to ako druh tohto kúzelného hodnoty, stdout tu.
Chybička sa vlúdila. Dajte bodkočiarku mimo.
>> To je veľa nových, funky informácií tu.
Mnoho z toho je veľmi pozostáva z ustálených spojení, v tom zmysle, že je to kód
, Ktorý je písaný táto cesta len preto, že je to čistý čítať, ľahko čitateľný.
Existuje mnoho rôznych spôsobov, ako to urobiť, veľa rôznych funkcií, ktoré môžete použiť,
ale máme tendenciu postupujte podľa nasledujúcich rovnaké vzorce znova a znova.
Takže nebuďte prekvapení, keď uvidíte kód, ako to prichádza znovu a znovu.
Dobrá. V tomto bode, musíme zlomiť na deň.
Vďaka za že ste prišli. Vďaka za sledovanie, ak ste on-line. A uvidíme sa budúci týždeň.
[CS50.TV]