L 5,R 65,J,T 5 20 @Ots(C-kielen alkeita) Aloitamme C-kielen opiskelun klassisella esimerkill„: Tulostetaan teksti "Hello world!"-n„ytt””n: IXREF Hello World BEGIN GESIMERKKI FNAME hello.c: /* Ohjelma tulostaa tekstin Hello world! */ #include int main(void) { printf("Hello world!\n"); return 0; } END GESIMERKKI BEGIN TEHTAVA TehtOts Nimi ja osoite Kirjoita C-ohjelma, joka tulostaa: BEGIN GESIMERKKI Terve! Olen Matti Meik„l„inen 25 vuotta. Asun Kortepohjassa. Puhelinnumeroni on 603333. END GESIMERKKI END TEHTAVA SECTION Tekstitiedostosta toimivaksi konekieliseksiversioksi SUBSECTION Kirjoittaminen IXREF tekstitiedosto Ohjelmakoodi kirjoitetaan mill„ tahansa tekstieditorillatekstitiedostoon vaikkapa nimelle HELLO.C. SUBSECTION K„„nt„minen IXMASTER k„„nt„minen T„m„n j„lkeen valmis tekstitiedosto k„„nnet„„n ko. kielenk„„nt„j„ll„. K„„nn”ksest„ muodostuu objektitiedosto, jokaon jo l„hell„ lopullisen ohjelman konekielist„ versiota. Objektitiedostosta puuttuu kuitenkin mm. kirjastorutiinit. SUBSECTION Linkitt„minen IXMASTER linkitt„minen Linkitt„j„ll„ (kielest„ riippumaton ohjelma) liitet„„n kirjastorutiinit k„„nnettyyn objektitiedostoon ja n„in saadaanvalmis ajokelpoinen konekielinen versio alkuper„isest„ ohjelmasta. SUBSECTION Ohjelman ajaminen IXMASTER ohjelman ajaminen K„„nnetty ohjelma ajetaan k„ytt”j„rjestelm„st„ riippuenyleens„ kirjoittamalla ohjelman alkuper„inen nimi. T„ll”ink„ytt”j„rjestelm„n lataaja-ohjelma lataa ohjelman konekielisen version muistiin ja siirt„„ prosessorin ohjelmalaskurinohjelman ensimm„isen„ suoritettavaksi tarkoitettuun k„skyyn. T„m„n j„lkeen vastuu koneen k„ytt„ytymisest„ on ohjelmalla. Onnistunut ohjelma p„„ttyy aina ennemmin tai my”hemmin k„ytt”j„rjestelm„n kutsuun, jossa ohjelma pyydet„„n poistamaanmuistista. IXREF .C IXREF .OBJ IXREF .EXE BEGIN GESIMERKKISUOJA ³ Kirjoita ÚÄÄÄ>ÄkorjaaÄÄÄÄÄÄ´ ³ Tekstieditori ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ L„ht”kielinen HELLO.C ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ C-esik„„nt„j„ ³ vikaa C-k„„nt„j„ ÃÄÄÄ<ÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ Objektitiedosto HELLO.OBJ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ vikaa Linkitys ÃÄÄÄ<ÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ Toteutuskelpoinen HELLO.EXE ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ vikaa Ohjelman ajaminen ÀÄÄÄ<ÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ END GESIMERKKI SUBSECTION Varoitus Alkuper„isell„ editorilla kirjoitetulla ohjelmakoodilla eiole tavallista kirjett„ kummempaa virkaa ennenkuin tekstiannetaan k„„nt„j„-ohjelman tutkittavaksi. K„„nn”ksen j„lkeen alkuper„inen teksti voidaan vaikka h„vitt„„! Siis mekirjoitamme teksti„, joka ehk„ (toivottavasti) muistuttaaC-kielen syntaksin mukaista ohjelmaa. Vasta k„„nn”s jalinkkaus tekev„t todella toimivan ohjelman. SUBSECTION Integroitu ymp„rist” On olemassa ohjelmankehitysymp„rist”j„, joissa editori,k„„nt„j„ ja linkkeri (sek„ mahdollisesti debuggeri, virheenj„ljitin) on yhdistetty k„ytt„j„n kannalta yhdeksi toimivaksi kokonaisuudeksi. Esimerkkin„ Microsoftin Quick-C ja Borlandin Turbo-C tai Borland-C++. IXREF Microsoft Esimerkiksi Borlandin ymp„rist”iss„ ohjelma kirjoitetaantekstin„ ja kun ohjelmakoodi on valmis, saadaan koodi k„„nnetty„, linkitetty„ ja ladattua ajoa varten vain painamalla[Ctrl-F9]. SECTION Ohjelman yksityiskohtainen tarkastelu Seuraavaksi tutkimme ohjelmaa lause kerrallaan: SUBSECTION Kommentti IXMASTER kommentti IXMASTER /* IXMASTER */ BEGIN GESIMERKKI /* Ohjelma tulostaa tekstin Hello world! */ END GESIMERKKI Ohjelman alussa on kommentoitu mit„ ohjelma tekee. Yleens„ohjelmakoodit on hyv„ varustaa kuvauksella siit„, mit„ ohjelma tekee, kuka ohjelman on tehnyt, milloin ja miksi. Milloin ohjelmaa on viimeksi muutettu, kuka ja miten. Lis„ksi jokainen v„h„nkin ei-triviaali lause tai lauseryhm„kommentoidaan. Kommenttien tarkoituksena on kuvata ohjelmakoodia lukevalle lukijalle se mist„ on kyse. Kommentti alkaa /* -merkkiyhdistelm„ll„ ja p„„ttyy */ -merkkiyhdistelm„„n. Kommentteja voidaan sijoittaa C-koodissamihin tahansa mihin voitaisiin pist„„ my”s v„lily”nti. Rivin loppuminen ei sin„ns„ lopeta kommenttia. Kommentin sis„ll„ SAA esiinty„ / ja * -merkkej„ yhdess„ tai erikseen,muttei lopettavaa yhdistelm„„ */. Yleinen virhe on unohtaa kommentin loppusulku pois. Mik„liesimerkiss„mme puuttuisi kommentin loppusulku, olisi kokoloppuohjelma kommenttia ja mit„„n ohjelmaa ei siis olisikaan. Mik„li k„„nt„j„ antaa vy”ryn ihmeellisi„ virheilmoituksia, kannattaa aina ensin tarkistaa kommenttisulkujent„sm„„vyys. Tosin t„h„n auttaa nykyisten ohjelmointiymp„rist”jen v„rikoodien k„ytt” eri ohjelman osille, eli esimerkiksi kommentit n„kyv„t eri v„risin„ ja puuttuva komenttisulku paljastuu v„litt”m„sti. SUBSECTION Kirjastofunktioiden esittely IXREF kirjastofunktio IXMASTER #include IXREF printf IXMASTER stdio IXMASTER .h IXMASTER < > IXMASTER " " BEGIN GESIMERKKI #include END GESIMERKKI Tarvitsemme ohjelmassamme tulostusfunktiota printf. T„m„funktio l”ytyy C-kielen kirjastosta ja se on esitelty otsikkotiedostossa stdio.h. K„„nt„j„„ varten meid„n t„ytyy esitell„ millaisia parametreja funktiolle voidaan v„litt„„. Kutakin kirjastoa varten on esittelytiedostot ("header"-tiedostot, yleens„ nimet„„n .h), joissa kirjastofunktioiden parametrilistat on esitelty. IXMASTER header IXMASTER pre-prosessor IXMASTER esik„„nt„j„ #include on C-kielen esik„„nt„j„n (pre-prosessor) k„sky, joka ilmoittaa ett„ per„ss„ olevan niminen tiedosto on luettava koodin sekaan t„ss„kohti k„„nn”st„. < > -merkit tiedoston nimen ymp„rill„ ilmoittavat, ett„ ko. tiedostoa etsit„„n C:n systeemin mukaisesta INCLUDE-hakemistosta. Mik„linimi suljettaisiin "-merkeill„, etsitt„isiintiedostoa my”s k„ytt„j„n kotihakemistosta. N„in voidaan tehd„ omia teht„v„kohtaisia kirjastoja. SUBSECTION P„„modulin esittely IXMASTER main IXREF int BEGIN GESIMERKKI int main(void) END GESIMERKKI Seuraavaksi esitell„„n ohjelman p„„ohjelma ("oikea" ohjelmakoostuu isosta kasasta aliohjelmia ja yhdest„ p„„ohjelmasta,jonka nimi on main). int tarkoittaa, ett„ p„„ohjelmamme palauttaa kutsuvalle ohjelmalle (k„ytt”j„rjestelm„lle) kokonaisluvun. Palautettavan luvun arvo ontyypillisesti 0 mik„li kaikki menee ohjelmanaikana niinkuin pit„„kin ja muilla numeroillailmaistaan erilaisia virhetilanteita. MS-DOSissa t„t„ arvoa voidaan tutkia ERRORLEVEL-muuttujalla. main tarkoittaa p„„ohjelman nime„. T„m„ TŽYTYYaina olla main. IXMASTER void (void) ilmoittaa, ett„ funktio jota kirjoitamme eitarvitse yht„„n parametria (eng. void = mit„t”n). SUBSECTION Lausesulut IXMASTER { } IXMASTER lausesulut { } C:ss„ isompi joukko lauseita kootaan yhdeksilauseeksi sulkemalla lauseet aaltosulkuihin. Funktion t„ytyy aina sis„lt„„ aaltosulkupari,vaikka siin„ olisi vain 0 tai 1 suoritettavaalausetta. SUBSECTION Tulostuslause IXMASTER printf IXMASTER \n BEGIN GESIMERKKI printf("Hello world!\n") END GESIMERKKI printf("?") tulostaa ajonaikana sen tekstin, joka on lainausmerkkien v„liss„. My”hemmin opimme, ett„funktion kutsussa voi olla my”s useampia parametreja ja voidaan k„ytt„„ my”s muuttujia. \n on C:n erikoismerkki, joka k„„ntyy merkkijonon sis„ll„ k„ytt”j„rjestelm„n rivinvaihtomerkiksi. T„llaisen esiintyminen merkkijonossa aiheuttaa tulostuksen siirtymisen uuden rivin alkuun. Muista k„ytt„„! SUBSECTION Lauseen loppumerkki ; IXREF puolipiste IXMASTER ; ; puolipiste lopettaa lauseen. Puolipiste voidaan sijoittaa mihin tahansa lopetettavaanlauseeseen n„hden. Sen eteen voidaan j„tt„„v„lily”ntej„ tai jopa tyhji„ rivej„. Sen pit„„ kuitenkin esiinty„ ennen uuden lauseenalkua. N„in C-kieli ei ole rivisidonnainen,vaan C-kielinen lause voi jakaantua usealleeri riville tai samalla rivill„ voi ollauseita C-kielisi„ lauseita. Puolipisteen unohtaminen on tyypillinen syntaksivirhe. Ylim„„r„iset puolipisteet aiheuttavat tyhji„ lauseita, joistatosin ei ole mit„„n haittaa. Tyhj„n tekemiseen ei kauan mene - sanoo tyhj„n toimittaja. SUBSECTION Funktion arvon palautus IXMASTER return IXREF void BEGIN GESIMERKKI return 0 END GESIMERKKI return jokainen C-funktio tulisi lopettaa return-lauseeseen. Mik„li funktio on esitelty muunkuin void-tyyppiseksi, pit„„ kertoa my”s arvo, joka palautetaan. Funktio voi tarvittaessa sis„lt„„ my”s useita eri return-lauseita. SUBSECTION Isot ja pienet kirjaimet IXMASTER isot ja pienet kirjaimet Isoilla ja pienill„ kirjaimilla on C-kieless„ eri merkitys. Siis EI VOIDA KIRJOITTAA: BEGIN GESIMERKKI Int MAIN(Void) END GESIMERKKI SUBSECTION White spaces, tyhj„ IXMASTER white space IXREF tyhj„ IXREF rivinvaihto IXREF tabulointi IXREF v„lily”nti IXREF direktiivi V„lily”ntej„, tabulointimerkkej„, rivinvaihtoja ja sivunvaihtoja nimitet„„n yleisesti yhteisell„ nimell„ "white space". K„„nnett„ess„ kommentit muutetaan yhdeksi v„lily”nniksi, joten my”s kommenteista voitaisiin k„ytt„„ nimityst„"white space". Jatkossa k„yt„mme nimityst„ tyhj„ tai tyhj„merkki, kun tarkoitamme "white space". C-koodi voi sis„lt„„ tyhji„ merkkej„ miss„ tahansa, kunhanniit„ ei kirjoiteta keskelle sanaa tai teksti„ m„„rittelev„n""-parin ollessa auki. ""-parin sis„ll„ tyhj„tkin merkitovat merkityksellisi„. Tyhjill„ merkeill„ ei saa my”sk„„nsotkea esik„„nt„j„lle tarkoitettuja #-direktiivi -rivej„,n„iden pit„„ muodostaa t„sm„lleen yksi rivi. Lainausmerkkeihin suljettu jono voidaan tarvittaessa katkaista tyhjill„ merkill„ sulkemalla ja avaamalla lainausmerkit. Esimerkiksi BEGIN GESIMERKKI "Kissa" "istuu" -> "Kissaistuu" END GESIMERKKI Tarvittaessa C-ohjelman rivi„ voidaan jatkaa uudelle rivillekirjoittamalla \-merkki edellisen rivin loppuun ja sen j„lkeen v„litt”m„sti rivinvaihto. Siis k„„nt„j„n kannalta malliohjelmamme voitaisiin kirjoittaa my”s seuraavillakin tavoilla: BEGIN GESIMERKKI ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ #include\ int main ( void ) { printf ( "Hel\ lo " "w" /* kommentti keskell„ jonoa */ "or" "ld!" "\n" ) ; return 0 ; } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ END GESIMERKKI BEGIN GESIMERKKI ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ #include int main(void){ printf("Hello " "world!\n" );return 0;} ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ END GESIMERKKI BEGIN GESIMERKKI ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ #include int main(void){printf("Hello world!\n");return 0;} ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ END GESIMERKKI Yleinen tyyli on kuitenkin jakaa koodia riveihin ja sisent„„lohkoja muutamalla pyk„l„ll„. Kunnes lukija on varma omastatyylist„„n, kannattaa matkia t„ss„ monisteessa (ei kuitenkaan edellisi„ esimerkkej„) esitetty„ kirjoitustapaa ohjelmille. SECTION Makro-direktiivi ja vakiot IXMASTER vakio IXMASTER makro IXMASTER #define #include oli tiedote esik„„nt„j„lle siit„, ett„ koodin sekaan t„ytyy lukea v„lill„ jokin toinen teksti. Makro-direktiivi #define on tiedote siit„, ett„ t„ll„ m„„reell„ my”hemmin tekstiss„ esiintyv„t sanat t„ytyy korvatatoisella sanalla/sanoilla/merkeill„. Siis #define-direktiivi on puhdas tekstink„sittelyotus, jokatoimii suurinpiirtein seuraavasti: BEGIN GESIMERKKI /* FNAME makrot.c */ #define TERVE "Hello " END GESIMERKKI tarkoittaisi esik„„nt„j„lle: BEGIN GESIMERKKI vaihda kaikki TERVE-sanat merkkijonoiksi "Hello " @keep eli seuraavat vaihdettaisiin: p=TERVE+1 "Kissa"TERVE"istuu" TERVE MIEHEEN @keep muttei seuraavia TERVEYDEKSI TERVE_MIEHEEN "OLEN OLLUT TERVE 2 PŽIVŽŽ" Terve MIEHEEN END GESIMERKKI Huomattakoon, ettei lainausmerkkien sis„ll„ oleviin sanoihinkajota lainkaan! M„„ritelt„v„ sana voidaan kirjoittaa isoja ja/tai pieni„kirjaimia k„ytt„en, mutta yleiseen C-tyyliin kuuluu kirjoittaa #define -m„„ritellyt sanat isoilla kirjaimilla. SUBSECTION Vakiomerkkijonot IXREF vakiomerkkijono T„t„ esik„„nt„j„n ominaisuutta hyv„ksik„ytt„en voimme m„„ritell„ ohjelmaamme vakioita; eli arvoja jotka esiintyv„t ohjelmassa t„sm„lleen yhden kerran. N„in ohjelmastamme saadaan helpommin muuteltava. Esimerkiksi seuraava ohjelma tulostaisi my”s tekstin "Hello world!": BEGIN GESIMERKKI /* FNAME hello2.c */ /* Ohjelma tulostaa tekstin Hello world! */ #include #define TERVE "Hello " #define MAAILMA "world" int main(void) { printf(TERVE MAAILMA"!\n"); return 0; } END GESIMERKKI Miksik”? Koska esik„„nt„j„ muuttaisi lauseen BEGIN GESIMERKKI printf(TERVE MAAILMA"!\n"); END GESIMERKKI muotoon BEGIN GESIMERKKI printf("Hello " "world""!\n"); END GESIMERKKI Kun t„st„ lis„ksi poistetaan ylim„„r„iset "white space"-merkit saadaan: BEGIN GESIMERKKI printf("Hello world!\n"); END GESIMERKKI BEGIN TEHTAVA TehtOts Terve maailma! Kirjoita edellisest„ ohjelmasta suomenkielell„ tulostavaversio (= suomenna ohjelma). END TEHTAVA BEGIN TEHTAVA TehtOts Nimi ja osoite vakioksi Kirjoita aikaisemmasta "Matti Meik„l„inen asuu Kortepohjassa" -ohjelmasta versio, jossa nimi, osoite ja puhelin onesitelty #define-direktiivill„. END TEHTAVA SUBSECTION Vakiolukuarvot IXREF vakioarvo Vakiom„„rittely„ voitaisiin k„ytt„„ esimerkiksi kokonaislukuvakioiden m„„rittelemiseen: BEGIN GESIMERKKI /* FNAME kuutio.c */ /* Ohjelma tulostaa tietoja monitahokkaasta */ #include #define TAHOKAS "Kuutiossa" #define KARKIA 8 #define SIVUTASOJA 6 #define SARMIA 12 int main(void) { printf("%20s on %2d k„rke„,\n" ,TAHOKAS,KARKIA); printf("%20s %2d sivutasoa ja\n"," " ,SIVUTASOJA); printf("%20s %2d s„rm„„.\n" ," " ,SARMIA); return 0; } END GESIMERKKI BEGIN TEHTAVA TehtOts Tetraedri Muuta edellist„ ohjelmaa siten, ett„ tulostetaan samat asiattetraedrist„. END TEHTAVA BEGIN TEHTAVA TehtOts printf ja % IXREF % Mit„ arvelet %2d:n ja %20s:n merkitsev„n edellisess„ esimerkiss„, kun ohjelma tulostaa seuraavan tekstin: BEGIN GESIMERKKI 0 1 2 3 4 1234567890123456789012345678901234567890 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³ Kuutiossa on 8 k„rke„, ³ 6 sivutasoa ja ³ 12 s„rm„„. END GESIMERKKI END TEHTAVA SUBSECTION Muita makro-"temppuja" Koska C-kielen makro on todellakin vain tekstinkorvaus,muuttaa esik„„nt„j„ seuraavan tekstin BEGIN GESIMERKKI /* FNAME makroja.c */ #define ALKU int main(void) { #define LOPPU return 0; } #define mk *100 #define km *1000 ALKU double hinta_penneina,matka_m; hinta_penneina = 5 mk; matka_m = 3.5 km; LOPPU END GESIMERKKI muotoon BEGIN GESIMERKKI int main(void) { double hinta_penneina,matka_m; hinta_penneina = 5 *100; matka_m = 3.5 *1000; return 0; } END GESIMERKKI Pelkk„ esik„„nn”s voidaan tehd„ vaikka Borland C++:lla: IXMASTER esik„„nn”s BEGIN GESIMERKKI C:\OMAT\OHJELMOI\VESA>PAINA CPP makroja.c tulee tiedosto makroja.i END GESIMERKKI