ProgramowaniewCzch.kis.p.lodz.pl/strony/wikiBooks_Programowanie_w_C.pdf · 12 ROZDZIAŁ1....

216
Programowanie w C Stworzone na Wikibooks, bibliotece wolny podręczników.

Transcript of ProgramowaniewCzch.kis.p.lodz.pl/strony/wikiBooks_Programowanie_w_C.pdf · 12 ROZDZIAŁ1....

  • Programowanie w C

    Stworzone na Wikibooks,bibliotece wolny podrcznikw.

  • Wersja . z dnia listopada Copyright - uytkownicy Wikibooks.

    Udziela si zezwolenia do kopiowania, rozpowszechniania lub modyfikacji tego dokumentuzgodnie z zasadami Licencji Creative Commons Uznanie autorstwa-Na ty samy warunka. Unported lub dowolnej pniejszej wersji licencji opublikowanej przez Creative Com-mons, ktra zawiera te same elementy co niniejsza licencja.

    Tekst licencji mona znale na stronie http://creativecommons.org/licenses/by-sa/3.0/deed.pl.

    Wikibooks nie udziela adnych gwarancji, zapewnie ani obietnic dotyczcych poprawnocipublikowanych treci. Nie udziela te adnych innych gwarancji, zarwno jednoznacznych,jak i dorozumianych.

    http://creativecommons.org/licenses/by-sa/3.0/deed.plhttp://creativecommons.org/licenses/by-sa/3.0/deed.pl

  • Spis tresci

    O podrczniku . O czym mwi ten podrcznik? . . . . . . . . . . . . . . . . . . . . . . . . . . 11. Co trzeba wiedzie, eby skorzysta z niniejszego podrcznika? . . . . . . . . 11. Konwencje przyjte w tym podrczniku . . . . . . . . . . . . . . . . . . . . . 11. Czy mog pomc? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12. Autorzy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12. rda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

    O jzyku C . Historia C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13. Zastosowania jzyka C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15. Przyszo C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    Czego potrzebujesz . Czego potrzebujesz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17. Zintegrowane rodowiska Programistyczne . . . . . . . . . . . . . . . . . . . 18. Dodatkowe narzdzia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    Uywanie kompilatora . GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19. Borland . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20. Czytanie komunikatw o bdach . . . . . . . . . . . . . . . . . . . . . . . . 20

    Pierwszy program . Twj pierwszy program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23. Rozwizywanie problemw . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    Podstawy . Kompilacja: Jak dziaa C? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27. Co moe C? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27. Struktura blokowa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28. Zasig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28. Funkcje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29. Biblioteki standardowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29. Komentarze i styl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30. Preprocesor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32. Nazwy zmiennych, staych i funkcji . . . . . . . . . . . . . . . . . . . . . . . 32

    3

  • Zmienne . Czym s zmienne? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33. Typy zmiennych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36. Specyfikatory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39. Modyfikatory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40. Uwagi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

    Operatory . Przypisanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43. Rzutowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44. Operatory arytmetyczne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45. Operacje bitowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46. Porwnanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48. Operatory logiczne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50. Operator wyraenia warunkowego . . . . . . . . . . . . . . . . . . . . . . . 51. Operator przecinek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51. Operator sizeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51. Inne operatory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52. Priorytety i kolejno oblicze . . . . . . . . . . . . . . . . . . . . . . . . . . 52. Kolejno wyliczania argumentw operatora . . . . . . . . . . . . . . . . . . 53. Uwagi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54. Zobacz te . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

    Instrukcje sterujce . Instrukcje warunkowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57. Ptle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60. Instrukcja goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65. Natychmiastowe koczenie programu funkcja exit . . . . . . . . . . . . . 65. Uwagi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

    Podstawowe procedury wejcia i wyjcia . Wejcie/wyjcie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67. Funkcje wyjcia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68. Funkcja puts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69. Funkcja fputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70. Funkcje wejcia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

    Funkcje . Tworzenie funkcji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78. Wywoywanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79. Zwracanie wartoci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80. Zwracana warto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81. Funkcja main() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81. Dalsze informacje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83. Zobacz te . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

    Preprocesor . Wstp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89. Dyrektywy preprocesora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89. Predefiniowane makra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

    4

  • Biblioteka standardowa . Czym jest biblioteka? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97. Po co nam biblioteka standardowa? . . . . . . . . . . . . . . . . . . . . . . . 97. Gdzie s funkcje z biblioteki standardowej? . . . . . . . . . . . . . . . . . . . 97. Opis funkcji biblioteki standardowej . . . . . . . . . . . . . . . . . . . . . . . 98. Uwagi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

    Czytanie i pisanie do plikw . Pojcie pliku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99. Identyfikacja pliku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99. Podstawowa obsuga plikw . . . . . . . . . . . . . . . . . . . . . . . . . . . 99. Rozmiar pliku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102. Przykad pliki graficzny . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103. Co z katalogami? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

    wiczenia dla pocztkujcy . wiczenia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

    Tablice . Wstp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107. Odczyt/zapis wartoci do tablicy . . . . . . . . . . . . . . . . . . . . . . . . . 109. Tablice znakw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109. Tablice wielowymiarowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110. Ograniczenia tablic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110. Ciekawostki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

    Wskaniki . Co to jest wskanik? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113. Operowanie na wskanikach . . . . . . . . . . . . . . . . . . . . . . . . . . . 114. Arytmetyka wskanikw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117. Tablice a wskaniki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118. Gdy argument jest wskanikiem. . . . . . . . . . . . . . . . . . . . . . . . . . . 119. Puapki wskanikw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120. Na co wskazuje ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120. Stae wskaniki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121. Dynamiczna alokacja pamici . . . . . . . . . . . . . . . . . . . . . . . . . . 122. Wskaniki na funkcje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125. Moliwe deklaracje wskanikw . . . . . . . . . . . . . . . . . . . . . . . . . 127. Popularne bdy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127. Ciekawostki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

    Napisy . acuchy znakw w jzyku C . . . . . . . . . . . . . . . . . . . . . . . . . . 129. Operacje na acuchach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132. Bezpieczestwo kodu a acuchy . . . . . . . . . . . . . . . . . . . . . . . . . 134. Konwersje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137. Operacje na znakach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137. Czste bdy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137. Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

    5

  • Typy zoone . typedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141. Typ wyliczeniowy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141. Struktury . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142. Unie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142. Inicjalizacja struktur i unii . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144. Wsplne wasnoci typw wyliczeniowych, unii i struktur . . . . . . . . . . 144. Studium przypadku implementacja listy wskanikowej . . . . . . . . . . . 146

    Biblioteki . Czym jest biblioteka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151. Jak zbudowana jest biblioteka . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

    Wicej o kompilowaniu . Ciekawe opcje kompilatora . . . . . . . . . . . . . . . . . . . . . . . . . 155. Program make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155. Optymalizacje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157. Kompilacja krzyowa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159. Inne narzdzia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

    Zaawansowane operacje matematyczne . Biblioteka matematyczna . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161. Prezentacja liczb rzeczywistych w pamici komputera . . . . . . . . . . . . . 162. Liczby zespolone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

    Powszene praktyki . Konstruktory i destruktory . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165. Zerowanie zwolnionych wskanikw . . . . . . . . . . . . . . . . . . . . . . 166. Konwencje pisania makr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166. Jak dosta si do konkretnego bitu? . . . . . . . . . . . . . . . . . . . . . . . 167. Skrty notacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

    Przenono programw . Niezdefiniowane zachowanie i zachowanie zalene od implementacji . . . . 171. Rozmiar zmiennych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172. Porzdek bajtw i bitw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172. Biblioteczne problemy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175. Kompilacja warunkowa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

    czenie z innymi jzykami . Jzyk C i Asembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177. C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

    A Indeks alfabetyczny

    B Indeks tematyczny B. assert.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183B. ctype.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183B. errno.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183B. float.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183B. limits.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

    6

  • B. locale.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184B. math.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184B. setjmp.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185B. signal.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185B. stdarg.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185B. stddef.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185B. stdio.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185B. stdlib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186B. string.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186B. time.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

    C Wybrane funkcje biblioteki standardowej C. assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189C. atoi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190C. isalnum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191C. malloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193C. printf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195C. scanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

    D Skadnia D. Symbole i sowa kluczowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203D. Polskie znaki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205D. Operatory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205D. Typy danych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

    E Przykady z komentarzem

    F Informacje o pliku F. Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213F. Informacje o pliku i historia . . . . . . . . . . . . . . . . . . . . . . . . . 213F. Autorzy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213F. Grafiki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

    Skorowidz

    7

  • 8

  • Spis tablic

    . Priorytety operatorw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

    D. Symbole i sowa kluczowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204D. Typy danych wedug rnych specyfikacji jzyka C . . . . . . . . . . . . . . 207

    9

  • Rozdzia 1

    O podrczniku

    1.1 O czym mwi ten podrcznik?Niniejszy podrcznik stanowi przewodnik dla pocztkujcych programistw po jzyku pro-gramowania C.

    1.2 Co trzeba wiedzie, eby skorzysta z niniejszego pod-rcznika?

    Ten podrcznik ma nauczy programowania w C od podstaw do poziomu zaawansowanego.Do zrozumienia rozdziau dla pocztkujcych wymagana jest jedynie znajomo podstawo-wych poj z zakresu algebry oraz terminw komputerowych. Dowiadczenie w programo-waniu w innych jzykach bardzo pomaga, ale nie jest konieczne.

    1.3 Konwencje przyjte w tym podrcznikuInformacje wane oznaczamy w nastpujcy sposb:

    Wana informacja!

    Dodatkowe informacje, ktre odrobin wykraczaj poza zakres podrcznika, a take wy-janiaj kwestie niezwizane bezporednio z jzykiem C oznaczamy tak:

    Wyjanienie

    Ponadto kod w jzyku C bdzie prezentowany w nastpujcy sposb:

    #include

    int main (int argc, char *argv[]){

    return 0;}

    11

  • 12 ROZDZIA 1. O PODRCZNIKU

    Innego rodzaju przykady, dialog uytkownika z konsol i programem, wejcie / wyjcieprogramu, informacje teoretyczne bd wyglday tak:

    typ zmienna = warto;

    1.4 Czy mog pomc?Oczywicie, e moesz. Mao tego, bdziemy zadowoleni z kadej pomocy moesz pisarozdziay lub tumaczy je z angielskiej wersji tego podrcznika. Nie musisz pyta si nikogoo zgod jeli chcesz, moesz zacz ju teraz. Prosimy jedynie o zapoznanie si ze stylempodrcznika, uytymi w nim szablonami i zachowanie ukadu rozdziaw. Propozycje zmianyspisu treci naley zgasza na stronie dyskusji.

    Jeli znalaze jaki bd, a nie umiesz go poprawi, koniecznie powiadom o tym fakcieautorw tego podrcznika za pomoc strony dyskusji danego moduu ksiki. Dziki temuprzyczyniasz si do rozwoju tego podrcznika.

    1.5 AutorzyIstotny wkad w powstanie podrcznika maj:

    CzarnyZajaczek

    Derbeth

    Kj

    mina

    Dodatkowo w rozwoju podrcznika pomagali midzy innymi:

    Lrds

    Noisy

    1.6 rda podrcznik C Programming na anglojzycznej wersji Wikibooks, licencja GFDL

    Brian W. Kernighan, Dennis M. Ritchie, Jzyk ANSI C

    ISO C Commiee Dra, stycznia

    Bruce Eckel, inking in C++. Rozdzia Jzyk C w programie C++.

    http://pl.wikibooks.org/wiki/:en:C_Programminghttp://pl.wikibooks.org/wiki/Dyskusja:Chttp://pl.wikibooks.org/wiki/Wikipedysta:CzarnyZajaczekhttp://pl.wikibooks.org/wiki/Wikipedysta:Derbethhttp://pl.wikibooks.org/wiki/Wikipedysta:Kjhttp://pl.wikibooks.org/wiki/Wikipedysta:Mina86http://pl.wikibooks.org/wiki/Wikipedysta:Lrdshttp://pl.wikibooks.org/wiki/Wikipedysta:Noisyhttp://pl.wikibooks.org/wiki/:en:C_Programminghttp://pl.wikipedia.org/wiki/GFDLhttp://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/http://moria.ii.uj.edu.pl/thinkcpp/index.php/Jzyk_C_w_programie_Cplusplus

  • Rozdzia 2

    O jzyku C

    Zobacz w Wikipedii: C (j-zyk programowania)C jest jzykiem programowania wysokiego poziomu. Jego nazw interpretuje si jako na-

    stpn liter po B (nazwa jego poprzednika), lub drug liter jzyka BCPL (poprzednik jzykaB).

    2.1 Historia CW roku trzej naukowcy z Bell Telephone Laboratories William Shockley, Walter Brat-tain i John Bardeen stworzyli pierwszy tranzystor; w roku, w MIT skonstruowanopierwszy komputer oparty wycznie na tranzystorach: TX-O; w roku Jack Kilby z Te-xas Instruments skonstruowa ukad scalony. Ale zanim powsta pierwszy ukad scalony,pierwszy jzyk wysokiego poziomu zosta ju napisany.

    W powsta Fortran (Formula Translator), ktry zapocztkowa napisanie jzyka For-tran I (). Pniej powstay kolejno:

    Algol Algorithmic Language w r.

    Algol ()

    CPL Combined Programming Language ()

    BCPL Basic CPL ()

    B ()

    i C w oparciu o B.B zosta stworzony przez Kena ompsona z Bell Labs; by to jzyk interpretowany, uy-

    wany we wczesnych, wewntrznych wersjach systemu operacyjnego UNIX. Inni pracownicyBell Labs, ompson i Dennis Richie, rozwinli B, nazywajc go NB; dalszy rozwj NB da C jzyk kompilowany. Wiksza cz UNIX-a zostaa ponownie napisana w NB, a nastpniew C, co dao w efekcie bardziej przenony system operacyjny. W roku wydana zostaaksika pt. e C Programming Language, ktra staa si pierwszym podrcznikiem donauki jzyka C.

    Moliwo uruchamiania UNIX-a na rnych komputerach bya gwn przyczyn po-cztkowej popularnoci zarwno UNIX-a, jak i C; zamiast tworzy nowy system operacyjny,programici mogli po prostu napisa tylko te czci systemu, ktrych wymaga inny sprzt,oraz napisa kompilator C dla nowego systemu. Odkd wiksza cz narzdzi systemowychbya napisana w C, logiczne byo pisanie kolejnych w tym samym jzyku.

    13

    http://pl.wikipedia.org/wiki/C_(jzyk_programowania)http://pl.wikipedia.org/wiki/C_(jzyk_programowania)http://pl.wikibooks.org/wiki/Fortranhttp://pl.wikipedia.org/wiki/Algol_(jzyk_programowania)http://pl.wikipedia.org/wiki/CPLhttp://pl.wikipedia.org/wiki/BCPLhttp://pl.wikipedia.org/wiki/B_(jzyk_programowania)http://pl.wikipedia.org/wiki/Jzyk_interpretowanyhttp://pl.wikipedia.org/wiki/UNIXhttp://pl.wikipedia.org/wiki/Jzyk_kompilowany

  • 14 ROZDZIA 2. O JZYKU C

    Kilka z obecnie powszechnie stosowanych systemw operacyjnych takich jak Linux, Mi-croso Windows zostay napisane w jzyku C.

    2.1.1 Standaryzacje

    W roku Ritchie i Kerninghan opublikowali pierwsz ksik nt. jzyka C e CProgramming Language. Owa ksika przez wiele lat bya swoistym wyznacznikiem, jakprogramowa w jzyku C. Bya wic to niejako pierwsza standaryzacja, nazywana od na-zwisk twrcw K&R. Oto nowoci, wprowadzone przez ni do jzyka C w stosunku dojego pierwszych wersji (pochodzcych z pocztku lat .):

    moliwo tworzenia struktur (sowo struct)

    dusze typy danych (modyfikator long)

    liczby cakowite bez znaku (modyfikator unsigned)

    zmieniono operator =+ na +=

    Ponadto producenci kompilatorw (zwaszcza AT&T) wprowadzali swoje zmiany, nieob-jte standardem:

    funkcje nie zwracajce wartoci (void) oraz typ void*

    funkcje zwracajce struktury i unie

    przypisywanie wartoci strukturom

    wprowadzenie sowa kluczowego const

    utworzenie biblioteki standardowej

    wprowadzenie sowa kluczowego enum

    Owe nieoficjalne rozszerzenia zagroziy spjnoci jzyka, dlatego te powsta standard,regulujcy wprowadzone nowinki. Od roku trway prace standaryzacyjne, aby w roku wyda standard C (poprawna nazwa to: ANSI X.-). Niektre zmiany wpro-wadzono z jzyka C++, jednak rewolucj mia dopiero przynie standard C, ktry wpro-wadzi m.in.:

    funkcje inline

    nowe typy danych (np. long long int)

    nowy sposb komentowania, zapoyczony od C++ (//)

    przechowywanie liczb zmiennoprzecinkowych zostao zaadaptowane do norm IEEE

    utworzono kilka nowych plikw nagwkowych (stdbool.h, inypes.h)

    Na dzie dzisiejszy norm obowizujc jest norma C.

    http://pl.wikipedia.org/wiki/Linuxhttp://pl.wikipedia.org/wiki/Microsoft_Windowshttp://pl.wikipedia.org/wiki/Microsoft_Windowshttp://std.dkuug.dk/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

  • 2.2. ZASTOSOWANIA JZYKA C 15

    2.2 Zastosowania jzyka CJzyk C zosta opracowany jako strukturalny jzyk programowania do celw oglnych. Przezca sw histori (czyli ponad lat) suy do tworzenia przernych programw od syste-mw operacyjnych po programy nadzorujce prac urzdze przemysowych. C, jako jzykduo szybszy od jzykw interpretowanych (Perl, Python) oraz uruchamianych w maszy-nach wirtualnych (np. C#, Java) moe bez problemu wykonywa zoone operacje nawetwtedy, gdy naoone s do due limity czasu wykonywania pewnych operacji. Jest on przytym bardzo przenony moe dziaa praktycznie na kadej architekturze sprztowej podwarunkiem opracowania odpowiedniego kompilatora. Czsto wykorzystywany jest takedo oprogramowywania mikrokontrolerw i systemw wbudowanych. Jednak w niektrychsytuacjach jzyk C okazuje si by mao przydatny, zwaszcza chodzi tu o obliczenia mate-matyczne, wymagajce duej precyzji (w tej dziedzinie znakomicie spisuje si Fortran) lubte duej optymalizacji dla danego sprztu (wtedy niezastpiony jest jzyk asemblera).

    Kolejn zalet C jest jego dostpno waciwie kady system typu UNIX posiada kom-pilator C, w C pisane s funkcje systemowe.

    Problemem w przypadku C jest zarzdzanie pamici, ktre nie wybacza programiciebdw, niewygodne operowanie napisami i niestety pewna liczba kruczkw, ktre mogzaskakiwa nowicjuszy. Na tle modszych jzykw programowania, C jest jzykiem dosyniskiego poziomu wic wiele rzeczy trzeba w nim robi rcznie, jednak zarazem umoliwia torobienie rzeczy nieprzewidzianych w samym jzyku (np. implementacj liczb bitowych),a take atwe czenie C z Asemblerem.

    2.3 Przyszo CPomimo sdziwego ju wieku (C ma ponad lat) nadal jest on jednym z najczciej stosowa-nych jzykw programowania. Doczeka si ju swoich nastpcw, z ktrymi w niektrychdziedzinach nadal udaje mu si wygrywa. Wida zatem, e pomimo pozornej prostoty iniewielkich moliwoci jzyk C nadal spenia stawiane przed nim wymagania. Warto zatemuczy si jzyka C, gdy nadal jest on wykorzystywany (i nic nie wskazuje na to, by miaosi to zmieni), a wiedza ktr zdobdziesz uczc si C na pewno si nie zmarnuje. Skad-nia jzyka C, pomimo e przez wielu uwaana za nieczyteln, staa si podstaw dla takichjzykw jak C++, C# czy te Java.

    http://pl.wikipedia.org/wiki/Maszyna_wirtualnahttp://pl.wikipedia.org/wiki/Maszyna_wirtualnahttp://pl.wikibooks.org/wiki/Fortranhttp://pl.wikibooks.org/wiki/Asembler

  • 16 ROZDZIA 2. O JZYKU C

  • Rozdzia 3

    Czego potrzebujesz

    3.1 Czego potrzebujeszWbrew powszechnej opinii nauczenie si ktrego z jzykw programowania (w tym jzykaC) nie jest takie trudne. Do nauki wystarcz Ci:

    komputer z dowolnym systemem operacyjnym, takim jak FreeBSD, Linux, Windows;

    Jzyk C jest bardzo przenony, wic bdzie dziaa waciwie na kadej platformiesprztowej i w kadym nowoczesnym systemie operacyjnym.

    kompilator jzyka C

    Kompilator jzyka C jest programem, ktry tumaczy kod rdowy napisany przeznas do jzyka asembler, a nastpnie do postaci zrozumiaej dla komputera (maszynycyfrowej) czyli do postaci cigu zer i jedynek ktre steruj prac poszczeglnych ele-mentw komputera. Kompilator jzyka C mona dosta za darmo. Przykadem s:gcc pod systemy uniksowe, DJGPP pod systemy DOS, MinGW oraz lcc pod systemytypu Windows. Jako kompilator C moe dobrze suy kompilator jzyka C++ (rnicemidzy tymi jzykami przy pisaniu prostych programw s nieistotne). Spokojnie mo-esz wic uy na przykad Microso Visual C++ lub kompilatorw firmy Borland.Jeli lubisz eksperymentowa, wyprbuj Tiny C Compiler, bardzo szybki kompilatoro ciekawych funkcjach. Moesz ponadto wyprbowa interpreter jzyka C. Wicejinformacji na Wikipedii.

    Linker (czsto jest razem z kompilatorem)

    Linker jest to program ktry uruchamiany jest po etapie kompilacji jednego lub kilkuplikw rdowych (pliki z rozszerzeniem *.c, *.cpp lub innym) skompilowanych do-wolnym kompilatorem. Taki program czy wszystkie nasze skompilowane pliki r-dowe i inne funkcje (np. printf, scan) ktre byy uyte (doczone do naszego pro-gramu poprzez uycie dyrektywy #include) w naszym programie, a nie byy zdefinio-wane(napisane przez nas) w naszych plikach rdowych lub nagwkowych. Linkerjest to czasami jeden program poczony z kompilatorem. Wywoywany jest on naog automatycznie przez kompilator, w wyniku czego dostajemy gotowy program douruchomienia.

    Debuger (opcjonalnie, wedug potrzeb)

    17

    http://pl.wikipedia.org/wiki/system_operacyjnyhttp://pl.wikipedia.org/wiki/FreeBSDhttp://pl.wikipedia.org/wiki/Linuxhttp://pl.wikipedia.org/wiki/Windowshttp://pl.wikipedia.org/wiki/kompilatorhttp://pl.wikipedia.org/wiki/Gcchttp://pl.wikipedia.org/wiki/DJGPPhttp://pl.wikipedia.org/wiki/MinGWhttp://pl.wikipedia.org/wiki/C_plus_plushttp://pl.wikibooks.org/wiki/Borland_C++_Compilerhttp://pl.wikipedia.org/wiki/Tiny_C_Compilerhttp://pl.wikipedia.org/wiki/Ch_(jzyk_programowania)http://pl.wikipedia.org/wiki/linkerhttp://pl.wikipedia.org/wiki/debuger

  • 18 ROZDZIA 3. CZEGO POTRZEBUJESZ

    Debugger jest to program, ktry umoliwia przeledzenie(okrelenie wartoci poszcze-glnych zmiennych na kolejnych etapach wykonywania programu) linijka po linijcewykonywania skompilowanego i zlinkowanego (skonsolidowanego) programu. Uywasi go w celu okrelenia czemu nasz program nie dziaa po naszej myli lub czemu pro-gram niespodziewanie koczy dziaanie bez powodu. Aby uy debuggera kompilatormusi doczy kod rdowy do gotowego skompilowanego programu. Przykadowymidebuggerami s: gdb pod Linuksem, lub debugger firmy Borland pod Windowsa.

    edytora tekstowego;

    Systemy uniksowe oferuj wiele edytorw przydatnych dla programisty, jak chobyvim i Emacs w trybie tekstowym, Kate w KDE czy gedit w GNOME. Windows maedytor cakowicie wystarczajcy do pisania programw w C niemiertelny Notatnik ale z atwoci znajdziesz w Internecie wiele wygodniejszych narzdzi takich jak np.Notepad++. Odpowiednikiem Notepad++ w systemie uniksowym jest SciTE.

    duo chci i dobrej motywacji.

    3.2 Zintegrowane rodowiska ProgramistyczneZamiast osobnego kompilatora i edytora, moesz wybra Zintegrowane rodowisko Progra-mistyczne (Integrated Development Environment, IDE). IDE jest zestawem wszystkich pro-gramw, ktre potrzebuje programista, najczciej z interfejsem graficznym. IDE zawierakompilator, linker i edytor, z reguy rwnie debugger.

    Bardzo popularny IDE to patny (istnieje take jego darmowa wersja) Microso VisualC++ (MS VC++); popularne darmowe IDE to np.:

    Code::Blocks dla Windows jak i Linux, dostpny na stronie www.codeblocks.org,

    KDevelop (Linux) dla KDE,

    NetBeans multiplatformowy, darmowy do cignicia na stronie www.netbeans.org,

    Eclipse z wtyczk CDT (wsppracuje z MinGW i GCC),

    Borland C++ Builder dostpny za darmo do uytku prywatnego,

    Xcode dlaMac OS X .. i nowszy kompatybilny z procesorami PowerPC i Intel (mo-liwo stworzenia Universal Binary),

    Geany dla systemwWindows i Linux; wsppracuje zMinGW iGCC,www.geany.org,

    Pelles C, www.smorgasbordet.com,

    Dev-C++ dla Windows, dostpny na stronie www.bloodshed.net

    3.3 Dodatkowe narzdziaWrd narzdzi, ktre nie s niezbdne, ale zasuguj na uwag, mona wymieni Valgrinda specjalnego rodzaju debugger. Valgrind kontroluje wykonanie programu i wykrywa nie-prawidowe operacje w pamici oraz wycieki pamici. Uycie Valgrinda jest proste kom-pilujemy program, jak do debugowania, nastpnie podajemy jako argument Valgrindowi.

    http://pl.wikipedia.org/wiki/Vimhttp://pl.wikipedia.org/wiki/Emacshttp://pl.wikipedia.org/wiki/Katehttp://pl.wikipedia.org/wiki/Gedithttp://pl.wikipedia.org/wiki/Notepad++http://pl.wikipedia.org/wiki/SciTEhttp://pl.wikipedia.org/wiki/Zintegrowane_rodowisko_programistycznehttp://pl.wikipedia.org/wiki/Zintegrowane_rodowisko_programistycznehttp://pl.wikipedia.org/wiki/Microsoft_Visual_Studiohttp://pl.wikipedia.org/wiki/Microsoft_Visual_Studiohttp://pl.wikipedia.org/wiki/Code::Blockshttp://www.codeblocks.orghttp://pl.wikipedia.org/wiki/KDevelophttp://pl.wikipedia.org/wiki/NetBeanshttp://www.netbeans.org/http://pl.wikipedia.org/wiki/Eclipsehttp://pl.wikipedia.org/wiki/Borland_C++_Builderhttp://pl.wikipedia.org/wiki/Xcodehttp://www.geany.org/http://www.smorgasbordet.comhttp://pl.wikipedia.org/wiki/Dev-C++http://www.bloodshed.nethttp://valgrind.org/http://pl.wikibooks.org/wiki/C/Wskaniki#Obsuga_pamicihttp://valgrind.org/docs/manual/quick-start.html#quick-start.prepare

  • Rozdzia 4

    Uywanie kompilatora

    Jzyk C jest jzykiem kompilowanym, co oznacza, e potrzebuje specjalnego programu kompilatora ktry tumaczy kod rdowy, pisany przez czowieka, na jzyk rozkazw da-nego komputera. W skrcie dziaanie kompilatora sprowadza si do czytania tekstowegopliku z kodem programu, raportowania ewentualnych bdw i produkowania pliku wyniko-wego.

    Kompilator uruchamiamy ze Zintegrowanego rodowiska Programistycznego lub z kon-soli (linii polece). Przej do konsoli mona dla systemw typu UNIX w trybie graficz-nym uy programw gnome-terminal, konsole albo xterm, w Windows Wiersz polecenia(mona go znalewmenuAkcesoria albo uruchomiwpisujcw Start ->Uruchom. . . cmd).

    4.1 GCCZobacz w Wikipedii: GCC

    GCC jest to darmowy zestaw kompilatorw, m.in. jzyka C rozwijany w ramach projektuGNU. Dostpny jest on na du ilo platform sprztowych, obsugiwanych przez takie sys-temy operacyjne jak: AIX, *BSD, Linux, Mac OS X, SunOS, Windows. Na niektrych sys-temach (np. Windows) nie jest on jednak dostpny automatycznie. Naley zainstalowaodpowiednie narzdza (poprzedni rozdzia).

    Aby skompilowa kod jzyka C za pomoc kompilatora GCC, napisany wczeniej w do-wolnym edytorze tekstu, naley uruchomi program z odpowiednimi parametrami. Podsta-wowym parametrem, ktry jest wymagany, jest nazwa pliku zawierajcego kod programuktry chcemy skompilowa.

    gcc kod.c

    Rezultatem kompilacji bdzie plik wykonywalny, z domyln nazw (w systemach Unixjest to a.out). Jest to metoda niezalecana poniewa jeeli skompilujemy w tym samymkatalogu kilka plikw z kodem, kolejne pliki wykonywalne zostan nadpisane i w rezultacieotrzymamy tylko jeden (ten ostatni) skompilowany kod. Aby wymusi na GCC nazw plikuwykonywalnego musimy skorzysta z parametru -o :

    gcc -o program kod.c

    W rezultacie otrzymujemy plik wykonywalny o nazwie program.Pracujc nad zoonym programem skadajcym si z kilku plikw rdowych (.c), mo-

    emy skompilowa je niezalenie od siebie, tworzc tak zwane pliki typu obiekt, z rozszerze-niem .o (ang. Object File). Nastpnie moemy stworzy z nich jednolity program w procesie

    19

    http://pl.wikipedia.org/wiki/kompilatorhttp://pl.wikipedia.org/wiki/GCChttp://pl.wikipedia.org/wiki/GCChttp://pl.wikipedia.org/wiki/GNUhttp://pl.wikipedia.org/wiki/AIXhttp://pl.wikipedia.org/wiki/BSD#Rodzina_BSDhttp://pl.wikipedia.org/wiki/Linuxhttp://pl.wikipedia.org/wiki/Mac_OS_Xhttp://pl.wikipedia.org/wiki/SunOShttp://pl.wikipedia.org/wiki/Microsoft_Windowshttp://pl.wikipedia.org/wiki/GCChttp://pl.wikipedia.org/wiki/Kompilacja_(informatyka)

  • 20 ROZDZIA 4. UYWANIE KOMPILATORA

    konsolidacji (linkowaniu). Jest to bardzo wygodne i praktyczne rozwizanie ze wzgldu nato, i nie jestemy zmuszeni kompilowa wszystkich plikw tworzcych program za kadymrazem na nowo, a jedynie te, w ktrych wprowadzilimy zmiany Aby skompilowa plik bezlinkowania uywamy parametru -c :

    gcc -o program1.o -c kod1.cgcc -o program2.o -c kod2.c

    Otrzymujemy w ten sposb pliki typu obiekt program.o i program.o. A nastpnie two-rzymy z nich program gwny:

    gcc -o program program1.o program2.o

    Moemy uy rwnie flag, m.in. aby wczy dokadne, rygorystyczne sprawdzanie na-pisanego kodu (co moe by przydatne, jeli chcemy dy do perfekcji), uywamy przecz-nikw:

    gcc kod.c -o program -Werror -Wall -W -pedantic -ansi

    Wicej informacji na temat parametrw i dziaania kompilatora GCC mona znale na:

    Strona domowa projektu GNU GCC

    Krtki przekrojowy opis GCC po polsku

    Strona podrcznika systemu UNIX (man)

    4.2 BorlandZobacz podrcznik Borland C++ Compiler.

    4.3 Czytanie komunikatw o bdaJedn z najbardziej podstawowych umiejtnoci, ktre musi posi pocztkujcy progra-mista jest umiejtno rozumienia komunikatw o rnego rodzaju bdach, ktre sygnali-zuje kompilator. Wszystkie te informacje pomog Ci szybko wychwyci ewentualne bdy(ktrych na pocztku zawsze jest bardzo duo). Nie martw si, e na pocztku do czstobdziesz oglda wydruki bdw, zasygnalizowanych przez kompilator nawet zaawanso-wanym programistom si to zdarza. Kompilator ma za zadanie pomc Ci w szybkiej popra-wie ewentualnych bdw, dlatego te umiejtno analizy komunikatw o bdach jest takwana.

    4.3.1 GCC

    Kompilator jest w stanie wychwyci bdy skadniowe, ktre z pewnoci bdziesz popenia.Kompilator GCC wywietla je w nastpujcej formie:

    nazwa_pliku.c:numer_linijki:opis bdu

    Kompilator do czsto podaje take nazw funkcji, w ktrej wystpi bd. Przykadowo,bd deklaracji zmiennej w pliku test.c:

    http://pl.wikipedia.org/wiki/Konsolidacja_(informatyka)http://pl.wikibooks.org/wiki/w:GCChttp://gcc.gnu.org/http://mops.uci.agh.edu.pl/~pracuch/http://bama.ua.edu/cgi-bin/man-cgi?gcchttp://pl.wikibooks.org/wiki/Borland_C++_Compiler

  • 4.3. CZYTANIE KOMUNIKATW O BDACH 21

    #include

    int main (){

    intr r;printf ("%d\n", r);

    }

    Spowoduje wygenerowanie nastpujcego komunikatu o bdzie:

    test.c: In function main:test.c:5: error: intr undeclared (first use in this function)test.c:5: error: (Each undeclared identifier is reported only oncetest.c:5: error: for each function it appears in.)test.c:5: error: syntax error before rtest.c:6: error: r undeclared (first use in this function)

    Co widzimy w raporcie o bdach? W linii uylimy nieznanego (undeclared) identy-fikatora intr kompilator mwi, e nie zna tego identyfikatora, jest to pierwsze uycie wdanej funkcji i e wicej nie ostrzee o uyciu tego identyfykatora w tej funkcji. Poniewaintr nie zosta rozpoznany jako aden znany typ, linijka intr r; nie zostaa rozpoznana jakodeklaracja zmiennej i kompilator zgasza bd skadniowy (syntax error). W konsekwencji rnie zostao rozpoznane jako zmienna i kompilator zgosi to jeszcze w nastpnej linijce, gdzieuywamy r.

  • 22 ROZDZIA 4. UYWANIE KOMPILATORA

  • Rozdzia 5

    Pierwszy program

    5.1 Twj pierwszy program

    Przyjo si, e pierwszy program napisany w dowolnym jzyku programowania, powinienwywietli tekst Hello World! (Witaj wiecie!). Zauwa, e sam jzyk C nie ma adnychmechanizmw przeznaczonych do wprowadzania i wypisywania danych musimy zatemskorzysta z odpowiadajcych za to funkcji w tym przypadku printf, zawartej w standar-dowej bibliotece C (ang. C Standard Library) (podobnie jak w Pascalu uywa si do tegoprocedur. Pascalowskim odpowiednikiem funkcji printf s procedury write/writeln).

    W jzyku C deklaracje funkcji zawarte s w plika nagwkowy posiadajcych naj-czciej rozszerzenie .h, cho mona take spotka rozszerzenie .hpp, przy czym to drugiezwyko si stosowa w jzyku C++ (rozszerzenie nie ma swych technicznych korzeni jestto tylko pewna konwencja). W celu umieszczenia w swoim kodzie pewnego pliku nagwko-wego, uywamy dyrektywy kompilacyjnej #include. Przed procesem kompilacji, w miejscetej dyrektywy wstawiana jest tre podanego pliku nagwkowego, dostarczajc deklaracjifunkcji.

    Poniszy przykad obrazuje, jak przy uyciu dyrektywy #include umiecimyw kodzie plikstandardowej biblioteki C stdio.h (Standard Input/Output.Headerfile) zawierajc definicjfunkcji printf:

    #include

    W nawiasach trjktnych < > umieszcza si nazwy standardowych plikw nagwko-wych1. eby wczy inny plik nagwkowy (np. wasny), znajdujcy si w katalogu z kodemprogramu, trzeba go wpisa w cudzysw:

    #include "mj_plik_nagwkowy.h"

    Mamy wic funkcj printf, jak i wiele innych do wprowadzania i wypisywania danych,czas na pisanie programu.

    W programie definujemy gwn funkcj main, uruchamian przy starcie programu, za-wierajc waciwy kod. Definicja funkcji zawiera, oprcz nazwy i kodu, take typ wartocizwracanej i argumentw pobieranych. Konstrukcja funkcji main:

    1Domylne pliki nagwkowe znajduj si w katalogu z plikami nagwkowymi kompilatora. W systemach zrodziny Unix bdzie to katalog /usr/include, natomiast w systemie Windows w katalog bdzie umieszczony wkatalogu z kompilatorem.

    23

    http://pl.wikibooks.org/wiki/C/printfhttp://pl.wikibooks.org/wiki/C++http://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#stdio.hhttp://pl.wikibooks.org/wiki/C/printf

  • 24 ROZDZIA 5. PIERWSZY PROGRAM

    int main (void){

    Typem zwracany przez funkcj jest int (Integer), czyli liczba cakowita (w przypadkumainbdzie to kod wyjciowy programu). W nawiasach umieszczane s argumenty funkcji, tutajzapis void oznacza ich pominicie. Funkcja main jako argumenty moe pobiera parametrylinii polece, z jakimi program zosta uruchomiony, i pen ciek do katalogu z programem.

    Kod funkcji umieszcza si w nawiasach klamrowych { i }.Wewntrz funkcji moemy wpisa poniszy kod:

    printf("Hello World!");return 0;

    Wszystkie polecenia koczymy rednikiem. return ; okrela warto jak zwrci funkcja(program); Liczba zero zwracana przez funkcj main() oznacza, e program zakoczy sibez bdw; bdne zakoczenie czsto (cho nie zawsze) okrelane jest przez liczb jeden2.Funkcj main koczymy nawiasem klamrowym zamykajcym.

    Twj kod powinien wyglda jak poniej:

    #include int main (void){

    printf ("Hello World!");return 0;

    }

    Teraz wystarczy go tylko skompilowa i uruchomi.

    5.2 Rozwizywanie problemwJeli nie moesz skompilowa powyszego programu, to najprawdopodobniej popenie li-terwk przy rcznym przepisywaniu go. Zobacz te instrukcje na temat uywania kompi-latora.

    Moe te si zdarzy, e program skompiluje si, uruchomi, ale jego efektu dziaania niebdzie wida. Dzieje si tak, poniewa nasz pierwszy program po prostu wypisuje komunikati od razu koczy dziaanie, nie czekajc na reakcj uytkownika. Nie jest to problemem,gdy program jest uruchamiany z konsoli tekstowej, ale w innych przypadkach nie widzimyefektw jego dziaania.

    Jeli korzystasz ze Zintegrowanego rodowiska Programistycznego (ang. IDE), moeszzaznaczy, by nie zamykao ono programu po zakoczeniu jego dziaania. Innym sposobemjest dodanie instrukcji, ktre wstrzymywayby zakoczenie programu. Mona to zrobi do-dajc przed lini z return funkcj pobierajc znak z wejcia:

    getchar();

    2Jeeli chcesz mie pewno, e twj program bdzie dziaa poprawnie rwnie na platformach, gdzie 1 oznaczapoprawne zakoczenie (lub nie oznacza nic), moesz skorzysta z makr EXIT SUCCESS i EXIT FAILURE zdefiniowanychw pliku nagwkowym stdlib.h.

    http://pl.wikibooks.org/wiki/C/Uywanie_kompilatorahttp://pl.wikibooks.org/wiki/C/Uywanie_kompilatorahttp://pl.wikibooks.org/wiki/Programowanie:C:Biblioteka_standardowa:Indeks_tematyczny#stdlib.h

  • 5.2. ROZWIZYWANIE PROBLEMW 25

    Jest te prostszy (cho nieprzenony) sposb, mianowicie wywoanie polecenia systemo-wego. W zalenoci od uywanego systemu operacyjnego mamy do dyspozycji rne po-lecenia powodujce rne efekty. Do tego celu skorzystamy z funkcji system(), ktra jakoparametr przyjmuje polecenie systemowe ktre chcemy wykona, np:

    Rodzina systemw Unix/Linux:

    system("sleep 10"); /* oczekiwanie 10 s */system("read discard"); /* oczekiwanie na wpisanie tekstu */

    Rodzina systemw oraz MS Windows:

    system("pause"); /* oczekiwanie na wcinicie dowolnego klawisza */

    Funkcja ta jest o wiele bardziej pomocna w systemach operacyjnychWindows w ktrychto z reguy pracuje si w trybie okienkowym a z konsoli korzystamy tylko podczas urucha-mianiu programu. Z kolei w systemach Unix/Linux jest ona praktycznie w ogle nie uywanaw tym celu, ze wzgldu na uruchamianie programu bezporednio z konsoli.

    http://pl.wikibooks.org/wiki/C/system

  • 26 ROZDZIA 5. PIERWSZY PROGRAM

  • Rozdzia 6

    Podstawy

    Dla waciwego zrozumienia jzyka C nieodzowne jest przyswojenie sobie pewnych ogl-nych informacji.

    6.1 Kompilacja: Jak dziaa C?

    Jak kady jzyk programowania, C sam w sobie jest niezrozumiay dla procesora. Zosta onstworzony w celu umoliwienia ludziom atwego pisania kodu, ktry moe zosta przetwo-rzony na kod maszynowy. Program, ktry zamienia kod C na wykonywalny kod binarny,to kompilator. Jeli pracujesz nad projektem, ktry wymaga kilku plikw kodu rdowego(np. pliki nagwkowe), wtedy jest uruchamiany kolejny program linker. Linker suy dopoczenia rnych plikw i stworzenia jednej aplikacji lub biblioteki (library). Bibliotekajest zestawem procedur, ktry sam w sobie nie jest wykonywalny, ale moe by uywanaprzez inne programy. Kompilacja i czenie plikw s ze sob bardzo cile powizane, stds przez wielu traktowane jako jeden proces. Jedn rzecz warto sobie uwiadomi kompila-cja jest jednokierunkowa: przeksztacenie kodu rdowego C w kod maszynowy jest bardzoproste, natomiast odwrotnie nie. Dekompilatory co prawda istniej, ale rzadko tworzuyteczny kod C.

    Najpopularniejszym wolnym kompilatorem jest prawdopodobnie GNU Compiler Collec-tion, dostpny na stronie gcc.gnu.org.

    6.2 Co moe C?

    Pewnie zaskoczy Ci to, e tak naprawd czysty jzyk C nie moe zbyt wiele. Jzyk Cw grupie jzykw programowania wysokiego poziomu jest stosunkowo nisko. Dziki temukod napisany w jzyku C mona do atwo przetumaczy na kod asemblera. Bardzo atwojest te czy ze sob kod napisany w jzyku asemblera z kodem napisanym w C. Dla bar-dzo wielu ludzi przeszkod jest take do dua liczba i czsta dwuznaczno operatorw.Pocztkujcy programista, czytajcy kod programu w C moe odnie bardzo nieprzyjemnewraenie, ktre mona opisa cytatem ja nigdy tego nie opanuj. Wszystkie te elementyjzyka C, ktre wydaj Ci si dziwne i nielogiczne wmiar, jak bdziesz nabiera dowiadcze-nia nagle oka si cakiem przemylanie dobrane i takie, a nie inne konstrukcje przypadnCi do gustu. Dalsza lektura tego podrcznika oraz zaznajamianie si z funkcjami z rnychbibliotek uka Ci ca gam moliwoci, ktre daje jzyk C dowiadczonemu programicie.

    27

    http://pl.wikipedia.org/wiki/kompilatorhttp://pl.wikipedia.org/wiki/konsolidatorhttp://pl.wikipedia.org/wiki/biblioteka_(informatyka)http://pl.wikipedia.org/wiki/GNU_Compiler_Collectionhttp://pl.wikipedia.org/wiki/GNU_Compiler_Collectionhttp://gcc.gnu.org/http://pl.wikibooks.org/wiki/asembler

  • 28 ROZDZIA 6. PODSTAWY

    6.3 Struktura blokowaTeraz omwimy podstawow struktur programu napisanego w C. Jeli miae styczno zjzykiem Pascal, to pewnie syszae o nim, e jest to jzyk programowania strukturalny. WC nie ma tak cisej struktury blokowej, mimo to jest bardzo wane zrozumienie, co oznaczastruktura blokowa. Blok jest grup instrukcji, poczonych w ten sposb, e s traktowanejak jedna cao. W C, blok zawiera si pomidzy nawiasami klamrowymi { }. Blok moetake zawiera kolejne bloki.

    Zawarto bloku. Generalnie, blok zawiera cig kolejno wykonywanych polece. Polece-nia zawsze (z nielicznymi wyjtkami) kocz si rednikiem (;). W jednej linii moe znajdo-wa si wiele polece, cho dla zwikszenia czytelnoci kodu najczciej pisze si pojedynczinstrukcj w kadej linii. Jest kilka rodzajw polece, np. instrukcje przypisania, warunkoweczy ptli. W duej czci tego podrcznika bdziemy zajmowa si wanie instrukcjami.

    Pomidzy poleceniami s rwnie odstpy spacje, tabulacje, oraz przejcia do nastpnejlinii, przy czym dla kompilatora te trzy rodzaje odstpw maj takie samo znaczenie. Dlaprzykadu, ponisze trzy fragmenty kodu rdowego, dla kompilatora s takie same:

    printf("Hello world"); return 0;

    printf("Hello world");return 0;

    printf("Hello world");

    return 0;

    W tej regule istnieje jednak jeden wyjtek. Dotyczy on staych tekstowych. W powy-szych przykadach sta tekstow jest Hello world. Gdy jednak rozbijemy ten napis, kom-pilator zasygnalizuje bd:

    printf("Helloworld");return 0;

    Naley tylko zapamita, e stae tekstowe powinny zaczyna si i koczy w tej samejlini (mona omin to ograniczenie wicej w rozdziale Napisy). Oprcz tego jednego przy-padku dla kompilatora ma znaczenie samo istnienie odstpu, a nie jego wielko czy rodzaj.Jednak stosowanie odstpw jest bardzo wane, dla zwikszenia czytelnoci kodu dzikiczemu moemy zaoszczdzi sporo czasu i nerww, poniewa znalezienie bdu (ktre sizdarzaj kademu) w nieczytelnym kodzie moe by bardzo trudne.

    6.4 ZasigPojcie to dotyczy zmiennych (ktre przechowuj dane przetwarzane przez program). Wka-dym programie (oprcz tych najprostszych) s zarwno zmienne wykorzystywane przez cayczas dziaania programu, oraz takie ktre s uywane przez pojedynczy blok programu (np.funkcj). Na przykad, w pewnym programie w pewnym momencie jest wykonywane skom-plikowane obliczenie, ktre wymaga zadeklarowania wielu zmiennych do przechowywaniaporednich wynikw. Ale przez wiksz cz tego dziaania, te zmienne s niepotrzebne,

    http://pl.wikibooks.org/wiki/Pascalhttp://pl.wikibooks.org/wiki/C/Napisyhttp://pl.wikibooks.org/wiki/C/Napisy#acuchy_znakw_w_jzyku_C

  • 6.5. FUNKCJE 29

    i zajmuj tylko miejsce w pamici najlepiej gdyby to miejsce zostao zarezerwowane tuprzed wykonaniemwspomnianych oblicze, a zaraz po ich wykonaniu zwolnione. Dlatego wC istniej zmienne globalne, oraz lokalne. Zmienne globalne mog by uywane w kadymmiejscu programu, natomiast lokalne tylko w okrelonym bloku czy funkcji (oraz blokachw nim zawartych). Generalnie zmienna zadeklarowanaw danym bloku, jest dostpna tylkowewntrz niego.

    6.5 Funkcje

    Funkcje s cile zwizane ze struktur blokow funkcj jest po prostu blok instrukcji,ktry jest potem wywoywany w programie za pomoc pojedynczego polecenia. Zazwyczajfunkcja wykonuje pewne okrelone zadanie, np. we wspomnianym programie wykonuj-cym pewne skomplikowane obliczenie. Kada funkcja ma swoj nazw, za pomoc ktrejjest potem wywoywana w programie, oraz blok wykonywanych polece. Wiele funkcji po-biera pewne dane, czyli argumenty funkcji, wiele funkcji take zwraca pewn warto, pozakoczeniu wykonywania. Dobrym nawykiem jest dzielenie duego programu na zestawmniejszych funkcji dziki temu bdziesz mg atwiej odnale bd w programie.

    Jeli chcesz uy jakiej funkcji, to powiniene wiedzie:

    jakie zadanie wykonuje dana funkcja

    rodzaj wczytywanych argumentw, i do czego s one potrzebne tej funkcji

    rodzaj zwrconych danych, i co one oznaczaj.

    W programach w jzyku C jedna funkcja ma szczeglne znaczenie jest tomain(). Funk-cj t, zwan funkcj gwn, musi zawiera kady program. W niej zawiera si gwny kodprogramu, przekazywane s do niej argumenty, z ktrymi wywoywany jest program (jakoparametry argc i argv). Wicej o funkcji main() dowiesz si pniej w rozdziale Funkcje.

    6.6 Biblioteki standardowe

    Jzyk C, w przeciwiestwie do innych jzykw programowania (np. Fortranu czy Pascala)nie posiada absolutnie adny sw kluczowych, ktre odpowiedzialne by byy za obsugwejcia i wyjcia. Moe si to wydawa dziwne jzyk, ktry sam w sobie nie posiadapodstawowych funkcji, musi by jzykiem o ograniczonym zastosowaniu. Jednak brak pod-stawowych funkcji wejcia-wyjcia jest jedn z najwikszych zalet tego jzyka. Jego skadniaopracowana jest tak, by mona byo bardzo atwo przeoy j na kod maszynowy. To wa-nie dziki temu programy napisane w jzyku C s takie szybkie. Pozostaje jednak pytanie jak umoliwi programom komunikacj z uytkownikiem ?

    W roku, kiedy zapocztkowano prace nad standaryzacj C, zdecydowano, e po-winien by zestaw instrukcji identycznych w kadej implementacji C. Nazwano je BibliotekStandardow (czasemnazywan libc). Zawiera ona podstawowe funkcje, ktre umoliwiajwykonywanie takich zada jak wczytywanie i zwracanie danych, modyfikowanie zmiennychacuchowych, dziaania matematyczne, operacje na plikach, i wiele innych, jednak nie za-wiera adnych funkcji, ktre mog by zalene od systemu operacyjnego czy sprztu, jakgrafika, dwik czy obsuga sieci. W programie Hello World uyto funkcji z biblioteki stan-dardowej printf, ktra wywietla na ekranie sformatowany tekst.

    http://pl.wikibooks.org/wiki/C/Funkcje#Funkcja_main()http://pl.wikibooks.org/wiki/Fortran

  • 30 ROZDZIA 6. PODSTAWY

    6.7 Komentarze i stylKomentarze to tekst wczony do kodu rdowego, ktry jest pomijany przez kompilator,i suy jedynie dokumentacji. W jzyku C, komentarze zaczynaj si od

    /*

    a kocz

    */

    Dobre komentowanie ma due znaczenie dla rozwijania oprogramowania, nie tylko dlatego,e inni bd kiedy potrzebowali przeczyta napisany przez ciebie kod rdowy, ale takemoesz chcie po duszym czasie powrci do swojego programu, i moesz zapomnie, doczego suy dany blok kodu, albo dlaczego akurat uye tego polecenia a nie innego. Wchwili pisania programu, to moe by dla ciebie oczywiste, ale po duszym czasie moeszmie problemy ze zrozumieniem wasnego kodu. Jednak nie naley te wstawia zbyt duokomentarzy, poniewa wtedy kod moe sta si jeszcze mniej czytelny najlepiej komen-towa fragmenty, ktre nie s oczywiste dla programisty, oraz te o szczeglnym znaczeniu.Ale tego nauczysz si ju w praktyce.

    Dobry styl pisania kodu jest o tyle wany, e powinien on by czytelny i zrozumiay; po tow kocu wymylono jzyki programowania wysokiego poziomu (w tym C), aby kod byo a-two zrozumie ;). I tak naley stosowa wcicia dla odrnienia blokw kolejnego poziomu(zawartych w innym bloku; podrzdnych), nawiasy klamrowe otwierajce i zamykajce blokpowinny mie takie same wcicia, staraj si, aby nazwy funkcji i zmiennych kojarzyy si zzadaniem, jakie dana funkcja czy zmienna peni w programie. W dalszej czci podrcznikamoesz napotka wicej zalece dotyczcych stylu pisania kodu. Staraj si stosowa do tychzalece dziki temu kod pisanych przez ciebie programw bdzie atwiejszy do czytania izrozumienia.

    Jeli masz dowiadczenia z jzykiem C++ pamitaj, e w C nie powinno si stosowakomentarzy zaczynajcych si od dwch znakw slash:// tak nie komentujemy w CJest to niezgodne ze standardem ANSI C i niektre kompilatory mog nie skompilowa koduz komentarzami w stylu C++ (cho standard ISO C dopuszcza komentarze w stylu C++).

    Innym zastosowaniem komentarzy jest chwilowe usuwanie fragmentw kodu. Jeli czprogramu le dziaa i chcemy j chwilowo wyczy, albo fragment kodu jest nam ju nie-potrzebny, ale mamy wtpliwoci, czy w przyszoci nie bdziemy chcieli go uy umiesz-czamy go po prostu wewntrz komentarza.

    Podczas obejmowania chwilowo niepotrzebnego kodu w komentarz trzeba uwaa najedn subtelno. Ot komentarze /* * / w jzyku C nie mog by zagniedone. Trzebana to uwaa, gdy chcemy obj komentarzem obszar w ktrym ju istnieje komentarz (na-ley wtedy usun wewntrzny komentarz). W nowszym standardzie C dopuszcza si, abykomentarz typu /* */ zawiera w sobie komentarz //.

    6.7.1 Po polsku czy angielsku?

    Jak juwczeniej byowspomniane, zmiennym i funkcjom powinno si nadawa nazwy, ktreodpowiadaj ich znaczeniu. Zdecydowanie atwiej jest czyta kod, gdy redni liczb przecho-wuje zmienna srednia ni a a znajdowaniemmaksimumw cigu liczb zajmuje si funkcja maxalbo znajdz max ni nazwana f. Czsto nazwy funkcji to wanie czasowniki.

  • 6.7. KOMENTARZE I STYL 31

    Powstaje pytanie, w jakim jzyku naley pisa nazwy. Jeli chcemy, by nasz kod mogyczyta osoby nieznajce polskiego warto uy jzyka angielskiego. Jeli nie mona bezproblemu uy polskiego. Bardzo istotne jest jednak, by nie miesza jzykw. Jeli zdecy-dowalimy si uywa polskiego, uywajmy go od pocztku do koca; przeplatanie ze sobdwch jzykw robi ze wraenie.

    Warto rwnie zdecydowa si na sposb zapisywania nazw skadajcych si z wicej nijednego sowa. Istnieje kilka moliwoci, najwaniejsze z nich:

    . oddzielanie podkreleniem: int to str

    . konwencja pascalowska, kade sowo du liter: IntToStr

    . konwencja wielbdzia, pierwsze sowo ma, kolejne du liter: intToStr

    Ponownie, najlepiej stosowa konsekwentnie jedn z konwencji i nie miesza ze sobkilku.

    6.7.2 Notacja wgierska

    Czasem programista moe zapomnie, jakiego typu bya dana zmienna. Wtedy musi znaleodpowiedni deklaracj (co nie zawsze jest atwe). Dlatego wic wymylono sposb, by temuzaradzi. Pomylano, by w nazwie zmiennej (bd wskanika na zmienn) napisa, jakiegojest ona typu, np:

    a liczba (liczba typu int)

    w ll dlugaLiczba (wskanik na zmienn typu long long)

    t5x5 ch tabliczka (tablica x elementw typu char)

    func i silnia (funkcja zwracajca int)

    Jest to bardzo wygodne przy bardzo zagmatwanych zmiennych:

    w t4 w t2x2 s pomieszaniec (wskanik na tablic czterech wskanikw na tablice dwu-wymiarowe zmiennych typu short)

    Lub gdy nie pamitamy wymiarw tablicy:

    t4x5x6 f powalonaKostkaRubika (od razu wiemy, et4x5x6 f powalonaKostkaRubika[5][4][6] jest niewaciwe)

    Taki zapis ma te swoje wady. Gdy zdecydujemy si zmieni typ zmiennej, zamiast poprostu przemieni w deklaracji int na long, musimy zmienia nazwy w caym programie.Czsto takie nazwy s po prostu dugie i nie chce nam si ich pisa (no c, programista teczowiek), wic wolimy wprowadzi pomieszaniec zamiast w t4 w t2x2 s pomieszaniec. Naj-waniejsze to jednak trzyma si rozwizania, ktre wybralimy na pocztku, bo mieszaniejest przeraajce.

  • 32 ROZDZIA 6. PODSTAWY

    6.8 PreprocesorNie cay napisany przez ciebie kod bdzie przeksztacany przez kompilator bezporednio nakodwykonywalny programu. Wwielu przypadkach bdziesz uywa polece skierowanychdo kompilatora, tzw. dyrektyw kompilacyjnych. Na pocztku procesu kompilacji, specjalnypodprogram, tzw. preprocesor, wyszukuje wszystkie dyrektywy kompilacyjne, i wykonujeodpowiednie akcje ktre polegaj notabene na edycji kodu rdowego (np. wstawieniudeklaracji funkcji, zamianie jednego cigu znakw na inny). Waciwy kompilator, zamie-niajcy kod C na kod wykonywalny, nie napotka ju dyrektyw kompilacyjnych, poniewazostay one przez preprocesor usunite, po wykonaniu odpowiednich akcji.

    W C dyrektywy kompilacyjne zaczynaj si od znaku hash (#). Przykadem najczciejuywanej dyrektywy, jest #include, ktra jest uyta nawet w tak prostym programie jakHello, World!. #include nakazuje preprocesorowi wczy (ang. include) w tym miejscuzawarto podanego pliku, tzw. pliku nagwkowego; najczciej to bdzie plik zawierajcyfunkcje z ktrej biblioteki standardowej (stdio.h STandard Input-Output, rozszerzenie .hoznacza plik nagwkowy C). Dziki temu, zamiast wkleja do kodu swojego programu dekla-racje kilkunastu, a nawet kilkudziesiciu funkcji, wystarczy wpisa jedn magiczn linijk!

    6.9 Nazwy zmienny, stay i funkcjiIdentyfikatory, czyli nazwy zmiennych, staych i funkcji mog skada si z liter (bez polskichznakw), cyfr i znaku podkrelenia z tym, e nazwa taka nie moe zaczyna si od cyfry. Niemona uywa nazw zarezerwowanych (patrz: Skadnia).

    Przykady bdnych nazw:

    2liczba (nie mona zaczyna nazwy od cyfry)moja funkcja (nie mona uywa spacji)$i (nie mona uywa znaku $)if (if to sowo kluczowe)

    Aby kod by bardziej czytelny, przestrzegajmy poniszych (umownych) regu:

    nazwy zmiennych piszemy maymi literami: i, file

    nazwy staych (zadeklarowanych przy pomocy #define) piszemy wielkimi literami:SIZE

    nazwy funkcji piszemy maymi literami: print

    wyrazy w nazwach oddzielamy znakiem podkrelenia: open file, close all files

    S to tylko konwencje aden kompilator nie zgosi bdu, jeli wprowadzimy swj wa-sny system nazewnictwa. Jednak warto pamita, e by moe nad naszym kodem bd pra-cowali take inni programici, ktrzy mog mie trudnoci z analiz kodu niespeniajcegopewnych zasad.

    http://pl.wikibooks.org/wiki/C/Preprocesorhttp://pl.wikibooks.org/wiki/C/Skadnia

  • Rozdzia 7

    Zmienne

    Procesor komputera stworzony jest tak, aby przetwarza dane, znajdujce si w pamici kom-putera. Z punktu widzenia programu napisanego w jzyku C (ktry jak wiadomo jest jzy-kiem wysokiego poziomu) dane umieszczane s w postaci tzw. zmienny. Zmienne ua-twiaj programicie pisanie programu. Dziki nim programista nie musi si przejmowagdzie w pamici owe zmienne si znajduj, tzn. nie operuje fizycznymi adresami pamici,jak np. 0x14613467, tylko prost do zapamitania nazw zmiennej.

    7.1 Czym s zmienne?Zmienna jest to pewien fragment pamici o ustalonym rozmiarze, ktry posiada wasny iden-tyfikator (nazw) oraz moe przechowywa pewn warto, zalen od typu zmiennej.

    7.1.1 Deklaracja zmienny

    Aby mc skorzysta ze zmiennej naley j przed uyciem zadeklarowa, to znaczy poinfor-mowa kompilator, jak zmienna bdzie si nazywa i jaki typ ma mie. Zmienne deklarujesi w sposb nastpujcy:

    typ nazwa_zmiennej;

    Oto deklaracja zmiennej o nazwie wiek typu int czyli liczby cakowitej:

    int wiek;

    Zmiennej w momencie zadeklarowania mona od razu przypisa warto:

    int wiek = 17;

    W jzyku C zmienne deklaruje si na samym pocztku bloku (czyli przed pierwsz in-strukcj).

    int wiek = 17;printf("%d\n", wiek);int kopia_wieku; /* tu stary kompilator C zgosi bd */

    /* deklaracja wystpuje po instrukcji (printf). */kopia_wieku = wiek;

    33

    http://pl.wikibooks.org/wiki/#Typy_zmiennych

  • 34 ROZDZIA 7. ZMIENNE

    Wedug nowszych standardwmoliwe jest deklarowanie zmiennej w dowolnymmiejscuprogramu, ale wtedy musimy pamita, aby zadeklarowa zmienn przed jej uyciem. Toznaczy, e taki kod jest niepoprawny:

    printf ("Mam %d lat\n", wiek);int wiek = 17;

    Naley go zapisa tak:

    int wiek = 17;printf ("Mam %d lat\n", wiek);

    Jzyk C nie inicjalizuje zmiennych lokalnych. Oznacza to, e w nowo zadeklarowanejzmiennej znajduj si mieci - to, co wczeniej zawiera przydzielony zmiennej fragmentpamici. Aby unikn cikich do wykrycia bdw, dobrze jest inicjalizowa (przypisywawarto) wszystkie zmienne w momencie zadeklarowania.

    7.1.2 Zasig zmiennej

    Zmienne mog by dostpne dla wszystkich funkcji programu nazywamy je wtedy zmien-nymi globalnymi. Deklaruje si je przed wszystkimi funkcjami programu:

    #include

    int a,b; /* nasze zmienne globalne */

    void func1 (){

    /* instrukcje */a=3;/* dalsze instrukcje */

    }

    int main (){

    b=3;a=2;return 0;

    }

    Zmienne globalne, jeli programista nie przypisze im innej wartoci podczas definiowa-nia, s inicjalizowane wartoci .

    Zmienne, ktre funkcja deklaruje do wasnych potrzeb nazywamy zmiennymi lokal-nymi. Nasuwa si pytanie: czy bdzie bdem nazwanie t sam nazw zmiennej globalneji lokalnej?. Ot odpowied moe by zaskakujca: nie. Natomiast w danej funkcji da siuywa tylko jej zmiennej lokalnej. Tej konstrukcji naley, z wiadomych wzgldw, unika.

    int a=1; /* zmienna globalna */

    int main()

  • 7.1. CZYM S ZMIENNE? 35

    {int a=2; /* to ju zmienna lokalna */printf("%d", a); /* wypisze 2 */

    }

    7.1.3 Czas ycia

    Czas ycia to czas od momentu przydzielenia dla zmiennej miejsca w pamici (stworzenieobiektu) do momentu zwolnienia miejsca w pamici (likwidacja obiektu).

    Zakres wanoci to cz programu, w ktrej nazwa znana jest kompilatorowi.

    main(){

    int a = 10;{ /* otwarcie lokalnego bloku */

    int b = 10;printf("%d %d", a, b);

    } /* zamknicie lokalnego bloku, zmienna b jest usuwana */

    printf("%d %d", a, b); /* BD: b juz nie istnieje */} /* tu usuwana jest zmienna a */

    Zdefiniowalimy dwie zmienne typu int. Zarwno a i b istniej przez cay program (czasycia). Nazwa zmiennej a jest znana kompilatorowi przez cay program. Nazwa zmiennej bjest znana tylko w lokalnym bloku, dlatego nastpi bd w ostatniej instrukcji.

    Niektre kompilatory (prawdopodobniemona tu zaliczyMicrosoVisual C++ dowersji) uznaj powyszy kod za poprawny! W dodatku mona ustawi w opcjach niektrychkompilatorw zachowanie w takiej sytuacji, wcznie z zachowaniami niezgodnymi ze stan-dardem jzyka!

    Moemy wiadomie ograniczy wano zmiennej do kilku linijek programu (tak jak ro-bilimy wyej) tworzc blok. Nazwa zmiennej jest znana tylko w tym bloku.

    {...

    }

    7.1.4 Stae

    Staa, rni si od zmiennej tylko tym, e nie mona jej przypisa innej wartoci w trak-cie dziaania programu. Warto staej ustala si w kodzie programu i nigdy ona nie ulegazmianie. Sta deklaruje si z uyciem sowa kluczowego const w sposb nastpujcy:

    const typ nazwa_staej=warto;

    Dobrze jest uywa staych w programie, poniewa unikniemy wtedy przypadkowychpomyek a kompilator moe czsto zoptymalizowa ich uycie (np. od razu podstawiajc ichwarto do kodu).

  • 36 ROZDZIA 7. ZMIENNE

    const int WARTOSC_POCZATKOWA=5;int i=WARTOSC_POCZATKOWA;WARTOSC_POCZATKOWA=4; /* tu kompilator zaprotestuje */int j=WARTOSC_POCZATKOWA;

    Przykad pokazuje dobry zwyczaj programistyczny, jakim jest zastpowanie umieszczo-nych na stae w kodzie liczb staymi. W ten sposb bdziemy mieli wiksz kontrol nadkodem stae umieszczone w jednym miejscu mona atwo modyfikowa, zamiast szukapo caym kodzie liczb, ktre chcemy zmieni.

    Nie mamy jednak penej gwarancji, e staa bdzie miaa t sam warto przez cay czaswykonania programu, moliwe jest bowiem dostanie si do wartoci staej (miejsca jej prze-chowywania w pamici) porednio za pomoc wskanikw. Mona zatem doj do wnio-sku, e sowo kluczowe const suy tylko do poinformowania kompilatora, aby ten nie zezwa-la na jawn zmian wartoci staej. Z drugiej strony, zgodnie ze standardem, prba mody-fikacji wartoci staej ma niezdefiniowane dziaanie (tzw. undefined behaviour) i w zwizkuz tym moe si powie lub nie, ale moe te spowodowa jakie subtelne zmiany, ktre wefekcie spowoduj, e program bdzie le dziaa.

    Podobnie do zdefiniowania staej moemy uy dyrektywy preprocesora #define (opi-sanej w dalszej czci podrcznika). Tak zdefiniowan sta nazywamy sta symboliczn.W przeciwiestwie do staej zadeklarowanej z uyciem sowa const staa zdefiniowana przyuyciu #define jest zastpowana dan wartoci w kadym miejscu, gdzie wystpuje, dlategote moe by uywana w miejscach, gdzie normalna staa nie mogaby dobrze speni swejroli.

    W przeciwiestwie do jzyka C++, w C staa to cay czas zmienna, ktrej kompilatorpilnuje, by nie zmienia si.

    7.2 Typy zmienny

    Kady program w C operuje na zmiennych wydzielonych w pamici komputera obsza-rach, ktre mog reprezentowa obiekty nam znane, takie jak liczby, znaki, czy te bardziejzoone obiekty. Jednak dla komputera kady obszar w pamici jest taki sam to cig zeri jedynek, w takiej postaci zupenie nieprzydatny dla programisty i uytkownika. Podczaspisania programu musimy wskaza, w jaki sposb ten cig ma by interpretowany.

    Typ zmiennej wskazuje wanie sposb, w jaki pami, w ktrej znajduje si zmiennabdzie wykorzystywana. Okrelajc go przekazuje si kompilatorowi informacj, ile pamicitrzeba zarezerwowa dla zmiennej, a take w jaki sposb wykonywa na nim operacje.

    Kada zmienna musi mie okrelony swj typ w miejscu deklaracji i tego typu nie moeju zmieni. Lecz co jeli mamy zmienn jednego typu, ale potrzebujemy w pewnymmiejscuprogramu innego typu danych? W takimwypadku stosujemy konwersj (rzutowanie) jednejzmiennej na inn zmienn. Rzutowanie zostanie opisane pniej, w rozdziale Operatory.

    Istniej wbudowane i zdefiniowane przez uytkownika typy danych. Wbudowane typydanych to te, ktre zna kompilator, s one w nim bezporednio zaszyte. Mona te tworzywasne typy danych, ale naley je kompilatorowi opisa. Wicej informacji znajduje si wrozdziale Typy zoone.

    W jzyku C wyrniamy podstawowe typy zmiennych. S to:

    char jednobajtowe liczby cakowite, suy do przechowywania znakw;

    int typ cakowity, o dugoci domylnej dla danej architektury komputera;

    http://pl.wikibooks.org/wiki/C/Wskanikihttp://pl.wikibooks.org/wiki/Programowanie:C:Preprocesor#.23definehttp://pl.wikibooks.org/wiki/C++http://pl.wikibooks.org/wiki/C/Operatory#Rzutowaniehttp://pl.wikibooks.org/wiki/C/Typy_zoone

  • 7.2. TYPY ZMIENNYCH 37

    float typ zmiennopozycyjny (zwany rwnie zmiennoprzecinkowym), reprezentujcyliczby rzeczywiste ( bajty);

    double typ zmiennopozycyjny podwjnej precyzji ( bajtw);

    Typy zmiennoprzecinkowe zostay dokadnie opisane w IEEE .

    W jzyku C nie istnieje specjalny typ zmiennych przeznaczony na zmienne typu logicz-nego (albo prawda albo fasz). Jest to inne podejcie ni na przykad w jzykach Pascalalbo Java - definiujcych osobny typ boolean, ktrego nie mona mieszaz innymi typamizmiennych. W C do przechowywania wartoci logicznych zazwyczaj uywa si typu int.Wicej na temat tego, jak jzyk C rozumie prawd i fasz, znajduje si w rozdziale Operatory.

    7.2.1 int

    Ten typ przeznaczony jest do liczb cakowitych. Liczby temoemy zapisa na kilka sposobw:

    System dziesitny

    12 ; 13 ; 45 ; 35 itd

    System semkowy (oktalny)

    010 czyli 8016 czyli 8 + 6 = 14018 BD

    System ten operuje na cyfrach od do . Tak wiec jest niedozwolona. Jeeli chcemyuy takiego zapisu musimy zacz liczb od .

    System szesnastkowy (heksadecymalny)

    0x10 czyli 1*16 + 0 = 160x12 czyli 1*16 + 2 = 180xff czyli 15*16 + 15 = 255

    W tym systemie moliwe cyfry to i dodatkowo a, b, c, d, e, f, ktre oznaczaj ,, , , , . Aby uy takiego systemu musimy poprzedzi liczb cigiem 0x. Wielkoznakw w takich literaach nie ma znaczenia.

    Ponadto w niektrych kompilatorach przeznaczonych gwnie domikrokontrolerw spo-tyka si jeszcze uycie systemu binarnego. Zazwyczaj dodaje si przedrostek 0b przed liczb(analogicznie do zapisu spotykanego w jzyku Python). W tym systemie moemy oczywicieuywa tylko i wycznie cyfr i . Tego typu rozszerzenie bardzo uatwia programowanieniskopoziomowe ukadw. Naley jednak pamita, e jest to tylko i wycznie rozszerzenie.

    http://pl.wikipedia.org/wiki/en:IEEE_754

  • 38 ROZDZIA 7. ZMIENNE

    7.2.2 float

    Ten typ oznacza liczby zmiennoprzecinkowe czyli uamki. Istniej dwa sposoby zapisu:

    System dziesitny

    3.14 ; 45.644 ; 23.54 ; 3.21 itd

    System naukowy wykadniczy

    6e2 czyli 6 * 102 czyli 6001.5e3 czyli 1.5 * 103 czyli 15003.4e-3 czyli 3.4 * 103 czyli 0.0034

    Naley wzi pod uwag, e reprezentacja liczb rzeczywistych w komputerze jest niedo-skonaa i moemy otrzymywa wyniki o zauwaalnej niedokadnoci.

    7.2.3 double

    Double czyli podwjny oznacza liczby zmiennoprzecinkowe podwjnej precyzji. Ozna-cza to, e liczba taka zajmuje zazwyczaj w pamici dwa razy wicej miejsca ni float (np. bity wobec dla float), ale ma te dwa razy lepsz dokadno.

    Domylnie uamki wpisane w kodzie s typu double. Moemy to zmieni dodajc nakocu liter :

    1.5f (float)1.5 (double)

    7.2.4 ar

    Jest to typ znakowy, umoliwiajcy zapis znakw ASCII. Moe te by traktowany jako liczbaz zakresu ... Znaki zapisujemywpojedynczych cudzysowach (czasami nazywanymi apo-strofami), by odrni je od acuchw tekstowych (pisanych w podwjnych cudzysowach).

    'a' ; '7' ; '!' ; '$'

    Pojedynczy cudzysw zapisujemy tak: '\'' a null (czyli zero, ktre midzy innymikoczy napisy) tak: '\0'. Wicej znakw specjalnych.

    Warto zauway, e typ char to zwyky typ liczbowy i mona go uywa tak samo jaktypu int (zazwyczaj ma jednak mniejszy zakres). Co wicej literay znakowe (np. a) straktowane jako liczby i w jzyku C s typu int (w jzyku C++ s typu char).

    7.2.5 void

    Sowa kluczowego void mona w okrelonych sytuacjach uy tam, gdzie oczekiwana jestnazwa typu. void nie jest waciwym typem, bo nie mona utworzy zmiennej takiego typu;jest to pusty typ (ang. void znaczy pusty). Typ void przydaje si do zaznaczania, efunkcja nie zwraca adnej wartoci lub e nie przyjmuje adnych parametrw (wicej o tymw rozdziale Funkcje). Mona te tworzy zmienne bdce typu wskanik na void

    http://pl.wikibooks.org/wiki/Programowanie:C:Napisy#Znaki_specjalnehttp://pl.wikibooks.org/wiki/C/Funkcje#Tworzenie_funkcjihttp://pl.wikibooks.org/wiki/C/Wskaniki#Do_czego_suy_typ_void*?

  • 7.3. SPECYFIKATORY 39

    7.3 Specyfikatory

    Specyfikatory to sowa kluczowe, ktre postawione przy typie danych zmieniaj jego zna-czenie.

    7.3.1 signed i unsigned

    Na pocztku zastanwmy si, jak komputer moe przechowa liczb ujemn. Ot w przy-padku przechowywania liczb ujemnych musimyw zmiennej przechowa jeszcze jej znak. Jakwiadomo, zmienna skada si z szeregu bitw. W przypadku uycia zmiennej pierwszy bit zlewej strony (nazywany take bitem najbardziej znaczcym) przechowuje znak liczby. Efek-tem tego jest spadek pojemnoci zmiennej, czyli zmniejszenie najwikszej wartoci, ktrmoemy przechowa w zmiennej.

    Signed oznacza liczb ze znakiem, unsigned bez znaku (nieujemn). Mog by zasto-sowane do typw: char i int i czone ze specyfikatorami short i long (gdy ma to sens).

    Jeli przy signed lub unsigned nie napiszemy, o jaki typ nam chodzi, kompilator przyjmiewarto domyln czyli int.

    Przykadowo dla zmiennej char(zajmujcej bitw zapisanej w formacie uzupenie dodwch) wyglda to tak:

    signed char a; /* zmienna a przyjmuje wartoci od -128 do 127 */unsigned char b; /* zmienna b przyjmuje wartoci od 0 do 255 */unsigned short c;unsigned long int d;

    Jeeli nie podamy adnego ze specyfikatora wtedy liczba jest domylnie przyjmowanajako signed (nie dotyczy to typu char, dla ktrego jest to zalene od kompilatora).

    signed int i = 0;// jest rwnoznaczne z:int i = 0;

    Liczby bez znaku pozwalaj nam zapisa wiksze liczby przy tej samej wielkoci zmiennej ale trzeba uwaa, by nie zej z nimi poniej zera wtedy przewijaj si na sam konieczakresu, co moe powodowa trudne do wykrycia bdy w programach.

    7.3.2 short i long

    Short i long s wskazwkami dla kompilatora, by zarezerwowa dla danego typu mniej (od-powiednio wicej) pamici. Mog by zastosowane do dwch typw: int i double (tylkolong), majc rne znaczenie.

    Jeli przy short lub long nie napiszemy, o jaki typ nam chodzi, kompilator przyjmie war-to domyln czyli int.

    Naley pamita, e to jedynie yczenie wobec kompilatora w wielu kompilatorachtypy int i long int maj ten sam rozmiar. Standard jzyka C nakada jedynie na kompilatorynastpujce ograniczenia: int nie moe by krtszy ni bitw; int musi byduszy lub rwny short a nie moe by duszy ni long; short int nie moe bykrtszy ni bitw; long int nie moe by krtszy ni bity;

    Zazwyczaj typ int jest typem danych o dugoci odpowiadajcej wielkoci rejestrw pro-cesora, czyli na procesorze szesnastobitowym ma bitw, na trzydziestodwubitowym

  • 40 ROZDZIA 7. ZMIENNE

    itd.1 Z tego powodu, jeli to tylko moliwe, do reprezentacji liczb cakowitych preferowanejest uycie typu int bez adnych specyfikatorw rozmiaru.

    7.4 Modyfikatory

    7.4.1 volatile

    volatile znaczy ulotny. Oznacza to, e kompilator wyczy dla takiej zmiennej optymaliza-cje typu zastpienia przez sta lub zawarto rejestru, za to wygeneruje kod, ktry bdzieodwoywa si zawsze do komrek pamici danego obiektu. Zapobiegnie to bdowi, gdyobiekt zostaje zmieniony przez cz programu, ktra nie ma zauwaalnego dla kompilatorazwizku z danym fragmentem kodu lub nawet przez zupenie inny proces.

    volatile float liczba1;float liczba2;{

    printf ("%f\n%f\n", liczba1, liczba2);/* instrukcje nie zwizane ze zmiennymi */printf ("%f\n%f", liczba1, liczba2);

    }

    Jeeli zmienne liczba i liczba zmieni si niezauwaalnie dla kompilatora to odczytujc:

    liczba nastpi odwoanie do komrek pamici. Kompilator pobierze now wartozmiennej.

    liczba kompilator moe wypisa poprzedni warto, ktr przechowywa w reje-strze.

    Modyfikator volatile jest rzadko stosowany i przydaje si w wskich zastosowaniach,jak wspbieno i wspdzielenie zasobw oraz przerwania systemowe.

    7.4.2 register

    Jeeli utworzymy zmienn, ktrej bdziemy uywa w swoim programie bardzo czsto, mo-emy wykorzysta modyfikator register. Kompilator moe wtedy umieci zmienn w re-jestrze, do ktrego ma szybki dostp, co przypieszy odwoania do tej zmiennej

    register int liczba ;

    W nowoczesnych kompilatorach ten modyfikator praktycznie nie ma wpywu na pro-gram. Optymalizator sam decyduje czy i co naley umieci w rejestrze. Nie mamy adnejgwarancji, e zmienna tak zadeklarowana rzeczywicie si tam znajdzie, chocia dostp doniej moe zosta przyspieszony w inny sposb. Raczej powinno si unika tego typu kon-strukcji w programie.

    1Wie si to z pewnymi uwarunkowaniami historycznymi. Podrcznik do jzyka C duetu K&R zakada, etyp int mia si odnosi do typowej dla danego procesora dugoci liczby cakowitej. Natomiast, jeli procesor mgobsugiwa typy dusze lub krtsze stosownego znaczenia nabieraymodyfikatory short i long. Dobrymprzykademmoe by architektura i386, ktra umoliwia obliczenia na liczbach 16-bitowych. Dlatego te modyfikator shortpowoduje skrcenie zmiennej do 16 bitw.

  • 7.5. UWAGI 41

    7.4.3 static

    Pozwala na zdefiniowanie zmiennej statycznej. Statyczno polega na zachowaniu warto-ci pomidzy kolejnymi definicjami tej samej zmiennej. Jest to przede wszystkim przydatnew funkcjach. Gdy zdefiniujemy zmienn w ciele funkcji, to zmienna ta bdzie od nowa defi-niowana wraz z domyln wartoci (jeeli tak podano). W wypadku zmiennej okrelonejjako statyczna, jej warto si nie zmieni przy ponownym wywoaniu funkcji. Na przykad:

    void dodaj(int liczba){

    int zmienna = 0; // bez staticzmienna = zmienna + liczba;printf ("Wartosc zmiennej %d\n", zmienna);

    }

    Gdy wywoamy t funkcj np. razy w ten sposb:

    dodaj(3);dodaj(5);dodaj(4);

    to ujrzymy na ekranie:

    Wartosc zmiennej 3Wartosc zmiennej 5Wartosc zmiennej 4

    jeeli jednak deklaracj zmiennej zmienimy na static int zmienna = 0, to warto zmiennejzostanie zachowana i po podobnym wykonaniu funkcji powinnymy ujrze:

    Wartosc zmiennej 3Wartosc zmiennej 8Wartosc zmiennej 12

    Zupenie co innego oznacza static zastosowane dla zmiennej globalnej. Jest ona wtedywidoczna tylko w jednym pliku. Zobacz te: rozdzia Biblioteki.

    7.4.4 extern

    Przez extern oznacza si zmienne globalne zadeklarowane w innych plikach informujemyw ten sposb kompilator, eby nie szuka jej w aktualnym pliku. Zobacz te: rozdzia Biblio-teki.

    7.4.5 auto

    Zupenym archaizmem jest modyfikator auto, ktry oznacza tyle, e zmienna jest lokalna.Poniewa zmienna zadeklarowana w dowolnym bloku zawsze jest lokalna, modyfikator tennie ma obecnie adnego zastosowania praktycznego. auto jest spadkiem po wczeniejszychjzykach programowania, na ktrych oparty jest C (np. B).

    7.5 Uwagi Jzyk C++ pozwala na mieszanie deklaracji zmiennych z kodem. Wicej informacji w

    C++/Zmienne.

    http://pl.wikibooks.org/wiki/C/Biblioteki#Zmiana_dostpu_do_funkcji_i_zmiennych_(static_i_extern)http://pl.wikibooks.org/wiki/C/Biblioteki#Zmiana_dostpu_do_funkcji_i_zmiennych_(static_i_extern)http://pl.wikibooks.org/wiki/C/Biblioteki#Zmiana_dostpu_do_funkcji_i_zmiennych_(static_i_extern)http://pl.wikibooks.org/wiki/w:B_(jzyk_programowania)http://pl.wikibooks.org/wiki/C++http://pl.wikibooks.org/wiki/C++/Zmienne

  • 42 ROZDZIA 7. ZMIENNE

  • Rozdzia 8

    Operatory

    8.1 Przypisanie

    Operator przypisania (,,=), jak sama nazwa wskazuje, przypisuje warto prawego argu-mentu lewemu, np.:

    int a = 5, b;b = a;printf("%d\n", b); /* wypisze 5 */

    Operator ten ma czno prawostronn tzn. obliczanie przypisa nastpuje z prawa nalewo i zwraca on przypisan warto, dziki czemu moe by uyty kaskadowo:

    int a, b, c;a = b = c = 3;printf("%d %d %d\n", a, b, c); /* wypisze "3 3 3" */

    8.1.1 Skrcony zapis

    C umoliwia te skrcony zapis postaci a #= b;, gdzie # jest jednym z operatorw: +, -, *, /,&, |, , > (opisanych niej). Oglnie rzecz ujmujc zapis a #= b; jest rwnowanyzapisowi a = a # (b);, np.:

    int a = 1;a += 5; /* to samo, co a = a + 5; */a /= a + 2; /* to samo, co a = a / (a + 2); */a %= 2; /* to samo, co a = a % 2; */

    Pocztkowo skrcona notacja miaa nastpujc skadni: a =# b, co czsto prowadzio doniejasnoci, np. i =- (i = - czy te i = i-?). Dlatego te zdecydowano si zmieni kolejnooperatorw.

    43

  • 44 ROZDZIA 8. OPERATORY

    8.2 Rzutowanie

    Zadaniem rzutowania jest konwersja danej jednego typu na dan innego typu. Konwer-sja moe by niejawna (domylna konwersja przyjta przez kompilator) lub jawna (podanaexplicite przez programist). Oto kilka przykadw konwersji niejawnej:

    int i = 42.7; /* konwersja z double do int */float f = i; /* konwersja z int do float */double d = f; /* konwersja z float do double */unsigned u = i; /* konwersja z int do unsigned int */f = 4.2; /* konwersja z double do float */i = d; /* konwersja z double do int */char *str = "foo"; /* konwersja z const char* do char* [1] */const char *cstr = str; /* konwersja z char* do const char* */void *ptr = str; /* konwersja z char* do void* */

    Podczas konwersji zmiennych zawierajcych wiksze iloci danych do typw prostszych(np. double do int) musimy liczy si z utrat informacji, jak to miao miejsce w pierwszejlinijce zmienna int nie moe przechowywa czci uamkowej tote zostaa ona odcita iw rezultacie zmiennej zostaa przypisana warto .

    Zaskakujca moe si wyda linijka oznaczona przez 1. Niejawna konwersja z typu constchar* do typu char* nie jest dopuszczana przez standard C. Jednak literay napisowe (ktre stypu const char*) stanowi tutaj wyjtek. Wynika on z faktu, e byy one uywane na dugoprzed wprowadzeniem swka const do jzyka i brak wspomnianegowyjtku spowodowaby,e dua cz kodu zostaaby nagle zakwalifikowana jako niepoprawny kod.

    Do jawnego wymuszenia konwersji suy jednoargumentowy operator rzutowania, np.:

    double d = 3.14;int pi = (int)d; /* 1 */pi = (unsigned)pi >> 4; /* 2 */

    W pierwszym przypadku operator zosta uyty, by zwrci uwag na utrat precyzji. Wdrugim, dlatego e bez niego operator przesunicia bitowego zachowuje si troch inaczej.

    Obie konwersje przedstawione powyej s dopuszczane przez standard jako jawne kon-wersje (tj. konwersja z double do int oraz z int do unsigned int), jednak niektre konwersjes bdne, np.:

    const char *cstr = "foo";char *str = cstr;

    W takich sytuacjach mona uy operatora rzutowania by wymusi konwersj:

    const char *cstr = "foo";char *str = (char*)cstr;

    Naley unika jednak takich sytuacji i nigdy nie stosowa rzutowania by uciszy kompi-lator. Zanim uyjemy operatora rzutowania naley si zastanowi co tak naprawd bdzieon robi i czy nie ma innego sposobu wykonania danej operacji, ktry nie wymagaby podej-mowania tak drastycznych krokw.

    1

  • 8.3. OPERATORY ARYTMETYCZNE 45

    8.3 Operatory arytmetyczne

    W arytmetyce komputerowej nie dziaa prawo cznoci oraz rozdzielnoci. Wynika toz ograniczonego rozmiaru zmiennych, ktre przechowuj wartoci. Przykad dla zmiennycho dugoci bitw (bez znaku). Maksymalna warto, ktr moe przechowywa typ to:2161 = 65535. Zatem operacja typu 65530+1020 zapisana jako (65530+10)20 moezaowocowa czym zupenie innym ni 65530+(1020). W pierwszym przypadku zapewnedojdzie do tzw. przepenienia - procesor nie bdzie mia miejsca, aby zapisa dodatkowybit. Zachowanie programu bdzie w takim przypadku zaleao od architektury procesora.Analogiczny przykad moemy poda dla rozdzielnoci mnoenia wzgldem dodawania.

    Jzyk C definiuje nastpujce dwuargumentowe operatory arytmetyczne:

    dodawanie (,,+),

    odejmowanie (,,-),

    mnoenie (,,*),

    dzielenie (,,/),

    reszta z dzielenia (,,%) okrelona tylko dla liczb cakowitych (tzw. dzielenie modulo).

    int a=7, b=2, c;c = a % b;printf ("%d\n",c); /* wypisze "1" */

    Naley pamita, e (w pewnym uproszczeniu) wynik operacji jest typu takiego jak naj-wikszy z argumentw. Oznacza to, e operacja wykonana na dwch liczbach cakowitychnadal ma typ cakowity nawet jeeli wynik przypiszemy do zmiennej rzeczywistej. Dla przy-kadu, poniszy kod:

    float a = 7 / 2;printf("%f\n", a);

    wypisze (wbrew oczekiwaniu pocztkujcych programistw) 3.0, a nie 3.5. Odnosi sito nie tylko do dzielenia, ale take mnoenia, np.:

    float a = 1000 * 1000 * 1000 * 1000 * 1000 * 1000;printf("%f\n", a);

    prawdopodobnie da o wiele mniejszy wynik ni bymy si spodziewali. Aby wymusiobliczenia rzeczywiste naley zmieni typ jednego z argumentw na liczb rzeczywist poprostu zmieniajc litera lub korzystajc z rzutowania, np.:

    float a = 7.0 / 2;float b = (float)1000 * 1000 * 1000 * 1000 * 1000 * 1000;printf("%f\n", a);printf("%f\n", b);

    Operatory dodawania i odejmowania s okrelone rwnie, gdy jednym z argumentwjest wskanik, a drugim liczba cakowita. Ten drugi jest take okrelony, gdy oba argumentys wskanikami. O takim uyciu tych operatorw dowiesz si wicej C/Wskaniki|w dalszejczci ksiki.

    http://pl.wikibooks.org/wiki/C/Wskaniki|w_dalszej_czci ksikihttp://pl.wikibooks.org/wiki/C/Wskaniki|w_dalszej_czci ksiki

  • 46 ROZDZIA 8. OPERATORY

    8.3.1 Inkrementacja i dekrementacja

    Aby skrci zapis wprowadzono dodatkowe operatory: inkrementacji (,,++) i dekrementa-cji (,,), ktre dodatkowo mog by pre- lub postfiksowe. W rezultacie mamy wic czteryoperatory:

    pre-inkrementacja (,,++i),

    post-inkrementacja (,,i++),

    pre-dekrementacja (,,i) i

    post-dekrementacja (,,i).

    Operatory inkrementacji zwiksza, a dekrementacji zmniejsza argument o jeden. Ponadtooperatory pre- zwracaj now warto argumentu, natomiast post- star warto argumentu.

    int a, b, c;a = 3;b = a--; /* po operacji b=3 a=2 */c = --b; /* po operacji b=2 c=2 */

    Czasami (szczeglnie w C++) uycie operatorw stawianych za argumentem jest niecomniej efektywne (bo kompilator musi stworzy now zmienn by przechowa warto tym-czasow).

    Bardzo wane jest, abymy poprawnie stosowali operatory dekrementacji i inkrementa-cji. Chodzi o to, aby w jednej instrukcji nie umieszcza kilku operatorw, ktre modyfikujten sam obiekt (zmienn). Jeeli taka sytuacja zaistnieje, to efekt dziaania instrukcji jestnieokrelony. Prostym przykadem mog by nastpujce instrukcje:

    int a = 1;a = a++;a = ++a;a = a++ + ++a;printf("%d %d\n", ++a, ++a);printf("%d %d\n", a++, a++);

    Kompilator potrafi ostrzega przed takimi bdami - aby to czyni naley poda mujako argument opcj -Wsequence-point.

    8.4 Operacje bitoweOprcz operacji znanych z lekcji matematyki w podstawwce, jzyk C zosta wyposaonytake w operatory bitowe, zdefiniowane dla liczb cakowitych. S to:

    negacja bitowa (,,),

    koniunkcja bitowa (,,&),

    alternatywa bitowa (,,|) i

    http://pl.wikipedia.org/wiki/pre-inkrementacjahttp://pl.wikipedia.org/wiki/post-inkrementacjahttp://pl.wikipedia.org/wiki/pre-dekrementacjahttp://pl.wikipedia.org/wiki/post-dekrementacja

  • 8.4. OPERACJE BITOWE 47

    alternatywa rozczna () (,,).

    Dziaaj one na poszczeglnych bitach przez co mog by szybsze od innych operacji.Dziaanie tych operatorw mona zdefiniowa za pomoc poniszych tabel:

    "~" | 0 1 "&" | 0 1 "|" | 0 1 "^" | 0 1-----+----- -----+----- -----+----- -----+-----

    | 1 0 0 | 0 0 0 | 0 1 0 | 0 11 | 0 1 1 | 1 1 1 | 1 0

    a | 0101 = 5b | 0011 = 3

    -------+------~a | 1010 = 10~b | 1100 = 12

    a & b | 0001 = 1a | b | 0111 = 7a ^ b | 0110 = 6

    Lub bardziej opisowo:

    negacja bitowa daje w wyniku liczb, ktra ma bity rwne jeden tylko na tych pozy-cjach, na ktrych argument mia bity rwne zero;

    koniunkcja bitowa daje wwyniku liczb, ktra ma bity rwne jeden tylko na tych pozy-cjach, na ktrych oba argumenty miay bity rwne jeden (mnemonik: gdy wszystkie);

    alternatywa bitowa daje w wyniku liczb, ktra ma bity rwne jeden na wszystkichtych pozycjach, na ktrych jeden z argumentw mia bit rwny jeden (mnemonik: jeli jest );

    alternatywa rozczna daje w wyniku liczb, ktra ma bity rwne jeden tylko na tychpozycjach, na ktrych tylko jeden z argumentw mia bit rwny jeden (mnemonik: gdy rne).

    Przy okazji warto zauway, e abb to po prostu a. Waciwo ta zostaa wykorzystanaw rnych algorytmach szyfrowania oraz funkcjach haszujcych. Alternatyw wyczn sto-suje si np. do szyfrowania kodu wirusw polimorficznych.

    8.4.1 Przesunicie bitowe

    Dodatkowo, jzyk C wyposaony jest w operatory przesunicia bitowego w lewo (,,). Przesuwaj one w danym kierunku bity lewego argumentu o liczb pozycjipodan jako prawy argument. Brzmi to moe strasznie, ale wcale takie nie jest. Rozwamy-bitowe liczby bez znaku (taki hipotetyczny unsigned int), wwczas:

    a | a2------+------+------+------+------0001 | 0010 | 0100 | 0000 | 00000011 | 0110 | 1100 | 0001 | 00000101 | 1010 | 0100 | 0010 | 0001

    http://pl.wikibooks.org/wiki/w:Wirus_komputerowy

  • 48 ROZDZIA 8. OPERATORY

    1000 | 0000 | 0000 | 0100 | 00101111 | 1110 | 1100 | 0111 | 00111001 | 0010 | 0100 | 0100 | 0010

    Nie jest to zatem takie straszne na jakie wyglda. Wida, e bity bdce na skraju stracone, a w ,,puste miejsca wpisywane s zera.

    Inaczej rzecz si ma jeeli lewy argument jest liczb ze znakiem. Dla przesunicia bito-wego w lewo a >1 | a>>2------+------+------0001 | 0000 | 00000011 | 0001 | 00000101 | 0010 | 00011000 | 1100 | 11101111 | 1111 | 11111001 | 1100 | 1110

    Przesunicie bitowe w lewo odpowiada pomnoeniu, natomiast przesunicie bitowe wprawo podzieleniu liczby przez dwa do potgi jak wyznacza prawy argument. Jeeli prawyargument jest ujemny lub wikszy lub rwny liczbie bitw w typie, dziaanie jest niezdefi-niowane.

    #include

    int main (){

    int a = 6;printf ("6 > 2 = %d\n", a>>2); /* wypisze 1 */return 0;

    }

    8.5 PorwnanieW jzyku C wystpuj nastpujce operatory porwnania:

    rwne (,,==),

    rne (,,!=),

    mniejsze (,,

  • 8.5. PORWNANIE 49

    wiksze (,,>),

    mniejsze lub rwne (,,=).

    Wykonuj one odpowiednie porwnanie swoich argumentw i zwracaj jedynk jeeliwarunek jest speniony lub zero jeeli nie jest.

    8.5.1 Czste bdy

    Osoby, ktre poprzednio uczyy si innych jzykw programowania, czsto maj nawykuywania w instrukcjach logicznych zamiast operatora porwnania ==, operatora przypi-sania =. Ma to czsto zgubne efekty, gdy przypisanie zwraca warto przypisan lewemuargumentowi.

    Porwnajmy ze sob dwa warunki:

    (a = 1)(a == 1)

    Pierwszy z nich zawsze bdzie prawdziwy, niezalenie od wartoci zmiennej a! Dziejesi tak, poniewa zostaje wykonane przypisanie do a wartoci a nastpnie jako warto jestzwracane to, co zostao przypisane czyli jeden. Drugi natomiast bdzie prawdziwy tylko,gdy a jest rwne .

    W celu uniknicia takich bdw niektrzy programici zamiast pisa a == 1 pisz 1 == a,dziki czemu pomyka spowoduje, e kompilator zgosi bd.

    Warto zauway, e kompilator potrafi w pewnych sytuacjach wychwyci taki bd.Aby zacz to robi naley poda mu argument -Wparentheses.

    Innym bdem jest uycie zwykych operatorw porwnania do sprawdzania relacji po-midzy liczbami rzeczywistymi. Poniewa operacje zmiennoprzecinkowe wykonywane s zpewnym przyblieniem rzadko kiedy dwie zmienne typu float czy double s sobie rwne. Dlaprzykadu:

    #include int main () {

    float a, b, c;a = 1e10; /* tj. 10 do potgi 10 */b