načítání...
nákupní košík
Košík

je prázdný
a
b

E-kniha: Programovací jazyk C - Brian W. Kernighan; Dennis M. Ritchie

Programovací jazyk C

Elektronická kniha: Programovací jazyk C
Autor: ;

Přestože světově proslulá kniha o programovacím jazyku C od jeho zakladatelů vychází v češtině teprve v roce 2006, pro mnohé programátory, kteří ve svém oboru něco dokázali, je již ... (celý popis)
Titul je skladem - ke stažení ihned
Médium: e-kniha
Vaše cena s DPH:  189
+
-
6,3
bo za nákup

ukázka z knihy ukázka

Titul je dostupný ve formě:
elektronická forma tištěná forma

hodnoceni - 82.7%hodnoceni - 82.7%hodnoceni - 82.7%hodnoceni - 82.7%hodnoceni - 82.7% 90%   celkové hodnocení
4 hodnocení + 1 recenze

Specifikace
Nakladatelství: » Computer press
Dostupné formáty
ke stažení:
PDF
Upozornění: většina e-knih je zabezpečena proti tisku
Médium: e-book
Počet stran: 286
Rozměr: 23 cm
Úprava: ilustrace
Vydání: 1. vyd.
Spolupracovali: překlad Zbyněk Šáva
Jazyk: česky
ADOBE DRM: bez
ISBN: 978-80-251-0897-0
Ukázka: » zobrazit ukázku
Popis

Přestože světově proslulá kniha o programovacím jazyku C od jeho zakladatelů vychází v češtině teprve v roce 2006, pro mnohé programátory, kteří ve svém oboru něco dokázali, je již léta vyhlášeným pojmem, stejně jako jména autorů Briana W. Kernighana a Dennise M. Ritchieho.

I když současné anglické vydání pochází z roku 1988 (první bylo napsáno v roce 1978), zůstává i v době překladu do češtiny předním celosvětovým bestsellerem, z něhož čerpají základy i detaily jazyka C začátečníci a studenti, ověřené informace autoři jiných publikací a odpovědi na své náhlé otázky programátoři, pro něž je programování v C nebo C++ denním chlebíčkem.

Protože v roce 1999 byla přijata nová verze standardu ANSI C, nechal navíc český vydavatel text pečlivě aktualizovat o příslušné změny a novinky. Autorem doplňků, které stojí v kapitolách a na závěr knihy stranou původního textu, je Miroslav Virius – tedy další jméno, jež je samo o sobě zárukou vysoké odbornosti a promyšleného výkladu.

Příklady v knize jsou převážně kompletní funkční programy (nejen obvyklé fragmenty), plně lokalizované do češtiny a českého prostředí, což vše dohromady činí knihu snadno použitelnou i pro začátečníky. Protože neobsahuje úvod do programování, předpokládá pouze určitou znalost jeho základních principů (např. proměnné, přiřazovací příkazy, cykly a funkce).

Kniha vás zasvětí do následujících aspektů jazyka C:
- Principy a základní prostředky jazyka
- Typy, operátory, výrazy
- Řízení běhu programu
- Funkce a struktura programu
- Ukazatele
- Struktury
- Vstup a výstup
- Rozhraní systému Unix
- Referenční příručka jazyka
- Standardní knihovna
- Přehled změn ve vývoji jazyka
- Hlavní novinky standardu C99

Kromě správného pochopení jazyka C a nalezení přesných informací o konstrukci a účelu jeho prvků bude i pro zkušenější programátory neocenitelným přínosem dílo mistrů svého oboru i jen pozorně přečíst a pozorovat efektivní použití programovacího jazyka, zásady kvalitního návrhu programů a vysoké znovupoužitelnosti kódu.

O autorech:

Brian W. Kernighan a Dennis M. Ritchie jsou vynálezci jazyka C a jedněmi z hlavních osobností v dřívějším vývoji Unixu. Oba pracují od konce 60. let ve výzkumném centru počítačových věd v Bell Laboratories/Lucent Technologies (první z nich údajně dokonce stále ve stejné kanceláři).

Kernighan píše programy a příležitostně knihy, např. The Unix Programming Environment nebo The Elements of Programming Style a je konzultantem pro knižní edici Professional Computing u nakladatelství Addison-Wesley.

Ritchie se zasloužil např. o vývoj jazyků ALTRAN, BCPL, C či Multics a systému Unix, dnes vede menší výzkumný tým pro distribuované operační systémy, programovací jazyky a síťový hardware.

Předmětná hesla
Zařazeno v kategoriích
Brian W. Kernighan; Dennis M. Ritchie - další tituly autora:
Recenze a komentáře k titulu



Programovací jazyk C, SPŠ týčr 2011-01-24 hodnoceni - 70%hodnoceni - 70%hodnoceni - 70%hodnoceni - 70%hodnoceni - 70%
Předmětné heslo "Objektově orientované programování" v tomto webshopu je blbina, C nemá objekty. ----- Učebnice je v angl. originále pětihvězdičková. Computer Press leccos zkope (i v této české verzi). K výuce používám obě. Studenti (střední průmyslové školy) mají českou; já českou používám k načerpání čes. terminologie a běžně pracuju s originálem.
reagovat
 


Ukázka / obsah
Přepis ukázky

Brian W. Kernighan, Dennis M. Ritchie

Programovací jazyk C

Computer Press

Brno

2013


Programovací jazyk C

Brian W. Kernighan, Dennis M. Ritchie

Překlad: Zbyněk Šáva

Odborná korektura: Miroslav Virius

Obálka: Martin Sodomka

Odpovědný redaktor: Martin Domes

Technický redaktor: Jiří Matoušek

Authorized translation from the English language edition, entitled „C PROGRAMMING LANGUAGE,

2 nd Edition“,ISBN 0131103628, by KERNINGHAN, BRIAN W.; RITCHIE, DENNIS, published by

Pearson Education, Inc, publishing as Prentice Hall PTR, Copyright © 1988 All rights reserved.

No part of this book may be reproduced or transmitted in any form or by by any means, electronic

or mechanical, including photocopying, recording or by any information storage retrieval system,

without permission from the Publisher. CZECH language edition published by Computer Press, a.s.,

Copyright © 2006.

Objednávky knih:

http://knihy.cpress.cz

www.albatrosmedia.cz

eshop@albatrosmedia.cz

bezplatná linka 800 555 513

ISBN 978-80-251-0897-0

Vydalo nakladatelství Computer Press v Brně roku 2013 ve společnosti Albatros Media a. s. se sídlem

Na Pankráci 30, Praha 4. Číslo publikace 16 695.

© Albatros Media a. s. Všechna práva vyhrazena. Žádná část této publikace nesmí být kopírována

a rozmnožována za účelem rozšiřování v jakékoli formě či jakýmkoli způsobem bez písemného souhlasu

vydavatele.

Dotisk 1. vydání


Obsah

Předmluva k českému vydání 11

Předmluva 13

Předmluva k prvnímu vydání 15

Úvod 17 Kapitola 1 Úvodní kurz 21

1.1 Začínáme 21

1.2 Proměnné a aritmetické výrazy 24

1.3 Příkaz for 28

1.4 Symbolické konstanty 29

1.5 Znakový vstup a výstup 30

1.5.1 Kopírování souboru 30

1.5.2 Počítání znaků 32

1.5.3 Počítání řádků 33

1.5.4 Počítání slov 34

1.6 Pole 35

1.7 Funkce 37

1.8 Argumenty – předávání hodnotou 40

1.9 Znaková pole 41

1.10 Externí proměnné a oblast platnosti 43

1.11 Standard C99 46 Kapitola 2 Typy, operátory a výrazy 47

2.1 Jména proměnných 47

2.2 Datové typy a velikosti 47

2.3 Konstanty 48

2.4 Deklarace 51

2.5 Aritmetické operátory 52

2.6 Relační a logické operátory 52

2.7 Konverze typů 53

2.8 Operátory inkrementace a dekrementace 57

2.9 Bitové operátory 58

2.10 Přiřazovací operátory a výrazy 60


2.11 Podmíněné výrazy 61

2.12 Priorita a pořadí výpočtu 62

2.12 Standard C99 63

2.12.1 Celočíselné typy 64

2.12.2 Čísla s pohyblivou řádovou čárkou 67

2.12.3 Komplexní čísla 69

2.12.4 Konverze 70

Kapitola 3

Řízení běhu programu 73

3.1 Příkazy a bloky 73

3.2 If-else 73

3.3 Else-if 74

3.4 Switch 76

3.5 Cykly – while a for 77

3.6 Cykly – do-while 80

3.7 Break a continue 81

3.8 goto a návěští 82

3.9 Standard C99 83

3.9.1 Bloky a deklarace 83

3.9.2 Cykly 83

3.9.3 Výběrové (podmíněné) příkazy 84

3.9.4 Skok 84

Kapitola 4

Funkce a struktura programu 85

4.1 Začínáme s funkcemi 85

4.2 Funkce, které nevrací celá čísla 88

4.3 Externí proměnné 90

4.4 Pravidla rozsahu platnosti 96

4.5 Hlavičkové soubory 97

4.6 Statické proměnné 98

4.7 Registrové proměnné 99

4.8 Bloková struktura 100

4.9 Inicializace 100

4.10 Rekurze 101

4.11 Preprocesor jazyka C 103

4.11.1 Vkládání souborů 103

4.11.2 Substituce maker 104

4.11.3 Podmíněný překlad 105 4.12 Standard C99 106

4

Obsah


4.12.1 Funkce 106

4.12.2 Makra 108

4.12.3 #pragma 108

Kapitola 5

Ukazatele a pole 111

5.1 Ukazatele a adresy 111

5.2 Ukazatele a argumenty funkcí 113

5.3 Ukazatele a pole 115

5.4 Adresová aritmetika 117

5.5 Funkce a ukazatele na znaky 120

5.6 Ukazatele na pole; ukazatele na ukazatele 123

5.7 Vícerozměrná pole 126

5.8 Inicializace polí ukazatelů 128

5.9 Ukazatele versus vícerozměrná pole 128

5.10 Argumenty příkazové řádky 129

5.11 Ukazatele na funkce 133

5.12 Komplikované deklarace 136

5.13 Standard v C99 140

5.13.1 Restringované (omezené) ukazatele 140

5.13.2 Pole 142

5.13.3 Pole jako parametr funkce 143

Kapitola 6

Struktury 145

6.1 Základní informace o strukturách 145

6.2 Struktury a funkce 147

6.3 Pole struktur 149

6.4 Ukazatele na struktury 153

6.5 Struktury odkazující na sebe 155

6.6 Vyhledávání v tabulkách 159

6.7 Typedef 161

6.9 Unie 162

6.9 Bitová pole 163

6.10 Standard C99 165

6.10.1 Bitová pole 165

6.10.2 Inicializace struktur a unií 165

6.10.3 Literály typu struktura a unie 165

Obsah

5


Kapitola 7

Vstup a výstup 167

7.1 Standardní vstup a výstup 167

7.2 Formátovaný výstup – funkce printf 169

7.3 Seznamy argumentů proměnné délky 171

7.4 Formátovaný vstup – funkce scanf 172

7.5 Přístup k souborům 175

7.6 Ošetření chyb – funkce stderr a exit 177

7.7 Vstup a výstup po řádcích 179

7.8 Různé funkce 180

7.8.1 Operace s řetězci 180

7.8.2 Testování tříd znaků a konverze 180

7.8.3 Funkce ungetc 181

7.8.4 Vykonání příkazu 181

7.8.5 Správa paměti 181

7.8.6 Matematické funkce 182

7.8.7 Generování náhodných čísel 182 7.9 Standard C99 182

7.9.1 Datové proudy 183

Kapitola 8

Rozhraní systému UNIX 185

8.1 Deskriptory souborů 185

8.2 Nízkoúrovňový vstup a výstup 186

8.3 Open, creat, close, unlink 187

8.4 Náhodný přístup – lseek 190

8.5 Příklad – implementace funkcí fopen a getc 190

8.6 Příklad – výpis adresářů 194

8.7 Příklad – alokátor paměti 199

Příloha A

Referenční příručka 203

A1. Úvod 203

A2. Lexikální konvence 203

A2.1 Symboly 203

A2.2 Komentáře 203

A2.3 Identifikátory 204

A2.4 Klíčová slova 204

A2.5 Konstanty 204

A2.6 Řetězcové literály 206

6

Obsah


A3 Zápis syntaxe 206

A4 Význam identifikátorů 207

A4.1 Paměťová třída 207

A4.2 Základní typy 207

A4.3 Odvozené typy 208

A4.4 Kvalifikátory typů 208 A5 Objekty a l-hodnoty 209 A6 Konverze 209

A6.1 Celočíselná rozšíření 209

A6.2 Celočíselné konverze 209

A6.3 Celá čísla a čísla s pohyblivou řádovou čárkou 209

A6.4 Typy s pohyblivou řádovou čárkou 210

A6.5 Aritmetické konverze 210

A6.6 Ukazatele a celá čísla 210

A6.7 Void 211

A6.8 Ukazatele na void 211 A7 Výrazy 212

A7.1 Vytváření ukazatelů 212

A7.2 Primární výrazy 212

A7.3 Postfixové výrazy 213

A7.4 Unární operátory 215

A7.5 Přetypování 217

A7.6 Multiplikativní operátory 217

A7.7 Aditivní operátory 217

A7.8 Operátory posunu 218

A7.9 Relační operátory 218

A7.10 Operátory rovnosti 219

A7.11 Operátor bitové konjunkce 219

A7.12 Operátor bitové nonekvivalence 219

A7.13 Operátor bitové disjunkce 219

A7.14 Operátor logické konjunkce 219

A7.15 Operátor logické disjunkce 220

A7.16 Podmíněný operátor 220

A7.17 Výrazy přiřazení 220

A7.18 Operátor čárka 221

A7.19 Konstantní výrazy 221 A8 Deklarace 222

A8.1 Specifikátory paměťové třídy 222

A8.2 Specifikátory typů 223

A8.3 Deklarace struktur a unií 224

A8.4 Výčty 227

A8.5 Deklarace 228

Obsah

7


A8.6 Význam deklarátorů 228

A8.7 Inicializace 231

A8.8 Jména typů 233

A8.9 Typedef 234

A8.10 Ekvivalence typů 234 A9 Příkazy 235

A9.1 Příkazy s návěštím 235

A9.2 Výrazový příkaz 235

A9.3 Složený příkaz 235

A9.4 Výběrové příkazy 236

A9.5 Iterační příkazy 237

A9.6 Příkazy skoku 237 A10 Externí deklarace 238

A10.1 Definice funkcí 238

A10.2 Externí deklarace 239 A11 Rozsah platnosti a vazba 240

A11.1 Lexikální rozsah platnosti 240

A11.2 Vazba 241 A12 Preprocesor 241

A12.1 Trigrafy 242

A12.2 Spojování řádků 242

A12.3 Definice a rozvoj maker 242

A12.4 Vkládání souborů 244

A12.5 Podmíněná kompilace 245

A12.6 Řízení řádků 246

A12.7 Generování chyb 246

A12.8 Pragma 246

A12.9 Prázdná direktiva 247

A12.10 Předdefinovaná jména 247 A13 Gramatika 247

Příloha B

Standardní knihovna 255

B1. Vstup a výstup: <stdio.h> 255

B1.1 Operace se soubory 256

B1.2 Formátovaný výstup 257

B1.3 Formátovaný vstup 259

B1.4 Funkce pro vstup a výstup po jednotlivých znacích 261

B1.5 Funkce pro přímý vstup a výstup 262

B1.6 Funkce pracující s pozicí v souboru 262

B1.7 Chybové funkce 262

8

Obsah


B2 Testy tříd znaků: <ctype.h> 263

B3. Funkce pracující s řetězci <string.h> 264

B4. Matematické funkce: <math.h> 265

B5. Užitečné funkce: <stdlib.h> 266

B6. Ladění: <assert.h> 269

B7. Seznam argumentů proměnné délky: <stdarg.h> 269

B8. Nelokální skoky: <setjmp.h> 270

B9. Signály: <signal.h> 270

B10. Funkce pro práci s datem a časem: <time.h> 271

B11. Implementací definované meze: <limits.h> a 273 Příloha C Shrnutí změn 275 Příloha D Hlavní novinky standardu C99 279 Rejstřík 281

Obsah

9



Předmluva

k českému vydání

Držíte v rukou nejznámější knihu o jazyce C, jaká kdy byla napsána – knihu nejen stále

aktuální, ale v mnoha ohledech také stále nepřekonanou. Jedním z jejích autorů je Denis

Ritchie, který v roce 1972 navrhl a implementoval první verzi jazyka C; spolu s Brianem W.

Kernighanem pak v roce 1978 vydali knihu The C Programming Language, která se na

dlouhou dobu stala neoficiálním standardem tohoto jazyka.

Jazyk popsaný v prvním vydání této knihy se dodnes označuje jako „jazyk C podleKer

nighana a Ritchieho“, případně „C podle K&R“, a s jeho implementacemi se lze stále ještě

setkat. U nás je toto první vydání známo ze slovenského překladu vydanéhonakladatel

stvím Alfa (Bratislava, 1988).

V roce 1988 vyšlo druhé, aktualizované vydání, které popisuje tehdy připravovaný standard

ANSI X3.159-1989. Překlad tohoto vydání se vám nyní dostává do rukou.

Americký národní standard jazyka C byl v USA v roce 1990 stažen a nahrazenmezinárod

ním standardem ISO/IEC 9899-1990, dnes běžně označovaným jako C90. To nic nemění na

skutečnosti, že se američtí výrobci softwaru stále odvolávají na standard ANSI. Obrátíte-li

se na Americký národní standardizační institut, ANSI, prodá vám jako standard jazyka C

zmíněnou normu ISO.

Dnešní překladače jazyka C zpravidla plně vyhovují standardu C90.

V roce 1999 byla přijata nová verze standardu jazyka C, dnes označovaná jako C99. Tapři

nesla řadu úprav a rozšíření, o nichž se dozvíte v dodatcích k jednotlivým kapitolám,nade

psaných Standard C99; jejich stručný souhrn pak najdete v dodatku D. Současné

překladače přistupují ke standardu C99 zatím opatrně: většinou implementují pouzeněkte

ré z novinek. To se však v dohledné době může změnit.

Při překladu této knihy jsme zachovali původní text, nesnažili jsme se o úpravu podlestan

dardu C99; pouze na místa, která by mohla při překladu v C99 způsobit problémy, jsme

vložili upozornění v podobě poznámek pod čarou, na závěr většiny kapitol jsme vložili

oddíl Standard C99, v němž jsou shrnutu novinky a změny, a na závěr knihy jsmepřipoji

li Přílohu D shrnující nejdůležitější změny, které standard C99 přinesl.

Spolupracovat na překladu této knihy pro mne bylo opravdu potěšením, a proto bych rád

poděkoval těm, kteří mi na přelomu 80. a 90. let pomohli tento krásný programovací jazyk

zvládnout. Pracoval jsem v oné době jako odborný asistent na Katedře matematiky FJFI

ČVUT na svém prvním projektu v jazyce C. Osobní počítače byly tehdy k dispozici pouze

ve studovně a Ivo Majetič, který právě dokončoval program ke své diplomové práci, si

našel čas a pomohl mi zorientovat se nejen v novinkách jazyka, které nebyly popsány

v prvním vydání Kernighana a Ritchieho, ale především v knihovnách tohoto jazyka.


Poté, co Ivo úspěšně dostudoval, mi s jazykem C pomáhal další z tehdejších studentů,

Mirek Minárik, který mne naučil luštit disasemblované programy a spolu se mnou hledal

chyby jednoho z tehdy populárních překladačů jazyka C a C++.

Oběma jim patří dík.

Miroslav Virius

Katedra softwarového inženýrství FJFI ČVUT

12

Předmluva k českému vydání


Předmluva

Od vydání The C Programming Language v roce 1978 prošel svět výpočetní technikyrevo

lucí. Velké počítače ještě nabraly na velikosti a osobní počítače disponují schopnostmi,

které mohou směle soupeřit se sálovými počítači uplynulé dekády. Během této doby se

změnil i programovací jazyk C (i když jen mírně) a rozšířil se daleko mimo své původní

působiště – operační systém UNIX.

Rostoucí popularita jazyka C, jeho změny v uplynulých letech a vytvoření kompilátorůsku

pinami, které se nepodílely na jeho návrhu, jsou důvodem, proč je nutná precizní aaktu

álnější definice jazyka, než jakou poskytlo první vydání této knihy. V roce 1983 sestavila

organizace American National Standards Institute (ANSI) komisi, jejímž úkolem bylovytvo

řit „bezespornou a strojově nezávislou definici jazyka C“, která by zachovávala původní

myšlenky jazyka. Výsledkem byl standard ANSI jazyka C.

Standard formalizuje konstrukce naznačené ale nepopsané v prvním vydání, zejména výčty

a přiřazování struktur. Přináší nový způsob deklarace funkcí, jež umožňuje provádětkří

žovou kontrolu definice funkce a jejího použití. Specifikuje standardní knihovnu srozsáh

lou množinou funkcí pro práci se vstupy a výstupy, správu paměti, manipulaci s řetězci

a podobné úkoly. Přesně určuje chování vlastností, jež nebylo detailně vysvětleno vpůvod

ní definici, a současně explicitně jmenuje aspekty jazyka, které zůstávají strojově závislé.

Toto druhé vydání The C Programming Language popisuje jazyk C tak, jak je definován

standardem ANSI. Programy jsme se rozhodli psát výhradně v novém tvaru zápisu, i když

zmiňujeme místa, kde se jazyk změnil. Většinou nedošlo k žádným podstatným změnám;

nejviditelnější změnou je nový způsob deklarace a definice funkcí. Moderní kompilátory již

většinu rysů standardu podporují.

Snažili jsme se zachovat stručnost prvního vydání. C není objemným jazykem, a proto mu

nesvědčí objemné knihy. Zapracovali jsme na výkladu kritických vlastností jazyka, jako

jsou ukazatele, jež jsou středem programování v jazyce C. Vyladili jsme původní příklady

a do několika kapitol jsme dodali příklady nové. Části s komplikovanými deklaracemi jsou

například rozšířeny o programy, které převádí deklarace do slov a naopak. Stejně jako

dříve i nyní jsme testovali přímo všechny příklady z textu, který je ve strojově čitelné formě.

Příloha A, referenční příručka, není standardem, ale naší snahou sdělit vám klíčovézákla

dy standardu na menším prostoru. Je určena programátorům pro snadnější pochopeníjazy

ka, ale nemůže sloužit jako definice pro autory kompilátorů – tato role po právu náleží

samotnému standardu. Příloha B je shrnutím prostředků, které poskytuje standardní kni

hovna. Stejně jako příloha A je zamýšlena jako referenční příručka pro programátory a ne

pro implementátory. Příloha C je stručným výčtem změn oproti původní verzi.

Jak jsme řekli v předmluvě k prvnímu vydání, C „slouží tím lépe, čím více rostou vašezku

šenosti s ním.“ S deseti roky nových zkušeností to cítíme stále stejně. Doufáme, že vám tato

kniha pomůže naučit se jazyk C a správně ho používat v každodenní praxi.


14

Předmluva

Jsme hluboce zavázáni přátelům, kteří nám pomohli s tímto druhým vydáním. Jon Bentley,

Doug Gwyn, Doug McIlroy, Peter Nelson a Rob Pike nám poskytli komentáře k téměř

každé stránce původních návrhů. Za pečlivé čtení děkujeme Alovi Ahovi, DennisiAlliso

novi, Joeovi Campbellovi, G. R. Emlinovi, Karen Fortgangové, Allenovi Holubovi,Andre

wovi Humemu, Davu Kristolovi, Johnu Lindermanovi, Daveovi Prosserovi, Geneovi

Spaffordovi a Chrisi Van Wykovi. Užitečné rady jsme dostali také od Billa Cheswicka,

Marka Kernighana, Andyho Koeniga, Robin Lakeové, Toma Londona, Jima Reedse,Clovi

se Tonda a Petera Weinbergera. Dave Prosser nám zodpověděl mnoho otázek ohledně

standardu ANSI. Pro lokální testování našich programů jsme často využívali překladač C++

Bjarne Stroustrupa a Dave Kristol nám poskytl kompilátor ANSI C pro finální testování. Se

sazbou nám velice pomohl Rich Drechsler.

Upřimně děkujeme všem.

Brian W. Kernighan

Dennis M. Ritchie


Předmluva

k prvnímu vydání

C je univerzální programovací jazyk, vyznačující se úspornými výrazy, moderním řízením

běhu, moderními datovými strukturami a bohatou množinou operátorů. C není „jazykem

vysoké úrovně“, ani „velkým“ jazykem a není specializován pro žádnou konkrétní oblast

nasazení. Ale nepřítomnost omezení a jeho obecnost ho dělají vhodnějším a efektivnějším

pro většinu úloh, než jiné „mocnější“ jazyky.

Jazyk C byl původně navržen a také implementován Dennisem Ritchiem na operačním

systému UNIX na počítači DEC PDP-11. Operační systém, kompilátor jazyka C a prakticky

všechny aplikace pro UNIX (včetně softwaru, jenž byl použit při přípravě této knihy) byly

napsány v C. Produkční kompilátory existují také pro několik dalších počítačů včetně IBM

System/370, Honeywell 6000 a Interdata 8/32. Avšak jazyk C není svázán s konkrétním

hardwarem nebo systémem a je snadné psát programy, které budou fungovat beze změn

na kterémkoli počítači podporujícím C.

Tato kniha si klade za cíl pomoci čtenáři naučit se programovat v jazyce C. Obsahujeúvod

ní kurz jazyka, který umožňuje novým uživatelům začít tak rychle, jak to jen jde, a dále

samostatné kapitoly pro každý z důležitých rysů jazyka a referenční příručku. Většina

výkladu je založena na čtení, psaní a revizi příkladů spíše než na výčtu pravidel. Vevětši

ně případů jsou jako příklady uvedeny kompletní skutečné programy, nikoli izolované

fragmenty kódu. Všechny příklady byly testovány přímo z textu, který je ve strojověčitel

né formě. Kromě ukázek efektivního používání jazyka jsme se také snažili, kde to bylo

možné, ilustrovat užitečné algoritmy a principy dobrého programátorského stylu akvalit

ního návrhu.

Tato kniha není úvodem do programování; předpokládá jistou zkušenost se základními

koncepty programování jako jsou proměnné, přiřazovací příkazy, cykly a funkce.Nicmé

ně ani programátor začátečník by neměl mít problémy s chápáním výkladu, i když rady

zkušenějšího kolegy mohou samozřejmě pomoci.

Naše zkušenosti ukázaly, že C je příjemný, expresivní a všestranný jazyk s širokýmvyuži

tím. Snadno se učí a slouží tím lépe, čím více rostou vaše zkušenosti s ním. Doufáme, že

tato kniha vám pomůže ho správně používat.

Této knize a naší radosti z jejího psaní velice pomohly rady a konstruktivní kritika

mnoha přátel a kolegů. Zejména Mike Bianchi, Jim Blue, Stu Feldman, Doug McIlroy,

Bill Rome, Bob Rosin a Larry Rosler pečlivě přečetli několik verzí této knihy. Jsme také

zavázáni Alovi Ahovi, Steveovi Bournemu, Danu Dvorakovi, Chucku Haleyimu, Debbie

Haleyové, Marion Harrisnové, Dicku Holtovi, Steveovi Johnsonovi, Johnu Masheyimu,

Bobovi Mitzemu, Ralphovi Muhaovi, Peterovi Nelsonovi, Elliotovi Pinsonovi, Billovi

Plaugerovi, Jerrymy Spivackovi, Kenovi Thompsonovi a Peterovi Weibergerovi zauži


tečné připomínky k různým stadiím knihy a Mikeovi Leskovi a Joeovi Ossannaovi za

neocenitelnou pomoc při sazbě.

Brian W. Kernighan

Dennis M. Ritchie

16

Předmluva k prvnímu vydání


Úvod

C je univerzální programovací jazyk. Jeho historie je úzce spjata s operačním systémem

UNIX, kde byl vyvinut, protože jak systém, tak i většina programů, které na něm běží, jsou

napsány v C. Avšak jazyk sám není svázán s žádným operačním systémem nebohardwa

rovou platformou; a i když byl nazýván „systémovým programovacím jazykem“, protože se

hodí pro psaní kompilátorů a operačních systémů, byl stejně dobře využíván pro psaní

důležitých programů v mnoha různých odvětvích.

Mnoho důležitých myšlenek jazyka C vychází z jazyka BCPL, který vyvinul Martin Richards.

Vliv BCPL na C probíhal nepřímo skrze jazyk B vytvořený Kenem Thompsonem v roce

1970 pro první systém UNIX na počítači DEC PDP-7.

BCPL a B jsou „netypované“ jazyky. Naproti tomu C nabízí množství datových typů.

Základními typy jsou znaky, celá čísla a čísla s pohyblivou desetinnou čárkou. Jazyk C

navíc obsahuje hierarchii odvozených datových typů vytvořených pomocí ukazatelů, polí,

struktur a unií. Výrazy se skládají z operátorů a operandů; jakýkoli výraz včetně přiřazení

nebo volání funkce může být příkazem. Díky ukazatelům lze v jazyce C používat strojově

nezávislou adresovou aritmetiku.

Jazyk C nabízí základní konstrukce pro řízení běhu, které jsou nezbytné pro správněstruk

turované programy: seskupování příkazů, rozhodování (if-else), výběr z množinymož

ných případů (switch), cykly s testem ukončení na počátku (while, for) nebo na konci

(do) a předčasný skok z cyklu (break).

Funkce mohou vracet hodnoty základních typů, struktury, unie nebo ukazatele. Jakoukoli

funkci lze volat rekurzivně. Lokální proměnné jsou obvykle „automatické“ a jsou znovu

vytvářeny při každém zavolání funkce. Definice funkcí nesmí být vnořené, ale deklarace

proměnných se řídí blokovou strukturou. Funkce programu v jazyce C mohou existovat

v oddělených zdrojových souborech, které jsou kompilovány zvláš. Proměnné mohou být

viditelné jen v dané funkci, mimo funkci, ale pouze v jednom zdrojovém souboru, nebo

v celém programu.

Preprocesor provádí náhradu maker v textu programu, vkládání dalších zdrojových sou

borů a podmíněnou kompilaci.

C je relativně „nízkoúrovňový“ jazyk. To není myšleno pejorativně; tím chceme říci, že C

pracuje se stejnými objekty jako většina počítačů, jmenovitě se znaky, čísly a adresami.

S tím vším je možno pracovat pomocí aritmetických a logických operátorůimplementova

ných skutečnými počítači.

C nenabízí žádné operace, které by přímo pracovaly se složenými objekty, jako jsouzna

kové řetězce, množiny, seznamy nebo pole. Neobsahuje žádné operace, které manipulují

s celým polem nebo řetězcem, i když struktury lze kopírovat jako atomické objekty. Jazyk

nedefinuje jiný nástroj pro alokaci paměti než statické definice a definice lokálních pro

měnných ve funkcích, které používají zásobník; není zde automatická správa paměti(gar

bage collector). Konečně, samotný jazyk C nemá žádné nástroje pro vstup a výstup;

neobsahuje žádné příkazy READ nebo WRITE a žádné zabudované metody pro přístup


k souborům. Nicméně většina implementací jazyka C obsahuje pro tyto úkoly rozumně

standardní sbírku funkcí.

Podobně, C nabízí pouze jednoduché, jednovláknové řízení běhu programu: testy, cykly,

seskupování a podprogramy, ale ne multiprogramování, paralelní operace, synchronizaci

nebo rutiny.

I když se absence některých těchto nástrojů může jevit jako zásadní nedostatek („Chcete

říct, že musím zavolat funkci, abych porovnal dva znakové řetězce?“), malá velikost jazyka

přináší skutečné výhody. Protože jazyk C je relativně malý, může být popsán na malém

prostoru a je možné se jej rychle naučit. Programátor tak může rozumně předpokládat, že

zná a chápe celý jazyk a může jej pravidelně používat.

Po mnoho let byla definicí jazyka C jeho referenční příručka – v prvním vydání The CPro

gramming Language. V roce 1983 organizace American National Standards Committee

(ANSI) ustanovila komisi, jejímž úkolem bylo vytvořit moderní, úplnou definici jazyka C.

Výsledná definice, standard ANSI neboli „ANSI C“, byla dokončena koncem roku 1988.

Moderní kompilátory už v té době podporovaly většinu rysů standardu.

Standard vychází z původní referenční příručky. Jazyk je změněn jen nepatrně; jedním

z cílů standardu bylo zajistit, že většina existujících programů zůstane platná, nebo, vpří

padě že se program stane neplatným, budou kompilátory varovat před novým chováním.

Pro většinu programátorů byla nejdůležitější změnou nová syntaxe deklarace a definice

funkcí. Deklarace funkce nyní může obsahovat popis argumentů funkce; syntaxe definice

se změnila stejným způsobem. Tato informace navíc velice usnadňuje kompilátorům práci

při detekci chyb způsobených neodpovídajícími argumenty; podle naší zkušenosti jde

o velice užitečné rozšíření jazyka.

V jazyce došlo i k jiným menším změnám. Výčty a přiřazení struktur, které patřily kběž

ným rozšířením, jsou nyní oficiálně součástí jazyka. Výpočty s pohyblivou desetinnoučár

kou lze nyní provádět s jednoduchou přesností. Vlastnosti aritmetiky, zvláště pro typy bez

znaménka, byly upřesněny. Preprocesor je propracovanější. Většina těchto změn má pouze

malý vliv na většinu programátorů.

Druhým důležitým přínosem standardu je specifikace knihovny, která doprovází jazyk C.

Specifikace definuje funkce pro přístup k operačnímu systému (například pro čtení zesou

borů a zápis do nich), formátovaný vstup a výstup, alokaci paměti, manipulaci s řetězci

a další. Sbírka standardních hlavičkových souborů představuje jednotný přístup kdeklara

cím funkcí a datových typů. Programy, které používají tuto knihovnu pro komunikaci

s hostitelským systémem, mají zajištěno kompatibilní chování. Větší část knihovny vychází

ze „standardní knihovny V/V“ systému UNIX. Zde opět pro většinu programátorů nedo

chází k téměř žádným změnám.

Díky tomu, že jsou datové typy a řídicí struktury poskytované jazykem C podporovány

přímo většinou počítačů, je knihovna nutná pro implementaci soběstačných programůveli

ce malá. Funkce standardní knihovny jsou volány pouze explicitně, takže se jim lze

vyhnout, nejsou-li potřeba. Většina z nich může být napsána v C a jsou přenositelné

s výjimkou detailů operačního systému, které zakrývají,.

I když C odpovídá schopnostem mnoha počítačů, je nezávislý na jakékoli konkrétníhard

warové architektuře. I s vynaložením malého úsilí je možné psát přenositelné programy,

tedy programy, které mohou běžet bez úprav na různých hardwarových platformách.Stan

18

Úvod


dard jednoznačně hovoří o problémech s přenositelností a předepisuje seznam konstant

charakterizujících počítač, na němž má program běžet.

C není silně typovaným jazykem, ale během jeho vývoje zesílila i jeho typová kontrola.

Původní definice jazyka C sice nerada viděla záměnu ukazatelů a celých čísel, alepovolo

vala ji; to již déle neplatí a standard nyní požaduje správné deklarace a explicitníkonver

ze, které již dříve vyžadovaly kvalitní kompilátory. Nové deklarace funkcí jsou dalším

krokem tímto směrem. Kompilátory varují při většině typových chyb a neexistujíautoma

tické konverze nekompatibilních datových typů. Nicméně C si uchovává základní filozofii,

že programátoři vědí, co dělají; pouze požaduje, aby své záměry uváděli explicitně.

C má stejně jako ostatní jazyky i své nedostatky. Některé operátory mají špatnou prioritu;

občas by syntaxe mohla být lepší. Přesto se ukázalo, že C je nesmírně efektivní aexpre

sivní jazyk, který našel uplatnění při vývoji širokého spektra aplikací.

Kniha je organizována následujícím způsobem. Kapitola 1 představuje kurz základů jazyka

C. Smyslem této kapitoly je umožnit čtenáři co nejrychlejší start, protože jsme pevněpře

svědčeni, že nejlépe se lze nový jazyk naučit psaním programů. Výuka předpokládá

základní znalost programování; nevysvětlujeme zde pojmy, jako je počítač nebokompila

ce (překlad programu) ani význam výrazu typu n=n+1. I když jsme se snažili předvádětuži

tečné techniky programování kde jen to bylo možné, kniha není koncipována jako

referenční práce o datových strukturách a algoritmech; když jsme byli přinuceni volit,sou

středili jsme se na jazyk.

Kapitoly 2 až 6 detailněji vysvětlují různé aspekty jazyka C formálněji než první kapitola,

i když důraz je stále kladen na příklady kompletních programů, nikoli na izolovanéfrag

menty. Kapitola 2 pojednává o základních typech dat, operátorech a výrazech. Kapitola 3

se zabývá řízením běhu programu: if-else, switch, while, for atd. Kapitola 4 probírá

funkce a strukturu programu – externí proměnné, oblasti platnosti, práci s několikazdro

jovými soubory atp., a také se zmiňuje o preprocesoru. V kapitole 5 jsou vysvětlenyuka

zatele a aritmetika ukazatelů. V kapitole 6 jsou vysvětleny struktury a unie.

Kapitola 7 popisuje standardní knihovnu, která poskytuje jednotné rozhraní operačního

systému. Knihovnu definuje standard ANSI a měla by být podporována každým počítačem,

který podporuje jazyk C, aby programy používající vstup a výstup mohly být přenášeny

beze změny z jednoho systému na druhý.

Kapitola 8 popisuje rozhraní mezi programy v jazyce C a operačním systémem UNIX.

Zaměřuje se na vstup a výstup, systém souborů a alokaci paměti. I přesto, že část tétokapi

toly je specifická pro operační systém UNIX, programátoři používající jiné systémy v ní

naleznou užitečné informace včetně vhledu do problematiky implementace jedné verze

standardní knihovny a postřehy týkající se přenositelnosti.

Příloha A obsahuje referenční příručku jazyka. Oficiální definici syntaxe a sémantikyjazy

ka C představuje samotný standard ANSI. Nicméně tento dokument je určen především pro

autory kompilátorů. Zdejší referenční příručka definuje jazyk stručněji, bez přehnaněfor

málního stylu. Příloha B je shrnutím funkcí standardní knihovny, opět spíše pro uživatele

než pro implementátory. Příloha C je krátkým shrnutím změn oproti původnímu jazyku.

Budete-li na pochybách, zůstává konečnou autoritou standard a váš kompilátor.

Úvod

19



Kapitola 1

Úvodní kurz

Začněme stručným úvodem do jazyka C. Naším cílem bude ukázat základní prvky jazyka

na skutečných programech, aniž bychom zabředávali do detailů, pravidel a výjimek.Pro

zatím se nebudeme snažit o kompletnost nebo přesnost (uvedené příklady budousamo

zřejmě korektní). Chceme vás co nejrychleji dostat do stavu, kdy budete sami schopni psát

použitelné programy. Abychom to dokázali, musíme se koncentrovat na základy:proměn

né a konstanty, aritmetiku, řízení běhu programu, funkce a základy problematiky vstupu

a výstupu. Z této kapitoly záměrně vynecháváme části jazyka C, které jsou důležité pro

psaní větších programů. Mezi ně patří ukazatele, struktury, větší část bohaté množinyope

rátorů, kterou jazyk C disponuje, několik příkazů pro řízení běhu a standardní knihovna.

Tento přístup má své nevýhody. K největším patří fakt, že žádný konkrétní rys jazyka zde

není vysvětlen v celé šíři a výuka může být díky své stručnosti místy zavádějící. Příklady

nevyužívají všech možností jazyka C, proto nejsou stručné a elegantní, jak by mohly být.

Snažili jsme se tyto důsledky minimalizovat, ale bute na pozoru. Další nevýhodou je, že

se budeme v dalších kapitolách chtě nechtě opakovat. Doufáme, že opakování vám bude

spíše k užitku než na obtíž.

Zkušení programátoři by měli být v každém případě schopni extrapolovat z materiálů

v této kapitole podle svých vlastních programátorských potřeb. Začátečníkůmdoporučuje

me psát podobné vlastní malé programy. Obě skupiny mohou tuto kapitolu využít jako

základ, z nějž odvozují detailnější rozbory v dalších kapitolách.

1.1 Začínáme

Programovací jazyk se lze naučit pouze psaním programů. První program bývá shodný ve

všech jazycích:

Vypište slova

Ahoj lidi!

To je velká překážka hned na začátek; abychom ji zdolali, musíme být schopni někde

vytvořit text programu, úspěšně jej zkompilovat, nahrát ho, spustit a zjistit, kam jenasmě

rován výstup programu. Jakmile vyřešíme tyto technické detaily, vše ostatní už je nepo

rovnatelně snazší.


Program pro vypsání „Ahoj lidi!“ vypadá v C následovně:**

#include <stdio.h>

main()

{

printf(“Ahoj lidi!“);

} Samotné spuštění programu závisí na systému, který používáte. Konkrétně na operačním systému UNIX musíte program uložit do souboru, jehož jméno končí příponou „.c“,například ahoj.c, a potom jej zkompilovat příkazem

cc ahoj.c Pokud jste nic nezkazili, například nevynechali některý znak nebo se nepřepsali,kompilace proběhne bez jakýchkoli hlášení a kompilátor vytvoří spustitelný soubor a.out.Spustíte-li soubor a.out napsáním příkazu

a.out vypíše

Ahoj lidi! Na jiných systémech se budou pravidla lišit; v případě nejasností se obrate na vašehomístního odborníka. Nyní vysvětlení programu samotného. Program v jazyce C se nezávisle na své velikostiskládá z funkcí a proměnných. Funkce obsahuje příkazy určující, jaké výpočetní operace se mají provést, a v proměnných se ukládají hodnoty používané během výpočtu. Funkcejazyka C jsou jako podprogramy a funkce jazyka Fortran nebo procedury a funkce jazykaPascal. V našem příkladu máme funkci pojmenovanou main. Obecně máte při pojmenovávání funkcí naprostou svobodu, ale „main“ je speciální případ – výpočet programu začíná na začátku funkce main. To znamená, že každý program musí main obsahovat. Funkce main obvykle volá další funkce, které jste vytvořili nebo které máte k dispozici ve formě knihoven. První řádek programu

#include <stdio.h> říká kompilátoru, aby do programu vložil informaci o standardní knihovně pro vstup a výstup; tento řádek se objevuje na počátcích mnoha zdrojových kódů v jazyce C.Standardní knihovna je popsána v kapitole 7 a v příloze B. Jednou z metod přenosu dat mezi funkcemi je použití seznamu hodnot nazývanýchargumenty, které volající funkce předává funkci volané. Závorky za jménem funkce obklopují seznam argumentů. V tomto příkladu je main definována jako funkce, která neočekává žádné argumenty, což je naznačeno prázdným seznamem (). 22

Začínáme

** Poznámka českého vydavatele: Používáte-li překladač jazyka C vyhovující standardu C99 nebo překladač jazyka C++,

budete muset upravit druhý řádek do tvaru int main().Význam programu se tím nezmění. Starší překladače si uměly

slovo int „domyslet“, nový standard to zakazuje. Stejně budete muset upravit funkci main i ve všech dalšíchprogramech v této knize.


#include <stdio.h> vloží informaci o standardní knihovně

main() definuje funkci jménem main, která nepřijímá

žádné argumenty

{ příkazy funkce main jsou uzavřeny ve složených

závorkách

printf(“Ahoj lidi!“); main volá funkci printf, aby vypsala posloupnost

znaků; reprezentuje znak nového řádku

}

První program v jazyce C

Příkazy funkce jsou uzavřeny ve složených závorkách {}. Funkce main obsahuje pouze

jeden příkaz,

printf(“Ahoj lidi!“); Funkce se volá svým jménem následovaným seznamem argumentů uzavřeným do závorek, tento příkaz tedy zavolá funkci printf s argumentem “Ahoj lidi!“. printf je knihovní funkce, která vypíše výstup, v tomto případě řetězec znaků mezi uvozovkami. Posloupnost znaků v uvozovkách, například “Ahoj světe!“, se nazývá znakový řetězec nebo řetězcová konstanta. Prozatím budeme znakové řetězce používat pouze jako argumenty pro printf a jiné funkce. Posloupnost znaků v řetězci představuje zápis znaku nového řádku v jazyce C. Je-li vypsán, posune aktuální pozici výpisu k levému okraji následujícího řádku. Vynecháte-li (pokus, který stojí za to), zjistíte, že po vypsání výstupu nedojde k posunu na nový řádek. Pro vložení znaku nového řádku do argumentu funkce printf musíte použít ; zkusíte-li něco jako

printf(“Ahoj lidi!

“); kompilátor vypíše chybové hlášení. Funkce printf nikdy nevkládá nový řádek automaticky, takže ji lze zavolat několikrát a vypsat tak jeden řádek v několika krocích. Náš první program mohl stejně dobřevypadat takto,

#include <stdio.h>

main()

{

printf(“Ahoj “);

printf(“světe!“);

printf(““);

} a vypsal by identický výstup. Všimněte si, že reprezentuje pouze jediný znak. Řídicí posloupnost typu nám dává obecný a rozšířitelný mechanismus pro reprezentaci znaků, které jsou neviditelné nebo se těžko píší. C poskytuje mimo jiné pro tabulátor,  pro backspace, “ pro uvozovky nahoře a \ pro samotné zpětné lomítko. Kompletní seznam řídicích posloupnostínaleznete v kapitole 2.3.

Kapitola 1 – Úvodní kurz

23


Cvičení 1.1. Spouštějte na svém systému program „Ahoj lidi!“. Experimentujte svynecháváním částí programu, abyste viděli, jaká chybová hlášení dostanete.

Cvičení 1.2. Experimentováním zjistěte, co se stane, jestliže argument funkce printftvořený řetězcem obsahuje z, kde z je libovolný znak, o němž jsme se nezmínili.

1.2 Proměnné a aritmetické výrazy

Další program použije vzorec şC = (5/9)(şF-32) a vypíše následující tabulku teplot ve

stupních Fahrenheita a jim odpovídajících teplot ve stupních Celsia:

0 -17

20 -6

40 4

60 15

80 26

100 37

120 48

140 60

160 71

180 82

200 93

220 104

240 115

260 126

280 137

300 148 Samotný program stále obsahuje definici funkce main. Ta je delší, než tomu bylo vminulém příkladu, ale není komplikovaná. Zavádí několik nových myšlenek, včetněkomentářů, deklarací, proměnných, aritmetických výrazů, cyklů a formátovaného výstupu.

#include <stdio.h>

/* vypíše tabulku Fahrenheit-Celsius pro fahr = 0, 20, ..., 300 */

main()

{

int fahr, celsius;

int dolni, horni, krok;

dolni = 0; /* spodní mez tabulky teplot */

horni = 300; /* horní mez */

krok = 20; /* velikost kroku */

fahr = dolni;

while ( fahr <= horni) {

celsius = 5 * (fahr-32) / 9;

printf(“%d %d“, fahr, celsius);

fahr = fahr + krok;

}

} Řádek

/* vypíše tabulku Fahrenheit-Celsius pro fahr = 0, 20, ..., 300 */ 24

Proměnné a aritmetické výrazy


je komentář, který v tomto případě stručně vysvětluje, co program dělá. Kompilátorvšechny znaky mezi /* a */ ignoruje; zde lze napsat cokoli, co usnadní pochopení programu.

Komentáře se mohou objevit kdekoli, kde se může objevit mezera, tabulátor nebo nový

řádek.

V C musí být všechny proměnné před použitím deklarovány, obvykle na začátku funkce

před prvním vykonatelným příkazem. Deklarace oznamuje vlastnosti proměnných; skládá

se ze jména typu a seznamu proměnných, například

int fahr, celsius;

int dolni, horni, krok; Typ int vyjadřuje, že uvedené proměnné jsou celočíselné. Naproti tomu typ floatoznačuje čísla s pohyblivou řádovou čárkou, tedy čísla s desetinnou částí. Rozsah int a float závisí na použitém počítači; stejně často narazíte na 16bitový int, jehož hodnoty leží mezi -32768 a +32767, jako na 32bitový typ int. Číslo typu float je obvykle 32bitové s alespoň šesti významnými číslicemi a s řádem obvykle mezi 10

-38

a10

+38

.

Kromě int a float nabízí jazyk C několik dalších datových typů, mimo jiné:

char znak – jeden bajt

short krátké celé číslo

long dlouhé celé číslo

double číslo s pohyblivou řádovou čárkou s dvojitou přesností Velikost těchto objektů je také strojově závislá. Stejně tak existují pole, struktury a unie těchto základních typů, ukazatele na ně a funkce vracející hodnoty těchto typů. Se všemi se postupně seznámíme. Výpočet v programu pro konverzi teplot začíná přiřazovacími příkazy

dolni = 0;

horni = 300;

krok = 20;

fahr = dolni; které nastavují počáteční hodnoty proměnných. Jednotlivé příkazy jsou ukončenystředníky. Všechny řádky tabulky se počítají stejným způsobem, takže použijeme cyklus, který se zopakuje jednou pro každý řádek výstupu; o to se postará příkaz while

while (fahr <= horni) {

...

} Cyklus while funguje takto: Otestuje se podmínka v závorkách. Je-li splněna (hodnota fahr je menší nebo rovna horni), je vykonáno tělo cyklu (tři příkazy uzavřené ve složených závorkách). Pak je opětovně testována podmínka, a je-li splněna, je znovu vykonáno tělo cyklu. Jakmile se při testování zjistí, že podmínka není splněna (fahr je větší než horni), cyklus skončí a výpočet pokračuje příkazem, který následuje za cyklem. V našemprogramu žádné další příkazy nejsou, proto program skončí. Tělo cyklu while může tvořit jeden nebo několik příkazů uzavřených ve složenýchzávorkách, jako je tomu v případě programu pro převod teplot, nebo jediný příkaz bezsložených závorek, například

while (i < j)

i = 2 * i;

Kapitola 1 – Úvodní kurz

25


A už nastane kterýkoli z obou případů, vždy budeme odsazovat příkazy řízené cyklem

while o jeden tabulátor, aby bylo okamžitě zřejmé, které příkazy leží uvnitř cyklu.Odsazení zvýrazňuje logické členění programu. I když kompilátory jazyka C nehledí na to, jak

program vypadá, správné odsazení a rozmístění rozhoduje o tom, bude-li program snadno

čitelný. Pro jasnější vyjádření souvislostí doporučujeme psát pouze jeden příkaz na řádek

a používat mezery okolo operátorů. Méně důležitá je pozice složených závorek. My jsme

si vybrali jeden z několika populárních stylů. Zvolte si styl, který vyhovuje vám, a pak se

ho držte.

Většinu práce odvádí tělo cyklu. Teplota ve stupních Celsia je vypočítána a přiřazenaproměnné celsius příkazem

celsius = 5 * (fahr-32) / 9; Důvod pro násobení pěti a dělení devíti namísto jednoduchého násobení zlomkem 5/9 je, že v C, stejně jako v mnoha jiných jazycích, celočíselné dělení ořezává: desetinná(zlomková) část výsledku je zahozena. Protože 5 a 9 jsou celá čísla, 5/9 by bylo oříznuto na nulu a všechny teploty ve stupních Celsia by byly vypsány jako nulové. Tento příklad také ukazuje další z principů fungování funkce printf. printf jeuniverzální funkce pro formátování výstupu, kterou detailně rozebereme v sedmé kapitole. Jako první argument přijímá řetězec znaků, kde každý znak % označuje místo, kam má býtvložen některý z dalších (druhý, třetí,...) argumentů, a určuje, v jakém formátu má být vypsán. Například %d určuje celočíselný argument, takže příkaz

printf(“%d %d“), fahr, celsius); zajistí vypsání dvou celočíselných proměnných fahr a celsius oddělených tabulátorem ( ). Každá konstrukce se znakem % v prvním argumentu funkce printf je spárována sodpovídajícím druhým argumentem, třetím argumentem atd.; musí si navzájem odpovídat typem, jinak dostaneme nesprávné výsledky. Mimochodem, printf není součástí jazyka C; v samotném C není definován žádný vstup nebo výstup. printf je pouze užitečná funkce ze standardní knihovny, která je programům v jazyce C běžně přístupná. Nicméně její chování je definováno standardem ANSI, takže by měla mít stejné vlastnosti v jakémkoli kompilátoru a v jakékoli knihovně, které standardu odpovídají. Abychom se mohli soustředit na samotný jazyk C, nebudeme se až do sedmé kapitolyvstuem a výstupem příliš zabývat. Zejména do té doby odložíme problematikuformátovaného vstupu. Potřebujete-li zadávat čísla, přečtěte si oddíl 7.4 pojednávající o funkci scanf. scanf je funkce podobná printf s tím rozdílem, že čte vstup namísto vypisování výstupu. Program konverze teplot není zdaleka dokonalý. Jedním z nejmenších problémů je, že výstup nevypadá příliš dobře, čísla nejsou zarovnána vpravo. To lze snadno napravit; pokud rozšíříme každý zápis %d v příkazu printf o šířku. Například můžeme říct

printf(“%3d %6d“, fahr, celsius); a vytisknout první číslo na každém řádku v poli o šířce tří číslic a druhé v poli o šířce šesti číslic:

0 -17

20 -6

40 4

60 15

26

Proměnné a aritmetické výrazy


80 26

100 37

... Nejzávažnějším problémem je malá přesnost teplot ve stupních Celsia způsobená tím, že jsme použili celočíselnou aritmetiku; například 0 ̊F je ve skutečnosti zhruba -17,8 ̊C, ne -17. Pro přesnější výsledky bychom měli namísto celočíselné aritmetiky použít aritmetiku pohyblivé řádové čárky. To vyžaduje jisté změny v programu. Zde je jeho druhá verze:

#include <stdio.h>

/* vypíše tabulku Fahrenheit-Celsius pro fahr = 0, 20, ..., 300; verze

s pohyblivou desetinnou čárkou */

main()

{

float fahr, celsius;

int dolni, horni, krok;

dolni = 0; /* spodní mez tabulky teplot */

horni = 300; /* horní mez */

krok = 20; /* velikost kroku */

fahr = dolni;

while (fahr <= horni) {

celsius = (5.0/9.0) * (fahr-32.0);

printf(“%3.0f %6.1f“, fahr, celsius);

fahr = fahr + krok;

}

} Program je skoro stejný jako v předchozím případě, pouze proměnné fahr a celsius jsou deklarovány jako float a vzorec pro konverzi je zapsán přirozenějším způsobem. Vpředchozí verzi jsme nemohli použít 5/9 kvůli celočíselnému dělení, jehož výsledkem by byla nula. Desetinná tečka v konstantě indikuje, že jde o číslo s pohyblivou řádovou čárkou. To znamená, že výsledek výrazu 5.0/9.0 není oříznut, protože jde o dělení dvou hodnot s pohyblivou řádovou čárkou. Má-li aritmetický operátor celočíselné operandy, proběhne celočíselná operace. Má-li však aritmetický operátor jeden operand s pohyblivou řádovou čárkou a druhý celočíselný, bude celočíselný operand před vykonáním operace převeden na číslo s pohyblivouřádovou čárkou. Pokud bychom například napsali fahr – 32, pak by 32 bylo automatickypřevedeno na číslo s pohyblivou řádovou čárkou. Nicméně zapisování konstant s pohyblivou řádovou čárkou s explicitními desetinnými místy i v případech, kdy mají celočíselnéhodnoty, zvýrazňuje jejich podstatu pro lidské čtenáře. Detailní pravidla, kdy jsou celá čísla převáděná na čísla s pohyblivou desetinnou čárkou, jsou uvedena ve druhé kapitole. Prozatím si zapamatujte, že i přiřazení

fahr = dolni; a test

while (fahr <= horni) fungují přirozeným způsobem – int je před vykonáním operace konvertován na float.

Kapitola 1 – Úvodní kurz

27


Specifikace konverze %3.0f ve funkci printf říká, že číslo s pohyblivou řádovou čárkou

(v našem případě fahr) bude vypsáno v šířce minimálně tří znaků, bez desetinné tečky

a bez desetinných míst. %6.1f popisuje jiné číslo (celsius), které bude vypsáno v šířce

minimálně šesti znaků, s jedním desetinným místem. Výstup pak vypadá následovně:

0 -17.8

20 -6.7

40 4.4

... Ze specifikace lze vypustit šířku i přesnost: %6f určuje výpis čísla minimálně šest znaků široký; %.2f vyžaduje dvě desetinná místa za desetinnou čárkou, ovšem bez určení šířky; a %f jednoduše říká, že se dané číslo vytiskne jako číslo s pohyblivou desetinnou čárkou.

%d vypiš jako celé číslo v desítkové soustavě

%6d vypiš jako celé číslo v desítkové soustavě v šířce alespoň šesti znaků

%f vypiš jako číslo s pohyblivou řádovou čárkou

%6f vypiš jako číslo s pohyblivou řádovou čárkou v šířce alespoň šesti znaků

%.2f vypiš jako číslo s pohyblivou řádovou čárkou se dvěma místy za desetinnou tečkou

%6.2f vypiš jako číslo s pohyblivou řádovou čárkou v šířce alespoň šesti znaků a se dvěma

místy za desetinnou tečkou

Funkce printf mimo jiné rozeznává %o pro čísla v osmičkové soustavě, %x pro čísla všestnáctkové soustavě, %c pro znaky, %s pro znakové řetězce a %% pro samotný znak %.

Cvičení 1.3. Upravte program pro konverzi teplot tak, aby vypisoval nad tabulkou nadpis.

Cvičení 1.4. Napište program, který vypíše odpovídající tabulku pro převod ze stupňůCelsia na Fahrenheita.

1.3 Příkaz for

Existuje mnoho různých způsobů, jak napsat program pro konkrétní problém. Zkusme

variaci konvertoru teplot.

#include <stdio.h>

/* vypíše tabulku Fahrenheit-Celsius */

main()

{

int fahr;

for(fahr = 0; fahr <= 300, fahr = fahr + 20)

printf(“%3d %6.1f “, fahr, (5.0/9.0)*(fahr-32));

} Tento program vyprodukuje stejný výstup, ale zjevně vypadá jinak. Jednou z hlavních změn je eliminace většiny proměnných; zůstává pouze fahr a ten jsme změnili na int. Horní a spodní meze i hodnota kroku se objevují pouze jako konstanty v příkazu for, což je pro nás nová konstrukce. Výraz vypočítávající teplotu ve stupních Celsia se nyníobjevuje jako třetí argument funkce printf, a ne jako samostatný přiřazovací příkaz, jak tomu bylo dosud. Tato poslední změna je příkladem obecného pravidla – v jakémkoli kontextu, v němž je povoleno použít hodnotu proměnné nějakého typu, můžeme použít komplikovanější výraz 28

Příkaz for


stejného typu. Protože třetím argumentem funkce printf musí být číslo s pohyblivouřádovou čárkou, aby odpovídalo specifikaci %6.1f, může se zde objevit jakýkoli výraz spohyblivou řádovou čárkou.

Příkaz for je cyklus; je to zobecnění příkazu while. Porovnáte-li jej s while zpředchozího příkladu, mělo by vám být jasné, jak funguje. Prostor mezi závorkami je rozdělen na tři

části oddělené středníky. První část, inicializace

fahr = 0 se vykoná pouze jednou před vstupem do cyklu. Druhou částí je test nebo podmínka, která řídí cyklus:

fahr <= 300 Tato podmínka je vyhodnocena; je-li výsledkem pravda, je vykonáno tělo cyklu (v tomto případě samotný příkaz printf). Pak proběhne inkrementace

fahr = fahr + 20 a je znovu vyhodnocena podmínka. Jestliže podmínka přestane platit, cyklus skončí.Stejně jako u while může tělem cyklu být jediný příkaz nebo skupina příkazů uzavřená vesložených závorkách. Jako inicializaci, podmínku nebo inkrementaci lze použít jakýkoli výraz. Záleží čistě na nás, rozhodneme-li se pro while či for. for se obvykle používá vpřípadech, kdy inicializace i inkremetace tvoří jednoduché a logicky spřízněné příkazy, protože je kompaktnější a sdružuje příkazy řídící cyklus na jednom místě. Cvičení 1.5. Upravte program pro konverzi teplot tak, aby tiskl tabulku v opačnémpořadí, tj. od 300 stupňů do 0. 1.4 Symbolické konstanty Poslední postřeh, než opustíme konverzi teplot. Je špatnou praxí rozsévat v programu „magická čísla“ jako je 300 či 20; komukoli, kdo by mohl číst program v budoucnu,poskytují jen velice málo informací a je obtížné je měnit systematickým způsobem. Jeden zezpůsobů, jak pracovat s magickými čísly, je dát jim smysluplná jména. Řádek #define definuje symbolické jméno nebo symbolickou konstantu jako konkrétní řetězec znaků:

#define jméno nahrazující text Odte bude jakýkoli výskyt jména (které se nenachází v uvozovkách a není součástíjiného jména) nahrazen odpovídajícím nahrazujícím textem. Toto jméno má stejnou formu jako jméno proměnné: je to posloupnost písmen a číslic začínající písmenem. Nahrazující text může být posloupností jakýchkoli znaků; není omezen jen na čísla.

#include <stdio.h>

#define DOLNI 0 /* dolní mez tabulky */

#define HORNI 300 /* horní mez */

#define KROK 20 /* velikost kroku */

/* vypíše tabulku Fahrenheit-Celsius */

main()

{

int fahr;

Kapitola 1 – Úvodní kurz

29


for (fahr = DOLNI; fahr <= HORNI; fahr = fahr + KROK)

printf(“%3d %6.1f “, fahr, (5.0/9.0)*(fahr-32));

} Veličiny DOLNI, HORNI a KROK jsou symbolické konstanty, nikoli proměnné, takže senenachází v deklaracích. Jména symbolických konstant se obvykle píší velkými písmeny, takže je lze snadno rozlišit od jmen proměnných psaných malými písmeny. Všimněte si, že na konci řádku #define není středník. 1.5 Znakový vstup a výstup Nyní probereme skupinu příbuzných programů pro zpracovávání znakových dat. Zjistíte, že mnohé programy jsou pouze rozšířenými verzemi prototypů, které zde probíráme. Model vstupu a výstupu podporovaný standardní knihovnou je velice jednoduchý. Stextovým vstupem i výstupem je nakládáno jako s proudem znaků bez ohledu na to, odkud



       
Knihkupectví Knihy.ABZ.cz - online prodej | ABZ Knihy, a.s.
ABZ knihy, a.s.
 
 
 

Knihy.ABZ.cz - knihkupectví online -  © 2004-2018 - ABZ ABZ knihy, a.s. TOPlist