Kernigan, Richi. YAzyk C YAZYK S B.V. Kernigan, D.M. Richi. Annotaciya YAzyk "C"(proiznositsya "si") - eto universal'nyj yazyk programmirovaniya, dlya kotorogo harakterny ekonomichnost' vyra- zheniya, sovremennyj potok upravleniya i struktury dannyh, boga- tyj nabor operatorov. YAzyk "C" ne yavlyaetsya ni yazykom "ochen' vysokogo urovnya", ni "bol'shim" yazykom, i ne prednaznachaetsya dlya nekotoroj special'noj oblasti primeneniya. No otsutstvie ogranichenij i obshchnost' yazyka delayut ego bolee udobnym i ef- fektivnym dlya mnogih zadach, chem yazyki, predpolozhitel'no bolee moshchnye. YAzyk "C", pervonachal'no prednaznachavshijsya dlya napisaniya operacionnoj sistemy "UNIX" na |VM DEC PDP-11, byl razrabo- tan i realizovan na etoj sisteme Dennisom Richi. Operacionnaya sistema, kompilyator s yazyka "C" i po sushchestvu vse prikladnye programmy sistemy "UNIX" (vklyuchaya vse programmnoe obespeche- nie, ispol'zovannoe pri podgotovke etoj knigi) napisany na "C". Kommercheskie kompilyatory s yazyka "C" sushchestvuyut takzhe na nekotoryh drugih |VM, vklyuchaya IBM SYSTEM/370, HONEYWELL 6000, INTERDATA 8/32. YAzyk "C", odnako, ne svyazan s kaki- mi-libo opredelennymi apparatnymi sredstvami ili sistemami, i na nem legko pisat' programmy, kotorye mozhno propuskat' bez izmenenij na lyuboj |VM, imeyushchej "C"-kompilyator. |ta kniga prednaznachena dlya togo, chtoby pomoch' chitatelyu nauchit'sya programmirovat' na yazyke "C". Ona soderzhit uchebnoe vvedenie, cel' kotorogo - pozvolit' novym pol'zovatelyam na- chat' programmirovat' kak mozhno bystree, otdel'nye glavy po vsem osnovnym osobennostyam yazyka i spravochnoe rukovodstvo. Obuchenie postroeno v osnovnom na chtenii, napisanii i razbore primerov, a ne goloj formulirovke pravil. Primery, privodi- mye v knige, po bol'shej chasti yavlyayutsya zakonchennymi real'ny- mi programmami, a ne otdel'nymi fragmentami. Vse primery by- li provereny neposredstvenno s teksta knigi, gde oni napecha- tany v vide, prigodnom dlya vvoda v mashinu. Krome ukazanij o tom, kak sdelat' ispol'zovanie yazyka bolee effektivnym, my takzhe pytalis', gde eto vozmozhno, proillyustrirovat' poleznye algoritmy i principy horoshego stilya i razumnoj razrabotki. Nastoyashchaya kniga ne yavlyaetsya vvodnym kursom v programmi- rovanie; ona predpolagaet opredelennoe znakomstvo s osnovny- mi ponyatiyami programmirovaniya takimi kak peremennye, opera- tory prisvaivaniya, cikly, funkcii. Tem ne menee i novichok v programmirovanii dolzhen okazat'sya v sostoyanii chitat' podryad i osvoit'sya s yazykom, hotya pri etom byla by poleznoj pomoshch' bolee opytnogo kollegi. Po nashemu opytu , "C" pokazal sebya priyatnym, vyrazi- tel'nym i raznostoronnim yazykom na shirokom mnozhestve razno- obraznyh programm. Ego legko vyuchit' , i on ne teryaet svoih kachestv s rostom opyta programmista. My nadeemsya , chto eta kniga pomozhet vam horosho ego ispol'zovat'. Vdumchivaya kritika i predlozheniya mnogih nashih druzej i kolleg ochen' mnogo dobavili kak dlya samoj knigi, tak i dlya nashego udovol'stviya pri ee napisanii. V chastnosti, Majk Bi- apsi, Dzhim Blyu, St'yu Fel'dman, Doug Mak-Ilroj, Bill Rum, Bob Rozin i Larri Rosler tshchatel'no prochitali mnozhestvo varian- tov. My takzhe obyazany |lyu Aho, Stivu Bornu, Devu Dvoraku, CHaku Heleyu, Debbi Helej, Marionu Harrisu, Riku Holtu, Stivu Dzhonsonu, Dzhonu Masheyu, Bobu Mitcu, Ral'fu M'yua, Piteru Nel'- sonu, |lliotu Pinsonu, Billu Plageru, Dzherri Spivaku, Kenu Tompsonu i Piteru Vejnbergeru za poleznye zamechaniya na raz- lichnyh etapah i Majku Losku i Dzho Osanna za neocenimuyu po- moshch' pri pechatanii knigi. Brajen V. Kernigan Dennis M. Richi Soderzhanie Annotaciya ........................................1 0.1. Vvedenie .......................................7 1. Uchebnoe vvedenie.................................. 1.1. Hachinaem....................................... 1.2. Peremennye i arifmetika........................ 1.3. Operator FOR................................... 1.4. Simvolicheskie konstanty........................ 1.5. Nabor poleznyh programm........................ 1.5.1. Vvod i vyvod simvolov........................ 1.5.2. Kopirovanie fajla............................ 1.5.3. Podschet simvolov............................. 1.5.4. Podschet strok................................ 1.5.5. Podschet slov................................. 1.6. Massivy........................................ 1.7. Funkcii........................................ 1.8. Argumenty - vyzov po znacheniyu.................. 1.9. Massivy simvolov............................... 1.10. Oblast' dejstviya: vneshnie peremennye........... 1.11. Rezyume......................................... 2. Tipy, operacii i vyrazheniya........................ 2.1. Imena peremennyh............................... 2.2. Tipy i razmery dannyh.......................... 2.3. Konstanty...................................... 2.3.1. Simvol'naya konstanta......................... 2.3.2. Konstantnoe vyrazhenie........................ 2.3.3. Strochnaya konstanta........................... 2.4. Opisaniya....................................... 2.5. Arifmeticheskie operacii........................ 2.6. Operacii otnosheniya i logicheskie operacii....... 2.7. Preobrazovanie tipov........................... 2.8. Operacii uvelicheniya i umen'sheniya............... 2.9. Pobitovye logicheskie operacii.................. 2.10. Operacii i vyrazheniya prisvaivaniya.............. 2.11. Uslovnye vyrazheniya............................. 2.12. Starshinstvo i poryadok vychisleniya............... 3. Potok upravleniya.................................. 3.1. Operatory i bloki.............................. 3.2. IF - ELSE...................................... 3.3. ELSE - IF...................................... 3.4. Pereklyuchatel'.................................. 3.5. Cikly - WHILE i FOR............................ 3.6. Cikl DO - WHILE................................ 3.7. Operator BREAK................................. 3.8. Operator CONTINUE.............................. 3.9. Operator GOTO i metki.......................... 4. Funkcii i struktura programm...................... 4.1. Osnovnye svedeniya.............................. 4.2. Funkcii, vozvrashchayushchie necelye znacheniya......... 4.3. Eshche ob argumentah funkcij...................... 4.4. Vneshnie peremennye............................. 4.5. Pravila, opredelyayushchie oblast' dejstviya......... 4.5.1. Oblast' dejstviya............................. 4.6. Staticheskie peremennye......................... 4.7. Registrovye peremennye......................... 4.8. Blochnaya struktura.............................. 4.9. Inicializaciya.................................. 4.10. Rekursiya....................................... 4.11. Preprocessor yazyka "C"......................... 4.11.1. Vklyuchenie fajlov............................. 4.11.2. Makropodstanovka............................. 5. Ukazateli i massivy............................ 5.1. Ukazateli i adresa............................. 5.2. Ukazateli i argumenty funkcij.................. 5.3. ukazateli i massivy............................ 5.4. Adresnaya arifmetika............................ 5.5. ukazateli simvolov i funkcii................... 5.6. Ukazateli - ne celye........................... 5.7. Mnogomernye massivy............................ 5.8. Massivy ukazatelej; ukazateli ukazatelej....... 5.9. Inicializaciya massivov ukazatelej.............. 5.10. Ukazateli i mnogomernye massivy................ 5.11. Komandnaya stroka argumentov.................... 5.12. Ukazateli na funkcii........................... 6. Struktury......................................... 6.1. Osnovnye svedeniya.............................. 6.2. Struktury i funkcii............................ 6.3. Massivy sruktur................................ 6.4. Ukazateli na struktury......................... 6.5. Struktury, ssylayushchiesya na sebya................. 6.6. Poisk v tablice................................ 6.7. Polya........................................... 6.8. Ob容dineniya.................................... 6.9. Opredelenie tipa............................... 7. Vvod i vyvod...................................... 7.1. Obrashchenie k standartnoj biblioteke............. 7.2. Standartnyj vvod i vyvod - funkcii GETCHAR i PUTCHAR...................................... 7.3. Formatnyj vyvod - funkciya PRINTF............... 7.4. Formatnyj vvod - funkciya SCANF................. 7.5. Formatnoe preobrazovanie v pamyati.............. 7.6. Dostup k fajlam................................ 7.7. Obrabotka oshibok - STDERR i EXIT............... 7.8. Vvod i vyvod strok............................. 7.9. Neskol'ko raznoobraznyh funkcij................ 7.9.1. Proverka vida simvolov i preobrazovaniya...... 7.9.2. Funkciya UNGETC............................... 7.9.3. Obrashchenie k sisteme.......................... 7.9.4. Upravlenie pamyat'yu........................... 8. Interfejs sistemy UNIX............................ 8.1. Deskriptory fajlov............................. 8.2. Nizkourovnevyj vvod/vyvod - operatory READ i WRITE........................................ 8.3. Otkrytie, sozdanie, zakrytie i rasceplenie (UNLINK)....................................... 8.4. Proizvol'nyj dostup - SEEK i LSEEK............. 8.5. Primer - realizaciya funkcij FOPEN i GETC....... 8.6. Primer - raspechatka spravochnikov............... 8.7. Primer - raspredelitel' pamyati................. Prilozhenie a: spravochnoe rukovodstvo po yazyku 'C'. 9.1. Vvedenie....................................... 10. Leksicheskie soglasheniya............................ 10.1. Kommentarii.................................... 10.2. Identifikatory (imena)......................... 10.3. Klyuchevye slova................................. 10.4. Konstanty...................................... 10.4.1. Celye konstanty.............................. 10.4.2. YAvnye dlinnye konstanty...................... 10.4.3. Simvol'nye konstanty......................... 10.4.4. Plavayushchie konstanty.......................... 10.5. Stroki......................................... 10.6. Harakteristiki apparatnyh sredstv.............. 11. Sintaksicheskaya notaciya............................ 12. CHto v imene tebe moem?............................ 13. Ob容kty i L-znacheniya.............................. 14. Preobrazovaniya.................................... 14.1. Simvoly i celye................................ 14.2. Tipy FLOAT i DOUBLE............................ 14.3. Plavayushchie i celochislennye velichiny............. 14.4. Ukazateli i celye.............................. 14.5. Celoe bez znaka................................ 14.6. Arifmeticheskie preobrazovaniya.................. 15. Vyrazheniya......................................... 15.1. Pervichnye vyrazheniya............................ 15.2. Unarnye operacii............................... 15.3. Mul'tiplikativnye operacii..................... 15.4. Additivnye operacii............................ 15.5. Operacii sdviga................................ 15.6. Operacii otnosheniya............................. 15.7. Operacii ravenstva............................. 15.8. Pobitovaya operaciya 'i'......................... 15.9. Pobitovaya operaciya isklyuchayushchego 'ili'.......... 15.10. Pobitovaya operaciya vklyuchayushchego 'ili'........... 15.11. Logicheskaya operaciya 'i'........................ 15.12. Operaciya logicheskogo 'ili'..................... 15.13. Uslovnaya operaciya.............................. 15.14. Operaciya prisvaivaniya.......................... 15.15. Operaciya zapyataya............................... 16. Opisaniya.......................................... 16.1. Specifikatory klassa pamyati.................... 16.2. Specifikatory tipa............................. 16.3. Opisateli...................................... 16.4. Smysl opisatelej............................... 16.5. Opisanie struktur i ob容dinenij................ 16.6. Inicializaciya.................................. 16.7. Imena tipov.................................... 16.8. TYPEDEF........................................ 17. Operatory......................................... 17.1. Pperatornoe vyrazhenie.......................... 17.2. Sostavnoj operator (ili blok).................. 17.3. Uslovnye operatory............................. 17.4. Operator WHILE................................. 17.5. Operator DO.................................... 17.6. Operator FOR................................... 17.7. Operator SWITCH................................ 17.8. Operator BREAK................................. 17.9. Operator CONTINUE.............................. 17.10. Operator vozvrata.............................. 17.11. Operator GOTO.................................. 17.12. Oomechennyj operator............................ 17.13. Oustoj operator................................ 18. Vneshnie opredeleniya............................... 18.1. Vneshnee opredelenie funkcii.................... 18.2. Vneshnie opredeleniya dannyh..................... 19. Pravila, opredelyayushchie oblast' dejstviya............ 19.1. Leksicheskaya oblast' dejstviya................... 19.2. Oblast' dejstviya vneshnih identifikatorov....... 20. Stroki upravleniya kompilyatorom.................... 20.1. Zamena leksem.................................. 20.2. Vklyuchenie fajlov............................... 20.3. Uslovnaya kompilyaciya............................ 21. Neyavnye opisaniya.................................. 22. Snova o tipah..................................... 22.1. Struktury i ob容dineniya........................ 22.2. Funkcii........................................ 22.3. Massivy, ukazateli i indeksaciya................ 22.4. YAvnye preobrazovaniya ukazatelej................ 23. Konstantnye vyrazheniya............................. 24. Soobrazheniya o perenosimosti....................... 25. Anahronizmy....................................... 26. Svodka sintaksicheskih pravil...................... 26.1. Vyrazheniya...................................... 26.2. Opisaniya....................................... 26.3. Operatory...................................... 26.4. Vneshnie opredeleniya............................ 26.5. Preprocessor................................... 27. Prisvaivanie struktury............................ 28. Tip perechisleniya.................................. 29. Tablica izobrazhenij nepechatnyh simvolov yazyka "C". 0.1. Vvedenie YAzyk "C" yavlyaetsya universal'nym yazykom programmirova- niya. On tesno svyazan s operacionnoj sistemoj "UNIX" , tak kak byl razvit na etoj sisteme i tak kak "UNIX" i ee prog- rammnoe obespechenie napisano na "C". Sam yazyk , odnako, ne svyazan s kakoj-libo odnoj operacionnoj sistemoj ili mashinoj; i hotya ego nazyvayut yazykom sistemnogo programmirovaniya, tak kak on udoben dlya napisaniya operacionnyh sistem, on s ravnym uspehom ispol'zovalsya pri napisanii bol'shih vychislitel'nyh programm, programm dlya obrabotki tekstov i baz dannyh. YAzyk "C" - eto yazyk otnositel'no "nizkogo urovnya". V takoj harakteristike net nichego oskorbitel'nogo; eto prosto oznachaet, chto "C" imeet delo s ob容ktami togo zhe vida, chto i bol'shinstvo |VM, a imenno, s simvolami, chislami i adresami. Oni mogut ob容dinyat'sya i peresylat'sya posredstvom obychnyh arifmeticheskih i logicheskih operacij, osushchestvlyaemyh real'- nymi |VM. V yazyke "C" otsutstvuyut operacii, imeyushchie delo nepos- redstvenno s sostavnymi ob容ktami, takimi kak stroki simvo- lov, mnozhestva, spiski ili s massivami, rassmatrivaemymi kak celoe. Zdes', naprimer, net nikakogo analoga operaciyam PL/1, operiruyushchim s celymi massivami i strokami. YAzyk ne predos- tavlyaet nikakih drugih vozmozhnostej raspredeleniya pamyati, krome staticheskogo opredeleniya i mehanizma stekov, obespechi- vaemogo lokal'nymi peremennyh funkcij; zdes' net ni "kuch"(HEAP), ni "sborki musora", kak eto predusmatrivaetsya v ALGOLE-68. Nakonec, sam po sebe "C" ne obespechivaet nikakih vozmozhnostej vvoda-vyvoda: zdes' net operatorov READ ili WRITE i nikakih vstroennyh metodov dostupa k fajlam. Vse eti mehanizmy vysokogo urovnya dolzhny obespechivat'sya yavno vyzyva- emymi funkciyami. Analogichno, yazyk "C" predlagaet tol'ko prostye, posle- dovatel'nye konstrukcii potokov upravleniya: proverki, cikly, gruppirovanie i podprogrammy, no ne mul'tiprogrammirovanie, parallel'nye operacii, sinhronizaciyu ili soprogrammy. Hotya otsutstvie nekotoryh iz etih sredstv mozhet vyglya- det' kak udruchayushchaya nepolnocennost' ("vyhodit, chto ya dolzhen obrashchat'sya k funkcii, chtoby sravnit' dve stroki simvolov ?!"), no uderzhanie yazyka v skromnyh razmerah daet real'nye preimushchestva. Tak kak "C" otnositel'no mal, on ne trebuet mnogo mesta dlya svoego opisaniya i mozhet byt' bystro vyuchen. Kompilyator s "C" mozhet byt' prostym i kompaktnym. Krome to- go, kompilyatory legko pishutsya; pri ispol'zovanii sovremennoj tehnologii mozhno ozhidat' napisaniya kompilyatora dlya novoj |VM za paru mesyacev i pri etom okazhetsya, chto 80 procentov prog- rammy novogo kompilyatora budet obshchej s programmoj dlya uzhe sushchestvuyushchih kompilyatorov. |to obespechivaet vysokuyu stepen' mobil'nosti yazyka. Poskol'ku tipy dannyh i stuktury upravle- niya, imeyushchiesya v "C", neposredstvenno podderzhivayutsya bol'- shinstvom sushchestvuyushchih |VM, biblioteka, neobhodimaya vo vremya progona izolirovannyh programm, okazyvaetsya ochen' malen'koj. Na PDP -11, naprimer, ona soderzhit tol'ko programmy dlya 32-bitovogo umnozheniya i deleniya i dlya vypolneniya programm vvoda i vyvoda posledovatel'nostej. Konechno, kazhdaya realiza- ciya obespechivaet ischerpyvayushchuyu, sovmestimuyu biblioteku funk- cij dlya vypolneniya operacij vvoda-vyvoda, obrabotki strok i raspredeleniya pamyati, no tak kak obrashchenie k nim osushchestvlya- etsya tol'ko yavno, mozhno , esli neobhodimo, izbezhat' ih vyzo- va; eti funkcii mogut byt' kompaktno napisany na samom "C". Opyat' zhe iz-za togo , chto yazyk "C" otrazhaet vozmozhnosti sovremennyh komp'yuterov, programmy na "C" okazyvayutsya dosta- tochno effektivnymi, tak chto ne voznikaet pobuzhdeniya pisat' vmesto etogo programmy na yazyke assemblera. Naibolee ubedi- tel'nym primerom etogo yavlyaetsya sama operacionnaya sistema "UNIX", kotoraya pochti polnost'yu napisana na "C". Iz 13000 strok programmy sistemy tol'ko okolo 800 strok samogo nizko- go urovnya napisany na assemblere. Krome togo, po sushchestvu vse prikladnoe programmnoe obespechenie sistemy "UNIX" napi- sano na "C"; podavlyayushchee bol'shinstvo pol'zovatelej sistemy "UNIX"(vklyuchaya odnogo iz avtorov etoj knigi) dazhe ne znaet yazyka assemblera PDP-11. Hotya "C" sootvetstvuet vozmozhnostyam mnogih |VM, on ne zavisit ot kakoj-libo konkretnoj arhitektury mashiny i v silu etogo bez osobyh usilij pozvolyaet pisat' "perenosimye" prog- rammy, t.e. programmy, kotorye mozhno propuskat' bez izmene- nij na razlichnyh apparatnyh sredstvah. V nashih krugah stal uzhe tradiciej perenos programmnogo obespecheniya, razrabotan- nogo na sisteme "UNIX", na sistemy |VM: HONEYWELL, IBM i INTERDATA. Fakticheski kompilyatory s "C" i programmnoe obes- pechenie vo vremya progona programm na etih chetyreh sistemah, po-vidimomu, gorazdo bolee sovmestimy, chem standartnye ver- sii fortrana amerikanskogo nacional'nogo instituta standar- tov (ANSI). Sama operacionnaya sistema "UNIX" teper' rabotaet kak na PDP-11, tak i na INTERDATA 8/32. Za isklyucheniem prog- ramm, kotorye neizbezhno okazyvayutsya v nekotoroj stepeni ma- shinno-zavisimymi, takih kak kompilyator, assembler i otlad- chik. Napisannoe na yazyke "C" programmnoe obespechenie iden- tichno na obeih mashinah. Vnutri samoj operacionnoj sistemy 7000 strok programmy, isklyuchaya matematicheskoe obespechenie yazyka assemblera |VM i upravleniya operaciyami vvoda-vyvoda, sovpadayut na 95 procentov. Programmistam, znakomym s drugimi yazykami, dlya sravne- niya i protivopostavleniya mozhet okazat'sya poleznym upominanie neskol'kih istoricheskih, tehnicheskih i filosofskih aspektov "C". Mnogie iz naibolee vazhnyh idej "C" proishodyat ot goraz- do bolee starogo, no vse eshche vpolne zhiznennogo yazyka BCPL , razrabotannogo Martinom Richardsom. Kosvenno yazyk BCPL okazal vliyanie na "C" cherez yazyk "B", napisannyj Kenom Tompsonom v 1970 godu dlya pervoj operacionnoj sistemy "UNIX" na |VM PDP-7. Hotya yazyk "C" imeet neskol'ko obshchih s BCPL harakternyh osobennostej, on nikoim obrazom ne yavlyaetsya dialektom pos- lednego. I BCPL i "B" - "beztipnye" yazyki; edinstvennym vi- dom dannyh dlya nih yavlyayutsya mashinnoe slovo, a dostup k dru- gim ob容ktam realizuetsya special'nymi operatorami ili obra- shcheniem k funkciyam. V yazyke "C" ob容ktami osnovnyh tipov dan- nyh yavlyayutsya simvoly, celye chisla neskol'kih razmerov i chis- la s plavayushchej tochkoj. Krome togo, imeetsya ierarhiya proiz- vodnyh tipov dannyh, sozdavaemyh ukazatelyami, massivami, strukturami, ob容dineniyami i funkciyami. YAzyk "C" vklyuchaet osnovnye konstrukcii potoka upravle- niya, trebuemye dlya horosho struktuirovannyh programm: gruppi- rovanie operatorov, prinyatie reshenij (IF), cikly s proverkoj zaversheniya v nachale (WHILE, FOR) ili v konce (DO) i vybor odnogo iz mnozhestva vozmozhnyh variantov (SWITCH). (Vse eti vozmozhnosti obespechivalis' i v BCPL, hotya i pri neskol'ko otlichnom sintaksise; etot yazyk predchuvstvoval nastupivshuyu cherez neskol'ko let modu na strukturnoe programmirovanie). V yazyke "C" imeyutsya ukazateli i vozmozhnost' adresnoj arifmetiki. Argumenty peredayutsya funkciyam posredstvom kopi- rovaniya znacheniya argumenta , i vyzvannaya funkciya ne mozhet izmenit' fakticheskij argument v vyzyvayushchej programme. Esli zhelatel'no dobit'sya "vyzova po ssylke", mozhno neyavno pere- dat' ukazatel', i funkciya smozhet izmenit' ob容kt, na kotoryj etot ukazatel' ukazyvaet. Imena massivov peredayutsya ukazani- em nachala massivov, tak chto argumenty tipa massivov effek- tivno vyzyvayutsya po ssylke. K lyuboj funkcii mozhno obrashchat'sya rekursivno, i ee lo- kal'nye peremennye obychno "avtomaticheskie", t.e. Sozdayutsya zanovo pri kazhdom obrashchenii. Opisanie odnoj funkcii ne mozhet soderzhat'sya vnutri drugoj, no peremennye mogut opisyvat'sya v sootvetstvii s obychnoj blochnoj strukturoj. Funkcii v "C" - programme mogut translirovat'sya otdel'no. peremennye po ot- nosheniyu k funkcii mogut byt' vnutrennimi, vneshnimi, no iz- vestnymi tol'ko v predelah odnogo ishodnogo fajla, ili pol- nost'yu global'nymi. Vnutrennie peremennye mogut byt' avtoma- ticheskimi ili staticheskimi. Avtomaticheskie peremennye dlya bol'shej effektivnosti mozhno pomeshchat' v registry, no ob座avle- nie registra yavlyaetsya tol'ko ukazaniem dlya kompilyatora i ni- kak ne svyazano s konkretnymi mashinnymi registrami. YAzyk "C" ne yavlyaetsya yazykom so strogimi tipami v smysle paskalya ili algola 68. On sravnitel'no snishoditelen k pre- obrazovaniyu dannyh, hotya i ne budet avtomaticheski preobrazo- vyvat' tipy dannyh s bujnoj neprinuzhdennost'yu yazyka PL/1. Sushchestvuyushchie kompilyatory ne predusmatrivayut nikakoj proverki vo vremya vypolneniya programmy indeksov massivov, tipov argu- mentov i t.d. V teh situaciyah, kogda zhelatel'na strogaya proverka ti- pov, ispol'zuetsya special'naya versiya kompilyatora. |ta prog- ramma nazyvaetsya LINT ochevidno potomu, ona vybiraet kusochki puha iz vashej programmy. Programma LINT ne generiruet mashin- nogo koda, a delaet ochen' stroguyu proverku vseh teh storon programmy, kotorye mozhno prokontrolirovat' vo vremya kompilya- cii i zagruzki. Ona opredelyaet nesootvetstvie tipov, nesov- mestimost' argumentov, neispol'zovannye ili ochevidnym obra- zom neinicializirovannye peremennye, potencial'nye trudnosti perenosimosti i t.d. Dlya programm,kotorye blagopoluchno pro- hodyat cherez LINT, garantiruetsya otsutstvie oshibok tipa pri- merno s toj zhe polnotoj, kak i dlya programm, napisannyh, naprimer, na ALGOLE-68. Drugie vozmozhnosti programmy LINT budut otmecheny, kogda predstavitsya sootvetstvuyushchij sluchaj. Nakonec, yazyk "C", podobno lyubomu drugomu yazyku, imeet svoi nedostatki. Nekotorye operacii imeyut neudachnoe starshin- stvo; nekotorye razdely sintaksisa mogli by byt' luchshe; su- shestvuet neskol'ko versij yazyka, otlichayushchihsya nebol'shimi de- talyami. Tem ne menee yazyk "C" zarekomendoval sebya kak isklyu- chitel'no effektivnyj i vyrazitel'nyj yazyk dlya shirokogo raz- noobraziya primenenij programmirovaniya. Soderzhanie knigi organizovano sleduyushchim obrazom. Glava 1 yavlyaetsya uchebnym vvedeniem v central'nuyu chast' yazyka "C". Cel' - pozvolit' chitatelyu startovat' tak bystro,kak tol'ko vozmozhno, tak kak my tverdo ubezhdeny, chto edinstvennyj spo- sob izuchit' novyj yazyk - pisat' na nem programmy. Pri etom , odnako, predpolagaetsya rabochee vladenie osnovnymi elementami programmirovaniya; zdes' ne ob座asnyaetsya, chto takoe |VM ili kompilyator, ne poyasnyaetsya smysl vyrazhenij tipa N=N+1. Hotya my i pytalis', gde eto vozmozhno, prodemonstrirovat' poleznuyu tehniku programmirovaniya. |ta kniga ne prednaznachaetsya byt' spravochnym rukovodstvom po strukturam dannyh i algoritmam; tam, gde my vynuzhdeny byli sdelat' vybor, my koncentrirova- lis' na yazyke. V glavah so 2-j po 6-yu razlichnye aspekty "C" izlagayutsya bolee detal'no i neskol'ko bolee formal'no, chem v glave 1, hotya udarenie po-prezhnemu delaetsya na razbore primerov za- konchennyh, poleznyh programm, a ne na otdel'nyh fragmentah. V glave 2 obsuzhdayutsya osnovnye tipy dannyh, operatory i vyrazheniya. V glave 3 rassmatrivayutsya upravlyayushchie operatory: IF-ELSE ,WHILE ,FOR i t.d. Glava 4 ohvatyvaet funkcii i strukturu programmy - vneshnie peremennye, pravila opredelen- nyh oblastej dejstviya opisaniya i t.d. V glave 5 obsuzhdayutsya ukazateli i adresnaya arifmetika. Glava 6 soderzhit podrobnoe opisanie struktur i ob容dinenij. V glave 7 opisyvaetsya standartnaya biblioteka vvoda-vy- voda yazyka "C", kotoraya obespechivaet standartnyj interfejs s operacionnoj sistemoj. |ta biblioteka vvoda-vyvoda podderzhi- vaetsya na vseh mashinah, na kotoryh realizovan "C", tak chto programmy, ispol'zuyushchie ee dlya vvoda, vyvoda i drugih sis- temnyh funkcij, mogut perenosit'sya s odnoj sistemy na druguyu po sushchestvu bez izmenenij. V glave 8 opisyvaetsya interfejs mezhdu "C" - programmami i operacionnoj sistemoj "UNIX". Upor delaetsya na vvod-vyvod, sistemu fajlov i perenosimost'. Hotya nekotorye chasti etoj glavy specifichny dlya operacionnoj sistemy "UNIX", program- misty, ne ispol'zuyushchie "UNIX", vse zhe dolzhny najti zdes' po- leznyj material, v tom chisle nekotoroe predstavlenie o tom, kak realizovana odna versiya standartnoj biblioteki i predlo- zheniya dlya dostizheniya perenosimosti programmy. Prilozhenie A soderzhit spravochnoe rukovodstvo po yazyku "C". Ono yavlyaetsya "oficial'nym" izlozheniem sintaksisa i se- mantiki "C" i (isklyuchaya chej-libo sobstvennyj kompilyator) okonchatel'nym arbitrom dlya vseh dvusmyslennostej i upushchenij v predydushchih glavah. Tak kak "C" yavlyaetsya razvivayushchimsya yazykom, realizovan- nym na mnozhestve sistem, chast' materila nastoyashchej knigi mo- zhet ne sootvetstvovat' tekushchemu sostoyaniyu razrabotki na ka- koj-to konkretnoj sisteme. My staralis' izbegat' takih prob- lem i predosteregat' o vozmozhnyh trudnostyah. V somnitel'nyh sluchayah, odnako, my obychno predpochitali opisyvat' situaciyu dlya sistemy "UNIX" PDP-11 , tak kak ona yavlyaetsya sredoj dlya bol'shinstva programmiruyushchih na yazyke "C". V prilozhenii a takzhe opisany rashozhdeniya v realizaciyah yazyka "C" na osnov- nyh sistemah.  * 1. Uchebnoe vvedenie *  Davajte nachnem s bystrogo vvedeniya v yazyk "C". Nasha cel' - prodemonstrirovat' sushchestvennye elementy yazyka na re- al'nyh programmah, ne uvyazaya pri etom v detalyah, formal'nyh pravilah i isklyucheniyah. V etoj glave my ne pytaemsya izlozhit' yazyk polnost'yu ili hotya by strogo (razumeetsya, privodimye primery budut korrektnymi). My hotim kak mozhno skoree doves- ti vas do takogo urovnya, na kotorom vy byli by v sostoyanii pisat' poleznye programmy, i chtoby dobit'sya etogo, my sosre- dotachivaemsya na osnovnom: peremennyh i konstantah, arifmeti- ke, operatorah peredachi upravleniya, funkciyah i elementarnyh svedeniyah o vvode i vyvode. My sovershenno namerenno ostavlya- em za predelami etoj glavy mnogie elementy yazyka "C", koto- rye imeyut pervostepennoe znachenie pri napisanii bol'shih programm, v tom chisle ukazateli, srtuktury, bol'shuyu chast' iz bogatogo nabora operatorov yazyka "C", neskol'ko operatorov peredachi upravleniya i nesmetnoe kolichestvo detalej. Takoj podhod imeet, konechno, svoi nedostatki. Samym su- shchestvennym yavlyaetsya to, chto polnoe opisanie lyubogo konkret- nogo elementa yazyka ne izlagaetsya v odnom meste, a poyasne- niya, v silu kratkosti, mogut privesti k nepravil'nomu istol- kovaniyu. Krome togo, iz-za nevozmozhnosti ispol'zovat' vsyu moshch' yazyka, primery okazyvayutsya ne stol' kratkimi i elegant- nymi, kak oni mogli by byt'. I hotya my staralis' svesti eti nedostatki k minimumu, vse zhe imejte ih vvidu. Drugoj nedostatok sostoit v tom, chto posleduyushchie glavy budut neizbezhno povtoryat' nekotorye chasti etoj glavy. My na- deemsya, chto takoe povtorenie budet skoree pomogat', chem raz- drazhat'. Vo vsyakom sluchae, opytnye programmisty dolzhny okazat'sya v sostoyanii proekstrapolirovat' material dannoj glavy na svoi sobstvennye programmistskie nuzhdy. Nachinayushchie zhe dolzhny v dopolnenie pisat' analogichnye malen'kie samostoyatel'nye programmy. I te, i drugie mogut ispol'zovat' etu glavu kak karkas, na kotoryj budut naveshivat'sya bolee podrobnye opisa- niya, nachinayushchiesya s glavy 2. 1.1. Hachinaem Edinstvennyj sposob osvoit' novyj yazyk programmirovaniya - pisat' na nem programmy. Pervaya program- ma, kotoraya dolzhna byt' napisana, - odna dlya vseh yazykov: napechatat' slova : HELLO, WORLD. |to - samyj sushchestvennyj bar'er; chtoby preodolet' ego, vy dolzhny sumet' zavesti gde-to tekst programmy, uspeshno ego skompilirovat', zagruzit', prognat' i najti, gde okazalas' vasha vydacha. Esli vy nauchilis' spravlyat'sya s etimi tehniches- kimi detalyami, vse ostal'noe sravnitel'no prosto. Programma pechati "HELLO, WORLD" na yazyke "C" imeet vid: MAIN () { PRINTF("HELLO, WORLD\N"); } Kak propustit' etu programmu - zavisit ot ispol'zuemoj vami sistemy. V chastnosti, na operacionnoj sisteme "UNIX" vy dolzhny zavesti ishodnuyu programmu v fajle, imya kotorogo okanchivaetsya na ".C" , naprimer, HELLO.C , i zatem skompili- rovat' ee po komande CC HELLO.C Esli vy ne dopustili kakoj-libo nebrezhnosti , takoj kak propusk simvola ili nepravil'noe napisanie, kompilyaciya proj- det bez soobshchenij i budet sozdan ispolnyaemyj fajl s imenem a.OUT . Progon ego po komande A.OUT privedet k vyvodu HELLO, WORLD Na drugih sistemah eti pravila budut inymi; prokonsul'- tirujtes' s mestnym avtoritetom. Uprazhnenie 1-1 --------------- Propustite etu programmu na vashej sisteme. Poprobujte ne vklyuchat' razlichnye chasti programmy i posmotrite kakie so- obshcheniya ob oshibkah vy pri etom poluchite. Teper' nekotorye poyasneniya k samoj programme. Lyubaya "C"-programma, kakov by ni byl ee razmer, sostoit iz odnoj ili bolee "funkcij", ukazyvayushchih fakticheskie operacii komp'yutera, kotorye dolzhny byt' vypolneny. Funkcii v yazyke "C" podobny funkciyam i podprogrammam fortrana i proceduram PL/1, paskalya i t.d. V nashem primere takoj funkciej yavlyaetsya MAIN. Obychno vy mozhete davat' funkciyam lyubye imena po vashemu usmotreniyu, no MAIN - eto osoboe imya; vypolnenie vashej prog- rammy nachinaetsya snachala s funkcii MAIN. |to oznachaet, chto kazhdaya programma dolzhna v kakom-to meste soderzhat' funkciyu s imenem MAIN. Dlya vypolneniya opredelennyh dejstvij funkciya MAIN obychno obrashchaetsya k drugim funkciyam, chast' iz kotoryh nahoditsya v toj zhe samoj programme, a chast' - v bibliotekah, soderzhashchih ranee napisannye funkcii. Odnim sposobom obmena dannymi mezhdu funkciyami yavlyaetsya peredacha posredstvom argumentov. Kruglye skobki, sleduyushchie za imenem funkcii, zaklyuchayut v sebe spisok argumentov; zdes' maIN - funkciya bez argumentov, chto ukazyvaetsya kak (). Ope- ratory, sostavlyayushchie funkciyu, zaklyuchayutsya v figurnye skobki { i }, kotorye analogichny DO-END v PL/1 ili BEGIN-END v al- gole, paskale i t.d. Obrashchenie k funkcii osushchestvlyaetsya uka- zaniem ee imeni, za kotorym sleduet zaklyuchennyj v kruglye skobki spisok argumentov. zdes' net nikakih operatorov CALL, kak v fortrane ili PL/1. Kruglye skobki dolzhny prisutstvo- vat' i v tom sluchae, kogda funkciya ne imeet argumentov. Stroka PRINTF("HELLO, WORLD\N"); yavlyaetsya obrashcheniem k funkcii, kotoroe vyzyvaet funkciyu s imenem PRINTF i argumetom "HELLO, WORLD\N". Funkciya PRINTF yavlyaetsya bibliotechnoj funkciej, kotoraya vydaet vyhodnye dan- nye na terminal (esli tol'ko ne ukazano kakoe-to drugoe mes- to naznacheniya). V dannom sluchae pechataetsya stroka simvolov, yavlyayushchayasya argumentom funkcii. Posledovatel'nost' iz lyubogo kolichestva simvolov, zak- lyuchennyh v udvoennye kavychki "...", nazyvaetsya 'simvol'noj strokoj' ili 'strochnoj konstantoj'. Poka my budem ispol'zo- vat' simvol'nye stroki tol'ko v kachestve argumentov dlya PRINTF i drugih funkcij. Posledovatel'nost' \N v privedennoj stroke yavlyaetsya oboznacheniem na yazyke "C" dlya 'simvola novoj stroki', koto- ryj sluzhit ukazaniem dlya perehoda na terminale k levomu krayu sleduyushchej stroki. Esli vy ne vklyuchite \N (poleznyj eksperi- ment), to obnaruzhite, chto vasha vydacha ne zakonchitsya pereho- dom terminala na novuyu stroku. Ispol'zovanie posledovatel'- nosti \N - edinstvennyj sposob vvedeniya simvola novoj stroki v argument funkcii PRINTF; esli vy poprobuete chto-nibud' vrode PRINTF("HELLO, WORLD "); to "C"-kompilyator budet pechatat' zloradnye diagnosticheskie soobshcheniya o nedostayushchih kavychkah. Funkciya PRINTF ne obespechivaet avtomaticheskogo perehoda na novuyu stroku, tak chto mnogokratnoe obrashchenie k nej mozhno ispol'zovat' dlya poetapnoj sborki vyhodnoj stroki. Nasha per- vaya programma, pechatayushchaya identichnuyu vydachu, s tochno takim zhe uspehom mogla by byt' napisana v vide MAIN() { PRINTF("HELLO, "); PRINTF("WORLD"); PRINTF("\N"); } Podcherknem, chto \N predstavlyaet tol'ko odin simvol. Us- lovnye 'posledovatel'nosti', podobnye \N , dayut obshchij i do- puskayushchij rasshirenie mehanizm dlya predstavleniya trudnyh dlya pechati ili nevidimyh simvolov. Sredi prochih simvolov v yazyke "C" predusmotreny sleduyushchie: \t - dlya tabulyacii, \B - dlya vozvrata na odnu poziciyu, \" - dlya dvojnoj kavychki i \\ dlya samoj obratnoj kosoj cherty. Uprazhnenie 1-2 --------------- Provedite eksperimenty dlya togo, chtoby uznat' chto proi- zojdet, esli v stroke, yavlyayushchejsya argumentom funkcii PRINTF budet soderzhat'sya \X, gde X - nekotoryj simvol, ne vhodyashchij v vysheprivedennyj spisok. 1.2. Peremennye i arifmetika Sleduyushchaya programma pechataet privedennuyu nizhe tablicu temperatur po Farengejtu i ih ekvivalentov po stogradusnoj shkale Cel'siya, ispol'zuya dlya perevoda formulu C = (5/9)*(F-32). 0 -17.8 20 -6.7 40 4.4 60 15.6 ... ... 260 126.7 280 137.8 300 140.9 Teper' sama programma: /* PRINT FAHRENHEIT-CELSIUS TABLE FOR F = 0, 20, ..., 300 */ MAIN() { INT LOWER, UPPER, STEP; FLOAT FAHR, CELSIUS; LOWER = 0; /* LOWER LIMIT OF TEMPERATURE TABLE */ UPPER =300; /* UPPER LIMIT */ STEP = 20; /* STEP SIZE */ FAHR = LOWER; WHILE (FAHR <= UPPER) { CELSIUS = (5.0/9.0) * (FAHR -32.0); PRINTF("%4.0F %6.1F\N", FAHR, CELSIUS); FAHR = FAHR + STEP; } } Pervye dve stroki /* PRINT FAHRENHEIT-CELSIUS TABLE FOR F = 0, 20, ..., 300 */ yavlyayutsya kommentariem, kotoryj v dannom sluchae kratko poyas- nyaet, chto delaet programma. Lyubye simvoly mezhdu /* i */ ig- noriruyutsya kompilyatorom; mozhno svobodno pol'zovat'sya kommen- tariyami dlya oblegcheniya ponimaniya programmy. Kommentarii mo- gut poyavlyat'sya v lyubom meste, gde vozmozhen probel ili pere- hod na novuyu stroku. V yazyke "C" vse peremennye dolzhny byt' opisany do ih is- pol'zovaniya, obychno eto delaetsya v nachale funkcii do pervogo vypolnyaemogo operatora. Esli vy zabudete vstavit' opisanie, to poluchite diagnosticheskoe soobshchenie ot kompilyatora. Opisa- nie sostoit iz tipa i spiska peremennyh, imeyushchih etot tip, kak v INT LOWER, UPPER, STEP; FLOAT FAHR, CELSIUS; Tip INT oznachaet, chto vse peremennye spiska celye; tip FLOAT prednaznachen dlya chisel s plavayushchej tochkoj, t.e. dlya chisel, kotorye mogut imet' drobnuyu chast'. Tochnost' kak INT , TAK i FLOAT zavisit ot konkretnoj mashiny, na kotoroj vy ra- botaete. Na PDP-11, naprimer, tip INT sootvetstvuet 16-bito- vomu chislu so znakom, t.e. chislu, lezhashchemu mezhdu -32768 i +32767. CHislo tipa FLOAT - eto 32-bitovoe chislo, imeyushchee okolo semi znachashchih cifr i lezhashchee v diapazone ot 10e-38 do 10e+38. V glave 2 privoditsya spisok razmerov dlya drugih ma- shin. V yazyke "C" predusmotreno neskol'ko drugih osnovnyh ti- pov dannyh, krome INT i FLOAT: CHAR simvol - odin bajt SHORT korotkoe celoe LONG dlinnoe celoe DOUBLE plavayushchee s dvojnoj tochnost'yu Razmery etih ob容ktov tozhe mashinno-nezavisimy; detali privedeny v glave 2. Imeyutsya takzhe massivy, struktury i ob- 容dineniya etih osnovnyh tipov, ukazateli na nih i funk- cii,kotorye ih vozvrashchayut; so vsemi nimi my vstretimsya v svoe vremya. Fakticheski vychisleniya v programme perevoda temperatur nachinayutsya s operatorov prisvaivaniya LOWER = 0; UPPER =300; STEP = 20; FAHR =LOWER; kotorye pridayut peremennym ih nachal'nye znacheniya. kazhdyj ot- del'nyj operator zakanchivaetsya tochkoj s zapyatoj. Kazhdaya stroka tablicy vychislyaetsya odinakovym obrazom, tak chto my ispol'zuem cikl, povtoryayushchijsya odin raz na stro- ku. V etom naznachenie operatora WHILE: WHILE (FAHR <= UPPER) { .... } proveryaetsya uslovie v kruglyh skobkah. Esli ono istinno (FAHR men'she ili ravno UPPER), to vypolnyaetsya telo cikla (vse operatory, zaklyuchennye v figurnye skobki { i } ). Zatem vnov' proveryaetsya eto uslovie i, esli ono istinno, opyat' vy- polnyaetsya telo cikla. Esli zhe uslovie ne vypolnyaetsya ( FAHR prevoshodit UPPER ), cikl zakanchivaetsya i proishodit perehod k vypolneniyu operatora, sleduyushchego za operatorom cikla. Tak kak v nastoyashchej programme net nikakih posleduyushchih operato- rov, to vypolnenie programmy zavershaetsya. Telo operatora WHILE mozhet sostoyat' iz odnogo ili bolee operatorov, zaklyuchennyh v figurnye skobki, kak v programme perevoda temperatur, ili iz odnogo operatora bez skobok, kak, naprimer, v WHILE (I < J) I = 2 * I; V oboih sluchayah operatory, upravlyaemye operatorom WHILE, sdvinuty na odnu tabulyaciyu, chtoby vy mogli s pervogo vzglyada videt', kakie operatory nahodyatsya vnutri cikla. Takoj sdvig podcherkivaet logicheskuyu strukturu programmy. Hotya v yazyke "C" dopuskaetsya sovershenno proizvol'noe raspolozhenie opera- torov v stroke, podhodyashchij sdvig i ispol'zovanie probelov znachitel'no oblegchayut chtenie programm. My rekomenduem pisat' tol'ko odin operator na stroke i (obychno) ostavlyat' probely vokrug operatorov. Raspolozhenie figurnyh skobok menee sushches- tvenno; my vybrali odin iz neskol'kih populyarnyh stilej. Vy- berite podhodyashchij dlya vas stil' i zatem ispol'zujte ego pos- ledovatel'no. Osnovnaya chast' raboty vypolnyaetsya v tele cikla. Tempera- tura po Cel'siyu vychislyaetsya i prisvaivaetsya peremennoj CELAIUS operatorom CELSIUS = (5.0/9.0) * (FAHR-32.0); prichina ispol'zovaniya vyrazheniya 5.0/9.0 vmesto vyglyadyashchego proshche 5/9 zaklyuchaetsya v tom, chto v yazyke "C", kak i vo mno- gih drugih yazykah, pri delenii celyh proishodit usechenie, sostoyashchee v otbrasyvanii drobnoj chasti rezul'tata. Takim ob- razom, rezul'tat operacii 5/9 raven nulyu, i, konechno, v etom sluchae vse temperatury okazalis' by ravnymi nulyu. Desyatichnaya tochka v konstante ukazyvaet, chto ona imeet tip s plavayushchej tochkoj, tak chto, kak my i hoteli, 5.0/9.0 ravno 0.5555... . My takzhe pisali 32.0 vmesto 32 , nesmotrya na to, chto tak kak peremennaya FAHR imeet tip FLOAT , celoe 32 avtomaticheski by preobrazovalos' k tipu FLOAT ( v 32.0) pered vychitaniem. S tochki zreniya stilya razumno pisat' plavayushchie konstanty s yavnoj desyatichnoj tochkoj dazhe togda, kogda oni imeyut celye znacheniya; eto podcherkivaet ih plavayushchuyu prirodu dlya prosmat- rivayushchego programmu i obespechivaet to, chto kompilyator budet smotret' na veshchi tak zhe, kak i Vy. Podrobnye