You are on page 1of 74

Tytu oryginau: C Primer Plus, 6th Edition

Tumaczenie: Przemysaw Szeremiota


ISBN: 978-83-283-1470-2
Authorized translation from the English language edition, entitled:
C PRIMER PLUS, Sixth Edition; ISBN 0321928423; by Stephen Prata;
published by Pearson Education, Inc, publishing as Addison Wesley.
Copyright 2014 Pearson Education, Inc.
All rights reserved. No part of this book may by reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying, recording or by any information storage
retrieval system, without permission from Pearson Education, Inc.
Polish language edition published by HELION S.A. Copyright 2016.
Wszelkie prawa zastrzeone. Nieautoryzowane rozpowszechnianie caoci lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metod kserograficzn,
fotograficzn, a take kopiowanie ksiki na noniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki wystpujce w tekcie s zastrzeonymi znakami firmowymi bd towarowymi ich
wacicieli.
Autor oraz Wydawnictwo HELION dooyli wszelkich stara, by zawarte w tej ksice informacje
byy kompletne i rzetelne. Nie bior jednak adnej odpowiedzialnoci ani za ich wykorzystanie, ani za
zwizane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo
HELION nie ponosz rwnie adnej odpowiedzialnoci za ewentualne szkody wynike
z wykorzystania informacji zawartych w ksice.
Wydawnictwo HELION
ul. Kociuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (ksigarnia internetowa, katalog ksiek)
Pliki z przykadami omawianymi w ksice mona znale pod adresem:
ftp://ftp.helion.pl/przyklady/jcszp6.zip
Drogi Czytelniku!
Jeeli chcesz oceni t ksik, zajrzyj pod adres
http://helion.pl/user/opinie/jcszp6
Moesz tam wpisa swoje uwagi, spostrzeenia, recenzj.
Printed in Poland.

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

J}ZYK C. SZKOA PROGRAMOWANIA

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

Typy danych w C ................................................................................................................ 86


Typ int ................................................................................................................ 86
Inne typy cakowite ............................................................................................ 91
Korzystanie ze znakw typ char ................................................................... 96
Typ _Bool .......................................................................................................... 102
Typy przenone ................................................................................................ 102
Typy float, double, long double ...................................................................... 105
Typy zespolone i urojone ................................................................................. 110
Inne typy ........................................................................................................... 111
Rozmiary typw ............................................................................................... 113
Korzystanie z typw danych ........................................................................................... 114
Uwaga na argumenty ....................................................................................................... 115
Jeszcze jeden przykad ..................................................................................................... 117
Co si dzieje? .................................................................................................... 117
Bufor wyjcia .................................................................................................... 118
Kluczowe zagadnienia ...................................................................................................... 119
Podsumowanie rozdziau ................................................................................................ 119
Pytania sprawdzajce ....................................................................................................... 120
mwiczenia ............................................................................................................................ 122
Rozdzia 4. acuchy znakowe i formatowane wejcie-wyjcie ........................................... 125
Na pocztek... program .................................................................................................... 126
acuchy znakowe. Wprowadzenie .............................................................................. 127
Tablice typu char i znak zerowy ..................................................................... 127
Korzystanie z acuchw ................................................................................. 128
Funkcja strlen() ................................................................................................ 130
Stae i preprocesor C ......................................................................................................... 132
Modyfikator const ............................................................................................ 135
Stae standardowe ............................................................................................ 136
Pozna i wykorzysta printf() i scanf() ........................................................................... 138
Funkcja printf() ................................................................................................ 138
Korzystanie z printf() ....................................................................................... 139
Modyfikatory specyfikatorw konwersji dla printf() ...................................... 141
Znaczenie konwersji ........................................................................................ 147
Korzystanie z funkcji scanf() ........................................................................... 154
Modyfikator * w funkcjach printf() i scanf() ................................................... 160
Praktyczne wskazwki ..................................................................................... 161
Kluczowe zagadnienia ...................................................................................................... 163
Podsumowanie rozdziau ................................................................................................ 164
Pytania sprawdzajce ....................................................................................................... 164
mwiczenia ............................................................................................................................ 167
Rozdzia 5. Operatory, wyraenia i instrukcje ......................................................................... 169
Wstp do ptli .................................................................................................................... 170
Podstawowe operatory ..................................................................................................... 172
Operator przypisania: = .................................................................................. 172
Operator dodawania: + .................................................................................... 175

Kup ksik

Pole ksik

J}ZYK C. SZKOA PROGRAMOWANIA

Operator odejmowania: - ................................................................................. 176


Operatory znaku: - i + ..................................................................................... 176
Operator mnoenia: * ....................................................................................... 177
Operator dzielenia: / ......................................................................................... 179
Priorytet operatorw ........................................................................................ 180
Priorytet i kolejno oblicze .......................................................................... 182
Niektre inne operatory ................................................................................................... 183
Operator sizeof i typ size_t .............................................................................. 183
Operator modulo: % ......................................................................................... 184
Operatory inkrementacji i dekrementacji: ++ i -- ......................................... 186
Dekrementacja -- .............................................................................................. 190
Priorytet ............................................................................................................ 191
Nie prbuj by zbyt sprytny ............................................................................ 191
Wyraenia i instrukcje ...................................................................................................... 193
Wyraenia ......................................................................................................... 193
Instrukcje .......................................................................................................... 194
Instrukcje zoone (bloki) ................................................................................ 197
Konwersje typw .............................................................................................................. 199
Operator rzutowania ........................................................................................ 202
Funkcje z argumentami .................................................................................................... 203
Przykadowy program ...................................................................................................... 206
Zagadnienia kluczowe ...................................................................................................... 207
Podsumowanie rozdziau ................................................................................................ 208
Pytania sprawdzajce ....................................................................................................... 209
mwiczenia ............................................................................................................................ 212
Rozdzia 6. Instrukcje sterujce C. Ptle .................................................................................... 215
Wracamy do ptli while ................................................................................................... 216
Komentarz ........................................................................................................ 217
Ptla odczytujca w stylu C ............................................................................. 219
Instrukcja while ................................................................................................................. 219
Zakoczenie ptli while ................................................................................... 220
Kiedy koczy si ptla? .................................................................................... 220
while jako ptla z warunkiem wejcia ............................................................ 221
Wskazwki dotyczce skadni ......................................................................... 222
Co jest wiksze? Korzystanie z operatorw i wyrae relacyjnych ......................... 223
Czym jest prawda? ........................................................................................... 225
Co jeszcze jest prawd? .................................................................................... 226
Problemy z prawd .......................................................................................... 227
Nowy typ _Bool ................................................................................................ 229
Priorytet operatorw relacyjnych .................................................................... 231
Ptle nieokrelone i ptle liczce ..................................................................................... 232
Ptla for ............................................................................................................................... 234
Elastyczno ptli for ....................................................................................... 235
Inne operatory przypisania: +=, -=, *=, /=, %= ....................................................... 239

Kup ksik

Pole ksik

SPIS TRECI

Operator przecinkowy: , .................................................................................................. 241


Zenon z Elei kontra ptla for ........................................................................... 244
Ptla z warunkiem wyjcia do while ......................................................................... 245
Ktrej ptli uy? ............................................................................................................... 248
Ptle zagniedone ........................................................................................................... 249
Omwienie ....................................................................................................... 250
Inny wariant ..................................................................................................... 250
Tablice .................................................................................................................................. 251
Wsppraca tablicy i ptli for .......................................................................... 252
Przykad wykorzystujcy ptl i warto zwracan przez funkcj .......................... 254
Omwienie programu ...................................................................................... 257
Korzystanie z funkcji zwracajcych wartoci ................................................. 258
Zagadnienia kluczowe ...................................................................................................... 258
Podsumowanie rozdziau ................................................................................................ 259
Pytania sprawdzajce ....................................................................................................... 260
mwiczenia ............................................................................................................................ 264
Rozdzia 7. Instrukcje sterujce C. Rozgazienia i skoki .......................................................... 269
Instrukcja if ......................................................................................................................... 270
Dodajemy else .................................................................................................................... 272
Kolejny przykad: funkcje getchar() i putchar() .............................................. 273
Rodzina funkcji znakowych ctype.h ............................................................... 276
Wybr spord wielu moliwoci else if .................................................... 278
czenie else z if .............................................................................................. 281
Wicej o zagniedonych instrukcjach if ........................................................ 283
Bdmy logiczni ................................................................................................................ 287
Zapis alternatywny plik nagwkowy iso646.h ......................................... 289
Priorytet ............................................................................................................ 289
Kolejno oblicze ........................................................................................... 290
Zakresy ............................................................................................................. 291
Program liczcy sowa ...................................................................................................... 292
Operator warunkowy: ?: .................................................................................................. 296
Dodatki do ptli continue i break .............................................................................. 298
Instrukcja continue .......................................................................................... 298
Instrukcja break ................................................................................................ 301
Wybr spord wielu moliwoci switch i break .................................................... 304
Korzystanie z instrukcji switch ....................................................................... 305
Pobieranie tylko pierwszego znaku w wierszu ............................................... 307
Etykiety wielokrotne ........................................................................................ 308
Switch a if else ................................................................................................. 309
Instrukcja goto ................................................................................................................... 311
Unikanie goto ................................................................................................... 311
Kluczowe zagadnienia ...................................................................................................... 314
Podsumowanie rozdziau ................................................................................................ 315
Pytania sprawdzajce ....................................................................................................... 316
mwiczenia ............................................................................................................................ 319

Kup ksik

Pole ksik

10

J}ZYK C. SZKOA PROGRAMOWANIA

Rozdzia 8. Znakowe wejcie-wyjcie i przekierowywanie ................................................... 323


Jednoznakowe we-wy getchar() i putchar() ............................................................ 324
Bufory .................................................................................................................................. 325
Koczenie danych wprowadzanych z klawiatury ...................................................... 327
Pliki, strumienie i dane wprowadzane z klawiatury ...................................... 327
Koniec pliku ..................................................................................................... 329
Przekierowywanie a pliki ................................................................................................. 332
Przekierowywanie w systemach UNIX, Linux i Windows ............................ 332
Tworzenie przyjaniejszego interfejsu uytkownika ................................................. 337
Wsppraca z buforowanym wejciem ........................................................... 337
czenie wejcia liczbowego i znakowego ..................................................... 340
Sprawdzanie poprawnoci danych wejciowych ........................................................ 343
Analiza programu ............................................................................................. 347
Strumienie wejciowe a liczby ........................................................................ 348
Menu .................................................................................................................................... 349
Zadania ............................................................................................................. 349
W kierunku sprawnego dziaania .................................................................... 350
czenie danych znakowych i numerycznych ............................................... 352
Zagadnienia kluczowe ...................................................................................................... 355
Podsumowanie rozdziau ................................................................................................ 356
Pytania sprawdzajce ....................................................................................................... 356
mwiczenia ............................................................................................................................ 357
Rozdzia 9. Funkcje ....................................................................................................................... 361
Przypomnienie ................................................................................................................... 361
Tworzenie i wykorzystanie prostej funkcji ..................................................... 363
Analiza programu ............................................................................................. 363
Argumenty funkcji ........................................................................................... 366
Definiowanie funkcji pobierajcej argument argumenty formalne ........... 368
Prototyp funkcji pobierajcej argumenty ........................................................ 369
Wywoywanie funkcji pobierajcej argumenty argumenty faktyczne ........ 369
Punkt widzenia czarnej skrzynki .................................................................... 370
Zwracanie wartoci z wykorzystaniem instrukcji return ............................... 371
Typy funkcji ..................................................................................................... 373
Prototypy ANSI C .............................................................................................................. 375
Problem ............................................................................................................. 375
ANSI C na ratunek! .......................................................................................... 376
Brak argumentw a argumenty nieokrelone ................................................. 377
Potga prototypw ............................................................................................ 378
Rekurencja .......................................................................................................................... 379
Rekurencja bez tajemnic .................................................................................. 379
Podstawy rekurencji ......................................................................................... 380
Rekurencja kocowa ........................................................................................ 382
Rekurencja i odwracanie kolejnoci dziaa ................................................... 384
Za i przeciw rekurencji .................................................................................... 386

Kup ksik

Pole ksik

SPIS TRECI

11

Kompilowanie programw zawierajcych wicej ni jedn funkcj ....................... 387


Unix .................................................................................................................. 387
Linux ................................................................................................................. 388
DOS (kompilatory wiersza polece) ................................................................ 388
rodowiska IDE dla Windows i OS X ............................................................. 388
Korzystanie z plikw nagwkowych .............................................................. 388
Uzyskiwanie adresw: operator & ................................................................................. 392
Modyfikacja zmiennych w funkcji wywoujcej ......................................................... 394
Wskaniki: pierwsze spojrzenie ...................................................................................... 396
Operator dereferencji: * ................................................................................... 396
Deklarowanie wskanikw .............................................................................. 396
Wykorzystanie wskanikw do komunikacji pomidzy funkcjami .............. 398
Kluczowe zagadnienia ...................................................................................................... 402
Podsumowanie rozdziau ................................................................................................ 403
Pytania sprawdzajce ....................................................................................................... 403
mwiczenia ............................................................................................................................ 404
Rozdzia 10. Tablice i wskaniki ................................................................................................. 407
Tablice .................................................................................................................................. 407
Inicjalizacja ....................................................................................................... 408
Oznaczona inicjalizacja (C99) ......................................................................... 412
Przypisywanie wartoci do tablic .................................................................... 414
Zakres tablic ..................................................................................................... 414
Okrelanie rozmiaru tablicy ............................................................................ 416
Tablice wielowymiarowe ................................................................................................. 417
Inicjalizacja tablicy dwuwymiarowej .............................................................. 420
Wicej wymiarw ............................................................................................. 421
Wskaniki do tablic ........................................................................................................... 422
Funkcje, tablice i wskaniki ............................................................................................. 425
Korzystanie z parametrw wskanikowych .................................................... 428
Komentarz wskaniki i tablice .................................................................... 430
Dziaania na wskanikach ................................................................................................ 430
Ochrona zawartoci tablicy .............................................................................................. 435
Zastosowanie sowa kluczowego const w parametrach formalnych ............. 436
Wicej o const .................................................................................................. 437
Wskaniki a tablice wielowymiarowe ............................................................................ 439
Wskaniki do tablic wielowymiarowych ........................................................ 442
Zgodno wskanikw ..................................................................................... 444
Funkcje a tablice wielowymiarowe ................................................................. 446
Tablice o zmiennym rozmiarze (VLA, ang. variable length array) ...................... 449
Literay zoone ................................................................................................................. 453
Zagadnienia kluczowe ...................................................................................................... 456
Podsumowanie rozdziau ................................................................................................ 456
Pytania sprawdzajce ....................................................................................................... 458
mwiczenia ............................................................................................................................ 460

Kup ksik

Pole ksik

12

J}ZYK C. SZKOA PROGRAMOWANIA

Rozdzia 11. acuchy znakowe i funkcje acuchowe ......................................................... 463


Reprezentacja acuchw i acuchowe wejcie-wyjcie ........................................... 463
Definiowanie acuchw ................................................................................. 464
Wskaniki a acuchy ...................................................................................... 473
Wczytywanie acuchw ................................................................................................. 475
Tworzenie miejsca ........................................................................................... 475
Niesawna funkcja gets() .................................................................................. 475
Alternatywy dla funkcji gets() ......................................................................... 477
Funkcja scanf() ................................................................................................. 484
Wywietlanie acuchw ................................................................................................. 486
Funkcja puts() ................................................................................................... 486
Funkcja fputs() .................................................................................................. 488
Funkcja printf() ................................................................................................ 488
Zrb to sam ......................................................................................................................... 489
Funkcje acuchowe ......................................................................................................... 491
Funkcja strlen() ................................................................................................ 492
Funkcja strcat() ................................................................................................. 493
Funkcja strncat() ............................................................................................... 495
Funkcja strcmp() .............................................................................................. 496
Funkcje strcpy() i strncpy() .............................................................................. 503
Funkcja sprintf() ............................................................................................... 508
Inne funkcje acuchowe ................................................................................. 509
Przykad uycia. Sortowanie acuchw ....................................................................... 512
Sortowanie wskanikw zamiast acuchw ................................................. 513
Algorytm sortowania przez selekcj ................................................................ 514
acuchy a funkcje znakowe z rodziny ctype.h .......................................................... 515
Argumenty wiersza polece ............................................................................................ 517
Argumenty wiersza polece w rodowiskach zintegrowanych ..................... 519
Argumenty linii polece w systemie Macintosh ............................................ 520
Konwersja acuchw do liczb ........................................................................................ 520
Zagadnienia kluczowe ...................................................................................................... 523
Podsumowanie rozdziau ................................................................................................ 524
Pytania sprawdzajce ....................................................................................................... 525
mwiczenia ............................................................................................................................ 528
Rozdzia 12. Klasy zmiennej, czno i zarzdzanie pamici ............................................. 531
Klasy zmiennych ............................................................................................................... 532
Zasig zmiennej ................................................................................................ 533
czno zmiennej ........................................................................................... 535
Czas trwania zmiennej ..................................................................................... 537
Zmienne automatyczne ................................................................................... 538
Zmienne rejestrowe .......................................................................................... 543
Zmienne statyczne o zasigu blokowym ........................................................ 543
Zmienne statyczne o cznoci zewntrznej ................................................... 545
Zmienne statyczne o cznoci wewntrznej ................................................. 550
Programy wieloplikowe ................................................................................... 551

Kup ksik

Pole ksik

SPIS TRECI

13

Specyfikatory klasy zmiennych podsumowanie ....................................... 551


Klasy zmiennych a funkcje .............................................................................. 554
Ktr klas wybra? ......................................................................................... 555
Funkcje pseudolosowe i zmienne statyczne ................................................................. 555
Rzut kostk ......................................................................................................................... 559
Przydzia pamici. Funkcje malloc() i free() .................................................................. 563
Znaczenie funkcji free() ................................................................................... 568
Funkcja calloc() ................................................................................................ 568
Dynamiczny przydzia pamici a tablice o zmiennym rozmiarze ................. 569
Klasy zmiennych a dynamiczny przydzia pamici ....................................... 570
Kwalifikatory typu ANSI C .............................................................................................. 572
Kwalifikator typu const .................................................................................... 572
Kwalifikator typu volatile ................................................................................ 575
Kwalifikator typu restrict ................................................................................. 576
Kwalifikator _Atomic (C11) ............................................................................. 577
Stare sowa kluczowe w nowych miejscach ................................................... 578
Kluczowe zagadnienia ...................................................................................................... 579
Podsumowanie rozdziau ................................................................................................ 579
Pytania sprawdzajce ....................................................................................................... 581
mwiczenia ............................................................................................................................ 582
Rozdzia 13. Obsuga plikw ....................................................................................................... 587
Wymiana informacji z plikami ........................................................................................ 587
Czym jest plik? ................................................................................................. 588
Poziomy wejcia-wyjcia ................................................................................. 590
Pliki standardowe ............................................................................................. 590
Standardowe wejcie-wyjcie .......................................................................................... 591
Sprawdzanie argumentw wiersza polece .................................................... 592
Funkcja fopen() ................................................................................................ 593
Funkcje getc() i putc() ...................................................................................... 595
Znak koca pliku EOF (ang. end of file) ......................................................... 595
Funkcja fclose() ................................................................................................ 596
Wskaniki do plikw standardowych ............................................................. 597
Niewyszukany program kompresujcy pliki ............................................................... 597
Plikowe wejcie-wyjcie fprintf(), fscanf(), fgets() i fputs() .................................... 599
Funkcje fprintf() i fscanf() ................................................................................ 599
Funkcje fgets() i fputs() .................................................................................... 601
Przygody z dostpem swobodnym fseek() i ftell() ................................................. 602
Jak dziaaj funkcje fseek() i ftell()? ................................................................. 603
Tryb binarny a tryb tekstowy .......................................................................... 604
Przenono ...................................................................................................... 605
Funkcje fgetpos() i fsetpos() ............................................................................. 606
Za kulisami standardowego wejcia-wyjcia ................................................................ 606
Inne standardowe funkcje wejcia-wyjcia ................................................................... 607
Funkcja int ungetc() ......................................................................................... 608
Funkcja int fflush() ........................................................................................... 608
Funkcja int setvbuf() ........................................................................................ 608

Kup ksik

Pole ksik

14

J}ZYK C. SZKOA PROGRAMOWANIA

Binarne wejcie-wyjcie: fread() i fwrite() ...................................................... 609


Funkcja size_t fwrite() ...................................................................................... 611
Funkcja size_t fread() ....................................................................................... 611
Funkcje int feof(FILE *fp) oraz int ferror(FILE *fp) ....................................... 612
Przykad ............................................................................................................ 612
Dostp swobodny w binarnym wejciu-wyjciu ............................................ 615
Zagadnienia kluczowe ...................................................................................................... 617
Podsumowanie rozdziau ................................................................................................ 618
Pytania sprawdzajce ....................................................................................................... 619
mwiczenia ............................................................................................................................ 621
Rozdzia 14. Struktury i inne formy danych ............................................................................ 625
Przykadowy problem. Tworzenie spisu ksiek ......................................................... 626
Deklaracja struktury .......................................................................................................... 627
Definiowanie zmiennej strukturalnej ............................................................................ 628
Inicjalizacja struktury ...................................................................................... 630
Odwoania do skadnikw struktury ............................................................... 630
Inicjalizatory oznaczone struktur .................................................................... 631
Tablice struktur .................................................................................................................. 632
Deklarowanie tablicy struktur ......................................................................... 634
Wskazywanie skadnikw tablicy struktur ..................................................... 634
Szczegy programu ......................................................................................... 635
Struktury zagniedone ................................................................................................... 636
Wskaniki do struktur ...................................................................................................... 638
Deklaracja i inicjalizacja wskanika do struktury .......................................... 639
Dostp do skadnikw za pomoc wskanika ................................................. 640
Struktury a funkcje ............................................................................................................ 641
Przekazywanie skadnikw struktur ............................................................... 641
Korzystanie z adresu struktury ........................................................................ 642
Przekazywanie struktury jako argumentu ...................................................... 643
Wicej o nowym, ulepszonym statusie struktury ........................................... 644
Struktury czy wskaniki do struktur? ............................................................. 648
Tablice znakowe lub wskaniki do znakw w strukturze ............................. 649
Struktury, wskaniki i funkcja malloc() .......................................................... 650
Literay zoone i struktury (C99) ................................................................... 652
Elastyczne skadniki tablicowe (C99) ............................................................. 654
Struktury anonimowe (C11) ............................................................................ 657
Funkcje korzystajce z tablic struktur ............................................................ 657
Zapisywanie zawartoci struktury w pliku ................................................................... 659
Przykad zapisu struktury ................................................................................ 660
Omwienie programu ...................................................................................... 663
Struktury. Co dalej? .......................................................................................................... 664
Unie. Szybkie spojrzenie .................................................................................................. 665
Wykorzystywanie unii ..................................................................................... 666
Unie anonimowe (C11) .................................................................................... 667

Kup ksik

Pole ksik

SPIS TRECI

15

Typy wyliczeniowe ........................................................................................................... 669


Stae enum ........................................................................................................ 670
Wartoci domylne ........................................................................................... 670
Przypisywane wartoci .................................................................................... 670
Uycie enum ..................................................................................................... 670
Wspdzielona przestrze nazw ...................................................................... 672
typedef: szybkie spojrzenie ............................................................................................. 673
Udziwnione deklaracje ..................................................................................................... 675
Funkcje a wskaniki .......................................................................................................... 677
Kluczowe zagadnienia ...................................................................................................... 684
Podsumowanie rozdziau ................................................................................................ 685
Pytania sprawdzajce ....................................................................................................... 686
mwiczenia ............................................................................................................................ 689
Rozdzia 15. Manipulowanie bitami .......................................................................................... 693
Liczby binarne, bity i bajty ............................................................................................... 694
Binarne liczby cakowite ................................................................................. 694
Liczby cakowite ze znakiem ........................................................................... 695
Binarne liczby zmiennoprzecinkowe .............................................................. 696
Inne systemy liczbowe ...................................................................................................... 697
System semkowy ............................................................................................ 697
System szesnastkowy ....................................................................................... 698
Operatory bitowe .............................................................................................................. 698
Bitowe operatory logiczne ............................................................................... 699
Zastosowanie. Maski ........................................................................................ 701
Zastosowanie. Ustawianie bitw (wczanie bitw) ...................................... 702
Zastosowanie. Zerowanie bitw (wyczanie bitw) ..................................... 702
Zastosowanie. Odwracanie bitw ................................................................... 703
Zastosowanie. Sprawdzenie wartoci bitu ..................................................... 703
Bitowe operatory przesunicia ........................................................................ 704
Przykad ............................................................................................................ 706
Kolejny przykad .............................................................................................. 708
Pola bitowe ......................................................................................................................... 710
Przykad ............................................................................................................ 711
Pola bitowe a operatory bitowe ....................................................................... 715
Mechanizmy wyrwnania danych (C11) ........................................................ 722
Kluczowe zagadnienia ...................................................................................................... 724
Podsumowanie rozdziau ................................................................................................ 725
Pytania sprawdzajce ....................................................................................................... 726
mwiczenia ............................................................................................................................ 727
Rozdzia 16. Preprocesor i biblioteka C ..................................................................................... 731
Pierwsze kroki w translacji programu ........................................................................... 732
Stae symboliczne. #define .............................................................................................. 733
Tokeny .............................................................................................................. 737
Przedefiniowywanie staych ............................................................................ 737

Kup ksik

Pole ksik

16

J}ZYK C. SZKOA PROGRAMOWANIA

#define i argumenty ......................................................................................................... 738


Argumenty makr w acuchach ...................................................................... 741
cznik preprocesora. Operator ## ................................................................ 742
Makra o zmiennej liczbie argumentw: ... i __VA_ARGS__ .......................... 743
Makro czy funkcja? ........................................................................................................... 744
Doczanie plikw. #include .......................................................................................... 746
Pliki nagwkowe. Przykad ............................................................................ 747
Zastosowania plikw nagwkowych ............................................................. 749
Inne dyrektywy ................................................................................................................. 750
Dyrektywa #undef ........................................................................................... 750
Zdefiniowany. Z perspektywy preprocesora C ............................................... 751
Kompilacja warunkowa ................................................................................... 751
Makra predefiniowane ..................................................................................... 756
#line i #error ................................................................................................... 757
#pragma ........................................................................................................... 758
Sowo kluczowe _Generic (C11) ...................................................................... 759
Funkcje wplatane (C99) .................................................................................................... 761
Funkcje bezpowrotne (C11) ............................................................................................. 764
Biblioteka jzyka C ............................................................................................................ 764
Uzyskiwanie dostpu do biblioteki C ............................................................. 764
Korzystanie z opisw funkcji ........................................................................... 765
Biblioteka funkcji matematycznych ............................................................................... 767
Odrobina trygonometrii ................................................................................... 768
Warianty typw zmiennoprzecinkowych ....................................................... 770
Biblioteka tgmath.h (C99) ................................................................................ 771
Biblioteka narzdzi oglnego uytku ............................................................................. 772
Funkcje exit() i atexit() ..................................................................................... 773
Funkcja qsort() .................................................................................................. 775
Biblioteka assert.h .............................................................................................................. 780
Stosowanie asercji ............................................................................................ 780
_Static_assert (C11) .......................................................................................... 781
Funkcje memcpy() i memmove() z biblioteki string.h ................................................. 782
Zmienna liczba argumentw. stdarg.h .......................................................................... 785
Zagadnienie kluczowe ...................................................................................................... 787
Podsumowanie rozdziau ................................................................................................ 788
Pytania sprawdzajce ....................................................................................................... 788
mwiczenia ............................................................................................................................ 790
Rozdzia 17. Zaawansowana reprezentacja danych ............................................................... 793
Poznajemy reprezentacj danych ................................................................................... 794
Listy czone ....................................................................................................................... 797
Korzystanie z listy czonej ............................................................................. 801
Refleksje ............................................................................................................ 805
Abstrakcyjne typy danych (ATD) ................................................................................... 806
Wicej abstrakcji .............................................................................................. 807
Budowanie interfejsu ....................................................................................... 808

Kup ksik

Pole ksik

SPIS TRECI

17

Korzystanie z interfejsu ................................................................................... 813


Implementacja interfejsu ................................................................................. 815
Kolejki .................................................................................................................................. 822
Definicja kolejki jako abstrakcyjnego typu danych ........................................ 822
Definicja interfejsu ........................................................................................... 823
Implementacja reprezentacji danych .............................................................. 824
Testowanie kolejki ........................................................................................... 832
Symulowanie za pomoc kolejki .................................................................................... 834
Lista czona czy tablica? .................................................................................................. 840
Drzewa binarne ................................................................................................................. 844
Drzewo binarne jako ATD ............................................................................... 846
Interfejs drzewa binarnego .............................................................................. 846
Implementacja drzewa binarnego ................................................................... 849
Testowanie drzewa .......................................................................................... 863
Uwagi o drzewach ............................................................................................ 868
Co dalej? .............................................................................................................................. 869
Zagadnienia kluczowe ...................................................................................................... 870
Podsumowanie rozdziau ................................................................................................ 871
Pytania sprawdzajce ....................................................................................................... 871
mwiczenia ............................................................................................................................ 872
Dodatek A. Odpowiedzi na pytania sprawdzajce ................................................................. 875
Dodatek B. Dokumentacja ........................................................................................................... 915
I. Lektura uzupeniajca ................................................................................................... 915
II. Operatory w jzyku C .................................................................................................. 919
III. Podstawowe typy i klasy zmiennych ....................................................................... 925
IV. Wyraenia, instrukcje i przepyw sterowania w programie ............................... 930
V. Standardowa biblioteka ANSI C oraz rozszerzenia standardu C99 i C11 ........... 937
VI. Rozszerzone typy cakowite ...................................................................................... 987
VII. Obsuga rozszerzonych zbiorw znakw .............................................................. 991
VIII. Efektywniejsze obliczenia numeryczne w C99 i C11 ....................................... 997
IX. Rnice midzy C a C++ ........................................................................................ 1006
Skorowidz .................................................................................................................................... 1013

Kup ksik

Pole ksik

18

J}ZYK C. SZKOA PROGRAMOWANIA

Kup ksik

Pole ksik

9
FUNKCJE
Zagadnienia poruszone w tym rozdziale:
z

Sowo kluczowe:

return
z

Operatory jednoargumentowe:
*i&

z
z

Funkcje i metody ich definiowania


Wykorzystanie argumentw
i zwracanych wartoci

z
z
z

Zastosowanie wskanikw
jako argumentw funkcji
Typy funkcji
Prototypy ANSI C
Rekurencja

a czym polega organizacja programu? Czci filozofii jzyka C jest stosowanie


funkcji jako podstawowych elementw budulcowych. Do tej pory korzystae
gwnie ze standardowych funkcji bibliotecznych, takich jak printf(),
scanf(), getchar(), putchar() czy strlen(). Teraz jeste gotowy, aby wzi na
siebie bardziej twrcze zadanie tworzenie wasnych funkcji. Niektrym aspektom
tego procesu miae okazj przyjrze si w poprzednich rozdziaach niniejszy
rozdzia systematyzuje i rozszerza podane wczeniej informacje.

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

J}ZYK C. SZKOA PROGRAMOWANIA

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

Co musisz wiedzie o funkcjach? Musisz wiedzie, jak je waciwie definiowa, jak je


wywoywa oraz jak zrealizowa wymian informacji midzy rnymi funkcjami.
Aby odwiey Twoj pami, rozpoczniemy od bardzo prostego przykadu, do ktrego dodawa bdziemy kolejne elementy a do otrzymania penego obrazu.

Tworzenie i wykorzystanie prostej funkcji


Naszym pierwszym skromnym celem jest utworzenie funkcji, ktra wywietla rzd 40
gwiazdek (*). Aby zaopatrzy j w jaki kontekst, umiecimy j w programie wywietlajcym prosty nagwek listu. Gotowy program, skadajcy si z dwch funkcji
main() i gwiazdki() przedstawiony jest na listingu 9.1.

LISTING 9.1. Program naglowek1.c


/* naglowek1.c */
#include <stdio.h>
#define NAZWA "MEGATHINK, INC."
#define ADRES "10 Megabuck Plaza"
#define MIEJSCOWOSC "Megapolis, CA 94904"
#define LIMIT 40
void gwiazdki(void); /* prototyp funkcji */
int main(void)
{
gwiazdki();
printf("%s\n", NAZWA);
printf("%s\n", ADRES);
printf("%s\n", MIEJSCOWOSC);
gwiazdki();
/* wywolanie funkcji */
return 0;
}
void gwiazdki(void)
/* definicja funkcji */
{
int licznik;
for (licznik = 1; licznik <= LIMIT; licznik++)
putchar('*');
putchar('\n');
}

Oto wynik dziaania programu:


****************************************
MEGATHINK, INC.
10 Megabuck Plaza
Megapolis, CA 94904
****************************************

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

J}ZYK C. SZKOA PROGRAMOWANIA

Podobnie jak zmienne, funkcje nale do typw. Kady program wykorzystujcy


funkcj powinien deklarowa jej typ, zanim zostanie ona wywoana. Dlatego przed
definicj funkcji main() umieszczony zosta nastpujcy prototyp ANSI C:
void gwiazdki(void);

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();

Jest to jeden ze sposobw wywoania funkcji. Zawsze, gdy komputer napotka


instrukcj gwiazdki();, odszukuje funkcj gwiazdki() i wykonuje zawarte w niej
instrukcje. Po zakoczeniu wykonywania kodu wewntrz funkcji gwiazdki()
komputer wraca do kolejnego wiersza funkcji wywoujcej w tym przypadku
main() (patrz rysunek 9.1). (Dokadnie rzecz biorc, kompilator C tumaczy kod
funkcji i programu na kod maszynowy, ktry zachowuje si zgodnie z powyszym opisem).
Definicja funkcji gwiazdki() wyglda tak samo, jak funkcji main(). Rozpoczyna
si ona typem funkcji, jej nazw i nawiasami. Dalej nastpuje klamra otwierajca,
deklaracja uytych zmiennych, instrukcje skadajce si na funkcj oraz klamra zamykajca (patrz rysunek 9.2). Zauwa, e w tym wypadku po nazwie gwiazdki()
nie wystpuje rednik. Brak rednika informuje kompilator, e funkcja jest definiowana, a nie deklarowana.

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

J}ZYK C. SZKOA PROGRAMOWANIA

W naszym przykadzie funkcje gwiazdki() i main() znajduj si w tym samym


pliku, mgby jednak uy dwch oddzielnych plikw. Model jednoplikowy jest
nieco atwiejszy w kompilacji, z kolei umieszczenie funkcji gwiazdki() w osobnym pliku uatwia wykorzystanie jej w innych programach. Jeli zdecydujesz si
na ten drugi wariant, w pliku zawierajcym funkcj gwiazdki() musisz rwnie
umieci wszystkie potrzebne dyrektywy #define i #include. Zagadnieniem
korzystania z dwch lub wicej plikw kodu rdowego zajmiemy si pniej;
tymczasem bdziemy trzyma si opcji jednoplikowej. Klamra zamykajca pokazuje
kompilatorowi koniec definicji funkcji main(); nastpujcy za nim nagwek
gwiazdki() to dla kompilatora informacja, e gwiazdki() jest kolejn, odrbn
funkcj.
Zmienna licznik w funkcji gwiazdki() jest zmienn lokaln. Oznacza to, e jest
ona znana tylko funkcji gwiazdki(). Mgby zadeklarowa zmienn o nazwie
licznik w innej funkcji, wcznie z main(), bez naraania si na konflikt. Otrzymaby po prostu dwie niezalene zmienne o tej samej nazwie.
Jeli potraktowa funkcj gwiazdki() jako czarn skrzynk, wykonywan przez ni
czynnoci jest wywietlenie rzdu gwiazdek. Funkcja nie posiada wejcia, poniewa
nie potrzebuje ona adnych informacji z funkcji wywoujcej. Nie posiada rwnie
wartoci zwracanej, a wic nie dostarcza adnych informacji do funkcji main(). Jednym
sowem, funkcja gwiazdki() nie musi komunikowa si z funkcj wywoujc.
Przyjrzyjmy si teraz sytuacji, w ktrej komunikacja jest potrzebna.

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.

LISTING 9.2. Program naglowek2.c


/* naglowek2.c */
#include <stdio.h>
#include <string.h>
/* zawiera prototyp strlen()
#define NAZWA "MEGATHINK, INC."
#define ADRES "10 Megabuck Plaza"
#define MIEJSCOWOSC "Megapolis, CA 94904"
#define LIMIT 40
#define ODSTEP ' '
void n_znak(char ch, int num);
int main(void)
{
int odstepy;
n_znak('*', LIMIT);
/* stale jako argumenty
putchar('\n');
n_znak(ODSTEP, 12);
/* stale jako argumenty
printf("%s\n", NAZWA);
odstepy = (LIMIT - strlen(ADRES)) / 2;
/* program oblicza, ile odstepow
/* nalezy wyswietlic
n_znak(ODSTEP, odstepy);
/* zmienna jako argument
printf("%s\n", ADRES);
n_znak(ODSTEP, (LIMIT - strlen(MIEJSCOWOSC)) / 2);
/* wyrazenie jako argument
printf("%s\n", MIEJSCOWOSC);
n_znak('*', LIMIT);
putchar('\n');
return 0;
}
/* definicja funkcji n_znak() */
void n_znak(char ch, int num)
{
int licznik;
for (licznik = 1; licznik <= num; licznik++)
putchar(ch);
}

*/

*/
*/

*/
*/
*/

*/

Oto wynik uruchomienia powyszego programu:


****************************************
MEGATHINK, INC.
10 Megabuck Plaza
Megapolis, CA 94904
****************************************

Kup ksik

Pole ksik

368

J}ZYK C. SZKOA PROGRAMOWANIA

Przypomnijmy sobie teraz sposb tworzenia funkcji przyjmujcej argumenty, a nastpnie przyjrzyjmy si, jak naley z niej korzysta.

Definiowanie funkcji pobierajcej argument argumenty formalne


Definicja funkcji rozpoczyna si ponisz deklaracj:
void n_znak(char ch, int num)

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)

/* nieprawidlowy naglowek funkcji */


/* prawidlowy naglowek funkcji
*/

Standard ANSI C dopuszcza rwnie starsz form, ale uznaje j za przestarza:


void n_znak(ch, num)
char ch;
int num;

Nawiasy zawieraj tu jedynie list nazw argumentw ich typy deklarowane s


poniej. Zwr uwag, e deklaracja argumentw znajduje si przed klamr otwierajc, a deklaracja zwykych zmiennych lokalnych po niej. Ta odmiana definicji
funkcji, w przeciwiestwie do odmiany ANSI C, pozwala korzysta z list zmiennych
nalecych do tego samego typu (nazwy zmiennych rozdzielone s przecinkami):
void ping(x, y, z)
int x, y, 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

Prototyp funkcji pobierajcej argumenty


Funkcj n_znak() zadeklarowalimy z wykorzystaniem nastpujcego prototypu
ANSI C:
void n_znak(char ch, int num);

Prototyp okrela liczb i typy argumentw przyjmowanych przez funkcj. Argumenty


rozdzielone s przecinkami. Nazwy zmiennych w prototypie mog zosta pominite:
void n_znak(char, int);

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();

Posta bez listy argumentw w przyszoci zostanie wycofana ze standardu C; ale


nawet gdyby si tak nie stao, stosowanie penego prototypu jest o wiele lepszym
rozwizaniem, o czym wkrtce si przekonasz. Wersj bez listy argumentw warto
zna gwnie na ewentualno pracy z jakim mocno leciwym kodem.

Wywoywanie funkcji pobierajcej argumenty argumenty faktyczne


Zmienne ch i num otrzymuj swoje wartoci dziki uyciu w wywoaniu funkcji
argumentw faktycznych. Przyjrzyj si pierwszemu wywoaniu funkcji n_znak()
w naszym programie:
n_znak(ODSTEP, 12);

Argumentami faktycznymi s tu znak odstpu oraz liczba 12. Wartoci te zostaj


przypisane odpowiadajcym im argumentom formalnym funkcji n_znak(), czyli
zmiennym ch i num. Mwic w skrcie, argument formalny jest zmienn w wywoywanej funkcji, a argument faktyczny konkretn wartoci przypisan tej zmiennej
przez funkcj wywoujc. Jak pokazalimy w naszym przykadzie, argument faktyczny moe by sta, zmienn lub wyraeniem. W kadym przypadku jest on obliczany,
a jego warto zostaje skopiowana do argumentu formalnego funkcji. Zastanw si na
przykad nad nastpujcym wywoaniem funkcji n_znak() w programie naglowek2.c:
n_znak(ODSTEP, (LIMIT strlen(MIEJSCOWOSC)) / 2);

Dugie wyraenie stanowice drugi argument faktyczny zostaje obliczone, a jego


warto (10) zostaje przypisana zmiennej num. Wywoywanej funkcji nie interesuje,
czy liczba 10 pochodzi ze staej, zmiennej czy te ze skomplikowanego wyraenia. Powtrzmy: argument faktyczny jest konkretn wartoci przypisywan zmiennej argumentowi formalnemu (patrz rysunek 9.3). Argumenty formalne s kopiami
danych z funkcji wywoujcej, a wic wszelkie modyfikacje, jakich dokonuje na nich
funkcja wywoywana, nie pocigaj za sob zmiany danych wyjciowych.

Kup ksik

Pole ksik

370

J}ZYK C. SZKOA PROGRAMOWANIA

RYSUNEK 9.3.
Argumenty formalne
i faktyczne

Argumenty faktyczne a argumenty formalne


Argument faktyczny to wyraenie podane w nawiasach wywoywanej funkcji. Argument formalny to zmienna zadeklarowana w nagwku definicji funkcji. W chwili
wywoywania funkcji zmienne zadeklarowane jako argumenty formalne s tworzone, a nastpnie inicjowane wartociami wynikajcymi z przetworzenia argumentw faktycznych. Na listingu 9.2 '*' i LIMIT s argumentami faktycznymi
podczas pierwszego wywoania funkcji n_znak(), natomiast stae ODSTEP i 12
w czasie drugiego wywoania. Zmienne ch i num s argumentami formalnymi
w definicji funkcji.

Punkt widzenia czarnej skrzynki


Przyjmujc perspektyw czarnej skrzynki, na wejciu funkcji n_znak() mamy znak
oraz liczb razy, jak naley go wywietli. Dane wejciowe s przekazywane do funkcji w postaci argumentw. Te informacje w peni wystarczaj do korzystania z funkcji
n_znak(), mog te stanowi podstaw do jej implementacji.
Tym, co umoliwia przyjcie punktu widzenia czarnej skrzynki, jest fakt, i ch, num
i licznik s zmiennymi lokalnymi, prywatnymi dla funkcji n_znak(). Gdyby mia
uy zmiennych o tej samej nazwie w funkcji main(), byyby one oddzielnymi, niezalenymi obiektami. Gdyby wic funkcja main() zawieraa zmienn licznik, zmiana
jej wartoci nie powodowaaby modyfikacji zmiennej licznik w funkcji n_znak(),
i odwrotnie. To, co dzieje si w rodku czarnej skrzynki, jest niewidoczne dla funkcji
wywoujcej.

Kup ksik

Pole ksik

Rozdzia 9. FUNKCJE

371

Zwracanie wartoci z wykorzystaniem instrukcji return


Wiesz ju, w jaki sposb przekazywa dane z funkcji wywoujcej do wywoywanej.
Do przesyania informacji w przeciwnym kierunku suy wartoci zwracana funkcji.
Aby odwiey Twoj pami, skonstruujemy funkcj, ktra zwraca mniejszy z dwch
argumentw. Nazwiemy j imin(), poniewa obsuguje ona wartoci typu int. Utworzymy rwnie prost funkcj main(), ktrej jedynym zadaniem bdzie sprawdzenie, czy funkcja imin() dziaa prawidowo. Czst praktyk poprzedzajc wykorzystanie funkcji w prawdziwym programie, na potrzeby ktrego zostaa ona napisana,
jest napisanie prostego programu testujcego. Przykad takiego podejcia ilustruje
listing 9.2 z funkcj imin() i moliwie prostym programem wywoujcym funkcj.

LISTING 9.3. Program mniejsze.c


/* mniejsze.c -- znajduje mniejsze zlo */
#include <stdio.h>
int imin(int, int);
int main(void)
{
int zlo1, zlo2;
printf("Podaj dwie liczby calkowite (q konczy program):\n");
while (scanf("%d %d", &zlo1, &zlo2) == 2)
{
printf("Mniejsza liczba sposrod %d i %d jest %d.\n",
zlo1, zlo2, imin(zlo1,zlo2));
printf("Podaj dwie liczby calkowite (q konczy program):\n");
}
printf("Gotowe.\n");
return 0;
}
int imin(int n,int m)
{
int min;
if (n < m)
min = n;
else
min = m;
return min;
}

Jak pamitamy, funkcja scanf() zwraca liczb skutecznie odczytanych elementw,


wic kade wejcie inne ni para liczb cakowitych spowoduje przerwanie wykonywania ptli. Oto wynik dziaania programu:
Podaj dwie liczby calkowite (q konczy program):
509 333
Mniejsza liczba sposrod 509 i 333 jest 333.
Podaj dwie liczby calkowite (q konczy program):
-9393 6
Mniejsza liczba sposrod -9393 i 6 jest -9393.
Podaj dwie liczby calkowite (q konczy program):
q
Gotowe

Kup ksik

Pole ksik

372

J}ZYK C. SZKOA PROGRAMOWANIA

Sowo kluczowe return sprawia, e warto nastpujcego po nim wyraenia staje


si wartoci zwracan funkcji. W tym przypadku funkcja zwraca warto zmiennej
min. Poniewa zmienna min naley do typu int, do tego typu naley rwnie funkcja
imin().
Zmienna min jest wprawdzie prywatna dla funkcji imin(), ale jej warto jest przekazywana do funkcji wywoujcej za porednictwem sowa return. Efektem poniszej
instrukcji jest wic nadanie zmiennej mniejszej wartoci zmiennej min:
mniejsze = imin(n,m);

Czy moglibymy uy zamiast tego nastpujcego kodu?


imin(n,m);
mniejsze = min;

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;
}

Wyraenie warunkowe otrzymuje warto n lub m (w zalenoci od tego, ktry z dwch


argumentw jest mniejszy) i warto ta zostaje zwrcona do funkcji wywoujcej. Jeli
chcesz, dla zwikszenia czytelnoci warto zwracan moesz uj w nawias nie jest
to jednak wymagane.
Co si dzieje, gdy funkcja zwraca typ inny ni zadeklarowano?
int co_gdy(int n)
{
double z = 100.0 / (double) n;
return z; // co sie stanie?
}

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;
}

Wielu programistw w C uwaa, e lepiej jest uy instrukcji return tylko raz na


kocu funkcji, gdy uatwia to ledzenie przebiegu programu. Nie jest jednak wielkim
grzechem uycie kilku instrukcji return w funkcji tak krtkiej, jak powysza. Tak czy
owak, z punktu widzenia uytkownika wszystkie trzy wersje funkcji imin() s identyczne, poniewa wszystkie przyjmuj te same dane wyjciowe i daj taki sam wynik.
Rni si tylko wewntrzn budow. Nawet ponisza wersja dziaa tak samo:
/* funkcja wartosci minimalnej, czwarta wersja */
imin(int n,int m)
{
if (n < m)
return n;
else
return m;
printf("Profesor Fleppard to kretyn.\n");
}

Instrukcje return sprawiaj, e instrukcja printf() nie zostanie nigdy wykonana.


Profesor Fleppard moe przez cae ycie wykorzystywa skompilowan wersj funkcji
imin() w swoich programach i nigdy nie dowiedzie si, co o nim sdzi jego ucze.
Moesz rwnie uy nastpujcej instrukcji:
return;

Powoduje ona zakoczenie funkcji i powrt do funkcji wywoujcej. Poniewa po


sowie return nie znajduje si adne wyraenie, nie ma rwnie wartoci zwracanej forma ta powinna by wic stosowana tylko w funkcji typu void.

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

J}ZYK C. SZKOA PROGRAMOWANIA

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;

/* deklaracja funkcji imin() */

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);

Informuje on kompilator, e funkcja sqrt() posiada parametr typu double i zwraca


warto typu double. Deklaracji funkcji nie naley myli z definicj. Deklaracja okrela,

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.

LISTING 9.4. Program blad.c


/* blad.c -- korzysta z funkcji w niewlasciwy sposob */
#include <stdio.h>
int imax();
/* deklaracja w starym stylu */
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)
int n, m;
{
return (n > m ? n : m);
}

Pierwsze wywoanie funkcji imax() pomija jeden z argumentw, a drugie przekazuje


wartoci zmiennoprzecinkowe zamiast cakowitych. Pomimo tych bdw program
kompiluje si i uruchamia. Oto przykadowe uruchomienie po uyciu kompilatora
Xcode 4.6:
Wieksza liczba z 3 i 5 jest 1606416656.
Wieksza liczba z 3 i 5 jest 3886.

Kup ksik

Pole ksik

376

J}ZYK C. SZKOA PROGRAMOWANIA

Uruchomienie po skompilowaniu przez GCC dao wartoci 1359379472 oraz 1359377160.


Kompilatory zadziaay prawidowo; pady jedynie ofiar braku prototypw funkcji.
O co chodzi? Szczegy zale od systemu, ale oto co dzieje si na komputerach PC
i VAX: funkcja wywoujca umieszcza argumenty w tymczasowym obszarze pamici
zwanym stosem (ang. stack), skd pobiera je funkcja wywoywana. Oba procesy nie s
ze sob skoordynowane. Funkcja wywoujca okrela typ przekazywanej wartoci
w oparciu o typy argumentw faktycznych, natomiast funkcja wywoywana odczytuje
wartoci, kierujc si typami argumentw formalnych. Tym samym, cho wywoanie
imax(3) umieszcza na stosie tylko jedn liczb cakowit, to funkcja imax() pobiera
ze stosu dwie takie liczby. Pierwsza odczytana warto jest przekazanym argumentem,
a druga czymkolwiek, co znajdowao si na stosie.
W drugim wywoaniu funkcja imax() otrzymuje dwa argumenty typu float. Jest to
rwnoznaczne z umieszczeniem na stosie dwch wartoci typu double. (Jak pamitasz,
wartoci typu float s awansowane do double, gdy s przekazywane jako argumenty). W naszym systemie typ double ma 64 bity, a wic na stosie znalazo si 128 bitw
danych. Odczytujc ze stosu dwie wartoci typu int, funkcja imax() pobraa 64 bity,
poniewa na naszym komputerze typ int mieci 32 bity. Bity te zupenie przypadkiem odpowiaday dwm liczbom cakowitym, z ktrych wiksza wynosia 3886.

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.

LISTING 9.5. Program proto1.c


/* proto1.c -- wykorzystuje prototyp funkcji */
#include <stdio.h>
int imax(int, int);
/* prototyp */

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);
}

Gdy sprbowalimy skompilowa listing 9.5, nasz kompilator wywietli komunikat


o tym, e wywoanie funkcji imax() zawiera za mao parametrw.
Co z bdami typw? Aby to sprawdzi, wywoanie imax(3) zamienilimy na imax(3, 5)
i ponownie dokonalimy prby kompilacji. Tym razem nie byo komunikatw o bdach,
a po uruchomieniu programu uzyskalimy nastpujcy wynik:
Wieksza liczba z 3 i 5 jest 5.
Wieksza liczba z 3 i 5 jest 5.

Wartoci 3.0 i 5.0 w drugim wywoaniu zostay zgodnie z obietnic przetworzone na


3 i 5, aby funkcja moga je prawidowo obsuy.
Cho nie wywietli si komunikat o bdzie, kompilator zgosi jednak ostrzeenie o konwersji wartoci typu double na int i moliwej utracie danych. Na przykad
wywoanie funkcji:
imax(3.9, 5.4);

staje si rwnowane wywoaniu:


imax(3, 5);

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.

Brak argumentw a argumenty nieokrelone


Zamy, e uyjesz nastpujcego prototypu:
void wyswietl_imie();

Kompilator zgodny z ANSI C przyjmie, e po prostu zdecydowae si nie korzysta


z prototypu, i nie bdzie sprawdza poprawnoci argumentw w wywoaniach funkcji.
Aby zasygnalizowa, e funkcja nie pobiera adnych argumentw, w nawiasie naley
umieci sowo kluczowe void:
void wyswietl_imie(void);

Kup ksik

Pole ksik

378

J}ZYK C. SZKOA PROGRAMOWANIA

ANSI C zinterpretuje powysze wyraenie jako informacj, e funkcja wyswietl_imie()


nie przyjmuje argumentw, i dopilnuje, aby wywoania funkcji rzeczywicie nie zawieray adnych parametrw.
Kilka funkcji, takich jak printf() i scanf(), przyjmuje zmienn liczb argumentw. Na przykad w funkcji printf() pierwszy argument jest acuchem, ale liczba
i typy pozostaych argumentw s nieznane. W takich przypadkach ANSI C dopuszcza
stosowanie prototypw czciowych. Funkcja printf() mogaby mie na przykad
nastpujcy prototyp:
int printf(const char *, ...);

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.

Rekurencja bez tajemnic


Aby zobaczy, o co chodzi, przyjrzyjmy si przykadowi. Funkcja main() w listingu
9.6 wywouje funkcj gora_i_dol(). Bdziemy to nazywa pierwszym poziomem
rekurencji. Nastpnie funkcja gora_i_dol() wywouje sama siebie, co bdziemy
okrela drugim poziomem rekurencji. Drugi poziom rekurencji wywouje trzeci
poziom itd. Poniszy przykad dochodzi do czwartego poziomu. Aby umoliwi lepszy
wgld w swoje dziaanie, oprcz wywietlenia wartoci n program podaje rwnie
adres &n, pod ktrym przechowywana jest zmienna n. (W dalszej czci rozdziau
omwiono dokadniej zagadnienie wskanikw. Funkcja printf() do wywietlania
wskanikw uywa specyfikatora %p; jeli dany system nie obsuguje tego specyfikatora,
mona uy %u lub %lu).

LISTING 9.6. Program rekur.c


/* rekur.c -- ilustracja rekurencji */
#include <stdio.h>
void gora_i_dol(int);
int main(void)
{
gora_i_dol(1);
return 0;
}
void gora_i_dol(int n)
{
printf("Poziom: %d: adres zmiennej n: %p\n", n, &n);
if (n < 4)
gora_i_dol(n+1);
printf("POZIOM %d: adres zmiennej n: %p\n", n, &n);
}

Dane wyjciowe wygldaj tak:


Poziom
Poziom
Poziom
Poziom

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

J}ZYK C. SZKOA PROGRAMOWANIA

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

Po drugie, kademu wywoaniu funkcji odpowiada jeden powrt. Po wykonaniu


instrukcji return na kocu ostatniego poziomu rekurencji program przechodzi do
poprzedniego poziomu rekurencji, nie za do funkcji main(). Aby dotrze do miejsca
pierwotnego wywoania funkcji gora_i_dol() w main(), program musi przej przez
wszystkie kolejne poziomy rekurencji, wracajc z kadego poziomu funkcji gora_i_dol()
do poziomu, ktry go wywoa.
Po trzecie, instrukcje w funkcji rekurencyjnej, znajdujce si przed miejscem, w ktrym
wywouje ona sam siebie, wykonywane s w kolejnoci wywoywania poziomw.
Na przykad na listingu 9.6 pierwsza instrukcja pisania znajduje si przed wywoaniem rekurencyjnym. Zostaa ona wykonana czterokrotnie w kolejnoci wywoa:
Poziom 1, Poziom 2, Poziom 3 i Poziom 4.
Po czwarte, instrukcje w funkcji rekurencyjnej, znajdujce si po miejscu, w ktrym
wywouje ona sam siebie, wykonywane s w kolejnoci odwrotnej do kolejnoci
wywoywania poziomw. Na przykad po wywoaniu rekurencyjnym znajduje si
druga instrukcja printf(). Zostaa ona wykonana w nastpujcej kolejnoci: Poziom
4, Poziom 3, Poziom 2, Poziom 1. Ta cecha rekurencji jest uyteczna w przypadku
problemw programistycznych wymagajcych odwrcenia kolejnoci dziaa (wkrtce
przedstawimy przykad).
Po pite, chocia kady poziom rekurencji posiada swj wasny zestaw zmiennych,
kod funkcji nie jest zwielokrotniany. Kod funkcji jest cigiem instrukcji, a wywoanie
funkcji jest poleceniem nakazujcym przejcie do jego pocztku. Wywoanie rekurencyjne powoduje wic powrt programu do pocztku funkcji. Poza tym, e wywoania rekurencyjne tworz nowe zmienne, w duym stopniu przypominaj one ptl.
W wielu przypadkach rekurencj i ptl mona stosowa zamiennie.
Po szste i ostatnie, niezwykle istotne jest, aby funkcja rekurencyjna posiadaa element umoliwiajcy zakoczenie sekwencji wywoa rekurencyjnych. Zazwyczaj
funkcja rekurencyjna uywa instrukcji warunkowej if albo jej odpowiednika, aby
przerwa rekurencj, gdy argument funkcji osignie okrelon warto. Aby ten
mechanizm zadziaa, kade wywoanie funkcji wymaga innej wartoci argumentu.

Kup ksik

Pole ksik

382

J}ZYK C. SZKOA PROGRAMOWANIA

W ostatnim z przykadw, funkcja gora_i_dol(n) wywouje gora_i_dol(n+1).


W kocu argument faktyczny n osiga warto 4, powodujc, e if(n < 4) zwraca false.

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.

LISTING 9.7. Program silnia.c


// silnia.c oblicza silnie za pomoca rekurencji i petli
#include <stdio.h>
long silnia(int n);
long rsilnia(int n);
int main(void)
{
int num;
printf("Ten program liczy silnie.\n");
printf("Podaj liczbe z przedzialu 0-12 (k - koniec):\n");
while (scanf("%d", &num) == 1)
{
if (num < 0)
printf("Prosze nie podawac liczb ujemnych.\n");
else if (num > 12)
printf("Prosze podac wartosc mniejsza od 13.\n");
else
{
printf("petla: %d silnia = %ld\n",
num, silnia(num));
printf("rekurencja: %d silnia = %ld\n",
num, rsilnia(num));
}
printf("Podaj liczbe z przedzialu 0-12 (k - koniec):\n");
}
printf("Gotowe.\n");
return 0;
}
long silnia(int n)
// wersja oparta na petlach
{
long wyn;
for (wyn = 1; n > 1; n--)
wyn *= n;

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;
}

Program ogranicza dane wejciowe do liczb cakowitych z przedziau od 0 do 12.


Wynika to z faktu, e 12! ma warto nieco poniej p miliarda, co oznacza, e liczba 13!
znacznie przekroczy zakres typu long na naszym komputerze. Aby wykroczy poza 12!,
musiaby uy typu o wikszym zakresie, takiego jak double czy long long.
Oto przykad wykonania programu:
Ten program liczy silnie.
Podaj liczbe z przedzialu 0-12 (k - koniec):
5
petla: 5 silnia = 120
rekurencja: 5 silnia = 120
Podaj liczbe z przedzialu 0-12 (k - koniec):
10
petla: 10 silnia = 3628800
rekurencja: 10 silnia = 3628800
Podaj liczbe z przedzialu 0-12 (k - koniec):
k
Gotowe

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

J}ZYK C. SZKOA PROGRAMOWANIA

Jeli funkcj mona napisa z wykorzystaniem zarwno ptli, jak i rekurencji, to


ktrej metody naley uy? Zazwyczaj lepszym rozwizaniem jest ptla. Po pierwsze,
rekurencja zuywa wicej pamici, poniewa kady poziom otrzymuje oddzielny zestaw zmiennych; ponadto kade wywoanie umieszcza na stosie now porcj danych, a systemowe ograniczenia rozmiaru stosu programu mog ograniczy osigaln gboko rekurencji. Po drugie, rekurencja jest wolniejsza, poniewa kade
wywoanie funkcji zabiera czas. Po co wic pokazalimy powyszy przykad? Poniewa
rekurencja kocowa jest najatwiejsz do zrozumienia postaci rekurencji. Rekurencja
jest za czym, co warto zna po prostu dlatego, e w niektrych przypadkach zastpienie jej ptl jest nieopacalne.

Rekurencja i odwracanie kolejnoci dziaa


Przyjrzyjmy si teraz problemowi, w ktrym przydatna jest zdolno rekurencji do
odwracania kolejnoci dziaa (co oznacza, e rekurencja rozwizuje go prociej ni
ptla). Zadanie jest nastpujce: naley napisa funkcj, ktra wywietla dwjkowy
(binarny) odpowiednik liczby cakowitej. System binarny przedstawia liczby za pomoc
potg dwjki. Tak jak 234 w systemie dziesitnym oznacza 2102+3101+4100, tak
w systemie dwjkowym 101 oznacza 122+021+120. Liczby w systemie dwjkowym
skadaj si wycznie z cyfr 0 i 1.
Potrzebujemy metody, algorytmu. W jaki sposb moemy znale dwjkowy odpowiednik np. liczby 5? No c, liczby nieparzyste w systemie binarnym kocz si
cyfr 1, a parzyste cyfr 0, ostatni cyfr moemy wic obliczy za pomoc wyraenia 5 % 2. Jeli ma ono warto 1, oznacza to, e 5 jest liczb nieparzyst i koczy si
cyfr 1. Oglnie rzecz biorc, jeli n jest liczb, to jej ostatni cyfr w systemie dwjkowym jest n % 2 pierwsza cyfra, jak moemy obliczy, jest wic ostatni cyfr,
ktr naley wywietli. Sugeruje to uycie funkcji rekurencyjnej, w ktrej n % 2
byoby obliczane przed wywoaniem rekurencyjnym, ale wywietlane po tym wywoaniu. W ten sposb warto obliczona jako pierwsza zostaaby wywietlona na kocu.
Aby otrzyma kolejn cyfr, dzielimy wyjciow liczb przez 2. W systemie dwjkowym jest to rwnowane usuniciu ostatniej cyfry (jeli nie operujemy na liczbach
zmiennoprzecinkowych). Jeli otrzymany wynik jest parzysty, kolejn cyfr postaci
binarnej jest 0; w przeciwnym wypadku cyfr t jest 1. Na przykad 5/2 jest rwne 2
(dzielenie cakowite!), a wic drug cyfr od koca jest 0. Na razie mamy wic 01.
Nastpnie powtarzamy proces. Dzielimy 2 przez 2, otrzymujc 1. Obliczenie 1 % 2
daje wynik 1 kolejn cyfr jest wic 1. Mamy ju trzy cyfry: 101. Kiedy powinnimy si zatrzyma? Koczymy prac, gdy wynik dzielenia przez 2 jest mniejszy ni 2,
poniewa w przeciwnym wypadku zostaa nam jeszcze przynajmniej jedna cyfra
binarna. Kade dzielenie przez 2 odcina jedn cyfr dwjkow, do momentu, gdy nie
zostanie ju nic. (Jeli jest to dla Ciebie niejasne, sprbuj przeanalizowa to samo
w systemie dziesitnym. Reszta z dzielenia 628 przez 10 jest rwna 8, a wic ostatni
cyfr jest 8. Dzielenie cakowite przez 10 daje wynik 62. Reszta z dzielenia 62 przez
10 wynosi 2, a wic nastpn cyfr jest 2 itd.). Listing 9.8 stanowi implementacj naszego algorytmu.

Kup ksik

Pole ksik

Rozdzia 9. FUNKCJE

385

LISTING 9.8. Program binar.c


/* binar.c -- wyswietla liczbe calkowita w postaci dwojkowej */
#include <stdio.h>
void do_binar(unsigned long n);
int main(void)
{
unsigned long liczba;
printf("Podaj liczbe calkowita (q konczy program):\n");
while (scanf("%ld", &liczba) == 1)
{
printf("Odpowiednik dwojkowy: ");
do_binar(liczba);
putchar('\n');
printf("Podaj liczbe calkowita (q konczy program):\n");
}
printf("Gotowe.\n");
return 0;
}
void do_binar(unsigned long n)
{
int r;
r = n % 2;
if (n >= 2)
do_binar(n / 2);
putchar(r == 0 ? '0' : '1');
return;
}

/* 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

Czy moglibymy zaimplementowa ten algorytm znajdowania postaci dwjkowej bez


korzystania z rekurencji? Tak. Jednak ze wzgldu na to, e ostatnia cyfra jest w nim
obliczana jako pierwsza, musielibymy zapisywa gdzie kolejne cyfry (na przykad
w tablicy) przed wywietleniem wyniku. Przykad podejcia nierekurencyjnego jest
przedstawiony w rozdziale 15., Manipulowanie bitami.

Kup ksik

Pole ksik

386

J}ZYK C. SZKOA PROGRAMOWANIA

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;
}

Rekurencyjna funkcja w jzyku C zaledwie przeformuowuje rekurencyjn definicj


matematyczn. Funkcja uywa podwjnej rekurencji (ang. double recursion) tzn.
funkcja wywouje sam siebie dwa razy. A to powoduje, e musimy przej do omawiania wad.
Aby uwidoczni natur tego problemu, przypumy, e wywoujesz funkcj Fibonacci(40). Jest to pierwszy poziom rekurencji, w ktrym zmiennej n przydzielona
zostaje pami. Nastpnie funkcja ponownie wywouje Fibonacci(), tworzc dwie
dodatkowe zmienne o nazwie n na drugim poziomie rekurencji. Kade z tych dwch
wywoa generuje dwa kolejne wywoania, wymagajce czterech dodatkowych
zmiennych n na trzecim poziomie rekurencji. Kady poziom wymaga dwa razy wicej
zmiennych ni poprzedni, liczba zmiennych ronie wic wykadniczo! Jak widziae na
przykadzie z ziarnami pszenicy w rozdziale 5., wzrost wykadniczy prowadzi byskawicznie do wielkich wartoci. W tym przypadku, wzrost wykadniczy szybko sprawi, e
wymagana pami przekroczy dostpn, co spowoduje zawieszenie si programu.
C, jest to moe skrajny przykad, ale dobrze demonstruje konieczno zachowania
ostronoci podczas uywania rekurencji, szczeglnie gdy liczy si wydajno.

Kup ksik

Pole ksik

Rozdzia 9. FUNKCJE

387

Wszystkie funkcje jzyka C s rwne


Kada funkcja jzyka C istnieje w programie na rwnych prawach. Kada moe
wywoa kolejn funkcj albo sama by wywoana przez inn. Sprawia to, e funkcje
w jzyku C rni si nieco od procedur w Pascalu czy Moduli-2, ktre mog by
zagniedane w procedurach. Procedury w jednym zagniedeniu nie mog korzysta
z procedur z innego zagniedenia.
Czy funkcja main() nie jest tu wyjtkiem? Tak, jest troch wyjtkowa, gdy wykonanie skadajcego si z wielu funkcji programu rozpoczyna si od pierwszej
instrukcji wewntrz funkcji main(), ale na tym kocz si jej przywileje. Nawet
main() moe by wywoywana rekurencyjnie przez siebie lub te przez inne funkcje, cho zdarza si to raczej rzadko.

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

W Uniksie stosuje si te polecenie make, ktre automatyzuje kompilacj programw


skadajcych si z wielu plikw kodu rdowego, ale jego omwienie to ju temat na
osobn ksik.
Pamitajmy, e w systemie OS X program Terminal pozwala na prac w powoce uniksowej, ale programy kompilatorw (Clang lub GCC) trzeba zainstalowa samodzielnie).

Kup ksik

Pole ksik

388

J}ZYK C. SZKOA PROGRAMOWANIA

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

DOS (kompilatory wiersza polece)


Wikszo kompilatorw wiersza polece dla systemu DOS dziaa podobnie jak polecenie cc w systemie Unix (rnica sprowadza si czsto do nazwy polecenia). Jedna
z rnic polega na tym, e pliki obiektowe otrzymuj w DOS-ie rozszerzenie .obj,
a nie .o. Niektre kompilatory zamiast plikw kodu obiektowego tworz pliki przejciowe w jzyku asemblera lub we wasnym, specjalnym jzyku.

rodowiska IDE dla Windows i OS X


Zintegrowane rodowiska programistyczne dla systemw Windows i OS X s oparte
na koncepcji projektu. Projekt opisuje zasoby wykorzystywane przez dany program.
Nale do nich take pliki z Twoim kodem rdowym. Jeli uywae ktrego z tych
kompilatorw, prawdopodobnie bye zmuszony tworzy projekty nawet po to, aby
uruchomi jednoplikowy program. W przypadku programw skadajcych si z kilku
plikw musisz znale w menu kompilatora polecenie, ktre pozwoli Ci doda plik
z kodem rdowym do projektu. Powiniene si upewni, e wszystkie pliki z kodem
rdowym (z rozszerzeniem .c) zostay wymienione jako skadniki projektu. W wikszoci IDE plikw nagwkowych (tych z rozszerzeniem .h) nie docza si jawnie do
listy plikw projektu, a jedynie wcza si je do plikw kodu rdowego (.c) dyrektyw
#include; wyjtkiem jest Xcode, gdzie pliki nagwkowe wczane do programu stanowi cz projektu.

Korzystanie z plikw nagwkowych


Jeli funkcja main() znajduje si w jednym pliku, a definicje pozostaych funkcji
w drugim, pierwszy plik wci potrzebuje prototypw. Aby nie musie wpisywa ich
za kadym razem, gdy bdziesz chcia skorzysta ze swoich funkcji, moesz umieci
je w pliku nagwkowym. Tak wanie postpili autorzy standardowej biblioteki C jak
pamitasz, prototypy funkcji we-wy znajduj si w pliku stdio.h, a prototypy funkcji
matematycznych w math.h. Analogicznie moesz postpi ze swoimi funkcjami.
Ponadto programy czsto zawieraj stae zdefiniowane z wykorzystaniem preprocesora. Takie definicje obejmuj jedynie plik, w ktrym znajduj si dyrektywy

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).

LISTING 9.9. Program oplaty.c


/* oplaty.c -- program obliczajacy oplate za pokoj */
/* kompiluj razem z listingiem 9.10
*/
#include <stdio.h>
#include "hotel.h" /* definiuje stale, deklaruje funkcje */
int main(void)
{
int noce;
double hotel;
int kod;
while ((kod = menu()) != KONIEC)
{
switch(kod)
{
case 1 : hotel = HOTEL1;
break;
case 2 : hotel = HOTEL2;
break;

Kup ksik

Pole ksik

390

J}ZYK C. SZKOA PROGRAMOWANIA

case 3 : hotel = HOTEL3;


break;
case 4 : hotel = HOTEL4;
break;
default: hotel = 0.0;
printf("Ups!\n");
break;
}
noce = pobierz_noce();
pokaz_cene(hotel, noce);
}
printf("Dziekuje i do widzenia\n");
return 0;
}

LISTING 9.10. Modu wspomagajcy hotel.c


/* hotel.c -- funkcje dla zarzadzajacych hotelami */
#include <stdio.h>
#include "hotel.h"
int menu(void)
{
int kod, stan;
printf("\n%s%s\n", GWIAZDKI, GWIAZDKI);
printf("Podaj numer hotelu:\n");
printf("1) Marek Antoniusz
2) Olimpijski\n");
printf("3) U Marynarza
4) Savoy\n");
printf("5) koniec\n");
printf("%s%s\n", GWIAZDKI, GWIAZDKI);
while ((stan = scanf("%d", &kod)) != 1 ||
(kod < 1 || kod > 5))
{
if (stan != 1)
scanf("%*s"); // odrzucamy wejcie nieliczbowe
printf("Podaj liczbe z przedzialu od 1 do 5.\n");
}
return kod;
}
int pobierz_noce(void)
{
int noce;
printf("Ile nocy bedzie potrzebne? ");
while (scanf("%d", &noce) != 1)
{
scanf("%*s"); // odrzucamy wejcie nieliczbowe
printf("Podaj liczbe calkowita, np. 2.\n");
}
return noce;
}
void pokaz_cene(double hotel, int noce)
{
int n;
double suma = 0.0;
double przelicznik = 1.0;

Kup ksik

Pole ksik

Rozdzia 9. FUNKCJE

391

for (n = 1; n <= noce; n++, przelicznik *= RABAT)


suma += hotel * przelicznik;
printf("Calkowity koszt pobytu wyniesie %0.2f $.\n", suma);
}

LISTING 9.11. Plik nagwkowy hotel.h


/* hotel.h -- stale i deklaracje dla hotel.c */
#define KONIEC
5
#define HOTEL1
80.00
#define HOTEL2
125.00
#define HOTEL3
155.00
#define HOTEL4
200.00
#define RABAT
0.95
#define GWIAZDKI "**********************************"
// pokazuje liste wyborow
int menu(void);
// zwraca zadana liczbe nocy
int pobierz_noce(void);
// oblicza cene na podstawie stawki i liczby noclegw
// i wyswietla wynik
void pokaz_cene(double hotel, int noce);

Oto przykadowy przebieg dziaania programu:


********************************************************************
Podaj numer hotelu:
1) Marek Antoniusz
2) Olimpijski
3) U Marynarza
4) Savoy
5) koniec
********************************************************************
3
Ile nocy bedzie potrzebne? 1
Calkowity koszt pobytu wyniesie 155.00 $.
********************************************************************
Podaj numer hotelu:
1) Marek Antoniusz
2) Olimpijski
3) U Marynarza
4) Savoy
5) koniec
********************************************************************
4
Ile nocy bedzie potrzebne? 3
Calkowity koszt pobytu wyniesie 570.50 $.
********************************************************************
Podaj numer hotelu:
1) Marek Antoniusz
2) Olimpijski
3) U Marynarza
4) Savoy
5) koniec
********************************************************************
5
Dziekuje i do widzenia

Kup ksik

Pole ksik

392

J}ZYK C. SZKOA PROGRAMOWANIA

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.

Uzyskiwanie adresw: operator &


Jednym z najwaniejszych (i czasami najtrudniejszych) poj jzyka C jest wskanik
(ang. pointer), czyli zmienna przechowujca adres w pamici. W jednym z wczeniejszych rozdziaw stwierdzilimy, e argumenty funkcji scanf() s adresami. Mwic
oglniej, kada funkcja, ktra modyfikuje dane w funkcji wywoujcej bez uycia
wartoci zwracanej, wykorzystuje adresy. Nasze omwienie rozpoczniemy od prezentacji jednoargumentowego operatora & (zagadnienia uywania i naduywania wskanikw bd kontynuowane w nastpnym rozdziale).
Jednoargumentowy operator & pozwala uzyska adres, pod ktrym przechowywana
jest zmienna. Jeli ach jest nazw zmiennej, to &ach jest jej adresem. Adres moesz
wyobraa sobie jako miejsce w pamici. Zamy, e mamy nastpujc instrukcj:
ach = 24;

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);

daaby nastpujcy wynik (%p jest specyfikatorem wywietlajcym adresy):


24 0B76

W listingu 9.12 wykorzystujemy operator &, aby sprawdzi, gdzie przechowywane s


zmienne o tych samych nazwach nalece do rnych funkcji.

Kup ksik

Pole ksik

Rozdzia 9. FUNKCJE

393

LISTING 9.12. Program sprmiejs.c


/* sprmiejs.c -- sprawdza, gdzie przechowywane sa zmienne */
#include <stdio.h>
void mikado(int);
/* deklaracja funkcji */
int main(void)
{
int ach = 2, och = 5;
/* lokalne wzgledem main() */
printf("W funkcji main() ach = %d, a &ach = %p\n", ach, &ach);
printf("W funkcji main() och = %d, a &och = %p\n", och, &och);
mikado(ach);
return 0;
}
void mikado(int och)
/* definicja funkcji */
{
int ach = 10;
/* lokalna wzgledem mikado() */
printf("W funkcji mikado() ach = %d, a &ach = %p\n",
ach, &ach);
printf("W funkcji mikado() och = %d, a &och = %p\n",
och, &och);
}

Powyszy program do wywietlania adresw wykorzystuje specyfikator formatu %p ze


standardu ANSI. Na naszym komputerze dane wyjciowe listingu 9.12 wygldaj
nastpujco:
W
W
W
W

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

J}ZYK C. SZKOA PROGRAMOWANIA

Modyfikacja zmiennych w funkcji wywoujcej


Czasami podane jest, aby funkcja dokonywaa modyfikacji zmiennych nalecych
do innej funkcji. Na przykad powszechn czynnoci przy sortowaniu jest zamiana
wartoci dwch zmiennych. Zamy, e mamy dwie zmienne o nazwach x i y i chcemy
zamieni ich wartoci. Najbardziej oczywiste rozwizanie
x = y;
y = x;

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.

LISTING 9.13. Program zamien1.c


/* zamien1.c -- pierwsza proba wykonania funkcji zamieniajacej */
#include <stdio.h>
void zamiana(int u, int v); /* deklaracja funkcji */
int main(void)
{
int x = 5, y = 10;
printf("Poczatkowo x = %d, a y = %d.\n", x, y);
zamiana(x, y);
printf("A teraz x = %d, a y = %d.\n", x, y);
return 0;
}
void zamiana(int u, int v) /* definicja funkcji */
{
int temp;
temp = u;
u = v;
v = temp;
}

Uruchomienie programu daje nastpujcy wynik:


Poczatkowo x = 5, a y = 10.
A teraz x = 5, a y = 10.

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

LISTING 9.14. Program zamien2.c


/* zamien2.c -- badanie programu zamien1.c */
#include <stdio.h>
void zamiana(int u, int v);
int main(void)
{
int x = 5, y = 10;
printf("Poczatkowo x = %d, a y = %d.\n", x, y);
zamiana(x, y);
printf("A teraz x = %d, a y = %d.\n", x, y);
return 0;
}
void zamiana(int u, int v)
{
int temp;
printf("Poczatkowo u = %d, a v = %d.\n", u, v);
temp = u;
u = v;
v = temp;
printf("A teraz u = %d, a v = %d.\n", u, v);
}

Oto nowe dane wyjciowe:


Poczatkowo x = 5, a y = 10.
Poczatkowo u = 5, a v = 10.
A teraz u = 10, a v = 5.
A teraz x = 5, a y = 10.

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);

a nastpnie zmieni wywoanie w funkcji main() tak, jak pokazano poniej:


x = zamiana(x,y);

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

J}ZYK C. SZKOA PROGRAMOWANIA

Wskaniki: pierwsze spojrzenie


Wskaniki? C to takiego? Zasadniczo wskanik (ang. pointer) jest zmienn (lub
mwic oglniej, obiektem danych), ktrej warto jest adresem. Tak jak wartoci
zmiennej typu char jest znak, a wartoci zmiennej typu int liczba cakowita,
tak wartoci zmiennej wskanikowej jest adres w pamici. Jeli zmienna wskanikowa nosi nazw wsk, prawidowa jest na przykad nastpujca instrukcja:
wsk = &ach;

// przypisuje zmiennej wsk adres zmiennej ach

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;

// powoduje, ze wsk wskazuje na och zamiast na ach

Teraz wartoci wsk jest adres zmiennej och.


Aby utworzy zmienn wskanikow, musisz zadeklarowa jej typ. Zamy, e chcesz
zadeklarowa wskanik wsk tak, aby mg on przechowywa adres zmiennej typu
int. Aby to zrobi, musisz skorzysta z nowego operatora, przedstawionego w nastpnym podrozdziale.

Operator dereferencji: *
Zamy, e wiesz, e wsk wskazuje na ach:
wsk = &ach;

Wwczas moesz skorzysta z operatora dereferencji *, zwanego rwnie operatorem


porednioci, (ang. dereference, indirection), aby znale warto przechowywan przez
zmienn ach. (Nie pomyl tego jednoargumentowego operatora z dwuargumentowym
operatorem mnoenia symbole s te same, ale dziaanie jest zasadniczo odmienne).
wart = *wsk;

// znajduje wartosc, na ktora wskazuje wsk

Powysze dwie instrukcje (wsk = &ach; i wart = *wsk;) s rwnowane nastpujcej


instrukcji:
wart = 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

// tak nie deklarujemy wskaznika!

Pole ksik

Rozdzia 9. FUNKCJE

397

Podsumowanie. Operatory zwizane ze wskanikami


Operator adresu:
&

Opis oglny:
Operator & pozwala uzyska adres zmiennej, ktra po nim nastpuje.
Przykad:
&siostra jest adresem zmiennej siostra.

Operator dereferencji (porednioci):


*

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

Efektem powyszych instrukcji jest przypisanie zmiennej wart wartoci 22.

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

J}ZYK C. SZKOA PROGRAMOWANIA

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.

Wykorzystanie wskanikw do komunikacji pomidzy funkcjami


Poniewa naszym zamiarem jest rozwizanie problemu z przekazywaniem danych
midzy funkcjami, zaledwie dotknlimy tu powierzchni bogatego i fascynujcego
wiata wskanikw. Listing 9.15 przedstawia program, ktry wykorzystuje wskaniki
w celu uzyskania poprawnego dziaania funkcji zamien(). Przyjrzyjmy mu si i sprbujmy zrozumie, jak dziaa.

LISTING 9.15. Program zamien3.c


/* zamien3.c -- zamiana z wykorzystaniem wskaznikow */
#include <stdio.h>
void zamiana(int * u, int * v);
int main(void)
{
int x = 5, y = 10;
printf("Poczatkowo x = %d, a y = %d.\n", x, y);
zamiana(&x, &y); // wyslanie adresow do funkcji
printf("A teraz x = %d, a y = %d.\n", x, y);
return 0;
}
void zamiana(int * u, int * v)
{
int temp;
temp = *u;
// temp otrzymuje wartosc, na ktora wskazuje u
*u = *v;
*v = temp;
}

Kup ksik

Pole ksik

Rozdzia 9. FUNKCJE

399

Czy listing 9.15 dziaa prawidowo?


Poczatkowo x = 5, a y = 10.
A teraz x = 10, a y = 5.

Tak tym razem wszystko jest w porzdku.


Zobaczmy teraz, w jaki sposb dziaa nasz program. Wywoanie funkcji wyglda
nastpujco:
zamiana(&x, &y);

Zamiast wartoci zmiennych x i y przekazalimy ich adresy. Oznacza to, e wartociami


argumentw formalnych u i v w funkcji zamiana() bd adresy. Zmienne u i v naley
wic zadeklarowa jako wskaniki. Poniewa x i y s liczbami cakowitymi, u i v powinny
by wskanikami do zmiennych typu int. Deklaracja wyglda zatem nastpujco:
void zamiana(int * u, int * v)

Nastpnie w czci gwnej funkcji deklarujemy potrzebn nam zmienn tymczasow:


int temp;

Poniewa chcemy nada temp warto zmiennej x, piszemy:


temp = *u;

Wskanik u ma bowiem warto &x wskazuje wic na zmienn x. Oznacza to, e


*u jest wartoci zmiennej x. Nie moglibymy napisa
temp = u;

/* ZLE */

poniewa spowodowaoby to przypisanie zmiennej temp adresu a nie wartoci


zmiennej x.
Podobnie, aby przypisa warto y zmiennej x, piszemy:
*u = *v;

co przekada si na
x = y;

Podsumujmy dziaanie naszego przykadu. Chcielimy napisa funkcj zmieniajc


wartoci x i y. Przekazujc funkcji zamiana() adresy x i y, dalimy jej dostp do tych
zmiennych. Dziki wskanikom i operatorowi * funkcja moe odczyta wartoci zapisane pod tymi adresami i dokona ich zmiany.
W prototypie ANSI C nazwy zmiennych mog zosta pominite:
void zamiana(int *, int *);

Oglnie rzecz biorc, do funkcji moesz przekaza dwa rodzaje informacji o zmiennej.
Jeli uyjesz wywoania w postaci
funkcja1(x);

Kup ksik

Pole ksik

400

J}ZYK C. SZKOA PROGRAMOWANIA

przekazujesz warto x. Jeli za skorzystasz z wywoania o postaci


funkcja2(&x);

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

Zmienne nazwy, adresy i wartoci


Powysze omwienie wskanikw obracao si wok zalenoci pomidzy nazwami,
adresami i wartociami zmiennych. Przyjrzyjmy si temu zagadnieniu nieco bliej.
Piszc program, koncentrujemy si gwnie na dwch cechach zmiennych: nazwie
i wartoci (inne cechy, jak typ, moemy tu zignorowa). Po skompilowaniu i zaadowaniu programu komputer rwnie zwraca uwag na dwie cechy zmiennych:
warto i adres. Adres moemy okreli jako komputerowy odpowiednik nazwy.
W wielu jzykach adres zmiennej jest prywatn spraw komputera, niewidoczn
dla programisty. Jzyk C pozwala natomiast uzyska adres zmiennej za pomoc
operatora &.
&trawa jest adresem zmiennej trawa.

Aby uzyska warto, wystarczy poda nazw zmiennej: printf("%d\n",


trawa) wywietli warto zmiennej trawa.
Aby uzyska warto przechowywan pod danym adresem, korzystamy z operatora *.
Jeli ptrawa == &trawa, to *ptrawa jest wartoci przechowywan pod
adresem &trawa.
Mwic w skrcie, podstawow cech zwykej zmiennej jest warto; adres jest
za cech drugorzdn, uzyskiwan za porednictwem operatora &. W przypadku
zmiennej wskanikowej jest dokadnie odwrotnie: cech drugorzdn jest warto aby j bowiem otrzyma, musimy skorzysta z operatora *.
Cho moesz chcie sprawdzi adres zmiennej tylko po to, aby zaspokoi swoj
ciekawo, nie jest to gwne zastosowanie operatora &. Operator ten (a take *)
pozwala przeprowadza operacje, w ktrych adresy wyraone s w sposb symboliczny, tak jak zrobilimy to w programie zamien3.c (patrz listing 9.15).

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

J}ZYK C. SZKOA PROGRAMOWANIA

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);

przesya te wartoci do zmiennych x i y. Wartoci 5 i 2 nazywamy argumentami


faktycznymi, a zmienne x i y w funkcji roznica() argumentami formalnymi.
Sowo kluczowe return przekazuje pojedyncz warto z funkcji wywoywanej
do funkcji wywoujcej. W powyszym przykadzie c otrzymuje warto zmiennej z, czyli 3. Aby moliwa bya modyfikacja wicej ni jednej zmiennej w funkcji
wywoujcej, argumenty formalne musz by wskanikami.
Typ zwracany funkcji:
Typ zwracany funkcji okrela typ wartoci zwracanych do wywoujcego. Jeli
zwracana warto jest innego typu ni deklarowany typ zwracany, warto zwracana jest rzutowana na odpowiedni typ.
Sygnatura funkcji:
Na sygnatur funkcji skada si typ zwracany funkcji wraz z list parametrw
funkcji; sygnatura okrela wic typy wartoci przekazywanych do funkcji w jej
wywoaniu i typ wartoci odbierany z funkcji po jej zakoczeniu.
Przykad:
double duff(double, int); // prototyp funkcji
int main()
{
double q, x;
int n;
...
q = duff(x,n);
// wywolanie funkcji
...
}
double duff(double u, int k) // definicja funkcji
{
double tor;
...
return tor;
// zwraca wartosc typu double
}

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

utworzy dwie rne zmienne. Funkcja nie ma bezporedniego dostpu do zmiennych


zadeklarowanych w innej funkcji. Takie ograniczenie uatwia zachowanie integralnoci danych. Jeli jednak chcesz, aby funkcja miaa dostp do danych innej funkcji,
moesz uy (jako argumentw) wskanikw.

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

J}ZYK C. SZKOA PROGRAMOWANIA

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");
}

8. Napisz funkcj zwracajc najwikszy z trzech argumentw cakowitych.


9. Zakadajc ponisze dane wyjciowe:
Wybierz jedna z ponizszych mozliwosci:
1) kopiowanie plikow
2) przenoszenie plikow
3) usuwanie plikow
4) koniec
Podaj numer wybranej opcji:

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

J}ZYK C. SZKOA PROGRAMOWANIA

Kup ksik

Pole ksik

SKOROWIDZ
A

abstrakcyjne typy danych,


806
adres, 392, 396
struktury, 642
adresowanie bajtowe, 424
alternatywna pisownia, 1011
analiza programu, 347, 363
analogiczny typ rzeczywisty,
927
anatomia programu, 53
ANSI C, 31, 32, 40
argument
argc, 518
argv, 519
argumenty, 62, 115
faktyczne, 204, 369, 370
formalne, 204, 368, 893
funkcji, 366, 368
makra, 738
makra w acuchach, 741
nieokrelone, 377
wiersza polece, 517, 519,
592
ASCII, 96
asercja, 780
ATD, 806, 821, 831
automatyczna zmiana ziarna,
559
awans, 200

bajt, 84, 694


bezporednie przekazywanie
zmiennej, 911
biae znaki, 163
biblioteka, 31, 38, 44,
Patrz take plik
assert.h, 780
C, 731, 764
ctype.h, 292
fenv.h, 942, 943
I/O, 962
math.h, 254
string.h, 782
tgmath.h, 771
binarne liczby
zmiennoprzecinkowe, 696
bit, 84
najbardziej znaczcy, 695
najmniej znaczcy, 695
bitowa
alternatywa, 700
alternatywa wyczajca,
700
koniunkcja, 699
negacja, 699
bitowe operatory
logiczne, 699
przesunicia, 704, 705
bity, 694
odwracanie, 703
sprawdzenie wartoci, 703

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

1014 J}ZYK C. SZKOA PROGRAMOWANIA

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

fprintf(), 599, 659


fputs(), 478, 488, 601
fread(), 609, 611, 660, 663
free(), 563, 565, 568
fscanf(), 599
fseek(), 602605
fsetpos(), 606
ftell(), 602605
fwrite(), 609, 611, 660, 663
getc(), 595
getchar(), 52, 81, 273, 324,
489, 595
gets(), 475
gets_s(), 477, 482
isalpha(), 277
islower(), 292
main(), 5456, 74, 347, 546
malloc(), 563, 565, 650, 797
memcpy(), 782
memmove(), 782
printf(), 62, 96, 138141,
151, 488, 520, 540
putc(), 595
putchar(), 273, 324, 489,
595
puts(), 486, 493
qsort(), 677, 775, 777
rand(), 561
rewind(), 599, 663
scanf(), 81, 138, 154158,
484
setvbuf(), 608, 615
skroc(), 492
sprintf(), 508, 520
sqrt(), 768
srand(), 563
strcat(), 493
strchr(), 510, 511, 684
strcmp(), 496499, 502
strcpy(), 503, 505
strftime(), 977, 978
strlen(), 127131, 492
strncat(), 495, 599
strncpy(), 503, 506
strpbrk(), 510
strrchr(), 510

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

1016 J}ZYK C. SZKOA PROGRAMOWANIA

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

acuch, string, 115, 524


sterujcy, 140
znakowy, 100, 125, 127, 463
acuchowe wejcie-wyjcie,
463
acuchy
a funkcje znakowe, 515
a wskaniki, 473
wczytywanie, 475
wywietlanie, 486
czenie
danych znakowych
i numerycznych, 352
else z if, 281
acuchw, 154
wejcia liczbowego
i znakowego, 340
cznik preprocesora, 742
czno
wewntrzna, 535, 550
zewntrzna, 535, 545
zmiennej, 531, 535, 580

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

1018 J}ZYK C. SZKOA PROGRAMOWANIA

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

poziomy wejcia-wyjcia, 590


prawda, 225-227
preprocesor, 56, 132, 731
priorytet
operatorw, 180, 182, 232
++ i --, 191
logicznych, 289
relacyjnych, 231
program, 64
kompresujcy pliki, 597
liczcy sowa, 292
czcy, 35
programowanie
obiektowe, 532, 870
strukturalne, 25
uoglnione, 759
zstpujce, 25
programy wieloplikowe, 551
projekt, 44, 388
projektowanie
modularne, 25
programu, 34
prototyp funkcji, 68, 205, 364,
369, 375, 403, 436, 812, 1007
przebieg programu, 215
przechowywanie wartoci
wskanikw, 960
przedefiniowywanie staych,
737
przedrostek
&, 127
0x, 107
przekazywanie
adresu zmiennej, 912
argumentw, 151, 152
skadnikw struktur, 641
struktury jako
argumentu, 643
tablicy, 457
wartoci, 401
przekierowywanie, 323, 332,
587, 591
czone, 334
wejcia, 333
wyjcia, 334
przenono typw, 25, 143,
605

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

rozmiar tablicy, 416, 453


rozmiary typw, 113
rozszerzalne funkcje
klasyfikujce, 986
rozszerzone
typy cakowite, 987
zbiory znakw, 991
rozwijanie makra, 734
r-warto, 173, 174
rzut kostk, 559
rzutowanie typu, 202, 376,
567

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

1020 J}ZYK C. SZKOA PROGRAMOWANIA

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

sygnatura funkcji, 401


symbol, Patrz specyfikator
formatu
symulowanie, 834
system
binarny, 694
dziesitny, 694
semkowy, 697
szesnastkowy, 698
szablon struktury, 628

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

1022 J}ZYK C. SZKOA PROGRAMOWANIA

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

zliczanie sw, 292


zmiana ziarna, 559
zmienna liczba argumentw,
785, 956
zmienne, 83
automatyczne, 538, 552
lokalne, 366
o statycznym czasie
trwania, 552
o zasigu blokowym, 552
rejestrowe, 543
statyczne, 543, 555
o cznoci
wewntrznej, 550
o cznoci zewntrznej,
545
strukturalne, 625, 628
wskanikowe, 432
zewntrzne, 545
znaczniki printf(), 142, 143
znak, 96, 129
apostrofu, , 97
backslash, \, 63
dolara, $, 898
hash, #, 164, 203
koca pliku, EOF, 329,
595
nowej linii, \n, 54, 154, 487
procentu, %, 141
pusty, 482
zerowy, \0, 127, 164, 252
znaki
biae, 163
niedrukowane, 98, 129,
153
szerokie, 979, 982, 994, 996
wielobajtowe, 993, 996
znakowe wejcie-wyjcie,
323
znormalizowane wartoci
zmiennoprzecinkowe, 999
zwalnianie pamici, 805

Pole ksik

You might also like