Professional Documents
Culture Documents
Kup ksik
Pole ksik
Oce ksik
Ksigarnia internetowa
Lubi to! Nasza spoeczno
SPIS TRECI
O autorze .......................................................................................................................................... 19
Przedmowa ....................................................................................................................................... 21
Rozdzia 1. Zaczynamy .................................................................................................................. 23
Skd C? .................................................................................................................................. 23
Dlaczego C? .......................................................................................................................... 24
Cechy uytkowe ................................................................................................. 25
Efektywno ....................................................................................................... 25
Przenono ........................................................................................................ 25
Moc i elastyczno ............................................................................................. 26
Ukierunkowanie na programist ....................................................................... 26
Sabe strony ........................................................................................................ 26
Dokd zmierza C? ............................................................................................................... 27
Co robi komputery? .......................................................................................................... 28
Jzyki wysokiego poziomu i kompilatory ....................................................................... 29
Standardy jzyka ................................................................................................................. 30
Standard ANSI/ISO C ......................................................................................... 31
Standard C99 ...................................................................................................... 31
Standard C11 ...................................................................................................... 32
Korzystanie z C siedem krokw .................................................................................. 33
Krok 1. Okrelenie celw programu .................................................................. 33
Krok 2. Projektowanie programu ....................................................................... 34
Krok 3. Pisanie kodu .......................................................................................... 34
Krok 4. Kompilacja ............................................................................................. 35
Krok 5. Uruchomienie programu ....................................................................... 35
Krok 6. Testowanie i usuwanie bdw ............................................................ 35
Krok 7. Pielgnowanie i modyfikowanie programu ......................................... 36
Komentarz .......................................................................................................... 36
Mechanika programowania ............................................................................................... 37
Pliki kodu obiektowego, pliki wykonywalne i biblioteki ................................. 38
UNIX ................................................................................................................... 39
GNU Compiler Collection i LLVM .................................................................... 41
Kup ksik
Pole ksik
Linux ................................................................................................................... 42
Kompilatory dla komputerw PC ...................................................................... 43
Zintegrowane rodowiska programistyczne (Windows) .................................. 43
Opcja podwjna Windows/Linux ................................................................. 45
Jzyk C a komputery Mac .................................................................................. 45
Jak zorganizowano t ksik ........................................................................................... 46
Konwencje zapisu ............................................................................................................... 46
Czcionka ............................................................................................................. 47
Tekst na ekranie ................................................................................................. 47
Informacje dodatkowe ........................................................................................................ 48
Podsumowanie rozdziau .................................................................................................. 49
Pytania sprawdzajce ......................................................................................................... 49
mwiczenie .............................................................................................................................. 49
Rozdzia 2. Wstp do C .................................................................................................................. 51
Prosty przykad jzyka C ................................................................................................... 51
Objanienie ........................................................................................................................... 53
Podejcie 1. Szybkie streszczenie ...................................................................... 53
Podejcie 2. Szczegy ........................................................................................ 55
Budowa prostego programu .............................................................................................. 64
Co zrobi, aby Twj program by czytelny? .................................................................... 65
Kolejny krok ......................................................................................................................... 66
Dokumentacja ..................................................................................................... 66
Wielokrotne deklaracje ...................................................................................... 67
Mnoenie ............................................................................................................ 67
Wywietlanie wielu wartoci ............................................................................. 67
Wiele funkcji ......................................................................................................................... 68
Usuwanie bdw ................................................................................................................ 69
Bdy skadniowe ............................................................................................... 70
Bdy semantyczne ............................................................................................ 71
Stan programu .................................................................................................... 72
Sowa kluczowe ................................................................................................................... 73
Kluczowe zagadnienia ........................................................................................................ 74
Podsumowanie rozdziau .................................................................................................. 74
Pytania sprawdzajce ......................................................................................................... 75
mwiczenia .............................................................................................................................. 76
Rozdzia 3. Dane w C ..................................................................................................................... 79
Program przykadowy ........................................................................................................ 79
Co nowego? ......................................................................................................... 81
Zmienne i stae ..................................................................................................................... 82
Sowa kluczowe typw danych ........................................................................................ 83
Typy cakowite a typy zmiennoprzecinkowe ................................................... 84
Liczba cakowita ................................................................................................. 85
Liczba zmiennoprzecinkowa ............................................................................. 85
Kup ksik
Pole ksik
SPIS TRECI
Kup ksik
Pole ksik
Kup ksik
Pole ksik
SPIS TRECI
Kup ksik
Pole ksik
10
Kup ksik
Pole ksik
SPIS TRECI
11
Kup ksik
Pole ksik
12
Kup ksik
Pole ksik
SPIS TRECI
13
Kup ksik
Pole ksik
14
Kup ksik
Pole ksik
SPIS TRECI
15
Kup ksik
Pole ksik
16
Kup ksik
Pole ksik
SPIS TRECI
17
Kup ksik
Pole ksik
18
Kup ksik
Pole ksik
9
FUNKCJE
Zagadnienia poruszone w tym rozdziale:
z
Sowo kluczowe:
return
z
Operatory jednoargumentowe:
*i&
z
z
z
z
z
Zastosowanie wskanikw
jako argumentw funkcji
Typy funkcji
Prototypy ANSI C
Rekurencja
Przypomnienie
Czym jest funkcja? Funkcja jest wydzielonym fragmentem kodu programu, speniajcym okrelone zadanie. Struktur funkcji i sposb ich uywania wyznaczaj reguy
skadniowe jzyka C. Funkcje w jzyku C odgrywaj t sam rol co funkcje, podprogramy i procedury w innych jzykach programowania, cho szczegy ich stosowania mog by inne. Niektre funkcje powoduj wykonanie jakiej czynnoci. Na
przykad funkcja printf() powoduje wywietlenie danych na ekranie. Zadaniem
innych funkcji jest obliczenie wartoci potrzebnej w programie. Na przykad funkcja
strlen() informuje program o dugoci danego acucha. Oglnie rzecz biorc, funkcja moe zarwno wykonywa czynnoci, jak i zwraca wartoci.
Kup ksik
Pole ksik
362
Dlaczego powiniene korzysta z funkcji? Po pierwsze, pozwalaj one unikn powtarzania tych samych fragmentw kodu. Jeli okrelone zadanie ma zosta wykonane kilkakrotnie, wystarczy napisa jedn funkcj i wywoywa j tam, gdzie jest to
potrzebne. Jedn funkcj mona ponadto wykorzystywa w wielu programach tak
samo, jak robilimy to z funkcjami putchar() czy printf(). Po drugie, w postaci
funkcji warto jest przedstawi nawet czynno wykonywan raz i tylko w jednym
programie, poniewa zwiksza to modularno programu, a tym samym czyni go
czytelniejszym i atwiejszym w modyfikacji. Zamy, e chcesz napisa program,
ktry wykonuje nastpujce czynnoci:
Wczytaj list liczb
Uporzdkuj liczby
Znajd warto redni
Narysuj wykres supkowy
Mgby uy poniszego kodu:
#include <stdio.h>
#define ROZMIAR 50
int main(void)
{
float lista[ROZMIAR];
wczytajliste(lista, ROZMIAR);
uporzadkuj(lista, ROZMIAR);
srednia(lista, ROZMIAR);
wykres(lista, ROZMIAR);
return 0;
}
Oczywicie musiaby napisa jeszcze drobny szczeg cztery uyte w programie funkcje: wczytajliste(), uporzadkuj(), srednia() i wykres(). Zauwa, e
opisowe nazwy funkcji pokazuj w jasny sposb dziaanie i organizacj programu.
Dziki podejciu modularnemu moesz pracowa nad kad funkcj z osobna, dopki
nie bdzie wykonywaa ona swojego zadania w naleyty sposb, a jeli Twoje funkcje
bd wystarczajco wszechstronne, bdziesz mg wykorzysta je rwnie w innych
programach.
Wielu programistw lubi wyobraa sobie funkcje jako czarne skrzynki, okrelone przez wchodzce do nich dane (wejcie) oraz wykonywane przez nie dziaania
lub zwracane wartoci (wyjcie). To, co dzieje si wewntrz funkcji czarnej skrzynki,
nie jest Twoim zmartwieniem, jeli tylko nie jeste osob, ktra musi j napisa.
Gdy korzystasz na przykad z funkcji printf(), wiesz, e musisz przekaza jej acuch sterujcy i argumenty. Wiesz rwnie, jakie skutki pocignie za sob jej wywoanie. Nie musisz natomiast zastanawia si nad kodem, z jakiego skada si
funkcja printf(). Traktowanie funkcji w ten sposb pomaga skoncentrowa si na
oglnej budowie programu, bez zagbiania si w szczegy. Zanim zaczniesz myle o tym, jak napisa funkcj, zastanw si dokadnie nad tym, jakie zadania ma
ona realizowa i jakie jest jej miejsce w programie jako caoci.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
363
Analiza programu
Identyfikator gwiazdki wystpuje w trzech rnych kontekstach: w prototypie
funkcji, ktry dostarcza kompilatorowi oglnych informacji o funkcji gwiazdki(),
w wywoaniu funkcji, ktre uruchamia funkcj oraz w definicji funkcji, ktra zawiera
jej kod.
Kup ksik
Pole ksik
364
Nawiasy wskazuj, e gwiazdki jest nazw funkcji. Pierwsze sowo void okrela
typ funkcji oznacza ono, e funkcja nie zwraca adnej wartoci. Drugie sowo
void (zawarte w nawiasie) wskazuje, e funkcja nie pobiera argumentw. rednik
oznacza, e wiersz jest deklaracj funkcji, a nie jej definicj. Wiersz void
gwiazdki(void); informuje zatem kompilator, e program wykorzystuje funkcj
o nazwie gwiazdki, ktra nie przyjmuje argumentw i nie zwraca wartoci, i e definicji funkcji naley szuka w innym miejscu. Jeli posiadasz kompilator, ktry nie
rozpoznaje prototypw ANSI C, po prostu zadeklaruj typ funkcji, tak jak poniej:
void gwiazdki();
Niektre bardzo stare kompilatory nie rozpoznaj rwnie typu void. W takim
przypadku skorzystaj z typu int. I koniecznie rozejrzyj si za kompilatorem
z obecnego stulecia.
Co do zasady, prototyp okrela zarwno typ wartoci zwracanej przez funkcj, jak
i typy wszystkich argumentw oczekiwanych w wywoaniu funkcji; cznie ta informacja to tak zwana sygnatura funkcji. W tym konkretnym przypadku sygnatura mwi, e funkcja nie zwraca wartoci i nie przyjmuje argumentw.
W naszym programie prototyp funkcji gwiazdki() znajduje si przed sowem
main(); mgby on znajdowa si wewntrz funkcji main(), w miejscu, gdzie
umieszcza si deklaracje zmiennych.
Program wywouje funkcj gwiazdki() w funkcji main() przez podanie jej nazwy wraz z nawiasem i rednikiem:
gwiazdki();
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
365
RYSUNEK 9.1.
Przebieg programu
naglowek1.c
(patrz listing 9.1)
RYSUNEK 9.2.
Budowa prostej
funkcji
Kup ksik
Pole ksik
366
Argumenty funkcji
Pokazany wczeniej nagwek listu wygldaby adniej, gdyby tekst by w nim wyrodkowany. Wyrodkowanie tekstu odbywa si przez wywietlenie przed nim odpowiedniej liczby odstpw. Przypomina to zadanie realizowane przez funkcj gwiazdki()
rzecz jasna z t rnic, e chodzi o wywietlenie odstpw. Zamiast pisa dwie
oddzielne funkcje dla gwiazdek i dla odstpw, utworzymy jedn wszechstronn
funkcj, ktra bdzie w stanie wykona oba zadania. Nazwiemy j n_znak() (aby
zaznaczy, e wywietla ona znak n razy). Zamiast wbudowywa wywietlany
znak oraz liczb powtrek w kodzie funkcji, wartoci te bdziemy przekazywa jako
argumenty.
Przejdmy do konkretw. Zamy, e w terminalu mamy dokadnie 40 kolumn znakw wywietlanych, wic rzd gwiazdek ma mie szeroko 40 znakw; std do jego
wywietlenia powinno posuy wywoanie n_znak('*', 40);. Co z odstpami?
Tekst MEGATHINK, INC. ma szeroko 15 znakw, a wic w pierwszej wersji programu
nastpowao po nim 25 odstpw. Aby go wyrodkowa, naley go przesun o 12
znakw w prawo, co spowoduje, e po jego obu stronach znajdowa si bdzie podobna liczba (12 po jednej i 13 po drugiej) odstpw. Naley wic skorzysta z wywoania
n_znak(' ', 12);.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
367
Poza tym, e wykorzystuje ona argumenty, funkcja n_znak() jest zupenie podobna
do funkcji gwiazdki(). Istotn rnic jest fakt, i n_znak() nie powinna wywietla
znaku nowej linii, poniewa po jej wywoaniu konieczne bdzie wywietlenie tekstu
w tym samym wierszu. Nowa wersja programu przedstawiona jest na listingu 9.2.
Aby zilustrowa, jak dziaaj argumenty, program przekazuje do funkcji n_znak()
bardzo rnorodne wyraenia.
*/
*/
*/
*/
*/
*/
*/
Kup ksik
Pole ksik
368
Przypomnijmy sobie teraz sposb tworzenia funkcji przyjmujcej argumenty, a nastpnie przyjrzyjmy si, jak naley z niej korzysta.
Wiersz ten informuje kompilator, e funkcja n_znak() pobiera dwa argumenty o nazwach ch i num, e ch naley do typu char oraz e num naley do typu int. Zmienne ch
i num nazywamy argumentami formalnymi. Podobnie jak zmienne zadeklarowane
wewntrz funkcji, argumenty formalne s zmiennymi lokalnymi, stanowicymi prywatn wasno funkcji. Oznacza to, e w innych funkcjach mog istnie niezalene
zmienne o tych samych nazwach. Zmienne ch i num otrzymuj wartoci przy kadym
wywoaniu funkcji n_znak().
Zauwa, e skadnia ANSI C wymaga, aby kada zmienna bya poprzedzona nazw
swojego typu. W odrnieniu od zwykej deklaracji nie wolno stosowa list zmiennych nalecych do tego samego typu:
void ping(int x, y, z)
void pong(int x, int y, int z)
/* prawidlowe */
Powysza posta definicji funkcji wychodzi z uycia. Powiniene o niej wiedzie, aby
by w stanie zrozumie starszy kod, ale piszc nowe programy, powiniene trzyma
si skadni zgodnej z ANSI C (w C99 i C11 rwnie pojawi si ostrzeenia o skadni
przeznaczonej do wycofania).
Funkcja n_znak() przyjmuje dane z funkcji main(), ale nie zwraca adnej wartoci.
Dlatego te naley ona do typu void.
Zobaczmy teraz, jak z niej korzysta.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
369
Uycie konstrukcji char ch i int num w prototypie nie powoduje bowiem utworzenia
adnych zmiennych.
Tak jak poprzednio, standard ANSI C zezwala na korzystanie ze starszej formy deklaracji niezawierajcej listy argumentw:
void n_znak();
Kup ksik
Pole ksik
370
RYSUNEK 9.3.
Argumenty formalne
i faktyczne
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
371
Kup ksik
Pole ksik
372
Nie, poniewa funkcja main() nie ma pojcia o istnieniu czego takiego jak zmienna
min. Pamitaj, e zmienne lokalne funkcji imin() s znane tylko funkcji imin().
Wywoanie imin(zlo1,zlo2) kopiuje wartoci zestawu zmiennych funkcji main()
(czyli zlo1 i zlo2) do zestawu zmiennych funkcji imin() (czyli n i m).
Zwrcona warto moe zosta nie tylko przypisana zmiennej, ale take uyta w wyraeniu. Prawidowe s na przykad ponisze instrukcje:
odpowiedz = 2 * imin(z, zstar) + 25;
printf("%d\n", imin(-32 + odpowiedz, LIMIT));
Warto zwracana funkcji moe by dostarczona przez dowolne wyraenie, nie tylko
zwyk zmienn. Funkcj imin() mona na przykad skrci w nastpujcy sposb:
/* funkcja wartosci minimalnej, druga wersja */
imin(int n,int m)
{
return (n < m) ? n : m;
}
Wwczas zwracana liczba jest wartoci, jak otrzymasz, gdy przypiszesz otrzyman
warto do zmiennej typu, ktry ma by zwracany. Tak wic w powyszym przykadzie kocowy skutek bdzie taki sam, jakby przypisa zmienn z do zmiennej typu
int i tak warto zwrci. Przypumy, e mamy nastpujce wywoanie funkcji:
wynik = co_gdy(64);
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
373
Zmiennej z przypisana zostanie warto 1.5625. Instrukcja return zwrci jednak wynik
w postaci liczby 1 typu int.
Uycie instrukcji return ma jeszcze jeden skutek. Powoduje ono zakoczenie funkcji
i przejcie do kolejnej instrukcji w funkcji wywoujcej. Ma to miejsce, nawet jeli
return nie jest ostatni instrukcj w funkcji. Funkcj imin() mona wic zapisa
nastpujco:
/* funkcja wartosci minimalnej, trzecia wersja */
imin(int n,int m)
{
if (n < m)
return n;
else
return m;
}
Typy funkcji
Deklaracja funkcji musi zawiera jej typ. Funkcja powinna nalee do tego samego
typu co zwracana przez ni warto. Funkcja, ktra nie zwraca wartoci, powinna
nalee do typu void. Jeli w deklaracji funkcji nie podano typu, jzyk C zakada, e
Kup ksik
Pole ksik
374
funkcja naley do typu int (to konwencja z wczesnego C, kiedy wikszo funkcji i tak
zwracaa int). Standard C99 porzuci jednak domniemanie niejawnego typu int dla
funkcji.
Deklaracja typu jest czci definicji funkcji. Pamitaj, e odnosi si ona do wartoci
zwracanej, a nie do argumentw. Na przykad poniszy nagwek definiuje funkcj,
ktra przyjmuje dwa argumenty typu int, ale zwraca warto typu double:
double klink(int a, int b)
Aby mc poprawnie korzysta z funkcji, program musi zna jej typ, zanim zostanie
ona uyta po raz pierwszy. Mona to osign przez umieszczenie penej definicji
funkcji przed miejscem jej pierwszego wywoania. Takie rozwizanie moe jednak
zmniejszy czytelno programu, a ponadto nie mona go zastosowa w przypadku,
gdy funkcja jest czci biblioteki lub znajduje si w osobnym pliku. Std oglnie
przyjt metod informowania kompilatora o funkcjach jest ich deklarowanie. Na
przykad funkcja main() w listingu 9.3 zawiera nastpujce wiersze:
#include <stdio.h>
int imin(int, int);
int main(void)
{
int zlo1, zlo2;
Drugi wiersz ustala, e imin jest nazw funkcji, ktra przyjmuje dwa argumenty typu
int i zwraca warto typu int. Dziki tej informacji kompilator bdzie wiedzia, jak
traktowa funkcj imin(), gdy pojawi si ona w programie.
Do tej pory wszystkie deklaracje funkcji umieszczalimy poza funkcj, ktra z nich
korzystaa. Dozwolone jest jednak umieszczenie ich wewntrz funkcji. Na przykad
pocztek programu mniejsze.c mona by zmieni w nastpujcy sposb:
#include <stdio.h>
int main(void)
{
int imin(int, int);
int zlo1, zlo2;
Niezalenie od wybranego zapisu istotne jest to, aby deklaracja znajdowaa si przed
pierwszym wywoaniem funkcji.
W standardowej bibliotece ANSI C funkcje pogrupowane s w rodziny, z ktrych
kada posiada swj plik nagwkowy. Plik nagwkowy zawiera midzy innymi deklaracje funkcji. Na przykad plik stdio.h zawiera deklaracje standardowych funkcji
wejcia-wyjcia, takich jak printf() i scanf(), a math.h deklaracje funkcji matematycznych. Plik math.h zawiera na przykad nastpujcy wiersz:
double sqrt(double);
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
375
do jakiego typu naley funkcja, ale kod funkcji znajduje si w definicji. Doczenie
pliku math.h informuje jedynie kompilator, e funkcja sqrt() zwraca typ double; kod
funkcji sqrt() znajduje si w oddzielnym pliku bibliotecznym.
Prototypy ANSI C
Tradycyjna forma deklaracji funkcji sprzed czasw ANSI C bya niekompletna, poniewa okrelaa jedynie typ wartoci zwracanej, milczc na temat argumentw.
Zobaczmy, jakie problemy mog wynikn z korzystania z tej postaci deklaracji.
Ponisza deklaracja stwierdza, e funkcja imin() zwraca warto typu int:
int imin();
Nie mwi ona jednak nic o liczbie i typach przyjmowanych przez ni argumentw.
Std jeli wywoasz funkcj imin(), przekazujc jej niewaciwe argumenty, kompilator nie zorientuje si, e popeniasz bd.
Problem
Przyjrzyjmy si kilku przykadom uycia funkcji imax(), bliskiej krewnej imin().
Listing 9.4 przedstawia program, ktry deklaruje funkcj imax(), a nastpnie uywa
jej w nieprawidowy sposb.
Kup ksik
Pole ksik
376
ANSI C na ratunek!
Proponowanym przez standard ANSI C rozwizaniem problemu niedopasowanych
argumentw jest uzupenienie deklaracji funkcji o typy zmiennych. Rezultatem jest
prototyp funkcji deklaracja, ktra okrela typ wartoci zwracanej oraz liczb i typy
argumentw. Aby zasygnalizowa, e funkcja imax() wymaga dwch argumentw
typu int, mona skorzysta z kadego z poniszych prototypw:
int imax(int, int);
int imax(int a, int b);
Pierwsza posta zawiera list typw; druga wzbogaca j o nazwy zmiennych. Pamitaj,
e nazwy te s w zasadzie atrapami i nie musz odpowiada nazwom uytym
w definicji funkcji.
Majc te informacje, kompilator moe sprawdzi, czy wywoanie funkcji pasuje do jej
prototypu. Czy przekazywana jest waciwa liczba argumentw? Czy nale one do
waciwych typw? Gdy typy w wywoaniu i w prototypie nie zgadzaj si i obydwa
s liczbami lub wskanikami, kompilator dokonuje rzutowania, ktre dostosowuje
argumenty faktyczne do typu argumentw formalnych. Na przykad imax(3.0, 5.0)
zostaje zamienione na imax(3, 5). Listing 9.5 jest wynikiem rozszerzenia listingu 9.4
o prototypy funkcji.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
377
int main(void)
{
printf("Wieksza liczba z %d i %d jest %d.\n",
3, 5, imax(3));
printf("Wieksza liczba z %d i %d jest %d.\n",
3, 5, imax(3.0, 5.0));
return 0;
}
int imax(n, m)
{
return (n > m ? n : m);
}
Rnica pomidzy bdem a ostrzeeniem polega na tym, e bd przerywa kompilacj, a ostrzeenie nie. Niektre kompilatory przeprowadzaj rzutowanie typw, nie
informujc Ci nawet o tym. Dzieje si tak, poniewa standard nie wymaga stosowania ostrzee. Jednak wiele kompilatorw pozwala na ustawienie poziomu ostrzegania,
co umoliwia dostosowanie szczegowoci wydawanych przez kompilator informacji.
Kup ksik
Pole ksik
378
Prototyp ten ustala, e pierwszy argument jest acuchem (wyjania to rozdzia 11.,
acuchy znakowe i funkcje acuchowe) oraz e funkcja moe przyjmowa dalsze
argumenty o dowolnych typach.
Biblioteka C w pliku nagwkowym stdarg.h udostpnia standardowy sposb definiowania funkcji o zmiennej liczbie argumentw. Rozdzia 16. zawiera wicej informacji na ten temat.
Potga prototypw
Prototypy stanowi mocn stron jzyka. Pozwalaj kompilatorowi wyapywa bdy
lub przeoczenia, jakich moesz si dopuci podczas uywania funkcji. Tego rodzaju
problemy, jeli zostan przeoczone, mog by trudne do wykrycia. Czy musisz uywa prototypw? Nie, moesz zamiast nich stosowa stary sposb deklarowania
funkcji (bez podawania argumentw), ale nie wi si z tym adne korzyci, natomiast
moe wynikn wiele kopotw.
Istnieje sposb, aby nie uywajc prototypu, zachowa jego zalety. Celem stosowania prototypw jest poinformowanie kompilatora, w jaki sposb powinno si uywa
funkcji, zanim natrafi on na jej pierwsze zastosowanie. Ten sam efekt moesz uzyska, umieszczajc definicj funkcji przed jej pierwszym uyciem. W ten sposb definicja dziaa jak swj wasny prototyp. Postpowanie takie stosuje si zwykle w przypadku krtkich funkcji:
// mamy tu i definicje, i prototyp
int imax(int a, int b) { return a >b ? a : b;}
int main()
{
int x,z;
z = imax(x, 50);
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
379
Rekurencja
Jzyk C pozwala, aby funkcja wywoywaa sam siebie. Proces ten nosi nazw
rekurencji (ang. recursion). Rekurencja jest narzdziem przydatnym, ale niekiedy trudnym w uyciu. Najwicej problemw sprawia zakoczenie rekurencji z uwagi na
to, e funkcja, ktra wywouje sam siebie, robi to bez koca, jeli nie zawiera odpowiednio sformuowanej instrukcji warunkowej.
Rekurencja moe by stosowana zamiast ptli. Czasami ptla stanowi rozwizanie
czytelniejsze, a czasami jednak przejrzystsza jest rekurencja. Implementacje rekurencyjne s bardzo czsto implementacjami eleganckimi, ale niekoniecznie bardziej
wydajnymi ni ptle.
Kup ksik
1:
2:
3:
4:
adres
adres
adres
adres
zmiennej
zmiennej
zmiennej
zmiennej
n:
n:
n:
n:
0x0012ff48
0x0012ff3c
0x0012ff30
0x0012ff24
Pole ksik
380
POZIOM
POZIOM
POZIOM
POZIOM
4:
3:
2:
1:
adres
adres
adres
adres
zmiennej
zmiennej
zmiennej
zmiennej
n:
n:
n:
n:
0x0012ff24
0x0012ff30
0x0012ff3c
0x0012ff48
Przeledmy program, aby zobaczy, jak dziaa rekurencja. Na pocztku funkcja main()
wywouje funkcj gora_i_dol(), przekazujc jej argument 1. W wyniku tego argument formalny n otrzymuje warto 1, co powoduje wywietlenie tekstu Poziom 1
przez pierwsz instrukcj printf(). Nastpnie, poniewa n jest mniejsze od 4, funkcja gora_i_dol (poziom 1) wywouje funkcj gora_i_dol (poziom 2) z argumentem
n + 1, czyli 2. Powoduje to przypisanie zmiennej n na drugim poziomie wartoci 2
oraz wywietlenie przez pierwsz instrukcj printf() acucha Poziom 2. W podobny
sposb kolejne dwa wywoania prowadz do wywietlenia tekstw Poziom 3 i Poziom 4.
Gdy osignity zostaje poziom 4, zmienna n jest rwna 4 i warunek instrukcji if nie
jest speniony. Funkcja gora_i_dol() nie zostaje ponownie wywoana. Zamiast tego
funkcja poziomu 4 przechodzi do drugiej instrukcji pisania, ktra wywietla tekst
POZIOM 4 (poniewa n wynosi 4). Nastpnie program wykonuje instrukcj return.
W tym momencie funkcja na poziomie 4 si koczy, a program wraca do funkcji,
ktra j wywoaa, czyli funkcji gora_i_dol() poziomu 3. Ostatni instrukcj wykonan na poziomie 3 byo wywoanie poziomu 4 w ramach instrukcji if. Poziom 3
wznawia wic dziaanie od kolejnej instrukcji, ktr jest druga instrukcja printf().
Powoduje to wywietlenie tekstu POZIOM 3. Nastpnie koczy si poziom 3, program
wraca do poziomu 2, ktry wywietla tekst POZIOM 2 itd.
Zauwa, e kady poziom rekurencji operuje na swojej prywatnej zmiennej n. Mona
to rozpozna po rnicy w adresach kolejnych zmiennych (w rnych systemach
bd miay one rne wartoci albo nawet bd inaczej sformatowane; wane, e adres na poziomie Poziom 1 jest taki sam jak na poziomie POZIOM 1 itd.).
Jeli wydaje Ci si to troch niejasne, wyobra sobie sytuacj, w ktrej mamy cig
wywoa funkcji funkcja fun1() wywouje fun2(), fun2() wywouje fun3()
i fun3() wywouje fun4(). Gdy fun4() koczy dziaanie, program wraca do funkcji
fun3(). Gdy fun3() koczy dziaanie, program wraca do fun2(). A gdy dziaanie
koczy fun2(), program wraca do fun1(). Rekurencja dziaa tak samo, z tym e zamiast fun1(), fun2(), fun3() i fun4() mamy jedn i t sam funkcj.
Podstawy rekurencji
Z pocztku rekurencja moe Ci si wydawa zagmatwana, przyjrzyjmy si wic kilku
podstawowym elementom, ktre pomog Ci j zrozumie.
Po pierwsze, kady poziom funkcji posiada swoje wasne zmienne. Zmienna n na
poziomie 1 jest inn zmienn ni n na poziomie 2 program utworzy wic cztery
niezalene zmienne o tej samej nazwie i rnych wartociach. Gdy program powrci
do pierwszego poziomu funkcji gora_i_dol(), zmienna n wci miaa warto 1,
ktr otrzymaa na pocztku (patrz rysunek 9.4).
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
381
RYSUNEK 9.4.
Zmienne w rekurencji
Kup ksik
Pole ksik
382
Rekurencja kocowa
W najprostszej postaci rekurencji wywoanie rekurencyjne znajduje si na kocu funkcji, tu przed instrukcj return. Nazywamy to rekurencj kocow (ang. tail recursion
lub end recursion). Jest to najprostsza forma rekurencji, poniewa dziaa tak samo jak
ptla.
Przyjrzyjmy si dwm wersjom funkcji obliczajcej silni jednej, wykorzystujcej ptl, i drugiej, stosujcej rekurencj. Silnia liczby cakowitej jest iloczynem
wszystkich liczb od 1 do tej liczby. Na przykad 3 silnia (zapisujemy: 3!) to tyle,
co 1*2*3. 0! ma z definicji warto 1; silnia nie jest okrelona dla liczb ujemnych.
Listing 9.7 przedstawia funkcj obliczajc silni za pomoc ptli for.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
383
return wyn;
}
long rsilnia(int n)
// wersja rekurencyjna
{
long wyn;
if (n > 0)
wyn = n * rsilnia(n-1);
else
wyn = 1;
return wyn;
}
Ptla nadaje zmiennej odp warto pocztkow 1, a nastpnie mnoy j kolejno przez
liczby od n do 2. W zasadzie zgodnie z definicj silni naleaoby wykona jeszcze
mnoenie przez 1, ale ten krok moemy pomin, poniewa nie wpywa on na wynik.
Sprbujmy stworzy teraz wersj wykorzystujc rekurencj. Kluczow rol odgrywa
tu fakt, i n! = n * (n-1)!. Jest to prawd, poniewa (n-1)! jest iloczynem
wszystkich dodatnich liczb cakowitych a do n-1; pomnoenie go przez n daje wic
iloczyn wszystkich liczb od 1 do n. Jeli zatem nasz funkcj nazwiemy rsilnia(),
to rsilnia(n) jest rwne n * rsilnia(n-1). Warto rsilnia(n) mona wic obliczy, korzystajc z wywoania rsilnia(n-1), jak pokazano na listingu 9.7. Rzecz jasna,
w pewnym momencie cig wywoa rekurencyjnych musi si zakoczy w tym
celu wystarczy zwrci warto 1, gdy n jest rwne 0.
Wersja rekurencyjna z listingu 9.7 daje w wyniku takie same dane wyjciowe, jak wersja poprzednia. Zauwa, e cho wywoanie rekurencyjne funkcji rsilnia() nie jest
ostatnim wierszem w funkcji, jest ono ostatni wykonywan instrukcj dla n > 0
mamy wic do czynienia z rekurencj kocow.
Kup ksik
Pole ksik
384
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
385
/* funkcja rekurencyjna */
Funkcja do_binar() powinna wypisa znak '0', jeli r ma warto liczbow 0, albo
znak '1', jeli r wynosi 1. Wyraenie r == 0 ? '0' : '1' stanowi wic nasz zminimalizowan metod konwersji pomidzy cyframi binarnymi a ich reprezentacj znakow.
Oto przykadowy przebieg dziaania programu:
Podaj liczbe calkowita (q konczy program):
9
Odpowiednik dwojkowy: 1001
Podaj liczbe calkowita (q konczy program):
255
Odpowiednik dwojkowy: 11111111
Podaj liczbe calkowita (q konczy program):
1024
Odpowiednik dwojkowy: 10000000000
Podaj liczbe calkowita (q konczy program):
q
Gotowe
Kup ksik
Pole ksik
386
Za i przeciw rekurencji
Rekurencja ma swoje plusy i minusy. Do plusw mona zaliczy midzy innymi to,
e rekurencja proponuje najprostsze rozwizania pewnych problemw programistycznych. Za minus natomiast trzeba uzna to, e niektre algorytmy rekurencyjne potrafi
byskawicznie wyczerpa zasoby pamici komputera. Rekurencja moe by rwnie
trudna do dokumentowania i pniejszych przerbek. Spjrzmy na przykad, ktry
ilustruje zarwno ze, jak i dobre aspekty rekurencji.
Cig Fibonacciego mona zdefiniowa nastpujco: pierwsza liczba Fibonacciego to 1,
druga liczba to 1, kada nastpna jest sum swoich dwch poprzedniczek. Zatem
pierwszych kilka elementw cigu to: 1, 1, 2, 3, 5, 8, 13. Cig Fibonacciego jest jednym
z ulubionych przez matematykw cigw; powicono mu nawet specjalne czasopismo. Nie wnikajmy w to jednak tutaj. Zajmijmy si lepiej utworzeniem funkcji, ktra
dla danej liczby cakowitej n zwraca warto n-tej liczby z cigu Fibonacciego.
Najpierw zalety rekurencji: rekurencja umoliwia proste definiowanie. Jeli nazwiemy
funkcj Fibonacci(), Fibonacci(n) powinno zwrci 1, jeli n rwna si 1 lub 2,
w przeciwnym razie funkcja zwraca sum Fibonacci(n-1) + Fibonacci(n-2):
unsigned long Fibonacci(unsigned n)
{
if(n>2)
return Fibonacci(n-1)+ Fibonacci(n-2);
else
return 1;
}
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
387
Kompilowanie programw
zawierajcych wicej ni jedn funkcj
Najprostszym sposobem na korzystanie z wielu funkcji jest umieszczenie ich w jednym pliku. Kompilacja pliku rdowego przebiega wwczas dokadnie tak samo
jak w przypadku pliku zawierajcego jedn funkcj. Inne warianty s w wikszym
stopniu uzalenione od systemu, o czym przekonasz si po przeczytaniu poniszych
podrozdziaw.
Unix
Przyjmujemy, e system Unix zawiera standardowy kompilator cc oraz e plik1.c
i plik2.c s dwoma plikami zawierajcymi funkcje jzyka C (klasyczny kompilator
cc ju raczej nie jest w uyciu, ale samo polecenie cc powinno by dostpne jako
alias dla faktycznej implementacji kompilatora, na przykad gcc czy clang). Ponisze
polecenie spowoduje skompilowanie obu plikw i utworzenie pliku wykonywalnego
o nazwie a.out:
cc plik1.c plik2.c
Dodatkowo tworzone s dwa pliki obiektowe plik1.o i plik2.o. Jeli pniej wprowadzisz zmiany w pliku plik1.c, ale nie w plik2.c, bdziesz mg skompilowa pierwszy
plik i poczy go ze skompilowan wersj pliku drugiego za pomoc nastpujcego
polecenia:
cc plik1.c plik2.o
Kup ksik
Pole ksik
388
Linux
Zakadamy, e system Linux ma zainstalowany kompilator GNU C gcc. Przypumy,
e plik1.c i plik2.c s dwoma plikami zawierajcymi funkcje jzyka C. Ponisze polecenie skompiluje obydwa pliki i utworzy plik wykonywalny o nazwie a.out:
gcc plik1.c plik2.c
Dodatkowo powstaj dwa pliki obiektowe plik1.o i plik2.o. Jeli pniej wprowadzisz
zmiany w pliku plik1.c, ale nie w pliku plik2.c, moesz skompilowa pierwszy plik i poczy go ze skompilowan wersj drugiego pliku, uywajc nastpujcego polecenia:
gcc plik1.c plik2.o
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
389
#define. Jeli wykorzystywane przez program funkcje umiecisz w kilku plikach, definicje staych bdziesz musia udostpni kademu plikowi z osobna. Najbardziej bezporednim sposobem, aby to osign, jest przepisanie dyrektyw do kadego pliku
pochania to jednak duo czasu i zwiksza moliwo popenienia bdu. Rozwizanie to powoduje rwnie powstanie powanego problemu z modyfikacj programu: jeli kiedy zmienisz jedn ze staych, bdziesz musia pamita, aby zrobi to we
wszystkich plikach programu. Znacznie lepszym wyjciem jest umieszczenie dyrektyw #define w pliku nagwkowym i uycie dyrektywy #include we wszystkich
plikach rdowych.
Umieszczanie prototypw funkcji i definicji staych w pliku nagwkowym wiadczy o dobrej technice programowania. Przyjrzyjmy si przykadowi. Zamy, e jeste
zarzdc sieci czterech hoteli. Pokj w kadym z hoteli ma inn cen, ale wszystkie
pokoje w danym hotelu kosztuj tyle samo. Jeli go zostaje na duej, za drug
noc paci 95% ceny pierwszej nocy, za trzeci 95% ceny drugiej nocy itd. (Pomimy
zagadnienie, czy taka polityka cenowa byaby opacalna). Potrzebujesz programu,
ktry umoliwia wybr jednego z hoteli oraz liczby nocy i na podstawie tych danych
oblicza cakowit opat za pobyt. Program powinien wywietla menu, ktre pozwoli
oblicza opaty dopty, dopki nie zdecydujesz si zakoczy pracy.
Listingi 9.9, 9.10 i 9.11 skadaj si na jedn z moliwych wersji takiego programu.
Pierwszy listing zawiera funkcj main(), ktra odzwierciedla ogln organizacj programu. Drugi listing zawiera wszystkie pozostae funkcje. Listing 9.11 przedstawia
plik nagwkowy, przechowujcy definicje staych i prototypy funkcji dla wszystkich
plikw rdowych. Jak by moe pamitasz, w rodowiskach Unix i DOS cudzysw
w dyrektywie #include "hotel.h" wskazuje, e doczany plik znajduje si w biecym
katalogu roboczym (czyli zazwyczaj w katalogu zawierajcym kod rdowy programu; jeli uywasz IDE, musisz dowiedzie si sam, czy i jak docza pliki nagwkowe do projektu).
Kup ksik
Pole ksik
390
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
391
Kup ksik
Pole ksik
392
Oprcz wieloplikowej organizacji program zawiera kilka innych interesujcych elementw. Funkcje menu() i pobierz_noce() pomijaj dane nienumeryczne, testujc
warto zwracan scanf() i wykorzystujc wywoanie scanf("%*s") w celu porzucenia acucha znakowego, jeli takowy zosta wprowadzony. Przedstawiony niej
fragment funkcji menu() sprawdza rwnoczenie, czy dane s numeryczne oraz czy
mieszcz si one w zadanych granicach:
while ((stan = scanf("%d", &kod)) != 1
(kod < 1 || kod > 5))
||
Kod ten wykorzystuje gwarancje, jakie daje jzyk C: po pierwsze, wyraenia logiczne
obliczane s od lewej do prawej; po drugie, obliczanie ulega zatrzymaniu w momencie, gdy warto wyraenia staje si jasna. W tym przykadzie warto zmiennej kod jest
sprawdzana tylko wtedy, gdy funkcji scanf() udao si odczyta liczb cakowit.
Przydzielenie poszczeglnych zada rnym funkcjom sprzyja udoskonalaniu programu. Pierwsza wersja funkcji menu() lub pobierz_noce() mogaby wykorzystywa proste wywoanie scanf() pozbawione elementw weryfikacji danych. Nastpnie,
gdyby okazao si, e wersja podstawowa dziaa poprawnie, mgby rozpocz jej
ulepszanie.
a adresem, pod ktrym zapisana jest zmienna ach jest 0B76. (Adresy na komputerach
PC s czsto wyraane w postaci wartoci szesnastkowych). Wwczas instrukcja:
printf("%d %p\n", ach, &ach);
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
393
funkcji
funkcji
funkcji
funkcji
main() ach =
main() och =
mikado() ach
mikado() och
2, a &ach = 0x7fff5fbff8e8
5, a &och = 0x7fff5fbff8e4
= 10, a &ach = 0x7fff5fbff8b8
= 2, a &och = 0x7fff5fbff8bc
Sposb zapisu adresw przez specyfikator %p zaley od implementacji. Wiele z nich stosuje zapis szesnastkowy; tutaj, skoro kada cyfra szesnastkowa odpowiada 4 bitom,
dwunastocyfrowe adresy szesnastkowe wskazuj na adresowanie z uyciem 48 bitw.
O czym wiadcz powysze dane wyjciowe? Po pierwsze, obie zmienne ach maj
rne adresy; to samo tyczy si zmiennych och. Oznacza to, e jak wspomnielimy
wczeniej komputer traktuje je jako cztery niezalene zmienne. Po drugie, wywoanie mikado(ach) przekazao warto (2) argumentu faktycznego (zmienna ach
z funkcji main()) do argumentu formalnego (zmienna och z funkcji mikado()).
Zauwa, e przekazana zostaa tylko warto. Obie zmienne (ach w main() i och
w mikado()) pozostaj niezalene.
Zwracamy uwag na drugi fakt, poniewa nie zachodzi on we wszystkich jzykach.
Na przykad w jzyku FORTRAN podprogram wpywa na zmienne podprogramu,
ktry go wywoa. Zmienna lokalna w podprogramie moe mie inn nazw, ale jej
adres jest zawsze taki sam jak zmiennej w podprogramie wywoujcym. Jzyk C dziaa
inaczej. Kada funkcja posiada swoje wasne zmienne. Jest to podane, poniewa
zapobiega zmianom pierwotnej zmiennej pod wpywem jakiego skutku ubocznego
wywoanej funkcji moe jednak rwnie sprawia trudnoci, o czym przekonasz
si w kolejnym podrozdziale.
Kup ksik
Pole ksik
394
nie dziaa, poniewa zanim program wykona drugi wiersz, pocztkowa warto zmiennej x zostanie zastpiona pocztkow wartoci zmiennej y. Potrzebny jest dodatkowy wiersz, ktry tymczasowo przechowa pierwotn warto zmiennej x.
temp = x;
x = y;
y = temp;
Kod ten moemy umieci w funkcji, a nastpnie napisa program, ktry j przetestuje. Rezultatem bdzie program podobny do listingu 9.13. Aby zaznaczy, ktre
zmienne nale do funkcji main(), a ktre do funkcji zamiana(), w pierwszej z nich
uylimy oznacze x i y, a w drugiej u i v.
Fatalnie! Wartoci nie zostay zamienione! Aby zobaczy, co poszo nie tak, dodajmy
do funkcji zamiana() kilka instrukcji pisania (patrz listing 9.14).
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
395
Jak wida, funkcja zamiana() dziaa prawidowo zamienia ona wartoci zmiennych
u i v. Problem dotyczy przekazania zmienionych wartoci do funkcji main(). Jak zwracalimy uwag wczeniej, funkcja zamiana() uywa innych zmiennych ni main(),
a wic zamiana wartoci u i v nie ma absolutnie adnego wpywu na x i y! Czy nie
moglibymy w jaki sposb wykorzysta instrukcji return? No c, moglibymy
zakoczy funkcj zamiana() nastpujcym wierszem:
return(u);
Nadaje to wprawdzie zmiennej x now warto, ale zupenie ignoruje zmienn y. Instrukcja return pozwala wysa do funkcji wywoujcej tylko jedn warto tutaj
za potrzebujemy zwrci dwie wartoci. Jak to osign? Wystarczy skorzysta ze
wskanikw.
Kup ksik
Pole ksik
396
Mwimy, e wsk wskazuje na ach. Rnica midzy wsk a &ach polega na tym, i
wsk jest zmienn, a &ach sta (inaczej: wsk jest modyfikowaln l-wartoci, a wyraenie
&ach jest r-wartoci). Jeli chcesz, moesz sprawi, aby zmienna wsk wskazywaa
gdzie indziej:
wsk = &och;
Operator dereferencji: *
Zamy, e wiesz, e wsk wskazuje na ach:
wsk = &ach;
Uycie adresu i operatora dereferencji jest raczej porednim sposobem osignicia tego
rezultatu std nazwa operator porednioci.
Deklarowanie wskanikw
Wiesz ju, w jaki sposb deklarowa zmienne typu int i innych typw podstawowych. Jak deklarujemy wskaniki? By moe przypuszczasz, e deklaracja wyglda
nastpujco:
pointer wsk;
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
397
Opis oglny:
Operator & pozwala uzyska adres zmiennej, ktra po nim nastpuje.
Przykad:
&siostra jest adresem zmiennej siostra.
Opis oglny:
Operator * zwraca warto przechowywan pod adresem wskazywanym przez
zmienn wskanikow.
Przykad:
siostra = 22;
wsk = &siostra;
wart = *wsk;
// wskanik do siostra
// przypisanie wart wartoci spod adresu wsk
Dlaczego nie? Poniewa nie wystarczy stwierdzi, e zmienna jest wskanikiem; naley
rwnie okreli, na jaki typ zmiennej bdzie ona wskazywaa. Powodem tego jest
fakt, i zmienne rnych typw zajmuj rne iloci pamici, a niektre operacje na
wskanikach wymagaj wiedzy o rozmiarze wskazywanej zmiennej. Ponadto program powinien wiedzie, jaki rodzaj danych jest przechowywany pod okrelonym
adresem. Typy long i float zajmuj na niektrych systemach tyle samo pamici,
ale wyraaj liczby w zupenie rny sposb. Oto jak powinna wyglda prawidowa deklaracja wskanika:
int * pi;
// pi jest wskaznikiem do zmiennej calkowitej
char * pc;
// pc jest wskaznikiem do zmiennej znakowej
float * pf, * pg; // pf i pg sa wskaznikami do zmiennych typu float
Sowa kluczowe int, char i float okrelaj typ wskazywanej zmiennej, a gwiazdka (*)
sygnalizuje, e deklarowana zmienna jest wskanikiem. Deklaracja int * pi; ustala
wic, e pi jest wskanikiem oraz e *pi naley do typu int (patrz rysunek 9.5).
Odstp pomidzy symbolem * a nazw wskanika nie jest wymagany. Wielu programistw uywa odstpu w deklaracji, ale pomija go przy dereferencji zmiennej.
Warto (*pc) zmiennej, na ktr wskazuje pc, jest typu char. A czym jest sama
zmienna pc? Nazywamy j wskanikiem do zmiennej typu char lub krcej wskanikiem do char. Jej warto (adres) jest na wikszoci systemw dodatni liczb
cakowit, nie naley jednak tych reprezentacji utosamia: na liczbach mona
wykonywa operacje, ktrych nie mona wykonywa na wskanikach (i odwrotnie).
Kup ksik
Pole ksik
398
RYSUNEK 9.5.
Deklarowanie
i korzystanie
ze wskanikw
Na przykad dozwolone jest mnoenie dwch liczb, ale nie mona pomnoy przez
siebie dwch wskanikw. Tak wic typ wskanikowy jest faktycznie istotnie rny
od typu liczbowego. Dlatego te standard ANSI C definiuje dla wskanikw osobny
specyfikator %p.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
399
/* ZLE */
co przekada si na
x = y;
Oglnie rzecz biorc, do funkcji moesz przekaza dwa rodzaje informacji o zmiennej.
Jeli uyjesz wywoania w postaci
funkcja1(x);
Kup ksik
Pole ksik
400
przekazujesz adres x. Pierwsza posta wymaga, aby definicja funkcji zawieraa argument formalny takiego samego typu jak zmienna x.
int funkcja1(int num)
Druga posta wymaga, aby definicja funkcji zawieraa argument formalny, bdcy
wskanikiem do waciwego typu:
int funkcja2(int * wsk)
Uyj pierwszej postaci, jeli funkcja potrzebuje wartoci, aby wykona jakie obliczenia
lub czynnoci. Uyj drugiej postaci, jeli zadaniem funkcji jest modyfikacja zmiennych w funkcji wywoujcej. Posta t stosowalimy od pocztku, korzystajc z funkcji
scanf(). Jeli chcemy na przykad pobra warto dla zmiennej num, uywamy wywoania scanf("%d", &num);.
Wskaniki pozwoliy nam obej ograniczenia stwarzane przez fakt, i zmienne funkcji zamiana() s lokalne. Dziki nim moglimy sign do funkcji main() i zmodyfikowa jej zmienne.
Uytkownicy jzykw Pascal i Modula-2 by moe rozpoznaj pierwsz posta jako
odpowiednik parametru staego, a drug posta jako odpowiednik parametru
zmiennego. Programici C++ poznaj zmienne wskanikowe i zapytaj, czy C te
(jak C++) ma typy referencyjne (odpowied brzmi: nie). Z kolei uytkownicy jzyka BASIC mog poczu si nieco zakopotani przedstawionymi tu technikami. Jeli
wskaniki wydaj Ci si dziwne i skomplikowane, moesz by pewny, e odrobina
praktyki sprawi, i przynajmniej niektre z ich zastosowa stan si proste i wygodne
(patrz rysunek 9.6).
RYSUNEK 9.6.
Nazwy, adresy
i wartoci
na komputerze
adresowalnym
bajtowo, takim
jak PC
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
401
Podsumowanie. Funkcje
Posta:
Typowa definicja funkcji w ANSI C ma nastpujc posta:
typ zwracany nazwa(lista argumentw)
tre funkcji
Lista argumentw to lista deklaracji zmiennych, rozdzielonych przecinkami. Zmienne niebdce argumentami deklarujemy w czci gwnej funkcji, ograniczonej
klamrami.
Przykady:
int roznica(int x, int y)
{
int z;
z = x y;
return z;
}
Kup ksik
// wersja ANSI C
// poczatek tresci funkcji
// deklaracja zmiennej lokalnej
// zwrocenie wartosci
// koniec tresci funkcji
Pole ksik
402
Przekazywanie wartoci:
Do przekazywania wartoci z funkcji wywoujcej do funkcji wywoywanej su
argumenty. Jeli zmienne a i b maj wartoci 5 i 2, to wywoanie
c = roznica(a,b);
Kluczowe zagadnienia
Jeli chcesz programowa w jzyku C z powodzeniem i efektywnie, musisz zrozumie funkcje. Podzia programu na kilka funkcji jest nie tylko przydatny, ale nawet
konieczny. Jeli skorzystasz z praktyki przydzielania kadej funkcji dokadnie do
jednego zadania, Twoje programy stan si atwiejsze do zrozumienia i poprawiania. Upewnij si, e wiesz, jak funkcje przekazuj midzy sob dane to znaczy,
e rozumiesz, jak dziaa mechanizm argumentw i zwracania wartoci przez funkcje.
Wiedz, e argumenty i zmienne lokalne maj wewntrz funkcji zasig prywatny;
dlatego te zadeklarowanie dwch zmiennych o tej samej nazwie w rnych funkcjach
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
403
Podsumowanie rozdziau
Funkcje s elementami, z ktrych zoone s programy. Kada funkcja powinna mie
jedno dobrze okrelone zadanie. Do przekazywania wartoci do funkcji su argumenty, a do zwracania wartoci sowo kluczowe return. Jeli funkcja zwraca warto nienalec do typu int, musisz okreli jej typ zarwno w definicji, jak i w obszarze deklaracyjnym funkcji wywoujcej. Jeli chcesz, aby funkcja moga wpywa na
zmienne w funkcji wywoujcej, uyj adresw i wskanikw.
Standard ANSI C udostpnia prototypy funkcji przydatne narzdzie, ktre daje kompilatorom moliwo sprawdzania poprawnoci wywoa funkcji pod ktem liczby i
typw przekazywanych parametrw.
Funkcja w jzyku C moe wywoywa sam siebie; zjawisko to nosi nazw rekurencji.
Niektre problemy obliczeniowe dobrze pasuj do rekurencji, ale sama rekurencja
moe by nieefektywna czasowo i pamiciowo.
Pytania sprawdzajce
Odpowiedzi na pytania sprawdzajce znajdziesz w dodatku A.
1. Na czym polega rnica midzy argumentem faktycznym i formalnym?
2. Napisz nagwki funkcji (w stylu ANSI) odpowiadajce poniszym opisom (pomi
tre funkcji):
a) funkcja pakiet() wywietla liczb zer okrelon przez przekazany jej argument typu int.
b) funkcja bieg() pobiera dwa argumenty typu int i zwraca typ int.
c) funkcja zgadula() nie pobiera argumentw i zwraca warto typu int.
d) funkcja podloga() pobiera zmienn typu double oraz adres zmiennej typu
double i zapisuje przekazan zmienn pod podanym adresem.
3. Napisz nagwki funkcji (w stylu ANSI) odpowiadajce poniszym opisom
(pomi tre funkcji):
a) funkcja n_znak() pobiera argument typu int, a zwraca argument typu char.
b) funkcja cyfry() pobiera argument typu double oraz argument typu int,
a zwraca liczb typu int.
Kup ksik
Pole ksik
404
c) funkcja ktory() pobiera dwa adresy wartoci typu double i zwraca adres
wartoci typu double.
d) funkcja los() nie pobiera argumentw, a zwraca warto int.
4. Zaprojektuj funkcj zwracajc sum dwch liczb cakowitych.
5. Jakie zmiany (jeli w ogle) musiaby wprowadzi w funkcji z pytania 4, aby
sumowaa ona dwie liczby typu double?
6. Zaprojektuj funkcj zmien(), ktra pobiera dwie zmienne typu int o nazwach
x i y i przypisuje im odpowiednio warto ich sumy i rnicy.
7. Czy ponisza definicja funkcji jest poprawna?
void salami(num)
{
int num, licznik;
for (licznik = 1; licznik <= num; num++)
printf(" o salami mio!\n");
}
a) Napisz funkcj, ktra wywietla menu skadajce si z czterech ponumerowanych opcji (powinno ono wyglda tak, jak powyej).
b) Napisz funkcj pobierajc dwa argumenty typu int: granic doln i grn.
Powinna ona odczyta z klawiatury liczb cakowit. Jeli liczba nie mieci si
w granicach, funkcja powinna ponownie wywietli menu (korzystajc z funkcji
z punktu a) i pobra now warto. W przypadku wpisania liczby mieszczcej
si w granicach funkcja powinna zwraca j do funkcji wywoujcej. Wpisanie
wartoci nieliczbowej powinno spowodowa zwrcenie z funkcji wartoci 4.
c) Napisz program atrap wykorzystujcy funkcje z punktw a. i b. tego pytania.
Sowo atrapa oznacza, e program nie musi naprawd wykonywa czynnoci
zapowiadanych w menu; powinien on po prostu wywietla opcje i pobiera
odpowied uytkownika.
mwiczenia
1. Zaprojektuj funkcj min(x,y), zwracajc mniejsz z dwch wartoci typu double, i przetestuj j za pomoc prostego programu.
2. Zaprojektuj funkcj rzad_zn(ch,i,j), wywietlajc znak ch w kolumnach od i do j.
Wyprbuj j w prostym programie.
Kup ksik
Pole ksik
Rozdzia 9. FUNKCJE
405
3. Napisz funkcj, ktra pobiera trzy argumenty: znak oraz dwie liczby cakowite.
Pierwsza liczba okrela liczb razy, jak naley wywietli znak w jednym wierszu;
druga liczba okrela liczb wierszy. Napisz program, ktry wykorzystuje t funkcj.
4. redni harmoniczn dwch liczb uzyskujemy przez znalezienie odwrotnoci danych liczb, wycignicie z nich redniej arytmetycznej i obliczenie odwrotnoci
otrzymanego wyniku. Napisz funkcj, ktra pobiera dwa argumenty typu double
i zwraca ich redni harmoniczn.
5. Napisz i sprawd funkcj o nazwie wieksze_od(), ktra zamienia zawarto obu
zmiennych typu double wiksz z nich. Na przykad wieksze_od(x,y) przypisze obu zmiennym x i y warto wikszej z nich.
6. Napisz i sprawd funkcj, ktra pobiera adresy trzech wartoci typu double
i przepisuje najmniejsz z tych wartoci pod pierwszy adres, warto rodkow
pod drugi adres, a warto najwiksz pod trzeci adres.
7. Napisz program, ktry odczytuje znaki z wejcia standardowego a do wystpienia
koca pliku. Dla kadego znaku program powinien informowa, czy jest on liter.
Jeli tak, program powinien rwnie wywietli numer litery w alfabecie. Na przykad litery c i C obie maj numer 3. Wykorzystaj funkcj, ktra pobiera znak jako
argument i zwraca jego numer w alfabecie, jeli jest on liter; w przeciwnym
wypadku wartoci zwracan powinno by 1.
8. W rozdziale 6. napisalimy funkcj potega(), ktra zwracaa wynik podniesienia liczby typu double do potgi naturalnej (patrz listing 6.20). Ulepsz t funkcj
tak, aby poprawnie obsugiwaa potgi ujemne. Ponadto wbuduj w funkcj zaoenie, e 0 do dowolnej potgi wynosi 0 oraz e podniesienie dowolnej liczby
do potgi 0 daje wynik 1 (funkcja powinna zasygnalizowa, e 0 do potgi 0 nie
zadziaa i e funkcja zamiast tego uyje wartoci 1). Uyj ptli. Przetestuj funkcj
w programie.
9. Ponownie wykonaj wiczenie 8. tym razem uyj funkcji rekurencyjnej.
10. Uoglnij funkcj do_binar z listingu 9.8 do postaci do_podst_n(), pobierajcej
jako drugi argument warto z przedziau od 2 do 10. Nastpnie powinna ona
wywietli liczb pobran jako pierwszy argument w odpowiadajcym drugiemu
argumentowi systemie liczbowym. Na przykad funkcja do_podst_n(129, 8)
wywietli 201, co jest semkowym odpowiednikiem liczby 129. Sprawd dziaanie
funkcji, piszc wykorzystujcy j program.
11. Napisz i przetestuj funkcj Fibonacci(), ktra zamiast rekurencji do obliczania
kolejnych wyrazw cigu Fibonacciego uywa ptli.
Kup ksik
Pole ksik
406
Kup ksik
Pole ksik
SKOROWIDZ
A
Kup ksik
ustawianie, 702
zerowanie, 702
blok, 171, 197, 533
bloki bez klamr, 541
bd, 80
obcinania wartoci, 109,
224
semantyczny, 71, 876
skadniowy, 70, 876
bufor, 325
wejciowy, 325, 337
wyjcia, 118
buforowanie, caching, 575,
591, 606
pene, 326
wierszowe, 326
C
C++, 10061012
ciao funkcji, 59
czarna skrzynka, 370
czas trwania
obiektu, 533
zmiennej, 537
cz
gwna funkcji, 64
uamkowa, 105
czytelno programw, 65
Pole ksik
D
dane, 79
binarne, 610
tekstowe, 610
wejciowe, 157, 343, 348
wyjciowe, 139
data i czas, 975
debugger, 73
debugowanie, 35
definicja
funkcji, 364, 368, 401, 436
interfejsu, 823
kolejki, 822
acuchw, 464
makra, 734
tablicy acuchw, 466
zmiennej strukturalnej,
628
definicje standardowe, 957
degradacja, 200
deklaracja
_Static_assert, 781
argumentw, 573
argumentw tablicy, 426
definiujca, 549
nawizujca, 549
struktury, 627
tablicy, 407
tablicy struktur, 634
unii, 685
wskanikw, 396
z wyprzedzeniem, 258
zmiennych, 58, 87, 927
typu char, 97
zmiennoprzecinkowych
, 106
dekrementacja, 186, 190
dereferencja, 396
wskanikw, 778
niezainicjalizowanych,
434
dugo acucha, 127
dodawanie do wskanika,
423, 457
dokumentacja, 66, 915
Kup ksik
doczanie
bibliotek, 765
plikw, 746, 765
dopenienie
dwjkowe, 149
jedynkowe, 699
dostp
automatyczny, 764
do biblioteki, 764
do pliku, 588
do skadnikw struktury,
640
sekwencyjny, 842
swobodny, 602, 615, 841
drzewo binarne, ATD, 664,
844, 868, 913
AVL, 869
dodawanie pozycji, 849
implementacja, 849
interfejs, 846
przechodzenie, 858
testowanie, 863
usuwanie, 858
usuwanie pozycji, 853
znajdowanie pozycji, 852
drzewo wyraenia, 181
dwuznaki, 992
dynamiczna tablica, 565
dynamiczny przydzia
pamici, 453, 569, 570
dyrektywa
#define, 133, 389, 674, 733
#elif, 755
#else, 751
#endif, 751
#error, 758
#if, 755
#ifdef, 751
#ifndef, 753
#include, 55, 164, 389, 746
#line, 757
#pragma, 758
#undef, 750
STDC_FP_CONTRACT,
1003
dyrektywy preprocesora, 55,
731
dziaania na wskanikach,
430
dziecko, 844
E
efektywno, 25
elastyczne skadniki
tablicowe, 654
elastyczno, 26
element tablicy, 251
EOF, end of file, 329, 595
etykieta, 305
case, 307
struktury, 628
etykiety wielokrotne, 308
F
fasz, 225
FIFO, first in, first out, 822
flaga, 285
formatowanie acuchw
znakowych, 146
formaty
zmiennoprzecinkowe, 110
funkcja, 38, 361
abort(), 780
atan(), 768
atan2(), 768
atexit(), 773, 774
atof(), 521
atoi(), 520
atol(), 521
calloc(), 568
clock(), 790
exit(), 592, 773
fclose(), 596
fabs(), 224
feof(), 612
ferror(), 612
fflush(), 608
fgetpos(), 606
fgets(), 129, 477, 524, 601,
627
fopen(), 593, 606
fpos_t, 606
Pole ksik
SKOROWIDZ 1015
Kup ksik
strstr(), 510
strtod(), 521
strtol(), 521
strtoul(), 521
sumuj2d(), 451
time(), 559
tolower(), 277
toupper(), 277, 517
ungetc(), 608
wczytaj(), 483
funkcje
bezpowrotne, 764
do obsugi znakw, 940
do obsugi znakw
szerokich, 981987
dotyczce liczb
zespolonych, 938, 939
inline, 1011
lokalizacji, 947
acuchowe, 463, 491,
970972
matematyczne, 767,
949954, 973
oglnego uytku, 772,
964970
porwnujce, 778
przetwarzajce tablice,
446
pseudolosowe, 555
statyczne, 554
sygnaw, 955
w setjmp.h, 954
w time.h, 976, 977
w wctype.h, 986
we-wy, 56, 138, 323,
962964
we-wy dla szerokich
znakw, 981
wplatane, 745, 761, 762
z argumentami, 203
z argumentem VLA, 450
zewntrzne, 554
znakowe, 276
funkcje-makro
diagnostyczne, 937
G
GNU C, 42
GNU Compiler Collection, 41
I
IDE, Integrated Development
Environment, 35, 43, 44
identyfikator, 532
implementacja
drzewa binarnego, 849
funkcji interfejsu, 828
interfejsu, 815
reprezentacji danych, 824
indeks, 252, 414
indeksowanie tablic, 416
inicjalizacja
oznaczona, 412
struktury, 630
tablicy, 412
tablicy dwuwymiarowej,
420
wskanika do struktury,
639
zmiennej, 87
zmiennej typu char, 97
zmiennych
zewntrznych, 547
inicjalizatory oznaczone
struktur, 631
inicjalizowanie
tablic, 468
tablic znakw, 466
zmiennych
automatycznych, 542
inkrementacja, 186
instrukcja, 169, 194, 271, 930
break, 301, 305, 313, 935
continue, 298, 314, 936
do while, 932
for, 932
goto, 311, 314, 936
if, 270, 933
if else, 272, 274
printf, 54
pusta, 223
Pole ksik
instrukcja
return, 371
switch, 304, 305, 310, 934
typedef, 768
while, 931
instrukcje
deklaracji, 58
przypisania, 62, 74, 195
rozgazienia, 271
skoku, 315
sterujce, 215, 269
strukturalne, 195
wyraeniowe, 194
wywoania funkcji, 195
zoone, 197
zwrotu, 64
interfejs, 813, 823
dla kolejki, 827
dla listy, 808
drzewa binarnego, 846
uytkownika, 337
J
jednostka
centralna, CPU, 28
pamici, 423
translacji, 536
jzyk
C, 23
C++, 1006
jzyki
maszynowe, 29
wysokiego poziomu, 29
K
K&R C, 30
klamry, 58
klasa zmiennych, 410, 532,
538, 552, 570, 925, 928
a funkcje, 554
automatyczna, 580
rejestrowa, 580
statyczna
bez cznoci, 580
Kup ksik
z cznoci
wewntrzn, 580
z cznoci
zewntrzn, 580
klasyfikacja znakw
szerokich, 985
kod
startowy, 38, 39
wplatany, 744
wykonywalny, 26, 35, 49
kolejka, 822
implementacja, 828
interfejs, 823, 827
symulowanie, 834
testowanie, 832
typu FIFO, 822
kolejno oblicze, 180, 182
dla operatorw
logicznych, 290
wyrae logicznych, 921
komentarz, 36, 54, 57, 217, 335
do prototypu, 810
kompilacja, 35, 40
DOS, 388
Linux, 38, 42, 388
Unix, 39, 387
warunkowa, 751
Windows, 43
kompilator, 29, 39, 68, 74
cc, 40, 42
Cygwin, 43
gcc, 41, 542
MinGW, 43
kompilatory Borland C, 633
kompresja
bezstratna, 795
pliku, 597
komputery Mac, 45
komunikacja pomidzy
funkcjami, 398
koniec pliku, 159, 329
konstrukcja
if else, 272, 278, 280
switch case, 304, 307
konwersja, 148
argumentw typu float,
144
formatu typw
cakowitych, 946
acuchw, 979
acuchw do liczb, 520
typu, 199, 779
korze, root, 844
korzystanie z interfejsu, 813
kwalifikator, 929
_Atomic, 577
typu ANSI C, 572
typu const, 572, 1008
typu restrict, 576
typu volatile, 575
L
liczby
binarne, 694
cakowite, 85, 806, 946,
960
bez znaku, 925
ze znakiem, 925
ze znakiem, 695
zespolone, 84, 926, 937,
1004, 1011
zmiennoprzecinkowe, 85,
105
linker, 35, 3841, 49, 875
lista
interfejs, 808
lista czona, 797801, 826
a tablice, 840
tworzenie, 803
wywietlanie, 802
literay
liczb cakowitych, 88
acuchowe, 465, 524
zoone, 453, 652
LLVM, 41
lokalizacja, 162, 947
l-warto, 173, 532
modyfikowalna, 174
Pole ksik
SKOROWIDZ 1017
M
makra, 734
a funkcje, 744
argumentw, 956
kategorii, 947
o zmiennej liczbie
argumentw, 743
predefiniowane, 756
sygnaw, 955
typu void, 955
w math.h, 949
w float.h, 943, 945
w stdalign.h, 956
w stdbool.h, 957
w stddef.h, 958
w wchar.h, 980
makro
_Noreturn, 970
assert(), 780
mantysa, 105, 109
maska, 701
Kup ksik
mechanika programowania,
37
menu, 349
metoda dopenienia
dwjkowego, 695
jedynkowego, 696
metody inicjalizacji tablicy,
421
Microsoft Visual Studio, 45
moc, 26
model reprezentacji
zmiennoprzecinkowej, 998
modyfikacja zmiennych, 394
modyfikator, 675
*, 160
const, 135
modyfikatory
printf(), 141, 146
scanf(), 156, 157
modyfikowalna l-warto,
532
modyfikowanie programu,
36
N
nagwek, 55
funkcji, 64
najszybsze typy o
minimalnym rozmiarze,
989
nawias
klamrowy, 541
kwadratowy, 416
nazwy
funkcji-makr, 745
staych symbolicznych, 133
tablicy, 457
zmiennych, 60
zmiennych
zewntrznych, 549
znakw, 993
niedomiar, 109
zmiennoprzecinkowy,
108
nieprawidowe argumenty
funkcji, 375
nieskoczono, 108
niezgodno konwersji, 148
notacja
naukowa, 105
tablicowa, 438
wskanikowa, 430
wykadnicza, 105
O
obcinanie, 179
w kierunku do zera, 180
obiekt, 532
danych, 173
obliczanie wartoci, 1000
obliczenia numeryczne, 997
obsuga
liczb zespolonych, 1004
acuchw, 970
plikw, 587
rozszerzonych zbiorw
znakw, 991
sygnaw, 954
szerokich znakw, 1011
typw logicznych, 957
znakw, 939
znakw szerokich, 979
obszar zastosowa, 27
odczytywanie plikw, 618
odwracanie
bitw, 703
kolejnoci dziaa, 384
odwzorowanie znakw
szerokich, 985
offset, 252
ograniczenia const, 820
okrelenie celw programu,
33
oktet, 694
operacje niepodzielne, 957
operand, 174, 203
operator, 169, 919
!=, 276
##, 742
*=, 255
_Alignof, 924
Pole ksik
operator
adresu, &, 392, 397
alternatywy bitowej, |,
700
bitowej alternatywy
wyczajcej, ^, 700
dekrementacji, --, 186
dereferencji, *, 396
dodawania, +, 175
dzielenia, /, 179
inkrementacji, ++, 186
koniunkcji bitowej, &, 699
mnoenia, *, 177
modulo, %, 184
negacji bitowej, ~, 699
odejmowania, -, 176
poredniej
przynalenoci, ->, 640,
668
porednioci, 396
przecinkowy, 241, 243
przekierowania, 333, 335
przesunicia w lewo, <<,
704
przesunicia w prawo,
>>, 704
przynalenoci, ., 630, 668,
922
przynalenoci
poredniej, 923
przypisania, =, 172, 203
relacyjny, 191
rwnoci, ==, 217
rzutowania, 202, 203
sizeof, 114, 131, 143, 183,
924
warunkowy, ?:, 296, 298,
315, 922
operatory
arytmetyczne, 203, 919
bitowe, 698, 715, 923
bitowe przesunicia, 704,
705
dotyczce wskanikw,
922
dwuargumentowe, 176,
296
Kup ksik
jednoargumentowe, 176,
296
logiczne, 287291, 921
przypisania, 239, 243, 920
relacyjne, 223, 231, 920
struktur i unii, 922
trjargumentowe, 296
znaku, 176, 922
opis funkcji, 765
oprnianie bufora, 118
ostrzeenia, 80
P
pami, 579
operacyjna, 28
parametry
aktualne, 62
faktyczne, 204
formalne, 62, 204, 436
wskanikowe, 428
pene wyraenie, 196
ptla, 170, 188
do while, 245, 247
for, 234, 235, 242, 244
while, 170, 198, 216, 219,
259
ptle
liczce, 232
nieokrelone, 232
nieskoczone, 222
odczytujce, 219
zagniedone, 249
pielgnowanie, 36
pisanie programu, 33
pisownia operatorw, 946
plik, 327, 536, 587, 588
assert.h, 780, 937
complex.h, 772, 937, 1005
conio.h, 327
ctype.h, 277, 515, 890, 939
errno.h, 940
fenv.h, 941, 1002
float.h, 114, 136, 164, 943
hotel.h, 391
inttypes.h, 104, 946
iso646.h, 289
kolejka.c, 831
limits.h, 102, 136, 164
locale.h, 947
math.h, 767, 949, 1003
setjmp.h, 954
signal.h, 954
stdalign.h, 724, 956
stdarg.h, 785, 956
stdatomic.h, 957
stdbool.h, 285, 294, 957
stddef.h, 957
stdint.h, 958, 960
stdio.h, 54, 69, 329, 597,
962
stdlib.h, 558, 773, 964
stdnoreturn.h, 970
string.h, 130, 491, 524, 970
tgmath.h, 973
threads.h, 974
time.h, 674, 975
uchar.h, 978
wchar.h, 978
wctype.h, 986
pliki
kodu obiektowego, 38
kodu rdowego, 34, 37,
44, 49
nagwkowe, 25, 69, 388,
746
obiektowe, 38
standardowe, 590
tekstowe, 333
wykonywalne, 38, 41
rdowe, 37, 40
plikowe wejcie-wyjcie, 599
pluskwy, bugs, 35
poddrzewo, 845
podstawianie w czasie
kompilacji, 133
podwyraenia, 193
pola bitowe, 698, 710, 719
a operatory bitowe, 715
pola struktury, 627
pole, 659
porzdek sortowania, 500
powtarzanie danych
wejciowych, 324
Pole ksik
SKOROWIDZ 1019
Kup ksik
przepenienie, 108
bufora, 476
zmiennych cakowitych,
93
przepyw sterowania, 935
przesunicie, offset, 603
w prawo, 704
wzgldne, 603
przeszukiwanie
dwudzielne, 842
sekwencyjne, 842
przetwarzanie wstpne, 55
przydzia pamici, 563
dla struktury, 629
dla tablicy, 467
przypisanie, 62
wskanikw, 1010
przyrostek
f, 107
l, 94
ll, 94
pseudokod, 218
punkty sekwencyjne, 196
Q
quick sort, 775
R
RAM, random access
memory, 28
raportowanie bdw, 940
rejestr, register, 28
rekord, 659, 664
rekurencja, 379386
kocowa, 382
podwjna, 386
reprezentacja
danych, 793, 794
koloru, 713
acuchw, 463
wartoci
zmiennoprzecinkowej,
697
znak-modu, 695
rozgazienia, 269, 271
S
sekwencje
sterujce, 63, 99, 117
trjznakw, 991
skalar, 408
skadniki
struct lconv, 948, 949
struktury, 627
struktury timespec, 975
tablicy struktur, 634
skoki, 269, 313, 935
nielokalne, 954
sowo, 84
sowo kluczowe, 58, 73
_Alignas, 722
_Alignof, 722
_Generic, 759
const, 409, 436, 573
return, 372, 644
static, 575
struct, 628
typedef, 673
void, 377
sortowanie
acuchw, 512
przez selekcj, 514
wskanikw, 513
specyfikator
_Alignas, 722
_Alignof, 722
auto, 551
extern, 552
formatu, 88, 138, 977
Pole ksik
specyfikator
#, 56
%c, 101
%d, 88, 147
%e, 145
%f, 145
%hd, 95
%ho, 95
%ld, 94
%lld, 95
%llu, 95
%o, 90
%p, 393
%s, 127, 129, 485
%u, 94
%x, 90
&&, 288
register, 551
static, 552
specyfikatory
klasy zmiennych, 539, 551
konwersji, 144147
scanf(), 156
sposoby tworzenia tablic, 565
sprawdzanie
poprawnoci danych, 343
wartoci bitu, 703
stae, 83
cakowite, 961
rozszerzone, 961, 991
zapis, 100
enum, 670
jawne, 133
acuchowe, 129, 465, 524
standardowe, 136
symboliczne, 132, 137,
437, 733, 960
typu char, 1007
typu int, 88
typu long, 94
w stdlib.h, 965
wyraenie cakowite, 416
zmiennoprzecinkowe, 106
znakowe, 97
stan
programu, 72
przesunicia, 979
Kup ksik
standard
ANSI/ISO C, 31
C11, 32
C99, 31
zmiennoprzecinkowy
IEC, 997
standardowe
pakiety we-wy, 328, 590,
607
wejcie-wyjcie, 591, 606
wyjcie dla bdw, 590
standardy C, 30, 40
statyczne zmienne
wewntrzne, 545
zewntrzne, 550
sterowanie ptl while, 303
stos, stack, 151, 376, 912
stosowanie, Patrz uywanie
struktura, 685
struct tm, 976
timespec, 975
struktury, 625, 1009
a funkcje, 641
a pliki, 659
adres, 642
anonimowe, 657
deklaracja, 627
dostp do skadnikw,
640
hierarchiczne, 844
inicjalizacja, 630
jako argument, 644
literay zoone, 652
odwoania do
skadnikw, 630
pami, 632
tablice znakowe, 649
wskaniki, 638, 648
zagniedone, 636
zapisywanie, 659
strumienie wejciowe, 348
strumie, 327, 328
binarny, 904
stdin, 332
tekstowy, 904
styl, 198
sygna, 954
rodowisko
IDE, 388
zmiennoprzecinkowe,
941
T
tablice, 126, 251, 407, 430, 456
a wskaniki, 467, 469
dwuwymiarowe, 418, 457
dynamiczne, 565
acuchw znakowych,
466, 471
nierwne, 473
o zmiennym rozmiarze,
VLA, 417, 449, 458, 569
ochrona zawartoci, 435
struktur, 632, 635
struktur a funkcje, 657
tablic, 442
w roli kolejki, 825
wielowymiarowe, 417,
442
wielowymiarowe
a funkcje, 446
znakowe, 127
testowanie, 35
drzewa, 863
kolejki, 832
tokeny, 737
translacja programu, 732
tre funkcji, 64
trjznaki, 991
Pole ksik
SKOROWIDZ 1021
tryb
binarny, 588, 604, 609, 615
dla funkcji fopen(), 594
przedrostkowy
operatorw ++ i --, 186
przyrostkowy
operatorw ++ i --, 186
tekstowy, 588, 590, 604
tryby sterujce, 1002
trygonometria, 768
tworzenie
funkcji, 363
interfejsu uytkownika,
337
listy, 803
spisu ksiek, 626
staych symbolicznych, 437
tablic, 565
typ danych
_Bool, 84, 102, 112, 229,
285
_Complex, 84
_Imaginary, 84
Boolean, 112
char, 83, 96, 163
double, 105, 106
float, 83, 105, 144
int, 83, 86
long, 83
long double, 105, 106
long int, 91
long long int, 91
short, 83
short int, 91
size_t, 511
time_t, 559, 674
unsigned int, 91
typy
bez znaku, 102
biblioteki fenv.h, 942
cakowite, 84, 91, 119, 958
bez znaku, 112
przechowujce wartoci
wskanikw, 990
rozszerzone, 987
ze znakiem, 111
danych, 59, 83, 114, 925
Kup ksik
funkcji, 373
kwalifikowane, 572
logiczne, 926, 957, 1011
o rozmiarze
dokadnym, 103, 958,
988
minimalnym, 103, 959,
989
maksymalnym, 960
pochodne, 456
przenone, 102
rzeczywiste, 926
w stddef.h, 957
w stdlib.h, 964
w time.h, 975
w wchar.h, 980
wyliczeniowe, 669
ze znakiem, 102
zespolone i urojone, 110,
112
zmiennoprzecinkowe, 84,
112, 120, 770, 943
znakowe, 112, 925
zwracane funkcji, 401
U
ukrywanie danych, 810, 822
uamki binarne, 696
Unicode, 97
unie, 665, 685, 716, 1009
anonimowe, 667
uniwersalne nazwy znakw,
UCN, 993
uruchomienie programu, 35
ustawianie bitw, 702
ustawienia lokalne, 947
usuwanie
bdw, 35, 69
drzewa, 858
pozycji, 857
wza, 855
uywanie
asercji, 780
instrukcji goto, 312
kwalifikatora const, 436,
439, 573
kwalifikatorw, 578
sowa enum, 670
unii, 666
zmiennych
zewntrznych, 548
V
VLA, variable-length array,
417, 449
W
wady, 26
wartoci
semkowe, 89
szesnastkowe, 89
zdenormalizowane, 999
znormalizowane, 999
warto
EXIT_FAILURE, 565
EXIT_SUCCESS, 566
NaN, 109
size_t, 184
wyraenia, 174
zwracana funkcji, 255,
258, 371
printf(), 151
scanf(), 159
warunek
wejcia, 221
wyjcia, 245
wczytywanie acuchw, 475
wejcie, 323
buforowane, 325
liczbowe, 340
niebuforowane, 326
standardowe, 332
znakowe, 340
wejcie-wyjcie
niskiego poziomu, 327,
590
plikowe, 606
wysokiego poziomu, 590
wze, node, 809
wielokrotne deklaracje, 67
Pole ksik
wiersz, 153
logiczny, 732
polece, 517
waciwoci
klas zmiennych, 928
liczb cakowitych, 806
wprowadzanie z klawiatury,
327
wskanik, pointer, 392, 423,
467, 473
do funkcji, 677
do plikw
standardowych, 597
do staej, 438
do struktur, 638, 639, 648
do tablic, 422, 430
do tablic
wielowymiarowych,
439, 442
do typu char, 564
do typu void, 564
do znakw, 649
gwny, 799
plikowy, 594
stderr, 597
stdin, 597
stdout, 597
pusty, 479, 482
wskaniki
dereferencja, 434
dziaania, 432, 433
zgodno, 444
wspdzielona przestrze
nazw, 672
wsprzdne biegunowe, 790
wstawianie elementu
do listy czonej, 841
do tablicy, 841
wyjcie, 323
wyliczenia, 686, 1010
wyraenia, 169, 199, 208, 271,
930
logiczne, 291, 921
relacyjne, 219, 223, 233,
287, 315, 920
warunkowe, 296
Kup ksik
wyrwnanie, 956
danych, 722
wywietlanie
listy, 802
acuchw, 153, 486
wartoci, 88
semkowych, 90
szesnastkowych, 90
typw, 94
zmiennoprzecinkowych,
107
wielu wartoci, 67
wywoanie funkcji, 63, 369
Z
zagniedanie instrukcji if,
280, 283
zakres
dla typw, 92
tablic, 414
zalety, 24
zaokrglanie, 1001
zapisywanie
plikw, 618
struktury, 660
zarzdzanie pamici, 531,
563
zasada modularnoci, 254
zasig
blokowy, 533, 543
funkcji, 534
plikowy, 535
prototypu funkcji, 535
zmiennej, 533, 579
zastosowania plikw
nagwkowych, 749
zbir instrukcji, 28
zerowanie bitw, 702
zewntrzna klasa zmiennych,
545
zgodno wskanikw, 444
ziarno, 556
zintegrowane rodowisko
programistyczne, IDE, 35,
43, 746
Pole ksik