Programski Jezik C - K&R

Embed Size (px)

Citation preview

  • 7/21/2019 Programski Jezik C - K&R

    1/141

    Dennis M. Ritchie

    Brian W. Kernighan

    Programski jezik C

    Drugo izdanje

    Prijevod: Ante Deni

  • 7/21/2019 Programski Jezik C - K&R

    2/141

    Programski jezik C Sadraj

    Predgovor------------------------------------------------------------------------------------------------------3 Predgovor prvom izdanju-----------------------------------------------------------------------------------4UVOD -----------------------------------------------------------------------------------------------------------5

    1.1 Putanje u rad-----------------------------------------------------------------------------------------71.4 Simbolike konstante------------------------------------------------------------------------------ 131.5 Znakovni ulaz i izlaz -------------------------------------------------------------------------------13

    1.5.1 Kopiranje datoteka-----------------------------------------------------------------------------14

    1.5.3 Brojanje linija ------------------------------------------------------------------------------------16

    1.5.4 Brojanje rijei------------------------------------------------------------------------------------16

    1.6 Polja ---------------------------------------------------------------------------------------------------171.7 Funkcije-----------------------------------------------------------------------------------------------191.8 Argumenti - pozivanje pomou vrijednosti----------------------------------------------------211.9 Polja znakova ---------------------------------------------------------------------------------------221.10 Vanjske varijable i podruja -------------------------------------------------------------------- 24

    POGLAVLJE 2: TIPOVI OPERATORI I IZRAZI ---------------------------------------------------- 272.1 Imena varijabli---------------------------------------------------------------------------------------272.2 Tipovi i veliine podataka-------------------------------------------------------------------------272.3 Konstante --------------------------------------------------------------------------------------------282.4 Deklaracije-------------------------------------------------------------------------------------------302.5 Aritmetiki operatori--------------------------------------------------------------------------------312.6 Relacijski i logiki operatori ----------------------------------------------------------------------312.7 Konverzije tipova -----------------------------------------------------------------------------------322.8 Operatori uveavanja i umanjivanja inkrementiranja i dekrementiranja) ------------- 342.9 Operatori za manipulaciju bitovima ------------------------------------------------------------ 362.10 Operatori i izrazi dodjeljivanja vrijednosti --------------------------------------------------- 372.11 Uvjetni izrazi ---------------------------------------------------------------------------------------382.12 Prioritet i redoslijed raunanja ----------------------------------------------------------------- 39

    POGLAVLJE 3: KONTROLA TOKA ------------------------------------------------------------------- 413.1 Naredbe i blokovi-----------------------------------------------------------------------------------413.2 If else -----------------------------------------------------------------------------------------------413.3 Else if -----------------------------------------------------------------------------------------------423.4 Switch-------------------------------------------------------------------------------------------------433.5 Petlje - while i for -----------------------------------------------------------------------------------44

  • 7/21/2019 Programski Jezik C - K&R

    3/141

    Programski jezik C Sadraj

    3.6 Petlja do while ------------------------------------------------------------------------------------463.7 Break i continue ------------------------------------------------------------------------------------473.8 Goto i labele -----------------------------------------------------------------------------------------48

    POGLAVLJE 4: FUNKCIJE I PROGRAMSKE STRUKTURE ----------------------------------- 504.1 Osnovni pojmovi o funkcijama ------------------------------------------------------------------504.3 Vanjske varijable -----------------------------------------------------------------------------------544.4. Pravila opsega -------------------------------------------------------------------------------------584.5 Datoteke zaglavlja ---------------------------------------------------------------------------------594.6 Statike varijable -----------------------------------------------------------------------------------604.7 Registarske varijable ------------------------------------------------------------------------------614.8 Struktura bloka--------------------------------------------------------------------------------------614.9 Inicijalizacija -----------------------------------------------------------------------------------------624.10 Rekurzija--------------------------------------------------------------------------------------------634.11 C preprocesor -------------------------------------------------------------------------------------64

    4.11.1 Ukljuivanje datoteke------------------------------------------------------------------------64

    4.11.2 Makrozamjena---------------------------------------------------------------------------------65

    4.11.3 Uvjetno ukljuivanje--------------------------------------------------------------------------66

    PETO POGLAVLJE: POKAZIVAI I POLJA --------------------------------------------------------68 5.1 Pokazivai i adrese --------------------------------------------------------------------------------685.2 Pokazivai i argumenti funkcija -----------------------------------------------------------------695.3 Pokazivai i polja -----------------------------------------------------------------------------------715.4 Adresna aritmetika---------------------------------------------------------------------------------735.5 Pokazivai i funkcije znaka-----------------------------------------------------------------------765.6 Pokazivai polja. Pokazivai na pokazivae -------------------------------------------------785.7 Viedimenzionalna polja--------------------------------------------------------------------------815.8 Inicijalizacija pokazivaa polja-------------------------------------------------------------------825.9 Pokazivai na viedimenzionalna polja ------------------------------------------------------- 835.10 Argumenti naredbene linije--------------------------------------------------------------------- 835.11 Pokazivai na funkcije---------------------------------------------------------------------------875.12 Sloene deklaracije ------------------------------------------------------------------------------89

    Poglavlje 6: STRUKTUR E ------------------------------------------------------------------------------- 946.1 Osnovni pojmovi o strukturama----------------------------------------------------------------- 946.2 Strukture i funkcije ---------------------------------------------------------------------------------96

  • 7/21/2019 Programski Jezik C - K&R

    4/141

    Programski jezik C Sadraj

    6.3 Polja struktura---------------------------------------------------------------------------------------986.4 Pokazivai na strukture ------------------------------------------------------------------------- 1016.5 Samopozivajue strukture---------------------------------------------------------------------- 1026.6 Pretraivanje tablice ----------------------------------------------------------------------------- 1066.7 Typedef--------------------------------------------------------------------------------------------- 1086.8 Unije------------------------------------------------------------------------------------------------- 1096.9 Polja bitova ---------------------------------------------------------------------------------------- 110

    POGLAVLJE 7: ULAZ I IZLAZ ------------------------------------------------------------------------ 1127.1 Standardni ulaz i izlaz--------------------------------------------------------------------------- 1127.2 Formatirani izlaz - printf------------------------------------------------------------------------- 1137.3 Liste argumenata promjenjive duine ------------------------------------------------------- 1157.4 Formatirani ulaz - scanf------------------------------------------------------------------------- 1167.5 Pristup datoteci ----------------------------------------------------------------------------------- 1187.6 Manipulacija grekama - stderr i exit -------------------------------------------------------- 1207.7 Linijski ulaz i izlaz -------------------------------------------------------------------------------- 1217.8 Raznolike funkcije-------------------------------------------------------------------------------- 122

    7.8.1 Operacije s znakovnim nizovima--------------------------------------------------------- 122

    7.8.2 Provjera i pretvorba klasa znakova ------------------------------------------------------ 122

    7.8.3 Funkcija ungetc------------------------------------------------------------------------------- 123

    7.8.4 Izvrenje naredbe ---------------------------------------------------------------------------- 123

    7.8.5 Upravljanje memorijom --------------------------------------------------------------------- 123

    7.8.6 Matematike funkcije------------------------------------------------------------------------ 124

    7.8.7 Generiranje sluajnih brojeva ------------------------------------------------------------- 124

    POGLAVLJE 8: SUELJE UNIX SISTEMA ------------------------------------------------------- 1258.1 Deskriptori datoteka ----------------------------------------------------------------------------- 1258.2 Primitivni U/I - read i write---------------------------------------------------------------------- 1258.3 open, creat, close, unlink ----------------------------------------------------------------------- 1268.4 Sluajan pristup - lseek ------------------------------------------------------------------------- 1288.5 Primjer - Implementacija funkcija fopen i getc--------------------------------------------- 1298.6 Primjer - Listanje direktorija-------------------------------------------------------------------- 1328.7 Primjer - Pridjeljiva memorije----------------------------------------------------------------- 136

  • 7/21/2019 Programski Jezik C - K&R

    5/141

    Programski jezik C Predgovor

    3

    Predgovor

    Od izdavanja "Programskog jezika C" 1978. godine, svijet raunala doivio je veliki napredak. Velikiraunalni sustavi postali su jo snaniji, a osobna raunala dobila su mogunosti koje se do desetak godinanisu mogle nazrijeti. Za to vrijeme i sam C se mijenjao, mada neznatno, i razvijao sve dalje od svojihzaetaka kao jezika UNIX operativnog sistema.

    Rastua popularnost C-a, promjene u jeziku tokom godina i kreiranje prevoditelja od strane onihkojima nije bitan izgled, kombinirano je s potrebom za preciznijom i suvremenijom definicijom jezika od onekoja je bila prezentirana u prvom izdanju ove knjige. Godine 1983. American National Standard Institute(ANSI) zasniva udrugu ija je svrha bila napraviti "nedvosmislenu i od raunala nezavisnu definiciju Cjezika". Rezultat svega je ANSI standard za C.

    Standard formalizira konstrukcije koje su bile najavljene, ali ne i opisane u prvom izdanju, kao to sudodjela strukture i nizovi dobiveni pobrojavanjem. Standard odreuje novi nain deklariranja funkcije kojiomoguuje provjeru definicije u praksi. Odreuje, takoer i standardnu biblioteku, s proirenim skupomfunkcija za pripremu ulaza i izlaza, upravljanje memorijom, rad s nizovima i sl. Standard precizira vladanjaatributa koji nisu bili u originalnoj definiciji i istovremeno jasno pokazuje koji su aspekti jezika ostali zavisni oraunalu.

    Drugo izdanje "Programskog jezika C" opisuje C onako kako ga definira ANSI standard (Za vrijeme

    pisanja ove knjige, standard je bio u zavrnom stadiju usvajanja; oekivalo se da bude usvojen krajem1988.god. Razlike izmeu onoga to pie ovdje i konane forme standarda su minimalne.). Iako smo

    naznaili mjesta na kojima se jezik proirio i razvio, odluili smo ga ekskluzivno predstaviti u novom obliku.U velikom dijelu razlike su neznatne; najuoljivija izmjena je novi nain deklaracije i definicije funkcije.Moderni prevoditelji vepodravaju najvei dio standarda.

    Pokuali smo zadrati sutinu prvog izdanja. C nije opiran jezik, pa ga nije potrebno opisivatiopirnim knjigama. Doradili smo predstavljanje kritinih faktora kao to su pokazivai, koji su sutina Cprogramiranja. Proistili smo originalne primjere i dodali nove, u veini poglavlja. Na primjer, dio koji opisujekomplicirane deklaracije proiren je programima koji pretvaraju deklaracije u rijei i obratno. Kao i uprethodnom sluaju i ovdje su svi primjeri provjereni direktno iz teksta, prepoznatljivog raunalu.

    Dodatak A, uputa za rad, nije standard ve samo pokuaj prikazivanja njegove sutine u kraemobliku. Poradi lakeg razumijevanja vrlo je znaajno da posebna uloga pripadne samom standardu. DodatakB predstavlja pregled karakteristika standardne biblioteke. Ovo je bitna napomena za programera, a ne za

    korisnika. Dodatak C prua kratak pregled izmjena u odnosu na originalno izdanje.Kao to smo rekli u predgovoru prvom izdanju, C je "korisniji to je vee iskustvo u radu s njim".Poslije desetogodinjeg iskustva, to i dalje tvrdimo. Nadamo se da e vam ova knjiga pomoi da nauite iprimijenite programski jezik C.

    Jako su nas zaduili prijatelji koji su pomogli pri radu na drugom izdanju. Jon Bentley, Doug Gwyn,Doug McIlroy, Peter Nelson i Rob Pike komentirali suoriginalni rukopis. Zahvaljujemo Alu Ahou, DennisuAllisonu, Joeu Campbellu, G. R. Emlinu, Karen Fortgang, Allenu Holubu, Andrewu Humeu, Daveu Kristolu,Johnu Lindermanu, Davidu Prosseru, Gene Spafford i Chrisu Van Wyku na paljivoj kontroli napisanogteksta. Svojim primjedbama pomogli su nam i Bill Chestwick, Mark Kernighan, Andy Koenig, Robin Lake,Tom London, Jim Reeds, Clovis Tondo i Peter Weinberger. Dave Prosser je detaljno odgovorio na mnogapitanja glede ANSI standarda. Koristili smo Bjarne Stroustrupov C++ translator za lokalno testiranje naihprograma, a Dave Kristol nam je nabavio C prevoditelj kojim su obavljena zavrna testiranja. Rich Drechslernam je mnogo pomogao pri pisanju teksta na raunalu. Svima im iskreno zahvaljujemo.

    Brian W. KernighanDennis M. Ritchie

  • 7/21/2019 Programski Jezik C - K&R

    6/141

    Programski jezik C Predgovor prvom izdanju

    4

    Predgovor prvom izdanju

    C je programski jezik ope namjene koji karakterizira mali broj izraza, moderna kontrola tijeka istrukture podataka kao i veliki broj operatora. C nije "high level" jezik niti je opiran, a nije namijenjen nekojposebnoj vrsti primjene. Meutim, openitost i nepostojanje ogranienja ine ga prihvatljivijim i efikasnijim oddrugih programskih jezika.

    C je u originalu kreirao i primijenio Dennis Ritchie. Operativni sustav, C prevoditelj i sve UNIX-oveaplikacije (ukljuujui cjelokupan software koriten u pripremi ove knjige) su napisani u C-u. Napravljeni suprevoditelji koji se vrte na veem broju raunala, ukljuujui IBM System/370, Honeywell 6000 i InterData8/32. C nije neposredno povezan s nekim posebnim sklopovljem ili sustavom, ali je lako napisati programekoji se daju, bez ikakvih izmjena koristiti na bilo kojem raunalu koje podrava C.

    Ova knjiga je korisna, jer pomae itatelju nauiti programirati u C programskom jeziku. Ona dajeosnovne napomene, koje omoguuju novim korisnicima poetak rada u najkraem moguem roku, posebnapoglavlja o svakoj vanijoj temi, te uputstvo za rad. Najvei dio operacija temelji se na itanju, pisanju irazradi primjera, a ne na turom predstavljanju postojeih pravila. Najee, primjeri su cjeloviti programi, ane izolirani dijelovi programa. Svi primjeri su provjereni direktno iz teksta, koji je napisan u oblikuprepoznatljivog raunalu. Pored predstavljanja naina na koje se jezik dade najbolje upotrijebiti, trudili smose, gdje god je to bilo mogue, prikazati korisne algoritme, dobro kreirane i pravilno koncipirane principe.

    Knjiga ne predstavlja uvod u programiranje; onaini bliskim osnovne

    imbenike programiranja kaonpr. varijable, petlje i funkcije. Iako je ovako poetnicima omogueno upoznavanje i koritenje jezika, vie e

    mu koristiti konzultacije s kolegama koji bolje barataju s C-om.Nae iskustvo pokazuje da je C pogodan za rad, sadrajan i raznovrstan jezik za najvei broj

    programa. Lak je za uenje, i sve korisniji to je vee iskustvo u radu s njim. Nadamo se da e vam ovaknjiga pomoi da ga to bolje savladate.

    Sadrajne kritike i primjedbe mnogih prijatelja i kolega ovoj knjizi doprinijele su da je sazadovoljstvom napiemo. Naroito su Mike Bianchi, Jim Blue, Stu Feldman, Doug McIlroy, Bill Roome, BobRosin i Larry Rosler paljivo pregledali mnoge inaice. Zahvaljujemo takoer Alu Ahou, Steveu Bourneu,Danu Dvoraku, Chucku Haleyu, Debbie Haleyu, Marion Harris, Ricku Holtu, Steveu Johnsonu, JohnuMasheyu, Bobu Mitzeu, Ralphu Muhau, Peteru Nelsonu, Elliotu Pinsonu, Billu Plaugeru, Jerryu Spivacku,Kenu Thompsonu i Peteru Weinebergeru na komentarima koji su bili od pomoi u razliitim situacijama, teMikeu Lesku i Joeu Ossannai na svesrdnoj pomoi pri obradi teksta.

    Brian W. KernighanDennis M. Ritchie

  • 7/21/2019 Programski Jezik C - K&R

    7/141

    Programski jezik C Uvod

    5

    UVOD

    C je programski jezik ope namjene. Tijesno je povezan s operativnim sistemom UNIX na kojemu jerazvijen, jer su i sistem i veina programa koji rade na UNIX-u napisani ba u C-u. Jezik, ipak, nije vezansamo za jedan operativni sistem ili raunalo; iako je nazvan "jezikom za sistemsko programiranje" zato tose koristi pri pisanju prevoditelja i operativnih sistema, podjednako se dobro koristi za programiranje udrugim podrujima. Veina bitnih ideja C-a potjee od jezika BCPL koji je razvio Martin Richards. UtjecajBCPL-a na C ostvaren je indirektno preko B jezika koji je 1970. napisao Ken Thompson za prvi UNIX sistemna DEC PDP-7 raunalu.

    BCPL i B su jezici bez "tipova podataka". Nasuprot njemu, C nudi mnotvo razliitih tipova podataka.Osnovni tipovi su znaci, cjelobrojne vrijednosti i vrijednosti iz podruja realnih brojeva (vrijednosti spominim zarezom) u vie veliina. Uz to postoji hijerarhija izvedenih tipova podataka kreiranihpokazivaima, poljima, strukturama i unijama. Izrazi se sastoje od operatora i operanda; bilo koji izraz,ukljuujui i dodjelu vrijednosti ili pozivanje funkcije, moe biti naredba. Pokazivai omoguuju nezavisnuadresnu aritmetiku.

    C nudi osnovne konstrukcije za kontrolu toka koje trae dobro strukturirani programi: grupiranjenaredbi, donoenje odluka (if-else), izbor (switch), petlje s uvjetima na poetku (while) i na kraju (do), te izlaziz petlje prije kraja (break).

    Funkcije mogu vraati vrijednosti osnovnih tipova, struktura, unija ili pokaziva

    a. Bilo koja funkcijamoe se rekurzivno pozivati. Lokalne varijable su tipino "automatske" (gube vrijednost pri izlasku iz

    funkcije) ili se kreiraju svakim novim pozivanjem. Definicije funkcija ne moraju se umetati, a varijable semogu deklarirati u blokovima. Funkcije C programa mogu se nalaziti u razliitim izvornim datotekama kojese posebno prevode. Varijable mogu biti unutranje, vanjske (za koje se zna samo unutar jedne izvornedatoteke) ili dostupne cijelom programu (globalne).

    Preprocesorska faza obavlja makrosupstitucije na izvornom tekstu programa, ukljuivanje ostalihizvornih datoteka i uvjetno prevoenje.

    C je jezik relativno "niskog nivoa". Ovakav epitet nije nedostatak, ve govori da C radi s istimvrstama objekata s kojima rade i sama raunala, a to su znakovi, brojevi i adrese. Ovi objekti se mogukombinirati i premjetati pomou aritmetikih i logikih operatora kojima su opremljena postojea raunala.

    C ne radi direktno sa sloenim objektima kao to su nizovi znakova, skupovi, liste ili matrice. Nepostoje operacije koje obrauju cijelu matricu ili niz, iako strukture mogu biti kopirane kao jedinka. C ne

    definira ni jednu drugu mogunost memoriranja lokacija osim stati

    ke definicije i discipline stoga, koja jeomoguena lokalnim varijablama funkcija; ovdje nema nagomilavanja ili skupljanja nebitnih elemenata. Na

    kraju, sam C ne nudi ulazno/izlazne olakice; u njemu ne postoje READ ili WRITE stanja, te nemaugraenih metoda za pristup datotekama. Svi ovi mehanizmi "vieg nivoa" moraju biti odreeni funkcijamakoje se zovu eksplicitno. Manje-vie sve implementacije C-a imaju standardnu kolekciju takovih funkcija.

    Shodno tomu, C zapravo nudi samo jednoznani kontrolni tok: uvjeta, petlji, grupiranja ipotprograma, ali ne i multiprogramiranje, paralelne operacije ili sinkronizaciju.

    Iako nepostojanje neke od ovih karakteristika moe izgledati kao ozbiljan nedostatak ("Znai da bihusporedio dva znakovna niza moram pozivati funkciju?"), odravanje jezika na umjerenoj razini ima svojustvarnu korist. Poto je C relativno mali jezik, dade se opisati na relativno malo prostora i nauiti brzo.Programer s punim pravom moe oekivati lako uenje i razumijevanje korektne upotrebe cijelog jezika.

    Dugi niz godina, jedina definicija C-a je bio referentni prirunik prvog izdanja ove knjige. AmericanNational Standards Institute (ANSI) je 1983.god. osnovao udrugu koja se skrbila za modernu i cjelovitu

    definiciju C-a. Oekuje se da

    e ANSI standard, ili ANSI C biti odobren u 1988.god. (odobren je op.prev).Sve karakteristike standarda vesu podrane preko novih prevoditelja.

    Standard se bazira na originalnom referentnom priruniku. Jezik je razmjerno malo mijenjan; jedanod ciljeva standarda je bio osigurati da veina postojeih programa ostane primjenjiva, ili, ako to ne uspije,prevoditelji moraju dati upozorenje o drugaijem nainu rada.

    Za veinu programera, najbitnija promjena je u novoj sintaksi za deklariranje i definiranje funkcija.Deklaracija funkcije moe sada imati opis argumenata funkcije; sintaksa definicije je na odreen nainizmijenjena. Ova dodatna informacija pomae da prevoditelji mnogo lake otkrivaju greke nastaleneslaganjem argumenata; po naem iskustvu, to je vrlo koristan dodatak jeziku.

    Postoje i jo neke, manje izmjene. Dodjela struktura i nizova dobivenih pobrojavanjem, koji su senairoko primjenjivali, postali su i zvanino dio jezika. Izraunavanje realnih brojeva moe se obaviti ijednostrukom tonou. Aritmetika svojstva, posebice za neoznaene tipove su razjanjena. Preprocesorje savreniji. Veina od ovih promjena ipak nee previe zanimati programere.

    Drugi znaajan doprinos standarda je definicija biblioteke koja prati C jezik. Ona odreuje funkcije zapristup operativnom sistemu (npr. za itanje i pisanje datoteka), formatira ulaz i izlaz, odreuje poloaj umemoriji, radi s nizovima i sl. Zbirka standardnih zaglavlja osigurava jednoznaan pristup deklaracijama

  • 7/21/2019 Programski Jezik C - K&R

    8/141

    Programski jezik C Uvod

    6

    funkcija i tipovima podataka. Da bi mogli biti u vezi sa osnovnim sistemom, programi to koriste ovubiblioteku su zasigurno kompatibilni i portabilni. Mnoge biblioteke su vrlo sline modelu standardne ulaz/izlazbiblioteke UNIX sistema. Ova biblioteka je opisana u prvom izdanju i masovno je bila u upotrebi na drugimsistemima. Kaimo ipak, jo jednom, da mnogi programeri nee uoiti bitnije izmjene.

    Zbog toga to tipove podataka i kontrolnih struktura odreenih C-om podrava veliki broj raunala,radna biblioteka koja je snabdjevena vlastitim programima jest mala. Jedino se funkcije iz standardne

    biblioteke pozivaju eksplicitno, a i one se mogu zaobii. Te funkcije daju se napisati u C-u, te prenijeti sraunala na raunalo, osim onih koje neposredno oslikavaju konkretno raunalo na kojemu se radi i njegovoperativni sistem.

    Iako C odgovara mogunostima veine raunala, on je nezavisan od konkretne arhitektureraunalskog sustava. Sa malo panje lako je napisati prenosive programe, to znai programe koje moemopokrenuti bez zahtjeva za sklopovskim promjenama. Standard ini sve aspekte prenosivosti eksplicitnim, apropisuje i skup konstanti koje karakteriziraju raunalo na kojem se program vrti.

    C nije strogo tipiziran, ali kako se razvijao, njegova kontrola tipova je jaala. Originalna definicija C-ane odobrava, ali doputa zamjenu pokazivaa i cijelih brojeva; nakon dueg razdoblja i to je rijeeno, istandard zahtjeva tone deklaracije i jasne konverzije koje su inili dobri prevoditelji. Nove deklaracijefunkcija su slijedei korak u tom smjeru. Prevoditelji e upozoriti na veinu tipskih greaka, mada ne postojiautomatsko pretvaranje neusuglaenih tipova podataka. C ipak zadrava osnovnu filozofiju koju programeripoznaju; on samo zahtjeva jasno definiranje ciljeva.

    C, kao i svaki drugi jezik ima svoje nedostatke. Neki operatori imaju pogrean prioritet; neki dijelovisintakse mogli bi biti bolji. Pored svega, C se dokazao kao jedan od najkorisnijih i najsadrajnijih za velikibroj razliitih aplikacija.

    Knjiga je organizirana na slijedei nain:Poglavlje 1 je udbenik osnovnih svojstava C-a. Prvotna namjera bila je pripremanje itatelja za

    poetak rada u najkraem moguem roku, jer vjerujemo da je najbolji nain uenja jezika pisanje razliitihprograma u njemu. Baza podrazumijeva znanje steeno radom s osnovnim elementima programiranja;ovdje nema pojanjavanja u vezi s raunalom, prevoenjem, ali ni znaenja izraza kao to je n=n+1. Iakosmo pokuali da, gdje god je takvo to bilo mogue, prikaemo korisne programske tehnike, knjiga nemanamjeru biti udbenik za strukture podataka i algoritme; kad god smo bili prinueni birati, usredotoili bismose na jezik.

    Poglavlja 2 i 6 razmatraju razliite aspekte jezika C s vie detalja, te mnogo formalnije negoliPogavlje 1, iako je naglasak jo uvijek na cjelovitim programskim primjerima, a ne na izoliranim

    fragmentima. Poglavlje 2 bavi se osnovnim tipovima podataka, operatorima i izrazima. Poglavlje 3 obraujekontrolu toka: if-else, switch, while, for itd. Poglavlje 4 pokriva funkcije i programske strukture - vanjskevarijable, pravila podruja, umnoene izvorne datoteke, itd., a takoer se dotie i preprocesora. Poglavlje 5bavi se pokazivaima i aritmetikim adresama. Poglavlje 6 govori o strukturama i unijama. Poglavlje 7opisuje standardnu biblioteku, koja oprema operativni sistem jednostavnim interface-om. Ova biblioteka jedefinirana ANSI standardom kojeg podrava C program na svakom raunalu, pa se programi koji ga koristeza ulaz, izlaz i pristup drugom operativnom sistemu mogu prenijeti s sistema na sistem bez izmjena.

    Poglavlje 8 opisuje vezu izmeu C programa i operativnog sistema UNIX, usredotoivi se naulaz/izlaz, sistem datoteka i raspodjelu memorije. Iako je dio ovog poglavlja specifian za UNIX sisteme,programeri koji koriste ostale sisteme jo uvijek mogu nai koristan materijal, ukljuujui i neke detaljnijeuvide u to kako je jedna verzija standardne biblioteke opremljena, te primjedbe o prenosivosti.

    Dodatak A sadri referentni prirunik. Zvanini prikaz sintakse i semantike C-a je sam ANSIstandard. Ovaj dokument je najprije namijenjen piscima prevoditelja. Referentni prirunik ovdje prikazuje

    definiciju jezika konciznije, a ne na uobiajeni, klasian nain. Dodatak B daje sadraj standardne biblioteke,koji je potrebniji za korisnike programa nego za one koji ih prave. Dodatak C daje kratak pregled izmjenaoriginalnog jezika. U sluaju sumnje, pak, standard i vlastiti prevoditelj ostaju najkompetentniji autoriteti zajezik.

  • 7/21/2019 Programski Jezik C - K&R

    9/141

    Programski jezik C Osnovne napomene

    7

    POGLAVLJE 1: OSNOVNE NAPOMENE

    Krenimo s brzim uvodom u C. Namjera nam je bila prikazati osnovne elemente jezika kroz realneprograme, ali bez ulaenja u detalje, pravila i izuzetke. U ovom trenutku, ne pokuavamo biti op eniti kao niprecizni (podrazumijeva se da su primjeri koje namjeravamo prikazati karakteristini). elimo vas samo nanajbri mogui nain dovesti do razine kad sami moete pisati korisnike programe, a za to, trebamo seusredotoiti na osnove: varijable i konstante, aritmetiku, kontrolu toka, funkcije i osnove ulaza i izlaza.Namjerno smo izostavili iz ovog poglavlja karakteristike C-a koje su bitne za pisanje veih programa. Tuspadaju pokazivai, strukture, veliki broj operatora u C-u, nekoliko naredbi kontrole toka, te standardnabiblioteka.

    Ovaj pristup ima i nedostatke. Najuoljiviji je injenica da se ovdje ne moe nai kompletan prikazneke odreene karakteristike jezika, a baza ako nije potpuna, takoer nije efikasna. Kako prikazani primjerine koriste sasvim kapacitete C-a, oni nisu tako koncizni i elegantni kakvi bi mogli biti. Tek toliko da znate,takve smo dojmove pokuali umanjiti. Slijedei nedostatak je to e se u kasnijim poglavljima ponavljatineto iz ovog poglavlja. Smatramo da je ponavljanje majka znanja.

    U svakom sluaju, iskusni programeri e biti u mogunosti izvui najbitnije iz ovog poglavlja premasvojim potrebama. Poetnici e to nadoknaditi piui male programe, sline priloenima. Obje grupe moi ekoristiti ovo poglavlje kao bazu na kojoj e se zasnivati detaljniji opisi s poetkom u Poglavlju 2.

    1.1 Putanje u rad

    Jedini nain uenja novog programskog jezika jest pisanje programa u njemu. Prvi program kojiemo napisati isti je za sve jezike:

    Ispii rijei

    Hello, World

    Pojavila se velika prepreka: da bi je savladali, morate moi kreirati izvorni tekst, uspjeno gaprevesti, uitati, pokrenuti i pronai gdje mu se pojavljuje izlaz. U usporedbi s ovim tehnikim detaljima, kadih svladate, sve drugo je lako.

    U C-u, program za ispis "Hello, World" jest

    #include

    main(){printf("Hello, World\n");

    }

    Kako e se ovaj program pokrenuti zavisi o sistemu koji koristite. Kao specifian primjer, na UNIXoperativnom sistemu moete kreirati program u datoteci ije se ime zavrava sa ".c", kao to je hello.c, kojise zatim prevodi naredbom

    cc hello.c

    Ako niste nigdje pogrijeili, bilo da ste izostavili neki znak ili neko slovo pogreno napisali,prevoenje e se obaviti i stvorit e se izvrna datoteka s imenom a.out. Ako pokrenete a.out tipkajuinaredbu

    a.out

    on e ispisati

    Hello, World

    Na drugim sistemima, vrijedit e druga pravila; to moete priupitati nekog s iskustvom.Sad emo se pozabaviti samim programom. C program, bilo koje veliine, sastoji se od funkcija i

    varijabli. Funkcija se sastoji od naredbi koje odreuju operacije koje treba izvriti, a varijable imaju

    vrijednosti koje koristimo tijekom njihova izvrenja. C funkcije izgledaju kao potprogrami i funkcije Fortrana iliprocedure i funkcije Pascala. U naem primjeru je funkcija s imenom main. Naravno, vi ste slobodni dati

  • 7/21/2019 Programski Jezik C - K&R

    10/141

    Programski jezik C Osnovne napomene

    8

    funkcijama imena po elji, ali ime "main" ima specijalnu namjenu - program se izvrava od po etka funkcijemain. Ovo znai da svaki program mora imati "main" negdje.

    Funkcija main e obino pozivati ostale funkcije da omogue njeno odvijanje, i to neke koje ste vinapisali, a druge iz ponuenih biblioteka. Prva linija programa,

    #include

    govori raunalu da ukljui informacije o standardnoj ulazno/izlaznoj biblioteci; ova linija se pojavljujena poetku mnogih C izvornih datoteka. Standardna biblioteka je opisana u Poglavlju 7 i Dodatku B.

    Jedan nain razmjene podataka izmeu funkcija jest odreivanje funkcijske liste vrijednosti, koje sezovu argumentima pozivne funkcije. U ovom sluaju main je definirana kao funkcija koja ne oekuje nikakveargumente, to je predstavljeno praznom listom ().

    Naredbe funkcije su ograene velikim zagradama {}. Funkcija main ima samo jednu naredbu

    printf("Hello, World\n");

    Funkcija se poziva njenim imenom, a popraena je listom argumenata u zagradi. Tako, pozivamofunkciju printf argumentom "Hello, World\n". Funkcija printf je iz biblioteke koja ispisuje izlaz, u ovom sluajuniz znakova izmeu navodnika. Niz znakova izmeu dvostrukih navodnika, kao to je "Hello, World\n", zove

    se znakovni niz. U poetku emo koristiti znakovne nizove samo kao argumente za printf i ostale funkcije.Dio \n u nizu je oznaka u C-u za znak novog reda, koji kada se ispisuje pomie ispis do kraja ulijevona slijedeoj liniji. Ako izostavite \n (potencijalno koristan eksperiment, a nikako tetan), uoit ete da nakonispisa izlaza ne postoji vie nijedna linija. Morate upotrijebiti \n da bi se znak novog reda prikljuio printfargumentu; ako napiete neto kao

    printf("Hello, World");

    C prevoditelj e prijaviti greku.Nikada printf ne odreuje novu liniju automatski, ve se iz viestrukih pozivanja moe postupno

    formirati izlazna linija. Na prvi program mogao je biti ovako napisan

    #include main(){printf("Hello, ");printf("World");printf("\n");

    }

    da bi nainio isti izlaz.Primijetimo da \n predstavlja samo jedan znak. Niz kakav je \n osigurava opi mehanizam za

    predstavljanje znakova koje nazivamo specijalnima (zato to su nevidljivi ili se ne daju otipkati). Izmeuostalih nizova koje C definira su \t za tabulator, \b za povratnik (backspace), \" za dvostruke navodnike i \\ zaobrnutu kosu crtu (slash). Potpuna lista postoji u dijelu pod naslovom 2.3.

    Vjeba 1-1. Pokrenite "Hello, World" program na vaem raunalu. Igrajte se s izostavljanjemdijelova koda, samo radi poruka o grekama koje ete dobivati.

    Vjeba 1-2.to se dogaa kad niz argumenata za printf sadri \c, gdje je c neki znak koji nije na listinavedenoj gore?

    1 2 Varijable i aritmetiki izraziSlijedei program koristi formulu oC=(5/9)(oF-32) da ispie tablicu temperatura u Fahrenheitovim

    stupnjevima i njihove ekvivalente u Celsiusovim:

    0 -17

    20 -640 460 15

  • 7/21/2019 Programski Jezik C - K&R

    11/141

    Programski jezik C Osnovne napomene

    9

    80 26100 37120 48140 60160 71180 82

    200 93220 104240 115260 126280 137300 148

    Program se sastoji od definicije funkcije pod imenom main. On je dui od prvog, koji ispisuje "Hello,World", ali ne i sloeniji. Program uvodi dosta novih ideja, ukljuujui komentare, deklaracije, varijable,aritmetike izraze, petlje i formatirani izlaz.

    #include

    /* Ispii Fahrenheit-Celsius tablicu za fahr=0, 20, 40, ..., 300 */main(){int fahr, celsius;int lower, upper, step;lower=0; /* donja granica tablice tempreratura */upper=300; /* gornja granica */step=20;fahr=lower;while(fahr

  • 7/21/2019 Programski Jezik C - K&R

    12/141

    Programski jezik C Osnovne napomene

    10

    Izraunavanje programa konverzije temperature poinje s naredbama dodjele

    lower=0;upper=300;step=20;fahr=lower;

    koji predstavljaju varijable na poetne vrijednosti. Pojedinane naredbe se zavravaju tokom-zarezom.

    Svaka linija u tablici izraunava se na isti nain, pa zato koristimo petlju koja se ponavlja jednom poizlaznoj liniji; to je svrha while petlje.

    while(fahr

  • 7/21/2019 Programski Jezik C - K&R

    13/141

    Programski jezik C Osnovne napomene

    11

    printf("%3d %6d\n", fahr, celsius);

    da bi se ispisao prvi broj svake linije u polju irokom tri znamenke, te drugi u polju irokom estznamenki, kao:

    0 -1720 -640 460 1580 26

    100 37...

    Ozbiljniji problem nalazi se u injenici da koristimo aritmetiku cijelih brojeva, pa Celsiusovetemperature nisu ba egzaktne; npr., 0oF jest zapravo -17.8oC, a ne -17. U cilju rjeavanja ovakovihproblema, potrebno je upotrebljavati aritmetiku realnih brojeva (brojevi s pokretnom decimalnom tokom)umjesto cijelih. To zahtjeva odreene izmjene u programu. Postoji i druga verzija:

    #include /* Ispii Fahrenheit-Celsius tablicu za fahr=0, 20, 40, ..., 300 */main(){

    float fahr, celsius;int lower, upper, step;lower=0; /* donja granica tablice tempreratura */upper=300; /* gornja granica */step=20;fahr=lower;while(fahr

  • 7/21/2019 Programski Jezik C - K&R

    14/141

    Programski jezik C Osnovne napomene

    12

    40 4.4...

    irina i tonost ne moraju biti navedene: %6f kae da broj mora biti irok najvie est znakova; %.2fodreuje dva znaka iza decimalne toke, ali irina nije naglaena; %f jedino kazuje kako se radi o broju spominom decimalnom tokom.

    %d ispii kao decimalni cijeli broj%6d ispii kao decimalni cijeli broj, irok najvie est znakova%f ispii kao realan broj%6f ispii kao realan broj, irok najvie est znakova%.2f ispii kao realan broj, sa dva znaka iza decimalne toke%6.2f ispii kao realan broj, irok najvie est znakova, sa dva znaka iza decimalne toke

    Izmeu ostalog, printf prepoznaje %0 kao oktalni broj, %x kao heksadecimalni, %c kao znak, %skao niz znakova i %% kao %.

    Vjeba 1-3.Izmijenite program pretvorbe temperature da ispisuje zaglavlje iznad tablice.

    Vjeba 1-4.Napiite odgovarajui program za ispis tablice pretvorbe Celsiusovih u Fahrenheitovestupnjeve.

    1 3 Programska petlja forMnogo je razliitih naina na koje se dade napisati program odreene namjene. Pokuat emo

    napraviti promjenu na pretvarau temperature

    #include /* ispii Fahrenheit-Celsius tablicu */main(){

    int fahr;for(fahr=0;fahr

  • 7/21/2019 Programski Jezik C - K&R

    15/141

    Programski jezik C Osnovne napomene

    13

    Izbor izmeu while i for je slobodan, a temelji se na povoljnijoj soluciji. Najee se for koristi upetljama gdje su inicijalizacija i inkrementacija pojedinani izrazi, ali logiki povezani, to je kompaktnijenego while petlja koja ima naredbe za inicijalizaciju, uvjete i inkrementaciju meusobno razmjetene.

    Vjeba 1-5. Izmijenite program pretvorbe temperature tako da program ispie tablicu obrnutimredoslijedom, od 300 stupnjeva do 0.

    1.4 Simbolike konstante

    Moemo se posljednji put osvrnuti na pretvorbu temperature prije negoli je zaboravimo. Nije uputnaupotreba "arobnih brojeva" 300 i 20 u programu; oni donose malo podataka nekome tko bi program itaokasnije, a teko ih je zamijeniti u cijelom programu. Jedan od naina baratanja takvim brojevima je da im sedodjele imena koja e govoriti o karakteru tih brojeva. Linija #define definira simboliko ime ili simbolikukonstantu tako da bude poseban niz znakova:

    #define ime tekst koji se mijenja

    Nadalje, bilo koje pojavljivanje imena (koje nije u navodnicima i nije dio drugog imena) bit ezamijenjeno odgovarajuim tekstom koji se mijenja. Ime ima istu formu kao i ime varijable: niz slova i

    znamenki koji poinju slovom. Tekst zamjene moe biti bilo koji niz znakova; on nije ogranien na brojeve.

    #include #define LOWER 0 /* donja granica tablice */#define UPPER 300 /* gornja granica */#define STEP 20 /* veliina koraka *//* ispii Fahrenheit-Celsius tablicu */main(){

    int fahr;for(fahr=LOWER;fahr

  • 7/21/2019 Programski Jezik C - K&R

    16/141

  • 7/21/2019 Programski Jezik C - K&R

    17/141

    Programski jezik C Osnovne napomene

    15

    potpuno ekvivalentan sa

    c=(getchar()!=EOF)

    To ima neeljeni efekt u postavljanju c na 0 ili 1, zavisno od toga da li je getchar naiao na krajdatoteke (vie o ovoj temi u Poglavlju 2.)

    Vjeba 1-6.Provjeriti vrijednost izraza getchar()!=EOF.

    Vjeba 1-7.Napiite program za ispis vrijednosti EOF-a.

    1.5.2 Brojanje znakova

    Slijedei program broji znakove, slino programu kopiranja

    #include /* brojanje znakova na ulazu; prva verzija */main(){

    long nc;

    nc=0;while(getchar()!=EOF)

    nc++;printf("%ld\n", nc);

    }

    Izraz

    ++nc;

    uvodi novi operator, ++, ije je znaenje "poveaj za jedan". Moemo, dakle, umjesto nc=nc+1 pisatinc++ to je konciznije i vrlo esto mnogo efikasnije. Postoji i odgovarajui operator za smanjivanje, --.Operatori ++ i -- mogu biti i prefiks (++nc) i sufiks operatori (nc++); ove dvije formulacije mogu dati razli ite

    vrijednosti u izrazima, kao to e biti obraeno u Poglavlju 2, iako i jedna i druga poveavaju nc za jedan. Zaovaj trenutak emo se posvetiti prefiks formulaciji.Program za brojanje znakova sumira svoje rezultate u varijabli tipa long umjesto u int. Cjelobrojne

    vrijednosti long imaju barem 32 bita. Iako su na nekim raunalima int i long iste veliine, na drugim int ima16 bitova, s maksimalnom vrijednou od 32767 to je relativno mala gornja granica za broja. Specifikacijapretvorbe %ld kae printf-u da je odgovarajui argument long cjelobrojna vrijednost. Mogue je, dakako,operirati i s veim brojevima ako se upotrijebi double (float s dvostrukom tonou). Koristit emo for petljuumjesto while radi ilustracije drugaijeg pisanja petlje.

    #include /* brojanje znakova na ulazu; druga verzija */main(){

    double nc;

    for(nc=0; getchar()!=EOF; ++nc);printf("%.0f", nc);

    }

    Funkcija printf koristi %f za ispis i float i double brojeva; %.0f ne doputa ispis decimalne toke idecimala.

    Tijelo ove for petlje je prazno, zato to se cijeli posao napravi u dijelu za provjeru uvjeta iuveavanje. Meutim, gramatika C jezika zahtjeva da for naredba ima tijelo. Zasebna toka-zarez, nazvananultom naredbom, tu je da bi udovoljila tom zahtjevu. Mi smo je umetnuli u posebnu liniju kako bi bilauoljivija.

    Prije nego programiza brojanje znakova prepustimo ropotarnici povijesti, zamijetimo da ako ulazniniz nema nijednog znaka, while i for provjere jave greku pri prvom pozivanju funkcije getchar, a program

    daje nulu to je ispravan odgovor. Ovo je bitno. Jedna od komparativnih prednosti ovih petlji jest injenica daone testiraju uvjete na vrhu petlje, prije ulaska u tijelo. Programi bi se trebali inteligentno ponaati kad im sezada ulaz nulte duljine. Naredbe while i for omoguuju dobar rad programima i za te granine sluajeve.

  • 7/21/2019 Programski Jezik C - K&R

    18/141

    Programski jezik C Osnovne napomene

    16

    1.5.3 Brojanje linija

    Slijedei program broji ulazne linije. Kako smo ranije spomenuli, standardne biblioteka osigurava dase ulazni tok teksta pojavi kao niz linija i da se svaki zavrava znakom nove linije. To zapravo znai da sebrojanje linija svodi na brojanje tih znakova:

    #include /* brojanje linija na ulazu */main(){

    int c, nl;nl=0;while((c=getchar())!=EOF)

    if(c=='\n')++nl;

    printf("%d\n", nl);}

    Tijelo petlje se sada sastoji od jednog if, koji kontrolira uveavanje nl. Naredba if provjerava uvjete u

    zagradama, te ako je uvjet istinit, izvrava naredbu ili grupu naredbi (u vitiastim zagradama) koji slijedi. Jojednom smo htjeli pokazati to se ime kontrolira.Dvostruki znak jednakosti == je C notacija za uvjet jednakosti (kao u Pascalu obino = ili u Fortranu

    .EQ.). Ovaj simbol se upotrebljava da bi se razlikovao uvjet jednakosti od obinog = koji C koristi pri dodjelivrijednosti. Ovo je ujedno i upozorenje; novi programeri C programa ponekad piu = umjesto ==. Kako emove vidjeti u Poglavlju 2., rezultat je obino regularan izraz, pa prevoditelj nee upozoriti na vjerojatnugreku.

    Znak napisan u jednostrukim navodnicima predstavlja cjelobrojnu vrijednost jednaku ASCIIvrijednosti znaka. Zovemo ga znakovnom konstantom, iako je to samo drugi nain za pisanje malog cijelogbroja. Tako, npr., 'A' je znakovna konstanta; u ASCII skupu znakova njena je vrijednost 65, a internopredstavlja znak A. Evidentno je bolje pisati 'A' nego 65; znaenje je jasnije, a nije zavisan o skupu znakova.

    ESCAPE sekvence koje koristimo u konstantama nizova su jednako tako upotrebljive u znakovnimkonstantama, pa '\n' ima znaenje znaka novog reda, a u ASCII tablici ima vrijednost 10. Moete zamijetiti

    da je '\n' jedan znak, a u izrazima on predstavlja cijeli broj; s druge strane, "\n" je konstanta niza koja imasamo jedan znak. Nizovi i znakovi bit e predmetom rasprave u Poglavlju 2.

    Vjeba 1-8.Napiite program koji broji razmake, tabulatore i nove linije.

    Vjeba 1-9.Napiite program koji kopira ulaz na izlaz, pretvarajui nizove od dva ili vie razmakasamo jednim razmakom.

    Vjeba 1-10. Napiite program koji kopira ulaz na izlaz, mijenjajui svaki tabulator s \t, svakibackspace sa \b i svaku dvostruku kosu crtu s \\. Program treba te specijalne znakove uiniti vidljivim.

    1.5.4 Brojanje rijei

    etvrti u nizu korisnikih programa broji linije, rijei i znakove, uz neformalnu definiciju da je rijenizznakova koji nema razmaka, tabulatora ili znakova novog reda. Ovo je glavna verzija standardnog UNIXprograma wc (word count).

    #include #define IN 1 /* unutar rijei */#define OUT 0 /* van rijei *//* zbraja linije, rijei i znakove na ulazu */main(){

    int c, nl, nw, nc, state;state=OUT;nl=nw=nc=0;while((c=getchar())!=EOF){

    ++nc;if(c=='\n')

  • 7/21/2019 Programski Jezik C - K&R

    19/141

    Programski jezik C Osnovne napomene

    17

    ++nl;if(c==' '||c=='\n'||c=='\t')

    state=OUT;else if(state==OUT){

    state=IN;++nw;

    }}printf("%d %d %d\n", nl, nw, nc);

    }

    Pri svakom susretu s prvim znakom u rijei, on odbroji jednu rijevie. Varijabla state kae da li jeprogram trenutno unutar rijei ili ne; njeno poetno stanje je OUT, odnosno "van rijei". Simbolikekonstante IN i OUT nam vie odgovaraju negoli brojane vrijednosti 0 i 1, jer, kako smo vespomenuli, ineprogram itljivijim. U ovako malom programu to nam nije odvie bitno, ali u veim programima, poveanjejasnoe programa je vrijedno dodatnog napora da se program napie od poetka u tom stilu. Vi ete istotako zakljuiti da je lake mijenjati programe gdje se brojevi pojavljuju kao simbolike konstante.

    Linija

    nl=nw=nc=0;

    postavlja sve tri varijable na nulu. To nije nikakva iznimka, ve posljedica injenice da jedodjeljivanje izraz koji ima vrijednost i obavlja se zdesna nalijevo. Umjesto toga mogli smo pisati

    nl=(nw=(nc=0));

    Operator || znai ILI (OR), pa linija

    if(c==' '||c=='\n'||c=='\t')

    znai "ako je c razmak ili znak za novi red ili tabulator" (prisjetimo se \t oznaka za tabulator). Postojiodgovarajui operator && za I (AND); njegov je prioritet vei nego za ||. Izrazi vezani s && ili || raunaju se

    slijeva nadesno (!!!!), a garantira se prekid raunanja

    im bude poznata to

    nost ili neto

    nost. Tako, ako je crazmak, nije potrebno ispitivati da li je znak za novu liniju i tabulator, pa se ti testovi preska u. To nije

    previe bitno za prikazani sluaj, ali jest za kompliciranije sluajeve to emo ubrzo vidjeti.Primjer takoer pokazuje else, naredbu koja obavlja "neto drugo" ako je uvjetni dio if naredbe

    neistinit. Opa forma je

    if(izraz)naredba1

    elsenaredba2

    Izvodi se jedna i samo jedna naredba od dviju pridruenih if-else konstrukciji. Ako je izraz istinit,izvodi se naredba1; ako nije izvodi se naredba2. Svaka naredba moe biti jedna ili vie njih u viti astim

    zagradama. U programu za brojanje rijei, nakon else imamo if koji kontrolira dvije naredbe unutar viti

    astihzagrada.

    Vjeba 1-11.Kako biste provjerili program za brojanje rijei? Koje su vrste ulaznih podatakanajpogodnije za otkrivanje netonosti ako postoje?

    Vjeba 1-12.Napiite program koji ispisuje svoj ulaz tako da bude po jedna rijeu svakoj liniji.

    1.6 Polja

    Napiimo program koji zbraja pojavljivanja svake znamenke, specijalnih znakova (razmaci, tabulatorii sl.) i svih drugih znakova. To nije upotrebljiv primjer, ali nam omoguuje ilustraciju vieznanu snagu C-a ujednom programu.

    Postoji dvanaest kategorija ulaza, pa je pogodnije koristiti jedno polje koje sadri broj pojavljivanjasvake znamenke, nego deset posebnih varijabli. Evo jedne verzije programa:

  • 7/21/2019 Programski Jezik C - K&R

    20/141

    Programski jezik C Osnovne napomene

    18

    #include /* zbraja znamenke, specijalne znakove i sve druge */main(){

    int c, i, nwhite, nother;int ndigit[10];

    nwhite=nother=0;for(i=0;i='0'&&c

  • 7/21/2019 Programski Jezik C - K&R

    21/141

    Programski jezik C Osnovne napomene

    19

    Uzorak

    if(uvjet1)naredba1

    elseif(uvjet2)

    naredba2elseif(uvjet3)

    naredba3......

    ......else

    naredban

    se esto susree u programima kao nain izraavanja vieznanih rjeenja. Uvjeti se provjeravajupo redu odozgo nadolje, sve dok neki ne bude zadovoljen; tu se odgovarajua naredba izvrava, akonstrukcija se zavrava (svaka se naredba moe sastojati od vie naredbi zatvorenih zagradama). Ako nijedan od uvjeta nije ispunjen, izvrava se naredba iza zadnjeg else ako ovaj postoji. Ako zadnji else i

    naredba nisu napisani, kao u naem programu za brojanje rijei, ne obavlja se nita. Moe biti bilo koji broj

    elseif(uvjet)

    naredba

    grupa izmeu inicijalnog if i zadnjeg else.To je stilsko pitanje, ali je preporuljivo praviti konstrukcije na prikazani nain. Naredba switch, o

    kojoj e biti rijei u Poglavlju 3, odreuje drugaiji nain pisanja vieznanog grananja koji je osobitopogodan ako neki cijeli broj ili znakovni izraz odgovara jednoj ili nizu konstanti. Tome nasuprot, pokazatemo switch verziju ovog programa u dijelu pod naslovom 3.4.

    Vjeba 1-13.Napiite program za ispis histograma duina rijei na ulazu. Iscrtavanje histograma sa

    horizontalnim linijama nije teak zadatak, ali je okomita orijentacija prilian izazov.

    Vjeba 1-14. Napiite program za ispis histograma frekvencija pojavljivanja razliitih znakova naulazu.

    1.7 Funkcije

    U C-u funkcija je ekvivalentna potprogramu ili funkciji u Fortranu te proceduri ili funkciji u Pascalu.Funkcija osigurava prikladan nain vrenja svakojakih izrauna, ije rezultate kasnije moemo upotrijebitibilo gdje. Pravilno zadanim funkcijama, mogue je posao obaviti bez poznavanja unutarnje strukturefunkcije; saznanje da je posao korektno obavljen je vie nego dovoljno. C ini upotrebu funkcije lakom,prikladnom i efikasnom; esto ete se susretati s kratkim funkcijama definiranim i pozvanim samo jednom,tek radi pojanjavanja dijelova koda.

    Dosad smo koristili samo ponuene funkcije tipa printf, getchar i putchar; dolo je vrijeme da saminapiemo nekoliko funkcija. Kako C nema eksponencijalni operator kao ** u Fortranu, predstavimomehanizam definiranja funkcija piui funkciju power(m,n) da bismo cijeli broj m podigli na pozitivnicjelobrojni eksponent n. Znai, vrijednost od power(2,5) je 32. Ova funkcija nije za praktinu primjenu, zatoto eksponent uzima samo pozitivne male cijele brojeve, ali je dovoljno dobra za ilustraciju (inae,standardna biblioteka ima funkciju pow(x,y) koja rauna x^y).

    Evo funkcije power i glavnog programa za njeno testiranje, kako bi mogli razluiti itavu njenustrukturu.

    #include int power(int m, int n);/* test power funkcije */main(){

    int i;for(i=0;i

  • 7/21/2019 Programski Jezik C - K&R

    22/141

    Programski jezik C Osnovne napomene

    20

    printf("", i, power(2,i), power(-3,i));return 0;

    }/* power: podie bazu na n-ti eksponent n>=0 */int power(int base, int n){

    int i,p;

    p=1;for(i=1;i

  • 7/21/2019 Programski Jezik C - K&R

    23/141

    Programski jezik C Osnovne napomene

    21

    Imena parametara ne moraju se slagati. Zapravo, imena parametara u prototipu funkcije suproizvoljna, pa se dade napisati i

    int power(int, int);

    Uredno odabrana imena ine program dokumentiranim, pa emo ih radije koristiti.

    Iz povijesti razvoja C-a znamo da je najvea razlika izmeu ANSI C programa i ranijih verzija unainu na koji su funkcije predstavljene i definirane. U originalnoj definiciji C programa, power funkcija jemogla biti napisana ovako:

    /* power: die bazu na n-ti eksponent *//* (starija verzija) */power(base, n)int base, n;{

    int i, p;p=1;for(i=1;i=0; verzija 2 */int power(int base, int n){

    int p;for(p=1;n>0;--n)

    p=p*base;

    return p;}

  • 7/21/2019 Programski Jezik C - K&R

    24/141

    Programski jezik C Osnovne napomene

    22

    Parametar n se koristi kao privremena varijabla, a vrijednost mu se smanjuje dok ne doe do nule;

    ne postoji vie potreba za varijablom i. Meutim, to god uradili sa n unutar funkcije power, nema nikakvogutjecaja na argument sa kojim je power prvobitno pozvan.

    Kada bude potrebno, mi emo omoguiti promjenu varijable unutar pozvane funkcije. Pri pozivujednostavno poaljemo adresu varijable koja se uvodi kao argument (zapravo se radi o pokazivau na

    varijablu), pa pozvana funkcija indirektno dohvaa varijablu i po potrebi mijenja. O pokazivaima(pointerima) vie emo govoriti u Poglavlju 5.Kod polja je pria neto drugaija. Kad se ime polja koristi kao argument, vrijednost koja se predaje

    funkciji je lokacija ili adresa poetka polja - tu nema kopiranja elemenata polja. Upisujui vrijednost kaoindeks, funkcija prihvatiti bilo koji element polja. Ovo e biti tema slijedeih razmatranja.

    1.9 Polja znakova

    Najjednostavniji tip polja u C-u jest polje znakova. Radi ilustracije upotrebe polja znakova i funkcijakoje barataju sa njima, napisat emo program koji ita ulaz i ispisuje najduu liniju. Glavne crte su prilinojednostavne

    while(ima jo linija)

    if(ova linija je dua od dosada najdue){pohrani jepohrani njenu duinu

    }ispii najduu liniju

    Ovaj prikaz uglavnom razjanjava kako se program prirodno rastavlja na dijelove. Jedan dio itanovu liniju, drugi je analizira, slijedei je pamti, a ostali kontroliraju proces.

    Obzirom da se zadaci tako lako dijele, bilo bi dobro napisati odgovarajui program. Prema tome,napiimo najprije funkciju getline koja uzima slijedeu liniju s ulaza. Trudit emo se napraviti funkciju koja bibila upotrebljiva i u nekom drugom kontekstu. U najmanju ruku, getline treba vraati signal o tome da sedolo (u itanju sa ulaza) do kraja datoteke; korisnije bi bilo vraati duinu linije ili nulu ako je nastupio krajdatoteke. Nula je prihvatljiva vrijednost za kraj jer ta vrijednost nema smisla kao duina linije. Svaka linija

    ima barem jedan znak, makar to bila oznaka nove linije (i to je linija duine 1). Kad pronaemo liniju koja jedua od najdue prethodne, moramo je pohraniti. Ovo nam obavlja druga funkcija, copy, koja kopira novi redna sigurno mjesto. Na kraju, treba nam osnovna funkcija main za manipuliranje funkcijama getline i copy.Evo rjeenja:

    #include #define MAXLINE 1000 /* maksimalna duina linije */

    int getline(char line[], int maxline);void copy(char to[], char from[]);

    /* ispis najdue linije s ulaza */main(){

    int len;int max;char line[MAXLINE];char longest[MAXLINE];max=0;while((len=getline(line, MAXLINE))>0)

    if(len>max){max=len;copy(longest, line);

    }if(max>0) /* ima linija */

    printf("%s", longest);return 0;

    }

  • 7/21/2019 Programski Jezik C - K&R

    25/141

    Programski jezik C Osnovne napomene

    23

    /* getline: uitava liniju u s, vraa duinu */int getline(char s[], int lim){

    int c, i;for(i=0;i

  • 7/21/2019 Programski Jezik C - K&R

    26/141

    Programski jezik C Osnovne napomene

    24

    Ne postoji nain za onoga koji rabi funkciju getline da unaprijed zna koliko duga moe biti ulaznalinija, pa getline mora sprijeiti preoptereenje. S druge strane, onaj koji koristi copy vezna (ili moe znati)koliko su dugaki nizovi, pa smo odluili da od ove funkcije ne traimo provjeru greaka.

    Vjeba 1-16. Ispravite (doradite) osnovnu rutinu programa za ispis najdue linije kako bi se mogleispisivati neogranieno duge ulazne linije i to je god mogue vie teksta.

    Vjeba 1-17.Napiite program za ispis svih ulaznih linija duih od 80 znakova.

    Vjeba 1-18.Napiite program za brisanje razmaka i tabulatora iz ulaznih linija, a koji e isto takouklanjati prazne linije.

    Vjeba 1-19. Napiite funkciju reverse(s) koja obre niz znakova s. Upotrijebite je u programu kojiobre ulaznu liniju.

    1.10 Vanjske varijable i podruja

    Varijable u main funkciji kao to su line, longest itd. su vlastite ili lokalne za funkciju main. Kako sustvorene unutar main-a, nijedna im druga funkcija ne moe direktno pristupiti. Isto vrijedi i za varijable u

    drugim funkcijama; npr. varijabla i u getline funkciji nije povezana s i u copy funkciji. Svaka lokalna varijablastvara se pri pozivu funkcije, a nestaje kad se funkcija izvri. Zato su takve varijable poznate pod imenomautomatske varijable, ako se prati terminologija iz drugih programskih jezika. Mi emo koristiti izrazautomatsko pozivanje koje e se odnositi na te lokalne varijable (u Poglavlju 4 se govori o tipu static, ijelokalne varijable zadravaju svoje vrijednosti izmeu poziva).

    Kako se automatske varijable javljaju s pozivanjem funkcija, one ne dre svoje vrijednosti izmeudva poziva i moraju biti tono namjetene pri svakom ulazu. Ako nisu namjetene, one e prenositi i krivepodatke.

    Nasuprot automatskim varijablama, mogue je definirati varijable koje su vanjske za sve funkcije,dakle varijable kojima se moe pristupiti pomou imena iz bilo koje funkcije (ova tehnika je slina FortranskojCOMMON varijabli i Pascalskim varijablama u krajnjem bloku). Kako su vanjske varijable odasvud vidljive,one se mogu rabiti umjesto liste argumenata za komunikaciju podacima izmeu funkcija. Nadalje, kako suvanjske varijable stalno prisutne, tj., ne stvaraju se i nestaju pozivima i zatvaranjima funkcija, one dre svojevrijednosti i nakon zatvaranja funkcija koje su ih postavile.

    Vanjska varijabla mora biti tono definirana izvan svih funkcija ime se za nju odreuje lokacija.Varijabla takoer mora biti predstavljena i u svakoj funkciji koja je eli koristiti ime se odreuje tip varijable.Deklaracija moe biti jedan jasan extern izraz ili izraz koji je razumljiv iz konteksta. Da bi mogli konkretnodiskutirati, napiimo program za najduu liniju s line, longest i max kao vanjskim varijablama. Ovo zahtjevaizmjenu poziva, deklaracija i tijela svih triju funkcija.

    #include

    #define MAXLINE 1000 /* maksimalna duina linije */

    int max; /* dosad najvea duina linije */char line[MAXLINE]; /* tekua linija */char longest[MAXLINE]; /* dosad najvea linija */

    int getline(void);void copy(void);

    /* ispisuje najduu liniju; posebna verzija */main(){

    int len;extern int max;extern char longest[];max=0;while((len=getline())>0)

    if(len>max){

    max=len;copy();

  • 7/21/2019 Programski Jezik C - K&R

    27/141

    Programski jezik C Osnovne napomene

    25

    }if(max>0) /* ima linija */

    printf("%s", longest);return 0;

    }

    /* getline; posebna verzija */int getline(void){int c,i;extern char line[];for(i=0; (i

  • 7/21/2019 Programski Jezik C - K&R

    28/141

    Programski jezik C Osnovne napomene

    26

    Moemo rei da smo dosad objedinili sve ono to se naziva sutinom C-a. S ovim mnotvomizgraenih blokova, mogue je pisati korisnike programe razumne duine i to bi bila dobra ideja ako imatedovoljno vremena provesti je u djelo. Vjebe koje slijede predlau malo kompleksnije programe odprikazanih u ovom poglavlju.

    Vjeba 1-20. Napiite program detab za zamjenu tabulatora odgovarajuim brojem razmaka.

    Odredite fiksni broj razmaka za stop-tabulator, npr., n. Da li n treba biti varijabla ili simboliki parametar?

    Vjeba 1-21.Napiite program entab za zamjenu razmake minimalnim brojem tabulatora i razmaka.Koristite iste tabulatore kao i za detab. Kad bi i tabulator i razmak bili dovoljni da se dostigne novi stop-tabulator, kojem znaku bi dali prednost?

    Vjeba 1-22. Napiite program koji prelama duge ulazne linije na dvije ili vie kraih linija nakonzadnjeg znaka koji nije razmak, a koji se javlja prije n-te ulazne kolone. Uvjerite se da va program pravilnotretira duge linije, te da nema razmaka i tabulatora prije odreene kolone.

    Vjeba 1-23. Napiite program koji uklanja komentare iz C programa. Ne zaboravite pravilnoiskoristiti znakovne nizove za komentare i znakovne konstante. C komentare ne treba umetati.

    Vjeba 1-24. Napiite program za provjeru osnovnih sintaksnih greaka u C programu, kakve suzagrade, navodnici (jednostruki i dvostruki) i komentari. Ovo je zahtjevan program ako se radi uopeno.

  • 7/21/2019 Programski Jezik C - K&R

    29/141

    Programski jezik C Tipovi, operatori i izrazi

    27

    POGLAVLJE 2: TIPOVI, OPERATORI I IZRAZI

    Varijable i konstante su osnovni oblici podataka s kojima se radi u programu. Deklaracije imaju popisvarijabli koje e se rabiti, odreuju im tip, te eventualno njihovu poetnu vrijednost. Operatori govore to e snjima biti uinjeno. Izrazi kombiniraju varijable i konstante kako bi proizveli nove vrijednosti. Tip nekogobjekta odreuje skup vrijednosti koje on moe imati i operacije koje se nad njim mogu izvravati. U ovompoglavlju e se, pored toga, govoriti i o formiranju blokova.

    ANSI standard je nainio mnogo neznatnih izmjena i dodataka osnovnim tipovima i izrazima.Uvedene su signed i unsigned forme za sve tipove cijelih brojeva, te obiljeavanje konstanti tipa unsigned iheksadecimalnih znakovnih konstanti. Operacije s realnim brojevima mogu se vriti s jednostrukom idvostrukom tonou (postoji tip long double za dvostruku tonost). Konstante nizova daju se povezivatitokom prevoenja. Nizovi dobiveni pobrojavanjem postali su dio jezika. Objekti mogu biti deklarirani kaoconst, to ih uva od promjene. Pravila za automatsku pretvorbu izmeu aritmetikih tipova proirena sukako bi se operiralo s veim izborom tipova.

    2.1 Imena varijabli

    Mada se u Poglavlju 1 nismo toga dotakli, napomenimo kako postoje neka ogranienja vezana za

    imena varijabli i simbolikih konstanti. Ime se sastoji od slova i znamenki pri emu prvi znak mora biti slovo.Podcrta ("_" - underscore) se uvaava kao slovo to je ponekad korisno jer poveava itljivost kod varijabli sdugim imenima. Ipak, ne poinjite imena varijabli podcrtom jer rutine iz standardne biblioteke esto koristetakva imena. Velika i mala slova se razlikuju, pa x i X nisu isto ime. Praksa je u C-u da se mala slova rabeza imena varijabli, a velika slova za simbolike konstante.

    Barem prvih 31 znakova nekog imena jesu bitni znakovi. Za imena funkcija i vanjskih varijabli brojmora biti manji od 31 jer se imena vanjskih varijabli mogu koristiti prevoditelja na strojni jezik (assembler) iuitavaa (loader) nad kojima program nema kontrolu. Kod vanjskih imena standard garantirajednoznanost samo za prvih 6 znakova. Kljune rijei kao to su if, else, int, float, itd. su rezervirane i nemogu se upotrebljavati kao imena varijabli. One moraju biti pisane malim slovima.

    Preporuka je koristiti takva imena iz kojih je vidljiva namjena varijable, a da nisu meusobno slina utipografskom smislu. Naa je politika koristiti kratka imena za lokalne varijable, posebice za petlje, a dua zavanjske varijable.

    2.2 Tipovi i veliine podataka

    U C-u postoji nekoliko osnovnih tipova podataka:

    char jedan byte, jedan znak iz skupa znakovaint cjelobrojna vrijednost, odnosi se na prirodnu veliinu cijelih brojeva na raunalufloat realni broj s jednostrukom tonoudouble realni broj s dvostrukom tonou

    Pored toga, postoje i kvalifikatori koji se pridruuju nabrojanim osnovnim tipovima. Tako se short ilong pridruuju cijelim brojevima:

    short int sh;long int counter;

    Rijeint moe se izostaviti u ovakvim deklaracijama, ali se obino pie.Htjeli smo sa short i long osigurati razliite duine cijelih brojeva, uglavnom tamo gdje za to postoji

    valjan razlog; int je prirodna veliina za svako pojedino raunalo. Tip short uglavnom ima 16 bita, long 32bita, a int ili 16 ili 32. Svaki prevoditelj ima slobodu biranja veliine koja odgovara sklopovlju na kojemu radi,uz ogranienja da short i int moraju biti najmanje 16 bita, long najmanje 32 bita, te da short ne smije biti duiod int koji opet ne smije biti dui od long.

    Kvalifikatori signed i unsigned mogu se pridruiti tipu char ili bilo kojem cijelom broju. Brojevi tipaunsigned su uvijek pozitivni ili jednaki nuli i za njih vrijedi aritmetiki zakon modula 2n, gdje je n broj bitova utipu. Tako, primjerice, ako char ima 8 bitova, varijable tipa unsigned char imaju vrijednost izmeu 0 i 255,

    dok varijable tipa signed char imaju vrijednost izmeu -128 i 127. Bilo da je char kvalificiran kao signed iliunsigned, on je ovisan o raunalu, a znakovi koji se ispisuju su uvijek pozitivni.

  • 7/21/2019 Programski Jezik C - K&R

    30/141

  • 7/21/2019 Programski Jezik C - K&R

    31/141

    Programski jezik C Tipovi, operatori i izrazi

    29

    Znakovna konstanta '\0' predstavlja znak ija je vrijednost nula (u brojevnom smislu). esto se pieupravo '\0' umjesto 0 kako bi se naglasila znakovna priroda nekog izraza, ali brojevna vrijednost mu je nula.

    Konstantni izraz je izraz koji sadri samo konstante. Takvi se izrazi daju izraunati prilikomprevoenja, a prije samog pokretanja programa, pa se sukladno tome mogu rabiti na svakom mjestu gdje semoe pojaviti konstanta, kao npr.

    #define MAXLINE 1000char line[MAXLINE];

    ili

    #define LEAP 1 /* u prijestupnim godinama */int dani[31+28+LEAP+31+30+31+30+31+31+30+31+30+31];

    Znakovni nizovi su nizovi nula i vie znakova omeenih dvostrukim navodnicima, kao

    "Ja sam niz"

    ili

    "" /* prazan niz */

    Navodnici nisu dio niza, vese koriste kako ograniili. Isti escape nizovi koji se rabe u znakovnimkonstantama pojavljuju se i u nizovima; '\"' predstavlja dvostruki navodnik. Znakovni se nizovi mogu povezatiprilikom prevoenja

    "Hello, " "World"

    je isto to i

    "Hello, World"

    Ova osobina korisna je pri radu s velikim nizovima jer se mogu podijeliti na vie osnovnih linija.Tehniki, znakovni niz je polje znakova. Interno predstavljanje niza ima na kraju nulu, odnosno, znak'\0', tako da fiziko pohranjivanje niza zahtjeva jedan znak vie od znakova napisanih meu navodnicima. Tone znai da nizovi imaju nekakvo ogranienje u smislu duine, ali programi moraju pregledati cijeli niz kakobi je odredili. Funkcija strlen(s) iz standardne biblioteke programa, vraa duinu znakovnog niza s, pri emune rauna zavrnu nulu (znak '\0'). Evo nae verzije:

    /* strlen: vraa duinu niza */int strlen(char s[]){

    int i;

    i=0;while(s[i]!='\0')

    ++i;return i;}

    Ostale funkcije nizova i strlen deklarirane su u standardnom zaglavlju . Treba biti oprezan ipraviti razliku izmeu znakovne konstante i niza koji ima samo jedan znak; 'x' nije isto to i "x". Prvi znakpredstavlja cjelobrojnu vrijednost znaka x u strojnom skupu znakova (bilo da se radi o ASCII ili bilo kojemdrugom). Drugi je polje znakova koje ima jedan znak (x) i '\0'.

    Postoji jo jedna vrsta nizova, tzv. nizovi dobiveni pobrojavanjem (enumerate). Pobrojavanje jeformiranje liste konstantnih cjelobrojnih vrijednosti, kao u

    enum boolean{NO, YES};

    Prvi naziv u enum listi ima vrijednost 0, drugi 1. Da imamo jo koji element on bi imao vrijednost 2itd. dok se god eksplicitno ne zada neka druga vrijednost. Progresija ide od one vrijednosti koja je posljednjaeksplicitno zadana (inae od 0) kao u npr.

  • 7/21/2019 Programski Jezik C - K&R

    32/141

  • 7/21/2019 Programski Jezik C - K&R

    33/141

    Programski jezik C Tipovi, operatori i izrazi

    31

    2.5 Aritmetiki operatori

    Binarni aritmetiki operatori su +, -, *, /, i modul operator %. Izraz

    x%y

    daje ostatak pri dijeljenju x sa y, a jednak je nuli ako je x djeljivo sa y. U primjeru, godina se smatraprestupnom ako je djeljiva s 4, ali ne sa 100, osim ako nisu djeljive s 400

    if((godina%4==0&&godina%100!=0||godina%400==0)printf("%d je prestupna godina\n", godina);

    elseprintf("%d nije prestupna godina\n");

    Operator % ne moe biti pridruen tipovima float i double. Smjer zaokruivanja (ili odsjecanja?!) zaoperator / i predznak rezultata operacije % ovisni su o tipu raunala za negativne operande kao i kod pojaveprekoraenja i potkoraenja (overflow i underflow).

    Binarni operatori + i - imaju isti prioritet, koji je nii od prioriteta operatora *, / i %, a koji opet imajunii prioritet od unarnih operatora + i -. Aritmetiki su operatori asocijativni slijeva nadesno.

    Tablica 2-1, na kraju poglavlja, prikazuje prioritete i asocijativnost svih operatora.

    2.6 Relacijski i logiki operatori

    Relacijski operatori su >, >=,

  • 7/21/2019 Programski Jezik C - K&R

    34/141

  • 7/21/2019 Programski Jezik C - K&R

    35/141

    Programski jezik C Tipovi, operatori i izrazi

    33

    pohranjena u znakovnim varijablama moe se interpretirati kao negativna vrijednost na nekim raunalima, apozitivna na drugim. Zbog prenosivosti (portabilnosti) treba obvezno ukljuiti signed ili unsigned kvalifikatoreako se neznakovni podatak pohranjuje u char varijablu.

    Relacijski izrazi kao i>j i logiki izrazi povezani s && ili || su definirani tako da imaju vrijednost 1 akosu toni, a 0 ako nisu. U tom smislu, dodjela

    d=c>='0'&&c

  • 7/21/2019 Programski Jezik C - K&R

    36/141

    Programski jezik C Tipovi, operatori i izrazi

    34

    za pretvorbu vrijednosti n u double prije negoli se nad njim obavi sqrt. Pripomenimo da cast prevodivrijednost n u navedeni tip pri emu se n ne mijenja. Cast operator ima visoki prioritet kao i drugi unarnioperatori, to emo pokazati tablicom na kraju ovog poglavlja.

    Ako su argumenti deklarirani funkcijskim prototipom kako se i oekuje, deklariranje pokreeautomatsku pretvorbu svih argumenata prilikom poziva funkcije. Tako, dani model funkcije za sqrt

    double sqrt(double);

    pri pozivu

    root2=sqrt(2);

    pretvara cijeli broj 2 u vrijednost 2.0 tipa double bez upotrebe operatora cast.U standardnoj biblioteci postoji mali generator sluajnih brojeva i funkcija za pokretanje, a slijedei

    primjer ilustrira operator cast

    unsigned long int next=1;

    /* rand: vraa sluajni cijeli broj iz intervala [0,32767] */

    int rand(void){next=next*1103515245+12345;return (unsigned int) (next/65536)%32768;

    }

    /* srand: postavljanje parametra za rand funkciju */void srand(unsigned int pocetak){

    next=pocetak;}

    Vjeba 2-3.Napisati funkciju htoi(s), koja pretvara niz heksadecimalnih brojeva (ukljuujui opcijske0x ili 0X) u njenu ekvivalentnu cjelobrojnu vrijednost. Doputene znamenke su [0-9], [a-f] ili [A-F].

    2.8 Operatori uveavanja i umanjivanja (inkrementiranja idekrementiranja)

    C ima dva neuobiajena operatora za uveavanje i smanjivanje (za jedan) varijabli. Operatorinkrementiranja ++ dodaje 1 svom operandu, dok operator dekrementiranja oduzima 1. esto emo koristiti++ za uveavanje varijabli kao u

    if(c=='\n')++nl;

    Neobinost ovih operatora jest da se mogu koristiti kao prefiks operatori (++n) ili kao sufiks (n++).Uinak je u oba sluaja jednak - varijabla se uvea za jedan. Meutim, izraz ++n uveava vrijednost n prije

    negoli njegova vrijednost bude upotrijebljena (pretpostavimo da je ++n dio neke relacije ili jednakosti), a n++nakon koritenja. To zapravo znai da ta dva izraza nikako ne moemo smatrati ekvivalentnima osim akonisu izdvojene programske linije. Neka je n 5, tada

    x=n++;

    postavlja x na 5, dok

    x=++n;

    postavlja x na 6. U oba sluaja, n postaje 6. Operatori uveavanja i umanjivanja pridjeljuju se samovarijablama; izraz kakav je (i+j)++ jest nekorektan.

    U sluaju kad se odreena vrijednost ne koristi veje bitno samo uveanje kao

    if(c=='\n')nl++;

  • 7/21/2019 Programski Jezik C - K&R

    37/141

    Programski jezik C Tipovi, operatori i izrazi

    35

    prefiks i sufiks oblik izraza postaju ekvivalentni. Ima situacija, meutim, kad se jedan ili drugi ciljano

    zovu. Primjerom kazano, nainimo prispodobu funkcije squeeze(s, c) koja uklanja znak c kad god se pojaviu nizu s.

    /* squeeze: brisanje svih c iz s */

    void squeeze(chars[], int c){int i,j;

    for(i=j=0;s[i]!='\0';i++)if(s[i]!=c)

    s[j++]=s[i];s[j]='\0';

    }

    Za svaki znak razliit od c, operator uveava j da bi prihvatio slijedei znak. Ovo je potpunoekvivalentno s

    if(s[i]!=c){

    s[j]=s[i];j++;}

    Slijedei primjer je slina konstrukcija iz getline funkcije o kojoj je vebilo rijei u Poglavlju 1, gdjedio programa

    if(c=='\n'){s[i]=c;++i;

    }

    moe biti napisan i kao

    if(c=='\n')s[i++]=c;

    Kao trei primjer, prispodobimo standardnu funkciju strcat(s, t), koja spaja kraj znakovnog niza s spoetkom niza t. Funkcija strcat pretpostavlja da ima dovoljno mjesta u s da smjesti oba niza. Kako smo venapisali, strcat ne vraa nikakvu vrijednost osim pokazivaa (pointera) na rezultirajui znakovni niz.

    /* strcat: povezivanje znakovnih nizova */void strcat(char s[], char t[]){

    int i, j;

    i=j=0;while(s[i]!='\0') /* Gdje je kraj niza s ? */

    i++;while((s[i++]=t[j++])!='\0') /* prebaci t */

    ;}

    Kada se znakovi prebacuju iz t u s, sufiks ++ pridruuje se i varijabli i i varijabli j kako bi smo bilisigurni da su u poziciji za naredni prolaz kroz petlju.

    Vjeba 2-4. Napisati alternativnu inaicu funkcije squeeze(s1, s2) koja brie svaki znak u s1 kojipostoji u s2.

    Vjeba 2-5.Napisati funkciju any(s1, s2) koja vraa prvo mjesto u nizu s1 gdje se nalazi bilo kojiznak iz niza s2 ili -1 ako niz s1 nema nijednog znaka iz niza s2 (funkcija strcpbrk iz standardne bibliotekeradi isto, osim to vraa pokazivana mjesto).

  • 7/21/2019 Programski Jezik C - K&R

    38/141

    Programski jezik C Tipovi, operatori i izrazi

    36

    2.9 Operatori za manipulaciju bitovima

    C osigurava est operatora za rad s bitovima. Oni rade samo s integralnim operandima kao to suchar, short, int i long, bez obzira bili oni signed ili unsigned tipa. To su

    & binarni I (AND)

    | binarni ILI (OR)^ binarno EXILI (XOR)> desni pomak (right shift)~ jedinini komplement (unarni)

    Operator binarno AND & najee se rabi za maskiranje bitova. Tako

    n=n&0177;

    postavlja na nulu sve osim najniih 7 bitova n.Operatorom binarno OR | moemo birati bitove koje postavljamo na 1. Tako

    x=x|SET_ON;

    postavlja u varijabli x na 1 one bitove koji su 1 u SET_ON.Ekskluzivno ILI, ^, je operator koji postavlja 1 na mjestima na kojima operandi imaju razliite bitove,

    a nule gdje su bitovi isti. Moemo napisati

    x=x^x;

    elimo li x postaviti na nulu.Mora se praviti razlika izmeu operatora za manipuliranje bitovima & i |, te logikih operatora && i ||,

    koji raunaju slijeva nadesno istinitost izraza. Npr., ako je x=1, a y=2, tada je x&y=0 dok je x&&y=1.Operatori pomaka (shift) > odreuju lijevi i desni pomak njihovog lijevog operanda pomou

    broja pozicija bitova kojeg daje desni operand, obavezno pozitivan. Zato x>(p+1-n))&~(~0(p+1-n) pomie eljeno polje na desnu stranu rijei. ~0 ima samo jedan bit. Pomiui gaulijevo n pozicija sa ~0

  • 7/21/2019 Programski Jezik C - K&R

    39/141

    Programski jezik C Tipovi, operatori i izrazi

    37

    Vjeba 2-7.Napiite funkciju invert(x, p, n) koja vraa x sa n bitova koji poinju na invertiranoj ppoziciji, ne mijenjajui druge bitove.

    Vjeba 2-8. Napiite funkciju rightrot(x, n) koja vraa vrijednost cjelobrojnog x rotiranog udesnopomou n bit pozicija.

    2.10 Operatori i izrazi dodjeljivanja vrijednosti

    Izrazi kakav je

    i=i+2;

    u kojima je varijabla na lijevoj strani jedan od operanda na desnoj, mogu se pisati u komprimiranomobliku

    i+=2;

    Operator += naziva se operatorom dodjele vrijednosti.Veina binarnih operatora (operatori kao +, dakle, koji imaju lijevi i desni operand) imaju

    odgovarajui operator dodjele vrijednosti op=, pri emu je op jedan od

    + - * / % > & ^ |

    Ako su imamo izraze izraz1 i izraz2, tada je

    izraz1 op=izraz2;

    ekvivalentno sa

    izraz1=(izraz1)op(izraz2);

    osim to se izraz1 rauna samo jedanput. Primijetimo zagrade oko izraz2:

    x*=y+1;

    jest

    x=x*(y+1);

    a ne

    x=x*y+1;

    Primjera radi, napisat emo funkciju bitcount koja prebrojava jedinice u binarnom obliku cjelobrojnevrijednosti argumenta.

    /* bitcount: broji jedinice binarnog broja */int bitcount(unsigned x);{

    int b;

    for(b=0;x!=0;x>>=1)if(x&01)

    b++;return b;

    }

    Prijavom argumenta kao unsigned, osiguravamo da se desnim pomakom slobodni bitovi ispunjavajunulama, neovisno o raunalu na kojemu pokreemo program.

  • 7/21/2019 Programski Jezik C - K&R

    40/141

    Programski jezik C Tipovi, operatori i izrazi

    38

    Osim kratkoe i konciznosti, operatori dodjele vrijednosti imaju prednost u komunikaciji s onim kojiita ili prouava program. Uistinu je lake shvatiti konstrukciju tipa "poveaj i za 2" negoli "uzmi i, dodaj 2, arezultat vrati u i". Stoga je izraz i+=2 itljiviji nego i=i+2. Pored toga, za kompleksnije izraze kakav je

    yyval[yypv[p3+p4]+yypv[p1+p2]]+=2;

    operator dodjele vrijednosti ini kod lakim za razumijevanje, jer itatelj ne mora provjeravati da li sudva duga izraza zapravo jednaka. Operator dodjele vrijednosti ima uinkovitije djelovanje od drugekonstrukcije jer je prevedeni kod efikasniji. Vesmo primjere rabili u programima, najee kao dio izraza

    while((c=getchar())!=EOF)...

    Ostali operatori dodjele vrijednosti (+=, -=, itd.) mogu se umetati u izraze, ali rjee.U svim ovakvim izrazima, tip izraza za dodjelu vrijednosti je tip njegovog lijevog operanda, a

    vrijednost je ona nakon dodjele.

    Vjeba 2-9. U dvokomplementnom sustavu brojeva izraz x&=(x-1) brie krajnji desni bit u x.Pojasnite zato. Iskoristite to zapaanje kako biste napisali bru inaicu bitcount funkcije.

    2.11 Uvjetni izrazi

    Izrazi

    if(a>b)z=a;

    elsez=b;

    pohranjuju u z maksimum od a i b. Uvjetni izrazi, pisani pomou ternarnog operatora ?:, odreujualternativan nain pisanja ovog izraza i slinih konstrukcija. U izrazu

    izraz1?izraz2:izraz3;

    najprije se rauna izraz1. Ako njegova vrijednost nije nula (ako je istinit), tada se rauna izraz2, a toje najvea vrijednost uvjetnog izraza. Naime, prolazi se kroz samo jedan od izraza izraz2 ili izraz3. Tako, dabi pohranili u z maksimum iz a i b piemo

    z=(a>b)?a:b;

    Morate uoiti da je uvjetni izraz zapravo samo jedan izraz koji se dade koristiti kao svaki drugi. Akosu izraz2 i izraz3 razliitog tipa, tip rezultata je odreen zakonima pretvorbe o kojima smo priali u ovompoglavlju. Npr. ako je f float, a n je int, tada je izraz

    (n>0)?f:n;

    tipa float bez obzira je li n pozitivan.Oko prvog uvjetnog izraza zagrade nisu obavezne, dok je prioritet od ?: nizak, samo neto vei od

    uvjeta. One se ipak preporuuju radi itljivosti programa. Uvjetni izraz je esto vrlo efikasan. Npr. ova petljaispisuje n elemenata jednog polja, deset po retku, sa stupcima koji su razdvojeni razmakom, a svaki red(ukljuujui i zadnji) zavrava znakom novog reda.

    for(i=0;i

  • 7/21/2019 Programski Jezik C - K&R

    41/141

    Programski jezik C Tipovi, operatori i izrazi

    39

    Vjeba 2-10. Nanovo napiite funkciju lower, koja pretvara velika u mala slova pomou uvjetnog

    izraza umjesto if-else.

    2.12 Prioritet i redoslijed raunanja

    Tablica 2-1 prikazuje pravila prioriteta i veza svih operatora, ukljuujui i one o kojima jo nije bilorijei. Operatori u istom retku imaju jednak prioritet, pri emu su redovi nizani po rastuem prioritetu, pa zato*, / i % imaju isti prioritet koji je vei od prioriteta + i -. "Operator" odnosi se na pozivanje funkcija. Operatori -> i . rabe se za pristup lanovima struktura o emu emo diskutirati u Poglavlju 6, kao i o sizeof-u (veliiniobjekta). U Poglavlju 5 govori se o znaku * (indirekcija kroz pokaziva) i & (adresa objekta), a u Poglavlju 3 ooperatoru , (zarez).

    Moete zamijetiti kako prioritet operatora za manipulaciju bitovima &, ^ i | ima svoje mjesto izmeuoperatora == i !=. Iz toga zakljuujemo da izrazi za provjeru bitova oblika

    if((x&MASK)==0)

    moraju biti omeeni zagradama radi tonosti rezultata.C, kao uostalom i mnogi jezici, nema jesno odreenje u smislu reda raunanja operanda u izrazu

    (izuzeci su logiki operatori && i ||, te uvjetni izraz ?: i ,). Tako u izrazu

    x=f()+g();

    f() moe biti izraunata prije g(), ali i obrnuto. Stoga, ako f i g mijenjaju varijablu bitnu za drugefunkcije, x moe imati razliite vrijednosti. Meurezultati se mogu pohranjivati u privremenim varijablamakako bi se takav problem rijeio.

    Slino tome, ni redoslijed raunanja argumenata funkcije nije determiniran pa naredba

    printf("%d %d\n", ++n, power(2, n)); /* pogreno */

    moe dati razliite rezultate na razliitim prevoditeljima, zavisno od toga da li je n poveano prijenegoli je funkcija power pozvana. Problem se, jasno, dade rijeiti sa

    ++n;printf("%d %d\n", n, power(2, n));

    Pozivi funkcija, umetanje naredbi dodjele vrijednosti, te operatora uveavanja i umanjivanja moguproizvesti neke nuspojave (side effect) - varijabla se moe mijenjati tokom raunanja izraza. U bilo kakvomizrazu u kojemu se nuspojave manifestiraju, javljaju se zamrene zavisnosti. To se redovito doga a unaredbama u kojima se u izrazu pojavljuju varijable ve obraene u istom izrazu. Evo jedne nezgodnesituacije

    a[i]=i++;

    Pitanje je da li je indeks stara ili nova vrijednost od i. Prevoditelji ovo mogu interpretirati na razne

    naine i generirati razliite odgovore. Standard namjerno ostavlja mnoga od ovih pitanja nedefiniranim. Kadse jave nuspojave u nekom izrazu ija vrijednost ovisi o prevoditelju, rjeenje nije univerzalno nego varira odraunala do raunala (standard kae da se nuspojave na argumentima dogaaju prije negoli je funkcijapozvana, ali to ne bi pomoglo pri ranijem pozivanju printf funkcije).

    Dobro je znati da pisanje koda, zavisnog o naredbi za raunanje, predstavlja lou programskupraksu. Treba, unato tomu, znati koje stvari moramo izbjegavati, ali bez znanja o tome kako su onerealizirane na razliitim platformama, neete moi koristiti komparativne prednosti pojedinih konfiguracija.

    TABLICA 2-1. PRIORITET I ASOCIJATIVNOST OPERATORA

    Operatori Asocijativnost

    () {} -> . slijeva nadesno

  • 7/21/2019 Programski Jezik C - K&R

    42/141

  • 7/21/2019 Programski Jezik C - K&R

    43/141

    Programski jezik C Kontrola toka

    41

    POGLAVLJE 3: KONTROLA TOKA

    Izrazi kontrole toka u jeziku odreuju red kojim e se naredbe izvravati. Ve smo vidjelinajjednostavnije konstrukcije kontrole toka ranije. Sad emo upotpuniti znanja i preciznije pojasniti naredbekoje smo spominjali.

    3.1 Naredbe i blokovi

    Izraz kao x=0 ili printf(...) postaje naredba kad je popraen toka-zarezom, kao u

    x=0;i++;printf(...);

    U C-u se toka-zarezom zavrava svaka naredba. Tako je, u C-u, toka-zarez (;) terminator, a neseparator, kao, recimo u Pascalu.

    Vitiaste zagrade {} rabe se za grupe deklaracija i naredbe u sloenoj naredbi tj., bloku koji jesintaksno jednakovrijedan jednoj naredbi. Vitiaste zagrade koje omeuju naredbe funkcija su klasian

    primjer. Slian primjer su takove zagrade oko mnogostrukih naredbi nakon if, else, while ili for (varijable semogu prijaviti unutar bilo kojeg bloka o emu emo priati u Poglavlju 4). Nakon desne vitiaste zagradekojom se okonava blok ne treba stavljati ";".

    3.2 If else

    Naredba if - else koristi se za donoenje odreenih odluka. Formalna sintaksa jest

    if(izraz)naredba1

    elsenaredba2

    pri emu je else neobavezan. Izraz se provjerava. Ako je istinit (ima vrijednost koja nije nula),izvrava se naredba1. Ako nije istinit (ima vrijednost nula) i ako postoji else dio, izvrava se naredba2.

    Kako if testira brojevnu vrijednost nekog izraza, mogua su odreena skraenja koda. Primjericedovoljno je napisati

    if(izraz)

    umjesto

    if(izraz!=0)

    Katkad je ovaj nain pisanja ipak zgodniji i itljiviji.Na prvi pogled, malo je nejasno to se dogaa u sluaju kad if - else konstrukcija nema else dijela

    (jer je neobavezan). Postoji pravilo, potpuno intuitivno, koje pridruuje else najbliem prethodnom if-u kojinema else. Npr. u

    if(n>0)if(a>b)

    z=a;else

    z=b;

    else se pridruuje unutranjem if-u, to zorno pokazuje i uvuenost redova. Ako to nije eljeniraspored, morate iskoristiti vitiaste zagrade kako bi pojasnili prevoditelju to zapravo elite

    if(n>0){if(a>b)

    z=a;

  • 7/21/2019 Programski Jezik C - K&R

    44/141

    Programski jezik C Kontrola toka

    42

    }else

    z=b;

    esta je greka

    if(n>0)for(i=0;i0){

    printf("...");return i;

    }else /* pogreno */

    printf("greska - n je negativno\n");

    Uvuenost redova pokazuje to programer eli, ali prevoditelj else pridruuje unutranjem if-u.Ovakve greke nije lako nai. Zato je topla preporuka koritenje vitiastih zagrada kad je to mogue, a nekad se moe.

    Osim toga primijetite da postoje toka-zarez nakon z=a u

    if(a>b)z=a;

    elsez=b;

    Gramatiki gledano, naredba ide kao posljedica if, a naredbu moramo okonati s toka-zarezom.

    3.3 Else if

    Konstrukcija

    if(izraz)

    naredbaelse

    if(izraz)naredba

    elseif(izraz)

    naredbaelse

    if(izraz)naredba

    elsenaredba

    je toliko esta da o tomu ne treba troiti rijei. Ovaj niz if naredbi predstavlja najopenitiji nainpisanja viesmjernog grananja. Izrazi se raunaju po redu. Ako je bilo koji izraz istinit pridruena naredba seizvrava, ime se zavrava itava konstrukcija. Kao i uvijek, naredbom se podrazumijeva ili jedna naredba ilivie njih omeenih vitiastim zagradama.

    Zadnja else naredba ne obavlja nijedan od gornjih sluajeva, ali izvodi sluajeve koji se izvravajukad nijedan od uvjeta nije zadovoljen. Ponekad takvi, podrazumijevani sluajevi, ne rade nita, pa tadazadnji else nije ni potreban. Meutim, ipak je dobro ostaviti else, te pomou njega traiti nemogue greke.

    Kako bi ilustrirali grananje s tri grane, prouimo funkciju binarnog pretraivanja koja kae da li jeodreena vrijednost x nalazi u sortiranom polju v. Elementi polja v moraju biti ureeni po rastuem nizu.Funkcija vraa poziciju (broj izmeu 0 i n-1) ako se x pojavi u v, a inae -1.

    Binarno traenje prvo usporeuje ulaznu vrijednost x sa korijenskim elementom polja v. Ako je xmanje od (u ovom sluaju to je srednja vrijednost) korijenske vrijednosti, pretraivanje se prebacuje na donjupolovinu tablice. Inae ostaje na gornjem dijelu. U svakom sluaju, slijedei korak je usporedba x sa

    korijenskim elementom izabrane polovine. Proces dijeljenja se nastavlja sve dok se ne nae traenavrijednost ili dok stablo ne bude pregledano.

  • 7/21/2019 Programski Jezik C - K&R

    45/141

    Programski jezik C Kontrola toka

    43

    /* binsearch: nai x u v[0]

  • 7/21/2019 Programski Jezik C - K&R

    46/141

    Programski jezik C Kontrola toka

    44

    case '\n':case '\t':

    nwhite++;break;

    default:nother++;

    break;}}printf("Znamenke=");for(i=0;i

  • 7/21/2019 Programski Jezik C - K&R

    47/141

  • 7/21/2019 Programski Jezik C - K&R

    48/141

    Programski jezik C Kontrola toka

    46

    manje posla (bubble sort premee susjedne elemente). Interval izmeu elemenata smanjuje se postepenodo 1 kada se sortiranje svede na sortiranje susjednih elemenata.

    /* shellsort: sortira niz */void shellsort(int v[], int n){

    int gap, i, j, temp;

    for(gap=n/2;gap>0;gap/=2)for(i=gap;i0&&v[j]>v[j+gap];j-=gap){temp=v[j];v[j]=v[j+gap];v[j+gap]=temp;

    }}

    Tu postoje umetnute petlje. Krajnja vanjska petlja kontrolira razmak izmeu elemenata koji seusporeuju, smanjujui ga od n/2 faktorom 2, dok god ne postane nula. Sredinja petlja pristupaelementima, a unutranja usporeuje svaki par elemenata koji je razdvojen pomou gap i preokree svaki

    koji nije u redu. Ako je gap smanjen do 1, mogue je da su svi elementi ve

    poredani. Dade se primijetitikako openitost funkcije for osigurava da vanjska petlja ima istu formu kao druge, ak i kada nije rije o

    istoj aritmetikoj progresiji (pri tom se misli na niz koji tvori varijabla petlje).Zadnji C operator je zarez koji se najee koristi upravo u for naredbi. Nekoliko izraza odvojenih

    zarezom izraunava se slijeva nadesno, a tip i vrijednost rezultata su tip i vrijednost desnog operanda.Stoga je u for naredbu mogue smjestiti velik broj izraza, kako bi, npr., obradili dvije naredbe koje trebaju iiparalelno. Ovo emo ilustrirati funkcijom reverse(s), koja preokree znakovni niz s.

    /* reverse: obrtanje znakovnog niza */#include

    void reverse(char s[]){int c, i, j;

    for(i=0;j=strlen(s)-1;i

  • 7/21/2019 Programski Jezik C - K&R

    49/141

    Programski jezik C Kontrola toka

    47

    Sin