Kurz Visual C++ (4.)


V prvnφ Φßsti dneÜnφ lekce si povφme, jak p°edßvßme programu parametry p°φmo z v²vojovΘho prost°edφ VC++. V druhΘ Φßsti si povφme n∞co o lad∞nφ programu.

4.1. P°edßvanφ parametr∙ programu

Pokud program, kter² vy₧aduje parametry p°φkazovΘ °ßdky, spouÜtφte p°φmo z p°φkazovΘ °ßdky, nenastßvß ₧ßdn² problΘm, proto₧e parametry jednoduÜe napφÜete za jmΘno programu a ka₧d² parametr odd∞lφte mezerou. Co kdy₧ ale chcete, aby takov² program Üel spustit (a ladit) p°φmo z VC++. Program, kter² vy₧aduje parametry, obvykle nepracuje sprßvn∞ pokud ₧ßdnΘ nedostane. VC++ implicitn∞ ₧ßdnΘ parametry nep°edßvß, ale dß se nastavit tak, aby p°edßval tytΘ₧ parametry jako na p°φkazovΘ °ßdce.

A jak to provedeme?
Z menu Project vyberte polo₧ku Settings....  Objevφ se tento dialog:

P°epn∞te se na kartu Debug a vepiÜte do °ßdku Program arguments parametry, kterΘ budou p°i spuÜt∞nφ p°edßny programu. V tomto p°φpad∞ mßme otev°en² projekt Functions, co₧ je p°φklad z prvnφho kurzu o C/C++. Tento program vy₧aduje parametry. Jsou to dv∞ kladnΘ celoΦφselnΘ hodnoty (v mΘm p°φpad∞ 5 a 6). Nynφ, kdy₧ spustφte program, vÜechny v²poΦty prob∞hnou sprßvn∞ a vypφÜe se sprßvn² v²sledek.

 

4.2. Lad∞nφ programu

Ka₧d² programßtor musφ v∞d∞t, jak mß ladit program. ╚asto si myslφte, ₧e program prost∞ musφ fungovat, ale on nefunguje. Co s tφm? Mßte dv∞ mo₧nosti. Prvnφ je, ₧e se budete dφvat do k≤du a doufat, ₧e najdete chybu. V duchu si budete program pouÜt∞t. Druhß mo₧nost je p°evedenφ vaÜich myÜlenek do reality tφm, ₧e program budete ladit. Program se normßln∞ spustφ, ale vy budete moci sledovat, jak program pracuje krok po kroku, budete moci sledovat  obsah vybran²ch prom∞nn²ch, budete  moci vid∞t obsah pam∞ti, obsah registr∙ procesoru atd. Zkrßtka lad∞nφ je velmi d∙le₧itß souΦßst, bez kterΘ se jist∞ neobejdete.

Lad∞nφ programu je principieln∞ v ka₧dΘm v²vojovΘm prost°edφ stejnΘ. V ka₧dΘm IDE se m∙₧ete dφvat "do" prom∞nn²ch atd.  JinΘ je akorßt ovlßdßnφ Debugeru (ladiΦe). Ji₧ vφte, ₧e VC++ jsou dva re₧imy kompilace: Debug a Release. Jak z nßzv∙ vypl²vß, ladit budete moci jen v re₧imu Debug a pak se budete modlit, aby v re₧imu Release vÜe fungovalo. ObΦas se stane, ₧e v re₧imu Debug vÜe chodφ a v Release nikoliv. To jsou ovÜem mßlo pravd∞podobnΘ varianty a tφm se zab²vat nechci.

D∙le₧itΘ pojmy v oblasti lad∞nφ

Asi nejd∙le₧it∞jÜφ pojem je tzv. Break point (neboli zlomov² bod?). Break point (Φesk² p°eklad se nepou₧φvß) je skuteΦn∞ bod n∞kde v programu, kde kterΘm dojde k p°eruÜenφ programu a p°edßnφ jeho b∞hu vßm, jako₧to ladiΦ∙m. Break point m∙₧ete umφstit prakticky kamkoliv do vaÜeho k≤du a jakmile se program dostane k tomuto bodu, je okam₧it∞ p°eruÜen. VÜe si budeme zkouÜet na p°φkladu z prvnφho kurzu o C/C++. Otev°ete si tento projekt a kurzorem naje∩te na °ßdek, kam chcete vlo₧it Break point a pak stiskn∞te F9. Na zaΦßtku °ßdku se objevφ ΦervenΘ koleΦko, kterΘ oznaΦuje Break point. Break point m∙₧ete takΘ vlo₧it p°es toolbar tlaΦφtkem ruky:

V²°ez programu s umφst∞n²m Break pointem, m∙₧ete vid∞t na nßsledujφcφm obrßzku:

Break point odstranφte stejn∞ jako jste ho p°idali: stiskem F9 nebo stiskem ruky na °ßdce, kde je break point vlo₧en.

Poznßmka: Kdy₧ spustφte program v re₧imu Release a budete mφt nastavenΘ n∞jakΘ break pointy, VC++ vßm oznßmφ, ₧e tyto break pointy budou vypnuty. Jak u₧ jsem °φkal, v re₧imu Release ladit nelze, tak₧e tento jev je normßlnφ.


Nynφ m∙₧ete program spustit. Nastaven² break point je hned na zaΦßtku programu, tak₧e program se jakoby spustφ, ale ihned je p°eruÜen a fokus se vrßtφ na okno VC++, kterΘ se podstatn∞ zm∞nφ a m∙₧e vypadat n∞jak takto:
 

Jak je mo₧no vid∞t na obrßzku, je tu spoustu nov²ch okΘnek, kterΘ si te∩ popφÜeme. Okna lze libovoln∞ p°esouvat, m∞nit jejich velikost nebo zavφrat. Zav°enΘ okno znovu aktivujeme stiskem pravΘho tlaΦφtka myÜi na p°echodu z jednoho okna do druhΘho. Objevφ se kontextovΘ menu, kde vidφte zobrazenΘ (zaÜkrtanΘ) polo₧ky vΦetn∞ toolbar∙. Pravd∞podobn∞ nebudete vyu₧φvat vÜechna okna najednou a tak si plochu uspo°ßdejte podle sv²ch pot°eb.

Nynφ si popφÜeme jednotlivß okΘnka:

  1. Okno zdrojovΘho k≤du, kde byl program p°eruÜen. Vidφte zde ₧lutou Üipku, kterß ukazuje na aktußlnφ pozici v programu (nynφ je na break pointu). Touto Üipkou m∙₧ete pohybovat ikonami, kterΘ jsou na Debug toolbaru vpravo:


    Prvnφ ikonka v prvnφm °ßdku znovu pustφ cel² program a tudφ₧ i lad∞nφ. Je k tomu, kdy₧ b∞hem lad∞nφ zm∞nφte k≤d v programu, tak abyste nemuseli lad∞nφ ukonΦit a znovu pouÜt∞t. Rozdφl je ale v tom, ₧e program se nep°eruÜφ na prvnφm break pointu, ale hned na zaΦßtku celΘho programu, v tomto p°φpad∞ na vstupu funkce main().
    Druhß ikonka ukonΦφ celΘ lad∞nφ, ani₧ by se na n∞co ptala.
    ╚tvrtß ikonka je na zkompilovßnφ zm∞n∞nΘho k≤du b∞hem lad∞nφ. Osobn∞ tento postup p°φliÜ nedoporuΦuji. Podle mΘho nßzoru je lepÜφ lad∞nφ ukonΦit a po zm∞n∞ k≤du znovu spustit.
    Älutß Üipka jen zobrazφ v okn∞ 1 aktußlnφ pozici v programu, tzn., ₧e skoΦφ na ₧lutou Üipku v programu.
    Dßle nßsleduje Φtve°ice ikonek, kterΘ spolu ·zce souvisφ a jsou asi nejd∙le₧it∞jÜφ:
        1. Pokud je aktußlnφ pozice na n∞jakΘ funkci a klepnete na toto tlaΦφtko, program se p°esune do tΘto funkce. Tuto volbu pou₧ijeme, pokud chceme v∞d∞t, co p°esn∞ se d∞je ve funkci, na kterΘ jsme. Klßvesovß zkratka je F11.
        2. Toto tlaΦφtko naopak tuto funkci provede, ale vy to provßd∞nφ nevidφte, zkrßtka debugger ji p°eskoΦφ. Pou₧φvßme ji tehdy, kdy₧ stojφme na n∞jakΘ funkci, o kterΘ vφme, ₧e funguje a nezajφmß nßs co se d∞je uvnit°. V∞tÜinou jsou to funkce definovanΘ n∞k²m jin²m. Klßvesovß zkratka je F10.
        3. Tato volba naopak opustφ aktußlnφ funkci a skoΦφ o ·rove≥ v²Ü s tφm, ₧e provede zbytek funkce. Tuto volbu pou₧ijeme v p°φpad∞, ₧e chceme opustit aktußlnφ funkci a nezajφmß nßs, co se d∞je dßl. Klßvesovß zkratka je Shift+F11.
        4. Poslednφ ikonka provßdφ program od aktußlnφ pozice ₧lutΘ Üipky a a₧ do mφsta, kam je nastaven kurzor. Klßvesovß zkratka je Ctrl+F10

    Druh² °ßdek jen zobrazuje dalÜφ okna debuggeru, kterΘ si popφÜeme za chvilku.
     
  2. DalÜφ okno se naz²vß Call Stack. Je to jak²si seznam volan²ch funkcφ v po°adφ, ve kterΘm jsou volanΘ. Ta poslednφ volanß je ·pln∞ naho°e. V naÜem p°φpad∞ vidφte, kdo zavolal naÜi funkci main(), byla to jakßsi funkce mainCRTStartup() a kdo zavolal jφ? Byl to systΘm v podob∞ knihovny KERNEL32.DLL. Poklepem na funkci, se v okn∞ 1 zobrazφ mφsto odkud je volßna nßsledujφcφ funkce. Toto okno je d∙le₧itΘ, pokud v∙bec nevφte, kde se mohla stßt chyba. Pokud se nap°φklad pokusφte psßt do cizφ pam∞ti, systΘm se okam₧it∞ ozve a program se p°eruÜφ s hlßÜkou bu∩ Access vialotion (NßsilnΘ vniknutφ - v tomto p°φpad∞ se myslφ do pam∞ti) nebo Unhadled exception (Neodchycenß v²jimka). Chybu odhalφte prßv∞ kdy₧ se podφvßte do okna Call Stack, kde vidφte funkci, kterß chybu zp∙sobila.
     
  3. V²pis registr∙ procesoru. Pro ty, kdo neznajφ assembler, je to asi Üpan∞lskß vesnice.
  4. Toto okno souvisφ s oknem 3. Je to surov² obsah pam∞ti systΘmu, najdete tam i vßÜ program v podob∞ Φφsel.
     
  5. Okno tzv. Variables neboli prom∞nn²ch. Okno mß t°i karty, z nich₧ ka₧dß znamenß pohled na prom∞nnΘ z jinΘho hlediska.
        1.    Prvnφ karta Auto zobrazuje prom∞nnΘ, kterΘ se pou₧φvajφ v blφzkosti aktußlnφ pozice v programu, pokud se p°esunete o kousek dßl, obsah okna se m∞nφ. Vidφte nßzev prom∞nnΘ a vedle hodnotu. Prom∞nnΘ typu pole nebo objekt m∙₧ete dßle rozbalit pomocφ uzlu +. M∙₧ete tak sledovat ΦlenskΘ prom∞nnΘ prom∞nnΘ atd.
        2.    Druhß karta Locals, zobrazuje jen lokßlnφ prom∞nnΘ aktußlnφ funkce. Obsah tohoto okna se m∞nφ jen kdy₧ vstupujete nebo opouÜtφte funkci.
        3.    Poslednφ kartu this, zatφm nevyu₧ijete, proto₧e nepou₧φvßte objekty.

    Zm∞na hodnoty prom∞nnΘ
    Poklepßnφm na hodnotu prom∞nnΘ, m∙₧ete hodnotu p°episovat za b∞hu programu. To se hodφ zejmΘna u dlouh²ch cykl∙, kde pot°ebujete odchytit jen n∞kterΘ hodnoty °φdφcφ prom∞nnΘ. JednoduÜe tuto hodnotu p°epφÜete a skoΦφte dßl v programu. Zßdrhel je v tom, ₧e se vynechajφ cykly, kterΘ p°epsßnφm vynechßte.

    P°φklad
    V naÜem p°φpad∞ vidφte na kart∞ Auto Φty°i prom∞nnΘ: parametry funkce main() a lokßlnφ prom∞nnΘ k a n. Vidφte, co kterß prom∞nnß obsahuje. Prom∞nnΘ k a n nejsou inicializovanΘ, tak₧e v nich jsou n∞jakß straÜnΘ Φφsla, ale to se brzy zm∞nφ. Stiskn∞te jednou klßvesu F10. Tak provedeme p°φkaz, na kterΘm je ₧lutß Üipka a skoΦφme na dalÜφ p°φkaz. Zm∞nφ se se i obsah okna Variables. Mßme zde jen dv∞ prom∞nnΘ a to ty, kterΘ se pou₧ijφ v p°i°azenφ: k a argv. Prom∞nnß k mß stßle tu hroznou hodnotu, ale po dalÜφm stisku F10 se p°φkaz provede a program op∞t poskoΦφ kup°edu. Nynφ vidφte, ₧e hodnota prom∞nnΘ k se zm∞nila na 5 a zΦervenala, to proto, abyste vid∞li, ₧e se zm∞nila. Takto m∙₧ete postupovat dßl, dokud nenarazφte na funkci variace(), kterß je ukrytß v p°φkazu printf(). Na tomto p°φkazu stiskn∞te klßvesu F11 a tak skoΦφte dovnit° tΘto funkce. Program skuteΦn∞ skoΦφ do zcela jinΘho mφsta v k≤du. Pokud vßs funkce faktorial() nezajφmß, m∙₧ete stisknout klßvesy Shift + F11 a tak funkci variace() opustφte (funkce se ale provede). Nynφ v okn∞ Variables vidφte, co vrßtila funkce variace(). Po dalÜφm stisku F11, byste se dostali dovnit° funkce printf(), co₧ nenφ pot°eba. Tak₧e m∙₧ete pokraΦovat F10.
     
  6. Watches. Toto okno p°φmo vypisuje hodnoty zvolen²ch prom∞nn²ch. V∞tÜinou toto okno nenφ pot°eba, proto₧e v∞tÜinu prom∞nn²ch odchytßte oknem Variables, ale obΦas se hodφ, kdy₧ chcete po celou dobu trvßnφ programu sledovat urΦitou prom∞nnou.
  7. Output. KoneΦn∞ poslednφ okno, je v²stupnφ okno, do kterΘho se vypisujφ hlßÜky debuggeru. Existujφ funkce a makra, kterΘ do tohoto okna vypisujφ zprßvy vßmi urΦenΘ. Nynφ tam pouze vidφte, kterΘ dynamickΘ knihovny systΘm naΦetl pro vßÜ program.

DobrΘ rady:

A to je asi tak vÜechno. Tato problematika je docela rozsßhlß, tak₧e kdybyste se cht∞li na n∞co zeptat, staΦφ mi napsat.   

                                                                                                                                                                                                                                                                                                                   Ji°φ Formßnek