[? DAN ARMADARAS:?] Ahoj, Jsem [? Dan Armadaras?]. Dnes se budeme být při pohledu na ladění. Nejen, že budeme mluvit o některých technikách, ale také budeme dívat na některé funkce obsažené v rámci CS50 IDE, které umožňují snadno ladit program. Jen jeden příklad něco, co se může pokazit a je to vlastně něco že jsme již viděli dříve. V tomto případě se jedná o program, C který přijímá celé číslo od uživatele, rozdělí ji dva, a poskytuje výstup zpět uživateli. Teď z toho, co jsme viděli, dříve v přednáškách, víme, že to bude skutečně způsobit specifické typy problémů divize když máme lichá čísla. Konkrétně, budeme prostě vyhodit za desetinnou čárkou cokoliv. Teď víme, že to se stane být případ. A pokud bychom jej spustit, můžeme potvrdit, naše podezření, první, kompilací. A pak, spuštěním a zadávání lichý počet. To není nic nového. Ale to je vlastně Příkladem chybu, která mohou existovat v rámci většího programu že se stává těžší vystopovat. I když víme, co je problém Je pravda, jádro věci by se mohly pokusit identifikovat zejména pokud dojde k chybě, určení toho, co tento problém je, a pak ji opravit. Takže Poskytujeme tuto jako příklad z toho, co by mohlo být něco že už víme, ale mohou být pohřben v rámci jiných prvků kódu. Takže otevřením tohoto dalšího zdroje kód soubor jako příklad, Toto rozdělení problém je nyní součástí širšího programu. Přesto by mohlo být trochu bit nepřirozený, a my by mohl být schopen snadno identifikovat, zejména od té doby jsme jen diskutovat o tomto. Ale můžeme přijít na to, že tento Problém může existovat ve větším měřítku. Pokud bych to kompilace a teď spusťte jej, zadejte liché číslo, můžeme vidět, že nebudeme mít přesně výstup, že můžeme očekávat. V tomto konkrétním případě, můžeme říci, že jsme chcete spočítat všechna čísla od jednoho do určité konkrétní číslo. A my můžeme vidět, že jsme mají řadu problémů zde, pokud budeme výstup, jednoduše, 0 a 1, když jsme poskytují vstup 5. Takže už víme, že tam je tu problém. Ale my se nemusí přesně vědět, kde tento problém skutečně existuje. Teď jeden ze způsobů, se můžeme pokusit opravit je něco, co máme již byl představen. Můžeme stačí použít ve větším měřítku. Na řádku 14, máme tato funkce printf, což nám umožňuje vytisknout státu z různých informací. A to je něco, co vás by měl využít v rámci svého programu aby se pokusili zjistit, co přesně je se děje v různých řádků kódu. Takže i když to není Konečný výstup, že jsme vlastně chtějí vyrábět z tento program, stále může mít nějaké ladění Prohlášení kde jsme může pokusit se zjistit, co přesně se děje uvnitř našeho kódu. Takže v tomto případě, budu printf se značkou ladění. V tomto případě se jedná jen ladění řetězec že jsem až nepříjemné, takže se stane velmi jasně ve výstupu mého kódu co to je, že chci ukázat. A výstup zde číslo které jsme vypočítány. V tomto případě, já bych mohl chtějí přesně vědět, , co se děje před a Po nějaké konkrétní výpočty. Takže jsem mohl před použít printf a po tomto řádku kódu. V tomto případě by mohla dokonce jsem aby to trochu víc jasné, tím, že říká ladění před a ladění po tak že nemám plést sám s více řádků, které vypadají totožné. Teď, když jsme to překompilovat a běh to, zadejte číslo jako pět znovu, můžeme vidět, že máme Nyní výstup před a po a zjistíte, že jsme neudělali jasné rozdělení nebo jasné mají čísla že jsme vlastně chcete dělat. Nyní v tomto případě se jedná ve skutečnosti není jasný výstup. Není to opravdu jasné, že výsledek chceme z tohoto konkrétního programu. A to je, opět, je trochu nepřirozený. Ale možná, jednou z věcí, které bychom mohli udělat v případě, že specifikace řekl, že chceme rozdělit tím, 2 a přidá se 1-- tak, jinými slovy, chceme zaokrouhlit up-- pak abychom věděli, že jsme mohli dělat, že konkrétní věc, v tomto případě. Teď víme, že budeme možné přidat 1 do našeho sníží na polovinu počtu. Pojďme to překompilovat a potvrzují, že tato se chová tak, že chceme. Můžeme vidět, že nyní před s, máme číslo 5. Poté, co, máme číslo 3, která je podle našeho specifikace, je to, co jsme chtěli udělat. Ale když se podíváme na Výstup tady, můžeme vidět, že bychom mohli mít další bug celkem, což je že začínáme naši počítat od 0. Nyní se znovu, to je něco, že jsme viděli v minulosti a můžeme opravit poměrně snadno. Ale v tomto případě jsme také měl výhodu použití příkazu printf přímo uvnitř smyčky for přesně vědět, kde se děje, že chyba. Takže printf prohlášení jsou velmi užitečné při pomoci určit, kde, Přesně ve zdrojovém kódu, specifická chyba nastane. A to je také důležité si uvědomit, že, jak jsme psaní kódu, bychom mohli mít předpoklady o stavu programu. Nebo bychom mohli mít předpoklady o tom, co část programu je vlastně správné, nebo nesprávné, při později, když jsme stavět na tomto programu a učinit z něj součást komplexní a větší program, že bychom si uvědomit, že některé aspekty z toho není ve skutečnosti buggy. Použití printf může opravdu pomoci zúžit a identifikovat regiony programu, který nemusí chová přesně tak, že jsme očekávat, že, na základě našich předpokladů. Ale je tu další nástroje k dispozici, stejně, že nám umožní pokusit se zjistit , kde se chyba vyskytuje A také, konkrétně, jaké věci se děje uvnitř programu. Takže pomocí printf je velmi užitečné, pokud chceme, určit konkrétní oblasti program, který má nějakou chybu. Ale je to také stává únavné po chvíli. V tomto případě se jedná o relativně jednoduchý program jen s jedním nebo dvěma proměnnými. A to se stává pro nás velmi snadné vytisknout hodnotu těchto proměnných v rámci většího programu. Ale abychom mohli mít jiný program, který má mnoho proměnných. A to nemusí být zcela tak snadné printf pokusit se vyhodnotit, co se děje každému z těchto proměnných Jelikož je program provádění. Tam je program, který existuje volal debugger programu. V tomto případě je ten, který budeme Použití je GNU debugger, nebo GDB, že nám umožňuje kontrolovat interní workings programu v mnohem detailní cesta. Můžeme skutečně provádět GDB z příkazového řádku zde jednoduše napsáním GDB a příkaz, který chceme ladit. V tomto případě počítat. Nyní v tomto případě můžeme vidět, že to nás přivádí do řádku, který říká, že GDB. A můžeme skutečně provádění příkazů k GDB skutečně zahájit provádění z Program, zastavte jej v určitých bodech, vyhodnotit proměnné a zkontrolujte proměnné, které existují ve stavu programu v danou chvíli a tak dále a tak dále. Poskytuje hodně síly k nám. Ale to jen tak se stane že CS50 IDE také poskytuje GUI nebo uživatele rozhraní pro GDB, že umožňuje nám to udělat, aniž byste museli příkazového řádku rozhraní vůbec nebo dokonce vůbec. Tak, že mohu získat přístup, že je pomocí tlačítka ladění na samém vrcholu CS50 IDE. Nyní v minulosti, co máme vidět, je to, že pomocí příkazu linka kompilace a spustit program. Tlačítko ladění dělá obou těchto kroků. Ale také to přinese až Karta debugger na extrémní pravici který nám umožňuje prohlédnout celou řadu vlastností programu jak je provádění. Mám-li na tlačítko Debug, v tomto případ, bude vychovávat nová karta v konzoli Okno na samém dně. A můžete vidět, že tato karta má některé informace na samém vrcholu. A můžeme do značné míry ignorovat. Ale jedna z věcí, že chceme všimnout je to, že výstupy totéž, co jsme by se dostat, pokud jsme se snažili spustit, aby na C program v terminálovém okně. Zde můžeme vidět, že to běží řinčení, a má celou řadu příznaků, a to je kompilace naši count.c soubor, která byla vybraná karta v době že jsem narazila ladění. Tak to je velmi užitečná, protože nyní pomocí tohoto tlačítka ladění, můžeme současně kompilace a spustit program, který jsme vlastně chcete spustit. Jedním z příznaků, které je důležité, v tomto případě, jsme skutečně používali nejdelší dobu ale také jen dělal nějaký ruku mávání [neslyšitelný], který je tohle tady. V zazvoněním, říká -ggdb3. V tomto případě to, co jsme vyprávění zazvoněním, náš překladač, je to, že chceme sestavit náš program. Ale také jaké jsou označované jako informace o symbol takže kompilátor má skutečně přístup na mnoha podkladových informací obsažené v rámci programu. Přesněji řečeno, je počet funkcí, které mám, jména těchto funkcí, proměnné, typy že tyto proměnné jsou, a různé z dalších věcí, které pomáhají debugger vykonávat svou činnost. Teď je tu ještě něco to je důležité zmínit, když mluvíme o chod program tímto způsobem. Všimněte si, že to má vlastně vychoval novou kartu v naší konzole po dně. Máme již nemusí komunikovat přímo s okno terminálu. Ale tato nová karta je ve skutečnosti okno terminálu. Prostě je specifická pro chod Program, který jsme vytvořili. Všimněte si, že ve spodní části, v v kombinaci s nějakým výstupem tím, zvonit kompilátor a GDB, které můžeme do značné míry ignorovat, ve skutečnosti ukazuje výstup náš program na samém dně. Teď je důležité si uvědomit, že toto jedno okno vlastně vám ukáže Výstup z programu ale také může přijímat vstup pro daný program, stejně. Takže oznámení, která říká, Prosím, zadejte číslo, který je stejný výstup, který jsme měli měl v terminálovém okně předtím. Ale už je to uvedeno v této nové kartě. I můžete zadat číslo. A to bude skutečně fungují jako očekáváme nám ukazuje náš ladění, výstup, výstup, který by mohl být buggy, jak jsme viděli dříve. A na samém dně, jej ve skutečnosti má nějaký přídavný výstup z HDP, jen říkám, že tento program ukončen. Teď, jak jste viděli v této zejména běh přes, by bylo velmi málo užitečné, protože i když jsme měli přijít menu debugger up, to bylo ještě běžící program. V žádném okamžiku udělal to vlastně pozastavit výkon pro nás aby bylo možné kontrolovat všechny proměnné obsažené. Je tu něco jiného že musíme udělat, aby dostat GDB si uvědomit, že chceme, pozastavit provádění programu a ne jen aby mohl pokračovat v řízení obvykle jako bychom ve všech ostatních případech. Za účelem pozastavení plnění, v nějaké konkrétní lince, musíme vytvořit to, co je volal bodu zlomu. A zlom je velmi snadno vytvořena v tomto CS50 IDE tím, že myši a klepnutím na tlačítko přímo vlevo nějaké konkrétní číslo řádku. Jednou jsem to udělal, červená tečka Zobrazí se, což znamená, že linka je nyní bodu zlomu. A příště, který jsem běžet GDB to, se zastavíte v tomto bodu zlomu jakmile dosáhne tento řádek kódu. Nyní je tento důležitý si uvědomit že to není nezbytně případ, že každý řádek kódu je ve skutečnosti k dispozici. Pokud bych měl vytvořit funkci tady, pro example-- void F-- a prostě tiskovou linku here-- ahoj world-- pokud Nikdy jsem zavolat tuto funkci, to bude v případě, že když jsem nastavit bodu zlomu, funkce nebude nikdy volal. A proto je tento zejména zlom Nikdy vlastně pozastaví provádění programu. Takže řekněme, že jsem správně vytvořit přestávka bod na nějakém řádku kódu , který bude skutečně provedena. Nyní je v tomto případě, to je První řádek v hlavní funkce. Tak to bude jistě případ že jakmile začnu provedení, bude dosaženo velmi první řádek. GDB se zastaví provádění. A pak budu moci interakci s ladicí program. Můžete nastavit více řádky jako Hraniční hodnoty, pokud byste chtěli. Můžeme také vytvořit line up zde v tomto segmentu kódu že nikdy nebude dosaženo. A můžeme také nastavit jednu níže. Důvod, že bychom Chcete to uděláme jít do trochu víc detail za chvíli. Takže teď mi dovolte, abych prostě zakázat tyto další body přerušení takže se můžeme podívat na to, co se děje když mám jednu přestávku bod v mém programu. Udělal jsem nějaké změny tohoto programu. Tak jsem třeba uložit. Budu klepněte na příkaz debug tak, že můžu začne kompilace a poté provádění ladicí program. Budeme vidět, že po okamžicích, o linka, která jsme vybrali jako přestávce bod je zvýrazněn žlutě. Můžeme také všimnout, že v horní přímo v ladění panelu že ikona pauza změnil do malé ikony přehrávání. To znamená, že máme pauzu provedení, v tomto konkrétním případě. A bít na tlačítko Přehrát by nám umožní pokračovat v provádění v tomto konkrétním bodě. Všimněte si, že je tu pár dalších Tlačítka jsou k dispozici v tomto ladění panelu, také. Krok přes, což mi umožňuje spustit, že jeden řádek kódu a krok se k tomuto řádku na příští, která, v tomto případě, by znamenalo, že printf příkaz proveden. A bude pak pauza exekuce na řádku 13, tak jako. A je tu také krok do funkce, což je užitečné, pokud jsem vytvořil další Funkce jinde ve zdrojovém kódu. A chci vstoupit do ty funkce spíše než vykonávat tuto funkci, jako celek. Ale podíváme více na kroku do funkce za chvíli. Nyní si všimnout některé další věci, které ve skutečnosti existují v tomto ladění panelu. Máme tento panel nazvaný zásobník volání, který nám ukazuje, kde přesně jsme. V tomto případě jsme jsou uvnitř z hlavních funkcí. Náš scénář se nazývá count.c. A my stalo, že se na řádek 13, sloupec onu, který je přesně to, co zvýrazní region zdrojového kódu indikuje, stejně. Nyní si všimněte, že to také ukazuje, pod lokální proměnné úseku všechny proměnné, které existují v rámci této funkce. Je důležité si uvědomit, že všechny proměnné se objeví v tomto lokální proměnné část uvnitř funkce, ještě před tím, než jsou definovány. Vidíme tu, že máme proměnnou volal num, má výchozí hodnotu 0, a to je typu int. Nyní, než jsme vlastně inicializovat všechny tyto proměnné, nejsme nutně zaručeno, že vidět hodnotu 0. A v závislosti na dalších popravách že jste provedli a stav vaší paměti při jste skutečně spustit tento program, můžete zjistit, že vás Nevidím hodnoty 0 a, místo toho, některé další bláznivé čísla. Ale nebojte se o tom. Nebude to být relevantní, dokud jste skutečně inicializovat hodnotu. Nyní v tomto případě můžeme vidět, že Jsem provedl nějaké výstupy. A já, právě teď, se zastavil popravu. Ale v tomto případě to, co Opravdu chci dělat je nyní překročit tento řádek kódu, takže můžu vlastně dotaz uživatele pro toto int, že chceme používat v našem programu. Nyní v tomto případě, kdy Jsem narazila překročit, oznámení že Pozastavení nebo spíše Resume Tlačítko se změní na toto tlačítko Pause proto, že tento kód je ve skutečnosti provádění. Co se děje právě teď je, že je na nás čeká na vstup nějaké informace jak můžeme vidět naše výstupním textu na samém dně. Takže teď, je to ne ve skutečnosti se odmlčel, I když to, tak nějak se zdá, být proto, že se nic neděje. Ale jen tak se stane, že v můj specifický případ na řádku 13, Čekám na vstup uživatele. A tak GDB není schopen kontrolovat program se rozběhne. Nyní příště, že mám zadat některé input-- takže budu zadejte toto číslo 5, jak jsme viděli v past-- hit Return, a my Všimněte si, že okamžitě, GDB pauzy a opět upozorňuje na další řádek. Ale všimněte si, že teď, jako Výsledkem naší zadáním hodnoty, jsme aktualizovali tuto hodnotu uvnitř z našich lokálních proměnných, které je velmi užitečné, aby přesně znát co, že číslo bylo v paměti. Nyní mohu dovolit tento program pokračovat hrát až do konce jeho provedení tím, že udeří Pokračovat. Vidíme, že velmi rychle dělá program skončit vykonávající o stejném výkonu, které jsme předtím, ladicí program zavře, a nyní tento program zcela nezastaví. I ukazují, že pouze pro účely vidí to, co se stane, když jsme vlastně hit Pokračovat. Ale my ve skutečnosti se chystáme chci se vrátit do tohoto programu takže se můžeme pokusit ladění přesně to, co se děje. Teď, když jsem pomocí ladicího programu, mohu Není nutné tyto debug printf prohlášení. Takže jsem je mohl odstranit co budu dělat Nyní stačí se vrátit k našemu jednodušší kód že jsme měli před chvílí. Teď, když jsem se zachránit naprogramovat a spustit jej, to bude, opět, jděte na tuto počáteční zlomit bod, který jsem měl na lince 11. A budu moci prohlédnout moje proměnné jako já chci dělat. To jen tak se stane, že to Součástí není příliš zajímavé, A vím, že jdu vytisknout toto prohlášení. Prosím, zadejte číslo. A pak, já vím, že jdu požádat uživatele pro toto celé číslo. Tak snad jsem skutečně chtějí hýbat rozbít bod trochu dál. Můžete odstranit body přerušení kliknutím, opět přímo na levo od uvedené číslo řádku. To red dot zmizí, což znamená, že tento zlom je nyní pryč. Nyní v tomto případě, poprava byla pozastavena. A tak to není vlastně bude pokračovat v tomto konkrétním případě. Ale mohu nastavit pauzu bod o něco později. A když teď jsem znovu můj kód, bude pokračovat a říct bod tohoto bodem zlomu. Opět platí, že jsem narazila životopis. Nevypadá jako nic se neděje. Ale to je proto, že moje kód čeká na vstup. Budu zadat číslo 5, stiskněte klávesu Enter, a Nyní bude hit další zlom. Nyní v tomto případě to je řádek kódu že předtím, než jsme věděli, náhodou buggy. Takže pojďme hodnotit, co se stane v tomto konkrétním okamžiku. Když je zvýrazněna čára, to linka dosud nebyl vykonán. Takže v tomto případě můžeme vidět že mám číslo, které Mám číslo s názvem num, že má hodnotu 5. A já budu vykonávat někteří matematiky na tomto čísle. Kdybych krok nad tím, můžeme Všimněte si, že hodnotu pro num změnilo v souladu se aritmetika, že jsme skutečně udělali. A teď, že jsme z toho pro vnitřní smyčky nebo nyní, že pro smyčce sám je zvýrazněn, vidíme, že máme nový Proměnná Volal jsem, že se bude použit v tom, že na smyčce. Nyní pamatovat Předtím jsem zmínil, že někdy, že jste uvidí nějaký blázen Čísla jsou ve výchozím nastavení před tímto číslem nebo že proměnná je ve skutečnosti inicializován. Můžeme vidět, že přesně zde v této proměnné Volal jsem, který nemá dosud inicializován v době zvýraznění. Ale můžeme vidět, že má nějaké číslo že bychom vlastně očekávat. To je v pohodě. Nebojte se o tom protože jsme vlastně inicializuje toto číslo až I překročit této přímky a hodnotu i byla inicializována na hodnotu 1. Tak vidět, že to je vlastně v případě, pojďme překročit. Nyní můžeme vidět, že linka byla popravena. A jsme nyní zvýraznění printf tento řádek. A teď můžeme vidět, jak naše hodnoty o i a 3 se měnily v průběhu času. To je velmi užitečné k tomu, ve skutečnosti, je překročit linky opakovaně. A můžete najít to, co ve skutečnosti se děje uvnitř vašeho pro smyčky a co se stane s proměnné uvnitř, že pro smyčce jako to provádění programu vyskytuje jeden krok v době. Právě v tomto bodě, I Překročila tak akorát že jsem teď jsem na konci mého programu. Kdybych krok přes to, že to bude vlastně přestane provádění jak jsme viděli v minulosti. Dovolte mi, abych to znovu, opět, tak že mohu poukázat něco jiného ven, také. V tomto případě je Nyní mě ptá, znovu, pro množství, které Budu znovu zadejte. Ale tentokrát, já jdu pro vstup do větší počet, takže pro smyčce bude opakovat vícekrát. V tomto případě, jdu zadejte hodnotu 11. Teď znovu, protože jsem nastavit bod zlomu na řádku 15, to bude upozornit na tento řádek. Můžeme vidět, že naše Číslo 11 je správně zastoupeny v našich lokálních proměnných. Stepping přes to, že můžeme nyní sledujte, co se stane s naší hodnotu i jak budeme pokračovat uvnitř to pro smyčku. To dostane zvýšen pokaždé, když dostat na vrchol, který pro smyčky. A teď jedna z věcí, které by mohly být užitečné provést během provádění tohoto programu je pro mě skutečně změnit proměnné Midstream vidět co se stane s mým programem. V tomto případě, můžu vlastně dvakrát klikněte na hodnotu. Všimněte si, že se stane textové pole. Nyní mohu vstoupit jiný úplně cení vidět, jak můj program se chová když jsem se změnil této proměnné. Nyní je v tomto případě, je proměnná i nyní obsahuje hodnotu 10. Ale program je stále zastavila popravy. Když jsem se překročit, vidím, že hodnota i, který jsem vstoupil jako 10, není větší než hodnota num, který okamžitě způsobí, že pro smyčce zastavit provádění. Teď to není jediný Důvodem, proč byste Chcete změnit proměnnou na místě. Dalo by se skutečně chtějí pokusit se tak změnit že můžete pokračovat vykonání smyčky nebo tak, že si můžete upravit nějakou hodnotu před ním dosáhne nějaké konkrétní sadu aritmetiky že se chystáte provést. Takže teď, že jsme vlastně změnit hodnota i jako program se provádění, to způsobilo, že pro smyčce přestat předčasně, protože najednou, i se stalo, že je větší než hodnota NUM, což znamená, že pro smyčce již nejsou potřebné, které mají být provedeny. Dále se to stalo, že je případ, který jsme změnili hodnotu i kdy byl zdůrazněn linka 17, což byl okamžik že pro provedení smyčky byl ve skutečnosti hodnoceny. Kdybych změnil hodnotu i na jiné lince, řekněme 19, bychom viděli jiný chování, protože linka 19 by byly provedeny před smyčky podmínka byla přehodnotila. Nyní na tomto místě, že jsem opět, Na konci tohoto programu. A mohu dovolit to přistoupit k aby můj program ukončit přirozeně. Ale je tu pár věcí, které jsou důležité, aby vzali z tohoto konkrétního jednání. Je třeba vyhodnotit Vaše vlastní předpoklady o tom, jak by měl být kód chová. Kdykoli si myslíte, že nějaký kus o kód víte, se stane i práci, to by mohlo být červená vlajka jít dozadu a vyhodnocovat, a ujistěte se, že vaše převzetí jak tento kód funguje je vlastně pravda, jak to je vyjádřeno ve zdrojovém kódu. Ale ještě více k bodu byl, když jsme pomocí debugger, si můžete dát na zarážky různé řádků kódu, který způsobí, že ladicí pauza provádění v každém z těchto linek takže můžete hodnotit paměti nebo dokonce ji změnit na svém místě. A opět, nezapomeňte, že můžete vytvořit více zarážky, abyste Můžete také pokračovat v provádění, přeskočte přes velké části kódu, a to bude automaticky pozastaví při dalším bodem zlomu. Tam je vlastně vyspělejší funkce ladicí program, stejně. Ale musíme vás odkázat některých dalších videa aby se skutečně dráždit od sebe, jak používat tyto konkrétní funkce. Pro tuto chvíli, děkuji moc za sledování. A hodně štěstí ladění.