EVTEK Teknillinen ammattikorkeakoulu Ohjelmointi (C) T0004 Syksy 2003 Olli Hämäläinen kurssin sisältö ja tavoitteet työmuodot luennot 1-2/2003 laboratorioharjoitukset 1-2/2003 kotitehtävät, laboratoriokerrat 2-14 tentti harjoitustyöt 1/2004 www.evtek.fi 2 T0004/TP02S, Olli Hämäläinen www.evtek.fi Peruskysymyksiä Mitä on ohjelmointi? Millainen on hyvä ohjelma? Mitä ominaisuuksia ohjelmoijalla on oltava? Kuinka ohjelmointia oppii? Muuttuuko ohjelmointi? Miten? Ohjelmistotyön vaiheet Määrittely (MITÄ?) Suunnittelu (MITEN?) Toteutus Testaus (Vastaako toteutus määrittelyä ja suunnittelua?) 3 T0004/TP02S, Olli Hämäläinen www.evtek.fi 4 T0004/TP02S, Olli Hämäläinen www.evtek.fi Ihminen ja tietokone Mitähän on 12? #include <stdio.h> void main(void) { int a=1, b=2; int summa=ab ; 00401000 mov,eax[0x40a0d7] 00401005 shl,0x02 00401008 [0x40A0DB],eax 011001010110! Algoritmi Algoritmi on yksityiskohtainen ja yksikäsitteinen toimintaohje, jolla annetusta lähtötilasta päädytään haluttuun lopputulokseen äärellisellä määrällä askelia Algoritmisessa ohjelmoinnissa on muuttujia ja sijoituksia Muuttujien arvot kullakin hetkellä muodostavat algoritmin tilan 5 T0004/TP02S, Olli Hämäläinen www.evtek.fi 6 T0004/TP02S, Olli Hämäläinen www.evtek.fi 1
Esimerkki reaalimaailmasta Lähtötilanne: paketti silakoita, perunoita, sipulia, kanamunia, maitoa, suolaa, pippuria, sian kylkilihaa, jos on Tavoitetila: valmis silakkalaatikko Algoritmi: silakkalaatikon resepti Silakkalaatikkoalgoritmi Pane uuni läpiämään Perkaa silakat Kuori ja viipaloi perunat Kuori ja viipaloi sipuli Valmista munamaito Voitele uunivuoka ja asettele perunat, sipulit ja silakat kerroksittain vuokaan lisäten mausteet Kaada munamaito vuokaan Jos on siankylkeä, lisää viipaleet pinnalle Paista kypsäksi 7 T0004/TP02S, Olli Hämäläinen www.evtek.fi 8 T0004/TP02S, Olli Hämäläinen www.evtek.fi Esimerkki matematiikasta Lähtötieto: vaadittu likiarvon tarkkuus Tavoitetila: Neperin luvun e likiarvo halutulla tarkkuudella Algoritmi: lasketaan sarjan osasummia, kunnes termi on pienempi kuin vaadittu tarkkuus 1 =0 n! n 9 T0004/TP02S, Olli Hämäläinen www.evtek.fi Algoritmien peruselementit Peruskäsitteet Muuttujat Sijoittaminen Eteneminen Peräkkäisyys Valinta Toisto 10 T0004/TP02S, Olli Hämäläinen www.evtek.fi Algoritmin kuvaaminen Algoritmin kuvaaminen Vuokaavio ei ALKU LUE δ δ>0 S:=0, n:=0 termi:=1000 nfact:=1 1 1 δ>termi termi:=1/nfact S:=Stermi n:=n1 nfact:=nfact*n on TULOSTA S LOPPU Rakenteinen lohkokaavio δ:=0 niin kauan kuin δ <= 0 lue δ S:=0, n:=0,termi:=1000, nfact:=1 niin kauan kuin δ < termi tulosta S termi:=1/nfact S:=Stermi n:=n1 nfact:=nfact*n 11 T0004/TP02S, Olli Hämäläinen www.evtek.fi 12 T0004/TP02S, Olli Hämäläinen www.evtek.fi 2
Algoritmin kuvaaminen Algoritmit Pseudokoodi δ:=0 /* haluttu laskutarkkuus */ while ( δ <= 0) lue (δ ) /* muuttujien alustaminen */ S:=0 /* S:ään kerätään sarjan osasummaa */ n:=0 /* n on vuorossa olevan termin indeksi */ termi:=1000 /* alustetaan termi mahdottomalla arvolla */ fact:=1 /* 0! = 1 */ /* varsinainen laskenta alkaa */ while (δ < termi) { termi:=1/nfact S:=Stermi n:=n1 nfact:=nfact*n tulosta (S) Esimerkki Kauppias pitää alennusmyynnin ja alentaa hintaa 40%, jos kyseessä on sesonkituote ja muuten 5%. Laadi algoritmi, joka kysyy käyttäjältä hinnan ja koodin (S=sesonki, M=muu) ja tulostaa alkuperäisen ja alennetun hinnan. Virheellisestä koodista ilmoitetaan, eikö alennettua hintaa lasketa. Laskenta loppuu, kun luetaan hinnaksi 0. 13 T0004/TP02S, Olli Hämäläinen www.evtek.fi 14 T0004/TP02S, Olli Hämäläinen www.evtek.fi Algoritmit Algoritmit Esimerkki (jatkoa) Algoritmin käyttämät muuttujat: hinta, koodi, ale_hinta, virhe Pseudokoodi, versio 1: hinta olkoon aluksi 1 virhe olkoon aluksi epätosi niin kauan kuin hinta>0 toista seuraavaa: pyydä_käyttäjältä uusi hinta ja koodi jos koodi= S ale_hinta on 0.6*hinta muuten jos koodi= M ale_hinta olkoon 0.95*hinta muuten virhe saa arvon tosi jos virhe on arvoltaan epätosi ilmoita käyttäjälle hinta, alehinta muuten ilmoita käyttäjälle koodin virheellisyys virhe olkoon nyt uudestaan taas epätosi toistettavan osuuden loppu Esimerkki (jatkoa) Pseudokoodi, versio 2: hinta:=1; virhe:=false; while (hinta>0) { write( Anna hinta ja koodi ); read (hinta, koodi); if koodi= S ale_hinta:=0.6*hinta; else if koodi= M ale_hinta:=0.95*hinta else virhe:=true; if not virhe write(hinta, alehinta) else write( Antamasi koodi oli virheellinen); virhe:=flase; 15 T0004/TP02S, Olli Hämäläinen www.evtek.fi 16 T0004/TP02S, Olli Hämäläinen www.evtek.fi Lukujärjestelmät tietokoneissa käytetään mm. teknisen toteutuksen yksinkertaisuuden vuoksi binääristä eli 2-lukujärjestelmää normaalisti käyttämässämme paikkasidonnaisessa 10- järjestelmässä luvut esitetään 10:n potenssien avulla: 154.27 = 1*1005*104*12*0.17*0.01 = 1*10 2 5*10 1 4*10 0 2*10 1 7*10 2 samalla tavalla luvut voidaan esittää käyttäen kantalukuna mitä hyvänsä lukua kun kantaluku on 2, puhutaan binäärijärjestelmästä, kun 8, oktaalijärjestelmästä ja kantaluvun 16 tapauksessa heksadesimaalijärjestelmästä luvun binääri-, oktaali- ja heksadesimaaliesitykset voidaan muuntaa helposti toisikseen Lukujärjestelmät (jatkoa) Esim. 10110101 2 = (1*2 7 0*2 6 1*2 5 1*2 4 0*2 3 1*2 2 0*2 1 1*2 0 ) 10 = (128032160401) 10 = 181 10 10110101 2 = 265 8 (C:ssä kirjoitetaan 0265 ) 10110101 2 = B5 16 (C:ssä kirjoitetaan 0xB5) 17 T0004/TP02S, Olli Hämäläinen www.evtek.fi 18 T0004/TP02S, Olli Hämäläinen www.evtek.fi 3
Yleisesti käytettävät tietotyypit perustietotyypit: kokonaisluku liukuluku eli reaaliluku merkki totuusarvo tietoa esitettäessä kunkin tyyppiselle tiedolle varataan sille ominainen määrä muistitilaa, joka (yleensä) on 8 bitin (tavu, oktetti, byte) monikerta Kokonaisluvut tyypillisesti kokonaisluku (integer) talletetaan yhteen tietokoneen sanaan (16 tai 32 bittiä eli 2 tai 4 tavua) etumerkki vie yhden bitin, joten esim. 16 bittisen kokonaisluvun arvoalue on 32767..32767 positiiviset kokonaisluvut esitetään tavallisesti sellaisenaan ja negatiiviset esim. ns. 2- komplementtimuodossa bittien järjestys tavussa ja tavujen järjestys sanassa saattaa olla erilainen eri järjestelmissä (big endian vs. little endian) C-kielessä ohjelmoijan käytössä on short int, int ja long int, joille varattava muistimäärä on järjestelmäkohtainen 19 T0004/TP02S, Olli Hämäläinen www.evtek.fi 20 T0004/TP02S, Olli Hämäläinen www.evtek.fi Reaaliluvut tyypillisesti reaalilukujen tallettamiseen varataan 32 tai 64 bittiä reaaliluku esitetään ns. liukulukumuodossa: mantissa*2 ±eksponentti käytettävissä olevasta tilasta varataan vakio-osuus eksponentille ja mantissalle, esim. C-kielessä ohjelmoijan käytössä on float, double ja long double, joille varattava muistimäärä on järjestelmäkohtainen Reaaliluvut (jatkoa) tietokoneessa on käytössä vain äärellinen määrä liukulukuja so. on olemassa suurin ja pienin esitettävissä oleva luku => ylivuodon mahdollisuus tarkkuus vaihtelee lukualueella nollan ympärillä on reikä => alivuodon mahdollisuus esitys- ja laskentatarkkuus samoin kuin pyöristysvirheet on siis aina pidettävä mielessä! 21 T0004/TP02S, Olli Hämäläinen www.evtek.fi 22 T0004/TP02S, Olli Hämäläinen www.evtek.fi Merkkitieto merkkitieto esitetään sovitulla koodaustavalla yhdessä tai useammassa tavussa tavallisimmat koodijärjestelmät perustuvat ASCII-koodiin (8 bittiä) - näissä 127 ensimmäistä merkkiä enimmäkseen samat, kirjavuutta ja sekaannuksia merkeissä 128-255, esim. åäö jne. UNICODE-koodaus: UTF-8, UTF-16 ja UTF-32 aiemmin laajassa käytössä EBCDIC-koodi erityisesti suurkoneympäristössä C-kielessä ohjelmoijan käytössä on tietotyyppi char (1 tavu) merkkijono talletetaan C:ssä taulukkoon ja käsittely edellyttää osoitinmuuttujien käyttöä Totuusarvo totuusarvo voi olla tosi (true) tai epätosi (false) totuusarvon esittämiseen tietokoneessa riittää periaatteessa yksi ainoa bitti C-kielessä ei ole erillistä tietotyyppiä totuusarvolle, vaikka kielessä onkin kattavat loogiset operaatiot totuusarvon tallettamiseen käytetään kokonaislukumuuttuujia: arvo 0 vastaa arvoa epätosi ja mikä hyvänsä nollasta poikkeava arvo tulkitaan totuusarvoksi tosi loogisen operaation, esim. vertailun tulos on C:ssä 0 tai 1 23 T0004/TP02S, Olli Hämäläinen www.evtek.fi 24 T0004/TP02S, Olli Hämäläinen www.evtek.fi 4
Ensimmäinen #include <stdio.h> int main (void) { printf("hei vaan!"); return 0; Toinen /*Esimerkki 7.1 Ohjelma laskee yhteen kaksi käyttäjän syöttämää kokonaislukua ja tulostaa niiden summan */ #include <stdio.h> void main(void) { int x, y, summa; 25 T0004/TP02S, Olli Hämäläinen www.evtek.fi 26 T0004/TP02S, Olli Hämäläinen www.evtek.fi Toinen /* INPUT : */ printf ("Anna kaksi kokonaislukua,"); printf (" lasken niiden summan."); printf ("\nluku 1: "); scanf ("%d", &x); printf ("Luku 2: "); scanf ("%d", &y); /* TEMPUT : */ summa = xy; /* OUTPUT : */ printf ("Lukujen summa on %d", summa); 27 T0004/TP02S, Olli Hämäläinen www.evtek.fi n perusosat otsikkotiedostot, joilla saadaan käyttöön ulkopuoliset toiminnallisuudet (kirjastofunktiot, vakiot jne.) varsinainen ohjelma: pääohjelman otsikko int main(void) (tästä esiintyy monenlaisia variaatioita, esim. Silanderin kirjassa void main(void)) ohjelman runko eli suoritettavat lauseet aaltosulkeissa { ohjelman rungossa voidaan käyttää vapaasti otsikkotiedostoissa määriteltyjä olioita (esim. syöttö- ja tulostustoiminnot) Huom! pääohjelman nimi on aina main Huom! muista kommentit 28 T0004/TP02S, Olli Hämäläinen www.evtek.fi Perustietotyypit char character eli merkki int integer eli kokonaisluku float floating point eli yksinkertaisen tarkkuuden liukuluku double double floating point eli kaksinkertaisen tarkkuuden liukuluku void valueless eli tyhjä (ei arvoa, arvo puuttuu) Perustietotyypit ja lisämääreet tyyppi lisämääre signed unsigned short long char int float double 29 T0004/TP02S, Olli Hämäläinen www.evtek.fi 30 T0004/TP02S, Olli Hämäläinen www.evtek.fi 5
Tunnukset eli nimet ohjelmoinnissa joudutaan erilaisiin asioihin esim. muuttujiin, vakioihin, tyyppeihin, aliohjelmiin, viittaamaan nimillä C-kielessä tunnus voi koostua englanninkielisen aakkoston kirjaimista (A..Z, a..z), numeroista (0..9) ja alaviivasta (_) tunnus ei voi alkaa numerolla tunnukset erotetaan toisistaan 31 ensimmäisen merkin osalta, joten tätä pidempiä tunnuksia ei kannata käyttää Huomioita tunnuksista isot ja pienet kirjaimet ovat eri merkkejä å,ä, ö, Å,Ä, Ö jne. eivät ole kirjaimia C-kielessä vältä alaviivan käyttöä tunnuksen alussa ja lopussa, tällaiset tunnukset on monesti varattu kirjastojen käyttöön käytä aina selkeitä ja kuvaavia nimiä kokonaan isoilla kirjaimilla kirjoitettuja tunnuksia on tapana käyttää vakiolle itse määritellyille tietotyypeille C-kielessä on 32 varattua sanaa, joita ei voi käyttää muuhun tarkoitukseen 31 T0004/TP02S, Olli Hämäläinen www.evtek.fi 32 T0004/TP02S, Olli Hämäläinen www.evtek.fi Varatut sanat Esim. tunnuksia? auto const double float int short struct unsigned yx_tunus_vaa TiistaiAamu double DOUBLE break continue else for long signed switch void Aamu_päivä O Malleys s Double all_in_1 case default enum goto register sizeof typedef volatile aamu-paiva 2003_aineisto silaskuri EVTEK char do extern if return static union while aamu_paiva end lipalkka x2 33 T0004/TP02S, Olli Hämäläinen www.evtek.fi 34 T0004/TP02S, Olli Hämäläinen www.evtek.fi Muuttujan esittely (määrittely) ohjelmoijan käyttöönottamista muuttujista on annettava kääntäjälle riittävästi tietoa, jotta niitä voidaan käyttää ohjelmassa muuttujan esittelyn sijoitetaan tavallisesti ohjelmalohkon alkuun määrittelyssä annetaan muuttujan tyyppi, nimi ja haluttaessa alkuarvo esim. int i = 1; double pinta_ala = 0; char cccp= * ; Sijoitusoperaattorit = yleinen sijoitusoperaattori = a = b a = ab -= a -= b a = a-b *= a *= b a = a*b /= a /= b a = a/b %= a %= b a=a%b 35 T0004/TP02S, Olli Hämäläinen www.evtek.fi 36 T0004/TP02S, Olli Hämäläinen www.evtek.fi 6
Erityiset lisäys- ja vähennysoperaattorit operaattori voidaan sijoittaa operaation kohteena (operandina) olevan muuttujan eteen tai taakse (prefiksiksi tai suffiksiksi). kasvattaa arvoa yhdellä -- vähentää arvoa yhdellä Jos operaattori on ennen muuttujaa, operaatio suoritetaan ennen kuin arvoa käytetään, jos taas jäljessä, käytetään alkuperäistä arvoa ja kasvattaminen/vähentäminen suoritetaan lausekkeen laskemisen jälkeen. Esim. jos n:llä on arvo 5, on sijoituksen x = n; jälkeen n:n arvo 6 ja x:n arvo 6, kun taas sijoituksen x = n; jälkeen on x:llä arvo 5, mutta n:llä arvo 6 37 T0004/TP02S, Olli Hämäläinen www.evtek.fi 38 T0004/TP02S, Olli Hämäläinen www.evtek.fi Aritmeettiset operaattorit yhteenlasku - vähennyslasku * kertolasku / jakolasku % jakojäännös Huom! laskutoimituksen tulos riippuu laskutoimitukseen osallistuvien tyypistä, esim. kokonaislukujen jakolaskun tulos on kokonaisluku! Esimerkki int jaettava = 17; int jakaja = 5; int osamaara; int jakojaannos; osamaara = jaettava/jakaja; jakojaannos = jaettava%jakaja; lopussa muuttujalla osamaara on arvo 3 ja muuttujalla jakojaannos arvo 2 39 T0004/TP02S, Olli Hämäläinen www.evtek.fi 40 T0004/TP02S, Olli Hämäläinen www.evtek.fi Vertailuoperaattorit > suurempi kuin >= suurempi tai yhtäsuuri kuin < pienempi kuin <= pienempi tai yhtä suuri kuin = = yhtä suuri kuin (sama kuin)!= eri suuri kuin Loogisia operaatioita && ja a && b on tosi, jos ja vain jos sekä a että b on tosi, muuten epätosi tai a b on tosi, jos ainakin toinen on tosi, epätosi vain jos molemmat epätosia! ei kääntää lausekkeen totuusarvon,!a on tosi jos ja vain jos a on epätosi ( siis tosi -> epätosi, epätosi -> tosi) 41 T0004/TP02S, Olli Hämäläinen www.evtek.fi 42 T0004/TP02S, Olli Hämäläinen www.evtek.fi 7
Loogisia operaatioita - esimerkkejä Tänään on lämmin päivä ja perjantai Eilen satoi ja oli keskiviikko On perjantai ja kello on yli 13 Ei ole tiistai tai ei sada Ei pidä paikkaansa, että on tiistai tai sataa Laura on tytön nimi tai Saara on pojan nimi On perjantai tai kello on yli 11 Luokkatilassa on yli 50 oppilasta tai ei ole tiistai Ei ole totta, että ensi vuonna on joulu TAI taivas on vihreä Ei ole niin, että tänään sataa lunta Huomenna on perjantai tai tänään on tiistai Huomenna on torstai tai tänään ei ole torstai Huomenna on perjantai ja tänään on perjantai Ei ole niin, että huomenna on perjantai tai tänään on perjantai 43 T0004/TP02S, Olli Hämäläinen www.evtek.fi Ehtolause if - else ehtolauseella on kaksi muotoa: (1) if (ehto) lause; (2) if (ehto) lause1; else lause2; Huom! Lause voi olla yksinkertainen lause tai koottu lause (lohko) eli koostua useasta yksinkertaisesta lauseesta, jotka ovat aaltosuluissa. Huom! Toisin kuin joissain muissain ohjelmointikielissä C-kielen ehtolauseessa ei ole then-sanaa 44 T0004/TP02S, Olli Hämäläinen www.evtek.fi Ehtolause if - else - esimerkki if (luku<raja_arvo) { printf( Luku jää alle rajan ); printf ( Pitäisikö sitä kasvattaa? ); vertaa: if (luku<raja_arvo) printf( Luku jää alle rajan ); printf( Pitäisikö sitä kasvattaa? ); Valinta usean vaihtoehdon perusteella if-else rakennetta voidaan käyttää useamman vaihtoehdon tapauksessa seuraavasti: if (ehto1) lause1; else if (ehto2) lause2; else if (ehto3) lause3; else if (ehto4) lause4; else lause5; C-kielessä else viittaa aina lähimpään edelliseen samalla tasolla olevaan if:iin. 45 T0004/TP02S, Olli Hämäläinen www.evtek.fi 46 T0004/TP02S, Olli Hämäläinen www.evtek.fi while-toistolause while (ehto) lause; tavallisimmin lause on lohko eli koottu lause toiminta: lausetta suoritetaan niin kauan kun ehto on tosi (nollasta poikkeava), jos ehto on alunperin epätosi (0) lausetta ei suoriteta yhtään kertaa jotta while-lauseen suoritus joskus päättyisi, on ehdonehto arvon muututtava jollain lauseen suorituskerralla epätodeksi while-toistolause, esimerkki scanf( %d,&luku); while (luku < 100) { kirjoita (luku * luku); luku=luku 1; vertaa: luku=50; while (luku < 100) { kirjoita (luku * luku); luku=luku - 1; 47 T0004/TP02S, Olli Hämäläinen www.evtek.fi 48 T0004/TP02S, Olli Hämäläinen www.evtek.fi 8