You are on page 1of 159

Zadania z programowania w jzyku C/C++, cz.

Uniwersytet Marii Curie-Skodowskiej Wydzia Matematyki, Fizyki i Informatyki Instytut Informatyki

Zadania z programowania w jzyku C/C++, cz. I

Jacek Krzaczkowski

Lublin 2011

Instytut Informatyki UMCS Lublin 2011

Jacek Krzaczkowski

Zadania z programowania w jzyku C/C++, cz. I


Recenzent: Grzegorz Matecki Opracowanie techniczne: Marcin Denkowski Projekt okadki: Agnieszka Kumierska

Praca wspnansowana ze rodkw Unii Europejskiej w ramach Europejskiego Funduszu Spoecznego

Publikacja bezpatna dostpna on-line na stronach Instytutu Informatyki UMCS: informatyka.umcs.lublin.pl.

Wydawca
Uniwersytet Marii Curie-Skodowskiej w Lublinie Instytut Informatyki pl. Marii Curie-Skodowskiej 1, 20-031 Lublin Redaktor serii: prof. dr hab. Pawe Mikoajczak www: informatyka.umcs.lublin.pl email: dyrii@hektor.umcs.lublin.pl

Druk
ESUS Agencja Reklamowo-Wydawnicza Tomasz Przybylak ul. Ratajczaka 26/8 61-815 Pozna www: www.esus.pl

ISBN: 978-83-62773-06-0

Spis treci

Przedmowa 1 Podstawy jzykw C i C++, operacje sterujce


1.1. 1.2. 1.3. 1.4. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . Podstawy jzykw C i C++, operacje wejcia wyjcia. Instrukcje warunkowe i wyboru . . . . . . . . . . . . . Ptle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

vii 1 2 2 3 4 7 8 8

2 Funkcje
2.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 Wskaniki i referencje

13 3.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 17 4.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 23 5.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 31 6.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 32 6.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 37 7.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 38 7.2. Zoone typy danych . . . . . . . . . . . . . . . . . . . . . . . 38 7.3. Listy jednokierunkowe . . . . . . . . . . . . . . . . . . . . . . 41 47

4 Tablice jednowymiarowe

5 Napisy

6 Tablice wielowymiarowe

7 Zoone typy danych, listy wskanikowe

8 Operacje na plikach

vi

SPIS TRECI 8.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 48 8.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

9 Instrukcje preprocesora, aplikacje wieloplikowe, makefile.

51 9.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . 52 9.2. Makra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 9.3. Aplikacje wieloplikowe, makele . . . . . . . . . . . . . . . . . 53 10.1. Rozwizania 10.2. Rozwizania 10.3. Rozwizania 10.4. Rozwizania 10.5. Rozwizania 10.6. Rozwizania 10.7. Rozwizania 10.8. Rozwizania 10.9. Rozwizania 10.10. ozwizania R 10.11. ozwizania R 10.12. ozwizania R 10.13. ozwizania R do do do do do do do do do do do do do zada zada zada zada zada zada zada zada zada zada zada zada zada z z z z z z z z z z z z z rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau 1.2 1.3 1.4 2.2 3.2 4.2 5.2 6.2 7.2 7.3 8.2 9.2 9.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 58 62 65 70 77 79 86 97 105 113 129 138 139 151

10 Rozwizania i wskazwki

Bibliografia

Przedmowa
Ksika ta jest adresowana przede wszystkim do czytelnikw uczcych si jzyka C lub strukturalnego C++ jako swojego pierwszego jzyka programowania. Ponadto moe by uyteczna dla programistw C i programistw C++ pragncych szybko nauczy si podstaw drugiego z omawianych jzykw. Poniewa niniejszy zbir jest przeznaczony przede wszystkim dla pocztkujcych programistw, wiele spord zawartych w nim zada ma suy nie tyle sprawdzeniu znajomoci jzyka C lub C++, co wyrobieniu umiejtnoci algorytmicznego mylenia i programowania w ogle. Z tego samego powodu w zbiorze tym jest niewiele zada sprawdzajcych znajomo funkcji bibliotecznych. Nie znaczy to, e w skrypcie zabrako zada trudniejszych, wymagajcych znajomoci bardziej zaawansowanych moliwoci jzykw C i C++. Niniejszy zbir zada moe by uywany zarwno w ramach kursu na uczelni, jak i przez osoby uczce si programowa samodzielnie. Skrypt ten zosta napisany przy zaoeniu, e czytelnik korzysta jednoczenie z ksiki lub materiaw zawierajcych systematyczny opis skadni jzyka C lub C++. Przykady takich ksiek i materiaw, take takich, ktre s bezpatnie dostpne w internecie, czytelnik znajdzie w bibliograi. Piszc niniejszy zbir zada autor wykorzysta dowiadczenia nabyte w cigu kilku lat prowadzenia zaj z przedmiotw Programowanie w jzyku C i Programowanie w jzyku C++ na kierunku informatyka na Uniwersytecie Marii Curie-Skodowskiej w Lublinie. W pierwszych dziewiciu rozdziaach skryptu znajduj si podzielone tematycznie zadania. Kolejno rozdziaw odpowiada kolejnoci, w jakiej zdaniem autora naley uczy si strukturalnego programowania w jzykach C i C++. Czytelnik uczcy si jzyka C od podstaw moe omin rozdzia 3 i wrci do niego w trakcie czytania rozdziau 5. Zadania w poszczeglnych rozdziaach s zazwyczaj uoone od najprostszych do najtrudniejszych. Gwiazdk zostay oznaczone zadania trudniejsze lub wymagajce szczegowej znajomoci jzyka C lub C++. Czytelnik, ktry dopiero zaczyna swoj przygod z programowaniem, moe pomin w trakcie pierwszego czytania te zadania i wr do nich pniej.

viii

Przedmowa W ostatnim rozdziale czytelnik znajdzie rozwizania wielu spord zada zawartych w niniejszym zbiorze zada. Rozwizania te s integraln czci skryptu. Doczone do rozwiza komentarze maj na celu m.in. zwrcenie uwagi czytelnika na ciekawy sposb rozwizania zadania, pojawiajce si w trakcie rozwizywania zadania problemy czy te bdy czsto popeniane przez niedowiadczonych programistw. W przypadkach gdy ma to warto dydaktyczn przedstawiono kilka wariantw rozwiza poszczeglnych zada. W rozdziale z rozwizaniami prezentowane s zarwno rozwizania w jzyku C, jak i w C++. W wypadku gdy rozwizania danego zadania w obu jzykach s takie same lub podobne, prezentowane jest tylko jedno rozwizanie. Dla zada, dla ktrych wzorcowe rozwizania w jzykach C i C++ istotnie si rni, prezentowane s rozwizania w obu jzykach. Czsto jednak nawet w takich sytuacjach rozwizanie w jzyku C jest rwnoczenie poprawnym rozwizaniem w C++. Wszystkie rozwizania zawarte w tym skrypcie byy kompilowane przy pomocy GNU Compiler Collection w wersji 4.4.1 na komputerze z zainstalowanym systemem operacyjnym OpenSUSE 11.2. O ile nie podano inaczej, przykadowe programy napisane w C byy kompilowane przy pomocy polecenia gcc <nazwa programu>. Przykadowe programy w C++ byy kompilowane przy pomocy polecenia g++ <nazwa programu>.

Aby uatwi posugiwanie si zbiorem zada wprowadzono nastpujce oznaczenia: * trudne zadanie, r zadanie rozwizane w ostatnim rozdziale, ! zadanie, ktrego rozwizanie z rnych powodw jest szczeglnie interesujce, C zadanie do rozwizania wycznie w jzyku C, C++ zadanie do rozwizania wycznie w jzyku C++, r zadanie ilustrujce rnic pomidzy jzykiem C a jzykiem C++.

Rozdzia 1
Podstawy jzykw C i C++, operacje sterujce

1.1. 1.2. 1.3. 1.4.

Wprowadzenie . . . . . . . . . . . . . . . . . Podstawy jzykw C i C++, operacje wejcia Instrukcje warunkowe i wyboru . . . . . . . . Ptle . . . . . . . . . . . . . . . . . . . . . .

. . . . . wyjcia. . . . . . . . . . .

. . . .

2 2 3 4

1. Podstawy jzykw C i C++, operacje sterujce

1.1. Wprowadzenie
W tym rozdziale czytelnik znajdzie zadania pozwalajce przewiczy najbardziej podstawowe elementy jzykw C i C++. W podrozdziale ?? znajduj si zadania sprawdzajce podstawow wiedz na temat pisania programw w jzykach C i C++ oraz podstawy operacji wejcia/wyjcia w tych jzykach. Podrozdziay ?? i ?? zawieraj zadania pozwalajce przewiczy uywanie instrukcji sterujcych. Podrozdziay te s przeznaczone szczeglnie dla tych, ktrzy ucz si swojego pierwszego imperatywnego jzyka programowania. W rozwizaniach zada celowo nie uyto instrukcji takich jak goto, break (za wyjtkiem wntrza instrukcji switch) czy continue, ktre s uwaane za niezgodne z zasadami programowania strukturalnego.

1.2. Podstawy jzykw C i C++, operacje wejcia wyjcia.


??.1 (r) Napisz program wypisujcy na standardowym wyjciu napis Hello World. ??.2 Napisz program wypisujcy w kolejnych wierszach standardowego wyjcia pojedyncze sowa nastpujcego napisu Bardzo dlugi napis. ??.3 Napisz program wypisujcy na standardowym wyjciu nastpujcy napis: Napis zawierajacy rozne dziwne znaczki // \ \ $ & %. ??.4 (r,!) Napisz program, ktry wczytuje ze standardowego wejcia liczb cakowit i wypisuje j na standardowym wyjciu. ??.5 (r,!) Napisz program, ktry wczytuje ze standardowego wejcia liczb wymiern i wypisuje j na standardowym wyjciu ??.6 Napisz program, ktry wczytuje ze standardowego wejcia trzy liczby cakowite, a nastpnie wypisuje je w oddzielnych liniach na standardowym wyjciu. ??.7 Napisz program, ktry wczytuje ze standardowego wejcia liczb cakowit i wypisuje na standardowym wyjciu liczb o jeden wiksz. ??.8 (r,!) Napisz program, ktry wczytuje ze standardowego wejcia trzy liczby cakowite i wypisuje na standardowym wyjciu ich redni arytmetyczn. ??.9 (r,!,r) Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb wymiern x i wypisuje na standardowym wyjciu x. ??.10 Napisz program, ktry wczytuje ze standardowego wejcia liczb wymiern x i wypisuje na standardowym wyjciu warto bezwzgldn z x.

1.3. Instrukcje warunkowe i wyboru ??.11 (r) Napisz program, ktry wczytuje ze standardowego wejcia liczb wymiern i wypisuje j na standardowym wyjciu z dokadnoci do dwch miejsc po przecinku. ??.12 Napisz program, ktry wczytuje ze standardowego wejcia liczb wymiern i wypisuje j na standardowym wyjciu w notacji wykadniczej (czyli takiej, w ktrej 0.2 to 2.0e-1).

1.3. Instrukcje warunkowe i wyboru


??.1 (r) Napisz program, ktry wczytuje ze standardowego wejcia liczb cakowit n i wypisuje na standardowe wyjcie warto bezwzgldn z n. Do rozwizania zadania nie uywaj funkcji bibliotecznych za wyjtkiem operacji wejcia/wyjcia. ??.2 Napisz program, ktry wczytuje ze standardowego wejcia dwie liczby cakowite i wypisuje na standardowym wyjciu wiksz z nich (w przypadku gdy podane liczby s rwne, program powinien wypisa ktrkolwiek z nich). ??.3 Napisz program, ktry wczytuje ze standardowego wejcia trzy liczby cakowite i wypisuje na standardowym wyjciu najwiksz z ich wartoci (pamitaj o przypadku gdy wszystkie podane liczby lub dwie z nich s rwne). ??.4 Napisz program, ktry wczytuje ze standardowego wejcia dwie liczby cakowite i wypisuje t o wikszej wartoci bezwzgldnej. ??.5 (r) Napisz program obliczajcy pole trjkta na podstawie wymiarw podanych przez uytkownika. Uytkownik powinien mie moliwo podania dugoci podstawy i wysokoci lub wszystkich bokw trjkta. ??.6 Napisz program, ktry wczytuje ze standardowego wejcia wspczynniki ukadu dwch rwna liniowych z dwoma niewiadomymi i wypisuje na standardowym wyjciu rozwizanie ukadu rwna. W przypadku nieskoczonej liczby lub braku rozwiza program powinien wypisa na standardowym wyjciu odpowiedni informacj. Podpowied: zaimplementuj algorytm rozwizywania ukadw rwna metod wyznacznikw (inaczej nazywan wzorami Cramera). ??.7 Napisz program, ktry wczytuje ze standardowego wejcia wspczynniki rwnania kwadratowego z jedn niewiadom i wypisuje na standardowym wyjciu wszystkie rozwizania rzeczywiste tego rwnania lub odpowiedni informacj w przypadku braku rozwiza. ??.8 (r) Napisz program, ktry w zalenoci od wyboru uytkownika wczytuje ze standardowego wejcia wymiary: kwadratu, prostokta lub trj-

1. Podstawy jzykw C i C++, operacje sterujce kta i wypisuje na standardowym wyjciu pole gury o wczytanych wymiarach. ??.9 Napisz program kalkulator, ktry wykonuje wybran przez uytkownika operacj arytmetyczn na dwch wczytanych liczbach. Program powinien wczytywa dane ze standardowego wejcia i wypisywa wynik na standardowym wyjciu.

1.4. Ptle
??.1 (r,!) Napisz program wczytujcy ze standardowego wejcia dwie dodatnie liczby cakowite n i m, i wypisujcy w kolejnych wierszach na standardowym wyjciu wszystkie dodatnie wielokrotnoci n mniejsze od m. ??.2 Napisz program wczytujcy ze standardowego wejcia dwie dodatnie liczby cakowite n i m, i wypisujcy na standardowym wyjciu m pierwszych wielokrotnoci liczby n. ??.3 Napisz program wczytujcy ze standardowego wejcia trzy dodatnie liczby cakowite n, m i k, i wypisujcy w kolejnych wierszach wszystkie wielokrotnoci n wiksze od m i mniejsze od k. ??.4 (r) Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu liczb n!. ??.5 Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu sum kwadratw liczb od 0 do n, czyli warto 02 + 12 + 32 + ... + n2 . ??.6 Napisz program, ktry wczytuje ze standardowego wejcia liczb cakowit n (n > 2) i wypisuje na standardowym wyjciu iloczyn liczb parzystych z zakresu od 2 do n (czyli 2 4 . . . n dla n parzystych i 2 4 . . . (n 1) w przeciwnym wypadku). ??.7 Napisz program, ktry wczytuje ze standardowego wejcia dwie liczby cakowite n i m (zakadamy, e n < m) i wypisuje na standardowym wyjciu liczb n . . . m. ??.8 (*,r) Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu element cigu Fibonacciego o indeksie n. ??.9 (r,!) Napisz program, ktry wczytuje ze standardowego wejcia dodatnie liczby cakowite n i m, i wypisuje na standardowym wyjciu najwikszy wsplny dzielnik tych liczb. ??.10 (r,!) Napisz program, ktry wczytuje ze standardowego wejcia nie ujemn liczb n i wypisuje na standardowym wyjciu warto n

1.4. Ptle (warto n zaokrglon w d do najbliszej wartoci cakowitoliczbowej). Program napisz bez uycia funkcji z biblioteki matematycznej. Napisz program, ktry wczytuje ze standardowego wejcia liczby a, b, c, d i: a) wypisuje na standardowe wyjcie najmniejsz nieujemn liczb cakowit x tak, e |a| x2 + b x + c > d. b) wypisuje na standardowe wyjcie najwiksz nieujemn liczb cakowit x tak, e 5x2 +ax+b < c. Zakadamy, e taka nieujemna cakowita liczba x istnieje. c) wypisuje na standardowe wyjcie najwiksz nieujemn liczb cakowit x tak, e 5x2 +ax+b c. Zakadamy, e taka nieujemna cakowita liczba x istnieje. (*,r) Napisz program, ktry wczytuje ze standardowego wejcia dodatni liczb n i wypisuje na standardowym wyjciu sum wszystkich liczb mniejszych od n, wzgldnie pierwszych z n. (*, r, !) Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu warto 0! + 1! + . . . + n!. (*) Napisz program, ktry wczytuje ze standardowego wejcia liczb n i wypisuje na standardowym wyjciu wszystkie trjki pitagorejskie (tj. trjki liczb cakowitych a, b, c takich, e a2 + b2 = c2 ), skadajce si z liczb mniejszych od n.

??.11

??.12

??.13

??.14

Rozdzia 2
Funkcje

2.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 2.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . .

8 8

2. Funkcje

2.1. Wprowadzenie
Funkcje s wanym elementem wikszoci jzykw imperatywnych. W niniejszym rozdziale znajduj si zadania pozwalajce przewiczy rne aspekty pracy z funkcjami, od pisania prostych funkcji po przecianie funkcji i pisanie funkcji z domylnymi wartociami argumentw (dwie ostatnie moliwoci udostpnia nam tylko jzyk C++). Czytelnik znajdzie w tym rozdziale take grup zada, w ktrych naley napisa funkcj rekurencyjn. Pisanie funkcji rekurencyjnych wymaga szczeglnej ostronoci, gdy w ich przypadku szukanie bdw jest wyjtkowo trudne. Pomimo tego warto przewiczy pisanie funkcji rekurencyjnych, poniewa w wielu przypadkach ich uycie pozwala znacznie uproci kod programu.

2.2. Zadania
??.1 (r) Napisz program, ktry wczytuje ze standardowego wejcia liczb cakowit n i wypisuje na standardowe wyjcie warto bezwzgldn z n. Do rozwizania zadania nie uywaj funkcji bibliotecznych za wyjtkiem operacji wejcia/wyjcia. W programie uyj samodzielnie zaimplementowanej funkcji liczcej warto bezwzgldn. ??.2 (r) Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu liczb n!. W programie uyj samodzielnie zaimplementowanej funkcji liczcej warto silni. ??.3 Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n (n > 2) i wypisuje na standardowym wyjciu najwiksz liczb k tak, e k dzieli n i k < n. Algorytm wyszukiwania liczby k speniajcej powysze warunki umie w oddzielnej funkcji. ??.4 Napisz funkcj, ktra dostaje jako argument nieujemn liczb cakowit n i zwraca jako warto liczb 2n . ??.5 Napisz funkcj, ktra dostaje jako argument liczb cakowit n i zwraca jako warto liczb 2n . ??.6 Napisz funkcj, ktra dostaje jako argumenty nieujemne liczby cakowite n i m, z ktrych co najmniej jedna jest rna od zera i zwraca jako warto nm . ??.7 Napisz funkcj, ktra dostaje jako argumenty liczby cakowite n i m, z ktrych co najmniej jedna jest rna od zera i zwraca jako warto nm . ??.8 Napisz funkcj, ktra dostaje jako argumenty liczb dodatni n i zwra ca jako warto n. Rozwi zadanie nie wykorzystujc funkcji bibliotecznych.

2.2. Zadania ??.9 (*) Napisz funkcj, ktra dostaje jako argumenty liczb cakowit m (m > 1) oraz nieujemn liczb n i zwraca jako warto m n. Rozwi zadanie nie wykorzystujc funkcji bibliotecznych. ??.10 (r) Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu sum liczb mniejszych od n i zarazem wzgldnie pierwszych z n. Algorytm wyliczania sumy podziel na dwie funkcje. ??.11 Napisz program, ktry wczytuje ze standardowego wejcia nieujemn liczb cakowit n i wypisuje na standardowym wyjciu nastpujc 0 + 1 + . . . + n. Algorytm wyliczania sumy podziel sum na dwie funkcje. ??.12 Napisz program, ktry wczytuje ze standardowego wejcia nieujemne liczby cakowit n i (m > i wypisuje na standardowym wyjciu m 1), nastpujc sum m 0 + m 1 + . . . + m n. Algorytm wyliczania sumy podziel na dwie funkcje. ??.13 (*,r) Napisz funkcj, ktra dostaje jako argument dodatni liczb cakowit n i wypisuje na standardowym wyjciu wszystkie moliwe rozkady liczby n na sumy dwch kwadratw dodatnich liczb cakowitych. Rozwa dwa przypadki: (a) gdy a2 + b2 i b2 + a2 dla a = b traktujemy jako dwa rwne rozkady, (b) gdy a2 + b2 i b2 + a2 traktujemy jako ten sam rozkad i wypisujemy tylko jedne z nich. Jeeli zajdzie taka potrzeba, moesz w rozwizaniu uywa funkcji pomocniczych. ??.14 (*) Napisz funkcj, ktra dostaje jako argument dodatni liczb cakowit n i wypisuje na standardowym wyjciu wszystkie moliwe rozkady liczby n na sumy kwadratw dodatnich liczb cakowitych. Rozwa dwa przypadki analogiczne do tych z zadania ??.??. Jeeli zajdzie taka potrzeba moesz w rozwizaniu uywa funkcji pomocniczych. ??.15 (*) Napisz funkcj, ktra dostaje jako argumenty dodatnie liczby cakowite n i m, i wypisuje na standardowym wyjciu wszystkie moliwe rozkady liczby n na sum dwch dodatnich liczb cakowitych podniesionych do potgi m. Rozwa dwa przypadki analogiczne do tych z zadania ??.??. Jeeli zajdzie taka potrzeba moesz w rozwizaniu uywa funkcji pomocniczych. ??.16 (*) Napisz funkcj, ktra dostaje jako argumenty dodatnie liczby cakowite n i m, i wypisuje na standardowym wyjciu wszystkie moliwe rozkady liczby n na sum dodatnich liczb cakowitych podniesionych do potgi m. Rozwa dwa przypadki analogiczne do tych z zadania ??.??. Jeeli zajdzie taka potrzeba moesz w rozwizaniu uywa funkcji pomocniczych.

10

2. Funkcje ??.17 (*,r,!) Napisz funkcj, ktra zlicza i wypisuje na standardowym wyjciu liczb swoich wywoa. ??.18 (*) Napisz funkcj generujc liczby pseudolosowe. Pierwsz wartoci funkcji powinna by dowolna liczba z przedziau (0, 1). Kolejne wartoci powinny by wyliczane ze wzoru xn = 1 x2 , n1 gdzie xn to aktualna, a xn1 to poprzednia warto funkcji. ??.19 (*) Napisz funkcj, ktra wczytuje ze standardowego wejcia liczb cakowit i zwraca j jako swoj warto. Dodatkowo funkcja powinna sumowa wszystkie dotychczas wczytane wartoci i przy kadym swoim wywoaniu wypisywa na standardowym wyjciu ich aktualn sum . ??.20 (r,!) Napisz rekurencyjn funkcj, ktra dla otrzymanej w argumencie nieujemnej cakowitej liczby n zwraca jako warto n!. ??.21 Napisz rekurencyjn funkcj zwracajc dla otrzymanej w argumencie nieujemnej liczby cakowitej n warto elementu o indeksie n cigu zdeniowanego w nastpujcy sposb: a0 = 1 an = 2 an1 + 5 dla n > 0. ??.22 Napisz rekurencyjn funkcj zwracajc dla otrzymanej w argumencie nieujemnej liczby cakowitej n warto elementu o indeksie n cigu zdeniowanego w nastpujcy sposb: a0 = a1 = 1 an = an1 + 2 an2 + 3 dla n > 1 . ??.23 (r,!) Napisz rekurencyjn funkcj zwracajc dla otrzymanej w argumencie nieujemnej liczby cakowitej n warto elementu cigu Fibonacciego o indeksie n. ??.24 (*) Napisz rekurencyjn funkcj zwracajc dla otrzymanej w argumencie nieujemnej liczby cakowitej n warto elementu o indeksie n cigu zdeniowanego w nastpujcy sposb a0 = a1 = 1 an = a0 + a1 + ... + an1 dla n > 1 . ??.25 (*) Napisz funkcj rekurencyjn, ktra dla otrzymanej w argumencie nieujemnej liczby cakowitej n zwraca warto elementu o indeksie n cigu zdeniowanego w nastpujcy sposb a0 = a1 = 1

2.2. Zadania an = an1 + n dla n parzystych an = an1 n dla n nieparzystych. ??.26 (*,r,!) Napisz funkcj rekurencyjn, ktra dla otrzymanej w argumencie nieujemnej liczby cakowitej n zwraca warto elementu o indeksie n cigu zdeniowanego w nastpujcy sposb a0 = a1 = a2 = 1 oraz dla k > 2 a3k = a3k1 + a3k2 a3k+1 = 5 a3k + 4 a3k+2 = a3k+1 . ??.27 (r) Napisz funkcj rekurencyjn, ktra dla otrzymanej w argumentach pary nieujemnych liczb cakowitych n i m zwraca warto f (n, m) gdzie funkcja f jest zdeniowana w nastpujcy sposb: f (n, 0) = n f (0, m) = m f (n, m) = f (n 1, m) + f (n, m 1) + f (n 1, m 1) dla n, m > 0. ??.28 Napisz funkcj rekurencyjn, ktra dla otrzymanej w argumentach pary nieujemnych liczb cakowitych n i m zwraca warto f (n, m) gdzie funkcja f jest zdeniowana w nastpujcy sposb: f (n, 0) = n f (n, m) = f (m, n) f (n, m) = n m + f (n 1, m) + f (n, m 1) dla n m > 0. ??.29 (r,!) Napisz rekurencyjn funkcj, ktra dostaje jako argumenty dwie dodatnie liczby cakowite n i m, i zwraca jako warto najwikszy wsplny dzielnik tych liczb obliczony algorytmem Euklidesa. ??.30 (C++,r,!) Napisz funkcj, ktra dostaje jako argumenty nieujemne liczby cakowite n i m, z ktrych co najmniej jedna jest rna od zera, i zwraca jako warto nm . Jeeli drugi z argumentw nie zostanie podany, funkcja powinna zwrci warto n2 . ??.31 (C++) Napisz funkcj, ktra dostaje jako argumenty liczb cakowi t m (m > 1) oraz nieujemn liczb n i zwraca jako warto m n. Rozwi to zadanie nie wykorzystujc funkcji bibliotecznych. W przypadku podania tylko pierwszego argumentu funkcja powinna zwraca n.

11

12

2. Funkcje ??.32 (C++) Napisz funkcj, ktra dostaje jako argumenty pi liczb cakowitych typu unsigned int i zwraca jako warto maksimum z podanych liczb. Funkcj napisz w taki sposb, eby mona byo jej poda take mniejsz liczb argumentw. ??.33 (C++) Napisz funkcj, ktra dostaje jako argumenty pi liczb typu unsigned int i zwraca jako warto sum podanych liczb. Funkcj napisz w taki sposb, eby liczya sum take dwch, trzech i czterech argumentw. ??.34 (C++) Napisz funkcj, ktra dostaje jako argumenty pi liczb typu int i zwraca jako warto iloczyn podanych liczb. Funkcj napisz w taki sposb, eby liczya iloczyn take dwch, trzech i czterech argumentw. ??.35 (C++) Napisz funkcj, ktra dla dwch dodatnich cakowitoliczbowych argumentw m i n zwraca warto true jeeli n dzieli m oraz false w przeciwnym wypadku. W przypadku podania jednego argumentu funkcja powinna sprawdza czy podana liczba jest parzysta. ??.36 (C++,r,!) Napisz rodzin dwuargumentowych funkcji pot, z ktrych kada jako argumenty otrzymuje liczb n i nieujemn liczb cakowit m typu unsigned int (zakadamy, e co najmniej jeden z argumentw jest rny od zera) i zwraca jako warto nm . Przeci funkcj pot dla n o typach: double, int, unsigned int. Wynik zwrcony przez kad z funkcji pot powinien by tego samego typu co n. ??.37 (C++) Rodzin funkcji pot z zadania ??.?? rozszerz o funkcje, w ktrych m jest typu int. Funkcje te powinny zwraca wartoci typu double. ??.38 (C++) Napisz rodzin funkcji maksimum zwracajcych maksimum z dwch liczb otrzymanych w argumentach. Typem zwracanym powinien by bardziej pojemny z typw argumentw (tak jak to ma miejsce w przypadku operacji arytmetycznych). Przykadowo dla jednego argumentu typu int a drugiego typu double zwrcony powinien zosta wynik o typie doble. ??.39 (C++) Napisz rodzin funkcji maksimum zwracajcych maksimum od dwch do piciu wartoci otrzymanych w argumentach. Argumenty funkcji oraz warto zwracana przez funkcj powinny by typu int. ??.40 (C++) Napisz rodzin funkcji srednia zwracajcych redni arytmetyczn z dwch lub trzech wartoci podanych przez uytkownika. Typem wyniku kadej z funkcji powinien by najbardziej pojemny z typw argumentw.

Rozdzia 3
Wskaniki i referencje

3.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 3.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . .

14 14

14

3. Wskaniki i referencje

3.1. Wprowadzenie
Autor niniejszego zbioru jest zwolennikiem tego, aby w procesie nauczania jzyka C jako pierwszego jzyka programowania, najpierw mwi o tablicach jednowymiarowych, a dopiero potem mwi o wskanikach i ich powizaniach z tablicami. Od lat w takiej wanie kolejnoci by prezentowany materia na kursie Programowanie w jzyku C na kierunku informatyka na UMCS. Takie uoenie materiau pozwala studentom oswoi si z podstawami programowania zanim zaczn poznawa trudne zagadnienia zwizane ze wskanikami. Niniejszy zbir zada odszed od takiego uoenia materiau ze wzgldu na jednoczesn prezentacj rozwiza w jzykach C i C++. O ile bowiem w jzyku C moemy uywa jednowymiarowych tablic nie wiedzc nic o wskanikach ani dynamicznym zarzdzaniu pamici, o tyle w jzyku C++ jest to moliwe tylko wtedy, gdy uywamy tablic o z gry (t.j. w momencie kompilacji) znanych rozmiarach. Ci spord czytelnikw, ktrzy ucz si jzyka C i nie chc jeszcze poznawa wskanikw mog przej od razu do rozdziau ??. Wikszo z prezentowanych tam zada nie bdzie wymagaa od nich znajomoci wskanikw.

3.2. Zadania
??.1 (r) Napisz funkcj otrzymujc jako argumenty wskaniki do dwch zmiennych typu int, ktra zwraca jako warto mniejsz z liczb wskazywanych przez argumenty. ??.2 (r) Napisz funkcj otrzymujc jako argumenty wskaniki do dwch zmiennych typu int, ktra zwraca jako warto wskanik na zmienn przechowujc mniejsz z liczb wskazywanych przez argumenty. ??.3 (r) Napisz funkcj otrzymujc jako argumenty wskaniki do dwch zmiennych typu int, ktra zamienia ze sob wartoci wskazywanych zmiennych. ??.4 Napisz funkcj otrzymujc jako argumenty wskaniki do dwch zmiennych typu int, ktra zamienia ze sob wartoci wskazywanych zmiennych tylko wtedy, gdy wskazywana przez drugi argument zmienna jest mniejsza od zmiennej wskazywanej przez pierwszy argument. ??.5 Napisz funkcj, ktrej argumentami s dwa wskaniki do staych typu int, za zwracan wartoci jest suma wartoci zmiennych wskazywanych przez argumenty. ??.6 Napisz funkcj, ktrej argumentami s n typu int oraz w wskanik do int, ktra przepisuje warto n do zmiennej wskazywanej przez w.

3.2. Zadania ??.7 (C++,r) Napisz funkcj otrzymujc jako argumenty referencje do dwch zmiennych typu int, ktra zamienia ze sob wartoci zmiennych, do ktrych referencje dostalimy w argumentach. ??.8 (C++) Napisz funkcj otrzymujc dwa argumenty referencj a oraz wskanik b do zmiennych typu int, ktra zamienia ze sob wartoci zmiennych, do ktrych wskanik i referencj dostaa w argumentach. ??.9 (r,r) Napisz bezargumentow funkcj, ktra rezerwuje pami dla pojedynczej zmiennej typu int i zwraca jako warto wskanik do niej. ??.10 Napisz bezargumentow funkcj, ktra rezerwuje pami dla pojedynczej zmiennej typu double i zwraca jako warto wskanik do niej. ??.11 (r,r) Napisz funkcj, ktra dostaje jako argument dodatni liczb cakowit n, rezerwuje w pamici blok n zmiennych typu int i zwraca jako warto wskanik do pocztku zarezerwowanego bloku pamici. ??.12 Napisz funkcj, ktra dostaje jako argument dodatni liczb cakowit n, rezerwuje w pamici blok n zmiennych typu double i zwraca jako warto wskanik do pocztku zarezerwowanego bloku pamici. ??.13 (*,r,!) Napisz funkcj o dwch argumentach: wskanik na funkcj o jednym argumencie typu int zwracajc warto typu double, warto typu int, ktra zwraca warto funkcji otrzymanej w pierwszym argumencie na liczbie cakowitej podanej w drugim argumencie. ??.14 (*) Napisz funkcj, ktra otrzymuje trzy argumenty: dwa wskaniki na funkcje o jednym argumencie typu int zwracajce warto typu int, warto n typu unsigned int, i zwraca true, jeeli otrzymane w argumentach funkcje s rwne dla wartoci od 0 do n i false w przeciwnym wypadku. ??.15 (r,!) Napisz funkcj, ktra dostaje dwa argumenty: wskanik na sta typu int i wskanik na zmienn typu int, i przepisuje zawarto staej wskazywanej przez pierwszy argument do zmiennej wskazywanej przez drugi argument. ??.16 (r,!) Napisz funkcj, ktra dostaje dwa argumenty: wskanik na sta typu int i stay wskanik na zmienn typu int. I przepisuje zawarto staej wskazywanej przez pierwszy argument do zmiennej wskazywanej przez drugi argument.

15

Rozdzia 4
Tablice jednowymiarowe

4.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 4.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . .

18 18

18

4. Tablice jednowymiarowe

4.1. Wprowadzenie
Wikszo zada prezentowanych w tym rozdziale nie wymaga od czytelnika uczcego si jzyka C znajomoci wskanikw. Wystarczy umiejtno deklarowania tablic automatycznych. Wszystkie zadania wymagajce operowania na wskanikach zostay oznaczone gwiazdk. W jzyku C++ nie mona deklarowa tablic automatycznych o rozmiarze podanym przez zmienn. Jedynym sposobem w jzyku C++ tworzenia tablic o rozmiarze nieznanym w momencie kompilacji jest rczne tworzenie tablic dynamicznych (na przykad za pomoc operatora new).

4.2. Zadania
??.1 Napisz funkcj, ktra otrzymuje dwa argumenty: nieujemn liczb cakowit n oraz n-elementow tablic tab elementw typu int i: a) (r) nadaje warto zero wszystkim elementom tablicy tab, b) (r) zapisuje do kolejnych elementw tablicy wartoci rwne ich indeksom (do komrki o indeksie i funkcja ma zapisywa warto i), c) podwaja warto wszystkich elementw w tablicy tab, d) do wszystkich komrek tablicy tab wstawia wartoci bezwzgldne ich pierwotnych wartoci. ??.2 Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz n-elementow tablic tab o elementach typu int i zwraca jako warto: a) (r) redni arytmetyczn elementw tablicy tab. b) sum elementw tablicy tab, c) sum kwadratw elementw tablicy tab. ??.3 (r) Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz n-elementow tablic tab o elementach typu const int i zwraca jako warto redni arytmetyczn elementw tablicy tab. ??.4 (*) Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz n-elementow tablic tab o elementach typu unsigned int i zwraca jako warto redni geometryczn elementw tablicy tab. ??.5 (*,r,!,r) Napisz funkcj, ktra otrzymuje jako argument liczb cakowit n (n 3) i zwraca jako warto najwiksz liczb pierwsz mniejsz od n (do wyznaczenia wyniku uyj algorytmu sita Eratostenesa). ??.6 Napisz funkcj, ktra otrzymuje trzy argumenty: dodatni liczb cakowit n oraz dwie n-elementowe tablice tab1, tab2 o elementach typu int i: a) (r) przepisuje zawarto tablicy tab1 do tablicy tab2,

4.2. Zadania b) przepisuje zawarto tablicy tab1 do tablicy tab2 w odwrotnej kolejnoci (czyli element tab1[0] ma zosta zapisany do komrki tablicy tab2 o indeksie n 1). Napisz funkcj, ktra otrzymuje cztery argumenty: dodatni liczb cakowit n oraz trzy n-elementowe tablice tab1, tab2 i tab3 o elementach typu int, i: a) przypisuje elementom tablicy tab3 sum odpowiadajcych im elementw tablic tab1 i tab2 (do komrki tablicy tab3 o indeksie i powinna tra suma elementw tab1[i] i tab2[i]), b) przypisuje elementom tablicy tab3 wikszy spord odpowiadajcych im elementw tablic tab1 i tab2 (do komrki tablicy tab3 o indeksie i powinien tra wikszy spord elementw tab1[i] i tab2[i]), c) przypisuje zawarto tablicy tab1 do tablicy tab2, zawarto tablicy tab2 do tablicy tab3 oraz zawarto tablicy tab3 do tablicy tab1. Napisz funkcj, ktra otrzymuje cztery argumenty: dodatni liczb cakowit n, n-elementowe tablice tab1 i tab2 oraz 2 n-elementow tablic tab3 o elementach typu double. a) Funkcja powinna przepisywa zawarto tablic tab1 i tab2 do tablicy tab3 w taki sposb, e na pocztku tablicy tab3 powinny si znale elementy tablicy tab1, a po nich elementy tablicy tab2. b) Funkcja powinna przepisywa zawarto tablic tab1 i tab2 do tablicy tab3 w taki sposb, e w komrkach tablicy tab3 o nieparzystych indeksach powinny si znale elementy tablicy tab1, a w komrkach tablicy tab3 o parzystych indeksach elementy tablicy tab2. Napisz funkcj, ktra otrzymuje cztery argumenty: dodatni liczb cakowit n oraz trzy n-elementowe tablice tab1, tab2 i tab3 o elementach typu int i zamienia zawartoci komrek otrzymanych w argumentach tablic w nastpujcy sposb: dla dowolnego i komrka tab1[i] powinna zawiera najwiksz spord pierwotnych wartoci komrek tab1[i], tab2[i] oraz tab3[i], dla dowolnego i komrka tab2[i] powinna zawiera drug co do wielkoci spord pierwotnych wartoci komrek tab1[i], tab2[i] oraz tab3[i], dla dowolnego i komrka tab3[i] powinna zawiera najmniejsz spord pierwotnych wartoci komrek tab1[i], tab2[i] oraz tab3[i]. Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz n-elementow tablic tab o elementach typu int i:

19

??.7

??.8

??.9

??.10

20 a) b) c) d) e)

4. Tablice jednowymiarowe (r,!) zwraca najwiksz warto przechowywan w tablicy tab, zwraca najmniejsz warto przechowywan w tablicy tab, (r,!) zwraca indeks elementu tablicy tab o najwikszej wartoci, zwraca indeks elementu tablicy tab o najmniejszej wartoci, zwraca najwiksz spord wartoci bezwzgldnych elementw przechowywanych w tablicy tab, f) zwraca indeks elementu tablicy tab o najwikszej wartoci bezwzgldnej. Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz dwie n-elementowe tablice tab o elementach typu double przechowujce n-wymiarowe wektory i zwraca jako warto iloczyn skalarny wektorw otrzymanych w argumentach. Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz n-elementow tablic tab o elementach typu int i: a) (r) odwraca kolejno elementw tablicy tab. b) (r) przesuwa o jeden w lewo wszystkie elementy tablicy (tak, eby warto elementu o indeksie n 1 znalaza si w elemencie o indeksie n 2, warto elementu o indeksie n 2 znalaza si w elemencie o indeksie n 3, za warto elementu o indeksie 0 w elemencie o indeksie n 1), c) (r,!) przesuwa o jeden w prawo wszystkie elementy tablicy (tak, eby warto elementu o indeksie 0 znalaza si w elemencie o indeksie 1, warto elementu o indeksie 1 znalaza si w elemencie o indeksie 2, za warto elementu o indeksie n 1 w elemencie o indeksie 0), d) (*,r,!) sortuje rosnco elementy tablicy tab (porzdkuje elementy przechowywane w tablicy w taki sposb aby cig tab[0], tab[1],. . . ,tab[n-1] by cigiem niemalejcym), e) sortuje malejco elementy tablicy tab. (*,r,!) Napisz funkcj, ktra otrzymuje jako argument dodatni liczb cakowit n, a nastpnie tworzy dynamiczn n-elementow tablic o elementach typu int i zwraca jako warto wskanik do jej pierwszego elementu. (*) Napisz funkcj, ktra otrzymuje jako argument dodatni liczb cakowit n, a nastpnie tworzy dynamiczn n-elementow tablic o elementach typu double i zwraca jako warto wskanik do jej pierwszego elementu. (*,r,!) Napisz funkcj, ktra dostaje jako argument wskanik do jednowymiarowej dynamicznej tablicy o elementach typu int i zwalnia pami zajmowan przez przekazan w argumencie tablic. (*) Napisz funkcj, ktra dostaje jako argument wskanik do jedno-

??.11

??.12

??.13

??.14

??.15

??.16

4.2. Zadania wymiarowej dynamicznej tablicy o elementach typu double i zwalnia pami zajmowan przez przekazan w argumencie tablic. ??.17 (*) Napisz funkcj, ktra otrzymuje dwa argumenty: dodatni liczb cakowit n oraz n-elementow tablic tab o elementach typu double a nastpnie tworzy kopi tablicy tab i zwraca jako warto wskanik do nowo utworzonej kopii. ??.18 (*) Napisz funkcj, ktra otrzymuje trzy argumenty: dodatni liczb cakowit n oraz dwie tablice n-elementowe o elementach typu int przechowujce wsprzdne wektorw i zwraca jako warto wskanik do pierwszego elementu nowo utworzonej tablicy przechowujcej sum wektorw otrzymanych w argumentach. ??.19 (*) Napisz funkcj, ktra dostaje w argumentach dodatni liczb cakowit n oraz n-elementow tablic liczb cakowitych tab1 o elementach typu int i przepisuje do nowo utworzonej tablicy tab2 elementy tablicy tab1 o wartoci rnej od zera. Rozmiar tablicy tab2 powinien by rwny liczbie niezerowych elementw tablicy tab1. Jako warto funkcja powinna zwrci wskanik na pierwszy element tablicy tab2.

21

Rozdzia 5
Napisy

5.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 5.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . .

24 25

24

5. Napisy

5.1. Wprowadzenie
Operacje na napisach, nazywanych te acuchami lub z jzyka angielskiego stringami, to jedna z najsabszych stron jzyka C. Operacje te wymagaj od programisty szczeglnej ostronoci. Z tego powodu, pomimo i napisy s zwykymi tablicami jednowymiarowymi o elementach typw znakowych, to powicamy im oddzielny rozdzia. W jzyku C++ mona uywa napisw takich jak w C, jednak w C++ istniej specjalne klasy suce do ich przechowywania: string i wstring. Klasy te s znacznie wygodniejsze w uyciu od tablic znakw. Na pocztku podrozdziau ?? s zadania, ktre naley rozwiza bez uywania funkcji bibliotecznych. T cz uczcy si jzyka C++ mog pomin, mog j te potraktowa jako wiczenia z operacji na tablicach jednowymiarowych. W drugiej czci podrozdziau ?? s zadania, w ktrych mona uywa funkcji bibliotecznych. Znajduj si tam take zadania, przeznaczone specjalnie dla uczcych si C++, w ktrych naley uy typw string i wstring. Napisy w jzyku C s przechowywane w jednowymiarowych tablicach o elementach typw znakowych. W jzyku C s dwa podstawowe typy znakowe char i wchar_t oraz modykacje typu char: unsigned char i signed char. Standard jzyka C nie okrela dugoci zmiennych o typach char i wchar_t. Typ char jest okrelony jako typ wystarczajcy do przechowywania podstawowego zestawu znakw na danym komputerze (w praktyce char jest typem jednobajtowym), za typ wchart_t powinien wystarczy do przechowywania penego zestawu znakw dostpnego na danym komputerze. Na kocu poprawnego napisu w jzyku C (niezalenie od typu znakw z ktrych si skada) znajduje si znak o kodzie 0. Suy on do zaznaczenia koca napisu. Tablica przechowujca n-znakowy napis musi mie co najmniej n + 1 elementw (moe mie wicej), aby mc przechowa koczcy napis znak o kodzie 0. Konieczno dbania o to, eby na kocu napisu zawsze by znak o kodzie 0, jest jedn z dwch gwnych niedogodnoci przy operowaniu na napisach w jzyku C. Operacje na napisach o elementach typu char mona znale w bibliotece string, za niektre operacje na znakach tego typu take w bibliotece ctype. Typ wchar_t oraz funkcje operujce na zmiennych tego typu, odpowiadajce operacjom z innych bibliotek standardowych (w tym z biblioteki string) znajduj si w bibliotece wchar. Odpowiedniki funkcji z bibliotek ctype operujce na typie wchar_t znajduj si w bibliotece wctype. Opisy funkcji z powyszych bibliotek czytelnik znajdzie w literaturze. Funkcje z bibliotek standardowych wymagaj dbania o to, eby uywane tablice znakw

5.2. Zadania byy wystarczajcych rozmiarw. Jest to druga ze wspomnianych wczeniej dwch najwaniejszych niedogodnoci przy operowaniu na napisach w jzyku C. W jzyku C++ do przechowywania napisw su klasy string i wstring. Jedyn rnic pomidzy tymi klasami jest typ znakw, z ktrych skadaj si napisy. W obiektach klasy string znaki s typu char, natomiast napisy przechowywane w obiektach klasy wstring skadaj si ze znakw typu wchart_t. Klasy string i wstring s zdeniowane w bibliotece string jzyka C++. Uwaga! Biblioteka string jzyka C++ i biblioteka o tej samej nazwie z jzyka C to dwie rne biblioteki. Biblioteka string jzyka C jest dostpna w jzyku C++ pod nazw cstring. Uywanie klas string i wstring znacznie uatwia operowanie na napisach. W szczeglnoci operowanie na tych klasach uwalnia nas od wspomnianych wczeniej dwch gwnych mankamentw operacji na napisach w jzyku C, czyli koniecznoci dbania o obecno znaku o kodzie 0 na kocu napisu i o odpowiedni rozmiar uywanych tablic. Napisy przechowywane w obiektach klas string i wstring mog zawiera znaki o kodzie 0 jako normalne znaki w napisie, za metody zdeniowane dla tych klas dbaj za nas o przydzia pamici dla przechowywanych napisw. O rnicy w atwoci operowania na rnych rodzajach napisw mona si przekona analizujc rozwizania zada z nastpnego podrozdziau. Opis klas string i wstring czytelnik znajdzie w literaturze.

25

5.2. Zadania
Nastpujce zadania rozwi nie uywajc funkcji bibliotecznych: ??.1 (r) Napisz funkcj wyczysc, ktra usuwa z tablicy przechowywany w niej napis (w sensie: umieszcza w niej poprawny napis o dugoci 0). Napisz dwie wersje funkcji wyczysc dla napisw skadajcych si ze znakw typu char i wchar_t. ??.2 (r) Napisz funkcj dlugosc, ktra jako argument otrzymuje napis i zwraca jako warto jego dugo. Napisz dwie wersje funkcji dlugosc dla napisw skadajcych si ze znakw typu char i wchar_t. ??.3 Napisz funkcj porownaj, ktra jako argumenty otrzymuje dwa napisy i zwraca 1 gdy napisy s rwne i 0 w przeciwnym przypadku. Napisz dwie wersje funkcji porownaj dla napisw skadajcych si ze znakw typu char i wchar_t. ??.4 (r,!) Napisz funkcj, ktra jako argumenty otrzymuje dwa napisy i zwraca warto 1, gdy pierwszy napis jest wczeniejszy w kolejnoci leksykogracznej i 0 w przeciwnym przypadku.

26

5. Napisy Zakadamy, e oba napisy skadaj si ze znakw typu char, zawieraj wycznie mae litery alfabetu aciskiego, a system, na ktrym jest kompilowany i uruchamiany program, uywa standardowego kodowania ASCII. Napisz funkcj przepisz, ktra otrzymuje dwie tablice znakw i przepisuje napis znajdujcy si w pierwszej tablicy do drugiej tablicy. Zakadamy, e w drugiej tablicy jest wystarczajco duo miejsca. Napisz dwie wersje funkcji przepisz dla napisw skadajcych si ze znakw typu char i wchar_t. Napisz funkcj kopiujn, ktra dostaje w argumentach dwie tablice znakw nap1, nap2 oraz liczb n i przekopiowuje n pierwszych znakw z napisu przechowywanego w tablicy nap1 do tablicy nap2. W przypadku gdy napis w tablicy nap1 jest krtszy ni n znakw, funkcja powinna po prostu przepisa cay napis. Funkcja powinna zadba o to, eby na kocu napisu w tablicy nap2 znalaz si znak o kodzie 0. Zakadamy, e w docelowej tablicy jest wystarczajco duo miejsca. Napisz dwie wersje funkcji: dla napisw skadajcych si ze znakw typu char i wchar_t. (r) Napisz funkcj sklej otrzymujc jako argumenty trzy tablice znakw i zapisujc do trzeciej tablicy konkatenacj napisw znajdujcych si w dwch pierwszych tablicach (czyli dla napisw Ala m i a kota znajdujcych si w pierwszych dwch argumentach do trzeciej tablicy powinien zosta zapisany napis Ala ma kota). Zakadamy, e w trzeciej tablicy jest wystarczajco duo miejsca. Napisz dwie wersje funkcji sklej dla napisw skadajcych si ze znakw typu char i wchar_t. (r,!) Napisz funkcj, ktra otrzymuje w argumencie napis i podmienia w nim wszystkie mae litery na due litery. Zakadamy, e napis przechowywany jest w tablicy o elementach typu char, skada si wycznie z liter aciskich i biaych znakw, oraz e system ,na ktrym jest kompilowany i uruchamiany program, uywa standardowego kodowania ASCII. (r) Napisz funkcj wytnij, ktra dostaje jako argumenty napis oraz dwie liczby cakowite n i m, i wycina z otrzymanego napisu znaki o indeksach od n do m ( n m). Otrzymany w argumencie napis moe mie dowoln liczb znakw (w tym mniejsz od n lub m) Napisz dwie wersje funkcji wytnij dla napisw skadajcych si ze znakw typu char i wchar_t. (*,r) Napisz funkcj wytnij2, ktra dostaje jako argument dwa napisy nap1 i nap2, i wycina z napisu nap1 pierwsze wystpienie w nim napisu nap2. Napisz dwie wersje funkcji wytnij2 dla napisw skadajcych si ze znakw typu char i wchar_t.

??.5

??.6

??.7

??.8

??.9

??.10

5.2. Zadania ??.11 (*,r) Napisz funkcj wytnijzw, ktra dostaje jako argument dwa napisy nap1 i nap2, i wycina z napisu nap1 wszystkie znaki wystpujce take w napisie nap2. Napisz dwie wersje funkcji wytnijz dla napisw skadajcych si ze znakw typu char i wchar_t. ??.12 (*) Napisz funkcj wytnijzn, ktra dostaje jako argument dwa napisy nap1 i nap2, i wycina z napisu nap1 wszystkie znaki niewystpujce w napisie nap2. Napisz dwie wersje funkcji wytnijzn dla napisw skadajcych si ze znakw typu char i wchar_t. ??.13 (*,r) Napisz funkcj wytnijtm, ktra dostaje jako argument dwa napisy nap1 i nap2 o rwnej dugoci i wycina z napisu nap1 znaki rwne znakom wystpujcym na tym samym miejscu w napisie nap2 (znak o indeksie i usuwamy wtedy i tylko wtedy, gdy nap1[i]=nap2[i]). Napisz dwie wersje funkcji wytnijtm dla napisw skadajcych si ze znakw typu char i wchar_t. Dalsze zadania rozwi z uyciem funkcji bibliotecznych: ??.14 (r) Napisz funkcj, ktra wypisuje na standardowym wyjciu otrzymany w argumencie napis. Napisz dwie wersje funkcji: dla napisw skadajcych si ze znakw typu char i wchar_t. ??.15 (C++,r) Napisz funkcj, ktra wypisuje na standardowym wyjciu otrzymany w argumencie napis. Napisz dwie wersje funkcji: dla napisw typu string i wstring. ??.16 (r,!) Napisz funkcj, ktra dostaje jako argument tablic znakw i wczytuje do niej napis ze standardowego wejcia. Napisz dwie wersje funkcji: dla tablicy skadajcych si ze znakw typu char i wchar_t. ??.17 (C++,r) Napisz funkcj, ktra dostaje w argumentach referencj do zmiennej typu string i wczytuje do niej napis ze standardowego wejcia. Napisz drug wersj funkcji dla napisu typu wstring. ??.18 (*,r) Napisz funkcj, ktra otrzymuje w argumencie tablic napisw (tablic tablic a wic typ char** lub wchar_t**) oraz jej rozmiar i zwraca jako warto pierwszy leksykogracznie spord przechowywanych w tablicy napisw (funkcja powinna zwrci kopi znajdujcego si w tablicy napisu). Zakadamy, e napisy zawieraj wycznie mae litery aciskie. Napisz dwie wersje funkcji: dla napisw skadajcych si ze znakw typu char i wchar_t. ??.19 (C++,r,!) Napisz funkcj, ktra otrzymuje w argumencie tablic napisw (tablic o elementach typu string lub wstring) oraz jej rozmiar i zwraca jako warto pierwszy leksykogracznie spord przechowywanych w tablicy napisw (funkcja powinna zwrci kopi znajdujcego si w tablicy napisu).

27

28

5. Napisy Zakadamy, e napisy zawieraj wycznie mae litery aciskie. Napisz dwie wersje funkcji: dla napisw typu string i wstring. (r) Napisz funkcj godzina, ktra dostaje w argumentach trzy liczby cakowite godz, min i sek, zawierajce odpowiednio godziny, minuty oraz sekundy, i zwraca jako warto napis zawierajcy godzin w formacie godz:min:sek, w ktrym wartoci poszczeglnych pl pochodz ze zmiennych podanych w argumentach. Napisz dwie wersje funkcji godzina: zwracajce napisy bdce tablicami znakw typu char i typu wchar_t. (C++,r) Napisz funkcj godzina, ktra dostaje w argumentach trzy liczby cakowite godz, min i sek, zawierajce odpowiednio godziny, minuty oraz sekundy, i zwraca jako warto napis zawierajcy godzin w formacie godz:min:sek, w ktrym wartoci poszczeglnych pl pochodz ze zmiennych podanych w argumentach . Napisz dwie wersje funkcji godzina: zwracajce napisy typu string i typu wstring. (r) Napisz funkcj sklej, ktra dostaje w argumentach trzy napisy i zwraca jako warto napis powstay ze sklejenia napisw otrzymanych w argumentach. Napisz dwie wersje funkcji sklej operujce na napisach skadajcych si ze znakw typu char i typu wchar_t. (C++,r,!) Napisz funkcj sklej, ktra dostaje w argumentach trzy napisy i zwraca jako warto napis powstay ze sklejenia napisw otrzymanych w argumentach. Napisz dwie wersje funkcji sklej operujce na napisach typu string i typu wstring. Napisz funkcj kopiuj, ktra dostaje jako argumenty napis oraz tablic znakw i przepisuje napis do otrzymanej w argumencie tablicy znakw. Napisz dwie wersje funkcji kopiuj operujce na napisach skadajcych si ze znakw typu char i typu wchar_t. Napisz funkcj kopiuj, ktra dostaje jako argumenty napis oraz wskanik do napisu (czyli wskanik do wskanika), tworzy now tablic znakw, kopiuje do niej napis zawarty w pierwszym argumencie, i przypisuje wskanik do nowo utworzonej tablicy do zmiennej wskazywanej przez drugi argument. Napisz dwie wersje funkcji kopiuj operujce na napisach skadajcych si ze znakw typu char i typu wchar_t. (r) Napisz funkcj, ktra dostaje w argumencie napis i zamienia wszystkie wystpujce w nim mae litery na odpowiadajce im due litery. Napisz dwie wersje funkcji operujce na napisach skadajcych si ze znakw typu char i typu wchar_t. (C++,r) Napisz funkcj, ktra dostaje w argumencie referencj do na-

??.20

??.21

??.22

??.23

??.24

??.25

??.26

??.27

5.2. Zadania pisu i zamienia wszystkie wystpujce w nim mae litery na odpowiadajce im due litery. Napisz dwie wersje funkcji operujce na napisach typw string i wstring.

29

Rozdzia 6
Tablice wielowymiarowe

6.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 6.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . .

32 32

32

6. Tablice wielowymiarowe

6.1. Wprowadzenie
W jzykach C i C++ s dwa rodzaje tablic dwuwymiarowych. Jeden rodzaj to tablice ktrych elementami s tablice jednowymiarowe za drugi to tablice wskanikw do tablic jednowymiarowych. Analogicznie moemy stworzy w C i C++ cztery rodzaje tablic trjwymiarowych rnice si sposobem utworzenia poszczeglnych wymiarw. Nie istnieje ustalone polskie nazewnictwo rozrniajce rne rodzaje dynamicznych tablic wielowymiarowych w C i C++. W niniejszym zbiorze na okrelenie dwch gwnych typw tablic wielowymiarowych uywa si okrele tablice tablic (na przykad dla typw int** czy int **) i tablice wielowymiarowe (na przykad dla typw int[][n] lub int[][n][m]). W jzyk C++ nie ma moliwoci uywania wielowymiarowych tablic o wymiarach nieznanych w czasie kompilacji. W zwizku z tym wiele zada w podrozdziale ?? przeznaczonych jest tylko dla uczcych si jzyka C. Powyszy problem nie dotyczy wielowymiarowych tablic tablic.

6.2. Zadania
??.1 (r,!) Napisz funkcj, ktra dostaje jako argument dodatnie liczby cakowite n i m, tworzy dynamiczn dwuwymiarow tablic tablic elementw typu int o wymiarach n na m, i zwraca jako warto wskanik do niej. ??.2 (C,r,!) Napisz funkcj, ktra dostaje jako argument dodatnie liczby cakowite n i m, tworzy dynamiczn dwuwymiarow tablic elementw typu int o wymiarach n na m i zwraca jako warto wskanik do niej. ??.3 (r,!) Napisz funkcj, ktra dostaje jako argumenty wskanik do dwuwymiarowej tablicy tablic elementw typu int oraz jej wymiary: dodatnie liczby cakowite n i m, i usuwa z pamici otrzyman tablic. ??.4 (C,r) Napisz funkcj, ktra dostaje jako argumenty wskanik do tablicy dwuwymiarowej elementw typu int oraz jej wymiary wymiary n i m, i usuwa z pamici otrzyman tablic. ??.5 Rozwi zadania ??.?? i ??.?? w wersji z trjwymiarowymi tablicami tablic. ??.6 (C) Rozwi zadania ??.?? i ??.?? w wersji z tablicami trjwymiarowymi. ??.7 (r) Napisz funkcj, ktra dostaje jako argument dodatni liczb cakowit n, tworzy dynamiczn dwuwymiarow trjktn tablic tablic elementw typu int o wymiarach n na n i zwraca jako warto wskanik do niej.

6.2. Zadania ??.8 (r) Napisz funkcj, ktra dostaje w argumentach dwuwymiarow tablic elementw typu int, o pierwszym wymiarze podanym jako drugi argument funkcji oraz drugim wymiarze rwnym 100 i wypenia j zerami. ??.9 (r) Napisz funkcj, ktra dostaje w argumentach dwuwymiarow tablic tablic elementw typu int oraz jej wymiary n i m, i wypenia j zerami. ??.10 (C,r) Napisz funkcj, ktra dostaje w argumentach tablic dwuwymiarow elementw typu int oraz jej wymiary n i m, i wypenia j zerami. ??.11 Napisz funkcj, ktra dostaje w argumentach tablic dwuwymiarow elementw typu int, o pierwszym wymiarze podanym jako drugi argument funkcji oraz drugim wymiarze rwnym 100, ktra to funkcja zwraca jako warto sum wartoci elementw tablicy. ??.12 Napisz funkcj, ktra dostaje w argumentach dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary n i m, i zwraca jako warto sum wartoci elementw tablicy. ??.13 (C) Napisz funkcj, ktra dostaje w argumentach tablic dwuwymiarow o elementach typu int oraz jej wymiary n i m, i zwraca jako warto sum wartoci elementw tablicy. ??.14 (r) Napisz funkcj, ktra dostaje w argumentach tablic trjwymiarow o elementach typu int o wymiarach 100 100 100, i zwraca jako warto sum wartoci elementw tablicy. ??.15 Napisz funkcj, ktra dostaje w argumentach dodatni liczb cakowit n oraz tablic trjwymiarow o elementach typu int o wymiarach n 100 100, i zwraca jako warto sum wartoci elementw otrzymanej tablicy. ??.16 (r) Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary, i zwraca jako warto indeks wiersza o najwikszej redniej wartoci elementw. Przyjmujemy, e dwa elementy le w tym samym wierszu, jeeli maj taki sam pierwszy indeks. ??.17 (r) Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary, i zwraca najwiksz spord rednich wartoci elementw poszczeglnych wierszy. Przyjmujemy, e dwa elementy le w tym samym wierszu, jeeli maj taki sam pierwszy indeks. ??.18 Napisz funkcj, ktra dostaje jako argument dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary, i wypisuje jej zawarto na standardowym wyjciu w taki sposb, eby kolejne wiersze tablicy zostay wypisane w oddzielnych wierszach standardowego wyjcia.

33

34

6. Tablice wielowymiarowe Przyjmujemy, e dwa elementy le w tym samym wierszu, jeeli maj taki sam drugi indeks. (r) Napisz funkcj, ktra dostaje jako argumenty dwie dwuwymiarowe tablice tablic o elementach typu int oraz ich wymiary, i przepisuje zawarto pierwszej tablicy do drugiej tablicy. Napisz funkcj, ktra dostaje jako argumenty dwie dwuwymiarowe tablice tablic o elementach typu int oraz ich wymiary, i zamienia zawartoci obu tablic. (r) Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary, i odwraca kolejno elementw we wszystkich wierszach otrzymanej tablicy (przyjmujemy, e dwa elementy tablicy le w tym samym wierszu, jeeli maj tak sam pierwsz wsprzdn). (C, r) Napisz funkcj, ktra dostaje jako argumenty tablic dwuwymiarow o elementach typu int oraz jej wymiary, i odwraca kolejno elementw we wszystkich wierszach otrzymanej tablicy (przyjmujemy, e dwa elementy tablicy le w tym samym wierszu, jeeli maj tak sam pierwsz wsprzdn). (r,!) Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary, i zmienia kolejno wierszy w tablicy w taki sposb, e wiersz pierwszy ma si znale na miejscu drugiego, wiersz drugi ma si znale na miejscu trzeciego itd., natomiast ostatni wiersz ma si znale na miejscu pierwszego (przyjmujemy, e dwa elementy tablicy le w tym samym wierszu jeeli maj tak sam pierwsz wsprzdn). Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow tablic tablic o elementach typu int oraz jej wymiary, i zmienia kolejno kolumn w tablicy w taki sposb, e kolumna pierwsza ma si znale na miejscu drugiej, kolumna druga ma si znale na miejscu trzeciej itd., natomiast ostatnia kolumna ma si znale na miejscu pierwszej (przyjmujemy, e dwa elementy tablicy le w tej samej kolumnie, jeeli maj tak sam drug wsprzdn). Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow kwadratow tablic tablic tab o elementach typu int oraz jej wymiar, i zmienia kolejno elementw w otrzymanej tablicy w nastpujcy sposb: dla dowolnych k i j element tab[k][j] ma zosta zamieniony miejscami z elementem tab[j][k]. Napisz funkcj, ktra dostaje jako argumenty dwuwymiarow prostoktn tablic tablic tab1 o wymiarach n m i elementach typu int oraz jej wymiary, i zwraca jako warto wskanik do nowo utworzonej dwuwymiarowej tablicy tablic tab2 o wymiarach m n zawierajcej

??.19

??.20

??.21

??.22

??.23

??.24

??.25

??.26

6.2. Zadania transponowan macierz przechowywan w tablicy tab1 (czyli dla dowolnych k i j zachodzi tab1[k][j]=tab2[j][k]. (*,r) Napisz funkcj, ktra dostaje jako argumenty dodatni liczb cakowit n oraz trjwymiarow tablic tablic tab elementw typu int o wymiarach n n n, i zamienia elementy tablicy w taki sposb, e dla dowolnych i, j, k z zakresu od 0 do n 1, warto z komrki tab[i][j][k] po wykonaniu funkcji ma si znajdowa w komrce tab[k][i][j]. (C,*) Napisz funkcj, ktra dostaje jako argumenty dodatni liczb cakowit n oraz trjwymiarow tablic tab elementw typu int o wymiarach n n n, i zamienia elementy tablicy w taki sposb, e dla dowolnych i, j, k z zakresu od 0 do n 1, takich e i j k, warto z komrki tab[i][j][k] po wykonaniu funkcji ma si znajdowa w komrce tab[k][i][j]. (*) Napisz funkcj, ktra dostaje jako argument trjwymiarow tablic tab elementw typu int o wymiarach 100 100 100, i zamienia elementy tablicy w taki sposb, e dla dowolnych i, j, k z zakresu od 0 do 99, takich e i j k, warto z komrki tab[i][j][k] po wykonaniu funkcji ma si znajdowa w komrce tab[k][i][j]. Napisz funkcj, ktra otrzymuje w argumentach dwie kwadratowe tablice tablic elementw typu int oraz ich wsplny wymiar, i zwraca jako warto wynik dodawania macierzy przechowywanych w przekazanych argumentach. Wynik powinien zosta zwrcony w nowo utworzonej tablicy tablic. (C) Napisz funkcj, ktra otrzymuje w argumentach dwie kwadratowe tablice dwuwymiarowe elementw typu int oraz ich wsplny wymiar, i zwraca jako warto wynik dodawania macierzy przechowywanych w przekazanych argumentach. Wynik powinien zosta zwrcony w nowo utworzonej tablicy dwuwymiarowej. (*,r) Napisz funkcj, ktra otrzymuje w argumentach dwie kwadratowe tablice tablic elementw typu int oraz ich wsplny wymiar, i zwraca jako warto wynik mnoenia macierzy przechowywanych w przekazanych argumentach. Wynik powinien zosta zwrcony w nowo utworzonej tablicy tablic. Napisz funkcj, ktra otrzymuje w argumentach trzy kwadratowe tablice tablic elementw typu int oraz ich wsplny wymiar, i zapisuje do trzeciej tablicy wynik mnoenia macierzy przechowywanych w dwch pierwszych tablicach. (C,*) Napisz funkcj, ktra otrzymuje w argumentach dwie kwadratowe tablice dwuwymiarowe elementw typu int oraz ich wsplny wymiar, i zwraca jako warto wynik mnoenia macierzy przechowywa-

35

??.27

??.28

??.29

??.30

??.31

??.32

??.33

??.34

36

6. Tablice wielowymiarowe nych w przekazanych argumentach. Wynik powinien zosta zwrcony w nowo utworzonej tablicy dwuwymiarowej. ??.35 (*) Napisz funkcj, ktra otrzymuje w argumentach dwie prostoktne dwuwymiarowe tablice tablic elementw typu int o wymiarach odpowiednio n m i m k oraz ich wymiary, i zwraca jako warto wynik mnoenia macierzy przechowywanych w przekazanych argumentach. Wynik powinien zosta zwrcony w nowo utworzonej tablicy tablic. ??.36 (*,r,!) Napisz funkcj otrzymujc dwa argumenty: dodatni liczb cakowit n i dwuwymiarow kwadratow tablic tablic elementw typu int o wymiarach n n, i zwraca jako warto wyznacznik macierzy przechowywanej w otrzymanej w argumencie tablicy. ??.37 (C,*,r,!) Napisz funkcj otrzymujc dwa argumenty: dodatni liczb cakowit n i kwadratow tablic dwuwymiarow elementw typu int o wymiarach n n, i zwraca jako warto wyznacznik macierzy przechowywanej w otrzymanej w argumencie tablicy.

Rozdzia 7
Zoone typy danych, listy wskanikowe

7.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 7.2. Zoone typy danych . . . . . . . . . . . . . . . . . . . 7.3. Listy jednokierunkowe . . . . . . . . . . . . . . . . . . .

38 38 41

38

7. Zoone typy danych, listy wskanikowe

7.1. Wprowadzenie
W tym rozdziale czytelnik znajdzie zadania zwizane ze zoonymi typami danych dostpnymi w C, a wic: strukturami, uniami i typami wyliczeniowymi. Duy nacisk zosta pooony na zadania dotyczce list wskanikowych, jednego z popularnych zastosowa struktur. Zadania dotyczce list wskanikowych to okazja do przewiczenia operacji na wskanikach oraz zarzdzania pamici. Istnieje wiele rodzajw list wskanikowych. Jednak ze wzgldu na to, e nie jest to zbir zada ze struktur danych, w zadaniach pojawiaj si wycznie listy jednokierunkowe. Zadania dotycz zarwno list bez gowy, czyli takich, w ktrych na pocztku listy znajduje si jej pierwszy element, jak i list z gow, czyli takich, w ktrych na pocztku listy znajduje si sztuczny element nazywany gow. Dziki dodaniu do listy gowy wiele operacji si upraszcza. W jzyku C++ struktury to prawie to samo, co klasy. Rni si tylko tym, e w przeciwiestwie do klas, pola i metody w strukturach s domylnie publiczne. W tym rozdziale traktujemy jednak struktury wycznie jako tradycyjne zoone typy danych, tak jak jest to w jzyku C. W podrozdziale ?? czytelnik znajdzie zadania majce na celu przewiczenie deniowania zoonych typw danych oraz wykonywania prostych operacji na nich. W podrozdziale ?? znajduje si urozmaicony zestaw zada, umoliwiajcy przewiczenie uywania list jednokierunkowych z gow i bez gowy. Na pocztku tego rozdziau znajduj si zadania wymagajce implementacji podstawowych operacji na listach. Ze wzgldu na problemy, jakie operowanie na listach sprawia pocztkujcym programistom, wszystkie zadania z tej czci podrozdziau ?? zostay rozwizane.

7.2. Zoone typy danych


??.1 (r,r) Zdeniuj struktur trojkat przechowujc dugoci bokw trjkta. Napisz funkcj, ktra otrzymuje jako argument zmienn typu struct trojkat, i zwraca jako warto obwd trjkta przekazanego w argumencie. ??.2 (r,!) Napisz funkcj, ktra otrzymuje jako argumenty zmienn troj1 typu struct trojkat zdeniowanego w zadaniu ??.?? oraz zmienn troj2 wskanik na zmienn typu struct trojkat, i przepisuje zawarto zmiennej troj1 do zmiennej wskazywanej przez troj2. ??.3 (r) Zdeniuj struktur punkt suc do przechowywania wsprzdnych punktw w trjwymiarowej przestrzeni kartezjaskiej.

7.2. Zoone typy danych Napisz funkcj, ktra otrzymuje jako argumenty tablic tab o argumentach typu struct punkt oraz jej rozmiar, i zwraca jako warto najmniejsz spord odlegoci pomidzy punktami przechowywanymi w tablicy tab. Zakadamy, e otrzymana w argumencie tablica ma co najmniej dwa argumenty. ??.4 (r,!) Napisz funkcj, ktra otrzymuje jako argumenty tablice tab1 i tab2 o argumentach typu struct punkt zdeniowanego w rozwizaniu zadania ??.?? oraz ich rozmiar, i przepisuje zwarto tablicy tab1 do tablicy tab2. ??.5 (r,!) Zdeniuj struktur punkt10 suc do przechowywania wsprzdnych punktw w dziesiciowymiarowej przestrzeni kartezjaskiej. Do przechowywania poszczeglnych wymiarw wykorzystaj tablic dziesicioelementow. Napisz funkcj, ktra otrzymuje jako argumenty tablice tab1 i tab2 typu struct punkt10 oraz ich wsplny rozmiar, i przepisuje zwarto tablicy tab1 do tablicy tab2. ??.6 (r,!) Zdeniuj struktur punktn suc do przechowywania wsprzdnych punktw w n-wymiarowej przestrzeni kartezjaskiej. Do przechowywania poszczeglnych wymiarw wykorzystaj tablic n-elementow. W strukturze punktn przechowuj take ilo wymiarw przestrzeni. Napisz funkcj, ktra otrzymuje jako argumenty tablice tab1 i tab2 o argumentach typu struct punktn oraz ich wsplny rozmiar, i przepisuje zwarto tablicy tab1 do tablicy tab2. Zakadamy, e tablica tab2 jest pusta (czyli nie musimy si martwi o jej poprzedni zawarto). ??.7 Zdeniuj struktur zespolone suc do przechowywania liczb zespolonych. Zdeniowana struktura powinna zawiera pola im i re typu double suce do przechowywania odpowiednio czci urojonej i rzeczywistej liczby zespolonej. Napisz funkcj dodaj, ktra dostaje dwa argumenty typu zespolone i zwraca jako warto ich sum. ??.8 Zdeniuj struktur student suc do przechowywania danych osobowych studenta (struktura powinna zawiera takie pola, jak: imie, nazwisko, adres, pesel, kierunek i numer legitymacji). Napisz funkcj, ktra otrzymuje jako argument wskanik na struktur student i wczytuje dane ze standardowego wejcia do rekordu wskazywanego przez argument funkcji. ??.9 (r) Zdeniuj struktur lista posiadajc dwa pola: jedno typu int oraz oraz drugie bdce wskanikiem do deniowanego typu.

39

40

7. Zoone typy danych, listy wskanikowe ??.10 (r) Zdeniuj uni super_int, w ktrej bdzie mona przechowywa zarwno zmienne typu int, jak i unsigned int. ??.11 (r) Zdeniuj uni Liczba, ktra moe suy w zalenoci od potrzeb do przechowywania liczby wymiernej lub liczby cakowitej. Zdeniuj struktur Dane, o dwch polach polu tp typu int oraz polu zaw typu Liczba. Napisz bezargumentow funkcj, ktra wczytuje ze standardowego wejcia zawarto do struktury Dane i zwraca j jako warto. Funkcja powinna pyta uytkownika, czy chce wczyta liczb cakowit, czy wymiern oraz w zalenoci od jego wyboru wstawi do pola tp warto 0 lub 1. Nastpnie funkcja powinna wczyta do pola zaw warto odpowiedniego typu. ??.12 (*) Zdeniuj struktur zespolone, ktra ma suy do przechowywania liczb zespolonych oraz uni Liczba mogc przechowywa liczby wymierne i cakowite. Czci urojona i rzeczywista liczby zespolonej powinny by przechowywane w polach im i re typu Liczba. Struktura zespolone powinna mie dodatkowe pole tp przechowujce informacj jakiego typu wartoci przechowywane s w polach im i re (zakadamy, e oba s tego samego typu). Napisz funkcj dodaj, ktra dostaje dwa argumenty typu zespolone i zwraca jako warto ich sum. Zwr uwag na zgodno typw skadnikw i zwracanej wartoci (suma dwch liczb cakowitych jest liczb cakowit, natomiast jeeli ktrykolwiek ze skadnikw jest wymierny to i suma jest wymierna). ??.13 (r) Zdeniuj struktur figura przechowujc wymiary gur geometrycznych niezbdne do obliczenia pola. Struktura powinna mie moliwo przechowywania wymiarw takich gur, jak: trjkt, prostokt, rwnolegobok i trapez. Rodzaj przechowywanej gury powinien by zakodowany w wartoci pola fig typu int. Deniujc struktur, staraj si zuy jak najmniej pamici. Napisz funkcj pole, ktra dostaje jako argument zmienn f typu struct figura i zwraca jako warto pole gury ktrej wymiary przechowuje zmienna f. ??.14 (r) Zdeniuj typ wyliczeniowy czworokat, mogcy przyjmowa wartoci odpowiadajce nazwom rnych czworoktw. ??.15 Zdeniuj typ wyliczeniowy zwierzak, mogcy przyjmowa wartoci odpowiadajce nazwom rnych zwierzt domowych. ??.16 Zdeniuj typ wyliczeniowy, sucy do przechowywania informacji o stanie poczenia internetowego, o trzech wartociach odpowiadajcych trzem stanom: poczenie nawizane, poczenie nienawizane i poczenie w trakcie nawizywania. Nastpnie zdeniuj struktur komputer

7.3. Listy jednokierunkowe przechowujc stan poczenia, IP podczonego komputera (jako napis) oraz nazw jego waciciela. Napisz funkcj, ktra jako argument otrzymuje struktur komputer i wywietla na standardowym wyjciu jej zawarto w sposb przyjazny dla uytkownika. ??.17 (r,!,r) Zdeniuj struktur dane osobowe zawierajc pola: imie, nazwisko, plec, stan_cywilny. W zalenoci od pci pole stan_cywilny powinno mc mie jedn z dwch wartoci wolny lub zonaty dla mczyzn i wolna lub mezatka dla kobiet. Napisz funkcj wczytaj o dwch argumentach: tablicy tab o elementw typu stan_cywilny i jej rozmiarze. Funkcja powinna wczytywa do komrek tablicy tab wartoci podane na standardowym wejciu. ??.18 (r,!) Zdeniuj zoony typ danych dziki ktremu bdzie mona odnosi si do kolejnych bajtw zmiennej typu unsigned int jak do kolejnych elementw tablicy. ??.19 (r) Wykorzystujc typ danych zdeniowany w rozwizaniu zadania ?? napisz funkcj, ktra dostaje w argumentach dwie nieujemne liczby cakowite typu unsigned int i zwraca jako warto nieujemn liczb cakowit, ktrej kolejne bajty s iloczynami modulo 256 odpowiadajcych sobie bajtw liczb podanych w argumentach.

41

7.3. Listy jednokierunkowe


Jednokierunkowe listy bez gowy Listing 7.1. Denicja struktury element
struct e l e m e n t { int i ; struct e l e m e n t nex t ; };

Struktura element moe by wykorzystana w implementacji jednokierunkowej listy wskanikowej. Najpierw zostan przedstawione zadania umoliwiajce przewiczenie operacji na licie jednokierunkowej bez gowy (czyli takiej, ktra jest reprezentowana przez wskanik na pierwszy element ). List pust reprezentuje wskanik o wartoci NULL. Pamitaj, e pole next ostatniego elementu listy powinno mie warto NULL. Dziki temu bdzie moliwe rozpoznanie koca listy. ??.1 (r) Napisz funkcj utworz zwracajc wskanik do pustej listy bez gowy o elementach typu element.

42

7. Zoone typy danych, listy wskanikowe ??.2 (r) Napisz funkcj wyczysc, ktra dostaje jako argument wskanik do pierwszego elementu listy wskanikowej bezgowy o elementach typu element i usuwa wszystkie elementy listy. ??.3 (r) Napisz funkcj dodaj o dwch argumentach Lista typu element* oraz a typu int zwracajc wskanik do typu element. Funkcja powinna dodawa na pocztek listy reprezentowanej przez zmienn Lista nowy element o wartoci a pola i oraz zwraca wskanik do pierwszego elementu tak powikszonej listy. ??.4 (r) Napisz funkcj dodajk o dwch argumentach Lista typu element* i a typu int zwracajc wskanik do typu element. Funkcja powinna dodawa na koniec listy reprezentowanej przez zmienn Lista nowy element o wartoci a pola i oraz zwraca wskanik do pierwszego elementu tak powikszonej listy. ??.5 (r) Napisz funkcj dodajw o trzech argumentach Lista i elem typu element* oraz a typu int zwracajc wskanik do typu element. Funkcja powinna dodawa element o wartoci a pola i do listy reprezentowanej przez zmienn Lista na miejscu tu za elementem wskazywanym przez elem. W przypadku, gdy elem jest rwny NULL funkcja powinna wstawi nowy element na pocztek listy. Funkcja powinna zwrci jako warto wskanik do pierwszego elementu powikszonej listy. ??.6 (r,!) Napisz funkcj znajdz o dwch argumentach Lista typu element* i a typu int zwracajc wskanik do typu element. Funkcja powinna sprawdza, czy na licie reprezentowanej przez zmienn Lista znajduje si element o polu i rwnym a. Jeeli tak, to funkcja powinna zwrci wskanik do tego elementu. W przeciwnym wypadku funkcja powinna zwrci warto NULL. ??.7 (r) Napisz funkcj usun o dwch argumentach Lista typu element* i a typu int zwracajc wskanik do typu element. Funkcja powinna usuwa z listy reprezentowanej przez zmienn Lista element o wartoci a pola i (o ile taki element znajduje si na licie) oraz zwraca wskanik do pierwszego elementu zmodykowanej listy (jeeli po usuniciu elementu lista bdzie pusta, to funkcja powinna zwrci warto NULL). ??.8 (r,!) Napisz funkcj usunw o dwch argumentach Lista i elem typu element* i zwracajc wskanik do typu element. Funkcja powinna usuwa z listy reprezentowanej przez zmienn Lista element wskazywany przez elem oraz zwraca wskanik do pierwszego elementu zmodykowanej listy (jeeli po usuniciu elementu lista bdzie pusta, to funkcja powinna zwrci warto NULL). Dla elem rwnego NULL funkcja usunw nie powinna nic robi. ??.9 (r,!) Napisz funkcj usunw2 o dwch argumentach Lista i elem typu

7.3. Listy jednokierunkowe element* i zwracajc wskanik do typu element. Funkcja powinna usuwa z listy reprezentowanej przez zmienn Lista element wskazywany przez elem->next oraz zwraca wskanik do pierwszego elementu zmodykowanej listy (jeeli po usuniciu elementu lista bdzie pusta, to funkcja powinna zwrci warto NULL). Dla elem rwnego NULL funkcja powinna usun pierwszy element listy (o ile taki istnieje). Dla elem rnego od NULL i elem->next rwnego NULL funkcja usunw2 nie powinna nic robi. Jednokierunkowe listy z gow W zadaniach dotyczcych jednokierunkowych list wskanikowych z gow (czyli takich, na pocztku ktrych znajduje si sztuczny pusty element, nazywany gow) zostanie wykorzystana struktury element zdeniowan w Listingu ?? . Pamitaj, e pole next ostatniego elementu listy powinno mie warto NULL, w ten sposb bdzie moliwe rozpoznanie koca listy. ??.10 (r) Napisz funkcj utworz tworzc pust list z gow o elementach typu element i zwracajc jako warto wskanik do gowy utworzonej listy. ??.11 (r) Napisz funkcj wyczysc, ktra dostaje jako argument wskanik do listy wskanikowej z gow o elementach typu element i usuwa wszystkie elementy listy (razem z gow). ??.12 (r) Napisz funkcj dodaj o dwch argumentach Lista typu element* i a typu int. Funkcja powinna dodawa na pocztek listy reprezentowanej przez zmienn Lista nowy element o wartoci a pola i. ??.13 (r) Napisz funkcj dodajk o dwch argumentach Lista typu element* i a typu int. Funkcja powinna dodawa na koniec listy reprezentowanej przez zmienn Lista nowy element o wartoci a pola i. ??.14 (r) Napisz funkcj dodajw o trzech argumentach Lista oraz elem typu element* i a typu int. Funkcja powinna dodawa element o wartoci a pola i do listy reprezentowanej przez zmienn Lista na miejscu tu za elementem wskazywanym przez elem. ??.15 (r) Napisz funkcj znajdz o dwch argumentach Lista typu element* i a typu int zwracajc wskanik do typu element. Funkcja powinna sprawdza, czy na licie reprezentowanej przez zmienn Lista, znajduje si element o polu i rwnym a. Jeeli tak, to funkcja powinna zwrci wskanik do tego elementu. W przeciwnym wypadku funkcja powinna zwrci warto NULL. ??.16 (r) Napisz funkcj znajdzp o dwch argumentach Lista typu element* i a typu int zwracajc wskanik do typu element. Funkcja powinna sprawdza, czy na licie reprezentowanej przez zmienn Lista, znajduje si element o polu i rwnym a. Jeeli tak, to funkcja powinna

43

44

7. Zoone typy danych, listy wskanikowe zwrci wskanik do elementu go poprzedzajcego. W przeciwnym wypadku funkcja powinna zwrci wskanik do ostatniego elementu listy. ??.17 (r) Napisz funkcj usun o dwch argumentach Lista typu element* i a typu int. Funkcja powinna usuwa z listy reprezentowanej przez zmienn Lista element o wartoci a pola i (o ile taki element znajduje si na licie). ??.18 (r) Napisz funkcj usunw o dwch argumentach Lista i elem typu element*. Funkcja powinna usuwa z listy reprezentowanej przez zmienn Lista element wskazywany przez zmienn elem. ??.19 (r) Napisz funkcj usunw2 o dwch argumentach Lista i elem typu element*. Funkcja powinna usuwa z listy reprezentowanej przez zmienn Lista element wskazywany przez elem->next. Pozostae zadania z list jednokierunkowych ??.20 (r) Napisz funkcj zeruj, ktra dostaje jako argument list wskanikow o elementach typu element i nadaje warto 0 polom i we wszystkich elementach listy. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. ??.21 Napisz funkcj bezwzgldna, ktra dostaje jako argument list wskanikow o elementach typu element i zapisuje do pl i wszystkich elementw listy warto bezwzgldn ich pierwotnej wartoci. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. ??.22 Zdeniuj struktur trojkat mogc suy jako typ elementw listy jednokierunkowej. Struktura trojkat powinna posiada pola suce do przechowywania wszystkich bokw trjkta oraz jego pola. Napisz funkcj pole, ktra otrzymuje w argumencie list wskanikow o elementach typu trojkat i we wszystkich elementach listy do odpowiedniego pola wstawia warto pola trjkta o bokach, ktrych dugo przechowuje dana struktura. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. ??.23 (r) Zdeniuj struktur trojka majc suy jako typ elementu jednokierunkowej listy wskanikowej przechowujcej trjki dodatnich liczb cakowitych a. b, c. Napisz funkcj pitagoras, ktra dostaje w argumencie list wskanikow o elementach typu trojka i usuwa z otrzymanej listy wszystkie elementy nieprzechowujce trjek pitagorejskich (czyli takich, e a2 + b2 = c2 ). Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. W wersji dla list bez gowy funkcja powinna zwraca wskanik do pierwszego elementu przeksztaconej listy. Jeeli wynikowa lista bez gowy bdzie pusta, funkcja powinna zwrci NULL. ??.24 (r) Napisz funkcj suma, ktra dostaje jako argument list wskanikow o elementach typu element i zwraca jako warto sum pl i

7.3. Listy jednokierunkowe ze wszystkich elementw listy. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. (r) Napisz funkcj minimum, ktra dostaje jako argument list wskanikow o elementach typu element i zwraca jako warto najmniejsz spord wartoci pl i elementw listy. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. (r) Napisz funkcj minimum, ktra dostaje jako argument Lista list wskanikow o elementach typu element i zwraca jako warto wskanik do elementu listy o najmniejszej wartoci pola i. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. (r) Napisz funkcj minimum, ktra dostaje jako argument list wskanikow o elementach typu element i zwraca jako warto wskanik do bezporedniego poprzednika elementu listy o najmniejszej wartoci pola i. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. W przypadku listy bez gowy, jeeli najmniejsz warto pola i ma pierwszy element listy lub gdy otrzymana w argumencie lista jest pusta, funkcja minimum powinna zwrci warto NULL. (r) Napisz funkcj, ktra dostaje jako argument list o elementach typu element i zwraca jako warto najwiksz na warto bezwzgldn spord rnic pomidzy polami i w rnych elementach listy otrzymanej w argumencie. Zakadamy, e otrzymana w argumencie funkcji lista jest co najmniej dwuelementowa. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. (r) Napisz funkcj kopiuj, ktra jako argument otrzymuje jednokierunkow list wskanikow o elementach typu element, tworzy kopi otrzymanej w argumencie listy i zwraca jako warto wskanik do kopii. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. (r) Napisz funkcj doklej o dwch argumentach Lista1 i Lista2 typu element * wskazujcych na dwie jednokierunkowe listy wskanikowe bez gowy, ktra wstawia na koniec listy Lista1 elementy listy Lista2 (funkcja nie powinna alokowa w pamici nowych zmiennych typu element, ale odpowiednio podpi ju istniejce). Funkcja powinna zwraca wskanik do pierwszego elementu poczonej listy. (r,!) Napisz funkcj, ktra dostaje w argumentach wskanik do listy wskanikowej o elementach typu element i odwraca kolejno elementw listy. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. W wersji dla list bez gowy funkcja powinna zwraca wskanik do pierwszego elementu odwrconej listy. (r) Napisz funkcj ktra dostaje w argumentach wskaniki do dwch list wskanikowych bez gowy o elementach typu element i rwnej dugoci, tworzy list zoon z elementw obu list uoonych naprzemiennie (pierwszy ma by pierwszy element pierwszej listy, nastp-

45

??.25

??.26

??.27

??.28

??.29

??.30

??.31

??.32

46

7. Zoone typy danych, listy wskanikowe nie pierwszy element drugiej listy, drugie element pierwszej listy itd.) i zwraca jako warto wskanik do pierwszego elementu nowo utworzonej listy. ??.33 (r,!) Napisz funkcj, ktra dostaje jako argument list wskanikow o elementach typu element i przesuwa jej elementy w taki sposb, e pierwszy element bdzie drugi, drugi element bdzie trzeci etc. a na pierwszym miejscu bdzie ostatni element pierwotnej listy. Dla listy o dugoci nie wikszej ni 1 funkcja nie powinna nic robi. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. W wersji dla list bez gowy funkcja powinna zwraca wskanik do pierwszego elementu przeksztaconej listy. ??.34 (r) Napisz funkcj, ktra dostaje jako argumenty dwie listy wskanikowe Lista1 i Lista2 o elementach typu element i tworzy now list o elementach tego samego typu przechowujc wartoci wystpujce w polach i elementw zarwno listy Lista1 jak i Lista2. W stworzonej licie nie powinny powtarza si przechowywane w elementach wartoci. Funkcja powinna zwraca wskanik do nowo utworzonej listy. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. ??.35 (*,r,!) Napisz funkcj sortujc rosnco podan w argumencie list o elementach typu element. Napisz dwie wersje funkcji: dla list z gow i dla list bez gowy. W wersji dla listy bez gowy funkcja powinna zwraca wskanik do pierwszego elementu posortowanej listy.

Rozdzia 8
Operacje na plikach

8.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 8.2. Zadania . . . . . . . . . . . . . . . . . . . . . . . . . . .

48 48

48

8. Operacje na plikach

8.1. Wprowadzenie
W jzykach C i C++ pliki powizane s ze strumieniami i pracuje si na nich podobnie jak na innych strumieniach. W jzyku C do operacji na plikach su funkcje z biblioteki stdio, a wrd nich midzy innymi: fopen, fclose, fwrite, fread, fprintf, fscanf, feof i fseek. W jzyku C++ do operowania na plikach su klasy ifstream, ofstream i fstream znajdujce si w bibliotece fstream. Szczegy czytelnik znajdzie w literaturze. Aby zacz operowa na pliku naley go otworzy, za po zakoczeniu pracy naley plik zamkn. Otwierajc plik naley okreli w jakim celu plik jest otwierany (do czytania, do pisania etc.) oraz czy plik ma by otwarty w trybie binarnym (czyli jako cig bajtw) czy tekstowym. Aby zrozumie rnic pomidzy plikiem binarnym a tekstowym mona zapisa do obu rodzajw plikw jednobajtow bezznakow liczb cakowit o wartoci 100. W pliku binarnym znajdzie si jeden bajt zawierajcy binarnie zapisan liczb 100, natomiast w pliku tekstowym znajd si trzy bajty, z ktrych pierwszy bdzie zawiera kod znaku 1, a dwa kolejne bajty bd zawieray kod znaku 0. Czstym bdem u pocztkujcych programistw C jest niewaciwe uycie funkcji feof. Uywajc jej naley pamita, e ta funkcje zwraca true dopiero wtedy, gdy nie powiedzie si prba czytania. Czyli to, e feof ma warto false, nie oznacza, e w pliku pozostao jeszcze co do przeczytania. Podobny problem dotyczy metody eof klasy fstream. Inn rzecz, o ktrej naley pamita, to fakt, e strumieni w jzyku C++ nie mona kopiowa. Mona przekazywa je co najwyej przez referencj lub wskanik. W treciach zada wielokrotnie pojawia si pojcie deskryptora. W systemie UNIX jest to liczba cakowita jednoznacznie identykujca otworzony plik. Chcc pisa do lub czyta z otworzonego pliku naley poda jego deskryptor. W treci zada dla uproszczania pojcie deskryptora uywane jest w odniesieniu do wartoci typu FILE *.

8.2. Zadania
??.1 (r,r) Napisz funkcj, ktra dostaje jako argument ciek dostpu do pliku, otwiera plik do tekstowego czytania i zwraca jako warto deskryptor wieo otwartego pliku (w wersji dla jzyka C++ funkcja powinna zwrci wskanik do obiektu klasy fstream). ??.2 (r,!) Napisz funkcj, ktra dostaje jako argument deskryptor do pliku tekstowego otwartego do czytania (w wersji dla jzyka C++ referencj

8.2. Zadania do obiektu klasy fstream), wypisuje zawarto pliku na standardowe wyjcie i zamyka plik. (r,!) Napisz funkcj, ktra dostaje jako argument ciek dostpu do pliku tekstowego i wypisuje na standardowym wyjciu zawarto pliku z pominiciem biaych znakw. Napisz dwie wersje funkcji dla znakw typw char i wchar_t. (r) Napisz funkcj, ktra dostaje jako argumenty ciek dostpu do pliku tekstowego oraz znak c i zwraca jako warto liczb wystpie znaku c w podanym w argumencie pliku. Napisz dwie wersje funkcji dla znakw typw char i wchar_t. Napisz funkcj, ktra dostaje w argumencie ciek dostpu do pliku tekstowego i wypisuje na standardowym wyjciu statystyki wystpowania w pliku poszczeglnych znakw (zakadamy, e znaki s typu char). Napisz funkcj, ktra dostaje jako argument ciek dostpu do pliku tekstowego i zwraca jako warto najczciej wystpujcy w pliku znak (zakadamy, e znaki s typu char). Napisz funkcj, ktra dostaje jako argument ciek dostpu do pliku tekstowego zawierajcego liczby cakowite oddzielone biaymi znakami i zwraca jako warto sum znajdujcych si w pliku liczb. Napisz funkcj, ktra dostaje jako argument ciek dostpu do pliku tekstowego zawierajcego liczby cakowite oddzielone biaymi znakami i zwraca jako warto najmniejsz spord znajdujcych si w pliku liczb. (r,!) Napisz funkcj, ktra dostaje jako argumenty cieki dostpu do dwch plikw tekstowych i zwraca jako warto 1, jeeli podane pliki maj tak sam zawarto oraz 0 w przeciwnym wypadku. Napisz dwie wersje funkcji dla znakw typu char i wchar_t. (r) Napisz funkcj, ktra dostaje jako argumenty cieki dostpu do dwch plikw tekstowych i zwraca jako warto 1, jeeli podane pliki maj tak sam zawarto z dokadnoci do biaych znakw oraz 0 w przeciwnym wypadku. Napisz dwie wersje funkcji dla znakw typu char i wchar_t. (r) Napisz funkcj, ktra dostaje jako argument ciek dostpu do pliku, otwiera plik do tekstowego pisania z kursorem ustawionym na kocu pliku i zwraca jako warto deskryptor wieo otwartego pliku (w wersji dla jzyka C++ funkcja powinna zwrci wskanik do obiektu klasy fstream). (r) Napisz funkcj, ktra dostaje jako argument deskryptor do pliku tekstowego otwartego do pisania (w wersji dla jzyka C++ referencj do obiektu klasy fstream) oraz liczb n, wczytuje ze standardowego

49

??.3

??.4

??.5

??.6

??.7

??.8

??.9

??.10

??.11

??.12

50

8. Operacje na plikach wejcia n wersw tekstu, zapisuje do pliku wczytany tekst i zamyka plik. Napisz dwie wersje funkcji dla znakw typw char i wchar_t. (r) Napisz funkcj, ktra dostaje jako argumenty deskryptory dwch plikw tekstowych i przepisuje zawarto pierwszego pliku do drugiego pliku. (r) Napisz funkcj, ktra dostaje jako argumenty cieki dostpu do dwch plikw (w wersji dla jzyka C++ referencje do obiektw klasy fstream) i przepisuje zawarto pierwszego pliku do drugiego pliku (stara zawarto drugiego pliku ma zosta skasowana). Napisz funkcj, ktra dostaje jako argumenty cieki dostpu do dwch plikw i dopisuje zawarto pierwszego pliku na koniec drugiego pliku. Napisz funkcj, ktra dostaje w argumentach jednowymiarow tablic liczb cakowitych tab, jej rozmiar oraz ciek dostpu do pliku tekstowego, i dopisuje w kolejnych wierszach na kocu otrzymanego pliku wartoci kolejnych elementw tablicy tab. (*,r,!) Napisz funkcj, ktra dostaje jako argumenty nazw pliku, dwuwymiarow tablic tablic o elementach typu int oraz wymiary tablicy i zapisuje binarnie zawarto tablicy do podanego pliku. (*,r,!) Napisz funkcj, ktra dostaje jako argumenty nazw pliku, dwuwymiarow tablic tablic o elementach typu int oraz wymiary tablicy i wczytuje binarnie zawarto pliku do tablicy. Napisz funkcj tak, aby bya kompatybilna z funkcj z zadania ??.??. (*) Napisz funkcj, ktra dostaje jako argumenty nazw pliku, dwuwymiarow tablic tablic o elementach typu int oraz wymiary tablicy i zapisuje binarnie zawarto tablicy oraz jej wymiary do podanego pliku. (*) Napisz funkcj, ktra dostaje jako argumenty nazw pliku, wczytuje zawarto pliku do nowo utworzonej dwuwymiarowej tablicy tablic. Wymiary tablicy powinny by podane w pliku. Napisz funkcj tak, aby bya kompatybilna z funkcj z zadania ??.??.

??.13

??.14

??.15 ??.16

??.17

??.18

??.19

??.20

Rozdzia 9
Instrukcje preprocesora, aplikacje wieloplikowe, makefile.

9.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . 9.2. Makra . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3. Aplikacje wieloplikowe, makele . . . . . . . . . . . . .

52 52 53

52

9. Instrukcje preprocesora, aplikacje wieloplikowe, makele.

9.1. Wprowadzenie
Przed waciwym procesem kompilacji, czyli tumaczeniem programu napisanego w jzyku wysokiego poziomu na kod maszynowy, w przypadku jzykw C i C++ kod programu przetwarzany jest przez preprocesor. W pocztkach jzyka C preprocesor odgrywa bardzo du rol. Jednak w wyniku rozwoju tego jzyka, w tym dodania do niego m. in. takich elementw jak stae, czy funkcje inline, znaczenia preprocesora zmalao. Nie bez znaczenia by te rozwj debuggerw, ktre znacznie uatwiy szukanie bdw w programach, co wczeniej byo jedn z dziedzin, w ktrej wykorzystywano dyrektywy preprocesora. Obecnie dyrektywy preprocesora wykorzystuje si niemal wycznie do doczania bibliotek i tworzenia aplikacji wieloplikowych.

9.2. Makra
W zadaniach w tym podrozdziale naley napisa makrodenicje. Makrodenicje, nazywane krcej makrami, tworzy si przy pomocy dyrektywy #define. ??.1 (r,!) Napisz makro, ktre dostaje trzy argumenty i zwraca ich sum. ??.2 Napisz makro, ktre dla trzech otrzymanych w argumentach liczb zwraca ich redni. ??.3 (r) Napisz makro, ktre dostaje jako argumenty dwie liczby cakowite i wypisuje na standardowym wyjciu wiksz z nich. ??.4 (r) Napisz jednoargumentowe makro, ktre zwraca warto 1 jeeli argumentem jest liczba parzysta i 0 jeeli argument jest nieparzysty. ??.5 Napisz makro, ktre dostaje dwa argumenty i zwraca wikszy z nich (zakadamy, e otrzymane wartoci s porwnywalne). ??.6 (r,!) Napisz makro, ktre dostaje trzy liczby cakowite jako argumenty i wypisuje na standardowym wyjciu najwiksz z otrzymanych wartoci. ??.7 (r) Napisz makro, ktre dostaje trzy argumenty i zwraca najwiksz z otrzymanych wartoci (zakadamy, e otrzymane wartoci s porwnywalne). ??.8 (r) Napisz makro o dwch argumentach x i n, ktre dziaa jak ptla for+, w ktrej zmienna x przebiega wartoci od 0 do n-1. ??.9 Napisz makro o dwch argumentach x i n, ktre dziaa jak ptla for, w ktrej zmienna x przebiega wartoci od n do 0. ??.10 (r) Napisz makro, ktre nadaje warto 0 podanej w argumencie zmiennej.

9.3. Aplikacje wieloplikowe, makele ??.11 Napisz makro, ktre zwiksza o 2 podan w argumencie zmienn liczbow.

53

9.3. Aplikacje wieloplikowe, makele


??.1 (r) Napisz program, ktry oblicza miejsca zerowe wielomianu drugiego stopnia o wspczynnikach wczytanych ze standardowego wejcia. W programie wykorzystaj samodzielnie napisan funkcj liczc pierwiastek z liczby dodatniej. Funkcj liczc pierwiastek umie w oddzielnym pliku. ??.2 Napisz program, ktry oblicza warto wielomianu jednej zmiennej o wspczynnikach podanych przez uytkownika w punkcie podanym przez niego. W programie wykorzystaj samodzielnie napisan funkcj liczc potg. Funkcj liczc potg umie w oddzielnym pliku. ??.3 (r,!) Napisz program, ktry oblicza miejsca zerowe wielomianu drugiego stopnia o wspczynnikach wczytanych ze standardowego wejcia. W programie wykorzystaj samodzielnie napisan funkcj liczc pierwiastek z liczby dodatniej. Program podziel na trzy pliki: plik zawierajcy gwny program, plik zawierajcy funkcj pierwiastkujc, oraz plik z nagwkiem funkcji pierwiastkujcej. ??.4 (r,!) Napisz plik makele pozwalajcy na kompilacj programu z zadania ??.??. ??.5 Napisz program, ktry oblicza warto wielomianu jednej zmiennej o wspczynnikach podanych przez uytkownika w punkcie podanym przez uytkownika. W programie wykorzystaj samodzielnie napisan funkcj liczc potg. Program podziel na trzy pliki: plik zawierajcy gwny program, plik zawierajcy funkcj potgujc oraz plik z nagwkiem funkcji potgujcej. ??.6 Napisz plik makele pozwalajcy na kompilacj programu z zadania ??.??. ??.7 (r) Napisz program, ktry wczytuje ze standardowego wejcia cig liczb zespolonych i wypisuje na standardowym wyjciu sum wczytanych liczb. Program powinien skada si z trzech czci: programu gwnego, biblioteki zawierajcej denicje typu zespolone oraz funkcji do wczytywania i wypisywania elementw tego typu, biblioteki zawierajcej funkcje do dodawania i mnoenia liczb zespolonych. Biblioteki powinny si skada z dwch plikw: pliku nagwkowego oraz pliku z denicjami funkcji.

54

9. Instrukcje preprocesora, aplikacje wieloplikowe, makele. ??.8 (r) Napisz plik makele pozwalajcy na kompilacj programu z zadania ??.??. ??.9 Napisz program, ktry wczytuje ze standardowego wejcia list pracownikw (imi, nazwisko, wiek), zapisuje ich w tablicy rekordw typu osoba, i wypisuje redni wieku wczytanych pracownikw. Program powinien skada si z trzech czci: programu gwnego, biblioteki zawierajcej denicj typu osoba oraz funkcje do wczytywania i wypisywania elementw tego typu, biblioteki zawierajcej funkcje statystyczne (rednia wieku, minimalny oraz maksymalny wiek) pracujce na tablicach o elementach typu osoba. Funkcje zawarte w tej bibliotece powinny otrzymywa w argumentach tablic elementw typu osoba oraz jej rozmiar i zwraca wynik dziaania jako swoj warto. Biblioteki powinny si skada z dwch plikw: pliku nagwkowego oraz pliku z denicjami funkcji. ??.10 Napisz plik makele pozwalajcy na kompilacj programu z zadania ??.??. ??.11 (r,!) Napisz program, ktry wczytuje ze standardowego wejcia list pracownikw (imi, nazwisko, wiek), zapisuje ich w tablicy rekordw typu osoba, i wypisuje redni wieku wczytanych pracownikw. Program powinien skada si z trzech czci: programu gwnego, biblioteki dane zawierajcej denicj typu osoba oraz funkcje do wczytywania i wypisywania elementw tego typu. Wczytane dane osobowe oraz liczba przechowywanych rekordw powinny by przechowywane przez zmienne zadeklarowane w tej bibliotece, biblioteki zawierajcej funkcje statystyczne (rednia wieku, minimalny oraz maksymalny wiek) pracujce na tablicach o elementach typu osoba. Funkcje zawarte w tej bibliotece powinny korzysta z danych przechowywanych przez zmienne zadeklarowane w bibliotece dane. Biblioteki powinny si skada z dwch plikw: pliku nagwkowego oraz pliku z denicjami funkcji. ??.12 (r) Napisz plik makele pozwalajcy na kompilacj programu z zadania ??.??. ??.13 (r,!) Napisz bibliotek suc do przechowywania danych osobowych (imi, nazwisko, wiek). Biblioteka powinna zawiera denicj typu osoba oraz udostpnia nastpujce funkcje: wczytaj funkcja wczytujca dane jednej osoby ze standardowego wejcia. Dane powinny by wczytywane do tablicy o elementach typu osoba.

9.3. Aplikacje wieloplikowe, makele wypisz funkcja wypisujca na standardowym wyjciu wszystkie wczytane dane osobowe, ile funkcja zwracajca jako warto liczb osb, ktrych dane osobowe zostay wczytane. wczytana funkcja udostpniajca wczytane dane osobowe. Funkcja dla podanej w argumencie nieujemnej liczby cakowitej n powinna zwrci element typu osoba przechowywany pod indeksem n. Dostp do danych przechowywanych w bibliotece powinien by moliwy wycznie za porednictwem zdeniowanych w bibliotece funkcji. Zdeniowane w bibliotece zmienne powinny by widoczne wycznie w tej bibliotece. ??.14 Napisz bibliotek kalkulator. Biblioteka ta powinna udostpnia nastpujce funkcje: wczytaj funkcja wczytujca podan w argumencie warto do kalkulatora, dodaj funkcja dodajca liczb podan w argumencie do wartoci przechowywanej w kalkulatorze; wynik dziaania powinien zosta zapisany w kalkulatorze i zwrcony przez funkcj, odejmij funkcja odejmujca liczb podan w argumencie od wartoci przechowywanej w kalkulatorze; wynik dziaania powinien zosta zapisany w kalkulatorze i zwrcony przez funkcj, pomnoz funkcja mnoca liczb podan w argumencie przez warto przechowywan w kalkulatorze;, wynik dziaania powinien zosta zapisany w kalkulatorze i zwrcony przez funkcj, odejmij funkcja dzielca warto przechowywan w kalkulatorze przez liczb podan w argumencie funkcji; wynik dziaania powinien zosta zapisany w kalkulatorze i zwrcony przez funkcj. Zdeniowane w bibliotece kalkulator zmienne powinny by widoczne wycznie w tej bibliotece. ??.15 (r,!,r) Napisz bibliotek kolo zawierajc: jednoargumentow funkcj pole zwracajc pole koa o podanym w argumencie promieniu, jednoargumentow funkcj obwod zwracajc obwd koa o podanym w argumencie promieniu, sta pi przechowujc warto liczby . Staa ta powinna by dostpna w programach uywajcych biblioteki kolo.

55

Rozdzia 10
Rozwizania i wskazwki

10.1. Rozwizania 10.2. Rozwizania 10.3. Rozwizania 10.4. Rozwizania 10.5. Rozwizania 10.6. Rozwizania 10.7. Rozwizania 10.8. Rozwizania 10.9. Rozwizania 10.10.Rozwizania 10.11.Rozwizania 10.12.Rozwizania 10.13.Rozwizania

do do do do do do do do do do do do do

zada zada zada zada zada zada zada zada zada zada zada zada zada

z z z z z z z z z z z z z

rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau rozdziau

1.2 1.3 1.4 2.2 3.2 4.2 5.2 6.2 7.2 7.3 8.2 9.2 9.3

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

58 62 65 70 77 79 86 97 105 113 129 138 139

58

10. Rozwizania i wskazwki

10.1. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.1. Rozwizanie zad. ??.?? w jzyku C
#include <s t d i o . h>
2

i n t main ( ) { int l i c z b a ; p r i n t f ( " H e l l o World " ) ; return 0 ; }

Standardowe wejcie i standardowe wyjcie to nazwy predeniowanych w jzyku C strumieni. To, co one oznaczaj, nie zaley od programu napisanego w C, ale od konguracji systemu, w ktrym uruchamiany jest skompilowany program. Zazwyczaj standardowe wejcie oznacza klawiatur, a standardowe wyjcie ekran. Listing 10.2. Rozwizanie zad. ??.?? w jzyku C++
#include <i o s t r e a m > i n t main ( ) { int l i c z b a ; s t d : : cout<<" H e l l o World " ; return 0 ; }

Aby w powyszym rozwizaniu unikn uywania przedrostka std::, mona uy polecenia using namespace std. Wtedy rozwizanie wyglda nastpujco: Listing 10.3. Rozwizanie zad. ??.?? w jzyku C++
#include <i o s t r e a m > using namespace s t d ; i n t main ( ) { cout<<" H e l l o World " ; return 0 ; }

10.1. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Listing 10.4. Rozwizanie zad. ??.?? w jzyku C
1

59

#include <s t d i o . h> i n t main ( ) { int l i c z b a ; s c a n f ( "%d" , &l i c z b a ) ; p r i n t f ( "%d" , l i c z b a ) ; return 0 ; }

W funkcji scanf zmienne, do ktrych wczytywane s wartoci, s poprzedzone znakiem &. Uywajc funkcji scanf naley uwaa, aby nie zapomina o wstawianiu &, gdy jest to bd niewykrywany przez kompilatory, ktry ujawnia si dopiero podczas dziaania programu. Wyjtkiem, w ktrym nie stosuje si znaku & przed nazw wczytywanej zmiennej jest wczytywanie napisw. Listing 10.5. Rozwizanie zad. ??.?? w jzyku C++
#include <i o s t r e a m > using namespace s t d ; i n t main ( ) { int l i c z b a ; c i n >>l i c z b a ; cout<<l i c z b a ; return 0 ; }

Zadanie ??.?? Listing 10.6. Rozwizanie zad. ??.?? w jzyku C


#include <s t d i o . h> i n t main ( ) { double l i c z b a ; s c a n f ( "%l f " , &l i c z b a ) ; p r i n t f ( "%f " , l i c z b a ) ; return 0 ; }

Warto zapamita, e w funkcjach scanf i printf innych ag uywa si przy wczytywaniu i wypisywaniu wartoci typu double (odpowiednio%lf i %f).

60

10. Rozwizania i wskazwki Listing 10.7. Rozwizanie zad. ??.?? w jzyku C++
#include <i o s t r e a m > i n t main ( ) { double l i c z b a ; s t d : : c i n >>l i c z b a ; s t d : : cout<<l i c z b a ; return 0 ; }

Jak wida powysze rozwizanie rni si od rozwizania zadania ??.?? jedynie typem zmiennej liczba. Operatory << i >> w pewnym sensie rozpoznaj typ zmiennej liczba i w zalenoci od niego wczytuj i wypisuj warto zmiennej liczba w odpowiedni sposb. Zadanie ??.?? Listing 10.8. Rozwizanie zad. ??.?? w jzyku C
#include <s t d i o . h>
2

10

i n t main ( ) { int l1 , l2 , s c a n f ( "%d" , s c a n f ( "%d" , s c a n f ( "%d" , p r i n t f ( "%f " return 0 ; }

l3 ; &l 1 ) ; &l 2 ) ; &l 3 ) ; , ( double ) ( l 1 + l 2 + l 3 ) / 3 ) ;

Znaczna cz studentw na kolokwium lini 8 powyszego programu napisaaby w nastpujcy sposb printf("%f",(l1+l2+l3)/3); co byoby bdem, gdy dla l1=0, l2=1 i l3=1 na ekranie wywietlona zostaaby liczba 0, a nie 0.666667. Operatory arytmetyczne w jzykach C i C++ zwracaj wynik takiego samego typu jak argumenty, a gdy argumenty s rnego typu, to typ wyniku jest najpojemniejszym spord typw argumentw. W powyszym programie warto pierwszego argumentu dzielenia zostaa zrzutowana na typ double. Dziki temu argumentami dzielenia nie s dwie wartoci typu int, a jedna warto typu double i druga warto typu int. Co za tym idzie, wynik dzielenia wykonanego w programie jest typu double, a wic moe on wyrazi liczb 0.6(6) (a raczej najblisza jej warto moliwa do zapisania w typie double). Innym poprawnym, cho mniej eleganckim, rozwizaniem jest napisanie linii 8 programu ?? w nastpujcy sposb printf("%f",(l1*1.0+l2+l3)/3);.

10.1. Rozwizania do zada z rozdziau ?? Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.9. Rozwizanie zad. ??.?? w jzyku C
2

61

#include <s t d i o . h> #include <math . h> i n t main ( ) { double x ; s c a n f ( "%l f " , &x ) ; p r i n t f ( "%f " , s q r t ( x ) ) ; return 0 ; }

Aby powyszy program skompilowa przy uyciu gcc naley uy parametru lm. Jest tak, gdy w programie uyta zostaa funkcja sqrt z biblioteki math. Podobnie naley postpowa take przy kompilacji za pomoc gcc programw uywajcych innych operacji z biblioteki math. Problem taki nie wystpuje w przypadku g++, a wic ponisze rozwizanie dla C++ kompiluje si poprawnie bez dodatkowego parametru: Listing 10.10. Rozwizanie zad. ??.?? w jzyku C
1

#include <i o s t r e a m > #include <cmath> using namespace s t d ; i n t main ( ) { double x ; c i n >>x ; cout<<s q r t ( x ) ; return 0 ; }

Zadanie ??.?? Rozwizanie dla jzyka C: Listing 10.11. Rozwizanie zad. ??.?? w jzyku C
#include <s t d i o . h>
2

i n t main ( ) { float f ; s c a n f ( "%f " , &f ) ; p r i n t f ( " %.2 f " , f ) ; return 0 ; }

62 Rozwizanie dla jzyka C++:

10. Rozwizania i wskazwki

Listing 10.12. Rozwizanie zad. ??.?? w jzyku C


2

#include<i o s t r e a m > using namespace s t d ; i n t main ( ) { float f ; c i n >>f ; cout . p r e c i s i o n ( 2) ; cout . s e t f ( i o s : : fix ed , i o s : : f l o a t f i e l d ) ; cout<<f i x e d <<f ; }

10

10.2. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.13. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { int l i c z b a ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a : " ) ; s c a n f ( "%d" , &l i c z b a ) ; i f ( l i c z b a < 0) l i c z b a = 1; p r i n t f ( " | l i c z b a | =%d" , l i c z b a ) ; return 0 ; }

To samo zadanie mona rozwiza uywajc operatora warunkowego: Listing 10.14. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { int l i c z b a ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a : " ) ; s c a n f ( "%d" , &l i c z b a ) ; p r i n t f ( " | l i c z b a | =%d" , ( l i c z b a >=0)? l i c z b a :( 1) l i c z b a ) ; return 0 ; }

10.2. Rozwizania do zada z rozdziau ?? Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.15. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> #include <math . h> i n t main ( ) { int w; double bok1 , bok2 , bok3 , h , p , s ; p r i n t f ( "Witam . Obliczam p o l e t r o j k a t a . Wpisz : \ n" ) ; p r i n t f ( "1 j e s l i c h c e s z podac d l . podstawy i wys . \ n" ) ; p r i n t f ( "2 j e s l i c h c e s z podac d l . t r z e c h bokow \n" ) ; s c a n f ( "%d" , &w) ; i f (w == 1 ) { p r i n t f ( " Podaj d l u g o s c podstawy t r o j k a t a . " ) ; s c a n f ( "%l f " , &bok1 ) ; p r i n t f ( " Podaj wy sok osc t r o j k a t a . " ) ; s c a n f ( "%l f " , &h ) ; p=bok1 h / 2 ; } else { p r i n t f ( " Podaj d l u g o s c p i e r w s z e g o boku t r o j k a t a : " ) ; s c a n f ( "%l f " , &bok1 ) ; p r i n t f ( " Podaj d l u g o s c d r u g i e g o boku t r o j k a t a : " ) ; s c a n f ( "%l f " , &bok2 ) ; p r i n t f ( " Podaj d l u g o s c t r z e c i e g o boku t r o j k a t a : " ) ; s c a n f ( "%l f " , &bok3 ) ; s =(bok1 + bok2 + bok3 ) / 2 ; p=s q r t ( s ( s bok1 ) ( s bok2 ) ( s bok3 ) ) ; } p r i n t f ( " P o l e t r o j k a t a o podanych wymiarach wy nosi %f " , p ) ; return 0 ; }

63

Rozwizanie w jzyku C++: Listing 10.16. Rozwizanie zadania ??.?? w jzyku C++
#include <i o s t r e a m > #include <cmath> using namespace s t d ; i n t main ( ) { int w; double bok1 , bok2 , bok3 , h , p , s ; cout<<"Witam . Obliczam p o l e t r o j k a t a . Wpisz : "<<e n d l ; cout<<"1 j e s l i c h c e s z podac d l . podstawy i wys . "<<e n d l ; cout<<"2 j e s l i c h c e s z podac d l . i t r z e c h bokow "<<e n d l ;

64

10. Rozwizania i wskazwki


c i n >>w ; i f (w == 1 ) { cout<<" Podaj d l u g o s c podstawy t r o j k a t a : " ; c i n >>bok1 ; cout<<" Podaj wy sok osc t r o j k a t a : " ; c i n >>h ; p=bok1 h / 2 ; } else { cout<<" Podaj d l u g o s c p i e r w s z e g o boku t r o j k a t a : " ; c i n >>bok1 ; cout<<" Podaj d l u g o s c d r u g i e g o boku t r o j k a t a : " ; c i n >>bok2 ; cout<<" Podaj d l u g o s c t r z e c i e g o boku t r o j k a t a : " ; c i n >>bok3 ; s =(bok1 + bok2 + bok3 ) / 2 ; p=s q r t ( s ( s bok1 ) ( s bok2 ) ( s bok3 ) ) ; } cout<<" P o l e t r o j k a t a o podanych wymiarach wy nosi "<<p ; return 0 ; }

Zadanie ??.?? Listing 10.17. Rozwizanie zadania ??.?? w jzyku C


#include <s t d i o . h> i n t main ( ) { int i ; double a , b , h , p ; p r i n t f ( " P o l e j a k i e j f i g u r y c h c e s z p o l i c z y c ?\ n" ) ; p r i n t f ( " 1 kwadrat \n" ) ; p r i n t f ( " 2 p r o s t o k a t \n" ) ; p r i n t f ( " 3 t r o j k a t \n" ) ; s c a n f ( "%d" ,& i ) ; switch ( i ) { case 1 : p r i n t f ( " Podaj d l . boku kwadratu" ) ; s c a n f ( "%l f " ,&a ) ; p=a a ; break ; case 2 : p r i n t f ( " Podaj d l . bokow p r o s t o k a t a " ) ; s c a n f ( "%l f %l f " ,&a ,&b ) ; p=a b ; break ; case 3 : p r i n t f ( " Podaj d l . podstawy i wys . t r o j k a t a " ) ; s c a n f ( "%l f %l f " ,&a ,&h ) ; p=0.5 a h ; } p r i n t f ( " P o l e f i g u r y o podanych wymiarach wy nosi %f \n" , p ) ; return 0 ;

10.3. Rozwizania do zada z rozdziau ??


}

65

W powyszym programie zamiast instrukcji switch mona uy kilku instrukcji if, jednak dziki uyciu instrukcji switch program jest bardziej czytelny. Wersja dla jzyka C++ jest analogiczna.

10.3. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.18. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { i n t n ,m; p r i n t f ( " Podaj l i c z b e c a l k o w i t a n : " ) ; s c a n f ( "%d" , &n ) ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a m: " ) ; s c a n f ( "%d" , & ; m) f o r ( i n t i = n ; i < m ; i += n ) p r i n t f ( "%d\n" , i ) ; return 0 ; }

W powyszym programie zmienna i zostaa zadeklarowana jednoczenie ze swoj inicjacj w ptli for. Taka moliwo w jzyku C pojawia si w standardzie C99. W powyszym programie zmiennej i nie mona uywa poza ptl for. W trakcie kompilacji program ?? moe wymaga dodatkowego parametru mwicego kompilatorowi, e program jest zgodny ze standardem C99 jzyka C (w gcc jest to parametr std=c99). Rozwizanie w jzyku C++: Listing 10.19. Rozwizanie zadania ??.?? w jzyku C++
#include <i o s t r e a m > using namespace s t d ; i n t main ( ) { i n t n ,m; cout<<" Podaj l i c z b e c a l k o w i t a n : " ; c i n >>n ; cout<<" Podaj l i c z b e c a l k o w i t a m: " ; c i n >> m; f o r ( i n t i = n ; i < m ; i += n ) cout<<i <<e n d l ;

66
return 0 ; }

10. Rozwizania i wskazwki

Zadanie ??.?? Listing 10.20. Rozwizanie zadania ??.?? w jzyku C


#include <s t d i o . h> i n t main ( ) { i n t n , i , s i l n i a =1; p r i n t f ( " Podaj l i c z b e c a l k o w i t a n : " ) ; s c a n f ( "%d" , &n ) ; f o r ( i =2; i<=n ; i ++) s i l n i a = i ; p r i n t f ( " S i l n i a z %d wy nosi %d\n" , n , s i l n i a ) ; return 0 ; }

W programie ?? naley zwrci uwag na kilka rzeczy: Zmienna silnia jest inicjowana od razu przy swojej deklaracji. Dla n = 0 oraz n = 1 ptla for nie wykona si ani razu i program zwrci pocztkow warto zmiennej silnia, a wic 1. Jest to oczywicie poprawna odpowied dla tych przypadkw. Warto przyjrze si sposobowi wyliczania silni dla n > 1. Kluczowa jest tu linia silnia *= i;, ktr inaczej mona zapisa jako silnia = silnia * i;. Jest to typowa programistyczna sztuczka. W i-tym obrocie ptli obliczana jest warto i! (program zapisuje j do zmiennej silnia), korzystajc ze wzoru i! = (i 1)! i, gdzie (i 1)! to stara warto zmiennej silnia. W ten sposb po n obrotach ptli for w zmiennej silnia zapisana jest warto n!. Czytelnik, ktremu zaprezentowane powyej rozwizanie wydaje si niejasne powinien sprbowa rozwiza kilka kolejnych zada. Mona je rozwiza w bardzo podobny sposb. Rozwizanie zadania w jzyku C++ jest podobne. Zadanie ??.?? Listing 10.21. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { i n t n , i , f i b 1 =1 , f i b 2 =1 , pom ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a n : " ) ; s c a n f ( "%d" , &n ) ;

10.3. Rozwizania do zada z rozdziau ??


f o r ( i =2; i<=n ; i ++){ pom= f i b 1 ; fib1 = fib2 + fib1 ; f i b 2 = pom ; } p r i n t f ( "Elem . c i a g u Fib . o i n d e k s i e %d t o %d\n" , n , f i b 1 ) ; return 0 ; }

67

W powyszym rozwizaniu zaoono, e indeks pierwszego elementu cigu Fibonacciego to 0. Rozwizanie w jzyku C++ jest podobne. Zadanie ??.?? Tym razem przedstawiono rozwizanie zadania w jzyku C++. Rozwizanie w jzyku C rni si od zaprezentowanego jedynie operacjami wejcia/wyjcia. Zadanie mona rozwiza poprzez przeszukanie wszystkich liczb dodatnich mniejszych rwnych zarwno od n, jak i od m: Listing 10.22. Rozwizanie zadania ??.?? w jzyku C++
#include <i o s t r e a m > using namespace s t d ; i n t main ( ) { i n t n , m, nwd=1 , max ; cout<<" Podaj l i c z b e c a l k o w i t a n : " ; c i n >>n ; cout<<" Podaj l i c z b e c a l k o w i t a m : " ; c i n >> m; max=(n> ?n :m; m) f o r ( i n t i =2; i <=max ; i ++) i f ( ( n % i == 0 ) && (m % i == 0 ) ) nwd=i ; cout<<"NWD l i c z b "<<n<<" i "<<m <<" wy nosi "<<nwd<<e n d l ; return 0 ; }

Poniewa powyszy program przeszukuje zbir potencjalnych rozwiza od dou, to ostatni znaleziony wsplny dzielnik n i m bdzie tym najwikszym. W programie uyto operatora % zwracajcego reszt z dzielenia pierwszego argumentu przez drugi. Innym sposobem rozwizania zadania jest zaimplementowanie algorytmu Euklidesa szukania NWD: Listing 10.23. Rozwizanie zadania ??.?? w jzyku C++

68
#include <i o s t r e a m > using namespace s t d ;

10. Rozwizania i wskazwki

i n t main ( ) { i n t n , m, pom1 , pom2 ; cout<<" Podaj l i c z b e c a l k o w i t a n : " ; c i n >>n ; cout<<" Podaj l i c z b e c a l k o w i t a m : " ; c i n >> m; pom1=n ; pom2= m; while ( pom1pom2 !=0) i f ( pom1>pom2 ) pom1=pom1%pom2 ; else pom2=pom2%pom1 ; cout<<"NWD l i c z b "<<n<<" i "<<m <<" wy nosi " ; i f ( pom1 !=0) cout<<pom1<<e n d l ; else cout<<pom2<<e n d l ; return 0 ; }

Drugi z zaprezentowanych programw dla duych liczb n i m dziaa znacznie szybciej ni pierwszy. Zadanie ??.?? Take to zadanie mona rozwiza poprzez przeszukiwanie wszystkich potencjalnych rozwiza. Listing 10.24. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { i n t x , i , p i e r w =0; p r i n t f ( " Podaj l i c z b e c a l k o w i t a x : " ) ; s c a n f ( "%d" , &x ) ; f o r ( i =1; i<=x ; i ++) i f ( i i <= x ) p i e r w=i ; p r i n t f ( " Pierw . z %d t o w p r z y b l i z e n i u %d\n" , x , p i e r w ) ; return 0 ; }

Zadanie ??.?? mona rozwiza efektywniej. Jedn z moliwoci jest zastosowanie algorytmu bisekcji:

10.3. Rozwizania do zada z rozdziau ?? Listing 10.25. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { i n t x , pocz , kon , s r ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a x : " ) ; s c a n f ( "%d" , &x ) ; pocz =0; kon=x ; while ( kon pocz > 1 ) { s r =(pocz + kon ) / 2 ; i f ( s r s r <= x ) pocz=s r ; else kon=s r ; } p r i n t f ( " P i e r w i a s t e k z %d t o w p r z y b l i z e n i u " , x ) ; i f ( x<=1) p r i n t f ( "%d\n" , kon ) ; else p r i n t f ( "%d\n" , pocz ) ; return 0 ; }

69

W powyszym programie w kadym obrocie ptli while zbir potencjalnych rozwiza zmniejsza si o poow. Przydaje si tu fakt, i dzielenie liczb cakowitych daje w wyniku liczb cakowit. W jzyku C++ to zadanie rozwizuje si w analogiczny sposb. Zadanie ??.?? To zadanie mona rozwiza za pomoc zagniedonych ptli: Listing 10.26. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t main ( ) { i n t n , m, pom1 , pom2 , suma=0 , i ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a n : " ) ; s c a n f ( "%d" ,&n ) ; f o r ( i = 2 ; i < n ; i++ ) { pom1=n ; pom2=i ; while ( pom1pom2 !=0) i f ( pom1<pom2 ) pom2=pom2%pom1 ; else pom1=pom1%pom2 ; i f ( ( pom1 == 1 ) | | ( pom2 == 1 ) )

70

10. Rozwizania i wskazwki


suma += i ; } p r i n t f ( "Wynik o b l i c z e n t o : %d\n" , suma ) ; return 0 ; }

W jzyku C++ to zadanie rozwizuje si w analogiczny sposb. Zadanie ??.?? Pozornie zadanie wymaga zastosowania ptli w ptli. W rzeczywistoci jednak tak nie jest: Listing 10.27. Rozwizanie zadania ??.?? w jzyku C++
#include <i o s t r e a m > using namespace s t d ; i n t main ( ) { i n t n , s i l n i a =1 ,suma=1; cout<<" Podaj l i c z b e c a l k o w i t a n : " ; c i n >>n ; f o r ( i n t i =1; i <=n ; i ++){ s i l n i a = i ; suma+=s i l n i a ; } cout<<" 0 ! + 1 ! + . . . + "<<n<<" ! = "<<suma<<e n d l ; return 0 ; }

W jzyku C to zadanie rozwizuje si w analogiczny sposb.

10.4. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.28. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t bezwzgledna ( i n t l i c z b a ) { i f ( l i c z b a < 0) return l i c z b a ( 1) ; else return l i c z b a ; } i n t main ( ) {

10.4. Rozwizania do zada z rozdziau ??


int n ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a : " ) ; s c a n f ( "%d" , &n ) ; p r i n t f ( "|%d | =%d\n" , n , bezwzgledna ( n ) ) ; return 0 ; }

71

Rozwizanie w jzyku C++ jest podobne. Zadanie ??.?? Listing 10.29. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> i n t s i l n i a ( unsigned i n t l i c z b a ) { i n t i , s i l =1; f o r ( i =2; i <= l i c z b a ; i ++) s i l = i ; return s i l ; } i n t main ( ) { int n ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a : " ) ; s c a n f ( "%d" , &n ) ; p r i n t f ( " s i l n i a z %d=%d\n" , n , s i l n i a ( n ) ) ; return 0 ; }

W jzyku C++ to zadanie rozwizuje si w analogiczny sposb. Zadanie ??.?? Listing 10.30. Rozwizanie zadania ??.?? w jzyku C
#include <s t d i o . h> unsigned i n t NWD( unsigned i n t p , unsigned i n t d ) { while ( p != d ) i f (p > d) p=pd ; else d=dp ; return p ; } unsigned i n t suma ( unsigned i n t n ) { i n t i , sum=0;

72
f o r ( i = 1 ; i < n ; i++ ) { i f ( NWD( i , n ) == 1 ) sum += i ; } return sum ; }

10. Rozwizania i wskazwki

i n t main ( ) { int n ; p r i n t f ( " Podaj l i c z b e c a l k o w i t a n : " ) ; s c a n f ( "%d" ,&n ) ; p r i n t f ( "Wynik o b l i c z e n t o : %d\n" , suma ( n ) ) ; return 0 ; }

Dziki uywaniu funkcji programy zyskuj na czytelnoci. Ponadto, raz zaimplementowane i przetestowane funkcje mog by traktowane jak czarne skrzynki, do ktrych kodu si nie wraca. Dziki takiemu podejciu programista moe skupia si naraz na niewielkich fragmentach kodu zawartych w pojedynczych funkcjach. Znacznie upraszcza to pisanie programw. Przykadowo, dziki wydzieleniu funkcji NWD w programie ?? napisanie funkcji suma stao si proste. W jzykach C i C++ argumenty funkcji przekazywane s przez warto. Oznacza to, e wewntrz funkcji pracuje si na kopiach wartoci przekazanych w argumentach. Przykadowo, w programie ??, zmiana wartoci zmiennych p i d wewntrz funkcji NWD nie pociga za sob zmiany wartoci zmiennych i i n z funkcji suma. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? a) Listing 10.31. Rozwizanie zadania ??.?? a) w jzyku C
i n t p i e r w ( unsigned i n t x ) { i n t pocz =0 , kon=x , s r ; while ( kon pocz > 1 ) { s r =(pocz + kon ) / 2 ; i f ( s r s r <= x ) pocz=s r ; else kon=s r ; } i f ( x<=1) return kon ; else return pocz ; }

10.4. Rozwizania do zada z rozdziau ??

73

void wy pisz ( unsigned i n t n ) { int i , p ; f o r ( i = 1 ; i <=p i e r w ( n ) ; i++ ) { p=p i e r w ( ni i ) ; i f ( ( p !=0)&&( i i+pp==n ) ) p r i n t f ( "%d%d+%d%d=%d\n" , i , i , p , p , n ) ; } }

W jzyku C++ to zadanie rozwizuje si w analogiczny sposb. Zadanie ??.?? b) Listing 10.32. Rozwizanie zadania ??.?? b) w jzyku C
i n t p i e r w ( unsigned i n t x ) { i n t pocz =0 , kon=x , s r ; while ( kon pocz > 1 ) { s r =(pocz + kon ) / 2 ; i f ( s r s r <= x ) pocz=s r ; else kon=s r ; } i f ( x<=1) return kon ; else return pocz ; }

void wy pisz ( unsigned i n t n ) { int i , p ; f o r ( i = 1 ; i <= p i e r w ( n ) ; i++ ) { p=p i e r w ( ni i ) ; i f ( ( i i+pp==n )&&(i <p ) ) p r i n t f ( "%d%d+%d%d=%d\n" , i , i , p , p , n ) ; } }

W tym wariancie zadania, aby nie powtarza tych samych rozkadw, program sprawdza, czy i jest mniejsze od p. W jzyku C++ to zadanie rozwizuje si w analogiczny sposb.

74 Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.33. Rozwizanie zadania ??.?? w jzyku C


void z l i c z ( ) { s t a t i c unsigned i n t l i c z b a =0; l i c z b a ++; p r i n t f ( " Funkcja z o s t a l a wywolana %d r a z y \n" , l i c z b a ) ; }

W powyszym rozwizaniu istotne jest sowo kluczowe static. Rozwizanie dla jzyka C++ jest analogiczne. Zadanie ??.?? Rozwizanie tego zadania dla jzykw C i C++ niczym si nie rni. Listing 10.34. Rozwizanie zadania ??.?? w jzyku C/C++
unsigned i n t s i l n i a ( unsigned i n t n ) { i f ( n <=1 ) return 1 ; else return s i l n i a ( n1)n ; }

Stosujc funkcje rekurencyjne w wielu przypadkach mona uzyska elegancki i prosty zapis algorytmu. Niestety szukanie bdw w funkcjach rekurencyjnych nie naley do rzeczy prostych. Dlatego przy pisaniu takich funkcji trzeba szczeglnie uwaa. W szczeglnoci trzeba pamita o tym, e funkcja musi posiada warunek stopu, czyli warunek przy ktrym oblicza swoj warto wprost (ju si dalej rekurencyjnie nie wywouje) oraz o tym, eby kolejne rekurencyjne wywoania funkcji prowadziy do spenienia warunku stopu. Kolejnych kilka zada ma sprawdzi umiejtno implementowania prostych funkcji rekurencyjnych. Zadanie ??.?? Cig Fibonacciego wydaje si by stworzony do tego, by jego elementy generowa przy pomocy funkcji rekurencyjnej: Listing 10.35. Rozwizanie zadania ??.?? w jzyku C/C++
unsigned i n t f i b ( unsigned i n t n ) { i f ( n <=1 ) return 1 ; else return f i b ( n1) + f i b ( n2) ; }

10.4. Rozwizania do zada z rozdziau ?? Po analizie zoonoci obliczeniowej powyszej funkcji okazuje si jednak, e duo bardziej efektywna jest iteracyjne generowanie elementw cigu Fibonacciego. Aby si o tym przekona, wystarczy uruchomi powysz funkcj oraz program ?? dla odpowiednio duych danych. Saba efektywno rekurencyjnej implementacji wynika z tego, e wielokrotnie liczy ona wartoci tych samych elementw cigu Fibonacciego. Zadanie ??.?? Listing 10.36. Rozwizanie zadania ??.?? w jzyku C/C++
unsigned i n t c i a g ( unsigned i n t n ) { i f ( n <= 2 ) return 1 ; else switch ( n%3){ case 0 : return c i a g ( n1) + c i a g ( n2) ; case 1 : return 5 c i a g ( n1) + 4 ; case 2 : return c i a g ( n1) ; } }

75

W funkcji ciag przedstawionej w Listingu ?? nie uyto instrukcji break w bloku instrukcji switch. Wynika to z tego, e instrukcja return koczy wykonywanie funkcji (a wic take instrukcji wyboru switch) i instrukcja break nie jest ju potrzebna. Zadanie ??.?? Listing 10.37. Rozwizanie zadania ??.?? w jzyku C/C++
unsigned i n t f ( unsigned i n t n , unsigned i n t m) { i f ( n == 0 ) return m; i f (m == 0 ) return n ; return f ( n1 ,m) + f ( n ,m1) + f ( n1 , m1) ; }

W funkcji f przedstawionej w Listingu ?? nie uyto instrukcji else. Wynika to z tego, e instrukcja return koczy wykonywanie funkcji. Jeeli wic return znajduje si w bloku instrukcji polecenia if, to wszystko, co jest po tym bloku instrukcji, zostanie wykonane tylko w przypadku niespenienia warunku z if-a (a wic tak, jakby po if bya instrukcja else). Pominicie instrukcji else skraca kod funkcji, ale moe take zmniejszy jej czytelno.

76

10. Rozwizania i wskazwki

Zadanie ??.?? Listing 10.38. Rozwizanie zadania ??.?? w jzyku C/C++


unsigned i n t NWD( unsigned i n t n , unsigned i n t m) { i f ( n == m) return m; i f ( n > m) return NWD( n% m, m) ; else return NWD(m , n ) ; %n }

W powyszej funkcji usunicie instrukcji else nie zmieni dziaania funkcji. Zadanie ??.?? Listing 10.39. Rozwizanie zadania ??.?? w jzyku C++
unsigned i n t pot ( unsigned i n t n , unsigned i n t m = 2 ) { i n t p=1; i f ( n == 0 ) return 0 ; f o r ( i n t i =1; i <= m; i ++) p=n ; return p ; }

Zadanie ??.?? Listing 10.40. Rozwizanie zadania ??.?? w jzyku C++


double pot ( double n , unsigned i n t m) { double p=1; i f ( n == 0 ) return 0 ; f o r ( i n t i =1; i <= m; i ++) p=n ; return p ; } i n t pot ( i n t n , unsigned i n t m) { i n t p=1; i f ( n == 0 ) return 0 ; f o r ( i n t i =1; i <= m; i ++) p=n ; return p ; }

10.5. Rozwizania do zada z rozdziau ??

77

unsigned i n t pot ( unsigned i n t n , unsigned i n t m) { unsigned i n t p=1; i f ( n == 0 ) return 0 ; f o r ( i n t i =1; i <= m; i ++) p=n ; return p ; }

10.5. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.41. Rozwizanie zadania ??.?? w jzyku C/C++
int mniejsza ( int a , int b ) { i f ( a<b ) return a ; else return b ; }

Zadanie to posiada take krtsze rozwizanie: Listing 10.42. Rozwizanie zadania ??.?? w jzyku C/C++
int mniejsza ( int a , int b ) { return ( a<b ) ? a : b ; }

Zadanie ??.?? Listing 10.43. Rozwizanie zadania ??.?? w jzyku C/C++


int mniejsza ( int a , int b ) { i f ( a<b ) return a ; else return b ; }

Zadanie ??.?? Listing 10.44. Rozwizanie zadania ??.?? w jzyku C/C++


void zamien ( i n t a , i n t b ) {

78
i n t pom ; pom=a ; a=b ; b=pom ; }

10. Rozwizania i wskazwki

Zadanie ??.?? Listing 10.45. Rozwizanie zadania ??.?? w jzyku C++


void zamien ( i n t & a , i n t & b ) { i n t pom ; pom=a ; a=b ; b=pom ; }

Zadanie ??.?? Rozwizanie w jzyku C: Listing 10.46. Rozwizanie zadania ??.?? w jzyku C
int alok u j ( ) { return m a l l o c ( s i z e o f ( i n t ) ) ; }

Uywajc funkcji malloc naley pamita o doczenia pliku nagwkowego <stdlib.h>. Jeeli si tego nie zrobi, kompilator zgosi ostrzeenie o prbie przypisania wartoci cakowitoliczbowej do zmiennej wskanikowej bez rzutowania. Rozwizanie w jzyku C++: Listing 10.47. Rozwizanie zadania ??.?? w jzyku C
int alok u j ( ) { return new i n t ; }

Zadanie ??.?? Rozwizanie w jzyku C: Listing 10.48. Rozwizanie zadania ??.?? w jzyku C
i n t a l o k u j ( unsigned i n t n ) { return m a l l o c ( n s i z e o f ( i n t ) ) ; }

Rozwizanie w jzyku C++:

10.6. Rozwizania do zada z rozdziau ?? Listing 10.49. Rozwizanie zadania ??.?? w jzyku C
i n t a l o k u j ( unsigned i n t n ) { return new i n t [ n ] ; }

79

W obu jzykach alokowanie w pamici jednowymiarowych tablic dynamicznych odbywa si w identyczny sposb jak w powyszych rozwizaniach. Zadanie ??.?? Listing 10.50. Rozwizanie zadania ??.?? w jzyku C/C++
double wywolaj ( double ( fun ) ( i n t a r g ) , i n t a ) { return fun ( a ) ; }

Zadanie ??.?? Listing 10.51. Rozwizanie zadania ??.?? w jzyku C/C++


void p r z e p i s z ( i n t const a , i n t b ) { b=a ; }

Zadanie ??.?? Listing 10.52. Rozwizanie zadania ??.?? w jzyku C/C++


void p r z e p i s z ( i n t const a , i n t const b ) { b=a ; }

10.6. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.53. Rozwizanie zadania ??.?? w jzyku C/C++
void z e r u j ( unsigned i n t n , i n t tab ) { int i ; f o r ( i =0; i <n ; i ++) tab [ i ] = 0 ; }

80

10. Rozwizania i wskazwki Warto zapamita, e w przypadku tablic przekazanych do funkcji w jej argumentach, wewntrz funkcji pracujemy na oryginaach tablic, a nie ich kopiach. Oznacza to, e zmiana wewntrz funkcji wartoci elementw takich tablic ma konsekwencje take na zewntrz funkcji. Jest to zachowanie odmienne od argumentw funkcji o typach prostych, w przypadku ktrych pracujemy na kopiach argumentw. Takie a nie inne zachowanie tablic wynika z faktu, e w C i C++ s one wskanikami na bloki pamici. Skopiowany wskanik cay czas wskazuje na ten sam blok pamici. Zadanie ??.?? Listing 10.54. Rozwizanie zadania ??.?? w jzyku C/C++
void i n i c j u j ( unsigned i n t n , i n t tab ) { int i ; f o r ( i =0; i <n ; i ++) tab [ i ]= i ; }

Zadanie ??.?? Listing 10.55. Rozwizanie zadania ??.?? w jzyku C/C++


double s r e d n i a ( unsigned i n t n , i n t tab ) { int i ; double s r e d =0; f o r ( i =0; i <n ; i ++) s r e d+=tab [ i ] ; s r e d /=n ; return s r e d ; }

Zastosowane powyej rozwizanie jest rozwiniciem metody zastosowanej w rozwizaniu zadania ??.??. Zadanie ??.?? Listing 10.56. Rozwizanie zadania ??.?? w jzyku C/C++
double s r e d n i a ( unsigned i n t n , const i n t tab ) { int i ; double s r e d =0; f o r ( i =0; i <n ; i ++) s r e d+=tab [ i ] ; s r e d /=n ; return s r e d ; }

10.6. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Listing 10.57. Rozwizanie zadania ??.?? w jzyku C
i n t p i e r w s z a ( unsigned i n t n ) { i n t i , j , pom ; bool s i t o [ n ] ; f o r ( i =0; i <n ; i ++) s i t o [ i ]= true ; f o r ( i =2; i <n ; i ++) if ( sito [ i ]) { pom=i ; f o r ( j =2 i ; j <n ; j+=i ) s i t o [ j ]= f a l s e ; } return pom ; }

81

W pierwszych standardach jzyka C nie byo typu bool. Zosta on wprowadzony dopiero w standardzie C99. Aby mc go uy, naley doczy plik nagwkowy stdbool.h. Rozwizanie w jzyku C++ nie rni si bardzo od powyszego. Istnieje jedna istotna rnica, ktra uzasadnia prezentacj rozwiza dla obu jzykw. Listing 10.58. Rozwizanie zadania ??.?? w jzyku C++
i n t p i e r w s z a ( unsigned i n t n ) { i n t pom ; bool s i t o = new bool [ n ] ; f o r ( i n t i =0; i <n ; i ++) s i t o [ i ]= true ; f o r ( i n t i =2; i <n ; i ++) if ( sito [ i ]) { pom=i ; f o r ( i n t j =2 i ; j <n ; j+=i ) s i t o [ j ]= f a l s e ; } delete [ ] s i t o ; return pom ; }

Jzyk C++, inaczej ni jzyk C, nie pozwala na tworzenie tablic automatycznych o rozmiarze zadanym przez zmienn. Std w tym przypadku pami dla tablicy sito rcznie rezerwowana operatorem new i rcznie zwalniana przy uyciu operatora delete. Usuwajc tablic naley doda [] po operatorze delete, a przed wskanikiem na tablic. W jzyku C++ zamiast

82

10. Rozwizania i wskazwki tablicy mona uy szablonu klasy vector, jednak w niniejszym zbiorze zada przedstawiona jest tylko strukturalna czci C++. Take w rozwizaniu w jzyku C mona rcznie zarezerwowa pami dla tablicy sito: Listing 10.59. Rozwizanie zadania ??.?? w jzyku C
i n t p i e r w s z a ( unsigned i n t n ) { i n t i , j , pom ; bool s i t o=m a l l o c ( n s i z e o f ( bool ) ) ; f o r ( i =0; i <n ; i ++) s i t o [ i ]= true ; f o r ( i =2; i <n ; i ++) if ( sito [ i ]) { pom=i ; f o r ( j =2 i ; j <n ; j+=i ) s i t o [ j ]= f a l s e ; } free ( sito ) ; return pom ; }

Jak mona zauway w Listingu ?? w jzyku C, inaczej ni ma to miejsce w C++, pami zajmowan przez tablic zwalnia si dokadnie w taki sam sposb, jak w przypadku typw prostych. Zadanie ??.?? Listing 10.60. Rozwizanie zadania ??.?? w jzyku C/C++
void p r z e p i s z ( unsigned i n t n , i n t tab1 , i n t tab2 ) { int i ; f o r ( i =0; i <n ; i ++) tab2 [ i ]= tab1 [ i ] ; }

Zadanie ??.?? Listing 10.61. Rozwizanie zadania ??.?? w jzyku C/C++


i n t maksimum ( unsigned i n t n , i n t tab ) { i n t i , max=tab [ 0 ] ; f o r ( i =1; i <n ; i ++) i f ( tab [ i ]>max) max=tab [ i ] ; return max ; }

10.6. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Listing 10.62. Rozwizanie zadania ??.?? w jzyku C/C++
i n t maksimum ( unsigned i n t n , i n t tab ) { i n t i , max=0; f o r ( i =1; i <n ; i ++) i f ( tab [ i ]> tab [ max ] ) max=i ; return max ; }

83

Zadanie ??.?? Listing 10.63. Rozwizanie zadania ??.?? w jzyku C/C++


void odwroc ( unsigned i n t n , i n t tab ) { i n t i , pom ; f o r ( i =0; i <n / 2 ; i ++){ pom=tab [ i ] ; tab [ i ]= tab [ n1 i ] ; tab [ n1 i ]=pom ; } }

W powyszym rozwizaniu wane jest, e zmienna i przebiega wartoci mniejsze od n/2. Gdyby i przebiegao wartoci od 0 do n1, wtedy kolejno elementw w tablicy zostaaby odwrcona dwukrotnie, a co za tym idzie, po zakoczeniu dziaania funkcji odwroc kolejno elementw tablicy tab pozostaaby niezmieniona. Zadanie ??.?? Listing 10.64. Rozwizanie zadania ??.?? w jzyku C/C++
void p r z e s u n ( unsigned i n t n , i n t tab ) { i n t i , pom=tab [ 0 ] ; f o r ( i =0; i <n1; i ++) tab [ i ]= tab [ i + 1 ] ; tab [ n1]=pom ; }

Kolejno, w jakiej zmienna i przebiega wartoci ze zbioru {0, . . . , n}, nie jest obojtna, o czym mona si przekona porwnujc powysze rozwizanie z rozwizaniem zadania ??.??

84 Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.65. Rozwizanie zadania ??.?? w jzyku C/C++


void p r z e s u n ( unsigned i n t n , i n t tab ) { i n t i , pom=tab [ n 1 ] ; f o r ( i=n2; i >=0; i ) tab [ i +1]= tab [ i ] ; tab [ 0 ] =pom ; }

Gdyby w powyszym programie zmienna i przebiegaa wartoci od 0 do n 2, tak jak ma to miejsce w programie ??, to w efekcie do wszystkich komrek tablicy tab, za wyjtkiem komrki tab[0], zostaaby wstawiona pierwotna warto komrki tab[0]. Zadanie ??.?? Istnieje wiele algorytmw sortujcych tablice. Poniej zaimplementowany zosta jeden z prostszych algorytmw. Jego idea jest nastpujca: wyszuka najwikszy element tablicy i zamieni go miejscami z ostatnim, po czym znale najwikszy element spord pierwszych n 1 elementw i zamieni go miejscami z elementem o indeksie n 1 etc. Listing 10.66. Rozwizanie zadania ??.?? w jzyku C/C++
i n t maksimum ( unsigned i n t n , i n t tab ) { i n t i , max=0; f o r ( i =1; i <n ; i ++) i f ( tab [ i ]> tab [ max ] ) max=i ; return max ; } void s o r t u j ( unsigned i n t n , i n t tab ) { i n t i , j , pom ; f o r ( i =0; i <n1; i ++){ j=maksimum ( ni , tab ) ; pom=tab [ ni 1 ] ; tab [ ni 1]= tab [ j ] ; tab [ j ]=pom ; } }

Co prawda niniejszy zbir zada nie obejmuje zagadnie z zakresu algorytmiki, ale mimo to, jako ciekawostk, przedstawiono poniej implementacj algorytmu sortowania przez scalanie. Dla duych tablic algorytm ten dziaa znacznie szybciej od tego przedstawionego w programie ??

10.6. Rozwizania do zada z rozdziau ?? Listing 10.67. Rozwizanie zadania ??.?? w jzyku C/C++
void merge ( i n t t a b l i c a , i n t s t a r t , i n t s r o d e k , i n t k o n i e c ) { i n t tab_pom [ k o n i e c s t a r t ] ; int i , j , k ; i = start ; k = 0; j = srodek + 1; while ( ( i <= s r o d e k )&&( j <= if ( tablica [ j ] < tablica tab_pom [ k ] = t a b l i c a j = j + 1; } else{ tab_pom [ k ] = t a b l i c a i = i + 1; } k = k + 1; } koniec ) ) { [ i ]){ [ j ];

85

[ i ];

i f ( i <= s r o d e k ) while ( i <= s r o d e k ) { tab_pom [ k ] = t a b l i c a [ i ] ; i = i + 1; k = k + 1; } else while ( j <= k o n i e c ) { tab_pom [ k ] = t a b l i c a [ j ] ; j = j + 1; k = k + 1; } f o r ( i= 0 ; i<=k o n i e c s t a r t ; i ++) t a b l i c a [ s t a r t + i ]= tab_pom [ i ] ; }

void merge_sort ( i n t t a b l i c a , i n t s t a r t , i n t k o n i e c ) { int srodek ; i f ( s t a r t != k o n i e c ) { srodek = ( s t a r t + koniec ) / 2; merge_sort ( t a b l i c a , s t a r t , s r o d e k ) ; merge_sort ( t a b l i c a , s r o d e k + 1 , k o n i e c ) ; merge ( t a b l i c a , s t a r t , s r o d e k , k o n i e c ) ; } } void s o r t u j ( unsigned i n t n , i n t tab ) { merge_sort ( tab , 0 , n1) ; }

86 Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.68. Rozwizanie zadania ??.?? w jzyku C


i n t a l o k u j ( unsigned i n t n ) { return m a l l o c ( n s i z e o f ( i n t ) ) ; }

Naley pamita, e w takiej sytuacji nie naley zwraca wskanika do tablicy utworzonej automatycznie, gdy przestaje ona istnie w momencie zakoczenia dziaania funkcji. Poniej rozwizanie dla jzyka C++ Listing 10.69. Rozwizanie zadania ??.?? w jzyku C++
i n t a l o k u j ( unsigned i n t n ) { return new i n t [ n ] ; }

Zadanie ??.?? Listing 10.70. Rozwizanie zadania ??.?? w jzyku C


void z w o l n i j ( i n t tab ) { f r e e ( tab ) ; }

To samo w jzyku C++: Listing 10.71. Rozwizanie zadania ??.?? w jzyku C++
void z w o l n i j ( i n t tab ) { delete [ ] tab ; }

10.7. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Najpierw wersja dla typu char: Listing 10.72. Rozwizanie zadania ??.?? w jzyku C/C++
i n t wy czy sc ( char nap ) { nap [ 0 ] = 0 ; }

Wersja dla typu wchar_t rni si niewiele:

10.7. Rozwizania do zada z rozdziau ?? Listing 10.73. Rozwizanie zadania ??.?? w jzyku C/C++
i n t wy czy sc (wchar_t nap ) { nap [ 0 ] = 0 ; }

87

Zadanie ??.?? Najpierw wersja dla typu char: Listing 10.74. Rozwizanie zadania ??.?? w jzyku C/C++
i n t d l u g o s c ( char nap ) { i n t i =0; while ( nap [ i ] ! = 0 ) i ++; return i ; }

Wersja dla typu wchar_t rni si niewiele: Listing 10.75. Rozwizanie zadania ??.?? w jzyku C/C++
i n t d l u g o s c (wchar_t nap ) { i n t i =0; while ( nap [ i ] ! = 0 ) i ++; return i ; }

Zadanie ??.?? Listing 10.76. Rozwizanie zadania ??.?? w jzyku C/C++


i n t porownaj ( char nap1 , char nap2 ) { int i ; f o r ( i =0;( nap1 [ i ] ! = 0 )&&(nap2 [ i ] ! = 0 ) ; i ++) i f ( nap1 [ i ] ! = nap2 [ i ] ) return ( nap1 [ i ]<nap2 [ i ] ) ? 1 : 0 ; i f ( nap1 [ i ] ! = 0 ) return 0 ; else return 1 ; }

W powyszym rozwizaniu wykorzystany zosta fakt, e w tablicy kodw ASCII mae aciskie litery s uoone zgodnie z porzdkiem alfabetycznym

88 Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.77. Rozwizanie zadania ??.?? w jzyku C/C++


void s k l e j ( char nap1 , char nap2 , char nap3 ) { int i , j ; f o r ( i =0; nap1 [ i ] ! = 0 ; i ++) nap3 [ i ]= nap1 [ i ] ; f o r ( j =0; nap2 [ j ] ! = 0 ; i ++, j ++) nap3 [ i ]= nap2 [ j ] ; nap3 [ i ] = 0 ; }

Wersja dla napisw o znakach typu wchar_t jest podobna. Zadanie ??.?? Listing 10.78. Rozwizanie zadania ??.?? w jzyku C/C++
void maleduze ( char nap ) { int i ; f o r ( i =0; nap [ i ] ! = 0 ; i ++) i f ( ( nap [ i ]>= a )&&(nap [ i ]<= z ) ) nap [ i ]=( a A ) ; }

Zadanie ??.?? Listing 10.79. Rozwizanie zadania ??.?? w jzyku C/C++


void w y t n i j ( char nap , i n t n , i n t m) { int i , dl ; f o r ( d l =0; nap [ d l ] ! = 0 ; d l++) ; i f ( d l+1>m) { f o r ( i =0; i+m l ; i ++) <d nap [ n+i ]=nap [ i+ m+ 1 ] ; } else i f ( ( n<d l )&&(d l+1<=m) ) nap [ n ] = 0 ; }

Wersja dla napisw o znakach typu wchar_t jest podobna.

10.7. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Listing 10.80. Rozwizanie zadania ??.?? w jzyku C/C++
bool porownaj ( char nap1 , char nap2 , i n t n ) { int i ; f o r ( i =0;( nap1 [ i ] ! = 0 )&&(nap2 [ i ] ! = 0 ) ; i ++) i f ( nap1 [ n+i ] ! = nap2 [ i ] ) return f a l s e ; i f ( nap2 [ i ]==0) return true ; else return f a l s e ; } void w y t n i j 2 ( char nap1 , char nap2 ) { int i , dl ; f o r ( d l =0; nap2 [ d l ] ! = 0 ; d l++) ; f o r ( i =0; nap1 [ i ] ! = 0 ; i ++) i f ( porownaj ( nap1 , nap2 , i ) ) { w y t n i j ( nap1 , i , i+dl 1) ; return ; } }

89

Uyta w powyszym rozwizaniu funkcja wytnij, to funkcja z rozwizania zadnia ??.??. Wersja dla napisw o znakach typu wchar_t jest podobna. Zadanie ??.?? Listing 10.81. Rozwizanie zadania ??.?? w jzyku C/C++
void wy tnijzw ( char nap1 , char nap2 ) { int i , dl ; i n t wyst [ 2 5 6 ] = { } ; f o r ( i =0; nap2 [ i ] ! = 0 ; i ++) wyst [ nap2 [ i ] ] = 1 ; f o r ( i =0 , j =0; nap1 [ i ] ! = 0 ; i ++) i f ( wyst [ nap1 [ i ]]==0) { i f ( j <i ) nap1 [ j ]=nap1 [ i ] ; j ++; } nap1 [ j ] = 0 ; }

90

10. Rozwizania i wskazwki Wersja dla typu wchar_t jest troch inna ze wzgldu na fakt, e tablica wyst musiaaby w tym przypadku by bardzo dua: Listing 10.82. Rozwizanie zadania ??.?? w jzyku C/C++
bool czy wy st (wchar_t z , wchar_t nap ) { int i ; f o r ( i =0; nap [ i ] ! = 0 ; i ++) i f ( nap [ i ]==z ) return true ; return f a l s e ; } void wy tnijzw (wchar_t nap1 , wchar_t nap2 ) { int i , j ; f o r ( i =0 , j =0; nap1 [ i ] ! = 0 ; i ++) i f ( ! czy wy st ( nap1 [ i ] , nap2 ) ) { i f ( j <i ) nap1 [ j ]=nap1 [ i ] ; j ++; } nap1 [ j ] = 0 ; }

Zadanie ??.?? Listing 10.83. Rozwizanie zadania ??.?? w jzyku C/C++


void wy tnijtm (wchar_t nap1 , wchar_t nap2 ) { int i , j ; f o r ( i =0 , j =0; nap1 [ i ] ! = 0 ; i ++) i f ( nap1 [ i ] ! = nap2 [ i ] ) { i f ( j <i ) nap1 [ j ]=nap1 [ i ] ; j ++; } nap1 [ j ] = 0 ; }

Wersja dla napisw o znakach typu char jest podobna. Zadanie ??.?? Wersja dla napisw o znakach typu char: Listing 10.84. Rozwizanie zadania ??.?? w jzyku C/C++
void wy pisz ( char nap ) { p r i n t f ( "%s " , nap ) ; }

10.7. Rozwizania do zada z rozdziau ?? Wersja dla napisw o znakach typu wchar_t: Listing 10.85. Rozwizanie zadania ??.?? w jzyku C/C++
void wy pisz (wchar_t nap ) { w p r i n t f (L"%l s " , nap ) ; }

91

Do wywietlania napisw o znakach typu wchar_t mona uy take funkcji printf: Listing 10.86. Rozwizanie zadania ??.?? w jzyku C/C++
void wy pisz (wchar_t nap ) { p r i n t f ( "%l s " , nap ) ; }

Rozwizania w jzyku C++: Listing 10.87. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz ( char nap ) { cout<<nap ; }

Wersja dla typu wchar_t w jzyku C++: Listing 10.88. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz (wchar_t nap ) { wcout<<nap ; }

W przeciwiestwie do jzyka C, gdzie funkcji printf mona uywa do wypisywania napisw o znakach typu wchar_t, w jzyku C++, aby operowa na takich napisach, trzeba uywa strumienia wcout zamiast cout. Zadanie ??.?? Wersja dla napisw typu string: Listing 10.89. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz ( s t r i n g s ) { cout<<s ; }

Wersja dla napisw typu wstring:

92

10. Rozwizania i wskazwki Listing 10.90. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz ( w s t r i n g s ) { wcout<<s ; }

Zadanie ??.?? Wersja dla napisw o znakach typu char: Listing 10.91. Rozwizanie zadania ??.?? w jzyku C/C++
void w c z y t a j ( char nap ) { s c a n f ( "%s " , nap ) ; }

Wersja dla napisw o znakach typu wchar_t: Listing 10.92. Rozwizanie zadania ??.?? w jzyku C/C++
void w c z y t a j (wchar_t nap ) { wscanf (L"%l s " , nap ) ; }

Do wczytywania napisw o znakach typu wchar_t mona uy take funkcji scanf: Listing 10.93. Rozwizanie zadania ??.?? w jzyku C/C++
void w c z y t a j (wchar_t nap ) { s c a n f ( "%l s " , nap ) ; }

Przy wczytywaniu napisw przy uyciu funkcji scanf nie pisze si znaku & przed zmienn, do ktrej wczytujemy warto. Jest tak dlatego, e zmienne tablicowe s wskanikami na bloki pamici zawierajce waciw tablic. Inn rzecz, o ktrej naley pamita, jest fakt, e wczytujc napis do tablicy naley zadba o to, eby tablica bya wystarczajcego rozmiaru. W praktyce jedynym sposobem na zapewnienie tego jest dodanie parametru przed specykatorami formatu s i ls w funkcjach scanf i wscanf, ktry ograniczy rozmiar wczytywanych napisw. Rozwizania w jzyku C++: Listing 10.94. Rozwizanie zadania ??.?? w jzyku C++
void w c z y t a j ( char nap ) { c i n >>nap ; }

10.7. Rozwizania do zada z rozdziau ?? Wersja dla typu wchar_t w jzyku C++: Listing 10.95. Rozwizanie zadania ??.?? w jzyku C++
void w c z y t a j (wchar_t nap ) { wcin>>nap ; }

93

W przeciwiestwie do jzyka C, gdzie funkcji scanf mona uywa do wczytywania napisw o znakach typu wchar_t, w jzyku C++, aby operowa na takich napisach, trzeba uywa strumienia wcin zamiast cin. Zadanie ??.?? Wersja dla napisw typu string: Listing 10.96. Rozwizanie zadania ??.?? w jzyku C++
void w c z y t a j ( s t r i n g& c i n >>s ; } s){

Wersja dla napisw typu wstring: Listing 10.97. Rozwizanie zadania ??.?? w jzyku C++
void w c z y t a j ( w s t r i n g& s ) { wcin>>s ; }

Zadanie ??.?? Wersja dla napisw o znakach typu char: Listing 10.98. Rozwizanie zadania ??.?? w jzyku C
char p i e r w s z y ( char tnap , i n t n ) { i n t i , min=0; char wyn ; f o r ( i =1; i <n ; i ++) i f ( stromo ( tnap [ min ] , tnap [ i ] ) >0) min=i ; wyn=m a l l o c ( ( s t r l e n ( tnap [ min ] ) +1) s i z e o f ( char ) ) ; s t r c p y ( wyn , tnap [ min ] ) ; return wyn ; }

Wersja dla napisw o znakach typu wchar_t: Listing 10.99. Rozwizanie zadania ??.?? w jzyku C
wchar_t p i e r w s z y (wchar_t tnap , i n t n ) { i n t i , min=0;

94

10. Rozwizania i wskazwki


wchar_t wyn ; f o r ( i =1; i <n ; i ++) i f ( wcscmp ( tnap [ min ] , tnap [ i ] ) >0) min=i ; wyn=m a l l o c ( ( w c s l e n ( tnap [ min ] ) +1) s i z e o f (wchar_t ) ) ; wcscpy ( wyn , tnap [ min ] ) ; return wyn ; }

Rozwizanie w jzyku C++ jest analogiczne. Wystarczy skorzysta z faktu, e funkcje biblioteczne jzyka C s dostpne rwnie w C++. Zadanie ??.?? Wersja dla napisw typu string: Listing 10.100. Rozwizanie zadania ??.?? w jzyku C
s t r i n g p i e r w s z y ( s t r i n g nap , i n t n ) { i n t i , min=0; f o r ( i =1; i <n ; i ++) i f ( nap [ min]>nap [ i ] ) min=i ; return nap [ min ] ; }

Wersja dla napisw typu wstring jest niemal identyczna. Zadanie ??.?? Wersja dla napisw o znakach typu char: Listing 10.101. Rozwizanie zadania ??.?? w jzyku C
char g o d z i n a ( i n t godz , i n t min , i n t s e k ) { char wyn=m a l l o c ( 9 s i z e o f ( char ) ) ; s p r i n t f ( wyn , "%02d:%02 d:%02 d" , godz , min , s e k ) ; return wyn ; }

Wersja dla napisw o znakach typu wchar_t: Listing 10.102. Rozwizanie zadania ??.?? w jzyku C
wchar_t g o d z i n a ( i n t godz , i n t min , i n t s e k ) { wchar_t wyn=m a l l o c ( 9 s i z e o f (wchar_t ) ) ; s w p r i n t f (wyn , 9 , L"%02d:%02 d:%02 d" , godz , min , s e k ) ; return wyn ; }

10.7. Rozwizania do zada z rozdziau ?? Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Wersja zwracajca napis o typie string: Listing 10.103. Rozwizanie zadania ??.?? w jzyku C++
s t r i n g g o d z i n a ( i n t godz , i n t min , i n t s e k ) { s t r i n g s t r e a m wyn ; wyn<<((godz <10) ? " 0 " : " " )<<godz ; wyn<<" : "<<((min<10) ? " 0 " : " " )<<min ; wyn<<" : "<<((sek <10) ? " 0 " : " " )<<s e k ; return wyn . s t r ( ) ; }

95

Wersja zwracajca napis o typie wstring: Listing 10.104. Rozwizanie zadania ??.?? w jzyku C++
wstring g o d z i n a ( i n t godz , i n t min , i n t s e k ) { w s t r i n g s t r e a m wyn ; wyn<<((godz <10) ?L" 0 " : L" " )<<godz ; wyn<<L" : "<<((min <10)?L" 0 " : L" " )<<min wyn<<L" : "<<((sek <10)?L" 0 " : L" " )<<s e k ; return wyn . s t r ( ) ; }

Zadanie ??.?? Wersja dla napisw o znakach typu char: Listing 10.105. Rozwizanie zadania ??.?? w jzyku C
char s k l e j ( char nap1 , char nap2 , char nap3 ) { char wyn=m a l l o c ( ( s t r l e n ( nap1 )+s t r l e n ( nap2 ) +s t r l e n ( nap3 ) +1) s i z e o f ( char ) ) ; s t r c p y ( wyn , nap1 ) ; s t r c a t ( wyn , nap2 ) ; s t r c a t ( wyn , nap3 ) ; return wyn ; }

Wersja dla napisw o znakach typu wchar_t: Listing 10.106. Rozwizanie zadania ??.?? w jzyku C
wchar_t s k l e j (wchar_t nap1 , wchar_t nap2 , wchar_t nap3 ) { wchar_t wyn=m a l l o c ( ( w c s l e n ( nap1 )+w c s l e n ( nap2 ) +w c s l e n ( nap3 ) +1) s i z e o f (wchar_t ) ) ; wcscpy ( wyn , nap1 ) ; w c s c a t ( wyn , nap2 ) ; w c s c a t ( wyn , nap3 ) ; return wyn ;

96
}

10. Rozwizania i wskazwki

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Wersja zwracajca napis o typie string: Listing 10.107. Rozwizanie zadania ??.?? w jzyku C++
s t r i n g s k l e j ( s t r i n g nap1 , s t r i n g nap2 , s t r i n g nap3 ) { return nap1+nap2+nap3 ; }

Rozwizanie dla napisw typu wstring jest podobne. Zadanie ??.?? Wersja dla napisw o znakach typu char: Listing 10.108. Rozwizanie zadania ??.?? w jzyku C/C++
void maleduze ( char nap ) { int i ; f o r ( i =0; nap [ i ] ! = 0 ; i ++) nap [ i ]= t o u p p e r ( nap [ i ] ) ; }

Wersja dla napisw o znakach typu wchar_t: jest bardzo podobna: Listing 10.109. Rozwizanie zadania ??.?? w jzyku C/C++
void maleduze (wchar_t nap ) { int i ; f o r ( i =0; nap [ i ] ! = 0 ; i ++) nap [ i ]= towupper ( nap [ i ] ) ; }

Zadanie ??.?? Wersja dla napisw typu string: Listing 10.110. Rozwizanie zadania ??.?? w jzyku C++
void maleduze ( s t r i n g& nap ) { f o r ( i n t i =0; i <nap . l e n g t h ( ) ; i ++) nap [ i ]= t o u p p e r ( nap [ i ] ) ; }

Wersja dla napisw typu wstring jest bardzo podobna. Listing 10.111. Rozwizanie zadania ??.?? w jzyku C++
void maleduze ( w s t r i n g & nap ) {

10.8. Rozwizania do zada z rozdziau ??


f o r ( i n t i =0; i <nap . l e n g t h ( ) ; i ++) nap [ i ]= towupper ( nap [ i ] ) ; }

97

10.8. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.112. Rozwizanie zadania ??.?? w jzyku C
i n t a l o k u j ( unsigned i n t n , unsigned i n t m) { i n t t=m a l l o c ( n s i z e o f ( i n t ) ) ; int i ; f o r ( i =0; i <n ; i ++) t [ i ]= m a l l o c (m s i z e o f ( i n t ) ) ; return t ; }

W jzyku C++ rozwizanie powyszego zadania wyglda nastpujco: Listing 10.113. Rozwizanie zadania ??.?? w jzyku C++
i n t a l o k u j ( unsigned i n t n , unsigned i n t m) { i n t t= new i n t [ n ] ; f o r ( i n t i =0; i <n ; i ++) t [ i ]= new i n t [m ] ; return t ; }

Zadanie ??.?? Listing 10.114. Rozwizanie zadania ??.?? w jzyku C


i n t ( a l o k u j ( unsigned i n t n , unsigned i n t m) ) [ ] { return m a l l o c ( n s i z e o f ( i n t [m] ) ) ; }

W jzyku C++ nie da si wprost rozwiza powyszego zadania ze wzgldu na brak moliwoci utworzenia w nim wielowymiarowych, w peni dynamicznych tablic, takich jak te w programie ??. Ten problem mona rozwiza tworzc klas zawierajc jednowymiarow tablic dynamiczn i przeciajc odpowiednie operatory. Nie mieci si to jednak w zakresie materiau obejmowanego przez niniejszy skrypt.

98 Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.115. Rozwizanie zadania ??.?? w jzyku C


void z w o l n i j ( unsigned i n t n , unsigned i n t m, i n t t ) { int i ; f o r ( i =0; i <n ; i ++) free ( t [ i ]) ; free (t) ; }

W jzyku C++ rozwizanie powyszego zadania wyglda nastpujco: Listing 10.116. Rozwizanie zadania ??.?? w jzyku C++
void z w o l n i j ( unsigned i n t n , unsigned i n t m, i n t t ) { f o r ( i n t i =0; i <n ; i ++) delete [ ] t [ i ] ; delete [ ] t ; }

Zadanie ??.?? Listing 10.117. Rozwizanie zadania ??.?? w jzyku C


void z w o l n i j ( unsigned i n t n , i n t t [ ] [ n ] ) { free (t) ; }

Zadanie ??.?? Listing 10.118. Rozwizanie zadania ??.?? w jzyku C


i n t a l o k u j ( unsigned i n t n ) { i n t t=m a l l o c ( n s i z e o f ( i n t ) ) ; int i ; f o r ( i =0; i <n ; i ++) t [ i ]= m a l l o c ( ( i +1) s i z e o f ( i n t ) ) ; return t ; }

W jzyku C++ rozwizanie powyszego zadania wyglda nastpujco: Listing 10.119. Rozwizanie zadania ??.?? w jzyku C++
i n t a l o k u j ( unsigned i n t n ) { i n t t= new i n t [ n ] ; f o r ( i n t i =0; i <n ; i ++) t [ i ]= new i n t [ i + 1 ] ; return t ;

10.8. Rozwizania do zada z rozdziau ??


}

99

Zadanie ??.?? Listing 10.120. Rozwizanie zadania ??.?? w jzyku C/C++


void z e r u j ( i n t t [ ] [ 1 0 0 ] , unsigned i n t n ) { int i , j ; f o r ( i =0; i <n ; i ++) f o r ( j =0; j <100; j ++) t [ i ] [ j ]=0; }

Zadanie ??.?? Listing 10.121. Rozwizanie zadania ??.?? w jzyku C/C++


void z e r u j ( i n t t , unsigned i n t n , unsigned i n t m) { int i , j ; f o r ( i =0; i <n ; i ++) f o r ( j =0; j < j ++) m; t [ i ] [ j ]=0; }

Zadanie ??.?? Listing 10.122. Rozwizanie zadania ??.?? w jzyku C


void z e r u j ( unsigned i n t n , unsigned i n t m, i n t t [ ] [ m] ) { int i , j ; f o r ( i =0; i <n ; i ++) f o r ( j =0; j < j ++) m; t [ i ] [ j ]=0; }

W powyszym rozwizaniu wane jest, eby deklaracja argumentu m wystpia przed deklaracj argumentu t (innym przypadku kompilator zgosi bd uycia niezadeklarowanej zmiennej m w deklaracji t). Zadanie ??.?? Listing 10.123. Rozwizanie zadania ??.?? w jzyku C/C++
i n t suma ( i n t t [ ] [ 1 0 0 ] [ 1 0 0 ] ) { i n t i , j , k , sum=0; f o r ( i =0; i <100; i ++) f o r ( j =0; j <100; j ++) f o r ( k =0;k <100; k++)

100
sum+=t [ i ] [ j ] [ k ] ; return sum ; }

10. Rozwizania i wskazwki

Zadanie ??.?? Listing 10.124. Rozwizanie zadania ??.?? w jzyku C/C++


i n t max_sred ( i n t t , unsigned i n t n , unsigned i n t m) { i n t i , j , sum , max ; double wart ; f o r ( i =0; i <n ; i ++){ sum=0; f o r ( j =0; j < j ++) m; sum+=t [ i ] [ j ] ; i f ( ( ( double ) sum/m >wart ) | | ( i ==0) ) { max=i ; wart =(double ) sum/m; } } return max ; }

Zadanie ??.?? Listing 10.125. Rozwizanie zadania ??.?? w jzyku C/C++


double max_sred ( i n t t , unsigned i n t n , unsigned i n t m) { i n t i , j , sum ; double wart ; f o r ( i =0; i <n ; i ++){ sum=0; f o r ( j =0; j < j ++) m; sum+=t [ i ] [ j ] ; i f ( ( ( double ) sum/m >wart ) | | ( i ==0) ) wart =(double ) sum/m; } return wart ; }

Zadanie ??.?? Listing 10.126. Rozwizanie zadania ??.?? w jzyku C/C++


void p r z e p i s z ( i n t t1 , i n t t2 , unsigned i n t n , unsigned i n t m) { int i , j ; f o r ( i =0; i <n ; i ++) f o r ( j =0; j < j ++) m; t 2 [ i ] [ j ]= t 1 [ i ] [ j ] ;

10.8. Rozwizania do zada z rozdziau ??


}

101

Zadanie ??.?? Listing 10.127. Rozwizanie zadania ??.?? w jzyku C/C++


void pom ( unsigned i n t n , i n t tab ) { int i , p ; f o r ( i =0; i <n / 2 ; i ++){ p=tab [ i ] ; tab [ i ]= tab [ n1 i ] ; tab [ n1 i ]=p ; } } void odwroc ( i n t t , unsigned i n t n , unsigned i n t m) { int i , j ; f o r ( i =0; i <n ; i ++) pom( n , t [ i ] ) ; }

W powyszym rozwizaniu wykorzystano struktur wielowymiarowych tablic tablic oraz rozwizanie zadania ??.??. Zadanie ??.?? Listing 10.128. Rozwizanie zadania ??.?? w jzyku C
void pom ( unsigned i n t n , unsigned i n t j , i n t tab [ ] [ n ] ) { int i , p ; f o r ( i =0; i <n / 2 ; i ++){ p=tab [ j ] [ i ] ; tab [ j ] [ i ]= tab [ j ] [ n1 i ] ; tab [ j ] [ n1 i ]=p ; } } void odwroc ( unsigned i n t n , unsigned i n t m, i n t t [ ] [ m] ) { unsigned i n t i , j ; f o r ( i =0; i <n ; i ++) pom( n , i , t ) ; }

Zadanie ??.?? Zadanie to mona rozwiza na kilka sposobw. Korzystajc z faktu, e funkcja dostaje jako argument tablic tablic mona po prostu przepi wskaniki do wierszy: Listing 10.129. Rozwizanie zadania ??.?? w jzyku C/C++

102

10. Rozwizania i wskazwki


void p r z e p n i j ( unsigned i n t n , unsigned i n t m, i n t t ) { int i ; i n t pom=t [ n 1 ] ; f o r ( i=n1; i >0; i ) t [ i ]= t [ i 1 ] ; t [ 0 ] =pom ; }

Powyszego rozwizania nie mona zastosowa w przypadku, gdy istnieje moliwo, e gdzie w programie przechowywany jest wskanik do pojedynczego wiersza przekazanej w argumencie tablicy. W takim przypadku trzeba przepisywa wartoci poszczeglnych elementw tablicy: Listing 10.130. Rozwizanie zadania ??.?? w jzyku C/C++
void p r z e p i s z ( unsigned i n t n , unsigned i n t m, i n t t ) { i n t i , j , pom ; f o r ( i =0; i < i ++){ m; pom=t [ n 1 ] [ i ] ; f o r ( j=n1; j >0; j ) t [ j ] [ i ]= t [ j 1 ] [ i ] ; t [ 0 ] [ i ]=pom ; } }

Drugie z zaprezentowanych rozwiza ma t zalet, e jest moliwe do zastosowania take w przypadku tablic dwuwymiarowych oraz atwo je zaadoptowa do zamiany miejscami kolumn. Zadanie ??.?? Listing 10.131. Rozwizanie zadania ??.?? w jzyku C/C++
void zamien ( unsigned i n t n , i n t tab ) { i n t i , j , k , pom ; f o r ( i =0; i <n ; i ++) f o r ( j=i ; j <n ; j ++){ i f ( i==j ) k=i ; else k=i +1; f o r ( ; k<n ; k++){ pom=tab [ i ] [ j ] [ k ] ; tab [ i ] [ j ] [ k]= tab [ j ] [ k ] [ i ] ; tab [ j ] [ k ] [ i ]= tab [ k ] [ i ] [ j ] ; tab [ k ] [ i ] [ j ]=pom ; } } }

10.8. Rozwizania do zada z rozdziau ??

103

Zadanie ??.?? Listing 10.132. Rozwizanie zadania ??.?? w jzyku C/C++


i n t pomnoz ( unsigned i n t n , i n t tab1 , i n t tab2 ) { int i , j , k ; i n t tab3=m a l l o c ( n s i z e o f ( i n t ) ) ; f o r ( i =0; i <n ; i ++) tab3 [ i ]= m a l l o c ( n s i z e o f ( i n t ) ) ; f o r ( i =0; i <n ; i ++) f o r ( j =0; j <n ; j ++){ tab3 [ i ] [ j ] = 0 ; f o r ( k =0;k<n ; k++) tab3 [ i ] [ j ]+=tab1 [ i ] [ k ] tab2 [ k ] [ j ] ; } return tab3 ; }

Zadanie ??.?? Listing 10.133. Rozwizanie zadania ??.?? w jzyku C


i n t utworz ( i n t n ) { i n t i , t=m a l l o c ( n s i z e o f ( i n t ) ) ; f o r ( i =0; i <n ; i ++) t [ i ]= m a l l o c ( n s i z e o f ( i n t ) ) ; return t ; } void usun ( i n t n , i n t t ) { int i ; f o r ( i =0; i <n ; i ++) free ( t [ i ]) ; free (t) ; } void p r z e p i s z ( i n t n , i n t m, i n t t1 , i n t t 2 ) { int i1 , i2 , j1 , j2 ; f o r ( i 1 =0 , i 2 =0; i 1 <n ; i 1 ++) i f ( i 1 !=m) { f o r ( j 1 =1 , j 2 =0; j 1 <n ; j 1 ++, j 2 ++) t 2 [ i 2 ] [ j 2 ]= t 1 [ i 1 ] [ j 1 ] ; i 2 ++; } } i n t wy znacznik ( unsigned i n t n , i n t tab ) { i n t i , j , wyz ;

104

10. Rozwizania i wskazwki


i n t t ; i f ( n==1) return tab [ 0 ] [ 0 ] ; wyz=0; t=utworz ( n1) ; f o r ( i =0; i <n ; i ++){ p r z e p i s z ( n , i , tab , t ) ; i f ( i %2==0) wyz+=tab [ i ] [ 0 ] wy znacznik ( n1 , t ) ; else wyz=tab [ i ] [ 0 ] wy znacznik ( n1 , t ) ; } usun ( n , t ) ; return wyz ; }

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.134. Rozwizanie zadania ??.?? w jzyku C/C++
void p r z e p i s z ( i n t n , i n t m, i n t t 1 [ ] [ n ] , i n t t 2 [ ] [ n 1]) { int i1 , i2 , j1 , j2 ; f o r ( i 1 =0 , i 2 =0; i 1 <n ; i 1 ++) i f ( i 1 !=m) { f o r ( j 1 =1 , j 2 =0; j 1 <n ; j 1 ++, j 2 ++) t 2 [ i 2 ] [ j 2 ]= t 1 [ i 1 ] [ j 1 ] ; i 2 ++; } } i n t wy znacznik ( unsigned i n t n , i n t tab [ ] [ n ] ) { i n t i , j , wyz ; int t [ n 1][n 1]; i f ( n==1) return tab [ 0 ] [ 0 ] ; wyz=0; f o r ( i =0; i <n ; i ++){ p r z e p i s z ( n , i , tab , t ) ; i f ( i %2==0) wyz+=tab [ i ] [ 0 ] wy znacznik ( n1 , t ) ; else wyz=tab [ i ] [ 0 ] wy znacznik ( n1 , t ) ; } return wyz ; }

10.9. Rozwizania do zada z rozdziau ??

105

10.9. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.135. Rozwizanie zadania ??.?? w jzyku C/C++
struct t r o j k a t { double a , b , c ; }; double obwod ( struct t r o j k a t t ) { return t . a+t . b+t . c ; }

Wan rzecz jest, eby nie zapomina o redniku po denicji typw zoonych. Komunikat kompilatora o bdzie w przypadku pominicia rednika moe mwi o bdzie w zupenie innym miejscu programu. W jzyku C++, nie trzeba powtarza sowa kluczowego struct przy deklaracji zmiennej majcej przechowywa wczeniej zdeniowan struktur, a wic rozwizanie w nim zadania mogoby wyglda nastpujco: Listing 10.136. Rozwizanie zadania ??.?? w jzyku C++
struct t r o j k a t { double a , b , c ; }; double obwod ( t r o j k a t t ) { return t . a+t . b+t . c ; }

W jzyku C, aby unikn powtarzania przed nazw typu sowa kluczowego struct (a take sw kluczowych union i enum), mona uy polecenia typedef: Listing 10.137. Rozwizanie zadania ??.?? w jzyku C/C++
struct t r o j k a t { double a , b , c ; }; typedef struct t r o j k a t t r o j ; double obwod ( t r o j t ) { return t . a+t . b+t . c ; }

106

10. Rozwizania i wskazwki Polecenia typedef mona uywa take w jzyku C++. Zadanie ??.?? Listing 10.138. Rozwizanie zadania ??.?? w jzyku C/C++
void p r z e p i s z ( struct t r o j k a t t r o j 1 , struct t r o j k a t t r o j 2 ) { t r o j 2=t r o j 1 ; }

Warto zauway, e wszystkie pola struktury s przepisywane za jednym zamachem. Zadanie ??.?? Listing 10.139. Rozwizanie zadania ??.?? w jzyku C/C++
struct punkt { double x , y , z ; }; double minimum ( struct punkt tab [ ] , i n t n ) { int i , j ; double pom , min=s q r t ( pow ( tab [ 1 ] . xtab [ 0 ] . x , 2 ) +pow ( tab [ 1 ] . ytab [ 0 ] . y , 2 ) +pow ( tab [ 1 ] . ztab [ 0 ] . z , 2 ) ) ; f o r ( i =0; i <n1; i ++) f o r ( j=i +1; j <n ; j ++){ pom=s q r t ( pow ( tab [ j ] . xtab [ i ] . x , 2 ) +pow ( tab [ j ] . ytab [ i ] . y , 2 ) +pow ( tab [ j ] . ztab [ i ] . z , 2 ) ) ; i f (pom<min ) min=pom ; } return min ; }

Zadanie ??.?? Listing 10.140. Rozwizanie zadania ??.?? w jzyku C/C++


void p r z e p i s z ( struct punkt tab1 [ ] , struct punkt tab2 [ ] , unsigned i n t n ) { int i ; f o r ( i =0; i <n ; i ++) tab2 [ i ]= tab1 [ i ] ; }

10.9. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Listing 10.141. Rozwizanie zadania ??.?? w jzyku C/C++
struct punkt10 { double t [ 1 0 ] ; }; void p r z e p i s z ( struct punkt10 tab1 [ ] , struct punkt10 tab2 [ ] , unsigned i n t n ) { int i ; f o r ( i =0; i <n ; i ++) tab2 [ i ]= tab1 [ i ] ; }

107

W zdeniowanej powyej funkcji przepisz caa struktura, a wic take caa zawarto pola t jest przepisywana przy uyciu pojedynczego operatora przypisania. Zadanie ??.?? Listing 10.142. Rozwizanie zadania ??.?? w jzyku C
struct punktn{ double t ; int w; }; void p r z e p i s z ( struct punktn tab1 [ ] , struct punktn tab2 [ ] , unsigned i n t n ) { int i , j ; f o r ( i =0; i <n ; i ++){ tab2 [ i ] . t=m a l l o c ( tab1 [ i ] . w s i z e o f ( double ) ) ; f o r ( j =0; j <tab1 [ i ] . w ; j ++) tab2 [ i ] . t [ j ]= tab1 [ i ] . t [ j ] ; } }

W tym przypadku naley tworzy i przepisywa tablice rcznie (operator przypisania dla struct punktn przepisaby wskanik, ale nie stworzyby nowej tablicy). Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.143. Rozwizanie zadania ??.?? w jzyku C/C++
struct l i s t a { int i ;

108
struct l i s t a wsk ; };

10. Rozwizania i wskazwki

Zadanie ??.?? Listing 10.144. Rozwizanie zadania ??.?? w jzyku C/C++


union s u p e r _ i n t { int i ; unsigned i n t u ; };

Zadanie ??.?? Listing 10.145. Rozwizanie zadania ??.?? w jzyku C


union L i c z b a { int i ; double d ; }; struct Dane{ i n t tp ; union L i c z b a zaw ; }; struct Dane w c z y t a j ( ) { struct Dane dane ; p r i n t f ( " J e z e l i c h c e s z podac l i c z b e c a l k o w i t a w p i s z 0\ n" ) ; p r i n t f ( " j e z e l i c h c e s z podac l i c z b e wymierna w p i s z 1\ n" ) ; s c a n f ( "%d" , dane . tp ) ; i f ( dane . tp==0){ p r i n t f ( " Wpisz l i c z b e c a l k o w i t a " ) ; s c a n f ( "%d" ,&dane . zaw . i ) ; } else{ p r i n t f ( " Wpisz l i c z b e wymierna " ) ; s c a n f ( "%l f " ,&dane . zaw . d ) ; } return dane ; }

W jzykach C i C++ rozrniane s due i mae litery. Dlatego w funkcji wczytaj moliwe byo zadeklarowanie zmiennej dane typu struct Dane. W praktyce nie naley uywa w programie nazw, ktre rni si tylko wielkoci liter. Uywanie w programie podobnych nazw zmiennych, funkcji etc. sprzyja robieniu przypadkowych i trudnych do wykrycia bdw.

10.9. Rozwizania do zada z rozdziau ?? Rozwizanie w jzyku C++ wyglda analogicznie. Zadanie ??.?? Listing 10.146. Rozwizanie zadania ??.?? w jzyku C/C++
struct t r o j k a t { double a , h ; }; struct p r o s t o k a t { double a , b ; }; struct t r a p e z { double a , b , h ; }; union wymiary { struct t r o j k a t t r o j , rown ; struct p r o s t o k a t p r o s t ; struct t r a p e z t r a p ; }; struct f i g u r a { union wymiary wym; int f i g ; }; double p o l e ( struct switch ( f . f i g ) { case 0 : return case 1 : return case 2 : return case 3 : return } } figura f ){ f f f f . wym. t r o j . a f . wym. t r o j . h / 2 ; . wym. p r o s t . a f . wym. p r o s t . b ; . wym. rown . a f . wym. rown . h ; . wym. t r a p . h ( f .wym. t r a p . a+f .wym. t r a p . b ) / 2 ;

109

W powyszym rozwizaniu pola rown i troj unii wymiary s tego samego typu. Jest to moliwe gdy do liczenia pl trjktw i rwnolegobokw potrzebne s te same wymiary (podstawa i wysoko). Zadanie ??.?? Listing 10.147. Rozwizanie zadania ??.?? w jzyku C/C++
enum c z w o r o k a t { kwadrat , p r o s t o k a t , romb , r o w n o l e g l o b o k , t r a p e z };

110

10. Rozwizania i wskazwki

Zadanie ??.?? Listing 10.148. Rozwizanie zadania ??.?? w jzyku C


enum P l e c { mezczyzna , k o b i e t a }; enum mezczyzna { wolny , zonaty }; enum k o b i e t a { wolna , mezatka }; union c z l o w i e k { enum mezczyzna m; enum k o b i e t a k ; }; struct dane_osobowe { char i m i e [ 3 0 ] ; char nazwisk o [ 3 0 ] ; enum P l e c p l e c ; union c z l o w i e k stan_cy wilny ; }; void w c z y t a j ( struct dane_osobowe tab [ ] , i n t n ) { int i , d ; f o r ( i =0; i <n ; i ++){ p r i n t f ( "Czy t e r a z wczytujemy dane k o b i e t y ( 1 ) " ) ; p r i n t f ( " czy mezczyzny ( 2 ) ? " ) ; s c a n f ( "%d" ,&d ) ; i f ( d==1) tab [ i ] . p l e c=k o b i e t a ; else tab [ i ] . p l e c=mezczyzna ; p r i n t f ( " podaj i m i e " ) ; s c a n f ( "%s " , tab [ i ] . i m i e ) ; p r i n t f ( " podaj nazwisk o " ) ; s c a n f ( "%s " , tab [ i ] . nazwisk o ) ; p r i n t f ( " podaj s t a n c y w i l n y " ) ; i f ( tab [ i ] . p l e c==k o b i e t a ) p r i n t f ( " ( wolna 0 , mezatka 1 ) " ) ;

10.9. Rozwizania do zada z rozdziau ??


else p r i n t f ( " ( wolny 0 , zonaty 1 ) " ) ; s c a n f ( "%d" ,& tab [ i ] . stan_cy wilny . k ) ; } }

111

Jak wida w powyszym rozwizaniu, typ wyliczeniowy mona wczytywa jak zmienne typu int. Ponadto niezalenie, czy wczytywane s dane kobiety czy mczyzny, wczytywane s dane do pola k w unii stan_cywilny typu union czowiek. Mona tak zrobi, gdy pola k i m znajduj si w tym samym miejscu w pamici, a wic wczytujc dane do jednego pola, zmienia si jednoczenie warto drugiego. Ponadto oba wspomniane pola s typw wyliczeniowych o tej samej liczbie zdeniowanych wartoci. Funkcja wczytaj w jzyku C++ moe wyglda nastpujco: Listing 10.149. Rozwizanie zadania ??.?? w jzyku C++
void w c z y t a j ( struct dane_osobowe tab [ ] , i n t n ) { int i , d ; f o r ( i =0; i <n ; i ++){ cout<<"Czy t e r a z wczytujemy dane k o b i e t y ( 1 ) " ; cout<<" czy mezczyzny ( 2 ) ? "<<e n d l ; c i n >>d ; i f ( d==1) tab [ i ] . p l e c=k o b i e t a ; else tab [ i ] . p l e c=mezczyzna ; cout<<" Podaj i m i e "<<e n d l ; c i n >>tab [ i ] . i m i e ; cout<<" Podaj nazwisk o "<<e n d l ; c i n >>tab [ i ] . nazwisk o ; cout<<" Podaj s t a n c y w i l n y "<<e n d l ; ; i f ( tab [ i ] . p l e c==k o b i e t a ) { cout<<" wolna 0 , mezatka 1 "<<e n d l ; c i n >>d ; i f ( d==0) tab [ i ] . stan_cy wilny . k=wolna ; else tab [ i ] . stan_cy wilny . k=mezatka ; } else{ cout<<" wolny 0 , zonaty 1 "<<e n d l ; c i n >>d ; i f ( d==0) tab [ i ] . stan_cy wilny .m =wolny ;

112

10. Rozwizania i wskazwki


else tab [ i ] . stan_cy wilny .m =zonaty ; } } }

Podstawow rnic w stosunku do rozwizania w jzyku C jest niemono wczytania wprost wartoci do zmiennej typu wyliczeniowego. Aby to zrobi, trzeba by przeciy operator >>, ale to nie mieci si w zakresie materiau niniejszego zbioru zada. Innym rozwizaniem mogoby by wczytanie wartoci typu int i zrzutowanie jej do typu wyliczeniowego. Podobnie jak w C, w jzyku C++ typy wyliczeniowe s domylnie wywietlane jako wartoci typu int. Zadanie ??.?? Listing 10.150. Rozwizanie zadania ??.?? w jzyku C/C++
union sup_int{ unsigned i n t l ; unsigned char t [ 4 ] ; };

Poprawno powyszego rozwizania jest zalena od uywanego kompilatora, gdy standard jzyka C nie okrela, z ilu bajtw ma si skada zmienna typu int. Typowy rozmiar typu int w systemach 32-bitowych to 4 bajty, std taki rozmiar tablicy t. Zadanie ??.?? Listing 10.151. Rozwizanie zadania ??.?? w jzyku C/C++
unsigned i n t f u n k c j a ( unsigned i n t a , unsigned i n t b ) { union sup_int poma , pomb , pomwyn ; poma . l=a ; pomb . l=b ; pomwyn . t [ 0 ] = poma . t [ 0 ] pomb . t [ 0 ] ; pomwyn . t [ 1 ] = poma . t [ 1 ] pomb . t [ 1 ] ; pomwyn . t [ 2 ] = poma . t [ 2 ] pomb . t [ 2 ] ; pomwyn . t [ 3 ] = poma . t [ 3 ] pomb . t [ 3 ] ; return pomwyn . l ; }

10.10. Rozwizania do zada z rozdziau ??

113

10.10. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.152. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t utworz ( ) { return NULL; }

Zadanie ??.?? Listing 10.153. Rozwizanie zadania ??.?? w jzyku C


void wy czy sc ( struct e l e m e n t L i s t a ) { struct e l e m e n t wsk=L i s t a ; while ( L i s t a !=NULL) { L i s t a=L i s t a >nex t ; f r e e ( wsk ) ; wsk=L i s t a ; } }

Rozwizanie w jzyku C++: Listing 10.154. Rozwizanie zadania ??.?? w jzyku C++
void wy czy sc ( e l e m e n t L i s t a ) { e l e m e n t wsk=L i s t a ; while ( L i s t a !=NULL) { L i s t a=L i s t a >nex t ; delete wsk ) ; wsk=L i s t a ; } }

Zadanie ??.?? Listing 10.155. Rozwizanie zadania ??.?? w jzyku C


struct e l e m e n t dodaj ( struct e l e m e n t L i s t a , i n t a ) { struct e l e m e n t wsk=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk>i=a ; wsk>nex t=L i s t a ; return wsk ; }

Rozwizanie w jzyku C++:

114

10. Rozwizania i wskazwki Listing 10.156. Rozwizanie zadania ??.?? w jzyku C++
e l e m e n t dodaj ( e l e m e n t L i s t a , i n t a ) { e l e m e n t wsk = new e l e m e n t ; wsk>i=a ; wsk>nex t=L i s t a ; return wsk ; }

Zadanie ??.?? Listing 10.157. Rozwizanie zadania ??.?? w jzyku C


struct e l e m e n t dodajk ( struct e l e m e n t L i s t a , i n t a ) { struct e l e m e n t wsk ; i f ( L i s t a==NULL) { L i s t a=wsk=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; } else{ wsk=L i s t a ; while ( wsk>nex t !=NULL) wsk=wsk>nex t ; wsk>nex t=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk=wsk>nex t ; } wsk>i=a ; wsk>nex t=NULL; return L i s t a ; }

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.158. Rozwizanie zadania ??.?? w jzyku C
struct e l e m e n t dodajw ( struct e l e m e n t L i s t a , struct e l e m e n t elem , i n t a ) { struct e l e m e n t wsk=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk>i=a ; i f ( elem==NULL) { wsk>nex t=L i s t a ; L i s t a=wsk ; } else{ wsk>nex t=elem>nex t ; elem>nex t=wsk ; } return L i s t a ; }

10.10. Rozwizania do zada z rozdziau ?? Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.159. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t z n a j d z ( struct e l e m e n t L i s t a , i n t a ) { while ( ( L i s t a !=NULL)&&(L i s t a >i !=a ) ) L i s t a=L i s t a >nex t ; return L i s t a ; }

115

W rozwizaniu wykorzystany zosta fakt, e w jzykach C i C++, jeeli pierwszy argument koniunkcji jest faszywy, to drugi nie jest ju sprawdzany (dziki temu w drugim argumencie koniunkcji mona zaoy, e Lista->i istnieje). Zadanie ??.?? Listing 10.160. Rozwizanie zadania ??.?? w jzyku C
struct e l e m e n t usun ( struct e l e m e n t L i s t a , i n t a ) { struct e l e m e n t wsk , wsk2 ; i f ( L i s t a==NULL) return L i s t a ; wsk=L i s t a ; i f ( L i s t a >i==a ) { L i s t a=L i s t a >nex t ; f r e e ( wsk ) ; } else { while ( ( wsk>nex t !=NULL)&&(wsk>next>i != a ) ) wsk=wsk>nex t ; i f ( wsk>nex t !=NULL) { wsk2=wsk>nex t ; wsk>nex t=wsk2>nex t ; f r e e ( wsk2 ) ; } } return L i s t a ; }

Rozwizanie w jzyku C++ jest analogiczne.

116 Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.161. Rozwizanie zadania ??.?? w jzyku C


struct e l e m e n t usunw ( struct e l e m e n t L i s t a , struct e l e m e n t elem ) { struct e l e m e n t wsk , wsk2 ; i f ( L i s t a==NULL) return L i s t a ; wsk=L i s t a ; i f ( L i s t a==elem ) { L i s t a=L i s t a >nex t ; f r e e ( wsk ) ; return L i s t a ; } while ( ( wsk>nex t !=NULL)&&(wsk>nex t != elem ) ) wsk=wsk>nex t ; i f ( wsk>nex t !=NULL) { wsk2=wsk>nex t ; wsk>nex t=wsk2>nex t ; f r e e ( wsk2 ) ; } return L i s t a ; }

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.162. Rozwizanie zadania ??.?? w jzyku C
struct e l e m e n t usunw2 ( struct e l e m e n t L i s t a , struct e l e m e n t elem ) { struct e l e m e n t wsk ; i f ( L i s t a==NULL) return L i s t a ; i f ( elem==NULL) { wsk=L i s t a ; L i s t a=L i s t a >nex t ; } e l s e i f ( elem>nex t==NULL) return L i s t a ; else{ wsk=elem>nex t ; elem>nex t=wsk>nex t ; }

10.10. Rozwizania do zada z rozdziau ??


f r e e ( wsk ) ; return L i s t a ; }

117

Zoono obliczeniowa powyszej funkcji jest mniejsza ni funkcji z Listingu ??. Z tego powodu operacje na listach w argumentach czsto wymagaj podania, zamiast wskanika na jaki element, wskanika do elementu poprzedniego. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.163. Rozwizanie zadania ??.?? w jzyku C
struct e l e m e n t utworz ( ) { struct e l e m e n t wsk=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk>nex t=NULL; return wsk ; }

Inaczej ni ma to miejsce w przypadku listy bez gowy, tworzenie pustej listy z gow wymaga wykonania pewnych prostych operacji. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.164. Rozwizanie zadania ??.?? w jzyku C
void wy czy sc ( struct e l e m e n t L i s t a ) { struct e l e m e n t wsk=L i s t a >nex t ; L i s t a=wsk ; while ( L i s t a !=NULL) { L i s t a=L i s t a >nex t ; f r e e ( wsk ) ; wsk=L i s t a ; } }

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.165. Rozwizanie zadania ??.?? w jzyku C
void dodaj ( struct e l e m e n t L i s t a , i n t a ) { struct e l e m e n t wsk=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk>i=a ;

118
wsk>nex t=L i s t a >nex t ; L i s t a >nex t=wsk ; }

10. Rozwizania i wskazwki

W przeciwiestwie do podobnego zadania dla list bez gowy, w przypadku list z gow funkcja nie musi zwraca wskanika do pocztku listy. Wynika to z tego, e w przypadku list z gow przed pierwszym element listy znajduje si gowa, do ktrej wskanik si nie zmienia. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.166. Rozwizanie zadania ??.?? w jzyku C
void dodajk ( struct e l e m e n t L i s t a , i n t a ) { struct e l e m e n t wsk=L i s t a ; while ( wsk>nex t !=NULL) wsk=wsk>nex t ; wsk>nex t=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk=wsk>nex t ; wsk>i=a ; wsk>nex t=NULL; }

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.167. Rozwizanie zadania ??.?? w jzyku C
void dodajw ( struct e l e m e n t L i s t a , struct e l e m e n t elem , int a ) { struct e l e m e n t wsk=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; wsk>i=a ; wsk>nex t=elem>nex t ; elem>nex t=wsk ; }

Naley zauway, e w powyszym rozwizaniu pierwszy argument (wskanik na gow listy) nie jest wykorzystywany.. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.168. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t z n a j d z ( struct e l e m e n t L i s t a , i n t a ) {

10.10. Rozwizania do zada z rozdziau ??


L i s t a=L i s t a >nex t ; while ( ( L i s t a !=NULL)&&(L i s t a >i !=a ) ) L i s t a=L i s t a >nex t ; return L i s t a ; }

119

Zadanie ??.?? Listing 10.169. Rozwizanie zadania ??.?? w jzyku C/C++


struct e l e m e n t z n a j d z p ( struct e l e m e n t L i s t a , i n t a ) { while ( ( L i s t a >nex t !=NULL)&&(L i s t a >next>i != a ) ) L i s t a=L i s t a >nex t ; return L i s t a ; }

Zadanie ??.?? Listing 10.170. Rozwizanie zadania ??.?? w jzyku C


void usun ( struct e l e m e n t L i s t a , i n t a ) { struct e l e m e n t wsk ; while ( ( L i s t a >nex t !=NULL)&&(L i s t a >next>i != a ) ) L i s t a=L i s t a >nex t ; i f ( L i s t a >nex t !=NULL) { wsk=L i s t a >nex t ; L i s t a >nex t=wsk>nex t ; f r e e ( wsk ) ; } }

Porwnujc powysze rozwizanie z rozwizaniem zadania ??.??, wida, o ile prostsze jest operowanie na listach z gow w stosunku do list bez gowy. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.171. Rozwizanie zadania ??.?? w jzyku C
void usunw ( struct e l e m e n t L i s t a , struct e l e m e n t elem ) { struct e l e m e n t wsk ; while ( ( L i s t a >nex t !=NULL)&&(L i s t a >nex t != elem ) ) L i s t a=L i s t a >nex t ; wsk=L i s t a >nex t ; L i s t a >nex t=wsk>nex t ; f r e e ( wsk ) ; }

120 Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.??

10. Rozwizania i wskazwki

Listing 10.172. Rozwizanie zadania ??.?? w jzyku C


void usunw2 ( struct e l e m e n t L i s t a , struct e l e m e n t elem ) { struct e l e m e n t wsk=elem>nex t ; elem>nex t=wsk>nex t ; f r e e ( wsk ) ; }

Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.173. Rozwizanie zadania ??.?? w jzyku C/C++
void z e r u j ( struct e l e m e n t L i s t a ) { while ( L i s t a !=NULL) { L i s t a >i =0; L i s t a=L i s t a >nex t ; } }

Wersja dla listy z gow: Listing 10.174. Rozwizanie zadania ??.?? w jzyku C/C++
void z e r u j ( struct e l e m e n t L i s t a ) { while ( L i s t a >nex t !=NULL) { L i s t a=L i s t a >nex t ; L i s t a >i =0; } }

Prostym sposobem uzyskania rozwizania zadania dla listy wskanikowej z gow jest dodanie jednego wiersza do rozwizania dedykowanego dla listy wskanikowej bez gowy: Listing 10.175. Rozwizanie zadania ??.?? w jzyku C/C++
void z e r u j ( struct e l e m e n t L i s t a ) { L i s t a=L i s t a >nex t ; while ( L i s t a !=NULL) { L i s t a >i =0; L i s t a=L i s t a >nex t ; } }

10.10. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.176. Rozwizanie zadania ??.?? w jzyku C/C++
struct t r o j k a { unsigned i n t a , b , c ; struct t r o j k a nex t ; }; bool t r ( struct t r o j k a e ) { i f ( e>a e>a + e>b e>b == e>c e>c ) return true ; else return f a l s e ; } struct t r o j k a p i t a g o r a s ( struct t r o j k a L i s t a ) { struct t r o j k a pom , pom2 ; while ( ( L i s t a !=NULL) &&(! t r ( L i s t a ) ) ) { pom=L i s t a ; L i s t a=L i s t a >nex t ; f r e e (pom) ; } i f ( L i s t a==NULL) return NULL; pom=L i s t a ; while (pom>nex t !=NULL) { i f ( t r (pom>nex t ) ) pom=pom>nex t ; else{ pom2=pom>nex t ; pom>nex t=pom2>nex t ; f r e e ( pom2 ) ; } } return L i s t a ; }

121

Rozwizanie dla listy z gow rni si tylko funkcj pitagoras: Listing 10.177. Rozwizanie zadania ??.?? w jzyku C/C++
void p i t a g o r a s ( struct t r o j k a L i s t a ) { struct t r o j k a pom ; while ( L i s t a >nex t !=NULL) { i f ( t r ( L i s t a >nex t ) ) L i s t a=L i s t a >nex t ; else{ pom=L i s t a >nex t ; L i s t a >nex t=pom>nex t ; f r e e (pom) ;

122
} } }

10. Rozwizania i wskazwki

Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.178. Rozwizanie zadania ??.?? w jzyku C/C++
i n t suma ( struct e l e m e n t L i s t a ) { i n t sum=0; while ( L i s t a !=NULL) { sum+=L i s t a >i ; L i s t a=L i s t a >nex t ; } return sum ; }

Wersja dla listy z gow jest podobna: Listing 10.179. Rozwizanie zadania ??.?? w jzyku C/C++
i n t suma ( struct e l e m e n t L i s t a ) { i n t sum=0; L i s t a=L i s t a >nex t ; while ( L i s t a !=NULL) { sum+=L i s t a >i ; L i s t a=L i s t a >nex t ; } return sum ; }

Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.180. Rozwizanie zadania ??.?? w jzyku C/C++
i n t minimum ( struct e l e m e n t L i s t a ) { i n t min=L i s t a >i ; while ( L i s t a !=NULL) { i f ( L i s t a >i <min ) min=L i s t a >i ; L i s t a=L i s t a >nex t ; } return min ; }

Wersja dla listy z gow jest podobna: Listing 10.181. Rozwizanie zadania ??.?? w jzyku C/C++

10.10. Rozwizania do zada z rozdziau ??


i n t minimum ( struct e l e m e n t L i s t a ) { i n t min=L i s t a >next>i ; while ( L i s t a >nex t !=NULL) { L i s t a=L i s t a >nex t ; i f ( L i s t a >i <min ) min=L i s t a >i ; } return min ; }

123

Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.182. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t minimum ( struct e l e m e n t L i s t a ) { struct e l e m e n t min=L i s t a ; while ( L i s t a !=NULL) { i f ( L i s t a >i <min>i ) min=L i s t a ; L i s t a=L i s t a >nex t ; } return min ; }

Wersja dla listy z gow jest podobna. Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.183. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t minimum ( struct e l e m e n t L i s t a ) { struct e l e m e n t min=NULL, pom ; i f ( ( L i s t a==NULL) | | ( L i s t a >nex t==NULL) ) return NULL; pom=L i s t a ; while (pom>nex t !=NULL) { i f ( ( ( min== NULL)&&(pom>next>i <L i s t a >i ) ) | | ( ( min!=NULL)&&(pom>next>i <min>next>i ) ) ) min=pom ; pom=pom>nex t ; } return min ; }

Wersja dla listy z gow jest prostsza: Listing 10.184. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t minimum ( struct e l e m e n t L i s t a ) {

124

10. Rozwizania i wskazwki


struct e l e m e n t min=L i s t a ; while ( L i s t a >nex t !=NULL) { i f ( L i s t a >next>i <min>next>i ) min=L i s t a ; L i s t a=L i s t a >nex t ; } return min ; }

Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.185. Rozwizanie zadania ??.?? w jzyku C/C++
i n t maks_rozn ( struct e l e m e n t L i s t a ) { struct e l e m e n t pom ; i n t maks=abs ( L i s t a >i L i s t a >next>i ) ; f o r ( ; L i s t a >nex t !=NULL; L i s t a=L i s t a >nex t ) f o r (pom=L i s t a >nex t ; pom!=NULL; pom=pom>nex t ) i f ( abs (pom>i L i s t a >i )<maks ) maks=abs (pom>i L i s t a >i ) ; return maks ; }

Powysze rozwizanie polega na przeszukaniu wszystkich par elementw listy. Efektywniejsze obliczeniowo byoby znalezienie elementw o najmniejszej i najwikszej wartoci pola i, i zwrcenie ich rnicy. Wersja dla listy z gow jest podobna. Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.186. Rozwizanie zadania ??.?? w jzyku C
struct e l e m e n t k o p i u j ( struct e l e m e n t L i s t a ) { struct e l e m e n t k opia , pom ; i f ( L i s t a==NULL) return NULL; k o p i a=m a l l 0 c ( s i z e o f ( struct e l e m e n t ) ) ; pom=k o p i a ; pom>i=L i s t a >i ; L i s t a=L i s t a >nex t ; while ( L i s t a !=NULL) { pom>nex t=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; pom=pom>nex t ; pom>i=L i s t a >i ; L i s t a=L i s t a >nex t ; } pom>nex t=NULL; return k o p i a ; }

10.10. Rozwizania do zada z rozdziau ?? Uwany czytelnik atwo przerobi powysze rozwizanie na rozwizanie w jzyku C++ oraz na rozwizanie dla listy wskanikowej z gow. Zadanie ??.?? Listing 10.187. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t s k l e j ( struct e l e m e n t L i s t a 1 , struct e l e m e n t L i s t a 2 ) { struct e l e m e n t pom ; i f ( L i s t a 1==NULL) return L i s t a 2 ; pom=L i s t a 1 ; while (pom>nex t !=NULL) pom=pom>nex t ; pom>nex t=L i s t a 2 ; return L i s t a 1 ; }

125

Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.188. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t odwroc ( struct e l e m e n t L i s t a ) { struct e l e m e n t pom1 , pom2 ; i f ( ( L i s t a==NULL) | | ( L i s t a >nex t==NULL) ) return L i s t a ; pom1=L i s t a >nex t ; pom2=pom1>nex t ; L i s t a >nex t=NULL; pom1>nex t=L i s t a ; while ( pom2!=NULL) { L i s t a=pom1 ; pom1=pom2 ; pom2=pom2>nex t ; pom1>nex t=L i s t a ; } return pom1 ; }

Wersja dla listy z gow jest podobna. Zadanie ??.?? Listing 10.189. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t p o l a c z ( struct e l e m e n t L i s t a 1 , struct e l e m e n t L i s t a 2 ) { struct e l e m e n t pom , pom2 ; i f ( L i s t a 1==NULL)

126
return NULL; pom=pom2=L i s t a 1 ; L i s t a 1=L i s t a 1 >nex t ; pom2>nex t=L i s t a 2 ; pom2=L i s t a 2 ; L i s t a 2=L i s t a 2 >nex t ; while ( L i s t a 1 !=NULL) { pom2>nex t=L i s t a 1 ; pom2=L i s t a 1 ; L i s t a 1=L i s t a 1 >nex t ; pom2>nex t=L i s t a 2 ; pom2=L i s t a 2 ; L i s t a 2=L i s t a 2 >nex t ; } return pom ; }

10. Rozwizania i wskazwki

Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.190. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t p r z e s u n ( struct e l e m e n t L i s t a ) { struct e l e m e n t pom ; i f ( ( L i s t a==NULL) | | ( L i s t a >nex t==NULL) ) return L i s t a ; pom=L i s t a ; while ( L i s t a >next>nex t !=NULL) L i s t a=L i s t a >nex t ; L i s t a >next>nex t=pom ; pom=L i s t a >nex t ; L i s t a >nex t=NULL; return pom ; }

Wersja dla listy z gow jest podobna. Zadanie ??.?? Wersja dla listy bez gowy: Listing 10.191. Rozwizanie zadania ??.?? w jzyku C
bool w y s t e p u j e ( struct e l e m e n t L i s t a , i n t i ) { while ( L i s t a !=NULL) { i f ( L i s t a >i==i ) return true ; L i s t a=L i s t a >nex t ; } return f a l s e ; } struct e l e m e n t powtorzone ( struct e l e m e n t L i s t a 1 ,

10.10. Rozwizania do zada z rozdziau ??


struct e l e m e n t L i s t a 2 ) { struct e l e m e n t L i s t a 3=NULL, pom, pom2 ; i f ( ( L i s t a 1== NULL) | | ( L i s t a 2== NULL) ) return NULL; pom=L i s t a 1 ; while (pom!=NULL) { i f ( ( w y s t e p u j e ( L i s t a 2 , pom>i ) ) &&(! w y s t e p u j e ( L i s t a 3 , pom>i ) ) ) { i f ( L i s t a 3==NULL) pom2=L i s t a 3=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; else{ pom2>nex t=m a l l o c ( s i z e o f ( struct e l e m e n t ) ) ; pom2=pom2>nex t ; } pom2>i=pom>i ; } pom=pom>nex t ; } pom2>nex t=NULL; return L i s t a 3 ; }

127

Uwany czytelnik szybko stworzy wersj dla listy z gow. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Tym razem zaprezentowany zostanie prosty algorytm sortujcy dla listy z gow: Listing 10.192. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t minimum ( struct e l e m e n t L i s t a ) { struct e l e m e n t min=L i s t a ; while ( L i s t a >nex t !=NULL) { i f ( L i s t a >next>i <min>next>i ) min=L i s t a ; L i s t a=L i s t a >nex t ; } return min ; } void s o r t ( struct e l e m e n t L i s t a ) { struct e l e m e n t pom, pom2 ; while ( L i s t a >nex t !=NULL) { pom=minimum ( L i s t a ) ; i f (pom!= L i s t a ) { pom2=pom>nex t ; pom>nex t=pom2>nex t ; pom2>nex t=L i s t a >nex t ; L i s t a >nex t=pom2 ; }

128
L i s t a=L i s t a >nex t ; } }

10. Rozwizania i wskazwki

Podobnie jak miao to miejsce w przypadku rozwizania zadania ???? dotyczcego sortowania elementw tablic jednowymiarowych, take tym razem zostanie przedstawione nieco bardziej skomplikowany w implementacji ale te bardziej efektywny algorytm sortujcy (w wersji dla list bez gowy): Listing 10.193. Rozwizanie zadania ??.?? w jzyku C/C++
struct e l e m e n t merge ( struct e l e m e n t L i s t a 1 , struct e l e m e n t L i s t a 2 ) { struct e l e m e n t pom , pom2 ; i f ( L i s t a 1 >i <L i s t a 2 >i ) { pom=pom2=L i s t a 1 ; L i s t a 1=L i s t a 1 >nex t ; } else{ pom=pom2=L i s t a 2 ; L i s t a 2=L i s t a 2 >nex t ; } while ( ( L i s t a 1 !=NULL)&&(L i s t a 2 !=NULL) ) i f ( L i s t a 1 >i <L i s t a 2 >i ) { pom2>nex t=L i s t a 1 ; L i s t a 1=L i s t a 1 >nex t ; pom2=pom2>nex t ; } else{ pom2>nex t=L i s t a 2 ; L i s t a 2=L i s t a 2 >nex t ; pom2=pom2>nex t ; } i f ( L i s t a 1 !=NULL) pom2>nex t=L i s t a 1 ; else pom2>nex t=L i s t a 2 ; return pom ; }

struct e l e m e n t m e r g e s o r t ( struct e l e m e n t L i s t a ) { struct e l e m e n t pom1 , pom2 , l 1 , l 2 ; unsigned i n t i =0; i f ( ( L i s t a==NULL) | | ( L i s t a >nex t==NULL) ) return L i s t a ; l 1=pom1=L i s t a ; l 2=pom2=L i s t a >nex t ; L i s t a=L i s t a >next>nex t ; while ( L i s t a !=NULL) {

10.11. Rozwizania do zada z rozdziau ??


i f ( i %2){ pom1>nex t=L i s t a ; pom1=pom1>nex t ; } else{ pom2>nex t=L i s t a ; pom2=pom2>nex t ; } i ++; L i s t a=L i s t a >nex t ; } pom1>nex t=NULL; pom2>nex t=NULL; l 1=m e r g e s o r t ( l 1 ) ; l 2=m e r g e s o r t ( l 2 ) ; l 1=merge ( l 1 , l 2 ) ; return l 1 ; }

129

10.11. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Program w wersji dla jzyka C: Listing 10.194. Rozwizanie zadania ??.?? w jzyku C
FILE otworz ( char p l i k ) { return f o p e n ( p l i k , " r " ) ; }

Program w wersji dla jzyka C++: Listing 10.195. Rozwizanie zadania ??.?? w jzyku C++
f s t r e a m otworz ( char p l i k ) { return new f s t r e a m ( p l i k , i o s : : i n ) ; }

Warto zapamita, e w powyszym rozwizaniu funkcja otworz nie mogaby zwrci wartoci strumienia fstream ze wzgldu na to, e nie posiada on konstruktora kopiujcego, ani nie mona zdeniowa dla niego operatora przypisania. Funkcja otworz mogaby zwrci referencj do strumienia, ale w ten sposb program straciby wskanik do niego i nie mgby go w przyszoci usun z pamici. Zadanie ??.?? Rozwizanie w wersji dla jzyka C:

130

10. Rozwizania i wskazwki Listing 10.196. Rozwizanie zadania ??.?? w jzyku C


void wy pisz ( FILE p l i k ) { char c ; while ( f s c a n f ( p l i k , "%c " ,& c )==1) p r i n t f ( "%c " , c ) ; fclose ( plik ) ; }

Rozwizanie w wersji dla jzyka C++: Listing 10.197. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz ( f s t r e a m& p l i k ) { char c ; while ( ! p l i k . e o f ( ) ) { p l i k . get ( c ) ; if (! plik . eof () ) cout<<c ; } plik . close () ; }

Zadanie ??.?? Rozwizanie w wersji dla jzyka C i znakw typu char: Listing 10.198. Rozwizanie zadania ??.?? w jzyku C
void wy pisz ( char s c i e z k a ) { FILE p l i k=f o p e n ( s c i e z k a , " r " ) ; char c ; while ( f s c a n f ( p l i k , "%c " ,& c )==1) if (! isspace ( c ) ) p r i n t f ( "%c " , c ) ; fclose ( plik ) ; }

Rozwizanie w wersji dla jzyka C i znakw typu wchar_t Listing 10.199. Rozwizanie zadania ??.?? w jzyku C
void wy pisz ( char s c i e z k a ) { FILE p l i k=f o p e n ( s c i e z k a , " r " ) ; wchar_t c ; while ( f s c a n f ( p l i k , "%l c " ,& c )==1) i f ( ! iswspace ( c ) ) p r i n t f ( "%l c " , c ) ; fclose ( plik ) ; }

Rozwizanie w wersji dla jzyka C++ i znakw typu char:

10.11. Rozwizania do zada z rozdziau ?? Listing 10.200. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz ( char s c i e z k a ) { fstream p l i k ( sciezka , i o s : : in ) ; char c ; while ( ! p l i k . e o f ( ) ) { p l i k >>c ; if (! plik . eof () ) cout<<c ; } plik . close () ; }

131

W programie ?? nie ma koniecznoci zamykania pliku rcznie, tak jak jest to zrobione. Zrobiby to destruktor obiektu plik przy wyjciu z funkcji wypisz. Rczne zamykanie pliku w takiej sytuacji ma sens wtedy, kiedy do zakoczenia dziaania funkcji zostao jeszcze duo czasu lub gdy program ma ledzi, czy przy zamykaniu pliku nie wystpi bd. Rozwizanie w wersji dla jzyka C++ i znakw typu wchar_t: Listing 10.201. Rozwizanie zadania ??.?? w jzyku C++
void wy pisz ( char s c i e z k a ) { wfstream p l i k ( s c i e z k a , i o s : : i n ) ; wchar_t c ; while ( ! p l i k . e o f ( ) ) { p l i k >>c ; if (! plik . eof () ) wcout<<c ; } }

Warto zapamita rnic pomidzy metod get a operatorem >>. Metoda get wyuskuje kolejne znaki, natomiast operator >> pomija biae znaki. Zadanie ??.?? Rozwizanie w wersji dla jzyka C i znakw typu char: Listing 10.202. Rozwizanie zadania ??.?? w jzyku C
i n t w y s t a p i e n ( char s c i e z k a , char c ) { char pom ; i n t l i c z =0; FILE p l i k=f o p e n ( s c i e z k a , " r " ) ; while ( f s c a n f ( p l i k , "%c " ,&pom)==1) i f ( c==pom) l i c z ++; fclose ( plik ) ; return l i c z ; }

132

10. Rozwizania i wskazwki Rozwizanie w wersji dla jzyka C++ i znakw typu char: Listing 10.203. Rozwizanie zadania ??.?? w jzyku C++
i n t w y s t a p i e n ( const char s c i e z k a , char c ) { char pom ; i n t l i c z =0; fstream p l i k ( sciezka , i o s : : in ) ; while ( ! p l i k . e o f ( ) ) { p l i k . g e t (pom) ; i f ( ( ! p l i k . e o f ( ) )&&(c==pom) ) l i c z ++; } return l i c z ; }

Rozwizanie dla znakw typu wchar_t jest analogiczne. Zadanie ??.?? Rozwizanie w wersji dla jzyka C i znakw typu char: Listing 10.204. Rozwizanie zadania ??.?? w jzyku C
i n t porownaj ( char s c i e z k a 1 , char s c i e z k a 2 ) { char c1 , c2 ; FILE p l i k 1=f o p e n ( s c i e z k a 1 , " r " ) ; FILE p l i k 2=f o p e n ( s c i e z k a 2 , " r " ) ; f s c a n f ( p l i k 1 , "%c " ,& c1 ) ; f s c a n f ( p l i k 2 , "%c " ,& c2 ) ; while ( ( ! f e o f ( p l i k 1 ) ) &&(! f e o f ( p l i k 2 ) ) ) { i f ( c1 != c2 ) return 0 ; f s c a n f ( p l i k 1 , "%c " ,& c1 ) ; f s c a n f ( p l i k 2 , "%c " ,& c2 ) ; } i f ( ( ! feof ( plik1 ) ) | | ( ! feof ( plik2 ) ) ){ fclose ( plik1 ) ; fclose ( plik2 ) ; return 0 ; } else{ fclose ( plik1 ) ; fclose ( plik2 ) ; return 1 ; } }

10.11. Rozwizania do zada z rozdziau ?? Rozwizanie w wersji dla jzyka C++ i znakw typu char: Listing 10.205. Rozwizanie zadania ??.?? w jzyku C++
i n t porownaj ( char s c i e z k a 1 , char s c i e z k a 2 ) { char c1= \0 , c2= \0 ; fstream p lik 1 ( sciezka1 , i o s : : in ) ; fstream p lik 2 ( sciezka2 , i o s : : in ) ; while ( ( ! p l i k 1 . e o f ( ) ) &&(! p l i k 2 . e o f ( ) ) ) { p l i k 1 . g e t ( c1 ) ; p l i k 2 . g e t ( c2 ) ; i f ( c1 != c2 ) return 0 ; } i f ( ( ! plik1 . eof () ) | | ( ! plik2 . eof () ) ) return 0 ; else return 1 ; }

133

Rozwizanie dla znakw typu wchar_t jest analogiczne. Zadanie ??.?? Rozwizanie w wersji dla jzyka C i znakw typu char: Listing 10.206. Rozwizanie zadania ??.?? w jzyku C
i n t porownaj ( char s c i e z k a 1 , char s c i e z k a 2 ) { char c1 , c2 ; FILE p l i k 1=f o p e n ( s c i e z k a 1 , " r " ) ; FILE p l i k 2=f o p e n ( s c i e z k a 2 , " r " ) ; while ( ( f s c a n f ( p l i k 1 , "%c " ,& c1 )==1)&&( i s s p a c e ( c1 ) ) ) ; while ( ( f s c a n f ( p l i k 2 , "%c " ,& c2 )==1)&&( i s s p a c e ( c2 ) ) ) ; while ( ( ! f e o f ( p l i k 1 ) ) &&(! f e o f ( p l i k 2 ) ) ) { i f ( c1 != c2 ) return 0 ; while ( ( f s c a n f ( p l i k 1 , "%c " ,& c1 )==1)&&( i s s p a c e ( c1 ) ) ) ; while ( ( f s c a n f ( p l i k 2 , "%c " ,& c2 )==1)&&( i s s p a c e ( c2 ) ) ) ; } i f ( ( ! feof ( plik1 ) ) | | ( ! feof ( plik2 ) ) ){ fclose ( plik1 ) ; fclose ( plik2 ) ; return 0 ; } else{ fclose ( plik1 ) ; fclose ( plik2 ) ; return 1 ; } }

Rozwizanie w wersji dla jzyka C++ i znakw typu char:

134

10. Rozwizania i wskazwki Listing 10.207. Rozwizanie zadania ??.?? w jzyku C++
i n t porownaj ( char s c i e z k a 1 , char s c i e z k a 2 ) { char c1= \0 , c2= \0 ; fstream p lik 1 ( sciezka1 , i o s : : in ) ; fstream p lik 2 ( sciezka2 , i o s : : in ) ; while ( ( ! p l i k 1 . e o f ( ) ) &&(! p l i k 2 . e o f ( ) ) ) { p l i k 1 >>c1 ; p l i k 2 >>c2 ; i f ( c1 != c2 ) return 0 ; } i f ( ( ! plik1 . eof () ) | | ( ! plik2 . eof () ) ) return 0 ; else return 1 ; }

Rozwizanie dla typu znakw wchar_t jest analogiczne. Zadanie ??.?? Rozwizanie dla jzyka C: Listing 10.208. Rozwizanie zadania ??.?? w jzyku C
FILE otworz ( char p l i k ) { return f o p e n ( p l i k , " a " ) ; }

Rozwizanie dla jzyka C++: Listing 10.209. Rozwizanie zadania ??.?? w jzyku C++
f s t r e a m otworz ( char p l i k ) { return new f s t r e a m ( p l i k , i o s : : out | i o s : : app ) ; }

Zadanie ??.?? Rozwizania w wersji dla jzyka C i znakw typu char: Listing 10.210. Rozwizanie zadania ??.?? w jzyku C
void w c z y t a j ( FILE p l i k , i n t n ) { int i ; char tab [ 1 0 0 ] ; f o r ( i =0; i <n ; i ++){ f g e t s ( tab , 1 0 0 , s t d i n ) ; f p r i n t f ( p l i k , "%s " , tab ) ; } fclose ( plik ) ; }

10.11. Rozwizania do zada z rozdziau ?? Wad powyszego rozwizania jest fakt, e linie mog mie co najwyej 99 znakw. Ponisze rozwizanie jest pozbawione tej wady: Listing 10.211. Rozwizanie zadania ??.?? w jzyku C
void w c z y t a j ( FILE p l i k , i n t n ) { i n t i =0; char c ; while ( i <n ) { s c a n f ( "%c " ,& c ) ; i f ( c== \n ) i ++; i f ( i <n ) f p r i n t f ( p l i k , "%c " , c ) ; } fclose ( plik ) ; }

135

Rozwizanie w wersji dla jzyka C++ i znakw typu char: Listing 10.212. Rozwizanie zadania ??.?? w jzyku C++
void w c z y t a j ( f s t r e a m& p l i k , i n t n ) { int i ; string s ; f o r ( i =0; i <n ; i ++){ g e t l i n e ( cin , s ) ; p l i k <<s<<e n d l ; } plik . close () ; }

W programie ?? trzeba zamkn plik rcznie, gdy zmienna plik nie jest lokalnym obiektem funkcji wczytaj, ale referencj do obiektu utworzonego poza t funkcj. W takiej sytuacji zakoczenie dziaania funkcji wczytaj nie spowoduje zamknicia pliku skojarzonego ze zmienn plik . Rozwizanie dla typu wchar_t jest analogiczne. Zadanie ??.?? Program w wersji dla jzyka C: Listing 10.213. Rozwizanie zadania ??.?? w jzyku C
void p r z e p i s z ( FILE p l i k 1 , FILE p l i k 2 ) { char c ; while ( f s c a n f ( p l i k 1 , "%c " ,& c )==1) f p r i n t f ( p l i k 2 , "%c " , c ) ; }

136 Program w wersji dla jzyka C++:

10. Rozwizania i wskazwki

Listing 10.214. Rozwizanie zadania ??.?? w jzyku C++


void p r z e p i s z ( f s t r e a m& p l i k 1 , f s t r e a m& p l i k 2 ) { char c ; while ( ! p l i k 1 . e o f ( ) ) { p lik 1 . get ( c ) ; if (! plik1 . eof () ) p l i k 2 <<c ; } }

Zadanie ??.?? Poniewa w teici nie jest zaznaczone, e przepisywany plik jest tekstowy, to naley go przepisa w trybie binarnym: Najpierw wersja dla jzyka C: Listing 10.215. Rozwizanie zadania ??.?? w jzyku C
void p r z e p i s z ( char s c i e z k a 1 , char s c i e z k a 2 ) { FILE p l i k 1=f o p e n ( s c i e z k a 1 , " rb " ) ; FILE p l i k 2=f o p e n ( s c i e z k a 2 , "wb" ) ; char c [ 1 0 0 ] ; i n t n=100; while ( n==100){ n=f r e a d ( c , 1 , 1 0 0 , p l i k 1 ) ; fwrite (c ,1 ,n , plik2 ) } fc lose ( plik1 ) ; fc lose ( plik2 ) ; }

Wersja dla jzyka C++: Listing 10.216. Rozwizanie zadania ??.?? w jzyku C++
void p r z e p i s z ( char s c i e z k a 1 , char s c i e z k a 2 ) { fstream p l i k 1 ( sciezk a1 , i o s : : in | i o s : : bin ) ; f s t r e a m p l i k 2 ( s c i e z k a 2 , i o s : : out | i o s : : b i n ) ; char c [ 1 0 0 ] ; i n t n=100; while ( n==100){ p l i k 1 . read ( c , 1 0 0 ) ; n=p l i k 1 . gcount ( ) ; plik2 . write (c , n) ; } }

10.11. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Wersja w jzyku C Listing 10.217. Rozwizanie zadania ??.?? w jzyku C
void z a p i s z ( char s c i e z k a , i n t tab , i n t n , i n t m) { FILE p l i k=f o p e n ( s c i e z k a , "wb" ) ; int i ; f o r ( i =0; i <n ; i ++) f w r i t e ( tab [ i ] , s i z e o f ( i n t ) ,m, p l i k ) ; fclose ( plik ) ; }

137

Wersja w jzyku C++: Listing 10.218. Rozwizanie zadania ??.?? w jzyku C++
void z a p i s z ( const char s c i e z k a , i n t tab , i n t n , i n t m) { f s t r e a m p l i k ( s c i e z k a , i o s : : out | i o s : : b i n a r y ) ; int i ; f o r ( i =0; i <n ; i ++) p l i k . w r i t e ( reinterpret_cast <char >( tab [ i ] ) , s i z e o f ( i n t ) m) ; }

W powyszym rozwizaniu konieczne byo rzutowanie typu int* na typ char* gdy pierwszy argument metody write klasy fstream musi by wskanikiem na typ char. Zadanie ??.?? Wersja w jzyku C Listing 10.219. Rozwizanie zadania ??.?? w jzyku C
void w c z y t a j ( char s c i e z k a , i n t tab , i n t n , i n t m) { FILE p l i k=f o p e n ( s c i e z k a , " rb " ) ; int i ; f o r ( i =0; i <n ; i ++) f r e a d ( tab [ i ] , s i z e o f ( i n t ) ,m, p l i k ) ; fclose ( plik ) ; }

Rozwizanie w jzyku C++ Listing 10.220. Rozwizanie zadania ??.?? w jzyku C


void w c z y t a j ( const char s c i e z k a , i n t tab , i n t n , i n t m) { fstream p l i k ( sciezka , i o s : : in | i o s : : binary ) ; int i ; f o r ( i =0; i <n ; i ++) p l i k . r e a d ( reinterpret_cast <char >( tab [ i ] ) ,

138

10. Rozwizania i wskazwki


s i z e o f ( i n t ) m) ; }

10.12. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Listing 10.221. Rozwizanie zadania ??.?? w jzyku C/C++
#define suma ( a , b , c ) ( a+b+c )

Dobrym nawykiem jest umieszczanie w nawiasach denicji makr (czyli tak, jak w powyszym rozwizaniu (ab+c)+, a nie ab+c+). Zadanie ??.?? Listing 10.222. Rozwizanie zadania ??.?? w jzyku C/C++
#define w i e k s z y ( a , b ) \ i f ( a>b ) p r i n t f ( "%d" , a ) ; e l s e p r i n t f ( "%d" , b )

Dyrektywy preprocesora powinny mieci si w pojedynczej linii. Jeeli z jakiego powodu chce si podzieli dyrektyw na kilka linii, naley w miejscach przejcia do nowej linii, wstawi lewy ukonik, tak jak to ma miejsce w programie ??. Zadanie ??.?? Listing 10.223. Rozwizanie zadania ??.?? w jzyku C/C++
#define p a r z y s t a ( a ) ( a%2==0) ? 1 : 0

Zadanie ??.?? Listing 10.224. Rozwizanie zadania ??.?? w jzyku C/C++


#define n a j w i e k s z a ( a , b , c ) i f ( ( a>=b )&&(a>=c ) ) \ p r i n t f ( "%d" , a ) ; e l s e i f ( b>=c ) p r i n t f ( "%d" , b ) ; \ e l s e p r i n t f ( "%d" , c )

Zadanie ??.?? Listing 10.225. Rozwizanie zadania ??.?? w jzyku C/C++


#define n a j w i e k s z a ( a , b , c ) ( ( a>=b )&&(a>=c ) ) ? a : ( ( b>=c ) ?b : c )

10.13. Rozwizania do zada z rozdziau ?? Zadanie ??.?? Listing 10.226. Rozwizanie zadania ??.?? w jzyku C/C++
#define p e t l a ( x , y ) f o r ( x =0;x<y ; x++)

139

Zadanie ??.?? Listing 10.227. Rozwizanie zadania ??.?? w jzyku C/C++


#define z e r u j ( x ) x=0

10.13. Rozwizania do zada z rozdziau ??


Zadanie ??.?? Plik gwnego programu: Listing 10.228. Plik glowny.c
#include <s t d i o . h> #include " p i e r w i a s t e k . c " i n t main ( ) { double a , b , c , d e l t a ; p r i n t f ( " Podaj w s p o l c z y n n i k i rownania kwadratowego" ) ; s c a n f ( "%l f %l f %l f " ,&a ,&b,& c ) ; d e l t a=bb4a c ; i f ( d e l t a >0) p r i n t f ( " x1=%f x2=%f " ,( bp i e r w ( d e l t a ) ) / ( 2 a ) , (b+p i e r w ( d e l t a ) ) / ( 2 a ) ) ; e l s e i f ( d e l t a ==0) p r i n t f ( "x=%f " ,( b ) / ( 2 a ) ) ; else p r i n t f ( " Brak r o z w i a z a n " ) ; return 0 ; }

Plik z funkcj liczc pierwiastek: Listing 10.229. Plik pierwiastek.c


double p i e r w ( double n ) { float p , k , sr ; p=0; k=n ; s r =(p+k ) / 2 ; while ( ( s r !=p )&&( s r !=k ) ) { i f ( ( s r s r )>n ) k=s r ;

140
else p=s r ; s r =(p+k ) / 2 ; } return s r ; }

10. Rozwizania i wskazwki

Aby skompilowa powyszy program, naley oba pliki umieci w jednym katalogu i skompilowa plik glowny.c. Plik pierwiastek.c zostanie w caoci wklejony do pliku glowny.c za spraw dyrektywy include. Rozwizanie dla jzyka C++ jest analogiczne Zadanie ??.?? Plik gwnego programu: Listing 10.230. Plik glowny.c
#include <s t d i o . h> #include " p i e r w i a s t e k . h" i n t main ( ) { double a , b , c , d e l t a ; p r i n t f ( " Podaj w s p o l c z y n n i k i rownania kwadratowego" ) ; s c a n f ( "%l f %l f %l f " ,&a ,&b,& c ) ; d e l t a=bb4a c ; i f ( d e l t a >0) p r i n t f ( " x1=%f x2=%f " ,( bp i e r w ( d e l t a ) ) / ( 2 a ) , (b+p i e r w ( d e l t a ) ) / ( 2 a ) ) ; e l s e i f ( d e l t a ==0) p r i n t f ( "x=%f " ,( b ) / ( 2 a ) ) ; else p r i n t f ( " Brak r o z w i a z a n " ) ; return 0 ; }

Plik nagwkowy: Listing 10.231. Plik pierwiastek.h


#i f n d e f _pierw_ #define _pierw_ double p i e r w ( double ) ; #endif

I plik z funkcj liczc pierwiastek: Listing 10.232. Plik pierwiastek.c


#include " p i e r w i a s t e k . h"

10.13. Rozwizania do zada z rozdziau ??


double p i e r w ( double n ) { float p , k , sr ; p=0; k=n ; s r =(p+k ) / 2 ; while ( ( s r !=p )&&( s r !=k ) ) { i f ( ( s r s r )>n ) k=s r ; else p=s r ; s r =(p+k ) / 2 ; } return s r ; }

141

W pliku pieriwastek.h umieszczone zostay dyrektywy preprocesora zabezpieczajce przed wielokrotnym doczaniem tego samego nagwka. Nie jest to konieczne w powyszym przypadku, ale jest to standardowa praktyka przy tworzeniu bibliotek. Podobnie standardow praktyk jest doczanie do plikw ze rdami bibliotek ich plikw nagwkowych. Dziki temu ewentualne bdy w plikach nagwkowych s wykrywane ju na etapie kompilacji bibliotek. Aby skompilowa powyszy program, naley najpierw oddzielnie skompilowa piliki glowny.c i pierwiastek.c, a nastpnie je poczy. Przy uyciu kompilatora gcc wyglda to nastpujco: gcc pierwiastek.c -c -o pierwiatek.o gcc glowny.c -c -o glowny.o gcc glowny.o pierwiastek.o -o glowny Rozwizanie dla jzyka C++ jest analogiczne. Zadanie ??.?? W pliku Makefile zapisuje si potrzebne do wykonania operacje w odwrotnej kolejnoci (czyli jako pierwsz wymienia si operacj, ktra ma by wykonana jako pierwsza): Listing 10.233. plik Makele
glowny : glowny . o p i e r w i a s t e k . o g c c glowny . o p i e r w i a s t e k . o o glowny glowny . o : glowny . c p i e r w i a s t e k . h g c c glowny . c c o glowny . o pierwiastek . o : pierwiastek .h pierwiastek . c g c c p i e r w i a s t e k . c c o p i e r w i a s t e k . o

142

10. Rozwizania i wskazwki W powyszym rozwizaniu wrd plikw potrzebnych do stworzenia plikw glowny.o i pierwiastek.o wymieniony zosta take plik pierwiastek.h, ktry nie jest parametrem w kompilacji. Dziki temu program make, ledzi zmiany take w pliku nagwkowym. W pliku Makefile nie trzeba wymienia wszystkich komend potrzebnych do kompilacji programu. Wystarczy wypisa zalenoci. Poniej skrcona wersja pliku Makefile: Listing 10.234. plik Makele, krtsza wersja
glowny : glowny . o p i e r w i a s t e k . o g c c glowny . o p i e r w i a s t e k . o o glowny glowny . o : glowny . c p i e r w i a s t e k . h pierwiastek . o : pierwiastek .h pierwiastek . c

Rozwizanie dla jzyka C++ jest analogiczne. Wystarczy podmieni gcc na g++ i zmieni rozszerzenia nazw plikw. Zadanie ??.?? Plik gwnej czci programu: Listing 10.235. Plik glowny.c
#include <s t d i o . h> #include " z e s p o l o n e . h" #include " ary tmety k a . h" i n t main ( ) { z e s p o l o n e suma , wczyt ; int i ; p r i n t f ( " I l e l i c z b z e s p o l o n y c h c h c e s z zsumowac ? " ) ; s c a n f ( "%d" ,& i ) ; while ( i >0){ wczyt=w c z y t a j ( ) ; suma=dodaj ( suma , wczyt ) ; i ; } wy pisz ( suma ) ; return 0 ; }

Plik nagwkowy biblioteki zespolone: Listing 10.236. Plik zespolone.h


#i f n d e f _zespolone_ #define _zespolone_ typedef struct z e s p { double r , u ; } z e s p o l o n e ;

10.13. Rozwizania do zada z rozdziau ??

143

z e sp olon e wczytaj ( ) ; void wy pisz ( z e s p o l o n e ) ; #endif

Plik gwny biblioteki zespolone: Listing 10.237. Plik zespolone.c


#include <s t d i o . h> #include " z e s p o l o n e . h" z e sp olon e wczytaj ( ) { zespolone z ; p r i n t f ( " Podaj c z e s c r z e c z y w i s t a wczy ty wanej l i c z b y " ) ; s c a n f ( "%l f " ,&( z . r ) ) ; p r i n t f ( " Podaj c z e s c u r o j o n a wczy ty wanej l i c z b y " ) ; s c a n f ( "%l f " ,&( z . u ) ) ; return z ; } void wy pisz ( z e s p o l o n e z ) { p r i n t f ( " Czesc r z e c z . ma w a r t o s c %f a c z e s c u r o j o n a %f " , z . r , z . u) ; }

Plik nagwkowy biblioteki z funkcjami arytmetycznymi: Listing 10.238. Plik arytmetyka.h


#i f n d e f _pierw_ #define _arytmetyka_ #include " z e s p o l o n e . h" z e s p o l o n e dodaj ( z e s p o l o n e , z e s p o l o n e ) ; z e s p o l o n e pomnoz ( z e s p o l o n e , z e s p o l o n e ) ; #endif

Plik biblioteki z funkcjami arytmetycznymi: Listing 10.239. Plik arytmetyka.c


#include " z e s p o l o n e . h" #include " ary tmety k a . h" z e s p o l o n e dodaj ( z e s p o l o n e a , z e s p o l o n e b ) {

144
zespolone z ; z . r=a . r+b . r ; z . u=a . u+b . u ; return z ; }

10. Rozwizania i wskazwki

z e s p o l o n e pomnoz ( z e s p o l o n e a , z e s p o l o n e b ) { zespolone z ; z . r=a . r b . ra . ub . u ; z . u=a . r b . u+a . ub . r ; return z ; }

W plikach biblioteki z operacjami arytmetycznymi na liczbach zespolonych dyrektyw include zosta doczony plik zespolone.h ze wzgldu na zdeniowany w nim typ zespolone. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.240. plik Makele, krtsza wersja
glowny : glowny . o z e s p o l o n e . o ary tmety k a . o g c c glowny . o p i e r w i a s t e k . o ary tmety k a . o o glowny glowny . o : glowny . c z e s p o l o n e . h ary tmety k a . h ary tmety k a . o : ary tmety k a . h z e s p o l o n e . h ary tmety k a . c zespolone . o : zespolone . h zespolone . c

Zadanie ??.?? Plik gwnej czci programu: Listing 10.241. Plik glowny.c
#include <s t d i o . h> #include " dane . h" #include " s t a t y s t y k a . h" i n t main ( ) { int i ; p r i n t f ( "Dane i l u osob c h c e s z wczy tac ? " ) ; s c a n f ( "%d" ,& i ) ; while ( i >0){ wczytaj ( ) ; i ; } p r i n t f ( "%f " , s r e d n i a ( ) ) ; return 0 ; }

10.13. Rozwizania do zada z rozdziau ?? Plik nagwkowy biblioteki dane: Listing 10.242. Plik dane.h
#i f n d e f _dane_ #define _dane_ typedef struct o s { char i m i e [ 1 5 ] ; nazwisk o [ 3 0 ] ; i n t wiek ; } osoba ; void w c z y t a j ( ) ; void wy pisz ( osoba ) ; #endif

145

Plik gwny biblioteki dane: Listing 10.243. Plik dane.c


#include <s t d i o . h> #include < s t d l i b . h> #include " dane . h" i n t l i c z b a =0; i n t pojemnosc =0; osoba tab=NULL; void w c z y t a j ( ) { i f ( l i c z b a==pojemnosc ) { osoba pom=tab ; tab=m a l l o c ( 2 ( pojemnosc+1) s i z e o f ( osoba ) ) ; int i ; f o r ( i =0; i <pojemnosc ; i ++) tab [ i ]=pom [ i ] ; i f (pom!=NULL) f r e e (pom) ; pojemnosc =2( pojemnosc+1) ; } p r i n t f ( " Podaj i m i e " ) ; s c a n f ( "%s " ,&( tab [ l i c z b a ] . i m i e ) ) ; p r i n t f ( " Podaj nazwisk o " ) ; s c a n f ( "%s " ,&( tab [ l i c z b a ] . nazwisk o ) ) ; p r i n t f ( " Podaj wiek " ) ; s c a n f ( "%d" ,&( tab [ l i c z b a ] . wiek ) ) ; l i c z b a ++; } void wy pisz ( osoba o ) {

146

10. Rozwizania i wskazwki


p r i n t f ( " i m i e : %s \n nazwisk o : %s \n wiek %d\n" , o . imie , o . nazwisk o , o . wiek ) ; }

Plik nagwkowy biblioteki z funkcjami statystycznymi: Listing 10.244. Plik statystyka.h


#i f n d e f _pierw_ #define _staty sty k a_ double s r e d n i a ( ) ; i n t minimalny ( ) ; i n t maksymalny ( ) ; #endif

Plik biblioteki z funkcjami statystycznymi: Listing 10.245. Plik statystyka.c


#include < s t d l i b . h> #include " dane . h" #include " s t a t y s t y k a . h" extern osoba tab ; extern i n t l i c z b a ; double s r e d n i a ( ) { i f ( tab==NULL) return 0 ; i n t suma=0 , i ; f o r ( i =0; i <l i c z b a ; i ++) suma+=tab [ i ] . wiek ; return ( double ) suma/ l i c z b a ; } i n t minimalny ( ) { i f ( tab==NULL) return 0 ; i n t min=tab [ 0 ] . wiek , i ; f o r ( i =1; i <l i c z b a ; i ++) i f ( tab [ i ] . wiek<min ) min=tab [ i ] . wiek ; return min ; } i n t maksymalny ( ) { i f ( tab==NULL)

10.13. Rozwizania do zada z rozdziau ??


return 0 ; i n t maks=tab [ 0 ] . wiek , i ; f o r ( i =1; i <l i c z b a ; i ++) i f ( tab [ i ] . wiek>maks ) maks=tab [ i ] . wiek ; return maks ; }

147

Dostp do zmiennych zadeklarowanych w bibliotece dane biblioteka statystyka uzyskuje poprzez zadeklarowanie potrzebnych zmiennych ze specykatorem extern. Innym sposobem udostpnienia na zewntrz zmiennych tab i liczba bez koniecznoci ich kadorazowego importu przy pomocy modykatora extern jest umieszczenie kodu odpowiadajcego za import zmiennych w pliku nagwkowym biblioteki dane: Listing 10.246. Plik dane.h
#i f n d e f _dane_ #define _dane_ typedef struct o s { char i m i e [ 1 5 ] ; nazwisk o [ 3 0 ] ; i n t wiek ; } osoba ; extern osoba tab ; extern i n t l i c z b a ; void w c z y t a j ( ) ; void wy pisz ( osoba ) ; #endif

W powyszym przypadku zmienne tab i liczba byyby dostpne we wszystkich moduach programu uywajcych biblioteki dane, niezalenie od tego czy byyby potrzebne czy nie. Rozwizanie w jzyku C++ jest analogiczne. Zadanie ??.?? Listing 10.247. plik Makele, krtsza wersja
glowny : glowny . o dane . o s t a t y s t y k a . o g c c glowny . o dane . o s t a y s t y k a . o o glowny glowny . o : glowny . c dane . h s t a t y s t y k a . h

148

10. Rozwizania i wskazwki


s t a t y s t y k a . o : s t a t y s t y k a . h dane . h s t a t y s t y k a . c dane . o : dane . h dane . c

Zadanie ??.?? Plik nagwkowy biblioteki dane: Listing 10.248. Plik dane.h
#i f n d e f _dane_ #define _dane_ typedef struct o s { char i m i e [ 1 5 ] ; nazwisk o [ 3 0 ] ; i n t wiek ; } osoba ; void w c z y t a j ( ) ; void wy pisz ( ) ; int i l e ( ) ; osoba wczytana ( i n t ) ; #endif

Plik gwny biblioteki dane: Listing 10.249. Plik dane.c


#include <s t d i o . h> #include < s t d l i b . h> #include " dane . h" s t a t i c l i c z b a =0; s t a t i c pojemnosc =0; s t a t i c osoba tab=NULL; void w c z y t a j ( ) { i f ( l i c z b a==pojemnosc ) { osoba pom=tab ; tab=m a l l o c ( 2 ( pojemnosc+1) s i z e o f ( osoba ) ) ; int i ; f o r ( i =0; i <pojemnosc ; i ++) tab [ i ]=pom [ i ] ; i f (pom!=NULL) f r e e (pom) ; pojemnosc =2( pojemnosc+1) ; } p r i n t f ( " Podaj i m i e " ) ; s c a n f ( "%s " ,&( tab [ l i c z b a ] . i m i e ) ) ; p r i n t f ( " Podaj nazwisk o " ) ; s c a n f ( "%s " ,&( tab [ l i c z b a ] . nazwisk o ) ) ;

10.13. Rozwizania do zada z rozdziau ??


p r i n t f ( " Podaj wiek " ) ; s c a n f ( "%d" ,&( tab [ l i c z b a ] . wiek ) ) ; l i c z b a ++; }

149

void wy pisz ( ) { int i ; f o r ( i =0; i <l i c z b a ; i ++) p r i n t f ( " i m i e : %s \n nazwisk o : %s \n wiek %d\n" , tab [ i ] . imie , tab [ i ] . nazwisk o , tab [ i ] . wiek ) ; } int i l e ( ) { return l i c z b a ; } osoba wczytana ( i n t i ) { return tab [ i ] ; }

Dziki uyciu specykatora static zmienne zadeklarowane w bibliotece dane nie s dostpne poza t bibliotek (take przy uyciu specykatora extern). Rozwizanie w jzyka C++ jest podobne. Zadanie ??.?? Rozwizanie w jzyku C: Plik nagwkowy biblioteki kolo: Listing 10.250. Plik kolo.h
i f n d e f _kolo_ #define _kolo_ s t a t i c double const p i = 3 . 1 4 1 5 ; double p o l e ( double ) ; double obwod ( double ) ; #endif

Gdyby przy deklaracji staej pi pomin specykator static to przy prbie kompilacji programu uywajcego biblioteki kolo kompilator zgosiby bd o wielokrotnej denicji staej pi. Plik gwny biblioteki kolo: Listing 10.251. Plik kolo.c
#include " k o l o . h" double p o l e ( double r ) {

150
return p i r r ; } double obwod ( double r ) { return 2 p i r ; }

10. Rozwizania i wskazwki

Rozwizanie w jzyku C++ rni si tylko drobnym szczegem w pliku nagwkowym: Listing 10.252. Plik kolo.h
#i f n d e f _kolo_ #define _kolo_ double const p i = 3 . 1 4 1 5 ; double p o l e ( double ) ; double obwod ( double ) ; #endif

W przeciwiestwie do jzyka C ,stae w jzyku C++ s domylnie statyczne. Uycie w takiej sytuacji specykatora static jest dozwolone, ale nie wywoa adnego efektu.

Bibliografia
[1] Mike Banahan, Declan Brady, Mark Doran, The C Book, Second Edition, Addison-Wesley 1991 [2] Krzysztof Diks, Wstp do programowania w jzyku C, http://wazniak.mimuw.edu.pl/ [3] Bruce Eckel, Thinking in C++. Edycja polska, Helion, Warszawa 2002 [4] Brian W. Kernighan, Dennis M. Ritchie,Jzyk ANSI C, WNT Warszawa 2000, wyd. VI, ISBN 83-204-2620-0 [5] Bjarne Stroustrup, Jzyk C++, WNT, Warszawa 2002 [6] Kurc C na Wikibooks, http://pl.wikibooks.org/wiki/C [7] Standard jzyka C ISO/IEC 9899:1999 [8] Standard Jzyka C++ ISO/IEC 14882:2003

You might also like