background image

VIII. Wyszukiwanie błędów

Środowisko Visual Studio 2010 integruje narzędzia pozwalające programiście efektywnie pro-

jektować aplikację. Wcześniejsze ćwiczenia wykorzystywały edytor i kompilator w celu uzyskania 

działającej aplikacji. Edytor, kontrolując w sposób ciągły wprowadzany kod źródłowy, pozwala progra-

miście skupić się na implementowaniu pomysłów. „Pomocna dłoń” edytora przejawia się w wielu 

aspektach. Po pierwsze, dla wybranego typu projektu tworzy on standardowe pliki kodu źródłowego. 

Przykładem tego działania jest plik zawierający procedurę Main. Inny rodzaj wspomagania polega na 

uzupełnianiu kodu źródłowego elementami, które muszą wystąpić ze względu na wymagania składni 

języka. Przypomnijmy w tym miejscu słowa kluczowe 

End Sub

 (

End Function

) dodawane przez 

edytor w chwili tworzenia nowego wiersza (naciśnięcia klawisza Enter) po zakończeniu wprowadza-

nia nagłówka procedury (funkcji), ponadto edytor uzupełnia deklaracje parametrów o słowo kluczowe 

ByVal

. Edytor udziela także podpowiedzi na temat wskazanego elementu kodu źródłowego. Progra-

miści pracujący w różnych językach programowania z pewnością doceniają tworzenie przez edytor 

wielu konstrukcji po wpisaniu charakterystycznego słowa kluczowego i dwukrotnym naciśnięciu tabu-

latora.

Do najprostszych błędów popełnianych w trakcie pisania kodu źródłowego należą tzw. literówki. 

Błędy tego typu wychwytuje edytor tekstowy. Polega to na ciągłym porównywaniu wpisywanych przez 

programistę słów z zadeklarowanymi wcześniej typami, zmiennymi, funkcjami itp. elementami środo-

wiska.   Jeśli   dany   ciąg   znaków   nie   został   wcześniej   zadeklarowany,   innymi   słowy   jest   nieznany 

dla środowiska, to zostanie on podkreślony falowaną, niebieską linią. Podkreślenie służy w ogólności 

do wskazywania błędów składniowych języka. Zaliczają się do nich np. użycie zmiennych, które nie 

zostały wcześniej zadeklarowane, pominięcie wymaganego elementu deklaracji, użycie niedozwolo-

nych w kodzie źródłowym znaków.

Kolejne ćwiczenie przypomina wybrane działania edytora wspomagające programistę.

Ćwiczenie 95
Zaobserwować wspomagające działania edytora kodu źródłowego.

1. Utwórz projekt aplikacji konsolowej.

2. Zdefiniuj w części deklaracyjnej modułu enumerację RodzajOpisu. Zauważ, że po wpisa-

niu słów Enum RodzajOpisu i naciśnięciu klawisza Enter pojawia się wprawdzie komplet-

ny blok struktury, ale nazwa RodzajOpisu jest podkreślone niebieską, falowaną linią.

3. Naprowadź kursor myszy na podkreślone słowo i zapoznaj się z podpowiedzią.

Przykład.

Podpowiedź wskazuje na konieczność umieszczenia chociaż jednego elementu w bloku enu-

meracji. Warto zwracać uwagę na wszelkie podpowiedzi zawierające słowo must – musieć.

background image

4. Wyświetl okno Error List (Lista błędów) wybierając menu View, a następnie polecenie Er-

ror List. Okno można również aktywować używając myszy (jeśli jest wyświetlane) klikając 

zakładkę Error List, lub sekwencją Ctrl+W, Ctrl+E (przy wciśniętym klawiszu Ctrl należy 

wcisnąć kolejno klawisz W i (po zwolnieniu W) klawisz E.

Przykład. Nieaktywna zakładka Error List po nieudanej próbie kompilacji Projekt_103.

5. Zwróć uwagę na pierwszą linię tekstu w kolumnie Description (Opis), zawiera ona widzia-

ną wcześniej podpowiedź, ta jest jednak statyczna, co pozwala wykonywać inne czynno-

ści myszą.

Przykład.

6. Kliknij dwukrotnie opis błędu w oknie Error List:

w  kodzie  źródłowym  zaznaczone  zostało  niebieskim  tłem  słowo  Historia,  „po-

strzegane” przez edytor jako miejsce wystąpienia błędu,

w pasku stanu środowiska widnieje opis błędu.

Przykład.

7. Dodaj w deklaracji struktury stałe Krótki oraz Długi. Zauważ, że zniknęło podkreślenie 

słowa RodzajOpisu oraz wpis w oknie Error List. Gdy środowisko wykona inne zadanie, 

komunikat paska stanu zostanie zastąpiony komunikatem o innym błędzie, lub braku błę-

dów i gotowości środowiska – Ready.

Właściwość środowiska omówiona w ćwiczeniu 95. stanowi wspaniały dodatek ułatwiający pra-

cę programistom niezależnie od stopnia zaawansowania ich umiejętności. Możliwość skupienia się 

background image

wyłącznie na rozwiązywanym zadaniu, a pozostawienie mozolnego wykrywania błędów składni śro-

dowisku, stanowi o wielkiej użyteczności Visual Studio 2010.

Innym zabezpieczeniem przed błędami popełnianymi w kodzie źródłowym jest polecenie Com-

pleteWord   (Uzupełnij   słowo).   Jest   to   polecenie   edycyjne.   Służy   do   uzupełniania   wpisywanych 

do kodu źródłowego słów. Jeśli programista wpisze dość liter, aby edytor mógł zidentyfikować jedno-

znacznie wpisywane słowo, to zostanie ono uzupełnione. Jeśli ilość liter jest niewystarczająca do peł-

nej identyfikacji, to edytor wyświetli listę słów, z której można wybrać pasujące.

Kolejne ćwiczenie ugruntowuje znajomość z oknem Error List oraz zapoznaje z poleceniem 

CompleteWord.

Ćwiczenie 96
Zapoznać się z różnymi wariantami działania polecenia CompleteWord.

1. Rozpocznij deklarowanie w procedurze Main zmiennej DługośćOpisu wpisując: Dim Dłu-

gośćOpisu As.

2. Dopisz spację i zauważ, że edytor w miejscu położenia kursora tekstowego rozwija listę 

pasujących do kontekstu elementów języka.

Przykład.

3. Zamknij listę naciskając klawisz Esc.

4. Wpisz literę R i uruchom polecenie CompleteWord wybierając sekwencję Ctrl+Spacja – 

edytor ponownie rozwija, posortowaną alfabetycznie, listę elementów pasujących do kon-

tekstu, tym razem zaznaczając pierwsze słowo rozpoczynające się od litery R.

background image

Przykład.

5. Zamknij listę naciskając klawisz Esc.

6. Dopisz (świadomie popełniając błąd) literę b tak, aby wprowadzany tekst rozpoczynał się 

od liter Rb.

7. Uruchom ponownie polecenie CompleteWord. Jeśli żaden pasujący do kontekstu ele-

ment nie rozpoczyna się od liter Rb, to edytor nie dokona wyboru (cieniowane tło), za-

znaczy jedynie pierwsze słowo rozpoczynające się od litery R.

Przykład.

8. Usuń dopisaną literę y używając klawisza Backspace, edytor ponownie wyświetla listę 

tak, jak w punkcie 4.

9. Dopisz literę o, na liście zaznaczony zostaje element RodzajOpisu. Zatwierdź wybór kla-

wiszem Enter. (Wybór można również zakończyć klawiszem spacji, co w wielu przypad-

kach jest lepszym rozwiązaniem – nie tworzy nowego wiersza kodu źródłowego, albo 

klawiszem tabulacji – należy jednak pamiętać, że dwukrotne naciśnięcie klawisza tabula-

cji   powoduje   wstawienie   do   kodu   schematu   (jeśli   istnieje)   wprowadzanej   konstrukcji, 

np. For, If, While, Do itd.)

10.Usuń z nazwy RodzajOpisu ciąg znaków zajOpisu i uruchom polecenie CompleteWord. 

Ponieważ inna nazwa nie rozpoczyna się od liter Rod, to edytor automatycznie wybiera 

jedyny pasujący element listy i uzupełnia nazwę.

background image

Polecenie CompleteWord zwalnia programistę z obowiązku zapamiętywania pełnych nazw defi-

niowanych typów, deklarowanych zmiennych itp. Wystarczy pamiętać początkowe znaki nazw, resztą 

zajmie się edytor.

Konieczna jest w tym miejscu uwaga przypominająca o konsekwentnym stosowaniu metodyki 

tworzenia nazw. Programista stosujący przedrostki wskazujące na typ zmiennej ułatwia sobie odnale-

zienie   zmiennej  na  liście  elementów  wyświetlanych  w  wyniku   uruchomienia  polecenia   Complete-

Word.

Polecenie można uruchomić w każdym miejscu kodu źródłowego. W pewnych przypadkach li-

sta rozwija się automatycznie, bez udziału programisty, np. po słowie As i spacji, po kropce, gdy od-

wołujemy się do pól zmiennej strukturalnej.

Dotychczasowy kod projektu jest stosunkowo krótki, dlatego łatwo można w nim zauważyć błę-

dy wykryte przez edytor. Biorąc pod uwagę fakt, że projekty z reguły bywają bardziej rozbudowane, a  

także to, że programista może otrzymać fragmenty kodu zawierające błędy, można dojść do wniosku,  

że czasami wyśledzenie pomyłki może okazać się trudne, zwłaszcza jeśli okno Error List nie jest wi-

doczne. Kolejne ćwiczenie ma na celu zobrazowanie takiej sytuacji.

Ćwiczenie 97
Zapoznać się z komunikatami generowanymi na etapie kompilacji projektu.

1. Dołącz do projektu moduł Moje_095 dostarczony wraz z treścią ćwiczeń.

2. Zadeklaruj zmienną Dane typu Historia, posłuży do przechowywania jednego zestawu 

danych. Typ strukturalny Historia jest zdefiniowany w module Moje_095.

3. Zadeklaruj tablicę hiObliczenia o dziesięciu komórkach (najwyższy indeks to 9) typu Hi-

storia.

4. Zadeklaruj zmienną intIleZestawów typu Integer o wartości początkowej równej 0, posłu-

ży do przechowywania liczby zestawów danych pobranych od użytkownika.

5. Skonstruuj pętlę Do z warunkiem sprawdzanym na końcu. Pętla powinna być wykonywa-

na tak długo, jak długo wynik funkcji Wybór wynosi „T”. Funkcja Wybór jest zdefiniowana 

w module Moje_095.

6. Utwórz w pętli konstrukcję wiążącą With dla zmiennej Dane i zaprogramuj w niej:

wykorzystanie procedury Pobierz do pobrania dwóch wartości do pól Dzielna i Dzielnik,

obliczenie wyniku dzielenia wartości pól Dzielna i Dzielnik i przypisanie go do pola Iloraz,

wyświetlenie danych oraz wyniku w formacie pokazanym na rysunku przedstawiającym 

efekt pracy aplikacji (patrz: rys. 47). Wykorzystaj funkcję Wyrównaj (moduł Moje_095).

7. Zaprogramuj po konstrukcji wiążącej With zwiększenie wartości zmiennej intIleZestawów 

o jedność.

background image

8. Utwórz konstrukcję warunkową sprawdzającą czy wartość zmiennej intIleZestawów jest 

mniejsza niż 11. Jeżeli warunek jest spełniony, to wartość zmiennej Dane powinna zostać 

przypisana odpowiedniej komórce tabeli hiObliczenia.

Przykład.

hiObliczenia(intIleZestawów – 1) = Dane

9. Zaprogramuj po pętli Do wywołanie procedury WyświetlHistorię (moduł Moje_095) prze-

kazując jako parametr tablicę hiObliczenia i zmienną intIleZestawów.

10.Spróbuj uruchomić aplikację i zapoznaj się z komunikatem środowiska o postaci:

11. Przerwij kompilację wybierając No.

12.Zapoznaj się z wpisami okna Error List.

Przykład.

13.Znajdź miejsce wystąpienia błędu (dwukrotne kliknięcie we wpis) i napraw go usuwając 

apostrof rozpoczynający komentarz z deklaracją zmiennej Tekst.

background image

Efekt działania programu może być taki jak przedstawiono na rysunku:

Kod źródłowy projektu nie był w tym ćwiczeniu najważniejszy, dlatego poniżej przedstawiono 

jedną z możliwych wersji procedury Main w module startowym projektu:

W punkcie 10. ćwiczenia próbowaliśmy uruchomić aplikację. Program tłumaczący kod źródłowy 

na kod wykonywalny zakomunikował, że podczas translacji odnalezione zostały błędy. Mówi o tym  

treść okna Microsoft Visual Studio – There were build errors. Komunikat kończy się pytaniem, czy 

kontynuować próbę uruchomienia. Do wyboru mamy jedną z dwóch możliwości – przerwać urucha-

mianie (przycisk No), lub kontynuować (przycisk Yes). Przerywając uruchamianie powodujemy po-

wrót do projektowania. Jeżeli potwierdzimy chęć kontynuacji uruchamiania, to zostanie uruchomiona 

ostatnia pozbawiona błędów kompilacja. Jest to szczególnie ważne dla początkujących programistów 

– aplikacja nie działa „mimo błędów”, jak to słyszy się niejednokrotnie – uruchomiona aplikacja, to po 

Rysunek 47: Projekt_103 w działaniu.

background image

prostu efekt działania poprzedniej, pozbawionej błędów, wersji projektu. Kolejne ćwiczenie pokazuje 

istotność powyższych zdań.

Ćwiczenie 98
Dokonać   próby   uruchomienia   aplikacji   projektu,   który   nie   posiada   wcześniejszej, 
pozbawionej błędów, skompilowanej wersji.

1. Utwórz projekt aplikacji konsolowej.

2. Przypisz w procedurze Main zmiennej intLiczbaPrób (nie należy deklarować tej zmiennej, 

chodzi o popełnienie oczywistego błędu) wartość 7.

3. Dokonaj próby uruchomienia aplikacji.

4. Potwierdź chęć kontynuacji mimo wykrytych błędów.

5. Zapoznaj się z komunikatem okna Microsoft Visual Studio.

Przykład. Obserwowana przez ćwiczących treść komunikatu może być odmienna – inna będzie 

ścieżka dostępu.

W komunikacie okna Microsoft Development Environment czytamy:

Visual Studio nie może rozpocząć debugowania ponieważ brakuje podmiotu debugowania (tu 

występuje ścieżka dostępu do pliku wykonywalnego). Proszę skompilować projekt i ponowić próbę.

Skompilowane projekty są przechowywane w folderze o nazwie Debug. Jeśli żadna kompilacja 

nie zakończyła się powodzeniem, ze względu na błędy w kodzie źródłowym, to folder ten nie zawiera  

pliku wykonywalnego.

Ostatni punkt ćwiczenia 97. polegał na usunięciu błędu uniemożliwiającego kompilację. Projekt 

został skompilowany i można uruchomić aplikację. Czy oznacza to, że aplikacja będzie działać po-

prawnie?

Odpowiedź nie jest jednoznaczna. Może się tak zdarzyć, że w czasie pracy aplikacji nie wystą-

pią błędy (zostały podane dwa zestawy danych i program działał poprawnie). Jednak istnieje prawdo-

podobieństwo, że zbudowany przez nas projekt, wobec splotu różnych okoliczności – szczególny ze-

staw danych, błąd logiczny w implementacji algorytmu, błędny algorytm itd., będzie generował błędne 

wyniki lub będzie pracował nieprzewidywalnie, albo też będzie przerywał działanie. Usuwanie takich 

background image

błędów możliwe jest jedynie wtedy, gdy znamy miejsce i przyczynę ich wystąpienia. Pierwotnym za-

gadnieniem jest odnalezienie w kodzie źródłowym miejsca zawierającego instrukcję, której wykona-

nie kończy się błędem. Niestety, często jest to dopiero początek żmudnej drogi odszukiwania pier-

wotnego źródła błędu. Na każdym kroku działania programisty w tym zakresie wspiera debugger – 

narzędzie śledzące powiązanie wykonywanej instrukcji kodu wykonywalnego z kodem źródłowym. 

Aby wykorzystać to narzędzie należy uruchamiać aplikację projektu używając debuggera. Kolejne 

ćwiczenie rozpoczyna serię dotyczącą błędów czasu wykonania, czyli takich, które pojawiają się już 

w trakcie działania aplikacji. 

Ćwiczenie 99
Zapoznać się z błędami czasu wykonania.

1. Uruchom aplikację projektu utworzonego w ćwiczeniu 95. włączając mechanizm debug-

gera Visual Studio 2010, w tym celu rozwiń menu Debug i zapoznaj się z występującymi  

w nim grupami poleceń, zwróć uwagę na polecenie Start Debugging – F5, włącza ono 

debugowanie. Zwróć uwagę na ikonę polecenia, występuje ona w pasku narzędzi De-

bug.

2. Wprowadź jako pierwszą dzielną dowolną liczbę, a jako pierwszy dzielnik tekst: Duża 

liczba.

3. Zauważ, że działanie aplikacji zostało wstrzymane, uaktywnione zostało okno Visual Stu-

dio 2010 z tym fragmentem kodu źródłowego, w którym nastąpił błąd podczas pracy apli-

kacji. Linia z poleceniem, które zakończyło się błędem jest wyróżniona zmienionym kolo-

rem tła oraz strzałką na lewym marginesie okna. Dodatkowo wyświetlone jest okno z opi-

sem błędu.

4. Zapoznaj się z treścią okna z opisem błędu.

Przykład.

background image

5. Zamknij okno ostrzeżenia.

6. Zakończ aplikację wybierając polecenie Stop Debugging z menu Debug.

Objaśniając słowo „debugowanie” można napisać, że oznacza ono czynność polegającą na 

usuwaniu błędów. Rozpoczyna się od momentu uruchomienia procesu poleceniem Start z menu De-

bug, a kończy w chwili zakończenia aplikacji, lub po wybraniu polecenia Stop Debugging.

Wróćmy do objaśnienia reakcji środowiska. Aplikacja pobrała z konsoli ciąg znaków „Duża licz-

ba”, dalej nastąpiła próba konwersji tego tekstu na liczbę rzeczywistą. Próba ta zakończyła się niepo-

wodzeniem. Program debugujący zgłosił ten problem, komunikując, że wyjątek typu  

InvalidCastE-

xception

  nie został obsłużony, a także dodał informacje, że „Konwersja ciagu „Duża liczba” na typ 

'Double' nie jest dozwolone”.

Informacja dodatkowa jest czytelna – nie można przekonwertować na liczbę ciągu znaków, któ-

ry nie reprezentuje liczby. Kolejne ćwiczenie pokaże jakie mogą być efekty pracy takiej aplikacji dla 

jej użytkownika. Aby uprościć wykonanie ćwiczenia skopiuj plik wykonywalny (*.exe) z katalogu De-

bug projektu wykonanego w ćwiczeniu 95. do katalogu głównego dysku (\).

Ćwiczenie 100
Zapoznać się z „problemami” użytkownika aplikacji.

1. Uruchom wiersz poleceń systemu operacyjnego (cmd.exe) i przejdź do katalogu główne-

go wydając polecenie „cd \”.

2. Uruchom aplikację w wierszu poleceń i wprowadź jako dzielną dowolną liczbę, a jako 

dzielnik tekst: Duża liczba.

Systemy operacyjne Windows w swoich kolejnych wersjach rozwojowych nieco odmiennie re-

agują na błędy czasu wykonania. Wspólna reakcja, to wyświetlenie okna Projekt_103. Okno to może 

zawierać informację o tym, że wystąpił problem z tą aplikacją i zostanie ona zamknięta (XP), może  

także informować o tym, że program przestał działać (Vista, 7). W Windows XP okno pozwala rozpo-

cząć debugowanie – Just-In-Time Debugging, wysłać (albo nie) raport o błędach. Okno należy za -

mknąć wybierając przycisk Nie wysyłaj. W Windows Vista (7), po zakończeniu zbierania informacji 

związanych z zatrzymaniem aplikacji, zostanie wyświetlone dodatkowe okno Projekt_103, pozwalają-

ce przesłać informacje o niepowodzeniu. Należy anulować każde z okien.

background image

3. Zauważ treści wyświetlone w wierszu poleceń:

Łatwo wyobrazić sobie „radość” użytkownika po obejrzeniu takiego obrazka.

4. Zamknij wiersz poleceń (Exit).

5. Uruchom Explorator Windows i uruchom ponownie aplikację podając te same dane i za-

mykając okno systemu operacyjnego informujące o błędzie.

Wyświetlane komunikaty mogą być dla użytkownika niezrozumiałe, a jeśli nawet są zrozumiałe, 

to aplikacja z jego punktu widzenia nie jest bezpieczna. Instrukcja prowadząca do tych komunikatów, 

sama w sobie, nie jest błędna. Do zatrzymania aplikacji doprowadziło działanie użytkownika, jednak 

to na programiście spoczywa ciężar przewidywania takich sytuacji. Sprawdzenie jak aplikacja reaguje 

na dzielnik równy zeru pozostawia się ćwiczącym do samodzielnego wykonania.

Zaprogramowanie aplikacji odpornej na nieprawidłowe dane nie jest łatwe, ale możliwe. Innym 

rodzajem błędów są te wynikające z nieprawidłowej logiki, lub zastosowania nieprawidłowego bądź 

błędnego algorytmu. Kolejne ćwiczenie pokazuje taki błąd projektu.

Ćwiczenie 101
Zapoznać się z działaniem aplikacji zawierającej błąd logiczny.

1. Uruchom debugowanie aplikacji (Projekt_103) i wprowadź więcej niż 10 zestawów da-

nych. Należy pamiętać, że aplikacja przechowuje w tablicy tylko 10 pierwszych zesta-

wów.

background image

2. Odpowiedz „N” po wprowadzeniu danych. Zauważ, że aplikacja nie wyświetla historii da-

nych, ale jej praca zostaje wstrzymana, a debugger wyświetla komunikat:

IndexOutOfRangeException was unhandled – nie został obsłużony wyjątek przekroczenia za-

kresu indeksów.

Index was outside the bounds of the array – indeks nie znajdował się wewnątrz ograniczeń ta-

blicy.

3. Zamknij okno komunikatu.

4. Zauważ,   że   aplikacja   nie   zakończyła   działania,   edytor   zaznacza   wykonywany   wiersz 

kodu kolorem żółtym. (Nie należy przerywać działania debuggera, będzie ono kontynu-

owane w kolejnym ćwiczeniu.)

5. Zastanów się dlaczego w procedurze WyświetlHistorię, w trakcie wykonywania pętli, war-

tość zmiennej sterującej pętlą przekracza maksymalny indeks tablicy.

Odpowiedź na pytanie zawarte w ćwiczeniu wydaje się oczywista. Widocznie górne ogranicze-

nie zmiennej sterującej pętlą jest większe niż 9 (maksymalny indeks tablicy hiObliczenia). Górne 

ograniczenie ma postać: LiczbaWpisow – 1. „Ktoś” pamiętał o odjęciu jedynki, aby przetworzyć natu-

ralną „liczbę wpisów” na, rozpoczynający się od zera, indeks. Skoro indeks przekroczył wartość 9, to 

znaczy, że LiczbaWpisow przekroczyła wartość 10, ale to nie wina procedury WyświetlHistorię. Pro-

cedura otrzymuje liczbę wpisów jako parametr.

W tym momencie kończą się możliwości analizy kodu źródłowego. Projekt celowo jest nieskom-

plikowany, aby możliwe było naturalne przejście od pełnej wiedzy programisty na temat utworzonego 

kodu do wykorzystania debuggera.

background image

Wydaje się, że należy przejść do miejsca wywołania procedury WyświetlHistorię i będzie można 

kontynuować analizę. Jednak należy zdawać sobie sprawę z tego, że projekt może zawierać więcej  

niż jedno wywołanie procedury WyświetlHistorię, a wtedy nie będzie wiadomo, do którego wywołania 

się cofnąć. Na szczęście debbuger nie tylko wyświetla błędy, ale także zapamiętuje wywołania, które 

poprzedziły wystąpienie błędu. Kolejne ćwiczenie pokazuje wykorzystanie tej funkcjonalności.

Ćwiczenie 102
Zapoznać się z możliwością wykorzystania zapamiętanych przez debugger wywołań do 
odnalezienia błędu logicznego w kodzie źródłowym.

1. Rozwiń menu Debug i wyświetl polecenia grupy Windows (postaraj się zapamiętać na-

zwy poleceń tej grupy). Zwróć szczególną uwagę na polecenie Call Stack (Stos wywo-

łań). 

2. Uaktywnij okno stosu wywołań. Będzie ono zawierało treść zbliżoną do przedstawionej 

w poniższym przykładzie.

Przykładowy obraz okna Call Stack.

3. Zapoznaj się z listą wywołań. Żółta strzałka wskazuje ostatnie wywołanie metody. Poniżej 

wyświetlone są wywołania poprzedzające ostatnie.

4. Wyświetl miejsce wywołania metody poprzedzającej wywołanie procedury WyświetlHisto-

rię, w tym celu kliknij dwukrotnie drugi wpis w oknie Call Stack. Zauważ, że został zazna-

czony (jasnozielone tło) wiersz z wywołaniem procedury WyświetlHistorię.

5. Prześledź poprzedzające wiersz instrukcje w celu odnalezienia źródła błędu, pamiętając, 

że drugi parametr (intIleZestawów) przekazany do procedury miał wartość większą niż 

10, a to spowodowało przekroczenie indeksu tablicy.

Odnalezienie wiersza kodu źródłowego, w którym następuje powiększenie wartości zmiennej in-

tIleZestawów o jeden, nie jest trudne. Znajduje się on w pętli Do. Wartość tej zmiennej jest następnie  

przekazywana   jako   parametr.   Krótki   namysł   pozwala   zrozumieć   problem   –   intIleZestawów   zlicza 

wszystkie podane zestawy. Jest to zgodne z logiką działania pętli, jednak procedura WyświetlHistorię 

powinna wyświetlać maksymalnie 10 zestawów. Sposobów na rozwiązanie problemu jest wiele i wy-

bór jednego z nich pozostawia się ćwiczącym jako zadanie do samodzielnego wykonania. Nasuwa 

się w tym miejscu uwaga praktyczna, modyfikacja kodu powinna obejmować najmniejszy możliwy 

blok. W ćwiczeniu tym blokiem jest procedura WyświetlHistorię, to ona powinna być przygotowana 

pod względem bezpieczeństwa na różne zestawy danych. Wydaje się, że sprawdzenie czy drugi pa-

background image

rametr nie ma zbyt dużej wartości powinno nastąpić przed wykonaniem pętli. Pozwoliłoby to na unik-

nięcie przekroczenia zakresu indeksów.

Przed edycją kodu należy przerwać debugowanie, lub włączyć zezwolenie na edycję kodu pod-

czas przerwania wykonywania aplikacji (odpowiednia opcja dostępna jest po wybraniu menu Tools, 

następnie polecenia Options i zakładki Edit and Continue folderu Debugging – Enable Edit and Conti-

nue).

Programy zawierają ciągi obliczeń, procedury i funkcje. Korzystając ze sprawdzonych wcześniej 

procedur i funkcji możemy założyć, że będą one działać bezbłędnie również w projektowanej aplika -

cji. Może się jednak zdarzyć, że np. ciąg obliczeń doprowadzi do nieprawidłowego wyniku. W takim 

przypadku należałoby przeanalizować algorytm i porównać go z wykonywanym kodem. Jeśli wyniki 

otrzymane tradycyjną metodą – papier i ołówek, różnią się od wyników otrzymywanych w aplikacji, to 

należy   domniemywać,   że   implementacja   algorytmu   zawiera   błąd.   Kolejne   ćwiczenie,   w   oparciu 

o działania na liczbach zespolonych, zobrazuje opisany przypadek.

Przypomnienie.   Jednostka   urojona,   to   liczba   i   o   następującej   właściwości:   i

2

=-1.   Wyrażenie 

o postaci a+ib nazywa się liczbą zespoloną, przy tym a nazywa się częścią rzeczywistą, b częścią 

urojoną liczby zespolonej. Dla liczb zespolonych z

1

=a

1

+ib

1

 oraz z

2

=a

2

+ib

2

 definiuje się operacje aryt-

metyczne:

Dodawanie

z

1

z

2

=

a

1

ib

1

a

2

ib

2

=

a

1

a

2

ib

1

b

2

Odejmowanie

z

1

z

2

=

a

1

ib

1

−

a

2

ib

2

=

a

1

a

2

b

1

b

2

Mnożenie

z

1

z

2

=

a

1

ib

1



a

2

ib

2

=

a

1

a

2

b

1

b

2

a

1

b

2

a

2

b

1

Dzielenie

z

1

z

2

=

a

1

ib

1

a

2

ib

2

=

a

1

ib

1

a

2

ib

2

a

2

ib

2

a

2

ib

2

=

a

1

a

2

b

1

b

2

a

2

b

1

a

1

b

2

a

2

2



b

2

2

=

a

1

a

2

b

1

b

2

a

2

2



b

2

2

i

a

2

b

1

a

1

b

2

a

2

2



b

2

2

Błąd będzie zawarty w funkcji obliczającej iloraz dwóch liczb zespolonych. Zatem wyniki będą 

oczywiście fałszywe.

Ćwiczenie 103
Zapoznać się z kodem źródłowym Projekt_103. Porównać wyniki działania aplikacji tego 
projektu z wynikami działania aplikacji Projekt_103OK.exe.

1. Otwórz Projekt_103 i zapoznaj się z jego kodem źródłowym, w tym z kodem modułu Ze-

spolone.vb.

2. Uruchom aplikację projektu i wprowadź dane, nie kończ działania aplikacji.

background image

3. Uruchom aplikację Projekt_103OK.exe i wprowadź dane identyczne jak w poprzednim 

punkcie. Zwróć uwagę na różnicę wartości obliczonych przez oba programy ilorazów.

4. Zakończ działanie obu aplikacji.

Procedura  Main  Projekt_103   zawiera   kilka   instrukcji   wynikających   z   potrzeb   użytkownika. 

Na program składają się: pobranie wartości dwóch liczb zespolonych i wyświetlenie wyników czte-

rech podstawowych działań arytmetycznych. Moduł Zespolone zawiera funkcje przydatne do wykony-

wania obliczeń. Kod źródłowy niektórych z tych funkcji został skomplikowany, aby pokazać możliwo-

ści debuggera.

Przyjrzyjmy się ponownie deklaracji różnicy dwóch liczb zespolonych:

z

1

z

2

=

a

1

ib

1

−

a

2

ib

2

=

a

1

a

2

b

1

b

2

Zauważmy, że możemy zastąpić odejmowanie sumowaniem:

z

1

z

2

=

a

1

ib

1

−

a

2

ib

2

=

a

1

a

2

ib

1

b

2

Liczba w nawiasie występującym po znaku sumy, to liczba przeciwna do pierwotnego odjemni -

ka. (Właściwością liczb przeciwnych jest to, że ich suma jest zerem.) Można zatem odejmowanie za-

stąpić dodawaniem liczby przeciwnej do odjemnika. Taki algorytm został zaimplementowany w funkcji 

Różnica. Oznacza to, że funkcja Różnica, w celu obliczenia wyniku, wywołuje funkcję Suma prze-

kazując jako drugi parametr liczbę przeciwną do odjemnika.

W związku z powyższym śledzenie przepływu sterowania w aplikacji staje się utrudnione. De-

bugger pozwala w tym zakresie, między innymi, na:

wstrzymanie wykonywania aplikacji – decyzję o wstrzymaniu podejmuje programista w trakcie 

wykonywania aplikacji, a edytor zaznacza w kodzie źródłowym instrukcję, która będzie wyko-

nywana jako następna, albo wykonywaną instrukcję, jeśli przerwanie nastąpiło przed zakoń-

czeniem jej wykonywania,

wstrzymanie   wykonywania   aplikacji   przed   wykonaniem   określonej   instrukcji   –   decyzję 

o wstrzymaniu podejmuje programista na etapie projektowania; po zatrzymaniu, edytor ozna-

cza instrukcję, która będzie wykonywana jako następna,

wstrzymanie wykonywania aplikacji przed wykonaniem określonej instrukcji, ale tylko wtedy, 

gdy spełnione są wyspecyfikowane przez programistę warunki – decyzja o wstrzymaniu oraz 

warunki wstrzymania ustalane są na etapie projektowania,

wykonanie pojedynczej instrukcji,

wykonanie metody bez śledzenia wykonywania kolejnych instrukcji bloku metody.

We wszystkich wymienionych przypadkach możliwy jest przegląd aktualnych wartości zmien-

nych. Wstrzymanie wykonywania aplikacji „na żądanie” wykonuje się w trakcie działania aplikacji. Ilu-

background image

struje to kolejne ćwiczenie, które dodatkowo zapoznaje ze sposobami krokowego (instrukcja po in-

strukcji) wykonywania aplikacji.

Ćwiczenie 104
Zapoznać   się   z   możliwością   wstrzymania   pracy   aplikacji   i   śledzenia   wykonywania 
kolejnych instrukcji kodu źródłowego.

1. Uruchom   debugowanie   aplikacji   Projekt_103.   Początkowe   działanie   programu   polega 

na pobraniu od użytkownika wartości części rzeczywistej pierwszej liczby zespolonej. Nie 

należy wprowadzać tej wartości.

2. Wstrzymaj działanie aplikacji przed wprowadzeniem wartości części rzeczywistej pierw-

szej liczby zespolonej, w tym celu:

uaktywnij   Visual   Studio   2010   (przełącz   aktywność   z   konsoli   aplikacji   Projekt_103 

na okno środowiska),

rozwiń   menu   Debug   i   zauważ,   że   aktywne   jest   polecenie   Break  All   –   Ctrl+Break 

(Przerwij wszystko),

wybierz polecenie Break All i zauważ, że w kodzie źródłowym pojawiła się jasnozielo-

na strzałka wskazująca aktualnie wykonywaną instrukcję przypisania – nie została 

ona zakończona, gdyż użytkownik nie wprowadził wartości.

3. Uaktywnij konsolę aplikacji Projekt_103 i wprowadź wartość części rzeczywistej pierw-

szej liczby zespolonej. Zauważ, że aplikacja nie wykonuje dalszych instrukcji.

4. Uaktywnij Visual Studio 2010 – edytor w dalszym ciągu wskazuje, że instrukcja przypisa-

nia jest w trakcie wykonywania; tekst podany przez użytkownika został pobrany przez in-

strukcję ReadLine, lecz nie został jeszcze skonwertowany na typ Double. Konwersja zo-

stanie wykonana jako kolejny krok.

5. Spowoduj wykonanie kolejnego kroku w działaniu aplikacji – konwersji tekstu na typ Do-

uble, w tym celu:

rozwiń menu Debug i zapoznaj się z trzema instrukcjami rozpoczynającymi się od sło-

wa Step:

Step Into – F8 (Krok do) – powoduje wykonanie kolejnej instrukcji kodu źródło-

wego, a jeśli instrukcja wywołuje jakąkolwiek metodę, której deklaracja jest do-

stępna w projekcie, to kolejną instrukcją, zaznaczoną jako instrukcja do wykona-

nia, będzie pierwsza instrukcja metody; oznacza to, że polecenie Step Into po-

woduje kolejne wykonywanie wszystkich instrukcji kodu,

Step Over – Shift+F8 (Krok nad) – powoduje wykonanie kolejnej instrukcji kodu 

źródłowego, a jeśli instrukcja wywołuje jakąkolwiek metodę, to instrukcje bloku 

metody będą wykonane bez śledzenia; oznacza to, że polecenie Step Over po-

background image

mija śledzenie metod wywoływanych przez wykonywaną instrukcję kodu źródło-

wego, działanie takie jest przydatne, gdy programista jest przekonany, że meto-

dy wywoływane w instrukcji nie powodują błędu, który chce wyśledzić,

Step Out – Ctrl+Shift+F8 (Krok na zewnątrz) – powoduje wykonanie wszystkich 

instrukcji do końca bloku, w którym znajduje się instrukcja wskazywana przez 

edytor; oznacza to, że polecenie Step Out powoduje zakończenie śledzenia wy-

konywania instrukcji w danym bloku, działanie takie jest przydatne, gdy progra-

mista jest przekonany, że pozostałe instrukcje bloku nie powodują błędu, który 

chce wyśledzić;

zauważ, że przyciski poznanych poleceń znajdują się na pasku narzędzi Debug,

uruchom polecenie Step Into,

zauważ, że edytor zaznaczył (żółte tło) instrukcję, która ma być wykonana jako na-

stępna i jest to instrukcja przypisania (warto uzmysłowić sobie, że instrukcja ta była 

poprzedzona pobraniem wartości z konsoli i skonwertowaniem jej na typ Double).

6. Spowoduj wykonanie instrukcji przypisania – Step Into (lub Step Over).

7. Spowoduj wykonanie instrukcji programu, do momentu, aż kolejną instrukcją do wykona-

nia będzie Console.WriteLine w wierszu 17.

8. Uruchom polecenie Step Into. Zauważ, że edytor wyświetla nagłówek funkcji Zespolona-

Tekstem z modułu Zespolone.

9. Załóż, że funkcja jest napisana poprawnie i można pominąć jej krokowe wykonanie. Uru-

chom polecenie Step Out.

10.Przerwij stan przerwania, w którym znajduje się aplikacja, w tym celu:

rozwiń menu Debug i zauważ, że aktywne jest polecenie Continue – F5 (Kontynuuj), 

służy ono tak, do rozpoczęcia pracy aplikacji, jak i do wyprowadzenia jej ze stanu 

przerwania,

uruchom polecenie Continue (odpowiedni przycisk znajduje się również na pasku na-

rzędzi Debug).

11. Dokończ pracę aplikacji.

Polecenia  Step  pozwalają programiście zapanować  nad procesem  krokowego  wykonywania 

aplikacji. Ich użycie możliwe jest jedynie w trybie przerwania pracy aplikacji. Przerwanie pracy aplika-

cji w przypadku, gdy oczekuje ona na działania ze strony użytkownika nie nastręcza trudności. Jed-

background image

nak, po wprowadzeniu danych (obu liczb zespolonych), próba zatrzymania, np. przed wykonaniem 

mnożenia, musi zakończyć się niepowodzeniem. W takim przypadku, decyzję o wstrzymaniu pracy 

programista musi podjąć już  na etapie projektowania. Narzędziem, które pozwala na takie działanie  

jest punkt przerwania (ang. breakpoint). Kolejne ćwiczenie pokazuje metodykę umieszczania punk-

tów przerwania w kodzie źródłowym.

Ćwiczenie 105
Zapoznać się z metodyką umieszczania punktu przerwania w kodzie źródłowym.

1. Ustaw kursor tekstowy w wierszu procedury Main poświęconym obliczeniu i wyświetleniu 

iloczynu liczb zespolonych (linia 34 modułu – aby włączyć numerację wierszy w kodzie 

źródłowym wybierz menu Tools, polecenie Options, folder Text Editor\Basic

7

, pole wyboru 

Line numbers).

2. Rozwiń menu Debug i zapoznaj się z poleceniem Toggle Breakpoint – F9 (Przełącz punkt 

przerwania – słowo „przełącz” oznacza w tym kontekście: włącz jeśli jest wyłączony, wy-

łącz jeśli jest włączony).

3. Włącz punkt przerwania w 9. wierszu kodu źródłowego, w tym celu uruchom polecenie 

Toggle Breakpoint. 

4. Zauważ, zmiany wprowadzone przez edytor:

tło wiersza z punktem przerwania zostało zmienione na brązowe,

na lewo od numeru wiersza pojawił się symbol brązowej, oświetlonej półkuli – zasad-

niczy wskaźnik punktu przerwania.

5. Sprawdź działanie punktu przerwania uruchamiając debugowanie.

6. Zakończ działanie aplikacji poleceniem Stop Debugging z menu Debug.

Aplikacja zatrzymuje się po wyświetleniu sumy i różnicy liczb zespolonych. Edytor wskazuje in-

strukcję z punktem przerwania (żółta strzałka na brązowej kuli punktu przerwania, żółte tło instrukcji, 

która będzie wykonana jako następna). Dalsze debugowanie polega na wykorzystaniu poleceń z gru -

py Step. Prosty punkt przerwania można ustawić także używając myszy.  Polega to na kliknięciu 

w obszarze po lewej stronie numeracji, gdy kursor myszy wskazuje w lewą stronę (gdy kursor wska-

zuje w prawą stronę następuje zaznaczenie wiersza

8

), na wysokości wiersza, w którym ma się poja-

wić punkt przerwania.

7 Jeśli pole wyboru Show all settings nie jest zaznaczone, to pole wyboru Line numbers znajduje się w podfolderze Edi -

tor folderu Basic.

8 W poprzednich wersjach środowiska zadanie było nieco łatwiejsze, gdyż obszar punktów przerwania oznaczony był 

kolorem szarym (pionowa szara belka).

background image

Punkty przerwania można usuwać pojedynczo, lub wszystkie, a także wyłączać ich działanie 

bez usuwania. Do usunięcia wszystkich punktów przerwania służy polecenie Delete All Breakpoints 

z menu Debug. Pojedynczy punkt przerwania można usunąć wybierając grupę poleceń Breakpoint,  

a następnie polecenie Delete Breakpoint z menu kontekstowego wiersza z punktem przerwania, albo 

klikając półkulę w belce po lewej stronie edytora. Do przeglądania punktów przerwania służy okno 

Breakpoints (menu Debug, grupa poleceń Windows, polecenie Breakpoints).

Punkt przerwania może działać warunkowo, to znaczy – przerwanie nastąpi tylko wtedy, gdy ma 

nastąpić wykonanie instrukcji z punktem przerwania i jest spełniony pewien ustalony warunek. Kolej-

ne ćwiczenie poświęcone jest ustaleniu warunku dla istniejącego punktu przerwania.

Ćwiczenie 106
Ustalić, że ustalony w pliku Start_105.vb punkt przerwania ma działać tylko wtedy, gdy 
spełniony jest pewien warunek.

1. Uaktywnij okno Breakpoints i zapoznaj się z jego paskiem narzędzi.

2. Zaznacz w oknie jedyny punkt przerwania.

3. Uruchom okno Breakpoint Condition, w tym celu:

rozwiń menu kontekstowe dla zaznaczonego punktu przerwania i zapoznaj się z do-

stępnymi poleceniami,

wybierz polecenie Condition – pojawia się okno Breakpoint Condition,

zapoznaj się z zawartością okna.

Przykład.

Komunikat okna głosi: W chwili osiągnięcia punktu przerwania, przeliczane jest wyrażenie i jeśli 

jego wartość wynosi true, albo zmieniła się, to punkt przerwania zadziała.

4. Ustal, że punkt przerwania ma działać tylko wtedy, gdy część rzeczywista zmiennej Z1 i  

część rzeczywista zmiennej Z1 są równe, w tym celu:

pozostaw zaznaczenie w polu wyboru Condition (pozwala włączyć lub wyłączyć dzia-

łanie warunku wprowadzonego do pola tekstowego),

background image

ustal, wybierając odpowiednią opcję, że warunek powinien zadziałać nie wtedy, gdy 

wartość wyrażenia się zmieni (Has changed), ale wtedy gdy ma wartość true (Is true),

wpisz w pole tekstowe warunek: Z1.Re=Z2.Re.

zatwierdź wprowadzone zmiany przyciskiem Ok,

zauważ, że punkt przerwania w oknie Breakpoints (także w edytorze kodu źródłowe-

go) otrzymał dodatkowo biały znak + oznaczający, że punkt przerwania posiada do-

datkowe ustawienia.

5. Sprawdź działanie punktu przerwania przy różnych zestawach danych.

Debugowanie umożliwia ustalenie wielu dróg poszukiwania błędu w kodzie źródłowym. Wcze-

śniej   zostało   zasygnalizowane,   że   w   trybie   przerwania   istnieje   możliwość   przeglądania   wartości 

zmiennych użytych w programie. Najłatwiejszym sposobem jest w tym zakresie wykorzystanie okna 

Autos. Okno to, uaktywniane w trybie przerwania poleceniem Autos (grupa poleceń Windows w menu 

Debug) wyświetla wartości zmiennych używanych w zaznaczonej instrukcji oraz w instrukcji poprzed-

niej. Okno pokazuje nazwę, wartość oraz typ zmiennej. Zmienne złożone można rozwijać używając 

ikony ze znakiem +. Kolejne ćwiczenie pokazuje wykorzystanie okna Autos.

Ćwiczenie 107
Śledzić wartości zmiennych w trakcie przerw w wykonywaniu aplikacji.

1. Ustaw punkt przerwania w nagłówku procedury Main, w tym celu:

wybierz przycisk New w pasku narzędzi okna Brakpoints,

wybierz polecenie Break at Function pojawi się jedna z kilku wersji okna New Break-

point,

wpisz w pole tekstowe nazwę procedury – Main,

zatwierdź zmiany przyciskiem Ok,

zauważ, że punkt przerwania wskazywany jest jedynie przez brązową półkulę.

2. Uruchom   debugowanie.   Wykonywanie   aplikacji   zostaje   przerwane   przed   wykonaniem 

którejkolwiek instrukcji procedury Main, której nagłówek jest zaznaczony żółtym tłem.

3. Uaktywnij okno Autos wybierając menu Debug, grupę poleceń Windows i polecenie Au-

tos – Ctrl+Alt+V, A (po wybraniu sekwencji Ctrl+Alt+V, należy uderzyć klawisz z literą A).

4. Wykonaj   polecenie   Step   Over   przechodząc   kolejno   przez   instrukcje   procedury   Main, 

aż do osiągnięcia wiersza nr 13.

5. Rozwiń w oknie Autos pola zmiennej Z1.

background image

6. Wykonaj polecenie Step Over przechodząc kolejno przez wszystkie instrukcje procedury 

Main, jeśli to potrzebne, w odpowiednich chwilach wprowadź dane. Obserwuj zmiany za-

chodzące w oknie Autos.

Śledzenie zmian wartości zmiennych w oknie Autos ułatwia fakt, że każda wartość, która uległa 

zmianie jako ostatnia, zaznaczana jest kolorem czerwonym. Innym sposobem na przeglądanie warto-

ści jest wykorzystanie okna Locals. Pokazuje ono wartości zmiennych, które są lokalne w bloku in-

strukcji, który jest aktualnie wykonywany. Okno Locals uruchamia się w podobny sposób jak okno Au-

tos. Prześledzenie zmian wartości lokalnych w trakcie przerw w wykonywaniu aplikacji pozostawia 

się ćwiczącym do samodzielnego wykonania. Ostatnim z omawianych sposobów przeglądania warto-

ści zmiennych jest wykorzystanie okna Watch. Oprócz walorów proponowanych przez okna Autos i 

Locals   okna   Watch   pozwalają   wyświetlać   również   wartości   wyrażeń,   a   także   zmieniać   wartości 

zmiennych. Kolejne ćwiczenie polegać będzie na wykorzystaniu pierwszego okna Watch.

Ćwiczenie 108
Wykorzystać   okno   Watch   do   przeglądania   wartości   zmiennych   i   wyrażeń   oraz 
modyfikacji wartości zmiennych.

1. Uruchom debugowanie i włącz okno Watch 1 (Debug\Windows).

2. Dodaj do okna możliwość śledzenia wartości pola Re zmiennej Pierwsza, w tym celu klik-

nij puste pole Name w pierwszym wierszu okna i wprowadź nazwę pola do śledzenia – 

Z1.Re.

3. Przeprowadź aplikację przez etap wprowadzania danych.

4. Dodaj do okna możliwość śledzenia wyniku funkcji ZespolonaTekstem dla argumentu Z2, 

w tym celu wprowadź odpowiednie wywołanie – ZespolonaTekstem(Z2) – w polu Name 

drugiego wiersza okna Watch 1.

5. Dodaj do okna możliwość śledzenia wartości iloczynu Z1.Re * Z2.Re.

6. Zmień wartość pola Re zmiennej Z1, w tym celu:

zaznacz pierwszy wiersz w oknie Watch 1,

kliknij dwukrotnie, szybko pole Value – przejdzie ono w tryb edycji,

wprowadź nową wartość i zatwierdź ją,

zauważ zmianę wartości iloczynu w trzecim wierszu okna Watch 1.

Okna Watch pozwalają grupować przeglądane wartości w taki sposób, aby przynieść programi-

ście optymalną liczbę informacji na danym etapie pracy aplikacji. Ułatwia to poszukiwanie błędów 

w kodzie źródłowym.


Document Outline