A C programozási nyelv

 

BRIAN W. KERNIGHAN – DENNIS M. RITCHIE

A C programozási nyelv

Az ANSI szerint szabványosított változat

MŰSZAKI KÖNYVKIADÓ, BUDAPEST
A könyv „A Magyar Műszaki Könyvkiadásért Alapítvány” támogatásával készült.
Az eredeti mű:
B. W. Kernighan – D. M. Ritchie
The C Programming Language
Second Edition
Original English language edition published by
Copyright © 1988, 1978 by Bell Telephone Laboratories, Incorporated
All Rights Reserved© Hungarian translation Molnár Ervin, 1994
© Hungarian edition Műszaki Könyvkiadó

ETO: 519.682 C
ISBN 963 16 0552 3

Kiadja a Műszaki Könyvkiadó
Felelős kiadó: Bérezi Sándor ügyvezető igazgató
Felelős szerkesztő: Molnár Ervin
Franklin Nyomda és Kiadó Kft.
Felelős vezető: a nyomda ügyvezető igazgatója
Műszaki szerkesztő: Uszinger Ágnes
A borítót tervezte: Kováts Tibor
A könyv formátuma: B/5
Ívterjedelme: 26,75 (A5)
Azonossági szám: 10 220/50
A kézirat lezárva: 1996. szeptember
Készült az MSZ 5601:1983 és 5602:1983 szerint

Tartalom

 

Előszó az átdolgozott könyv magyar nyelvű kiadásához
Előszó az angol nyelvű második kiadáshoz
Előszó a könyv angol nyelvű első kiadásához
Bevezetés

1. FEJEZET: Alapismeretek

1.1. Indulás
1.2. Változók és aritmetikai kifejezések
1.3. A for utasítás
1.4. Szimbolikus állandók
1.5. Karakteres adatok bevitele és kivitele
1.6. Tömbök
1.7. Függvények
1.8. Argumentumok – az érték szerinti hívás
1.9. Karaktertömbök
1.10. A változók érvényességi tartománya és a külső változók

2. FEJEZET: Típusok, operátorok és kifejezések

2.1. Változónevek
2.2. Adattípusok és méretek
2.3. Állandók
2.4. Deklarációk
2.5. Aritmetikai operátorok
2.6. Relációs és logikai operátorok
2.7. Típuskonverziók
2.8. Inkrementáló és dekrementáló operátorok
2.9. Bitenkénti logikai operátorok
2.10. Értékadó operátorok és kifejezések
2.11. Feltételes kifejezések
2.12. A precedencia és a kifejezés kiértékelési sorrendje

3. FEJEZET: Vezérlési szerkezetek

3.1. Utasítások és blokkok
3.2. Az if-else utasítás
3.3. Az else-if utasítás
3.4. A switch utasítás
3.5. Ciklusszervezés while és for utasítással
3.6. Ciklusszervezés do-while utasítással
3.7. A break és continue utasítások
3.8. A goto utasítás és a címkék

4. FEJEZET: Függvények és a program szerkezete

4.1. A függvényekkel kapcsolatos alapfogalmak
4.2. Nem egész értékkel visszatérő függvények
4.3. A külső változók
4.4. Az érvényességi tartomány szabályai
4.5. A header állományok
4.6. A statikus változók
4.7. Regiszterváltozók
4.8. Blokkstruktúra
4.9. Változók inicializálása
4.10. Rekurzió
4.11. A C előfeldolgozó rendszer

5. FEJEZET: Mutatók és tömbök

5.1. Mutatók és címek
5.2. Mutatók és függvényargumentumok
5.3. Mutatók és tömbök
5.4. A címaritmetika
5.5. Karaktermutatók és függvények
5.6. Mutatótömbök és mutatókat megcímző mutatók
5.7. Többdimenziós tömbök
5.8. Mutatótömbök inicializálása
5.9. Mutatók és többdimenziós tömbök
5.10. Parancssor-argumentumok
5.11. Függvényeket megcímző mutatók
5.12. Bonyolultabb deklarációk

6. FEJEZET: Struktúrák

6.1. Alapfogalmak
6.2. Struktúrák és függvények
6.3. Struktúratömbök
6.4. Struktúrákat kijelölő mutatók
6.5. Önhivatkozó struktúrák
6.6. Keresés táblázatban
6.7. A typedef utasítás
6.8. Unionok
6.9. Bitmezők

7. FEJEZET: Adatbevitel és adatkivitel

7.1. A standard adatbevitel és adatkivitel
7.2. A formátumozott adatkivitel – a printf függvény
7.3. A változó hosszúságú argumentumlisták kezelése
7.4. Formátumozott adatbevitel – a scanf függvény
7.5. Hozzáférés adatállományokhoz
7.6. Hibakezelés – az stderr és exit függvények
7.7. Szövegsorok beolvasása és kiírása
7.8. További könyvtári függvények

8. FEJEZET: Kapcsolódás a UNIX operációs rendszerhez

8.1. Az állományleírók
8.2. Alacsony szintű adatbevitel és adatkivitel – a read és write függvények
8.3. Az open, creat, close és unlink rendszerhívások
8.4. A véletlenszerű hozzáférés – az lseek függvény
8.5. Példa: az fopen és getc függvények megvalósítása
8.6. Példa: katalógusok kiíratása
8.7. Példa: tárterület-lefoglaló program

A. FÜGGELÉK: Referencia-kézikönyv

A1. Bevezetés
A2. Lexikális megállapodások

A2.1. Szintaktikai egységek
A2.2. Megjegyzések
A2.3. Azonosítók
A2.4. Kulcsszavak
A2.5. Állandók
A2.6. Karaktersorozat-állandók

A3. A szintaxis jelölése
A4. Az azonosítók értelmezése

A4.1. A tárolási osztály
A4.2. Alapvető adattípusok
A4.3. Származtatott adattípusok
A4.4. Típusminősítők

A5. Az objektumok és a balérték
A6. Típuskonverziók

A6.1. Az egész-előléptetés
A6.2. Egészek konverziója
A6.3. Egész és lebegőpontos mennyiségek
A6.4. Lebegőpontos típusok konverziója
A6.5. Aritmetikai típuskonverziók
A6.6. Mutatók és egész mennyiségek
A6.7. A void típus
A6.8. A void típushoz tartozó mutatók

A7. Kifejezések

A7.1. Mutatógenerálás
A7.2. Elsődleges kifejezések
A7.3. Utólagos kifejezések
A7.4. Egyoperandusú operátorok
A7.5. Kényszerített típusmódosító
A7.6. Multiplikatív operátorok
A7.7. Additív operátorok
A7.8. Léptető operátorok
A7.9. Relációs operátorok
A7.10. Egyenlőségoperátorok
A7.11. Bitenkénti ÉS operátor
A7.12. Bitenkénti kizáró VAGY operátor
A7.13. Bitenkénti inkluzív VAGY operátor
A7.14. Logikai ÉS operátor
A7.15. Logikai VAGY operátor
A7.16. Feltételes operátor
A7.17. Értékadó kifejezések
A7.18. Vesszőoperátor
A7.19. Állandó kifejezések

A8. Deklarációk

A8.1. Tárolásiosztály-specifikátorok
A8.2. Típusspecifikátorok
A8.3. Struktúrák és unionok deklarációja
A8.4. Felsorolások
A8.5. Deklarátorok
A8.6. A deklarátorok jelentése
A8.7. Kezdetiérték-adás
A8.8. Típusnevek
A8.9. A typedef
A8.10. Típusekvivalenciák

A9. Utasítások

A9.1. Címkézett utasítások
A9.2. Kifejezésutasítások
A9.3. Összetett utasítás
A9.4. Kiválasztó utasítások
A9.5. Iterációs utasítások
A9.6. Vezérlésátadó utasítások

A10. Külső deklarációk

A10.1. Függvénydefiníciók
A10.2. Külső deklarációk

A11. Érvényességi tartomány és csatolás

A11.1. Lexikális érvényességi tartomány.
A11.2. Csatolás

A12. Az előfeldolgozó rendszer

A12.1. Trigráf karaktersorozatok
A12.2. Sorok egyesítése
A12.3. Makrók definíciója és kifejtése
A12.4. Állományok beépítése
A12.5. Feltételes fordítás
A12.6. Sorvezérlés
A12.7. Hibaüzenet generálása
A12.8. A pragma direktíva
A12.9. A nulldirektíva
A12.10. Előre definiált nevek

A13. A C nyelv szintaktikájának összefoglalása

B. FÜGGELÉK: A standard könyvtár

B1. Adatbevitel és adatkivitel: az <stdio.h> header

B1.1. Állománykezelő műveletek
B1.2. Formátumozott adatkivitel
B1.3. Formátumozott adatbevitel
B1.4. Karakteres adatbevitelt és adatkivitelt kezelő függvények
B1.5. A közvetlen adatbevitel és adatkivitel függvényei
B1.6. Állományon belül pozicionáló függvények
B1.7. Hibakezelő függvények

B2. Karakteres vizsgálatok: a <ctype.h> header
B3. Karaktersorozat-kezelő függvények: a <string.h> header
B4. Matematikai függvények: a <math.h> header
B5. Kiegészítő rendszerfüggvények: az <stdlib.h> header
B6. Programdiagnosztika: az <assert.h> header
B7. Változó hosszúságú argumentumlisták kezelése: az <stdarg.h> header
B8. Nem lokális vezérlésátadások: a <setjmp.h> header
B9. Jelzések kezelése: a <signal.h> header
B10. Dátumot és időt kezelő függvények: a <time.h> header
B11. A gépi megvalósításban definiált határértékek: a <limits.h> és <float.h> headerek

C. FÜGGELÉK: A C nyelv szabvány bevezetéséből adódó változásai


Előszó az átdolgozott könyv magyar nyelvű kiadásához

A könyv fordítójával és szerkesztőjével együtt több más számítógépes szakember is Kernighan-Ritchie: A C programozási nyelv című könyvéből sajátította el a C nyelv alapjait. A sikert jelzi, hogy szakmai körökben a „C könyv” hivatkozás mindenki számára egyértelműen Kernighan és Ritchie könyvét jelentette, valamint az is, hogy az 1978-as angol kiadás után 1985-ben megjelent első magyar nyelvű kiadást még két további követte.A szerzők tevőleges részvételével az ANSI a C nyelvet 1989-ben szabványosította, ami – a C nyelv filozófiáját változatlanul hagyva – számos módosítással járt. A szerzők emiatt úgy döntöttek, hogy az új szabályok és lehetőségek figyelembevételével könyvüket átírják és kibővítik. Ennek a javított kiadásnak a magyar nyelvű változatát adjuk most közre. A könyv új, javított és átdolgozott kiadása valóban jobb, teljesebb és használhatóbb a korábbinál, és mindezek alapján várható, hogy újabb programozógenerációk tankönyve és munkájuk során kézikönyve lesz.

Előszó az angol nyelvű második kiadáshoz

A számítástechnikában jelentős forradalom ment végbe A C programozási nyelv című könyv első, 1978-as megjelenése óta: a nagy teljesítményű számítógépek még nagyobb teljesítményűek lettek és a személyi számítógépek teljesítőképessége megközelítette az egy évtizeddel korábbi nagy számítógépekét. Az eltelt időszakban a C programozási nyelv is megváltozott – bár csak kisebb mértékben – és már lényegesen szélesebb körben használatos, mint kezdetben, amikor a UNIX operációs rendszer nyelve volt.A C növekvő népszerűsége, a nyelv elmúlt időszakban bekövetkezett fejlődése és a különböző C fordítók nem kellően átgondolt megvalósítása igazolja a nyelv első kiadásához képest pontosabb és korszerűbb definiálásának szükségességét. 1983-ban az Amerikai Nemzeti Szabványügyi Hivatal (ANSI) létrehozott egy bizottságot, amelynek feladata „a C nyelv egyértelmű és géptől független definiálása” volt, megtartva annak alapfilozófiáját. A munka eredménye a C nyelv ANSI szabványa lett.

A szabványos megfogalmazásra – különösen a struktúrák értékadása és kiértékelése vonatkozásában – az első kiadás már utalt, de a részletes leírást nem tartalmazta. A szabványos megfogalmazás egy új függvénydeklarálási módot tartalmaz, ami lehetővé teszi a definíciók keresztellenőrzését. Az új megfogalmazás egy standard könyvtárat is kijelöl, amelyben a be- és kivitelt kezelő függvények, a tárkezelési eljárások, karakterláncokat kezelő függvények és más, hasonló közhasznú eljárások találhatók. Az új kiadásban pontosan megadjuk az egyes nyelvi elemek viselkedését, és ezzel egy időben explicit módon megadjuk, hogy a nyelv mely vonatkozásai maradnak géptől függetlenek.

A C programozási nyelv második kiadása a C nyelvnek az ANSI szabványban definiált leírását tartalmazza. Bár megjelöltük azokat a helyeket, ahol a nyelv megváltozott, mégis a könyv megírásához kizárólag az új megfogalmazás szerinti írásmódot választottuk. A legtöbb helyen ez nem okoz számottevő eltérést és a legszembetűnőbb változást főleg a függvénydeklarációk és -definíciók mutatják. A modern C fordítóprogramok már támogatják a szabvány legtöbb jellegzetességét.

Ebben a kiadásban is megpróbáltuk megtartani az első kiadás tömörségét. A C nem egy „nagy” nyelv, nem igényel terjedelmes könyvet. Az új kiadásban igyekeztünk jobban megvilágítani a C nyelvű programozásban központi szerepet játszó kritikusabb elemeket, mint pl. a mutatókat. Az eredeti példákat szintén finomítottuk, ill. sok fejezethez új példákat is adtunk, így például a bonyolult deklarációk kezelésével foglalkozó részt programokkal bővítettük, hogy a deklarációkat szavakba öntsük, ill. a leírást példaprogramokkal illusztráljuk. Csakúgy, mint az első kiadásban, az összes példát számítógéppel olvasható formában készítettük el és közvetlenül a szövegből kiemelve ellenőriztük.

A könyv A. Függeléke a referencia-kézikönyv, ami nem maga a szabvány, de mégis összetömörítve tartalmazza a lényeget. Ez azt jelenti, hogy a programozó számára könnyen érthető, de egy fordítóprogram írásához definícióként nem használható – ezt a szerepet csak a szabvány töltheti be megfelelően. A B. Függelék a standard könyvtár jellemzőinek összefoglalása, és szintén csak programozói referenciaként használható, nem pedig az implementáláshoz. A C. Függelék az eredeti C változathoz képesti változásokat tartalmazza.

Mint azt az első kiadás előszavában már elmondtuk, a C nyelvet – megismerése után – egyre szívesebben használják. Egy évtizeddel több tapasztalat birtokában még mindig ugyanez a véleményünk. Reméljük, hogy ez a könyv segíteni fog a C nyelv tanulásánál és hatékony alkalmazásánál.

Mély hálával tartozunk a könyv második kiadásának elkészítését segítő barátainknak. Jon Bentley, Doug Gwyn, Doug McIlroy, Peter Nelson és Rob Pike a nyers kézirat majdnem minden oldalához értékes tanácsokat és javaslatokat adtak. Hálásak vagyunk Al Ahónak, Dennis Allisonnak, Joe Campbellnek, G. R. Emlinnek, Karen Fortgangnak, Allen Holubnak, Andrew Hume-nak, Dave Kristolnak, John Lindermannak, Dave Prossernek, Gene Spaffordnak és Chris Van Wyknek a kézirat gondos átolvasásáért. Szintén köszönetet szeretnénk mondani Bill Cheswicknek, Mark Kernighannek, Andy Koenignek, Robin Lake-nek, Tom Londonnak, Jim Reedsnek, Clovis Tondonak és Peter Weinbergernek az értékes javaslataikért. Dave Prosser számos, az ANSI szabvánnyal kapcsolatos részletkérdést válaszolt meg. Széles körben használtuk Bjarne Stroustrup C++ fordítóprogramját a példaprogramok helyi ellenőrzéséhez, és Dave Kristol bocsátotta rendelkezésünkre ANSI C fordítóprogramját a végső ellenőrzéshez. Rich Drechsler nagy segítséget nyújtott a könyv szedésében.

Őszintén köszönjük mindannyiuk áldozatos munkáját.

Brian W. Kernighan
Dennis M. Ritchie

Előszó a könyv angol nyelvű első kiadásához

A C általános célú programozási nyelv, amelyre a tömör utasításformák, a bőséges utasításkészlet és a korszerű vezérlési és adatstruktúrák jellemzőek. A C sem egy nagyon magas szintű nyelv, sem egy „nagy” nyelv, és nem egy meghatározott alkalmazási területhez készült. Mindezek ellenére a megkötések hiánya és a teljesen általános jelleg miatt a C nyelv számos, magas szintű programozási nyelvvel támogatott alkalmazási területen is kényelmesen és hatékonyan használható.A C nyelvet eredetileg Dennis Ritchie a DEC PDP-11 UNIX operációs rendszeréhez tervezte, és a gép operációs rendszere, a C fordítóprogram, valamint az összes UNIX alkalmazói program (beleértve ezen könyv megírásához és nyomdai előkészítéséhez használt programot is) C nyelven íródott. A PDP-11-re írt változat után más gépekhez, pl. az IBM System/370-hez, a Honeywell 6000-hez és az Interdata 8/32-höz is elkészült a C fordítóprogram. Mivel a C nyelv nem kötődik egyetlen hardverhez vagy rendszerhez sem, ezért egyszerűen írhatunk olyan programokat, amelyek változtatás nélkül futtathatók bármelyik, C fordítóprogrammal ellátott gépen.

Könyvünk elsősorban azokat a tanulókat segíti, akik a C nyelvű programozást az Alapismeretek fejezet áttanulmányozása után máris megkezdhetik. A könyv további fejezetei a C nyelv főbb elemeit ismertetik, majd egy referencia-kézikönyv következik. Az egyes témakörök ismertetése elsősorban példaprogramok megértésén, írásán és módosításán alapszik, amit jobb módszernek tartunk, mint a szabályok tételes megfogalmazását. A példaprogramok többsége teljes, önálló program és nem pedig programrészlet. Az összes példát számítógéppel olvasható formában írtuk és közvetlenül a szövegből kiemelve ellenőriztük.

A nyelv hatékony használatának ismertetésén kívül – ahol lehetséges volt – igyekeztünk a stílusos, áttekinthető programozást segítő algoritmusokat és programozási elveket is bemutatni.

A könyv nem bevezető a programozástechnikába, hanem feltételezi, hogy az olvasó tisztában van olyan alapfogalmakkal, mint változó, értékadás, ciklus, függvény. Mindezek ellenére a könyvből a kezdő is elsajátíthatja a C nyelvű programozást, de esetenként szüksége lehet gyakorlottabb kollégái segítségére.

Tapasztalataink szerint a C nyelv számos alkalmazási terület programjainak kellemes, kifejező és rugalmas megfogalmazására alkalmas. Egyszerűen megtanulható, és elsajátítása után mindenki egyre szívesebben használja. Reméljük, hogy könyvünk jól fogja segíteni a C nyelv hatékony használatát.

A könyv megírása feletti örömünkhöz nagyban hozzájárultak barátaink hasznos kritikai megjegyzései és javaslatai. Különösen hálásak vagyunk Mike Bianchinak, Jim Blue-nak, Stu Feldmannak, Doug McIlroynak, Bill Roome-nak, Bob Rosinnak és Larry Roslernek a kézirat több változatának gondos átolvasásáért. Köszönetet kell mondanunk Al Ahónak, Steve Bourne-nek, Dan Dvoraknak, Chuck Haley-nek, Debbi Haley-nek, Marion Harrisnek, Rick Holtnak, Steve Johnsonnak, John Mashey-nek, Bob Mitzének, Ralph Muhának, Peter Nelsonnak, Elliot Pinsonnak, Bili Plaugernek, Jerry Spivacknak, Ken Thompsonnak és Peter Weinbergernek a különböző munkafázisokban adott hasznos tanácsaikért. Köszönjük Mike Lesknek és Joe Ossannának a kézirat szedésénél és nyomdai előkészítésénél nyújtott segítségüket.

Brian W. Kernighan
Dennis M. Ritchie

Bevezetés

A C olyan általános célú programozási nyelv, ami szorosan kapcsolódik a UNIX operációs rendszerhez, mivel magát az operációs rendszert és a felügyelete alatt futó programok többségét is C nyelven írták. Mindezek ellenére a nyelv nem kötődik szorosan egyetlen operációs rendszerhez vagy számítógéphez sem. A C nyelvet rendszerprogramozási nyelvnek is szokás nevezni, mivel jól használható fordítóprogramok és operációs rendszerek írására, de ugyancsak hatékonyan használható különböző területek alkalmazói programjainak írásához.A C nyelv fontosabb alapötleteinek többsége a Martin Richards által kidolgozott BCPL nyelvből ered. A BCPL C nyelvre gyakorolt hatása közvetetten, a B nyelven keresztül jelentkezik, amelyet Ken Thompson 1970-ben fejlesztett ki a DEC PDP-7 számítógépének első UNIX rendszeréhez. A BCPL és a B nyelvek „típus nélküli” nyelvek, ellentétben a C nyelvvel, amelyben számos adattípus alkalmazható. A C nyelv alapadattípusai a karakterek, valamint a különböző méretű egész és lebegőpontos számok. Ezekhez járul a származtatott adattípusok hierarchiája, amelyekbe a mutatók, tömbök, struktúrák és unionok tartoznak. A kifejezések operátorokból és operandusokból állnak, és bármely kifejezés – beleértve az értékadást vagy a függvényhívást is – lehet önálló utasítás. A mutatókkal végzett műveletekhez a nyelv egy géptől független címaritmetikát használ.

A C nyelv tartalmazza a strukturált programozáshoz szükséges vezérlési szerkezeteket: az összetartozó utasításokat egyetlen csoportba foglaló utasítás-zárójelet, a döntési szerkezetet (ifelse), a lehetséges esetek egyikének kiválasztását (switch), az elöltesztelt ciklust (while, for) és a hátultesztelt ciklust (do), valamint a ciklusból való feltétel nélküli kilépést (break).

A függvények értéke visszatéréskor az alapadattípusok egyike, ill. struktúra, union vagy mutató lehet. Bármely függvény rekurzívan hívható és lokális változói általában „automatikusak”, vagyis a függvény minden hívásakor újra generálódnak. A függvénydefiníciók nem ágyazhatók egymásba, de a változók blokkstruktúrában is definiálhatók. Egy C program függvényei önálló forrásállományban is elhelyezhetők és külön is fordíthatók. A függvények változói belső (internal), külső, de csak egyetlen forrásállományban ismert (external) vagy a teljes programban ismert (globális) típusúak lehetnek.

A C nyelvű programok fordításához egy előfeldolgozó menet is kapcsolódik, ami lehetővé teszi a program szövegében a makrohelyettesítést (más forrásállományokat is beleértve), valamint a feltételes fordítást.

A C viszonylag alacsony szintű nyelv. Ezt a kijelentést nem pejoratív értelemben használjuk, hanem egyszerűen csak azt akarjuk kifejezni vele, hogy a C nyelv – a legtöbb számítógéphez hasonlóan – karakterekkel, számokkal és címekkel dolgozik. Ezek az alapobjektumok az adott számítógépen értelmezett aritmetikai és logikai műveletekkel kombinálhatók és mozgathatók.

A C nyelv nem tartalmaz műveleteket az összetett objektumok (karakterláncok, halmazok, listák, tömbök) közvetlen kezelésére, vagyis hiányzanak a teljes tömb vagy karakterlánc manipulálására alkalmas műveletek, bár a struktúrák egy egységenkénti másolása megengedett. A nyelvben csak a statikus és a függvények lokális változóihoz használt verem típusú tárfoglalási lehetőség létezik, és nincs a más nyelvekben megszokott heap vagy garbage collection (a felszabaduló tárterületeket összegyűjtő és hasznosító mechanizmus) típusú dinamikus tárkezelés. Végül pedig a C nyelvben nincs adatbeviteli és adatkiviteli lehetőség, azaz nincs READ vagy WRITE utasítás, valamint nincsenek beépített állományelérési módszerek sem. Mindezeket a magasabb szintű tevékenységeket explicit függvényhívásokkal kell megvalósítani. A legtöbb C implementáció szerencsére már tartalmazza ezen tevékenységek megfelelő gyűjteményét, az ún. standard könyvtárat.

További jellemzője a C nyelvnek, hogy csak egy tevékenységi sorrendnek megfelelő vezérlő szerkezeteket – ellenőrzés, ciklus, utasításcsoport, alprogram – tartalmaz és nem teszi lehetővé a multiprogramozást, a párhuzamos műveletvégzést, a folyamatok szinkronizálását vagy a korutinok (párhuzamos rutinok) alkalmazását.

Bár ezen lehetőségek némelyikének hiánya komoly hiányosságnak tűnik („Két karakterlánc összehasonlításához egy függvény szükséges?”), a nyelv szigorú korlátozása valójában előnyös. Mivel a C viszonylag „kis” nyelv, ezért tömören leírható és gyorsan megtanulható. A programozótól elvárható, hogy ismerje és értse, valamint szabályosan használja a teljes nyelvet.

Éveken keresztül A C programozási nyelv első kiadásában szereplő referencia-kézikönyv volt a C nyelv definíciója. 1983-ban az Amerikai Nemzeti Szabványügyi Intézet (ANSI) létrehozott egy bizottságot a C nyelv modern, átfogó definiálására. Az így kapott definíció a C ANSI szabványa vagy röviden az ANSI C, amely 1988-ban vált teljessé. A modern fordítóprogramok ma már a szabvány előírásainak többségét támogatják.

A szabvány az eredeti referencia-kézikönyvön alapszik. A nyelv viszonylag keveset változott, mivel a szabvány megalkotásakor az egyik célkitűzés az volt, hogy a már meglévő programok többsége változatlanul használható legyen vagy ennek hiányában a fordítóprogram legalább figyelmeztessen a változásra.

A legtöbb programozó számára a legfontosabb eltérést a függvények deklarálásának és definiálásának megváltozott szintaktikája jelenti. A függvénydeklaráció új változata magában foglalja a függvény argumentumainak leírását. Ez a járulékos információ megkönnyíti a fordítóprogram számára az argumentumok hibás illesztéséből adódó hibák detektálását. Tapasztalataink szerint ez hasznos bővítése volt a nyelvnek.

Van néhány további, kisebb változás is a nyelvben: a struktúrák értékadása és kiértékelése, amelyet széles körben használtak, most a nyelv hivatalos részévé vált. A lebegőpontos számítások egyszeres (single) pontossággal is elvégezhetők. Az aritmetika tulajdonságait, különösen az előjel nélküli adattípusok esetén, tisztázta az új szabvány. Az előfeldolgozó (preprocesszor) rendszer sokkal kimunkáltabb lett. Ezen változások zöme csak kis mértékben érinti a legtöbb programozót.

A szabvány másik jelentős vonatkozása a C könyvtár kialakítása. Ez olyan függvényeket tartalmaz, amelyek többek között lehetővé teszik az operációs rendszerhez való hozzáférést (pl. állományok olvasása és írása), a formátumozott adatbevitelt és adatkivitelt, a tárkiosztás szervezését, a karakterláncokkal végzett műveleteket. Az ún. szabványos fejek (headerek) gyűjteménye lehetővé teszi a függvény- és adattípusdeklarációk egységes kezelését. Ezt a könyvtárat használó programok kompatibilis módon fognak együttműködni a befogadó rendszerrel. A könyvtár jelentős része a UNIX rendszer standard I/O könyvtárát modellezi. Ezt a könyvtárat a könyv első kiadásában már leírtuk, és széles körben használták más rendszerekhez is. A legtöbb programozó ebben sem talál sok változást.

Mivel a C nyelvben alkalmazott adattípusok és vezérlési szerkezetek alkalmazását a legtöbb számítógép közvetlenül támogatja, az önmagában zárt programok formájában megvalósított futtatási könyvtár kicsi. A standard könyvtár függvényeit csak explicit módon hívjuk, így minden további nélkül elhagyhatók, ha nincs szükség rájuk. A függvények többsége C nyelven íródott és – az operációs rendszerhez tartozó részek kivételével – más gépre is átvihető.

A C nyelv sokféle számítógép adottságaihoz illeszkedik, mégis bármilyen konkrét számítógép felépítésétől független, ezért viszonylag kis fáradsággal írhatunk hordozható, azaz változtatás nélkül különféle számítógépeken futtatható, C programokat. A szabvány a hordozhatóságot explicit módon megköveteli, és azon számítógép jellemzésére, amelyen a program futtatható egy paraméterhalmazt ír elő.

A C nem nevezhető erősen típusos nyelvnek, de a fejlődése során a típusellenőrzés erősödött. A C eredeti definíciója, eléggé el nem ítélhető módon, megengedte a mutatók és az egész típusú adatok keverését. Ezt a hiányosságot már régen kiküszöbölték, és a szabvány már megköveteli a megfelelő deklarációt és az explicit típuskonverziót, amit a jó fordítóprogramok ki is kényszerítenek. A függvénydeklaráció új formája a másik olyan lépés, ami a típusellenőrzés szigorodása irányába mutat. A fordítóprogramok a legtöbb típusillesztési hibára figyelmeztetnek és inkompatíbilis adatok között nincs automatikus típuskonverzió. Bárhogyan is nézzük, a C megtartotta az alapfilozófiáját, miszerint a programozónak csak tudnia kell, hogy mit csinál, és a C nyelv csak azt igényli, hogy a szándékát egyértelműen fogalmazza meg.

A C, hasonlóan más nyelvekhez, nem hibátlan. Némelyik művelet rossz precedencia szerint megy végbe és a szintaxis néhány helyen jobb is lehetne. Mindezek ellenére a C különböző programozási területeken rendkívül hatásos és kifejező nyelvnek bizonyult.

Végezetül még néhány szót szeretnénk szólni a könyv felépítéséről: az 1. fejezet a C nyelv főbb részeinek áttekintése, aminek az a célja, hogy az olvasó a lehető leghamarabb elkezdhesse a programok írását. Véleményünk szerint egy új nyelv megtanulásának legjobb módja, ha az adott nyelven programokat írunk. Az 1. fejezet feltételezi, hogy az olvasó rendelkezik az alapvető programozástechnikai ismeretekkel, ezért nem foglalkozunk azzal, hogy mi a számítógép vagy mi a fordítás, és nem magyarázzuk pl. az n=n+1 típusú kifejezések értelmezését sem. Ahol lehetőség volt rá, megpróbáltunk hasznos programozási módszereket bemutatni, de a könyvet nem az adatstruktúrák és algoritmusok kézikönyvének szántuk, így ahol kénytelenek voltunk választani, inkább a nyelv leírására helyeztük a hangsúlyt.

A 2-tól a 6. fejezetig terjedő részben az 1. fejezetben leírtaknál részletesebben és precízebben mutatjuk be a C nyelv egyes elemeit. A hangsúly itt is a teljes példaprogramokon van, az egyes elemeket illusztráló részletek helyett. A 2. fejezet az alapvető adattípusokkal, operátorokkal és kifejezésekkel foglalkozik. A 3. fejezet a vezérlési szerkezeteket (if-else, switch, while, for stb). tekinti át. A 4. fejezet témája a függvények és a program szerkezete, a külső változókkal és az érvényességi tartománnyal kapcsolatos problémák, valamint a több forrásállományú feldolgozás kérdései. Érintőlegesen itt tárgyaljuk az előfeldolgozó (preprocesszor) rendszert is. Az 5. fejezet a mutatókkal és a címaritmetikával, a 6. fejezet pedig a struktúrákkal és unionokkal foglalkozik.

A 7. fejezet témája az operációs rendszer felé közös csatlakozási felületet adó standard könyvtár. Ezt a könyvtárat az ANSI szabvány definiálja és minden C nyelv használatát lehetővé tevő számítógép támogatja, ezért az adatbevitelt és adatkivitelt, ill. más operációsrendszer-hívásokat tartalmazó programok változtatás nélkül átvihetők az egyik rendszerről a másikra.

A 8. fejezet a C nyelvű programok és a UNIX operációs rendszer közti kapcsolatot írja le, a hangsúlyt az adatbevitelre és -kivitelre, az állománykezelésre és a tárkiosztásra helyezve. A fejezet néhány része UNIX-specifikus, de más operációs rendszer alatt dolgozó programozók is haszonnal olvashatják, mivel megtudható belőle, hogy hogyan alakítható ki a standard könyvtár adott változata vagy hogyan érhető el a programok hordozhatósága.

Az A. Függelék a nyelv referencia-kézikönyve, és mint ilyen, tartalmazza a C nyelv szintaktikájának és szemantikájának ANSI szabvány szerinti hivatalos leírását. Ez a rész elsősorban a C fordítóprogramok írásához nyújt segítséget. A referencia-kézikönyv a nyelv definícióját nagyon tömör formában adja meg. A B. Függelék a standard könyvtárra vonatkozó ismeretek összefoglalása és szintén inkább a felhasználóknak, mint a könyvtárat megvalósítani akaróknak szól. A C. Függelék az ANSI szabvány eredeti nyelvtől való eltéréseit foglalja össze. Kétséges esetekben a szabványt és a saját fordítóprogramunkat tekintettük mérvadónak.

Tartalom 1. FEJEZET