You are on page 1of 36

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG

Turbo Pascal i Borland


C++Builder. Przykady
Autor: Kazimierz Jakubczyk
ISBN: 83-7197-873-1
Format: B5, stron: 234
Zawiera dyskietk

TWJ KOSZYK
DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Ksika ta adresowana jest do czytelnikw, ktrzy rozpoczli lub wanie rozpoczynaj


swoj przygod z programowaniem. Zawiera ona szereg przykadowych programw
napisanych zgodnie z zasadami dobrego stylu programowania. Wszystkie stworzone
zostay w dwch wersjach: w Turbo Pascalu i C++. Dlatego ksika ta jest szczeglnie
polecana osobom, ktre ju potrafi programowa w Pascalu i chc zapozna si
z jzykiem C++.
W ksice omwiono:

Proste operacje na liczbach


Dziaania na datach
Tworzenie grafiki z wykorzystaniem BGI
Animacje
Tworzenie list jednokierunkowych
Programowanie zorientowane obiektowo

Wymagania stawiane czytelnikowi s niewielkie wystarczy podstawowa umiejtno


programowania, najlepiej w Pascalu.
Do ksiki doczona jest dyskietka z przykadami.

Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl

Spis treci
Wstp ............................................................................................... 7
Rozdzia 1. Operacje na liczbach........................................................................ 11
Ile cyfr ma liczba? .............................................................................................................11
Program LCyf w Pascalu ............................................................................................11
Ptle w Pascalu ...........................................................................................................12
Ptle w C i C++...........................................................................................................13
Program LCyf w C++ .................................................................................................13
Uruchamianie programu w rodowisku programowania............................................14
Odwrcenie kolejnoci bitw liczby .................................................................................15
Program Bity w Pascalu..............................................................................................15
Program Bity w C++...................................................................................................16
Wyraenia przypisujce w C i C++ ............................................................................16
Zapis liczby w notacji rzymskiej.......................................................................................17
Program LRzym w Pascalu.........................................................................................18
Program LRzym w C++..............................................................................................19
Wskaniki a acuchy w C i C++ ...............................................................................20
Wspczynniki Newtona i trjkt Pascala.........................................................................20
Algorytm iteracyjny ....................................................................................................21
Algorytm rekurencyjny...............................................................................................22
Program TPascala w Pascalu ......................................................................................22
Program TPascala w C++ ...........................................................................................24
Tablicowanie funkcji Bessela............................................................................................24
Algorytm obliczania sumy szeregu liczbowego .........................................................25
Program FBessela w Pascalu ......................................................................................26
Program FBessela w C++ ...........................................................................................27
Formatowanie wydruku w funkcji printf ....................................................................28
wiczenia ..........................................................................................................................29

Rozdzia 2. Zadania z kalendarzem .................................................................... 31


Dzie tygodnia i numer dnia w roku.................................................................................31
Algorytmy kalendarzowe............................................................................................32
Modu obliczeniowy Kal w Pascalu ...........................................................................33
Program Dzien w Pascalu ...........................................................................................34
Modu obliczeniowy Kal w C++ ................................................................................35
Program Dzien w C++ ................................................................................................37
Kalendarz miesiczny .......................................................................................................38
Modu Klaw czytania znaku w Pascalu ......................................................................38
Modu Klaw czytania znaku w C++ ...........................................................................39

Turbo Pascal i Borland C++. Przykady


Program KMies w Pascalu..........................................................................................40
Program KMies w C++...............................................................................................42
Kolorowanie kalendarza....................................................................................................44
Algorytm Gaussa wyznaczania daty Wielkanocy.......................................................45
Program KMies2 w Pascalu........................................................................................46
Program KMies2 w C++.............................................................................................48
wiczenia ..........................................................................................................................51

Rozdzia 3. Grafika ............................................................................................ 53


Gra w chaos.......................................................................................................................53
Algorytm gry w chaos.................................................................................................54
Program Chaos w Pascalu...........................................................................................54
Program Chaos w C++................................................................................................56
Wielokt foremny i gwiazdka ...........................................................................................57
Wyznaczanie wierzchokw wielokta foremnego ....................................................57
Rysowanie wielokta foremnego w Pascalu...............................................................58
Rysowanie wielokta foremnego w C++....................................................................59
Wyznaczanie wierzchokw gwiazdki rwnoramiennej ............................................59
Program Gwiazdka w Pascalu ....................................................................................60
Program Gwiazdka w C++ .........................................................................................61
Najmniejszy wielokt wypuky.........................................................................................62
Algorytm wyznaczania brzegu najmniejszego wielokta wypukego ........................62
Program WielWyp w Pascalu .....................................................................................64
Program WielWyp w C++ ..........................................................................................66
Wskaniki a tablice w C i C++ ...................................................................................68
Wyraenia warunkowe w C i C++..............................................................................68
Czstotliwo wystpowania liter w pliku ........................................................................69
Program Litery w Pascalu...........................................................................................69
Program Litery w C++ ................................................................................................71
Konwersja znaku na acuch w C i C++.....................................................................73
Definiowanie staych symbolicznych w C++ .............................................................74
Wykres funkcji drga harmonicznych tumionych ...........................................................74
Okno i widok przy tworzeniu wykresu funkcji...........................................................74
Program Drgania w Pascalu........................................................................................76
Nazwa funkcji parametrem podprogramu w Pascalu .................................................78
Nazwa funkcji a wskanik w C i C++ ........................................................................79
Program Drgania w C++.............................................................................................80
wiczenia ..........................................................................................................................82

Rozdzia 4. Animacja ......................................................................................... 85


Pieczka .............................................................................................................................85
Program Pileczka w Pascalu .......................................................................................86
Program Pileczka w C++ ............................................................................................87
Wiee Hanoi......................................................................................................................88
Reprezentacja danych w Pascalu ................................................................................89
Wizualizacja krkw na ekranie monitora ................................................................89
Nakadanie krka na szczyt wiey ............................................................................90
Zdejmowanie krka ze szczytu wiey.......................................................................91
Algorytm rekurencyjny przenoszenia wie ................................................................91
Program WHanoi w Pascalu .......................................................................................92
Program WHanoi w C++ ............................................................................................94
Krzywe Lissajous ..............................................................................................................97
Rysowanie krzywej na ekranie monitora....................................................................97
Odwracajcy tryb rysowania.......................................................................................98

Spis treci

5
Program Lissa w Pascalu ............................................................................................98
Przekazywanie parametrw przez warto i referencj w C++ ................................100
Program Lissa w C++ ...............................................................................................101
Ukad planetarny .............................................................................................................102
Model komputerowy ukadu planetarnego ...............................................................103
Program Grawit w Pascalu........................................................................................104
Program Grawit w C++.............................................................................................107
Hipocykloida ...................................................................................................................109
Obliczanie wsprzdnych punktw .........................................................................109
Algorytm animacji oparty na kopiowaniu fragmentw obrazu ................................110
Dynamiczne przydzielanie i zwalnianie pamici......................................................111
Program Hipo w Pascalu...........................................................................................112
Program Hipo w C++................................................................................................113
Elementy charakterystyczne dla C++ .......................................................................114
wiczenia ........................................................................................................................115

Rozdzia 5. Listy jednokierunkowe ................................................................... 117


Sito Eratosthenesa ...........................................................................................................118
Definiowanie listy w Pascalu....................................................................................118
Wstawianie elementu na pocztek listy ....................................................................119
Przegldanie listy i usuwanie elementw .................................................................120
Program SitoEra w Pascalu.......................................................................................121
Definiowanie i obsuga listy w C++ .........................................................................123
Program SitoEra w C++............................................................................................123
Wskanik NULL w roli wyraenia warunkowego ...................................................125
Rozwinicie dziesitne uamka .......................................................................................125
Tablica czy lista?.......................................................................................................125
Generowanie listy cyfr rozwinicia dziesitnego uamka ........................................126
Program Rozwin w Pascalu ......................................................................................127
Program Rozwin w C++ ...........................................................................................128
Rozdanie kart do bryda..................................................................................................130
Generowanie talii kart i jej tasowanie.......................................................................130
Rozdanie kart czterem graczom................................................................................131
Wstawianie elementu do listy uporzdkowanej........................................................131
Program Brydz w Pascalu.........................................................................................133
Program Brydz w C++ ..............................................................................................136
Przekazywanie wskanika przez warto i referencj w C++ ..................................138
Zmienne statyczne w C i C++...................................................................................138
Skorowidz sw pliku tekstowego...................................................................................139
Czytanie sowa w Pascalu.........................................................................................139
Lista sw skorowidza z podlistami numerw wierszy ............................................140
Aktualizacja listy sw skorowidza ..........................................................................141
Program Skorow w Pascalu ......................................................................................143
Czytanie sowa w C++ ..............................................................................................145
acuchy dynamiczne w C++ ..................................................................................146
Program Skorow w C++ ...........................................................................................146
wiczenia ........................................................................................................................149

Rozdzia 6. Programy obiektowe ...................................................................... 151


Punkty..............................................................................................................................152
Pierwszy kontakt z typem obiektowym w Pascalu ...................................................152
Dostp do skadowych obiektu .................................................................................155
Metody wirtualne, konstruktor i destruktor ..............................................................155
Modu Punkty w Pascalu ..........................................................................................156

Turbo Pascal i Borland C++. Przykady


Klasa w C++ i jej modu definiujcy ........................................................................158
Modu Punkty w C++ ...............................................................................................159
Modu Ruch przesuwania punktu w Pascalu ............................................................161
Modu Ruch przesuwania punktu w C++ .................................................................161
Program przesuwania punktu w Pascalu...................................................................162
Obiekty dynamiczne w Pascalu ................................................................................163
Wywoywanie konstruktorw i destruktorw w C++...............................................164
Program przesuwania punktu w C++........................................................................164
Okrgi..............................................................................................................................165
Modu Okregi w Pascalu...........................................................................................165
Program przesuwania okrgu w Pascalu...................................................................167
Modu Okregi w C++................................................................................................168
Program przesuwania okrgu w C++........................................................................169
amane ............................................................................................................................170
Modu Lamane w Pascalu.........................................................................................170
Program przesuwania prostokta w Pascalu .............................................................172
Modu Lamane w C++ ..............................................................................................173
Program przesuwania prostokta w C++ ..................................................................174
Program przesuwania hipocykloidy w Pascalu.........................................................175
Program przesuwania hipocykloidy w C++..............................................................176
Lista figur geometrycznych.............................................................................................178
Modu Figury w Pascalu ...........................................................................................178
Program Pojazd w Pascalu........................................................................................179
Modu Figury w C++ ................................................................................................181
Program Pojazd w C++.............................................................................................182
Fontanna ..........................................................................................................................183
Koncepcja typu potomnego reprezentujcego kropl wody.....................................184
Program Fontanna w Pascalu....................................................................................185
Program Fontanna w C++.........................................................................................187
Osoby ..............................................................................................................................189
Modu Osoby w Pascalu ...........................................................................................189
Program tworzcy przykadow list pracownikw w Pascalu ................................191
Modu Osoby w C++ ................................................................................................194
Program tworzcy przykadow list pracownikw w C++ .....................................196
Edycja wiersza tekstu ......................................................................................................197
Tworzenie typu obiektowego edycji acucha w Pascalu.........................................198
Przesyanie danych do edycji i udostpnianie wyniku edycji...................................199
Programowanie operacji edycyjnych........................................................................200
Modu Edycja w Pascalu...........................................................................................201
Funkcje edycji acucha i listy acuchw ...............................................................205
Modu Edycja w C++................................................................................................206
Program Plik edycji danych osobowych w Pascalu..................................................211
Program Plik edycji danych osobowych w C++.......................................................215
wiczenia ........................................................................................................................219

Literatura ...................................................................................... 221


Skorowidz...................................................................................... 223

Rozdzia 3.

Grafika
Jednym ze sposobw tworzenia grafiki na ekranie monitora komputerowego jest skadanie obrazu z podstawowych elementw graficznych, takich jak punkty, odcinki proste, wielokty i okrgi, oraz wypenianie obszarw zadanym kolorem lub wzorcem.
Wszystkie programy zawarte w tym rozdziale dziaaj na tej zasadzie, korzystaj z biblioteki BGI (ang. Borland Graphics Interface interfejs graficzny firmy Borland)
i pracuj w 16-kolorowym trybie graficznym VGA o rozdzielczoci ekranu 640480
pikseli. Dotycz one nastpujcych zagadnie:
 rysowanie trjkta Sierpiskiego (gra w chaos),
 krelenie wielokta foremnego i gwiazdki,
 wyznaczanie najmniejszego wielokta wypukego zawierajcego dany zbir

punktw,
 zliczanie liter w pliku tekstowym i zobrazowanie wyniku w formie wykresu

supkowego,
 tworzenie wykresu funkcji drga harmonicznych tumionych.

Gra w chaos
Niekiedy bardzo proste algorytmy prowadz do zaskakujcych wynikw. Jednym
z nich jest zaprezentowany poniej algorytm generowania obrazu, zwany gr w chaos1.
Rysunek utworzony na ekranie monitora zaskakuje szczeglnie, poniewa cae postpowanie jest oparte na losowoci, czyli niemonoci przewidywania, chaosie.

Waciwie jest to jedna z gier polegajcych na losowym wyborze jednej z kilku prostych regu
postpowania. Przykad zaczerpnito z ksiki [8].

54

Turbo Pascal i Borland C++. Przykady

Algorytm gry w chaos


Algorytm gry w chaos jest rzeczywicie bardzo prosty. Na pocztku wybieramy na
ekranie trzy punkty P0, P1 i P2 tak, by stanowiy wierzchoki trjkta, np. rwnobocznego, oraz dowolny punkt Q0. Jest to tzw. punkt wiodcy. Nastpnie losujemy jeden
z wierzchokw trjkta i w rodku odcinka czcego ten wierzchoek z punktem Q0
zaznaczamy nowy punkt wiodcy Q1. Ponownie losujemy wierzchoek trjkta i w rodku odcinka o kocach w wylosowanym wierzchoku i punkcie Q1 zaznaczamy kolejny
punkt wiodcy Q2. Losowanie wierzchoka i zaznaczanie nastpnego punktu wiodcego dokadnie w poowie odcinka czcego wylosowany wierzchoek z poprzednim
punktem wiodcym powtarzamy wiele razy. Na rysunku 3.1 pokazano pi pierwszych
krokw, w ktrych kolejnymi wylosowanymi wierzchokami byy P1, P2, P1, P2, P0.
Rysunek 3.1.
Pi pierwszych
krokw gry w chaos

Jaki bdzie rezultat wykonania duej liczby powtrze wyznaczania nastpnego punktu wiodcego i rysowania go na ekranie? Wydaje si oczywiste, e jeli punkt wiodcy Q0 zosta wybrany na zewntrz trjkta P0P1P2, to po niewielkiej liczbie krokw
kolejny wyznaczony punkt wiodcy dostanie si do wntrza tego trjkta. Ponadto
gdy jaki punkt wiodcy znajdzie si we wntrzu trjkta, kady nastpny tam pozostanie. Mona wic przypuszcza, e po duej liczbie iteracji punkty wiodce zapeni
losowo wntrze trjkta. Aby si przekona, czy rzeczywicie tak bdzie, wystarczy
napisa i uruchomi prosty program.
Symulacja zdarze losowych na komputerze wymaga odpowiedniego podprogramu
generujcego liczby losowe. Naley jednak sobie uwiadomi, e generator taki dziaa
wedug cile okrelonego algorytmu, a dostarczone przez niego liczby jedynie sprawiaj wraenie losowoci. Bardziej stosowne jest wic nazywanie ich liczbami pseudolosowymi.

Program Chaos w Pascalu


W Turbo Pascalu liczby losowe generuje funkcja , ktr mona wywoywa
bez parametru lub z jednym parametrem reprezentujcym warto cakowit dodatni.
Wartoci wywoania funkcji w pierwszym przypadku jest losowa liczba rzeczywista
z przedziau [0, 1), za w drugim losowaniu nieujemna liczba cakowita mniejsza
od zadanego parametru, np. wartoci wywoania 
jest liczba cakowita od
0 do 48. Iteracyjne uycie funkcji  daje cig liczb o rozkadzie jednostajnym.

Rozdzia 3. Grafika

55

Zazwyczaj przed wykorzystaniem generatora inicjuje si go za pomoc bezparametrowej procedury  . Generator niezainicjowany tworzy taki sam cig liczb za
kadym uruchomieniem programu, co mona wykorzysta podczas testowania programu. Peny kod rdowy programu w Turbo Pascalu realizujcego gr w chaos jest
przedstawiony na wydruku 3.1.
Wydruk 3.1. Program Chaos.pas realizujcy gr w chaos

 
   
 


 !"##$%&'($"(")*"+
  !"##$%&'*,-)"-)"+
.
/

01
/

2 '34564723+
')-"+
/'-8"+
&09*",""""
/

'(+
':!
%+.$
/'/: !
%+.$
&0;" 661'/ +

 
1  
#

Tablice inicjalizowane x i y zawieraj wsprzdne ekranowe wierzchokw trjkta,


zmienne a i b wsprzdne biecego punktu wiodcego, w indeks wylosowanego wierzchoka, a k numer kolejny iteracji. Program (bez wejcia) inicjuje generator liczb losowych, przecza kart graficzn w tryb graficzny  o rozdzielczoci
 (640480 pikseli)2, rysuje 50 000 punktw wiodcych w kolorze  (turkusowy) za pomoc procedury   , a po wybraniu przez uytkownika dowolnego
znaku na klawiaturze przecza kart graficzn w tryb tekstowy i koczy dziaanie.
Faktycznie program wykonuje iteracj ponad 50 000 razy. Dodatkowe 11 pocztkowych krokw, w ktrych punkt wiodcy nie jest rysowany, ma na celu pominicie
punktw nienalecych do wntrza trjkta.
2

cieka dostpu podana w wywoaniu procedury 2 , okrelajca miejsce sterownika karty
graficznej (plik egavga.bgi), moe by inna w przypadku innego komputera.

56

Turbo Pascal i Borland C++. Przykady

Wynik utworzony przez program na ekranie monitora jest pokazany na rysunku 3.2.
Uwiadamia on, jak zawodna moe by intuicja. Wygenerowany obraz przedstawia
tzw. trjkt Sierpiskiego. Jest on zbiorem punktw wyjtkowo uporzdkowanym,
niemajcym wydawaoby si nic wsplnego z chaosem i losowoci.
Rysunek 3.2.
Trjkt Sierpiskiego
po 50 000 krokach
gry w chaos

Program Chaos w C++


W rodowisku Borland C++ jest rwnie dostpny generator liczb losowych. Realizuj go, podobnie jak w Pascalu, funkcje  i  , z tym e pierwsza istnieje tylko w wersji dla liczb cakowitych. Ich prototypy znajduj si w pliku stdlib.h.
Peny program rdowy w Borland C++, tworzcy trjkt Sierpiskiego metod gry
w chaos, jest przedstawiony na wydruku 3.2.
Wydruk 3.2. Program Chaos.cpp realizujcy gr w chaos
< 1=  # ;
< 1= 1/# ;
< 1= # ;
2
!%>($"(")*"? !%>*,-)"-)"?
.'+
>
/

10
'+
 '@@A4474472A+
')-"+
/'-8"+
&'09*"0=,""""0::+
>
':!
'(+%+B$
/'/: !
%+B$

Rozdzia 3. Grafika

57

&'0;"+1'/CD+
?
 '+
 1  '+
?

Podwjne znaki  (Backslash) w tekcie okrelajcym ciek dostpu do sterownika


karty graficznej w wywoaniu funkcji   wynikaj z faktu, i  jest znakiem
specjalnym. Kada sekwencja  reprezentuje w C i C++ pojedynczy znak .

Wielokt foremny i gwiazdka


Zadanie rysowania amanej, a w szczeglnoci wielokta, pojawia si w wielu praktycznych zagadnieniach grafiki komputerowej. Na przykad proces rysowania krzywej, nawet bardzo zoonej, sprowadza si do narysowania amanej o odpowiednio
duej liczbie wierzchokw lecych na tej krzywej. Technika rysowania amanej
o wierzchokach P0 , P1 ,..., Pn polega na przeniesieniu pisaka (pira) do wierzchoka
pocztkowego P0, a nastpnie wykonaniu ptli rysujcej kolejne odcinki Pk 1 Pk dla
k = 1,2,..., n . Tak samo postpuje si w przypadku wielokta, ktry jest aman zamknit: P0 = Pn .
Podstawowymi narzdziami do krelenia s:
 procedura ustawienia pisaka w dowolnym punkcie ekranu,
 procedura krelenia odcinka od aktualnej pozycji pisaka do jego nowej pozycji.

Wyznaczanie wierzchokw wielokta foremnego


Wierzchoki wielokta foremnego s rwnomiernie rozoone na okrgu (por. rysunek 3.3), a ich wsprzdne speniaj rwnania parametryczne:
x = r cos + p,

Rysunek 3.3.
Wielokt foremny
wpisany w okrg

y = r sin + q,

0 2

58

Turbo Pascal i Borland C++. Przykady

gdzie r jest promieniem, a p i q wsprzdnymi rodka S tego okrgu.


Niech oznacza kt midzy promieniami czcymi punkt S z dowolnymi dwoma ssiednimi wierzchokami:

2
n

Jeeli promie okrgu czcy punkty S i P0 jest rwnolegy do osi y, to wsprzdne


wierzchokw Pk = ( x k , y k ) dla k = 0,1,..., n mona wyznaczy, podstawiajc do powyszych rwna parametrycznych w miejsce parametru wartoci:

k = k
czyli korzystajc ze wzorw:

x k = r cos k + p,

y k = r sin k + q

Rysowanie wielokta foremnego w Pascalu


W Turbo Pascalu procedura  ustawia pisak w okrelonym punkcie ekranu, za
 rysuje odcinek od biecej pozycji pisaka do jego nowej pozycji. Ich parametrami s liczby cakowite okrelajce wsprzdne ekranowe punktu, do ktrego pisak
ma by przesunity. Zatem proces rysowania wielokta foremnego mona w tym jzyku zaprogramowa nastpujco:

  
 
 
 

   


  

 !"
 #
$
 !%   "&!%
   


Zmiana znaku (minus zamiast plus) w wyraeniu wystpujcym w roli drugiego parametru w wywoaniu procedury  wynika z dziwnego zaoenia przyjtego przez
projektantw komputera i twrcw rodowiska programowania, i pocztek ukadu
wsprzdnych znajduje si w lewym grnym rogu ekranu, a o y jest skierowana
w d3. Funkcja 
 zostaa wykorzystana w celu zaokrglenia wartoci rzeczywistej
do najbliszej wartoci cakowitej, uycie typu rzeczywistego spowodowaoby bd
(type mismatch niezgodno typu). Rwnie dobrze mona tu wykorzysta funkcj

 , ktra obcina warto rzeczywist do czci cakowitej.

W tym przypadku zmiana znaku nie ma znaczenia z uwagi na symetri wielokta wzgldem prostej
rwnolegej do osi x i przechodzcej przez jego rodek S.

Rozdzia 3. Grafika

59

Rysowanie wielokta foremnego w C++


Jzyki C i C++ nie s tak rygorystyczne. Zawieraj szereg mechanizmw automatycznego przeksztacania (konwersji) typw, ktre s wykorzystywane, gdy jest to
konieczne i ma sens. Oglnie mwic, s one bardzo uyteczne i daj wyniki zgodnie
z oczekiwaniami. Jednym z takich przeksztace jest zamiana wartoci rzeczywistej
na cakowit, odpowiadajca pascalowskiej funkcji 
 . Powysz procedur mona wic w Borland C++ zapisa nieco prociej:

'
  


 
(

 
   )*
+"
 # , ""

%   "&%
   
-

Oczywicie uycie symbolu  (warto ) w wyraeniu inicjalizujcym zmienn


alfa oraz funkcji trygonometrycznych sin i cos wymaga wczenia pliku nagwkowego math.h.

Wyznaczanie wierzchokw gwiazdki rwnoramiennej


Nietrudno teraz przej do narysowania gwiazdki rwnoramiennej. Jej 2n wierzchokw ley przemiennie na dwch koncentrycznych okrgach (por. rysunek 3.4).
Rysunek 3.4.
Gwiazdka
rwnoramienna
i dwa okrgi

Niech P0 , P1 ,....Pn = P0 bd wierzchokami gwiazdki lecymi, podobnie jak w przypadku wielokta foremnego, na okrgu o promieniu r i rodku S = ( p, q ) , niech rwnie promie okrgu czcy punkty S i P0 bdzie rwnolegy do osi y. Natomiast
niech Q1 , Q2 ,..., Qn bd wierzchokami gwiazdki lecymi na drugim okrgu o promieniu r1 i rodku S. Wsprzdne punktw Qk = (u k , v k ) dla k = 1,2,..., n mona
take wyznaczy z rwna parametrycznych okrgu. Promienie, ktrych kocami s
punkty Qk , s obrcone wok rodka S zgodnie z ruchem wskazwek zegara (kierunek ujemny) o kt /2 wzgldem promieni, ktrych kocami s punkty Pk . Zatem
spenione s rwnoci

60

Turbo Pascal i Borland C++. Przykady

u k = r1 cos k + p, v k = r1 sin k + q
w ktrych

k = k

= k
n
2

Narzucajcy si algorytm rysowania gwiazdki sprowadza si do przeniesienia pisaka


do punktu P0 i wykonania ptli, ktra dla k = 1,2,..., n rysuje dwa odcinki Pk 1Qk
i Qk Pk zamiast jednego odcinka Pk 1 Pk w przypadku wielokta foremnego.

Program Gwiazdka w Pascalu


Opisany wyej algorytm rysowania gwiazdki jest wykorzystany w programie w Turbo Pascalu przedstawionym na wydruku 3.3.
Wydruk 3.3. Program Gwiazdka.pas rysowania gwiazdki rwnoramiennej

    





 
  
 ! " #$%
&
 
$'$'(' 
$
)
$'(* + 
$'(,$'(
-&.! !%/"%
'# 
)
' ,$'

' 0$'(
1 .! !#,
!
%%/"0 !#,
!
%%%
1 .! !,
!' %%/"0 !,
!' %%%
 
2$2 $$!"$%
 
&
  
$
)
3 !41 )  4%
1 ! %
3 !4* 54%
1 !%
6 !47.*7864%

Rozdzia 3. Grafika

61

9$!1 %
92 $$9 $!9$ 2 $$:$$ %
 ! ;(<(=<+(%
 
$

 >

Program wczytuje z klawiatury liczb n ramion gwiazdki i promie r okrgu okrelajcego jej wielko, przecza kart graficzn w tryb graficzny, ustawia kolor rysowania linii ( jasnoczerwony) i styl wypeniania obszarw (
  peny,
kolor 
 ty). Nastpnie rysuje porodku ekranu gwiazdk o 2n wierzchokach lecych na przemian na okrgach o promieniach r i r/2, a w kocu zapenia j,
poczynajc od rodka. Gdy uytkownik wybierze dowolny znak na klawiaturze, program powraca do trybu tekstowego i koczy dziaanie.

Program Gwiazdka w C++


Analogiczny program w jzyku Borland C++, wykorzystujcy inicjalizowanie zmiennych lokalnych wyraeniami zbudowanymi z uprzednio okrelonych wartoci oraz
umieszczanie przypisa w wyraeniach (funkcja gwiazdka), zosta przedstawiony na
wydruku 3.4.
Wydruk 3.4. Program Gwiazdka.cpp rysowania gwiazdki rwnoramiennej
? $@ 
>A
? $@ 
>A
? $@ >A
? $@>A
 6
&  !    ")$)$#%
B
 
)$$'(-*6+ $'(,$'(' 

&!/"%
'!#@ //%
B

!' ,$'%0$'(
$ !#,
!
%/"0#,
!
%%
$ !,
!' %/"0,
!' %%
C
'$' $$!"$!%%
C
&  !%
B
  
'$
@@D1 )  D
 AA 
@@D* 5D
 AA

62

Turbo Pascal i Borland C++. Przykady


 !EED7787786D%

$!16 .FG%

' $$
 $!9H16G2611:F11H3%
 ! ;(<(=<+(%
!%
$
!%
C

Zazwyczaj przejcie od rodowiska Turbo Pascala do Borland C++ nie sprawia kopotw, gdy wykorzystuje si rwnowane biblioteki standardowe. Nazwy zdefiniowanych w bibliotekach staych i podprogramw s w obu rodowiskach takie same, z tym
e w C++ pierwsze pisane s duymi, a drugie maymi literami. Zdarzaj si jednak
niespodzianki, czego przykadem s stae
  i   (pene wypenianie
obszarw) uyte w dwch ostatnich programach (por. wydruki 3.3 i 3.4).

Najmniejszy wielokt wypuky


Zbir punktw, ktry dla dowolnych nalecych do niego dwch punktw A i B zawiera czcy je odcinek AB, nazywamy zbiorem wypukym. Najmniejszy zbir wypuky zawierajcy skoczon liczb punktw P1, P2,..., Pn jest wieloktem, a zbir jego
wierzchokw stanowi podzbir tego zbioru n punktw. Nie zajmiemy si tu jednak
prezentacj znanych algorytmw wyznaczania najmniejszego wielokta wypukego4,
lecz ograniczymy si do jego narysowania. Metoda polega bdzie na wyszukiwaniu
i rysowaniu tylko tych odcinkw PiPj dla 1 i < j n , ktre le na brzegu wielokta. W rezultacie wierzchoki najmniejszego wielokta wypukego zostan wyznaczone.
Nasuwa si wic pytanie: na czym polega wada takiego postpowania? Ot istotne
jest rwnie okrelenie kolejnoci wierzchokw. Brak uporzdkowania wierzchokw
wielokta moe w przypadku wspliniowoci trzech lub wikszej ich liczby prowadzi do ponownego rysowania narysowanych wczeniej fragmentw brzegu.

Algorytm wyznaczania brzegu


najmniejszego wielokta wypukego
Przejdmy teraz do sformuowania algorytmu umoliwiajcego sprawdzenie, czy odcinek PiPj okrelony przez dwa dowolne punkty Pi i Pj, wybrane spord punktw
Pk = ( x k , y k ) dla k = 1,2,..., n , ley na brzegu najmniejszego wielokta wypukego
zawierajcego wszystkie te punkty. Oczywiste jest, e odcinek PiPj ma tak waciwo wtedy i tylko wtedy, gdy wszystkie one le po jednej stronie prostej przechodzcej przez koce tego odcinka lub na niej. Rozpatrzmy przypadek xi x j . Prosta
spenia wwczas rwnanie

Mona je znale np. w ksice [2].

Rozdzia 3. Grafika

y = p( x) =

63

y j yi
( x xi ) + yi
x j xi

Pooenie punktu ( x k , y k ) wzgldem prostej zaley od znaku wyraenia v = p ( x k ) y k ,


mianowicie punkt ley na prostej, gdy v = 0, nad prost, gdy v < 0, albo pod ni, gdy
v > 0. Zatem sprawdzenie, czy punkty o indeksach i, j okrelaj odcinek lecy na brzegu wielokta, mona opisa za pomoc nastpujcej funkcji w Turbo Pascalu:
'   8! I %8$ 
&

 
&$
)
8'$


<
'# 
 '!@A % !@AI%
)
&! JIK0 J K%+!LJIK0LJ K%,!LJK0LJ K%/ J K0 JK
 '&@A<
)
 '&A< #$
0#
 '
< 
$
 '
@A FL 
 
 
8
 

Ptla 
 przebiega kolejno punkty i bada ich pooenie wzgldem prostej wyznaczonej przez punkty o indeksach i i j. Istotne dziaania s podejmowane, gdy rozpatrywany punkt nie ley na prostej (v 0). Wtedy zmiennej z przypisana zostaje warto 1,
gdy punkt ley poniej prostej, albo 1, gdy powyej. Dalsze postpowanie zaley od
wartoci zmiennej s. Warto zerowa s oznacza, e napotkany punkt jest pierwszym,
ktry nie ley na prostej, a wtedy jego pooenie wzgldem niej (liczba 1 lub 1) zostaje zapamitane w zmiennej s. Z kolei niezerowa warto s okrela pooenie wszystkich dotd uwzgldnionych punktw. Jeli jest ona rna od wartoci z, le one po innej stronie prostej ni rozpatrywany punkt. W takim przypadku ptla zostaje przerwana,
wykonanie podprogramu zakoczone, a rezultatem wywoania funkcji jest warto
  oznaczajca, e odcinek wyznaczony przez punkty Pi i Pj nie naley do brzegu
wielokta. Jeeli wszystkie punkty le po jednej stronie prostej lub na niej, ptla zostaje zakoczona w sposb naturalny, a do miejsca wywoania funkcji zostaje przekazana warto  oznaczajca, e odcinek PiPj stanowi fragment brzegu wielokta.
Funkcja Brzeg wymaga udoskonalenia, poniewa nie zadziaa prawidowo w przypadku, gdy punkty Pi i Pj wyznaczaj prost pionow, tj. gdy xi = x (ang. divide by
zero dzielenie przez zero). Mona temu zaradzi, wyliczajc wartoci dx = xi x j
i dy = y i y j , ktre posu do wybrania jednego z dwch rwna prostej, w zalenoci od jej kta nachylenia wzgldem osi x. I tak, dla dx dy , tj. gdy nachylenie
prostej nie przekracza kta 45o, korzystamy ze wzoru

64

Turbo Pascal i Borland C++. Przykady

y=

dy
( x xi ) + y i
dx

natomiast dla dx < dy , czyli dla nachyle wikszych, traktujemy zmienn x jako zalen od zmiennej y, co prowadzi do wzoru

y=

dy
( x xi ) + y i
dx

Program WielWyp w Pascalu


Zmodyfikowana funkcja Brzeg jest wykorzystana w przedstawionym na wydruku 3.5
programie w Turbo Pascalu, ktry wczytuje wsprzdne punktw z pliku tekstowego, wykrela te punkty w postaci maych krzyykw i rysuje najmniejszy zawierajcy
je wielokt wypuky.
Wydruk 3.5. Program WielWyp.pas rysowania najmniejszego wielokta wypukego
3 $ $ 





 
  
&
  
L  J#>>#<<<K' 
 IG 
&
G .L
M 
 
)
3 !4M $ 4%
1 !M %


 !G M %



!G %
 <
  $ F'!G %
)
6 ! %
1 !G LJ K J K%
 
$
!G %
 
'   8! I %8$ 
&
L 
 
&$
)
8'$


Rozdzia 3. Grafika

65

LLJIK0LJ K
  JIK0 J K
 '!L<% ! <% FL 

<
'# 
 '!@A % !@AI%
)
 ')
!L%A)
! %
 & +L,!LJK0LJ K%/ J K0 JK
$
&L+ ,! JK0 J K%/LJ K0LJK
 '&@A<
)
 '&A< #$
0#
 '
< 
$
 '
@A FL 
 
 
8
 
N 
 
&
 I 
)
' # 
)
1 !LJ K0( J K0(LJ K/( J K/(%
1 !LJ K0( J K/(LJ K/( J K0(%
 
' # 0#
'I /# 
 '8! I% 1 !LJ K J KLJIK JIK%
 
)
 IG 
6 !47.*7864%
N 
 
 
$

 >

Nazwa pliku jest podawana z klawiatury. Przyjto zaoenie, e plik zwiera co najwyej 1000 wierszy, tj. n 1000, oraz e wiersze pliku zawieraj po dwie liczby cakowite, oddzielone co najmniej jedn spacj, okrelajce wsprzdne ekranowe kolejnego punktu:

0 x k < 640, 0 y k < 480, (k = 1,2,..., n)


Tworzc plik, np. w edytorze Turbo Pascala, naley uwaa, aby po ostatnim wierszu
nie umieci wiersza pustego. Liczba punktw (wierszy) jest obliczana w ptli w trakcie czytania pliku wedug schematu:
podczas gdy (dopki) nie napotkano jeszcze koca pliku, zwiksz liczb punktw
(wstpnie zero) o jeden i wczytaj wsprzdne kolejnego punktu.

66

Turbo Pascal i Borland C++. Przykady

W funkcji Brzeg dodatkowo zabezpieczono si przed bdem w patologicznym przypadku, gdy parametry okrelaj punkty o takich samych wsprzdnych: dla dx = dy =
0 obliczenia s przerywane, wynikiem wywoania funkcji jest warto  . Korzystajcy z funkcji Brzeg podprogram UtworzRysunek najpierw rysuje wszystkie punkty, a nastpnie sprawdza, czy punkty o indeksach 1 i < j n okrelaj odcinki na
brzegu najmniejszego wielokta wypukego, i w przypadku spenienia warunku odcinki takie rysuje. Tym razem wygodniejszym narzdziem rysowania jest procedura
, ktra wymaga czterech parametrw reprezentujcych wsprzdne pocztku
i koca odcinka. W przeciwiestwie do 
, nie przenosi ona pisaka do koca rysowanego odcinka.

Program WielWyp w C++


Na wydruku 3.6 jest przedstawiony podobny program w Borland C++, ale o bardziej
zwartym w porwnaniu z Pascalem kodzie dotyczcym czytania danych i sprawdzania, czy odcinek okrelony przez dwa punkty ley na brzegu wielokta wypukego.
Wydruk 3.6. Program WielWyp.cpp rysowania najmniejszego wielokta wypukego
? $@
 >A
? $@>A
? $@ 
>A
? $@ >A
 6 LJ#<<<K J#<<<K
 I !%
B
261F, 
  J(OPK
 '!DM $ D%

!  %
 '!! ' !  DD%%QMN11%
B
'! <'
 '! DRRDL/  / %QFH2 //%
'$
! %
 #
C
$

 <
C
)!   I%
B
 LLJIK0LJ K  JIK0 J K
<
)$&
 '!L<EE <% <
'!<@ //%
 '!Q EEQI%
 '!!&!')
!L%A')
! %%
S)$! %+L,!LJK0LJ K%/ J K0 JK
)$!L%+ ,! JK0 J K%/LJ K0LJK%Q<%

Rozdzia 3. Grafika

67

B
!&A<%S#0#
 '!
<%
$
 '!
Q% <
C
 #
C
&  
 !%
B
  I
'! < @  //%
B
$ !LJ K0( J K0(LJ K/( J K/(%
$ !LJ K0( J K/(LJ K/( J K0(%
C
'! < @ 0# //%
'!I /#I@ I//%
 '!)! I%%$ !LJ K J KLJIK JIK%
C
&  !%
B
 '! I !%%
B
 !EED7787786D%
 
 !%
!%
$
!%
C
$

B
 '!DM    $ 7 D%
!%
C
C

Program rwnie rozpoczyna dziaanie od wczytania danych z pliku tekstowego, wykorzystujc funkcj czytajdane. Jednake w przypadku podania przez uytkownika
niewaciwej nazwy pliku, informuje o nieudanym otwarciu pliku, a nie koczy si
bdem (ang. file not found plik nieznaleziony). Parametrami funkcji 
 s nazwa pliku i tryb jego otwarcia (r oznacza odczyt, t plik tekstowy). Wartoci funkcji jest wskanik do struktury typu , gdy plik zosta otwarty, bd tzw. wskanik
pusty , gdy z rnych przyczyn pliku nie udao si otworzy. Funkcja 
 zamyka plik.
Do wczytania dwch wsprzdnych kolejnego punktu uyto funkcji . Jej wywoanie, zamieszczone w warunku kontynuacji ptli 
, daje warto rwn liczbie
wczytanych pl, gdy operacja czytania powioda si, bd warto  (ang. end of
file koniec pliku), gdy napotkano koniec pliku. Cztery parametry wywoania oznaczaj kolejno: wskanik do pliku, format czytanych danych (symbole formatujce 
odnosz si do liczb cakowitych dziesitnych) i dwa wskaniki okrelajce elementy
tablic, ktrych wartoci maj by wczytane.

68

Turbo Pascal i Borland C++. Przykady

Wskaniki a tablice w C i C++


Wskanik do zmiennej jest zazwyczaj tworzony za pomoc operatora , np. zapis 
oznacza wskanik do zmiennej n. Wyraeniami okrelajcymi wskaniki do elementw !"# i $"# s zatem !"# i $"#, mona je byo zastosowa w wywoaniu funkcji . Nazwa tablicy jest jednak traktowana jako wskanik do jej pocztkowego
elementu (skutkiem tego parametrem wywoania funkcji , wczytujcej nazw pliku z klawiatury, jest nazwa tablicy znakowej). Ponadto poprzez dodanie wartoci cakowitej do wskanika otrzymuje si wskanik do elementu przesunitego o t warto.
Zapisy !% i $% oraz !"# i $"# s wic cakowicie rwnowane.
cisa odpowiednio midzy tablicami i wskanikami przejawia si w dowolnoci
uywania indeksw i wskanikw w kodowaniu operacji dotyczcych przetwarzania
tablic. I tak, stosujc jednoargumentowe operatory i &, otrzymujemy rwnowane
formy wyrae:
!
!%(
!%+

!"'#
i
!"(#
i
!"+#
i
................
!%,
!",#
i
................

oraz

!"'#
!"(#
!"+#

i &!
i &)!%(*
i &)!%+*
..................
!",#
i &)!%,*
..................

Wyraenia warunkowe w C i C++


Niespodziank dla Czytelnika podejmujcego si przejcia od Pascala do jzykw C
i C++ mog stanowi wyraenia warunkowe wystpujce w funkcji brzeg, okrelajce
sposb obliczania wartoci zmiennych v i z, utworzone za pomoc operatora -. wymagajcego a trzech argumentw. Ich skadnia jest nastpujca:
 S


Najpierw obliczane jest pierwsze wyraenie. Jeli jego warto jest rna od zera, obliczana jest warto drugiego wyraenia i ona zostaje potraktowana jako warto caego wyraenia warunkowego. W przeciwnym przypadku obliczana jest warto trzeciego wyraenia i ona zostaje przyjta jako warto wynikowa. Tak wic spord dwch
wyrae, drugiego i trzeciego, obliczane jest tylko jedno.
Prostym przykadem uycia wyraenia warunkowego jest wyznaczenie wartoci c jako wikszej z a i b. Mona oczywicie zastosowa instrukcj warunkow
'!A)%

$

)

ale prociej jest napisa


!A)%S)

Rozdzia 3. Grafika

69

Wyraenie warunkowe moe wystpowa w innych wyraeniach, czego przykadem


jest wyraenie okrelajce warto zmiennej v w funkcji brzeg. Zostao ono uyte w warunku sterujcym wykonaniem instrukcji .

Czstotliwo wystpowania liter


w pliku
Zajmiemy si obecnie zliczaniem liter w pliku tekstowym. Warto wspomnie, e zagadnienie wyznaczenia czstotliwoci wystpowania liter w tekcie miao due znaczenie praktyczne ju wiele lat przed pojawieniem si komputerw. Gdy konstruowano pierwsze maszyny do pisania, naleao rozmieci klawisze jej klawiatury tak, aby
znaki najczciej uywane byy atwiej dostpne ni znaki uywane rzadziej. Rwnie
alfabet Morse'a zosta tak zbudowany, aby znakom czciej uywanym odpowiaday
krtsze sygnay.

Program Litery w Pascalu


Zakadamy, e program ma uwzgldnia tylko litery alfabetu angielskiego, oraz e ma
utosamia litery due i mae. Wynikiem jego dziaania nie maj by jednak liczby
wystpie poszczeglnych liter, lecz wykres supkowy obrazujcy czstotliwoci ich
wystpowania. Naturalne wydaje si wyodrbnienie dwch skadowych programu,
z ktrych pierwsza zlicza litery w pliku, a druga tworzy grafik. Program taki w jzyku Turbo Pascal zosta przedstawiony na wydruku 3.7.
Wydruk 3.7. Program Litery.pas obrazujcy czstotliwo wystpowania liter w pliku
1 )$ $ 
 





G & 
-  
&
1 J44>>4T4K' 
1  
&
*$ .L
M 
 

)
'444T4
1JK<
3 !4M $ 4%
1 !M %


 !*$ M %

70

Turbo Pascal i Borland C++. Przykady



!*$ %
  $ F'!*$ %
)
!*$ %
 ' J44>>4T444>>44K 6 !1JN
!%K%
 
$
!*$ %
 

  


MH!4T4%0H!44%/#B1 )
UV C
LP=< &MB
 
UV C
3 ;,L &OB9WX
UC
G!L03 % &(BUY)WX
UC
&
-LL 

)
-L#
'444T4
 '1JKA-L -L1JK
L!P=<0M,L% &(
92 $$9 $!9$ 2 $$G %
'444T4
)
8;G!L=O<0 !1JK+-L,==<%L/3 =O<G%
H.LZ:!L/G=P<%
6 !LL%
 
 
)
1  
6 !G &-47.*7864%

  
 
$

 >

Procedura Liczenie oblicza liczby wystpie poszczeglnych liter w pliku tekstowym,


umieszczajc wynik w tablicy globalnej L. Wartociami indeksw elementw tej tablicy s due litery od A do Z, typ indeksu jest wic podzbiorem typu znakowego ,
a element "# przedstawia liczb wystpie znaku (litery) c w tekcie. Najpierw zerowane s wszystkie elementy tablicy L. Nastpnie w ptli pobierany jest z pliku kolejny znak c i w przypadku, gdy jest to litera, warto elementu "# jest zwikszana
o 1. Wczeniej jednak, gdy c jest ma liter, indeks elementu jest zamieniany na du
liter za pomoc funkcji /.
Procedura Rysowanie rysuje dla kadej litery supek o wysokoci proporcjonalnej do
liczby wystpie tej litery w pliku. W celu uproszczenia kodu procedury i poprawienia jego czytelnoci zdefiniowano kilka staych: N liczba supkw (26, tj. liczba
liter alfabetu angielskiego), dx rozstaw supkw przy szerokoci ekranu 640 pikseli, Width szeroko supka, Depth gboko supka. Najwyszy supek, o wy-

Rozdzia 3. Grafika

71

sokoci 440 pikseli, odpowiada literze, ktra pojawia si w pliku najczciej. Licznik
wystpie tej litery jest maksymaln wartoci wszystkich elementw tablicy L. Wyznacza si go w zmiennej Max wedug schematu:
jeeli kolejny element ma warto wiksz od dotychczasowej wartoci zmiennej
Max, przypisz zmiennej Max warto tego elementu.
Elementy s nieujemne, na wstpie naleao wic wyzerowa zmienn Max. Jednake
z uwagi na obliczanie wysokoci supka litery c ze wzoru

h(c ) =

L[c]
440
Max

zmiennej Max przypisuje si na pocztku warto 1. Unika si w ten sposb bdu


dzielenia przez zero, gdy plik nie zawiera adnej litery.
Supki s rysowane za pomoc bibliotecznej procedury 01. Pierwsze cztery parametry jej wywoania okrelaj wsprzdne lewego grnego i prawego dolnego rogu
prostokta stanowicego ciank przedni supka, pity gboko supka, szsty
za () wymusza rysowanie grnego denka (dla   denko nie byoby rysowane). Wsplna warto y = 450 dla dolnego boku cianek przednich sprawia, e supki
wyrastaj w gr z jednej paszczyzny poziomej (por. rysunek 3.5). Jednoliterowe
napisy pod supkami, od y = 460, s tworzone za pomoc procedury !2 .
Rysunek 3.5.
Czstotliwo
wystpowania liter
w pliku Litery.pas

Program Litery w C++


Przystpujc do omwienia analogicznego programu w Borland C++ naley przypomnie, e elementy tablic s w C i C++ zawsze indeksowane liczbami cakowitymi od
zera wzwy. Zatem element "'# bdzie zawiera liczb wystpie litery A, "(#
liczb wystpie litery B, ..., "+3# liczb wystpie litery Z. Krtko mwic, licz-

72

Turbo Pascal i Borland C++. Przykady

ba wystpie litery bdcej wartoci zmiennej c zostanie zapamitana w elemencie


"4565#. Zmienne i stae typu  s arytmetycznie traktowane identycznie jak zmienne typu , wyraenie 4565 jest wic poprawne. Jego wartoci jest liczba cakowita
od 0 do 25, ktra odpowiada jednej z liter od A do Z zawartej w zmiennej c. W celu
przeksztacenia maej litery na du wygodnie jest posuy si funkcj 
. Pena wersja tego programu w Borland C++ zostaa przedstawiona na wydruku 3.8.
Wydruk 3.8. Program Litery.cpp obrazujcy czstotliwo wystpowania liter w pliku
? $@
 >A
? $@ >A
? $@ 
>A
? $@ >A
?' M!4T4044/#%++1 )
UV
?' GZ!P=<+M%++
 
UV
?' 36G. !;,GZ+O%++9WX
U
?' GF*. !!GZ036G. %+(%++UY)WX
U
G &- 61JMK
$  !%
B
261F,$ 
  J(OPK
 
 '!DM $ D%

!  %
 '!!$ ' !  DD%%QMN11%
B
'!<@M1J//K<%
  $!!'!$ %%QFH2%
 '!!!%%A44EE@4T4%1J044K//
'$
!$ %
 #
C
$

 <
C
& 
  !%
B
 -L#L!P=<0M,GZ%+(
,
DD
'!<@M//%
 '!1JKA-L%-L1JK

' $$
 $!9H16G2611G:%
'!<@M//%
B
);!L=O<0!1JK,==<><%+-LL/36G. =O<GF*. #%
,
44/
LL !L/GF*. =P<
%
L/GZ
C
C

Rozdzia 3. Grafika

73

&  !%
B
 '!$  !%%
B
 !EG &E-D7787786D%

  !%
!%
$
!%
C
$

B
 '!DM    $ 7 D%
!%
C
C

Wystpujca w funkcji liczenie definicja zmiennej c, sucej do pamitania kolejnego znaku pobranego z pliku, moe rodzi pytanie: dlaczego zmienna ta jest typu ,
a nie typu ? Powodem uycia typu  zamiast  jest typ wartoci zwracanych
przez funkcj , ktra czyta znak z pliku i zwraca go jako warto wynikow,
a w przypadku napotkania koca pliku zwraca warto odpowiadajc nazwie symbolicznej  , okrelon w pliku nagwkowym stdio.h jako 1. Tak wic wartociami zwracanymi przez funkcj  s wszystkie moliwe znaki i dodatkowa warto
1 typu , ktra binarnie jest cigiem samych jedynek. Przeksztacenie jej do typu
 polega na obciciu tego cigu do 8 bitw, co daje warto 2555. Zatem gdyby
zmienna c bya typu , program zawieszaby si, poniewa wykrycie koca pliku
powodowaoby przypisywanie zmiennej c wartoci 255, w efekcie warunek kontynuacji ptli   byby zawsze speniony.

Konwersja znaku na acuch w C i C++


Wyjanienia moe wymaga uycie zmiennej wskanikowej s w podprogramie rysowanie, ktra nie ma swojego odpowiednika w jego wersji pascalowskiej. Jest ona zainicjalizowana jednoznakow sta tekstow, czyli dwuelementow tablic znakow.
Warto pierwszego elementu tablicy nie ma tu znaczenia, istotna jest zerowa warto
jej drugiego elementu oznaczajca koniec tekstu (symbol 7'). W ptli 
 pierwszemu
elementowi tablicy jest przypisywana kolejna dua litera od A do Z, a powstay w ten
sposb tekst jednoznakowy jest nastpnie wykorzystywany w wywoaniu funkcji
4
!!$ tworzcej napis pod supkiem.
Zabieg ten jest waciwie konwersj midzy typem znakowym a typem tekstowym.
W jzykach C i C++ nie ma kompatybilnoci midzy tymi typami, nawet istnieje rnica midzy sta znakow i sta tekstow zawierajc jeden znak. Na przykad 565
to nie to samo co 868. Pierwsza staa oznacza znak o wartoci numerycznej 65 (kod
litery A), za druga tekst o dugoci jednego znaku, zawierajcy liter A i zakoczony znakiem 7'. W Turbo Pascalu nie ma takiego problemu, zmiennej acuchowej
(typu ) mona przypisa warto znakow.
5

Przy wczonej opcji Uunsigned characters kompilator Borland C++ traktuje wartoci typu  jak

  (liczby cakowite bez znaku). Domylnie opcja ta jest wczona.

74

Turbo Pascal i Borland C++. Przykady

Definiowanie staych symbolicznych w C++


Zamieszczone na pocztku programu cztery dyrektywy 9, waciwe jzykowi
C, s odpowiednikiem definicji staych w pascalowskiej procedurze Rysowanie. Definiuj one nazwy symboliczne: N, DX, WIDTH i DEPTH, z ktrymi wi okrelone
cigi znakw. Kade wystpienie takiej nazwy w tekcie programu, z wyjtkiem nazw
w cudzysowach, jest przez preprocesor zamieniane na odpowiadajcy jej cig znakw. Stosowanie dyrektyw 9 prowadzi niekiedy do bdw. Np. gdyby cig
znakw odpowiadajcy nazwie N nie zawiera nawiasw, cig odpowiadajcy nazwie
DX okrelaby nieprawidowy rozstaw supkw.
W jzyku C++ istnieje moliwo definiowania staych za pomoc sowa kluczowego

, co pozwala na unikanie dyrektywy 9 i nieprzyjemnych problemw wy-

nikajcych z jej stosowania. Omawiane dyrektywy lepiej jest zastpi nastpujcymi


deklaracjami staych:

 M4T4044/#++1 )
UV

 GZP=<+M++
 
UV

 36G. ;,GZ+O++9WX
U

 GF*. !GZ036G. %+(++UY)WX
U

Wykres funkcji
drga harmonicznych tumionych
Sporzdzenie wykresu funkcji cigej jednej zmiennej sprowadza si do obliczania
wartoci tej funkcji w odpowiednio duej liczbie punktw rozpatrywanego przedziau
i narysowania linii amanej o wyznaczonych w ten sposb wierzchokach punktach
paszczyzny. W celu zobrazowania wykresu na ekranie monitora komputerowego konieczne jest przejcie od rzeczywistego ukadu wsprzdnych, w ktrym zdefiniowana
jest funkcja, do ukadu ekranowego. Operacja ta, zwana okienkowaniem (ang. windowing), dotyczy dwch obszarw prostoktnych o bokach rwnolegych do osi wsprzdnych: okna w ukadzie rzeczywistym i widoku (ang. viewport) w ukadzie ekranowym [2].

Okno i widok przy tworzeniu wykresu funkcji


Zamy, e potrafimy wyznacza wartoci funkcji cigej y = f (x) dla wartoci
zmiennej x nalecych do przedziau [ xRmin , xRmax ] . Niech yRmin oznacza minimaln, a yRmax maksymaln warto f w tym przedziale. Wykres funkcji f mieci si wtedy w prostoktnym oknie

[ xRmin , xRmax ] [ yRmin , yRmax ]


ktrego odpowiednikiem na ekranie monitora jest widok

Rozdzia 3. Grafika

75

[ xVmin , xVmax ] [ yVmin , yVmax ]


Zazwyczaj widok nie zajmuje caego ekranu. Na przykad oprcz niego moe by
wywietlana dodatkowa informacja tekstowa, tabelka lub inny element graficzny.
W przedstawionym na rysunku 3.6 przypadku pokazane jest okno w ukadzie rzeczywistym (po lewej) i widok w ukadzie ekranowym (po prawej), zamieszczony w wikszym prostokcie pozwalajcym na dorysowanie osi ukadu wsprzdnych:

[ xE min , xE max ] [ yE min , yE max ]


Rysunek 3.6.
Ukad rzeczywisty
(po lewej) i ekranowy
(po prawej)

Takie rozwizanie pozwala na wygodne okrelanie rozmiarw rysunku i jego umiejscowienie na ekranie6. Wystarczy ustali parametry tego prostokta i wyliczy granice widoku ze wzorw:

xVmin = xE min + dx,

xVmax = xE max dx s

yVmin = yE min dy,

yVmax = yE max + dy + s

gdzie dx i dy s odstpami (poziomym i pionowym) granic prostoktw rwnymi dugociom odcinkw osi wystajcych poza widok, a s dugoci strzaki koczcej te
odcinki. Wartoci dx, dy i s mona dobra eksperymentalnie, kierujc si wzgldami
estetycznymi. Uycie znaku : (minus) zamiast % (plus) we wzorach okrelajcych
wsprzdne y widoku jest konsekwencj faktu, i na ekranie o y jest skierowana
w d. Jest oczywiste, e gdy o nie jest rysowana, stosowne brzegi obu prostoktw
pokrywaj si.
Odwzorowanie opisujce przejcie od wsprzdnych ( xR, yR) okna w ukadzie rzeczywistym do wsprzdnych ( xV , yV ) widoku w ukadzie ekranowym ma posta:

xV = xV min + sx ( xR xR min ),

yV = yV min + sy ( yR yR min )

gdzie sx i sy s czynnikami skalujcymi speniajcymi zalenoci

sx =

xVmax xV min
yV max yVmin
, sy =
xRmax xR min
yR max yRmin

Urzdzeniem krelcym moe by rwnie inne urzdzenie, np. drukarka i ploter.

76

Turbo Pascal i Borland C++. Przykady

Program Drgania w Pascalu


Wykorzystamy teraz powysze rozwaania do sporzdzenia wykresu funkcji opisujcej drgania harmoniczne tumione [13]:

y = A e bx cos( x + )
Wzr przedstawia amplitud (przemieszczenie) y drgajcego punktu materialnego
w zalenoci od czasu x. Staa A oznacza amplitud w chwili pocztkowej, b czynnik tumicy, czstotliwo drga, faz pocztkow. Wartoci A, b i s
liczbami dodatnimi. Wielko amplitudy zawiera si pomidzy dwoma asymptotami

Amin ( x) = A e bx y A e bx = Amax ( x)
i zanika w czasie, dc do zera.
Na wydruku 3.9 przedstawiony jest peny program w Turbo Pascalu tworzcy wykres
drga harmonicznych dla parametrw A = 3, b = 1/2, = 5 i = 0 w przedziale czasowym od 0 do 2. Podstawowymi skadowymi programu s:
 funkcje xV i yV opisujce przejcie od ukadu rzeczywistego do ekranowego,
 funkcje Amax i Amin stanowice deklaracje obydwu asymptot,
 funkcja Ruch opisujca drgania harmoniczne tumione,
 procedura Ustaw_Paramery nadajca wartoci wszystkim zmiennym

globalnym,
 procedura Rysuj_Uklad rysujca osie ukadu wsprzdnych,
 procedura Rysuj_Wykres rysujca wykres funkcji.
Wydruk 3.9. Program Drgania.pas tworzcy wykres funkcji drga harmonicznych tumionych

 
   
 
 
   
!""   #
$
%!%!% ! !% %  
%&%&% & &%%%%  %  
 
'
(% ) 
%(%! )  
* 
%!( %+(%!,%!))-%

 ( ! )  

Rozdzia 3. Grafika
* 
 !( +( !, !))- 

 %(% ) 
* 
 %.+ %(,/01+%)

 (% ) 
* 
 , %(%)

!(% ) 
* 
! %(%)+ (1+%)

  2 3 4  
$
  
* 
%&/%&% 5%6
 & 5%7 &%/
%!/%!%8+4
 ! (%!) !% %(%!)
(%&%,%&)$81
%%&-%%%&%,,9
( &%, &)$81
  &- % &%,-9
 %(%%,%):(%!%,%!)
 ( %, ):( !%, !)

  !  2

$
  
* 
 (/)
5$ ;(%&)< ;(%&%)
< ! (,9,.)5$ ;(%&%)< ! (,9.)
=; %67(%&%,9,>?@%@)
%(/)
5$ ;( &)< ;( &%)
< ! (,.9)5$ ;( &%)< ! (.9)
=; %67(,>? &%@ @)

  !  
 ('
)
$
%  
* 
5$ ;(% ((%!)))
%%->%%
< ;(% ((%!-(%,%): %)))


77

78

Turbo Pascal i Borland C++. Przykady


* 
A(!""@B;4BCA@)
2 3 4  
D ( )
!  2

!  
 ( %)
!  
 ( )
D ( )
!  
 (!)
!  
 
0

Procedura Ustaw_Parametry wykonuje szereg wanych operacji pomocniczych. Najpierw okrela usytuowanie i wielko prostokta obejmujcego rysunek, przypisujc
zmiennym xEmin, xEmax, yEmin i yEmax stosowne wartoci kracowe. Proponowany prostokt zajmuje cay ekran, poniewa jego lewy grny rg jest umiejscowiony
w punkcie (0, 0), a prawy dolny w punkcie (, ). Funkcja  podaje maksymaln warto wsprzdnej x, a  maksymaln warto wsprzdnej y ekranu graficznego (dla trybu 
s to liczby 639 i 479). Nastpnie procedura
Ustaw_Parametry wyznacza okno w ukadzie rzeczywistym, przypisujc zmiennym
xRmin i xRmax wartoci kocw rozpatrywanego przedziau czasowego, a zmiennym
yRmin i yRmax minimaln i maksymaln amplitud. Kolejne obliczenia dotycz ustalenia kracw widoku w ukadzie ekranowym. Poniewa na rysunku maj by pokazane odcinki obu osi ukadu wsprzdnych, granice widoku s przesunite wzgldem
granic prostokta obejmujcego cay rysunek o 1/25 jego szerokoci i 1/25 wysokoci, z uwzgldnieniem strzaek o dugoci 8 pikseli. Wartoci wynikowe zostaj zapamitane w zmiennych xVmin, xVmax, yVmin i yVmax. Na koniec procedura wylicza
w zmiennych sx i sy czynniki skalujce, ktre s wykorzystywane przez funkcje xV i yV.
Uproszczenia wynikajce z dbaoci o niewielki i czytelny kod programu sprawiy, e
procedura Ustaw_Parametry nie umoliwia okrelania parametrw drga harmonicznych (A, b, i ) i zakresu czasowego (xRmax), ani ustalania rozmiaru i pooenia
rysunku na ekranie (xEmin, xEmax, yEmin, yEmax). Czytelnik moe takie udoskonalenia wprowadzi, modyfikujc kod programu (podprogramy Amax, Ruch i Ustaw_
Parametry).
Procedura Rysuj_Uklad jest bardzo prosta. Rysuje odcinki osi ukadu wsprzdnych,
koczc je strzakami i opisujc tradycyjnymi jednoliterowymi nazwami x i y. Strzaki s skadane z dwch krtkich odcinkw za pomoc procedury , ktra rysuje
odcinek od biecej pozycji pisaka do jego nowej pozycji przesunitej o okrelon
liczb pikseli.

Nazwa funkcji parametrem podprogramu w Pascalu


Szczeglnie istotn rol w powyszym programie odgrywa krtka procedura Rysuj_
Wykres, ktra rysuje wykres funkcji f okrelonej w parametrze. Zmienna lokalna xV
przebiega kolejno wszystkie wartoci cakowite na osi x widoku w ukadzie ekranowym, te za s przeliczane na wartoci osi x okna w ukadzie rzeczywistym. W konse-

Rozdzia 3. Grafika

79

kwencji uzyskuje si cig rwnoodlegych punktw wypeniajcych na caej szerokoci


przedzia okrelonoci funkcji f, w ktrych wylicza si wartoci y = f (x) . Otrzymane
w ten sposb punkty (x, y) w ukadzie rzeczywistym s wierzchokami amanej przybliajcej funkcj. Odwzorowanie ich do ukadu ekranowego (tylko wsprzdnej y,
bo ekranowe x jest wartoci zmiennej xV) umoliwia rysowanie na ekranie amanej
stanowicej graficzne przedstawienie funkcji f.
Wynik wykonania programu jest pokazany na rysunku 3.7. Uzyskany obraz przedstawia przebiegi trzech funkcji: amplitudy grnej, amplitudy dolnej i drgania harmonicznego tumionego w czasie. Potrjny wykres jest efektem trzykrotnego wywoania
procedury Rysuj_Wykres: dla funkcji Amax, Amin i Ruch. Wystpienie nazw tych
funkcji w roli parametru procedury Rysuj_Wykres wymagao zdefiniowania nowego
typu funkcyjnego Funkcja i uycia sowa kluczowego  w ich deklaracjach7.
Rysunek 3.7.
Wykres drga
harmonicznych
tumionych w czasie

Nazwa funkcji a wskanik w C i C++


Przetumaczenie omwionego wyej programu pascalowskiego na jzyk Borland C++
jest czynnoci niemal automatyczn. Jedyny kopot moe sprawi podprogram rysowania wykresu funkcji. Nazwa funkcji, podobnie jak nazwa tablicy, jest w C i C++
wskanikiem. Przekonao si o tym dobitnie wielu studentw programujcych w Turbo Pascalu, ktrzy na pocztku swojej przygody z Borland C++ prbowali wyczyci
ekran za pomoc instrukcji
 

Turbo Pascal rozrnia wskaniki 16-bitowe (  bliskie) i 32-bitowe ( dalekie). Nazwa
podprogramu jest wskanikiem, a gdy wystpuje jako parametr, musi by wskanikiem 32-bitowym.
W rodowiskach 32-bitowych sowa  i   s ignorowane.

80

Turbo Pascal i Borland C++. Przykady

Ku ich wielkiemu zaskoczeniu ekran pozosta zamiecony, poniewa jest to formalnie


poprawna instrukcja wyraeniowa, ktra jedynie wyznacza wskanik do podprogramu
. Podan instrukcj bya
 ()

Powrmy do deklaracji podprogramu rysowania funkcji. Prawidowym jego parametrem okrelajcym funkcj, ktrej wykres ma by tworzony, jest
* (+)(* )

Zapis ten mwi, e f jest wskanikiem do funkcji zmiennej rzeczywistej zwracajcej


wynik rzeczywisty. Pierwsza para nawiasw jest tu bardzo istotna, gdy bez nich zapis okrelaby funkcj zwracajc wskanik do wartoci rzeczywistej.

Program Drgania w C++


Peny kod programu w jzyku Borland C++, rysujcego wykres funkcji drga harmonicznych tumionych w czasie, zosta przedstawiony na wydruku 3.10.
Wydruk 3.10. Program Drgania.cpp tworzcy wykres funkcji drga harmonicznych tumionych
E F 0G
E F0G
E F0G
 !"" #A
%&%&% & &%%%%  %
* %!%!% ! !% % 
%(* %!)
H
  %+(%!,%!)-%
I
 (*  !)
H
  +( !, !)- 
I
*  %(* %)
H
 .+ %(,/01+%)
I
*  (* %)
H
 , %(%)
I
* !(* %)
H
  %(%)+ (1+%)

Rozdzia 3. Grafika

81

I
$ 3   ()
H

%&/%&% %%()
 & % () &%/
%!/%!%8+5 4A
 ! (%!) !% %(%!)
%%&-((%&%,%&):81)
%%%&%,,9
  &-(( &%, &):81)
 % &%,-9
 %(%%,%):(%!%,%!)
 ( %, ):( !%, !)
I
$  
()
H

$ (%& (/)) (%&%)
  (,9,.)$ (%&%)  (,9.)
 %% (%&%,9,>?J%J)
$ (%(/) &) ( &%)
  (,.9)$ ( &%)  (.9)
 %% (,>? &%J J)
I
$  3
 (* (+)(* ))
H
$ (% ((%!)))
(%%->%F%%%--)
 (% ((%!-(%,%): %)))
I
$()
H
(KK!""JBBCBBCAJ)
 3   ()
 (7 L)
  
()
  3
 ( %)
  3
 ( )
 (#A;&)
  3
 (!)
 ()
 ()
I

W funkcji rysuj_wykres skorzystano z powszechnie stosowanego w C++ udogodnienia deklarowania zmiennej w wyraeniu inicjujcym ptli . Dotyczy to zmiennej
xV penicej rol licznika ptli. Tak zadeklarowana zmienna jest dostpna od miejsca
jej zadeklarowania do koca bloku obejmujcego ptl, w tym przypadku do koca
funkcji rysuj_wykres.

82

Turbo Pascal i Borland C++. Przykady

wiczenia
wiczenie 3.1
Trjkt Sierpiskiego mona wygenerowa, korzystajc z ukadu trzech tzw. iterowanych odwzorowa, ktre punktowi (x, y) przyporzdkowuj punkt (x, y) na podstawie rwna:
a) x = 0,5x,

y = 0,5y

b) x = 0,5x + 0,5,

y = 0,5y

c) x = 0,5x + 0,25,

y = 0,5y + 0,5

Algorytm jest rwnie prosty jak w przypadku omwionej na pocztku tego rozdziau
gry w chaos, stanowi waciwie jej odmian. Na pocztku wybieramy dowolny punkt
(x0, y0). Nastpnie losujemy jedno z trzech odwzorowa i wyznaczamy punkt (x1, y1)
jako obraz punktu (x0, y0) przeksztaconego przez wylosowane odwzorowanie. Losowanie odwzorowania i wyznaczanie kolejnego punktu powtarzamy, np. 50 000 razy.
Otrzymany cig punktw, po ewentualnym pominiciu pewnej liczby pocztkowych
elementw, tworzy trjkt Sierpiskiego zawarty w kwadracie [0, 1][0, 1]. Przedstawienie go na ekranie monitora wymaga odwzorowania tego kwadratu do stosownego widoku w ukadzie ekranowym. Napisa program rysujcy w ten sposb trjkt
Sierpiskiego.

wiczenie 3.2
Napisa program, ktry rysuje li paprotki Barnsleya8, wykorzystujc ukad czterech
iterowanych odwzorowa losowanych z rnym prawdopodobiestwem p:
a) x = 0,849x + 0,037y + 0,075,

y = -0,037x + 0,849y + 0,183,

p = 0,74

b) x = 0,197x 0,226y + 0,400,

y = 0,226x + 0,197y + 0,049,

p = 0,13

c) x = 0,150x + 0,283y + 0,575, y = 0,260x + 0,237y 0,084,

p = 0,11

d) x = 0,500,

p = 0,02

y = 0,160y,

Podany nierwnomierny rozkad prawdopodobiestwa mona uzyska, rozrniajc cztery zakresy wartoci losowych Random(100): 0 73, 74 86, 87 97
i 98 99.

wiczenie 3.3
Zmodyfikowa procedur rysowania gwiazdki (wydruki 3.3 i 3.4) tak, aby jedno jej rami byo skierowane w gr. Napisa program przedstawiajcy flag USA, ktry wykorzystuje tak zmodyfikowan procedur do rysowania 50 gwiazdek picioramiennych.
8

Trjkt Sierpiskiego i paprotka Barnsleya s tzw. fraktalami. Te i inne przykady fraktali oraz ich
metody generowania mona znale np. w ksikach [6, 8, 9].

Rozdzia 3. Grafika

83

wiczenie 3.4
Napisa program, ktry tworzy wykres funkcji

y = sin x cos 3 x

1
1 2
cos 2 x +
x 1,
4
20

x [2 ,2 ]

Przed sporzdzeniem wykresu program powinien wyznaczy wysoko okna w ukadzie rzeczywistym, znajdujc minimaln i maksymaln warto funkcji. Obliczenia te
nie musz by bardzo dokadne, wystarczy porwna wartoci funkcji w punktach
dzielcych przedzia np. na 100 rwnych odcinkw.

wiczenie 3.5
W obliczeniach numerycznych korzysta si niekiedy z wielomianw Czebyszewa, ktre mona zdefiniowa nastpujco:

T0 ( x) = 1
T1 ( x) = x
Tk ( x) = 2 xTk 1 ( x) Tk 2 ( x) (k = 2,3,...)
Ich wartoci bezwzgldne dla x nalecych do przedziau [-1, 1] nie przekraczaj wartoci 1. Napisa program, ktry w jednym widoku, odpowiadajcemu oknu [-1, 1][-1, 1],
rysuje wykresy kilku pocztkowych wielomianw Czebyszewa.

You might also like