1. C-kieli - Oamkjanneku/T080104/SAU14SNS/C/C_OSA1.pdf · Esimerkiksi lausekkeen 2.1 - 1.1 arvo ei...
Transcript of 1. C-kieli - Oamkjanneku/T080104/SAU14SNS/C/C_OSA1.pdf · Esimerkiksi lausekkeen 2.1 - 1.1 arvo ei...
1
1. C-kieli
yleiskäyttöinen ohjelmointikieli, standardoitu 1990.
• siirrettävä
• laiteläheinen
• pieni ydin, monimutkaiset kokonaisuudet rakennetaan aliohjelmakirjasto-
jen avulla.
• direktiivit ja esikääntäjien käyttö
• vaikeahko, helppo tehdä pahoja virheitä
• heikosti tyypitetty eikä ajonaikaisia tarkistuksia ( vrt. Java )
2
C-kieli mahdollistaa hyvin tiiviin ja samalla sekavan tavan esittää asioita,
kuitenkin hyvän ohjelman tulisi olla mahdollisimman helppolukuinen ja
ymmärrettävä.
3
C-kielen yleispiirteet Ohjelman ulkoasu esikääntäjän direktiivit main-funktion otsikko { muuttujien määrittelyt suoritettavat lauseet }
4
Esikääntäjän direktiivit Jokaiseen C-ohjelmaan liitetään yksi tai useampia otsikkotiedostoja, joiden tarve riippuu ohjelmassa käytetyistä funktioista. Esikääntäjän direktiivit ovat C-esiprosessorin ymmärtämiä käskyjä, jotka suoritetaan ennen ohjelman varsinaista kääntämistä.
• direktiivi alkaa "#"-merkillä • #include kertoo käytetyt kirjastot
• #define määrittelee vakiomakrot
5
C-kieli sisältää aika pienen määrän toimintoja
• ohjelmakirjastojen käyttö • C-kielen standardi edellyttää tiettyjen kirjastojen toimittamisen jokaisen
C-kielen toteutuksen mukana. • kirjastotiedostot päättyvät -.h tunnukseen (header)
6
Esimerkiksi: #include<stdio.h> -direktiivi käskee esiprosessoria lisäämään tiedoston stdio.h sisältämät määrittelyt ohjelmatiedostoon ennen ohjelman varsinaista kääntämistä. Määrittelyt kertovat esiprosessorille mm. sen, että ohjelmassa käytetyt nimet (kuten scanf ja printf ) löytyvät em. tiedostosta. #define MK_EUROINA 5.94573 /* muunnosvakio */ liittää vakiomakroon MK_EUROINA merkityksen 5.94573. Esiprosessori korvaa ohjelmakoodissa esiintyvän tunnuksen MK_EUROINA arvolla 5.94753 ennen kääntämistä.
7
• vakiomakroiksi kannattaa määritellä vain sellaisia arvoja, jotka pysyvät
vakioina • tunnuksen käyttö ohjelmakoodissa lisää ohjelman luettavuutta ja ylläpi-
dettävyyttä.
8
main-funktio main-funktion otsikko kertoo, mistä ohjelman suoritus alkaa main-funktion otsikko on muotoa:
int main (void) tai int main(int argc, char * argv[])
Kaikissa C-ohjelmissa on main-funktio.
9
• Loput koodirivit muodostavat ohjelman rungon.
• Ohjelman runko sijoitetaan { , } -merkkien sisälle
• Sulkeissa olevaa ohjelman osaa kutsutaan lohkoksi (block).
• Ohjelma päättyy "}"- merkkiin.
10
Ohjelman runko koostuu kahdesta osasta
• Määrittelyistä
• Suoritettavista lauseista Esimerkki C-ohjelmasta: #include <stdio.h> int main(void){ printf("Hello, World! "); return(0); }
11
Ohjelma sisältää kaksi suoritettavaa lausetta ( statement ):
printf("Hello, World! "); Se tulostaa kuvaruudulle tekstin "Hello, World!", (lainausmerkkejä ei tulosteta). Käskyllä return(0); lähetetään kontrolli takaisin käyttöjärjestelmälle, eli main-funktion suoritus päättyy. Luku 0 ilmoittaa käyttöjärjestelmälle että ohjelman suoritus päättyi normaalis-ti.
12
Varatut sanat
• varattuja sanoja (32 kpl), joita ei saa käyttää mihinkään muuhun, kuin niille varattuun tarkoitukseen.
auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while
13
Standarditunnukset
• esimerkiksi scanf ja printf, ovat standardi syöttö/tulostus -kirjastossa (stdio.h) määriteltyjen operaatioiden nimiä
• voidaan määritellä uudelleen (ei suositella) Käyttäjän määrittelemät tunnukset
• ohjelman käyttämien muistipaikkojen ja funktioiden nimeäminen Tunnus voi koostua • kirjaimista ( a - z ,A - Z) • numeroista ( 0 - 9 ), mutta ei saa alkaa numerolla • alaviivasta
14
Tunnuksen pituudelle ei ole määritelty maksimipituutta, mutta jotkut ANSI C-kääntäjät saattavat pitää kahta tunnusta samana elleivät ne eroa mitenkään 31ensimmäisen merkin osalta.
• Tunnukset kannattaa nimetä kuvaavasti, jolloin sen merkitys on helpompi tajuta.
• Jos tunnus koostuu kahdesta tai useammasta sanasta voidaan lukemista helpotta kirjoittamalla esim.
hintaEuroina tai hinta_euroina
• Liikaa toisiaan muistuttavia tunnusten nimiä kannatta välttää, ei kannata määritellä tunnuksia suuri ja SUURI
• C-kääntäjä tekee eron isojen ja pienten kirjainten välillä!
15
Muuttujien määrittelyt Muuttuja on muistielementti, joka tallettaa ohjelman käsittelemää syöttö- ja tulostustietoa sekä välituloksia. Muuttujan määrittely kertoo:
• talletetun tiedon tyypin • talletukseen käytetyn muistielementin nimen int vuosi;/*kokonaislukumuuttuja nimeltä vuosi */ char kirjain_1, kirjain_2, kirjain_3; /*kolme kirjainta*/ doub¬le kilometrit; Muuttujien, vakioiden, funktioiden ja tyyppien niminä käytetään ohjelmoijan määrittelemiä tunnuksia. Kaikki C-ohjelmassa käytettävät muuttujat on määriteltävä!
16
Tietotyypit C-kielen etukäteen määritellyt standarditietotyypit ovat
• kokonaisluvut: • long • int • short • byte • reaaliluvut • double • float • merkkitieto • char • totuusarvot (c99->) tarvitaan stdbool.h tiedostoa • bool
17
Kaikki C-kielen numeeriset vakiot ovat positiivisia kokonaislukuja. Negatiivisten lukujen "-" -merkki tulkitaan operaattoriksi (ei luvun osaksi), joka muuttaa positiivisen luvun negatiiviseksi. tietotyyppi int int -tyyppiseen muistipaikkaan voidaan tallettaa kokonaislukuja. ANSI C määrittelee tyypin int koon siten, että sen täytyy kyetä tallettamaan vähintään arvoja väliltä -32767 ... 32767. mahdolliset aritmeettiset operaatiot
• +, -, *, / ja % -operaatiot • == lukujen vertailu
18
tietotyyppi double Tietotyyppi double kykenee tallettamaan reaalilukuja kokonais- ja desimaaliosa erotetaan toisistaan pisteellä ( 32.99 ) mahdolliset aritmeettiset operaatiot
• +, -, *, / -operaatiot • == lukujen vertailu
double -tyypin luvut voidaan esittää myös käyttäen tieteellistä notaatiota (yleensä hyvin pienten ja hyvin suurten arvojen esittämisessä). 1.23e5 tai 1.23 E5, jossa e tai E tulkitaan luvuksi 10, jota korotetaan potenssiin 5.
19
Tyyppi double kykenee tallettamaan vain pienen osan kaikista reaaliluvuista, koska muistipaikoilla on rajallinen koko. Esimerkiksi lausekkeen 2.1 - 1.1 arvo ei välttämättä ole 1.0. Tietotyyppi char Tyyppi char esittää yksittäisen merkin arvon. Yksittäinen merkki esitetään ohjelmakoodissa heittomerkkien sisällä ('A', '1' , '&', '.' , ...) Kullekin merkille on sovittu numeerinen arvo, tavallisimmin on käytössä ns. ASCII-koodi (American Standard Code for Information Interchange). char-tyypin tietoja voidaan verrata ja tiedoille voidaan suorittaa myös aritmeettisia operaatioita.
20
Suoritettavat lauseet Suoritettavat lauseet sijaitsevat ohjelmakoodissa määrittelyiden jälkeen.
• Suoritettava lause päättyy puolipisteeseen (;). Ohjelmalle suoritettavat operaatiot 1. käännetään konekielelle 2. ladataan muistiin 3. suoritetaan
21
Sijoituslauseet Sijoituslause tallettaa käsittelyn tuloksen muuttujaan.
• C:n sijoitusoperaattorina käytetään = -merkkiä. • Sijoituslause on muotoa:
muuttuja = lauseke;
Esimerkiksi: euro = MK_EUROINA * mk; Muuttujan euro entinen arvo tuhoutuu ja tilalle talletetaan lausekkeen MK_EUROINA * mk tulos.
22
• C:ssä voidaan samaa muuttujaa käyttää lausekkeen molemmissa puolis-koissa yhtä aikaa.
pankkitili = pankkitili - otto;
23
Syöttö- ja tulostusoperaatiot ( I/O) Ohjelmalle välitetään tietoa syöttö-operaatioiden avulla ja ohjelmasta välitetään tietoja tulostusoperaatioiden avulla. C-kielessä ei ole itsessään valmiita syöttö- tai tulostusoperaatioita, vaan käytetään kirjastofunktioita. Useimmat C-kielen syöttö- ja tulostusfunktiot käyttävät puskurointia. Tiedot kerätään väliaikaiseen muistialueeseen (puskuri). Tieto välitetään lukufunktiolle, kun käyttäjä on painanut returnia. C-kieli käyttää ns. virtoja (stream, vuo) esittämään tietoa, joka siirtyy ohjelmaan tai ohjelmasta ulos.
24
Ennalta määriteltyjä standardeja tietovirtoja ovat: Virran nimi kuvaus laite stdin syöttövirta näppäimistö stdout tulostusvirta näyttö stdprn tulostinvirta rinnakkaisportti stdaux oheislaitetulostus sarjaportti stderr virhevirta näyttö Standardivirrat avataan automaattisesti ohjelmaa suoritettaessa (vrt. Java). Tietoja voidaan lukea myös puskuroimattomasti, jolloin käyttäjän antamat yksittäiset merkit ovat ohjelman käytettävissä heti merkkien syöttämisen jälkeen.
25
Tavallisimmin käytetyt I/O-funktiot toimitetaan C:n standardikirjastojen mukana ja saadaan käyttöön esikääntäjän direktiivillä #include <stdio.h>
26
Tietojen tulostaminen Yksittäisen merkin tulostaminen tapahtuu funktiolla: char merkki = 'A'; putchar ( merkki );
27
Muotoileva tulostus; printf printf-funktio kykenee muotoilemaan tulostusta käyttäjän haluamalla tavalla. printf ("Pankkitilin saldo on %f markkaa.\n" , pankkitili);
formaatti- merkkijono
funktion nimi
funktion argumentit (parametrit )
tulostuslista
28
Funktion printf kutsu koostuu
• funktion nimestä
• suluissa kirjoitetuista funktion argumenteista.
29
Funktion printf argumentit ovat
• formaatti-merkkijono lainausmerkeissä
• tulostuslista; muuttuja pankkitili Jos muuttujalla pankkitili on arvo 55999.99 niin kuvaruudulle tulostuisi Pankkitilin saldo on 55999.99 markkaa. ennen tulostusta muotoilumääre %f tai %lf korvataan tulostuslistan muuttujan pankkitili sisällöllä. Muotoilumääre ilmaisee missä muodossa muuttujien arvot tulostetaan. Muotoilumääre alkaa aina %-merkillä.
30
Jokaiselle tietotyypille on oma muotoilumääreensä esim. muotoilu-määre
tyyppi käyttö funktiossa
%d int printf / scanf %f double printf %lf double printf / scanf %c char printf / scanf %s merkkijono printf / scanf Huomatkaa että %d ei ole reaalilukujen tulostamiseen tarkoitettu muotoilu-määre!
31
Tulostettavan muuttujan arvo tulostuu muotoilumääreen paikalle siten, että varataan tilaa juuri sen verran kuin tarvitaan. Haluttaessa voidaan tulostuskentän leveyteen vaikuttaa kirjoittamalla %-merkin ja kirjainkoodin väliin kokonaisluku, joka ilmaisee vähimmäistilan, joka varataan tulostettavalle tiedolle. Esimerkiksi %8d varaa kahdeksan merkkiä tilaa kokonaisluvun tulostusta varten. Tulostettava tieto kirjoitetaan tulostuskentän oikeaan laitaan. Jos halutaan sijoittaa tulostettava tieto kentän vasempaan reunaan käytetään "-"- merkkiä %-merkin ja kentän koon välissä, esim. %-8d. Reaalilukujen desimaalit tulostetaan oletusarvoisesti järjestelmän määräämällä tarkkuudella.
32
Haluttaessa voidaan tarkkuutta rajoittaa kirjoittamalla tulostuskentän leveysmääreen jälkeen piste ja kokonaisluku, jolla ilmaistaan tulostettavien desimaalien määrä. Esimerkiksi printf ("Pankkitilin saldo on %7.1f markkaa.\n" , pankkitili); tulostaisi Pankkitilin saldo on 55999.9 markkaa.
33
Desimaalit pyöristetään tulostuksessa, jos tulostuksen muotoilussa käytetään desimaalien määrää kuvaavaa kenttää. Tämä ei kuitenkaan muuta pysyvästi käsiteltävää tulostettavaa tietoa. Tulostuskentän leveysosa voidaan jättää pois ja kuitenkin tulostettavien desimaalien määrää voidaan rajata esim. printf("Pankkitilin saldo on %.2lf euroa.\n", pankkitili); Formaattirivi sisältää myös tulostuksenohjausmerkin “\n” (rivinvaihto). Kaikki C-kielen ohjauskomennot alkavat aina "\"-merkillä. Samalla printf-lauseella voidaan tulostaa useamman muuttujan arvo. Muotoilumääreiden paikalle sijoitetaan perässä tulevien muuttujien sisällöt siinä järjestyksessä kuin ne on tulostuslistaan kirjoitettu.
34
printf("%d + %d = %d\n", luku1, luku2, summa); jos luku1, luku2 ja summa ovat int-tyypin muuttujia ja niillä on arvot. luku1 = 10; luku2 = 19; summa = 29; Ohjelma tulostaisi: 10 + 19 = 29
35
printf-lauseesta voi myös puuttua tulostuslista: println("Tässäpä on kaksi\nriviä tekstiä.\n"); Tulostaisi Tässäpä on kaksi riviä tekstiä.
36
Muita ohjausmerkkejä ovat: Koodi Määrittely \a äänimerkki (alarm) \b askelpalautin \r palautus saman rivin alkuun \f sivunvaihto \n rivinvaihto \t vaakatabulaattori \v pystytabulaattori \\ kenoviiva \0 null-arvo \" lainausmerkki \' heittomerkki \? kysymysmerkki
37
Tiedon lukeminen C-kielestä löytyy useita funktioita, joiden avulla voidaan lukea tietoja ohjelman käyttöön. Tavallisimmin tietoja luetaan näppäimistöltä.
• luetaan merkki kerralla • luetaan rivi kerralla
Kaikki lukeminen tapahtuu merkkitietona, muunnos muuttujan käyttämäksi tietotyypiksi tapahtuu lukuvaiheessa.
38
Puskuroitu lukeminen Yksittäisten merkkien lukeminen funktiolla getchar() char mki; mki = getchar();
• Palauttaa näppäimistöltä syötetyn yksittäisen merkin. • Käyttää puskurointia. • Ei tarvitse argumentteja.
39
Muotoiltu lukeminen, scanf Funktiolla scanf luetaan formatoidusti standardi-inputvirrasta, joka on tyypillisesti näppäimistö. scanf("%lf", &palkka); funktio scanf -kopioi näppäimistöltä syötetyn tiedon palkka -muuttujaan.
• %lf kertoo minkä tyyppistä tietoa luetaan (tässä tapauksessa reaaliluku).
• &-merkki on ns. osoiteoperaattori. scanf -funktiolle kerrotaan muuttujan palkka osoite, jonne luettava tieto talletetaan reaalilukuna.
• scanf odottaa luettavaa tietoa ja <return>-näppäimen painallusta.
40
• tietoa voidaan korjata syöttövaiheessa, jos ei ole ehditty painaa <return>-näppäintä.
• scanf palauttaa tiedon siitä kuinka monta merkkiä se pystyi lukemaan
näppäimistöltä virheettömästi.
• lukuvirheen sattuessa puskuriin jää lukematon tieto talteen, puskuri voidaan tyhjentää funktiolla fflush(stdin);
41
Useamman tiedon lukeminen yhdellä scanf-funktiolla tapahtuu seuraavasti: int maara; char merkki; double palkka; printf("Anna yksi kokonaisluku, merkki ja reaaliluku");
scanf ("%d%c%lf", &maara, &merkki, & palkka);
Käyttäjä voi syöttää pyydetyt tiedot samalla rivillä välilyönneillä erotettuna tai jokaisen tiedon omalla rivillä. Esimerkiksi 1 A 1200.50<return> tai 1<return> A<return> 1200.50<return>
42
Jos edellinen lukufunktio kirjoitetaan esimerkiksi näin: scanf("%d,%c,%lf", &maara, &merkki, &palkka); Odottaa ohjelma, että syötetävät tiedot erotetaan toisistaan pilkuilla: 1, A, 1200.50<return> Pilkun paikalla voi käyttää vaikka kirjainta a, jolloin lukeminen tulkitsee a:n erottimeksi eikä lue sitä muuttujien sisällöksi. scanf("%da%ca%lf", &maara, &merkki, &palkka); 1aAa1200.50<return>
43
Aritmeettiset operaatiot operaattorit:
• +, -, *, / ; sekä int- että double-tyypeille
• % -operaattori (jakojäännös ) vain int-tyypille
44
Lausekkeen tyypin määräytyminen Lausekkeen tyyppi määräytyy sen operandien perusteella seuraavasti: int operaattori int --> lausekkeen tyyppi int double operaattori int --> lausekkeen tyyppi double int operaattori double --> lausekkeen tyyppi double double operaattori double --> lausekkeen tyyppi double
45
Aritmeettisten lausekkeiden laskentajärjestys 1. Ensin sulut, sisältä ulos 2. Operaattoreiden sidontajärjestyksen mukaan a) unaari +. - b) *, /, % c) binaarit vasemmalta oikealle eli 3 + 4 - 1 on (3 + 4) - 1