553
Sisällysluettelo i Sisältö OHJ-1100 Ohjelmointi I Mitä on ohjelmointi? ....................................... 1 Tietokoneen ohjelmointi ..................................... 3 Harhaluulo ohjelmoinnista ................................... 5 Oikea malli ohjelmoinnista ................................... 7 Algoritmit ................................................ 9 Algoritmien muodostaminen ................................. 23 Ohjelmointikielistä ......................................... 25 Lausekielet ............................................... 26 Ohjelman tulkkaaminen ..................................... 27 Ohjelman kääntäminen ..................................... 28 Kääntäjän toiminta ......................................... 29 Ensimmäinen C++-ohjelma ................................... 30 Lähdekoodista suoritettavaksi ohjelmaksi ........................ 32 Editointi ................................................. 33 Emacs-editorin käytöstä ..................................... 34 Kääntäminen ............................................. 38 Virhetilanteet ............................................. 39 Varatut sanat ............................................. 42 C++-kielen varatut sanat ..................................... 43 Vastusesimerkki ............................................ 44 Perustietotyypit............................................ 46 Lausekeet ................................................ 48 Operaattorit .............................................. 49

kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

Sisällysluettelo i

Sisältö

OHJ-1100 Ohjelmointi I

Mitä on ohjelmointi? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Tietokoneen ohjelmointi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Harhaluulo ohjelmoinnista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Oikea malli ohjelmoinnista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Algoritmit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Algoritmien muodostaminen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Ohjelmointikielistä . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

Lausekielet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Ohjelman tulkkaaminen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Ohjelman kääntäminen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Kääntäjän toiminta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Ensimmäinen C++-ohjelma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

Lähdekoodista suoritettavaksi ohjelmaksi . . . . . . . . . . . . . . . . . . . . . . . . 32

Editointi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Emacs-editorin käytöstä . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

Kääntäminen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Virhetilanteet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Varatut sanat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

C++-kielen varatut sanat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Vastusesimerkki. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

Perustietotyypit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

Lausekeet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Operaattorit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 2: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

Sisällysluettelo iiLaskujärjestys eli presedenssi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

Sitomisjärjestys eli assosioituminen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

Yli- ja alivuoto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

Celsius–Fahrenheit -esimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

while-silmukka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

Vertailuoperaattorit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Muuttujat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

Painoindeksiesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

if-rakenne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

Loogiset operaattorit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Kertotauluesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Tulostuksen muotoilu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

Aliohjelmat eli proseduurit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Kertotauluesimerkki hiukan toisin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Määrittely vs. esittely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Mistä aliohjelmat tulevat? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Miksi aliohjelma on ystävä?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

Toisen asteen yhtälon ratkaisu-esimerkki . . . . . . . . . . . . . . . . . . . . . . . . . 87

Funktiot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

Mistä funktiot tulevat? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

Matematiikkakirjasto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Miksi reaalilukuja ei saa vertailla ==- ja !=-operaattoreilla? . . . . . . . . . . . . 100

Arvo- ja viiteparametrit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

Viikonpäiväesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

Merkkijonotietotyyppi (string) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

Merkkijonokirjaston funktioita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

Osoitelappuohjelma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Lokalisaatio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 3: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

Sisällysluettelo iiiSanojenerotteluohjelma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

Merkkien käsittely locale-kirjaston avulla . . . . . . . . . . . . . . . . . . . . . . . . . 143

Lämpötilagraafiesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

Taulukot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

Taulukkoparametrit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

Tenttitulosesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160

unsigned, short ja long . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

Perustietotyyppien ääriarvot: limits-kirjasto . . . . . . . . . . . . . . . . . . . . . . . 172

Tietue- eli struct-tietotyypit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

Ohjelmointityyli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

Tiedon lajittelu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

Tiedon etsintä. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

Tuotekoodiesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

Tietovirrat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

Tietovirrat C++:ssa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

Tietovirtaongelmien havaitseminen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

Standardivirrat cin, cout ja cerr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

Tietovirta funktion parametrina. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

Salasanatiedostoesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

Luettelo- eli enum-tyypit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

switch-rakenne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

for-silmukka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244

do–while-silmukka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

break, continue ja silmukat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

Käskyt vs. tieto ja tieto-ohjattu ohjelmointi . . . . . . . . . . . . . . . . . . . . . . . 248

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 4: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

Sisällysluettelo i

Sisältö

OHJ-1150 Ohjelmointi II

vector-tyyppi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252

Standard Template Library (STL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

STL-säiliöt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

Sarjat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265

Lyhyitä esimerkkejä sarjoista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268

Assosiatiiviset säiliöt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

Lyhyitä esimerkkejä set-rakenteesta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

Lyhyitä esimerkkejä map-rakenteesta . . . . . . . . . . . . . . . . . . . . . . . . . . . 283

STL-iteraattorit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

STL-algoritmit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

Monimutkaisten tyyppinimien yksinkertaistaminen . . . . . . . . . . . . . . . . . 311

Muuttujan tyypin automaattinen määrittely . . . . . . . . . . . . . . . . . . . . . . 314

Abstraktiot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316

Abstraktit tietotyypit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321

Vektoriesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323

Luokat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330

Luokan esittelyn private-osa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

Luokan esittelyn public-osa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334

Jäsenfunktioiden määrittely. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336

Vektoriesimerkki hiukan toisin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338

Toteutuksen »kätkeminen» luokan sisällä. . . . . . . . . . . . . . . . . . . . . . . . . 343

Mistä abstraktit tietotyypit tulevat?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347

Abstraktien tietotyyppien hyödyt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 5: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

Sisällysluettelo iiFunktioiden kuormittaminen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

Funktion oletusparametrit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353

Rakentajan parametrit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356

Nimettömät eli lambda-funktiot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360

main-funktion parametrit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365

main-funktion paluuarvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370

Modulaarisuus ja moduulit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373

TV-ohjelmatietokantaesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374

Moduulit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394

Moduulien toteuttaminen C++:lla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396

Esittely- eli .hh-tiedostot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397

Määrittely- eli .cc-tiedostot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402

Mistä moduulit tulevat? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405

Modulaarisuuden hyödyt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408

Automatisoitu käännös ja make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409

Versionhallinta ja rcs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415

Ajonaikaiset virheet ja gdb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422

Rekursio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427

Rekursio ohjelmoinnissa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429

Tietokoneen muisti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442

Osoittimet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446

Osoittimet struct- ja class-tietotyyppeihin . . . . . . . . . . . . . . . . . . . . . . . . 451

Taulukot ja osoittimet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453

Muuttujan näkyvyysalue ja elinikä . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456

Dynaaminen muistinhallinta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460

Dynaamiset tietorakenteet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466

Dynaaminen pinotietorakenne-esimerkki . . . . . . . . . . . . . . . . . . . . . . . . 468

new:n onnistumisen tarkistaminen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 6: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

Sisällysluettelo iiiPoikkeukset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476

Pino toteutettuna dynaamisena taulukkona . . . . . . . . . . . . . . . . . . . . . . 482

Tietorakenteen kopiointi: alustus ja sijoitus . . . . . . . . . . . . . . . . . . . . . . . 488

Puhelinluetteloesimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499

Listat ja rekursio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511

Kahteen suuntaan linkitetty lista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521

Binäärihakupuu. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527

Geneerisyys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535

Geneerinen pino-esimerkki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536

Geneerisyys C++:ssa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 7: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100Ohjelmointi I

lukuvuosi 2012–2013

Luentomoniste

Ari [email protected]

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 8: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 1

Mitä on ohjelmointi?

▼ Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokinsysteemi, laite, ihminen tms. saadaan suorittamaanjonkun toisen antamat toimenpiteet/käskyt.

▼ Ohjelmointia on tämän määritelmän mukaan esim:

– tallentavan digiboksin ajastaminen,

– lennonjohto antaa lentäjälle lento-ohjeet,

– ajo-ohjeiden selittäminen pizza-taxille ja

– aivopesu (propaganda, mainonta?),

▼ Ohjelmoinnin kohteelta (videot, lentokapteeni jne)ohjelmointi vaatii kykyä:

1. vastaanottaa ja ymmärtää annetut ohjeet/käskyt ja

2. suorittaa ne (oikeassa) järjestyksessä.

▼ Systeemi on ohjelmoitava, jos sillä on nämä kyvyt.

▼ Usein ohjelmoitava systeemi tarvitsee käskyt erittäintarkasti määritellyssä muodossa, jotta se pystyisi niitänoudattamaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 9: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 2▼ Käytännössä ohjelmointi koostuu vaiheista:

1. ongelman/halutun lopputuloksen ymmärtäminen,

2. ongelman ratkaisun kehittäminen ja

3. ratkaisun yksityiskohtainen selittäminen ohjelmoi-tavalle systeemille sen ymmärtämässä muodossa.

▼ Vaihe 2 on usein hankalin, koska se vaatii näkemystäja tietämystä siitä, kuinka kyseinen ongelma yleensäottaen ratkaistaan.

▼ Kuten ongelmanratkaisu yleensäkin, vaihe 2 vaatiiluovuutta.

▼ Vaihe 3 taas vaatii erityistietämystä ongelmanratkaisuun käytettävästä ohjelmoitavasta systeemistä(esimerkiksi sen ymmärtämistä käskyistä jne).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 10: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 3

Tietokoneen ohjelmointi

▼ Kurssin nimessä ja tästä eteenpäin sanalla »ohjel-mointi» tarkoitetaan tietokoneen ohjelmointia elisitä prosessia, jolla tietokone saadaan suorittamaankäyttäjän (lue ohjelmoijan) haluamat toiminnot.

▼ Tietokone on ohjelmoitava systeemi (vrt. kalvo 1).

▼ Käskyt, joita nykyiset tietokoneet suoraan ymmär-tävät, ovat erittäin alkeellisia (konekieli).

▼ Tyypilliset konekieliset käskyt ovat monimutkaisuu-deltaan verrattavissa seuraaviin:

– aritmeettiset operaatiot (l. peruslaskutoimitukset),

– lukujen vertailu (pienempi, suurempi, yhtäsuuri),

– seuraavien suoritettavien käskyjen valinta riippuenvertailun tuloksesta ja

– luvun siirtäminen paikasta toiseen

▼ Muunkin tyyppisiä käskyjä toki on, mutta niidensuorittamat toiminnot eivät ole merkittävästi noitamonimutkaisempia.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 11: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 4▼ Ennen kuin mitään ongelmaa voi tietokoneella

ratkaista, ratkaisu täytyy tavalla tai toisella pukeajoukoksi konekielen käskyjä ➠ kaikkia ongelmiatietokoneella ei voi ratkaista.

▼ Konekieli on erittäin alkeellista ➠ hiukankinisomman ongelman selittäminen tietokoneellepelkästään konekielellä on kohtuuttoman työlästä.

▼ On olemassa ns. korkean tason ohjelmointikieliä,joiden käskyt »tekevät enemmän» ➠ sama ongelmasaadaan esitettyä pienemmässä tilassa ja vähemmällävaivalla.

▼ Tietokoneet ymmärtävät vain omaa konekieltään ➠ennen korkean tason kielisen ohjelman suorittamistase on ensin muutettava konekielelle.

▼ Kurssin opetuskieli C++ on korkean tason kieli.

▼ Ohjelmointikielistä lisää myöhemmin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 12: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 5

Harhaluulo ohjelmoinnista

▼ Asiaan perehtymättömillä on sellainen käsitys, ettäohjelmointi on sitä, kun istutaan tietokoneen ääressäja syötetään näppäimistöltä koneelle ohjelmaa.Kun naputtelu on ohi, kone suorittaa ohjelmanongelmitta ja näyttää tarvittavan oikean tuloksen.

▼ Kun tätä käsitystä ohjelmoinnista vertaa kalvolla 2esitettyyn yleiseen malliin, niin jotain puuttuu.

▼ Harhaluuloinen käsitys koostuu pelkästään yleisenmallin viimeisestä vaiheesta ➠ ongelmaa eivälttämättä ole ymmärretty kunnolla eikä senratkaisua mietitty loppuun saakka.

▼ Tämä väärä lähestymistapa johtaa ikävyyksiin:

– ongelmaa ei ole ymmärretty ➠ ratkaistaan vääräongelma,

– ratkaisutapa virheellinen ➠ ohjelman antamalopputulos on väärä ja

– ohjelmaa pitää korjata ➠ hukataan aikaa ja rahaa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 13: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 6▼ Tämä virheellinen käsitys on lähes kaikilla ohjel-

mointia aloittelevilla ja siitä kannattaa hankkiutuaeroon välittömästi.

▼ Harhaluulo on erikoinen myös siksi, että se tuntuuesiintyvän vain ohjelmoinnin yhteydessä.

▼ Kaikilla muilla elämänaloilla tuottavaan työhönsisältyy aina paljon suunnittelua ja valmistelua ennenvarsinaiseen työhön ryhtymistä ➠

– suurempi varmuus lopputuloksen kelvollisuudesta ja

– hukatut resurssit (aika, raha, hermot) minimoi-daan.

▼ Vaikka virheellinen lähestymistapa saattaakin toimiapienissä ohjelmointiprojekteissa, ongelman koonkasvaessa homma karkaa käsistä, jos sitä ei olesuunniteltu kunnolla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 14: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 7

Oikea malli ohjelmoinnista

▼ Kokemus osoittaa, että seuraava kalvon 2 mallistahiukan kehittyneempi versio kuvaa onnistuneenohjelmointiprojektin vaiheita:

1. Ongelman ratkaisuvaihe

a . Analysointi ja määrittely: ymmärrä ongelma jaselvitä, mitä ratkaisun on tarkoitus tehdä.

b. Yleinen ratkaisu (algoritmi): kehitä looginensarja ohjeita, joita noudattamalla ongelmallesaadaan haluttu lopputulos.

c . Tarkistus: testaa kynällä ja paperilla, ettäkehittämäsi algoritmi todella toimii.

2. Ratkaisun toteutusvaihe

a . Konkreettinen ratkaisu: toteuta algoritmisopivalla ohjelmointikielellä.

b. Testaus: suorita ohjelmaa eri syötteillä ja vertailetuloksia tunnettuihin oikeisiin ratkaisuihin: josvirheitä löytyy, mieti »miksi?» ja korjaa ne.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 15: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 83. Ylläpitovaihe

a . Käyttö: käytä ohjelmaa suunniteltuun tarkoituk-seen.

b. Ylläpito: korjaa löytyviä virheitä ja lisäämahdollisia uusia tarvittavia ominaisuuksia.

▼ Karkea sääntö: ratkaisuvaihe/toteutusvaihe tulisiolla 50%/50%, kun vertaillaan käytettyä aikaa jaresursseja.

▼ »Väärää lähestymistapaa» käyttävillä suhde onusein 10%/90% tai huonompi: ongelmaa pohdittukahvikupin verran ja rynnätty suoraan toteuttamaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 16: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 9

Algoritmit

▼ Algoritmi: sarja toimenpiteitä tehtävän/ongelmansuorittamiseksi/ratkaisemiseksi.

▼ Esimerkiksi seuraava algoritmi esittää, kuinka neliön-muotoisesta paperiarkista taitellaan origami-pulu:

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 17: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 10▼ Seuraava algoritmi taas kertoo, kuinka saadaan

keitettyjä perunoita:

Algoritmi: Keitetyt perunat

1. pese perunat

2. etsi kattila

3. laita pestyt perunat kattilaan

4. lisää kattilaan vettä kunnes perunat peittyvät

5. laita kattila levylle

6. käännä levy päälle

7. anna kiehua kunnes perunat ovat kypsiä

8. käännä levy pois päältä

9. kaada keitinvesi viemäriin

▼ Algoritmilta vaaditaan seuraavat ominaisuudet(ainakin hyvältä algoritmilta):1. yksikäsitteinen (ei tulkittavissa väärin),

2. yksityiskohtainen (tyhmäkin osaa seurata),

3. saavuttaa tavoitteensa (eli toimii oikein),

4. määrää toimenpiteiden suoritusjärjestyksen(seuraus kohdasta 1) ja

5. sisältää äärellisen määrän toimenpiteitä (muutentehtävä ei tulisi suoritetuksi).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 18: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 11▼ Kohdat 1 ja 2 ovat jossain mielessä tulkinnanvaraisia:

milloin algoritmi on riittävän yksikäsitteinen jayksityiskohtainen?

▼ Perunoidenkeittoalgoritmin yksikäsitteisyydessäon parantamisen varaa: nykyistä algoritmia joku»tyhmä» tai ilkeämielinen voisi tulkita väärin.

▼ Yksikäsitteisempi versio olisi (muutokset lihavoitu):

Algoritmi: Keitetyt perunat

1. pese perunat

2. etsi riittävän suuri kattila

3. laita em. pestyt perunat em. kattilaan

4. lisää em. kattilaan vettä kunnes siellä olevat

perunat juuri peittyvät

5. laita em. kattila hellan levylle

6. käännä em. levyn maksimiteho päälle

7. anna em. kattilassa olevan veden kiehua

kunnes siellä olevat perunat ovat kypsiä

8. käännä em. levy pois päältä

9. kaada keitinvesi em. kattilasta viemäriin

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 19: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 12▼ Yksityiskohtaisuuden suhteen molemmat algoritmit

ovat puutteellisia.

▼ Esimerkiksi pulun nokan taittelu on sen verranhankala operaatio, että sitä kannattaisi tarkentaa:

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 20: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 13▼ Henkilö, joka ei ole koskaan kokannut, saattaisi

tarvita tarkemmat ohjeet perunoiden keittämiseen:

Algoritmi: Keitetyt perunat

1. pese perunat

1.1. laita tulppa tiskialtaaseen

1.2. laita perunat em. tiskialtaaseen

1.3. laske vettä em. tiskialtaaseen kunnes

em. perunat peittyvät

1.4. ota juuresharja

1.5. harjaa em. perunat yksitellen \em. juuresharjalla kunnes puhtaita

1.6. palauta em. juuresharja paikalleen

1.7. avaa em. tulppa ja laske vesi pois

2. etsi riittävän suuri kattila

2.1. avaa kattilakaapin ovi

2.2. valitse sopiva kattila

2.3. ota em. kattila

2.4. sulje em. ovi

2.5. aseta em. kattila tiskipöydälle

▼ Algoritmin loppuja kohtia 3–9 voitaisiin tarkentaasamaan tapaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 21: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 14▼ Jos algoritmi ei vieläkään ole riittävän yksityiskoh-

tainen, niin tarkennetaan lisää:

Algoritmi: Keitetyt perunat

1. pese perunat

1.1. laita tulppa tiskialtaaseen

1.1.1. etsi tiskialtaan tulppa

1.1.2. ota em. tulppa käteen

1.1.3. paina em. tulppa tiiviisti

em. altaan pohjassa olevaan

reikään

1.1.4. laske irti em. tulpasta

▼ Koko loppualgoritmi voitaisiin tietysti tarkentaasamaan tapaan ja niin edelleen aina vain yksityiskoh-taisemmin, kunnes haluttu taso saavutetaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 22: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 15▼ Riittävä yksikäsitteisyys ja yksityiskohtaisuus ovat

tulkinnanvaraisia suureita ja riippuvat tilanteesta.

▼ Aikuiselle alkuperäinen peruna-algoritmi olisi ollutriittävä, pikkulapselle luultavasti ei.

▼ Tietokoneet ovat »rajoittuneita» ➠ suunniteltaessatietokonealgoritmeja niiden on oltava äärimmäisenyksikäsitteisiä ja yksityiskohtaisia.

▼ Usein algoritmiin liittyy ehdollisuutta ja toistoa:

1. Jonkin algoritmin osan suorittaminen saattaariippua olosuhteista (ehdollisuus).

2. Jotain algoritmin osaa saatetaan tarvittaessasuorittaa useita kertoja peräkkäin (toisto).

▼ Peruna-algoritmissa on sekä ehdollisuutta ettätoistoa, joihin törmätään, jos joitain kohtia yritetäänvielä entisestään yksityiskohtaistaa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 23: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 16▼ Esimerkiksi haluttaessa tarkentaa algoritmin kohtaa

»2. etsi kattila» törmätään ehdollisuuteen:

Algoritmi: Etsi kattila

2. etsi riittävän suuri kattila

2.1. avaa kattilakaapin ovi

2.1.1. JOS kaapin ovi on kiinni NIIN

2.1.1.1. tartu kaapin kahvaan

2.1.1.2. vedä ovi auki

2.1.1.3. laske irti kahvasta

2.2. valitse sopiva kattila

2.3. ota kattila

2.4. sulje ovi

2.5. aseta kattila tiskipöydälle

2.5.1. JOS tiskipöydällä on tilaa NIIN

2.5.1.1. aseta kattila vapaaseen

paikkaan

MUUTEN

2.5.1.2. raivaa tilaa kattilan

verran

2.5.1.3. aseta kattila raivattuun

paikkaan

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 24: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 17▼ Algoritmissa ehdollisuus on siis esitetty muodossa

JOS väite NIIN

toimenpiteet1

MUUTEN

toimenpiteet2

▼ Tätä tulkitaan siten, että mikäli väite on tosi, onalgoritmin toteuttamiseksi suoritettava toimenpiteet1.

▼ Mikäli väite taas ei pidä paikkaansa, suoritetaantoimenpiteet2.

▼ Väite voi siis periaatteessa olla mikä tahansatoteamus, kunhan siitä tavalla tai toisella voidaanpäätellä, pitääkö se paikkansa vai ei.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 25: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 18▼ Toistoa peruna-algoritmista löytyy tarkentamalla

esimerkiksi kohtaa »7. anna veden kiehua kunnesperunat ovat kypsiä»:

Algoritmi: perunoiden keittäminen kypsiksi

7. anna kattilassa olevan veden kiehua kunnes

siellä olevat perunat ovat kypsiä

7.1. NIIN KAUAN KUIN vesi ei kiehu

7.1.1. odota hetki

7.1.2. tarkasta joko vesi kiehuu

7.2. NIIN KAUAN KUIN perunat eivät ole

kypsiä

7.2.1. odota hetki

7.2.2. ota haarukka

7.2.3. työnnä haarukka johonkin

perunaan

7.2.4. JOS ei tuntunut vastusta NIIN

7.2.4.1. totea perunat kypsiksi

MUUTEN

7.2.4.2. totea perunat raaoiksi

7.2.5. laita haarukka pöydälle

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 26: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 19▼ Eli toisto voidaan esittää algoritmissa seuraavasti:

NIIN KAUAN KUIN väite

toimenpiteet

jota tulkitaan suoraviivaisesti siten, että toimenpiteitä

toistetaan yhä uudelleen niin kauan kuin esitettyväite on tosi.

▼ Kuten aiemminkin väite saa olla mitä tahansa, jossiitä vain voidaan päätellä, onko se tosi vai epätosi.

▼ Algoritmikielessä »JOS-NIIN-MUUTEN» ja »NIIN

KAUAN KUIN» ovat syntaktisia (l. kieliopillisia)rakenteita, joiden semantiikka (l. merkitys) onehdollisuus ja toisto.

▼ Monista ohjelmointikielistä löytyy vastaavankaltaisetrakenteet »IF-THEN-ELSE» ja »WHILE» ➠ jatkonkannalta on selvempää, jos käytämme niitäsuomenkielisten rakenteiden sijaan.

▼ Tällaista ohjelmointikielen ja puhutun kielenyhdistelmää kutsutaan pseudokoodiksi ja se onerittäin hyödyllinen työkalu.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 27: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 20▼ Selvyyden vuoksi vielä koko perunankeittoalgoritmi

(Huom! Edelleen puutteellinen):

Algoritmi: Keitetyt perunat

1. pese perunat

1.1. laita tulppa tiskialtaaseen

1.1.1. etsi tiskialtaan tulppa

1.1.2. ota tulppa käteen

1.1.3. paina tulppa tiiviisti altaan

pohjassa olevaan reikään

1.1.4. laske irti tulpasta

1.2. laita perunat tiskialtaaseen

1.3. laske vettä tiskialtaaseen kunnes

perunat peittyvät

1.4. ota juuresharja

1.5. harjaa perunat yksitellen

juuresharjalla kunnes puhtaita

1.6. palauta juuresharja paikalleen

1.7. avaa tulppa ja laske vesi pois

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 28: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 212. etsi riittävän suuri kattila

2.1. avaa kattilakaapin ovi

2.1.1. IF kaapin ovi on kiinni THEN

2.1.1.1. tartu kaapin kahvaan

2.1.1.2. vedä ovi auki

2.1.1.3. laske irti kahvasta

2.2. valitse sopiva kattila

2.3. ota kattila

2.4. sulje ovi

2.5. aseta kattila tiskipöydälle

2.5.1. IF tiskipöydällä on tilaa THEN

2.5.1.1. aseta kattila vapaaseen

paikkaan

ELSE

2.5.1.2. raivaa tilaa kattilan verran

2.5.1.3. aseta kattila raivattuun

paikkaan

3. laita pestyt perunat kattilaan

4. lisää kattilaan vettä kunnes siellä olevat

perunat juuri peittyvät

5. laita kattila levylle

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 29: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 226. käännä levyn maksimiteho päälle

7. anna kattilassa olevan veden kiehua kunnes

siellä olevat perunat ovat kypsiä

7.1. WHILE vesi ei kiehu

7.1.1. odota hetki

7.1.2. tarkasta joko vesi kiehuu

7.2. WHILE perunat eivät ole kypsiä

7.2.1. odota hetki

7.2.2. ota haarukka

7.2.3. työnnä haarukka johonkin

perunaan

7.2.4. IF ei tuntunut vastusta THEN

7.2.4.1. totea perunat kypsiksi

ELSE

7.2.4.2. totea perunat raaoiksi

7.2.5. laita haarukka pöydälle

8. käännä levy pois päältä

9. kaada keitinvesi kattilasta viemäriin

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 30: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 23

Algoritmien muodostaminen

▼ Hyväksi havaittu tapa algoritmien muodostamiseenon jäsentää kokonaisuutta pienempiin osiin ➠

– pieniä kokonaisuuksia on helpompi hallita ja

– kokonaisuus saadaan pienistä osista yhdistämällä,kunhan osien algoritmit ovat oikein muodostettuja liitetty toisiinsa.

▼ »Hajoita ja hallitse»

▼ Idea on siis jokseenkin sama, joka esiintyi perunan-keittoalgoritmia kehiteltäessä.

▼ Jäsentämistä jatketaan, kunnes osatoiminnot ovatriittävän yksinkertaisia ➠ algoritmin toiminnot ovatmonimutkaisuudeltaan samalla tasolla kuin mitäalgoritmin suorittava systeemi ymmärtää käskyinään.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 31: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 24▼ Tietämystä algoritmin suorittavasta systeemistä siis

tarvitaan jo algoritmia suunniteltaessa ➠

– tiedetään, milloin algoritmi on jäsennelty riittävänpitkälle, ja

– jäsennystä osataan ohjata oikeaan suuntaanniin, että se sopii hyvin halutun systeeminsuoritettavaksi.

▼ Tietokoneelle algoritmia muodostettaessa ratkaisunkuvaus on kirjoitettava täsmällisesti ja täydellisesti,koska tietokoneelta puuttuu maalaisjärki ➠ se eiosaa päätellä epätäsmällisten ohjeiden tarkoitusta

▼ Puhuttuun kieleen verrattuna ohjelmointikielet ovatyksinkertaisia ja koska tietokoneelle tarkoitetut algo-ritmit täytyy aina lopulta pukea ohjelmointikieleksi,jotta ne saadaan suoritettua ➠ algoritmin oltavariittävän yksinkertaisessa muodossa, niin että se onhelposti esitettävissä ohjelmointikielellä.

▼ Algoritmien muodostaminen ei ole helppoa ja senoppiminen vaatii harjoittelua.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 32: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 25

Ohjelmointikielistä

▼ Ohjelmointikieli on se kieli, jolla tietokoneen kanssavoidaan kommunikoida (l. kuvata algoritmit koneellesen ymmärtämässä muodossa).

▼ Se on selkeästi analoginen puhutun kielen kanssa,mutta sangen yksinkertainen.

▼ Kaikki tietokoneet ymmärtävät pohjimmiltaan vainomaa konekieltään: sopivassa järjestyksessä koneenmuistiin tallennettuja lukuja 0 ja 1 (tosiasiassajännitetasoja).

▼ Tietyssä järjestyksessä esiintyvät nollat ja ykkösettietokone osaa tulkita alkeellisiksi käskyiksi, konekäs-

kyiksi.

▼ Alunperin kaikki ohjelmointi oli puhtaasti konekielelläohjelmointia: johtoja ja vipuja.

▼ Konekieli on kovin hankalakäyttöistä ➠ symbolinen

konekieli ➠ korkean tason ohjelmointikielet

(esim. lausekielet).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 33: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 26

Lausekielet

▼ Lausekielet ovat konekieltä ilmaisuvoimaisempia:niillä halutun tehtävän selittäminen tietokoneelleon helpompaa ja lopputulos ymmärrettävämpääihmiselle.

▼ Yksi lausekielellä kirjoitettu käsky vastaa useita, jopatuhansia, konekäskyjä.

▼ Ennen kuin tietokone voi suorittaa jollain muullakuin sen omalla konekielellä kirjoitetun ohjelman, setäytyy tavalla tai toisella muuntaa konekieleksi:

– kääntäminen (compiling)

– tulkkaaminen (interpreting)

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 34: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 27

Ohjelman tulkkaaminen

▼ Ohjelman tulkkaaminen perustuu siihen, ettäohjelmointikielen tulkki suorittaa ohjelmaa käsky(lause/lauseke) kerrallaan.

Etuja:

– ohjelma voidaan testata pala kerrallaan ja

– tulkki huolehtii virheilmoituksista ja auttaavirheiden etsinnässä.

Haittoja:

– ohjelman suoritus vaatii aina tulkin ja

– ohjelmaan saattaa jäädä virheitä, jos testaus eiole täydellinen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 35: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 28

Ohjelman kääntäminen

▼ Ohjelman kääntäminen perustuu siihen, että ohjel-makoodi käännetään kokonaisuudessaan konekielelleerityisellä kääntäjäohjelmalla (kääntäjällä) ennenkuin se voidaan suorittaa.

Etuja:

– syntaksi- ja semanttiset virheet havaitaan aina ja

– kääntäjää ei enää tarvita uudelleen.

Haittoja:

– ajonaikaiset virheet jäävät yleensä ohjelmoijanhoidettavaksi,

– ohjelman oltava kokonaan valmis ja

– testaus on hankalampaa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 36: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 29

Kääntäjän toiminta

Lähdekoodi

Kääntäjä

Konekieli Kirjastot

Linkkeri

Suoritettava ohjelma

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 37: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 30

Ensimmäinen C++-ohjelma

▼ Käydään yksityiskohtaisesti läpi pikkuruinenC++-kielinen ohjelma:

// Lähdekooditiedosto: forever.cc

// – – – – – – – – – – – – – – – – – – – – –

// Ohjelma tulostaa näytölle lausahduksen:

// "I plan to live forever

// or die trying."

#include <iostream>

using namespace std;

int main( ) {

cout << "I plan to live forever" << endl;

cout << "or die trying." << endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 38: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 31▼ Pienessä ohjelmassa on monta tärkeää asiaa:

– Teksti //-kirjainyhdistelmästä rivin loppuun onkommentti, joka ei vaikuta ohjelman toimintaan.

– Varsinaiset ohjelman suorittamat toiminnot ovatmain:ia seuraavien aaltosulkeiden sisällä.

– Käskyt (lauseet) tuntuvat päättyvän ";":een.

– Jos C++-ohjelmassa halutaan lukea syötteitätai kirjoittaa tulosteita, sen alkuun on lisättävä#include <iostream> ja using namespace std.

– cout on C++:ssa olio, johon voidaan<<-operaattorilla ohjata tulosteita, jotka sittenilmestyvät ohjelmaa suoritettaessa näytölle.

– Lainausmerkkien väliin kirjoitettua tekstiä kutsutaanmerkkijonoksi, mikä tarkoittaa selkokielellätekstimuotoista tietoa.

– endl tulostaa rivinvaihdon: seuraavat tulostuksetalkavat uudelta riviltä (sen vasemmasta laidasta).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 39: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 32

Lähdekoodista suoritettavaksi

ohjelmaksi

▼ C++-ohjelman tekeminen etenee yleensä seuraavasti:

1. suunnitellun algoritmin C++-version kirjoittaminenjollain editorilla

2. tallentaminen tiedostoon, jonka nimi päättyy .cc

3. tiedoston kääntäminen C++-kääntäjälläkonekielelle

4. jos tuli käännösvirheitä, niintakaisin editoriin korjaamaan ne

5. käännetyn ohjelman testaaminen,jotta nähdään, toimiiko se oikein

6. jos ei toimi oikein, niinmieti miksi ei japalaa takaisin editoriin korjaamaan viat

7. muutenohjelma on valmis

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 40: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 33

Editointi

▼ C++-ohjelmia voi kirjoittaa millä tahansa editoriohjel-malla.

▼ Ohjelmien editointiin kannattaa kuitenkin, josmahdollista, käyttää emacs-editoria.

▼ Kun emacs:illa käsittelee tiedostoa, jonka nimipäättyy .cc:hen, emacs menee automaattisestiC++-tilaan, joka osaa esimerkiksi sisentää ohjelma-koodin automaattisesti, kun vain painaa tabulaattori-näppäintä.

▼ Periaatteessa tällä kurssilla ei ole tarkoitus uppoutuaeditoriohjelman käyttöön: jonkin editorin tuntemuspitäisi jokaisella olla TiTePk:sta.

▼ Seuraavassa kuitenkin pikaopas emacs:in tärkeimpiinominaisuuksiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 41: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 34

Emacs-editorin käytöstä

▼ Emacsin saa käyntiin kirjoittamalla:

proffa> emacs tiedosto.cc

jolloin käsiteltäväksi otetaan tiedosto tiedosto.cc.

▼ Jos tiedostoa ei ennestään ole olemassa, se luodaanensimmäisen talletuksen yhteydessä.

▼ C++-lähdekooditiedostojen nimen pitää päättyä.cc:hen, jonka myös emacs tajuaa ja meneesen seurauksena C++-tilaan, jossa on ohjelmienkirjoittamisen avuksi monenlaisia ominaisuuksia.

▼ Käynnistyttyään emacs näyttää käsiteltäväntiedoston, jota sitten voidaan muuttaa joko suoraantekstiä kirjoittamalla tai eri näppäinyhdistelmiinsidotuilla komennoilla.

▼ Seuraavaan kerätty pikku lista hyödyllisiä emacsinnäppäinyhdistelmiin sidottuja komentoja.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 42: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 35ZYQR

Nuolinäppäimillä kursorin voi liikuttaa tekstinseassa haluamaansa paikkaan.

C+xC+sTallettaa tiedoston levylle. Muista aina tallettaatiedosto ennen kääntämistä.

C+zKeskeyttää emacsin suorituksen ja hyppääproffan komentotulkkiin, jolle voi syöttää UNIX-komentoja, esimerkiksi käännöskomennon. Kunkomennot on annettu, pääsee emacsiin takaisinkomennolla fg:

proffa> fg

jolloin emacs palaa samaan tilanteeseen, missä seoliC+z:aa painettaessa.

C+xC+cTappaa emacsin lopullisesti: fg-komennolla eipääse takaisin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 43: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 36

Xxgoto..- lineEnnnEKursori hyppää tiedoston riville nnn. Hyödyllinenkun halutaan päästä riville, jolla kääntäjä väittivirheen sijaitsevan.

XxcompileEMahdollistaa käännöskomennon antamisenemacsista. Ehdottaa aluksi komentoa make –k,josta pääsee eroon painamalla =-näppäintäriittävän monta kertaa, jonka jälkeen voi naputellahaluamansa käännöskomennon aivan, kuten UNIX-

komentoriviltä.E:in painalluksen jälkeenemacs avaa uuden ikkunan ja suorittaa annetunkomennon siten, että kaikki virheilmoituksetilmestyvät uuteen ikkunaan.

C+xoSiirtää kursorin emacsin ikkunasta toiseen:tällä komennolla pääsee lähdekoodi-ikkunastavirheilmoitusikkunaan ja takaisin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 44: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 37C+cC+c

SiirtymälläC+xo:lla virheilmoitusikkunaan,siellä nuolinäppäimillä virheilmoitusrivin päälle jasuorittamalla tämän komennon hyppää emacssiihen kohtaan lähdekooditiedostossa, jolla virhesijaitsi.

C+x1Emacs sulkee kaikki muut ikkunat, paitsi, senjossa kursori on. Tällä tavoin pääsee eroonvirheilmoitusikkunasta, kunhan muistaa ensinsiirtää kursorin lähdekoodi-ikkunaan.

C+xb tiedostonnimiEJos vahingossa tulee sulkeneeksi ikkunan,jossa lähdekoodi oli, saa sen haettua takaisintällä komennolla: antaa vain tiedostonnimeksi

lähdekooditiedoston nimen.

TPainamalla tabulaattoria lähdekoodirivillä emacsyrittää sisentää sen siististi parhaan kykynsämukaan. Vastuu on kuitenkin kirjoittajalla!

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 45: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 38

Kääntäminen

▼ Ohjelman kääntämiseen käytämme tällä kurssillaohj1c++-nimistä kääntäjää.

▼ ohj1c++:lle luetellaan komentorivillä kaikkiC++-kieliset lähdekooditiedostot, ja se kääntääniistä suoritettavan konekielisen ohjelman:

proffa> ohj1c++ forever.cc

▼ Jos ohjelma on virheetön, tuloksena syntyyajokelpoinen ohjelma a.out, joka voidaan suorittaakirjoittamalla sen nimi komentotulkille:

proffa> ./a.out

I plan to live forever

or die trying.

▼ a.out ei ole kuvaava nimi, mutta ohj1c++:lle voikertoa, minkä nimisen ohjelman haluaa tuloksena:

proffa> ohj1c++ –o plan forever.cc

proffa> ./plan

I plan to live forever

or die trying.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 46: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 39

Virhetilanteet

▼ Periaatteessa ohjelmissa on kolmenlaisia virheitä:

– kielioppi- eli syntaksivirheitä,

– semanttisia eli »merkitysvirheitä» ja

– loogisia eli »ajatusvirheitä».

Syntaksivirheet

▼ Syntaksivirheet ovat virheitä, jotka syntyvät, kunlähdekoodi ei ole käytetyn ohjelmointikielenkielioppisääntöjen mukaista.

▼ Esimerkiksi cout- tai return-komennon (lauseen)lopusta puuttuva ";"-merkki olisi C++:ssa syntaksivirhe.

▼ Kääntäjä löytää aina syntaksivirheet.

▼ Virheen löydyttyä kääntäjä tulostaa ilmoituksen,joka kertoo virheen syyn ja (suuntaa-antavan)rivinumeron, jolla virhe lähdekooditiedostossa senmielestä sijaitsi.

▼ Tyypillisesti virheilmoitus alkaa sanoilla »syntaxerror» tai »parse error».

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 47: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 40Semanttiset virheet

▼ Semanttiset virheet syntyvät, kun ohjelmakoodi onsyntaktisesti oikein, mutta kääntäjä ei silti pystyymmärtämään sitä.

▼ Jos esimerkkiohjelmassa olisi vahingossa kirjoitettundl, kun oikea vaihtoehto on endl, olisi tuloksenasemanttinen virhe.

▼ Semanttiset virheetkin kääntäjä löytää aina.

▼ Semanttisesta virheestä tulostuu virheilmoitus,jonka jälkeen kääntäjä tyypillisesti sekoaa ja väittäälöytävänsä koodista samalta ja myöhemmiltäriveiltä kaikennäköisiä virheitä ➠ korjaa virheet ainakääntäjän ilmoittamassa järjestyksessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 48: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 41Loogiset virheet

▼ Loogiset virheet syntyvät, kun ohjelman kirjoittajaajattelee jotain väärin tai unohtaa ottaa huomioonjonkun joskus hyvinkin vähäpätöisen seikan.

▼ Loogiset virheet ovat tavallisesti kirjoitusvirheitä taialgoritmin suunnittelussa tapahtuneita virheitä.

▼ Loogiset virheet ilmenevät siten, että ohjelma toimiiväärin.

▼ Kääntäjällä ei ole mahdollisuuksia havaita loogisiavirheitä, koska se vaatisi ohjelmoijan ajatuksen-juoksun ymmärtämistä.

▼ Ainoa tapa välttää loogisia virheitä on ohjelmanhuolellinen suunnittelu ja kirjoittaminen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 49: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 42Varatut sanat

▼ Kuten puhutuissa kielissä, on ohjelmointikielissäkinsanoja, joilla on jokin kiinteä merkitys.

▼ Ohjelmointikielistä puhuttaessa tällaisia sanojakutsutaan varatuiksi sanoiksi.

▼ Varatuille sanoille on siis ohjelmointikielessämääritelty merkitys, eikä ohjelmoija yleensä voimuuttaa tätä merkitystä, koska tällöin kyseisen sananalkuperäinen tarkoitus hukkuisi.

▼ Joskus kielen varattuja sanoja kutsutaan myöskäskyiksi.

▼ Sanaa »käsky» käytetään kuitenkin usein hiukanvapaammin, esimerkiksi tarkoittamaan yhtä ohjelmanlausetta.

▼ Varatut sanat luovat perustan koneen ja ohjelmoijankommunikoinnille käytettäessä korkean tasonohjelmointikieltä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 50: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 43

C++-kielen varatut sanat

▼ Seuraavassa on lueteltu C++-kielen varatut sanat:

and dynamic_cast not_eq throwand_eq else operator trueasm enum or trybitand explicit or_eq typedefbitor export private typeidbool false protected typenamebreak float public unioncase for register unsignedcatch friend reinterpret_cast usingchar goto return virtualclass if short voidcompl inline signed volatileconst int sizeof wchar_tconst_cast long static whilecontinue main static_cast xordefault mutable struct xor_eqdelete namespace switchdo new templatedouble not this

▼ Osaan kurssilla tutustutaan, muttei läheskäänkaikkiin.

▼ Luentomateriaalin ohjelmaesimerkeissä varatut sanaton lihavoitu.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 51: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 44

Esimerkki

// Lähdekooditiedosto: vastukset.cc

// – – – – – – – – – – – – – – – – – – – – – – –

// Kommentointi on tärkeä osa ohjelman

// kirjoittamista, mutta kalvoilla se vie lii–

// kaa tilaa, joten vastaisuudessa esimerkit

// ovat kommentoituja vain tositarpeessa!

#include <iostream>

using namespace std;

int main( ) {

cout << "Sarjaan: " << 5.0 + 10.0 << endl;

cout << "Rinnan: "

<< 5.0 * 10.0 / (5.0 + 10.0) << endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 52: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 45▼ Kun ohjelma käännetään ja suoritetaan:

proffa> ohj1c++ –o vastukset vastukset.cc

proffa> ./vastukset

Sarjaan: 15

Rinnan: 3.33333

▼ Siitä opittua:

– C++-kieli selvästikin ymmärtää lukuja ja sallii niillälaskemisen.

– cout:in avulla voidaan tulostaa myös lukuja(laskulausekkeen arvoja).

– C++ ei ole kovin tarkka siitä, kuinka jaammeohjelmamme riveille.

– Kuinka sisennetään siististi useamman rivinkokoinen C++-lause.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 53: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 46

Perustietotyypit

▼ Tietokoneohjelmat koostuvat kahdenlaisista olioista:

– tiedosta ja

– toimenpiteistä, jotka käsittelevät sitä.

▼ Jotta ohjelmointikielellä voisi tehdä tietoa käsitteleviäohjelmia, on oltava joku tapa tiedon esittämiseen jakäsittelyyn ➠

– perustietotyypit (alkeistietotyypit) tiedonesittämiseen ja

– varatut sanat ja operaattorit sen käsittelyyn.

▼ Yleisesti ottaen tietotyypillä käsitetään joukkoaalkioita, joilla on samat ominaisuudet, eli niitävoidaan käsitellä samoilla operaattoreilla.

▼ Perustietotyypit ovat sellaisia tiedon esitysmuotoja,jotka ohjelmointikieli tuntee automaattisesti.

▼ Tavallisesti perustietotyyppien alkioiden käsittelyynon valmiit käskyt konekielessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 54: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 47▼ Kaikella tiedolla on joku tyyppi.

▼ Alussa riittää tutustua perustietotyyppeihin, joitaC++-kielessä kutsutaan aritmeettisiksi tyypeiksi,eli tyypeiksi, joille voidaan suorittaa normaalejalaskuoperaatioita (kuten yhteen- ja kertolasku).

▼ Tälläisia tyyppejä ovat C++:ssä:

– int kokonaisluvuille (–2, 123456),

– double (float) reaaliluvuille (3.1415, 1E10) ja

– char kirjainmerkeille ( ’a’, ’\n’).

▼ Todellisuudessa C++ käsittelee kirjainmerkkejäkinpieninä kokonaislukuina (vrt. ASCII-koodi jaISO-8859).

▼ Myös merkkijonot (string, tekstimuotoinen tieto,lainausmerkkien sisällä oleva teksti) on käytän-nössä tässä vaiheessa perustietotyyppi, vaikkatodellisuudessa se ei sitä olekaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 55: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 48

Lausekeet

▼ Lauseke on tietokoneohjelmassa pohjimmiltaansama kuin se on matematiikassa: jokin kokonaisuusjolle voidaan laskea (eli evaluoida) arvo.

▼ Esimerkiksi

(8 + 16 * 4) / 2

on lauseke, jolle evaluoituu arvo 36.

▼ Ohjelmointikielissä lauseke on kuitenkin huomatta-vasti laajempi käsite kuin mihin perusmatematiikassaon totuttu.

▼ Lausekkeen lähtöarvoina käsitelty tieto ei välttämättämuodostu luvuista, eikä lopputuloksenkaan tarvitseolla luku.

▼ Pidetään mielessä, että ohjelmointikielissä lausek-keella tämä erityisen laaja tulkinta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 56: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 49

Operaattorit

▼ Seuraava taulukko on esittelee lähes kaikki C++-kielenoperaattorit, niiden laskujärjestyksen (presedenssin)ja sitomisjärjestyksen (assosioitumisen):

→ : :

→ . –> [ ] ( ) muuttuja++ muuttuja ––

← ~ ! – lauseke + lauseke ++muuttuja –– muuttuja

&muuttuja * lauseke sizeof new delete

→ * / %

→ + –

→ << >>

→ < <= > >=

→ == !=

→ &

→ ^

→ |

→ &&

→ | |

← = *= /= %= += –= <<= >>= &= |= ^=

→ lauseke ? lauseke : lauseke

→ lauseke , lauseke

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 57: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 50

Laskujärjestys (presedenssi)

▼ Operaattori lasketaan (evaluoidaan) sitä aikai-semmin, mitä ylemmässä lokerossa se on taulukossa.

▼ Suluilla evaluointijärjestys voidaan määrätä halutuksi.

▼ Jotkut operaattorit (+, –, * ja &) esiintyvät taulukossakahteen kertaan:

– korkeammalla olevat unaari-operaattorit tarvit-sevat yhden operandin ja

– alemmat binääri-operaattorit tarvitsevat kaksi.

▼ Esimerkiksi lauseke:

a = 1 * 2 + –3 / 4;

evaluoituu samoin kuin jos olisi kirjoitettu:

(a = ( (1 * 2) + ( ( –3) / 4) ) ) ;

▼ Kyseessä siis on aivan sama asia kuin matematiikastatutuissa laskujärjestyssäännöissä, paitsi että C++:ssaoperaattoreita on paljon enemmän.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 58: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 51▼ C++:ssa (lähes) kaikkien operaattorien tuloksena

evaluoituu arvo, jota voidaan käyttää operandinamuille operaattoreille.

▼ Aritmeettisten operaatioiden tulos on samaa tyyppiäkuin niiden operandien tyypit ➠ kannattaa ollaerityisen varovainen jakolaskuoperaation kanssa,esimerkiksi 1 / 2 tarkoittaa kokonaislukujakolaskua,eli tulos onkin nolla!

▼ Jos kokonaislukujen jakolaskusta on tarve saada»tarkka» reaalilukutulos, täytyy toinen operandimuuttaa reaaliluvuksi käsin käyttämällä tyyppi-

muunnosoperaattoria:

static_cast<double>(1) / 2

jolloin suoritettava laskutoimitus on:

1.0 / 2

eli myös tulos tulee olemaan reaaliluku 0.5.

▼ Nyrkkisääntönä: jos operandit ovat eri tyyppiä,tuloksena on esitysalueeltaan laajempi tyyppi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 59: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 52

Sitomisjärjestys (assosioituminen)

▼ Presedenssisäännöt eivät kerro kaikkea lausekkeenevaluointijärjestyksestä: jos samassa lausekkeessa onperäkkäin useita samalla tasolla olevia operaattoreita.

▼ Tällaiset tilanteet ratkaisee operaattorin sitomisjär-jestys, joka voi olla:

– vasemmalta oikealle, jolloin operaatiot suoritetaanvasemmalta oikealle tai

– oikealta vasemmalle vastaavasti.

▼ Taulukossa sitomisjärjestys on merkitty nuolellavasempaan sarakkeeseen.

▼ Esimerkiksi:

1 – 2 – 3 – 4

evaluoidaan C++:ssa siis:

( ( (1 – 2) – 3) – 4)

▼ Sitomisjärjestyksellä on merkitystä esimerkiksi yli- jaalivuototilanteissa ja pyöristysvirheiden kanssa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 60: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 53

Yli- ja alivuoto

▼ Sisäisesti tietokone esittää luvut kaksikantaisina(binäärilukuina) jollain äärellisellä määrällä nollia jaykkösiä (bittejä) ➠ lukualueet, joita se voi esittää,ovat rajallisia.

▼ Esimerkiksi useat tietokoneet nykyään esittävätkokonaisluvut (int) 32:lla bitillä, jolloin niiden suurinmahdollinen arvo 232 − 1 (= 4294967295).

▼ Tosiasiassa suurin arvo on 231 − 1 (= 2147483647),koska yksi bitti käytetään etumerkin esittämiseen.

▼ Tilannetta, jossa laskutoimituksen tuloksena syntyyniin iso luku, ettei tietokone voi sitä esittää, kutsutaanylivuodoksi.

▼ Vastaavasti alivuoto on tilanne, jossa reaaliluvuillalaskettaessa syntyy itseisarvoltaan niin pieni tulos,ettei esitystarkkuus riitä.

▼ Eri tietokoneissa on erilaiset lukualueet ja laskenta-tarkkuudet.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 61: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 54

Esimerkki

Ratkaistava ongelma

Tulosta yhden Celsius-asteen välein käyttäjänantaman alarajan ja ylärajan väliltä Celsius-lämpötiloja vastaavat Fahrenheit-lämpötilat.Tulostuksen selkeyttämiseksi numeroi tulostetut rivit.

Ratkaisualgoritmi

Algoritmi: Celsius–Fahrenheit -taulukko

kysy käyttäjältä alin tulostettava Celsius-lämpötila

alin celsius← käyttäjältä luettu syöte

kysy käyttäjältä ylin tulostettava Celsius-lämpötila

ylin celsius← käyttäjältä luettu syöte

rivinumero← 1

tulostettava celsius← alin celsius

WHILE tulostettava celsius ≤ ylin celsius

fahrenheit← 1.8 * tulostettava celsius + 32;

tulosta rivinumero, tulostettava celsius ja fahrenheit

rivinumero← rivinumero + 1

tulostettava celsius← tulostettava celsius + 1

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 62: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 55Algoritmin toteutus C++:lla

#include <iostream>

using namespace std;

int main( ) {int alin_celsius;int ylin_celsius;

cout << "Anna alin tulostettava Celsius–lämpötila: ";cin >> alin_celsius;cout << "Anna ylin tulostettava Celsius–lämpötila: " ;cin >> ylin_celsius;

int rivinumero = 1;int tulostettava_celsius = alin_celsius;

while (tulostettava_celsius <= ylin_celsius) {double fahrenheit = 1.8 * tulostettava_celsius + 32;

cout << rivinumero << ": "<< tulostettava_celsius << " C = "<< fahrenheit << " F" << endl;

rivinumero = rivinumero + 1;++tulostettava_celsius;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 63: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 56Käännös ja suoritus

proffa> ohj1c++ –o celsius celsius.ccproffa> ./celsiusAnna alin tulostettava Celsius-lämpötila: –10Anna ylin tulostettava Celsius-lämpötila: 101: –10 C = 14 F2: –9 C = 15.8 F3: –8 C = 17.6 F4: –7 C = 19.4 F5: –6 C = 21.2 F6: –5 C = 23 F7: –4 C = 24.8 F8: –3 C = 26.6 F9: –2 C = 28.4 F10: –1 C = 30.2 F11: 0 C = 32 F12: 1 C = 33.8 F13: 2 C = 35.6 F14: 3 C = 37.4 F15: 4 C = 39.2 F16: 5 C = 41 F17: 6 C = 42.8 F18: 7 C = 44.6 F19: 8 C = 46.4 F20: 9 C = 48.2 F21: 10 C = 50 F

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 64: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 57Mitä siitä opittiin

▼ Ohjelman käyttöön voidaan määritellä »tiedontallennuspaikkoja» eli muuttujia (esimerkiksi:alin_celsius, rivinumero ja fahrenheit).

▼ Muuttujaan voidaan tallettaa arvo sijoitusope-

raattorilla (=) tai lukemalla käyttäjän näppäimis-tösyötettä (cin >>).

▼ Myöhemmin ohjelmassa esiintyvä muuttujan nimikorvataan siihen kaikkein viimeisimpänä sijoitetullaarvolla (poikkeuksia on: =-operaattorin vasenoperandi ja ++).

▼ while-silmukkarakenteella voidaan toistaa joitainkäskyjä halutun monta kertaa.

▼ ++-operaattori kasvattaa kokonaislukuoperandinsaarvoa yhdellä (tämä on vain osatotuus asiasta).

▼ +-operaattori toimii oikein vaikka toinen operandiolisikin double- ja toinen int-tyyppinen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 65: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 58

while-silmukka

▼ while-silmukan yleinen muoto on:

while ( ehto ) {suoritettava_lause1;

· · ·suoritettava_lausen;

}

tai jos suoritettavia lauseita on vain yksi:

while ( ehto )

suoritettava_lause;

tässäkin tapauksessa saa käyttää aaltosulkuja.

▼ while toistaa rungossaan olevia lauseita niin kauankuin ehto evaluoituu ennen uutta kierrosta todeksi.

▼ Heti, kun ehdosta evaluoituu ennen uutta kierrostaepätosi, ohjelman suoritus jatkuu while-rakennettaseuraavasta käskystä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 66: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 59▼ Ehto evaluoidaan aina ensimmäisenä ennen uuden

kierroksen aloittamista ➠ jos se on heti aluksiepätosi, silmukan runkoa ei suoriteta kertaakaan.

▼ Ehto voi olla mikä tahansa lauseke, jolle evaluoituuarvo tosi tai epätosi ➠ lauseke, jossa käytetäänvertailu- tai loogisia operaattoreita (== , != , < , <= ,> , >= , ! , && , | | ).

▼ C++:ssa on erillinen perustietotyyppi bool, jonkalailliset arvot ovat true (tosi) tai false (epätosi)

➠ edellä lueteltuja operaattoreita sisältävistälausekkeista evaluoituu arvo, joka on tyypiltään bool.

▼ Myös bool-tyyppistä muuttujaa voi käyttää ehtona.

▼ Historiallisena jäänteenä C-kielestä kokonaisluvuttulkitaan totuusarvoiksi ➠ luku 0 on epätosi ja kaikkimuut luvut tosia.

▼ Jatkossa opitaan myös, että joissain tilanteissamuitakin tietotyyppejä voi käyttää ehtona.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 67: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 60

Vertailuoperaattorit

▼ C++-kielessä on perustietotyyppien vertailuunkäytettävissä seuraavat vertailuoperaattorit:

Operaattori Merkitys

== yhtäsuuri kuin

!= erisuuri kuin

< pienempi kuin

<= pienempi tai yhtäsuuri kuin

> suurempi kuin

>= suurempi tai yhtäsuuri kuin

▼ Kaikki vertailuoperaattorit ovat binäärioperaattoreita:ne vertailevat kahta tietoalkiota.

▼ Vertailun tuloksena evaluoituu bool-tyyppinen arvotrue (tosi) tai false (epätosi) riippuen siitä, pitikövertailulausekkeessa esitetty väite paikkansa vai ei.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 68: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 61

Muuttujat

▼ Muuttujia voi ajatella tiedon tallennuspaikkoina.

▼ Toisaalta ne ovat myös jollekin tietoalkiolle annettujanimiä.

▼ Kolmanneksi niitä voi ajatella muistipaikan sisällölleannettuna symbolisena nimenä.

▼ Muuttujilla on kolme ominaisuutta:

– tyyppi ja

– nimi, jotka kerrotaan muuttujaa määriteltäessä,esimerkiksi: int rivinumero; ja

– arvo, joka yleensä asetetaan =-operaattorilla,esimerkiksi: rivinumero = 1;

▼ Muuttujat pitää aina määritellä (ja vain kerran),ennen kuin niitä voi käyttää.

▼ Pääsääntöisesti muuttujiin voi tallettaa vain tietoa,joka on saman tyyppistä kuin muuttujan oma tyyppi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 69: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 62▼ Poikkeus: aritmeettisia tietotyyppejä C++ osaa

automaattisesti muuntaa toisikseen, jos se onmahdollista. On oikein sanoa: int i = 5.5; ➠huomaa kuitenkin pyöristysvirheet ja ylivuodot.

▼ Määrittelyn jälkeen ohjelmassa esiintyvän muuttujannimen paikalle evaluoituu siihen viimeisimpänäsijoitettu arvo (muutamia poikkeuksia on, kutenaiemmin todettiin).

▼ Muuttujia voi C++:ssa määritellä kahdessa paikassa:

– Minkä tahansa lohkon (eli aaltosulkuparin { })

sisällä sellaisessa kohdassa, jossa voisi olla lause.Tällaista muuttujaa kutsutaan paikalliseksi

muuttujaksi ja se on käytettävissä vain sen lohkonsisällä (sulkevaan }-merkkiin saakka), jossa se onmääritelty.

– Kaikkien lohkojen ulkopuolella, jolloin kyseessäglobaali muuttuja.

▼ Älä käytä globaaleja muuttujia!

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 70: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 63▼ Muuttujan nimen pitää alkaa merkillä A–Z tai a–z,

mutta loput merkit voivat olla myös numeroita taialaviivoja (_).

▼ Muuttuja voi olla myös vakiomuuttuja, jokakäyttäytyy aivan kuin normaali muuttuja, mutta senarvoa ei määrittelyn jälkeen voi muuttaa.

▼ Vakiomuuttujia määritellään lisäämällä varattu sanaconst määrittelyn eteen: const int paino = 115;

▼ Tällaisille vakioille pitää alustaa arvo määrittelynyhteydessä, sillä se ei myöhemmin ole mahdollista.

▼ Muista aina muuttujaa määritellessäsi pysähtyämiettimään, minkälaista tietoa siihen on tarkoitustallentaa ➠ tiedon tyyppi määrää muuttujan tyypin.

▼ Literaalit ovat tietoalkioita, joilla on vain tyyppi jaarvo mutta ei nimeä.

▼ Literaaleja voi kutsua myös nimettömiksi vakioiksi.

▼ Esimerkiksi literaaleja ovat seuraavat:’x’, 12345, 1.2345 ja "DFW".

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 71: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 64

Esimerkki

Ratkaistava ongelma

Tee ohjelma, joka laskee (miespuolisen) käyttäjänpainoindeksin ja kertoo, onko henkilöllä yli-, ali- tmspainoa. Ohjelman toiminta näytää seuraavalta:

proffa> ./painoindeksiMies, anna painosi kiloina: 115Pituutesi metreinä: 1.92Painoindeksi on: 31.1957 eli paljon ylipainoa

Taustatietoa

Painoindeksi lasketaan seuraavalla kaavalla:painoindeksi =

paino kg

pituus 2m

ja miehille sen arvoa tulkitaan seuraavasti:

Painoindeksi Tulkinta

indeksi ≤ 20.7 alipainoa

20.7 < indeksi ≤ 26.4 normaali

26.4 < indeksi ≤ 27.8 lievää ylipainoa

27.8 < indeksi ≤ 31.1 ylipainoa

31.1 < indeksi paljon ylipainoa

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 72: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 65Ratkaisualgoritmi

Algoritmi: Painoindeksi

kysy käyttäjän paino kiloina

paino← käyttäjän syöte

kysy käyttäjän pituus metreinä

pituus← käyttäjän syöte

painoindeksi← paino / (pituus * pituus)

tulosta painoindeksin arvo

IF painoindeksi ≤ 20.7 THEN

tulosta "alipainoa"

ELSE IF 20.7 < painoindeksi ≤ 26.4 THEN

tulosta "normaali"

ELSE IF 26.4 < painoindeksi ≤ 27.8 THEN

tulosta "lievää ylipainoa"

ELSE IF 27.8 < painoindeksi ≤ 31.1 THEN

tulosta "ylipainoa"

ELSE

tulosta "paljon ylipainoa"

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 73: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 66Algoritmin toteutus C++:lla

#include <iostream>

using namespace std;

int main( ) {double paino;double pituus;

cout << "Mies, anna painosi kiloina: " ;cin >> paino;cout << "Pituutesi metreinä: ";cin >> pituus;

double indeksi = paino / (pituus * pituus) ;

cout << "Painoindeksi on: " << indeksi << " eli " ;

if ( indeksi <= 20.7 ) {cout << "alipainoa" << endl;

} else if ( 20.7 < indeksi && indeksi <= 26.4 ) {cout << "normaali" << endl;

} else if ( 26.4 < indeksi && indeksi <= 27.8 ) {cout << "lievää ylipainoa" << endl;

} else if ( 27.8 < indeksi && indeksi <= 31.1 ) {cout << "ylipainoa" << endl;

} else {cout << "paljon ylipainoa" << endl;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 74: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 67Mitä siitä opittiin

▼ C++-kielen if-rakenteella saadaan aikaan ehdollista

suoritusta: joidenkin käskyjen suorittaminenriippuu ohjelmoijan määräämästä ehdosta.

▼ Looginen operaattori && (ja-operaattori) saaoperandeinaan kaksi totuusarvoa ja evaluoituutodeksi vain, jos molemmat operandit olivat tosia.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 75: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 68

if-rakenne

▼ If-rakenne on monipuolisin tapa toteuttaa ehdollistasuoritusta (haarautumista) C++-kielessä.

▼ If-rakenteen yleinen muoto on:

if ( ehto1 ) {suoritettava_lause1.1;

. . .

suoritettava_lause1.i;

} else if ( ehto2 ) {suoritettava_lause2.1;

. . .

suoritettava_lause2.j;

}// . . . tarvittava määrä else-if:ejä tähän . . .

else {suoritettava_lausen.1;

. . .

suoritettava_lausen.k;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 76: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 69▼ Ehtoja lähdetään tutkimaan ylhäältä alas, ja kun

löytyy ehto, joka evaluoituu todeksi, suoritetaansiihen liittyvät lauseet ja jatketaan if-rakennettaseuraavasta lauseesta.

▼ Else-haaran lauseet suoritetaan vain, jos mikäänedeltävä ehto ei evaluoitunut todeksi.

▼ Else if- ja else-haarat eivät ole pakollisia.

▼ If ei välttämättä suorita mitään haaraa, jos else

puuttuu, eikä mikään ehto evaluoidu todeksi.

▼ Aaltosulut eivät ole pakollisia, jos haarassa on vainyksi suoritettava lause.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 77: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 70

Loogiset operaattorit

▼ Usein silmukan ehto tai if-rakenteen haaranvalitsemiseen käytetty ehto on monimutkaisempikuin yhden vertailuoperaattorin tulos.

▼ Mielivaltaisia ehtorakennelmia saadaan aikaanyhdistelemällä sopivasti loogisia operaattoreita:

! ei-operaattori (unaarinen), tosi josoperandi on epätosi.

&& ja-operaattori (binäärinen), tosi josmolemmat operandit ovat tosia.

| | tai-operaattori (binäärinen), tosi josedes toinen operandi on tosi.

▼ Edellä kuvatun kolmen operaattorin sijaan voikäyttää myös varattuja sanoja not, and ja or.

▼ Ja- ja tai-operaattoreita voi olla monta perätysten ➠

– presedenssi edellisen taulukon mukaan laskeva ja

– sitomisjärjestys &&- ja | | -operaattoreilla → ja!-operaattorilla←

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 78: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 71▼ Ja- ja tai-operaattorit ovat oikosulkuoperaattoreita:

toisin kuin aritmeettiset operaattorit, ne eivät aluksievaluoi molempia operandejaan, vaan suorittavatevaluoinnin operandi kerrallaan vasemmalta oikealleja lopettavat heti, kun tulos on pääteltävissä.

▼ Tällä on merkitystä tilanteissa, joissa halutaan pukeaehdoksi lauseke, jonka evaluointi ei kaikissa tilanteissaole laillista.

▼ Jos esimerkiksi halutaan testata onko muuttujanluku arvo tasan jaollinen muuttujan jakaja arvolla:

int luku;int jakaja;

// · · ·if ( jakaja != 0 && luku % jakaja == 0 ) {

// · · ·}

jossa &&-operaattorin oikosulkuominaisuus takaasen, ettei ehtolausekkeessa koskaan yritetä ottaajakojäännöstä nollan kanssa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 79: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 72

Esimerkki

Ratkaistava ongelma

Tee ohjelma, joka tulostaa seuraavan söötin kerto-taululunttilapun:

+–––+––––––––––––––––––––––––––––+| × | 1 2 3 4 5 6 7 8 9 |+–––+––––––––––––––––––––––––––––+| 1 | 1 2 3 4 5 6 7 8 9 || 2 | 2 4 6 8 10 12 14 16 18 || 3 | 3 6 9 12 15 18 21 24 27 || 4 | 4 8 12 16 20 24 28 32 36 || 5 | 5 10 15 20 25 30 35 40 45 || 6 | 6 12 18 24 30 36 42 48 54 || 7 | 7 14 21 28 35 42 49 56 63 || 8 | 8 16 24 32 40 48 56 64 72 || 9 | 9 18 27 36 45 54 63 72 81 |+–––+––––––––––––––––––––––––––––+

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 80: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 73Ratkaisualgoritmi

Algoritmi: Kertotaulun tulostus

tulosta erotinvaakarivi

tulosta sarakkeiden otsikkorivi

tulosta erotinvaakarivi

luku← 1

WHILE luku ≤ 9

tulosta luvun kertotaulurivi

luku← luku + 1

tulosta erotinvaakarivi

▼ Joitain algoritmin kohtia voisi yksityiskohtaistaa,mutta se ei ole esimerkin opetuksellinen pointti,joten tyydytään yllä esitettyyn.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 81: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 74Algoritmin toteutus C++:lla

#include <iostream>

#include <iomanip>

using namespace std;

void TulostaErotinVaakarivi( ) {cout << "+– – – "

<< "+– – – – – – – – – – – – – – – – – – – – – – – – – – – –+"<< endl;

}

void TulostaOtsikkorivi( ) {cout << " | x | 1 2 3 4 5 6 7 8 9 | "

<< endl;}

void TulostaKertotaulurivi( int kertoja) {cout << " | " << kertoja << " | ";

int kerrottava = 1;while (kerrottava <= 9) {

cout << setw(3) << kertoja * kerrottava;++kerrottava;

}

cout << " | " << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 82: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 75int main( ) {

TulostaErotinVaakarivi( ) ;TulostaOtsikkorivi( ) ;TulostaErotinVaakarivi( ) ;

int luku = 1;while ( luku <= 9) {

TulostaKertotaulurivi( luku);++luku;

}

TulostaErotinVaakarivi( ) ;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 83: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 76Mitä siitä opittiin

▼ Lisäämällä ohjelman alkuun rivi#include <iomanip> saadaan käyttöön valmiitatyökaluja, joilla tulostuksen ulkoasua voidaanohjailla. Esimerkiksi tulostuskentän leveys saadaanasetettua setw ohjauskomennolla.

▼ Ohjelman monimutkaisuutta voidaan helpomminhallita jakamalla sen toiminnot osiin aliohjelmien

(proseduurien) avulla: jokainen aliohjelmatoteuttaa jonkun ohjelman osatoiminnon, jokasaadaan suoritettua aliohjelmaa kutsumalla.

▼ Aliohjelmalle voidaan tarvittaessa välittää myösparametreja, jotka »hienosäätävät» sen toimintaa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 84: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 77

Tulostuksen muotoilu

▼ Muista: #include <iomanip> ohjelman alkuun.

▼ Seuraavassa on esitelty lyhykäisesti tärkeimmättulostuksen muotoiluun käytetyt ohjauskomennot.

▼ Niitä ei käydä läpi sen yksityiskohtaisemmin, muttaon silti hyvä, että ne on kerätty yhteen listaan:

Ohjauskomento Merkitys

setw(leveys) Tulostettava tieto vie aina vähin-tään leveys merkkiä tilaa.

left Jos tulostettava tieto vievähemmän tilaa kuin mikätämänhetkinen tulostuskentänleveys on, tulostetaan kentänvasempaan laitaan.

right Kuten edellinen, mutta tuloste-taan kentän oikeaan laitaan.

setfill(merkki) Kentän täytteenä käytetään(setw’n yhteydessä) merkkiä.

setprecision(tarkkuus) Reaalilukuja tulostettaessa tark-

kuus kpl. merkitseviä numeroita.

fixed Em. tarkkuus tulkitaan desimaa-lipisteen oikealle puolelle tulos-tettavien desimaalien määräksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 85: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 78

Aliohjelmat eli proseduurit

▼ Aliohjelmat ovat ohjelmointikielen tarjoama työkaluohjelman pilkkomiseen hallittaviin osiin.

▼ Päämääränä aliohjelmien käytössä on tietysti sevanha tuttu: jos ongelma on liian iso, pilko sitäpienempiin palasiin, kunnes jäljellä on niin pieniäosia, että pää ei sekoa.

▼ Toimiva ohjelma saadaan, kun syntyneet pienetosaset yhdistellään toimimaan kokonaisuutena.

▼ C++:ssa aliohjelma määritellään seuraavasti:void AliohjelmanNimi( ) {

aliohjelman_runko

}

tai mikäli aliohjelmalla on parametreja:void AliohjelmanNimi(muodolliset_parametrit ) {

aliohjelman_runko

}

▼ AliohjelmanNimi voi olla mikä tahansa, kunhan senoudattaa samoja sääntöjä kuin muuttujien nimet.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 86: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 79▼ Aliohjelmalle kannattaa pyrkiä valitsemaan nimi, joka

kuvaa hyvin sen toimintaa ➠ ohjelma selkiytyy.

▼ aliohjelman_runko saa olla mitä tahansa suoritettaviaC++-lauseita ➠ ne määräävät, mitä aliohjelma tekee.

▼ Koska koko idea aliohjelmissa oli se, että iso ongelmapaloitellaan pienemmiksi osiksi ➠ aliohjelman_runko

ei saisi olla liian pitkä.

▼ Hyvä nyrkkisääntö kuuluu seuraavasti:

Jos aliohjelma on pidempi kuin mitä näytölle

mahtuu kerralla rivejä, mieti kuinka sen voisi jakaa

kahdeksi tai useammaksi uudeksi aliohjelmaksi,

jotka yhdessä toteuttavat sen toiminnot.

▼ muodolliset_parametrit näyttää listalta pilkulla ero-teltuja muuttujan määrittelyitä, mitä se käytännössäonkin.

▼ Jokainen muodolliset_parametrit-listassa määriteltymuuttuja käyttäytyy aliohjelman_rungossa kutenuusi paikallinen muuttuja, paitsi että sen alkuarvoksion automaattisesti alustettu vastaavasta kutsussa

annetusta todellisesta parametrista evaluoitu arvo.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 87: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 80▼ Muodolliset parametrit ovat tapa välittää tietoa

aliohjelman kutsujalta aliohjelman käyttöön.

▼ Aliohjelmalla voi olla muodollisia parametreja nollatai useampia, tilanteesta riippuen.

▼ Aliohjelman käskyt (runko) saadaan suoritettuakirjoittamalla haluttuun kohtaan ohjelmakoodissaaliohjelman nimi ja sen perään suluissa

– samassa järjestyksessä

– sama määrä

– saman tyyppisiä

lausekkeita, kuin mitä aliohjelman muodollisetparametrit määräävät (tyhjät sulut, jos parametrejaei ole).

▼ Tätä nimitetään usein myös aliohjelmakutsuksi.

▼ Aliohjelmaa kutsuttaessa hypätään suorittamaanaliohjelman käskyjä järjestyksessä kunnes neloppuvat, minkä jälkeen palataan alkuperäiseenkutsukohtaan ja jatketaan siitä normaalisti eteenpäin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 88: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 81

Sama esimerkki vain hiukan toisin

▼ Vertaile toisiinsa edellistä ja seuraavaa ohjemaa:

#include <iostream>

#include <iomanip>

using namespace std;

void TulostaErotinVaakarivi( ) ;void TulostaOtsikkorivi( ) ;void TulostaKertotaulurivi( int kertoja);

int main( ) {TulostaErotinVaakarivi( ) ;TulostaOtsikkorivi( ) ;TulostaErotinVaakarivi( ) ;

int luku = 1;while ( luku <= 9) {

TulostaKertotaulurivi( luku);++luku;

}

TulostaErotinVaakarivi( ) ;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 89: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 82void TulostaErotinVaakarivi( ) {

cout << "+– – – "<< "+– – – – – – – – – – – – – – – – – – – – – – – – – – – –+"<< endl;

}

void TulostaOtsikkorivi( ) {cout << " | x | 1 2 3 4 5 6 7 8 9 | "

<< endl;}

void TulostaKertotaulurivi( int kertoja) {cout << " | " << kertoja << " | ";

int kerrottava = 1;while (kerrottava <= 9) {

cout << setw(3) << kertoja * kerrottava;++kerrottava;

}

cout << " | " << endl;}

▼ Ainoat erot alkuperäiseen ohjelmaan verrattuna:– main on nyt määritelty ensimmäisenä ja muut

kolme aliohjelmaa vasta sen jälkeen ja– ennen main:ia muut kolme aliohjelmaa on

kuitenkin esitelty (laatikossa).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 90: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 83

Määrittely vs. esittely

▼ Aliohjelman määrittelyllä tarkoitetaan aliohjelmankirjoittamista ohjelmakoodiin kokonaisuudessaan.

▼ Esimerkiksi seuraava onaliohjelman TulostaKertotaulurivi määrittely:

void TulostaKertotaulurivi( int kertoja) {cout << " | " << kertoja << " | ";

int kerrottava = 1;while (kerrottava <= 9) {

cout << setw(3) << kertoja * kerrottava;++kerrottava;

}

cout << " | " << endl;}

▼ Aliohjelman esittely taas tarkoittaa sitä, kunaliohjelmasta kerrotaan vain sen nimi ja muodollistenparametrien tyypit.

▼ Seuraavassa TulostaKertotaulurivi:n esittely:

void TulostaKertotaulurivi( int kertoja);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 91: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 84

▼ Aliohjelman esittelyä kutsutaan myös prototyypiksi.

▼ Esittely kertoo aliohjelmasta kaiken sen, mitäkääntäjän tarvitsee tietää, kun se tarkistaa, onkoohjelmakoodiin kirjoitettu aliohjelmakutsu laillinen(ei sisällä semanttisia virheitä).

▼ Määrittely taas kertoo aliohjelmasta kaiken samankuin esittelykin, mutta sen lisäksi myös käskyt, jotkapitää suorittaa aliohjelmaa kutsuttaessa.

▼ Käytännössä tämä tarkoittaa seuraavaa:

1. Aliohjelma pitää aina määritellä (ja vain kerran)jossain päin ohjelmakoodia, sillä mistä muutentiedettäisiin, mitä pitää tehdä, kun aliohjelmaakutsutaan.

2. Jotta kääntäjä voisi suorittaa virhetarkistuksia,aliohjelma pitää joko esitellä tai määritellä

ohjelmakoodissa ennen kuin sitä kutsutaan

ensimmäisen kerran.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 92: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 85

Mistä aliohjelmat tulevat?

▼ Huolellisesti suunnitellusta algoritmista on suhteel-lisen helppo löytää sopivat aliohjelmaehdokkaat:

1. Jokainen algoritmin kohta (tai alakohta), jokavaatii tarkentamista, kannattaa yleensä toteuttaaaliohjelmana. Esimerkiksi kertotaulualgoritmintoiminto »tulosta luvun kertotaulurivi».

2. Jokainen algoritmissa moneen kertaan saman-laisena toistuva toiminto. Kertotaulualgoritmissaesimerkiksi »tulosta erotinvaakarivi».

▼ Jo näillä säännöillä selviää pitkälle.

▼ Mutta toki kokemus ja harjoittelu antavatlisänäkemystä.

▼ Lisäksi kannattaa pitää mielessä, mitä sovittiinaliohjelmista, joiden koko on suurempi kuin näytöllekerralla mahtuvien rivien määrä (s.79).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 93: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 86

Miksi aliohjelma on ystävä?

▼ Aliohjelmilla saavutetaan ainakin seuraavat hyödyt:

– Hyvin valitut aliohjelmien nimet selkeyttävätohjelmaa ja kertovat itsessään jotain ohjelmantoiminnasta.

– Aliohjelmat säästävät kirjoittamisen vaivaa, silläusein toistuvat toiminnot tarvitsee koodata vainkerran.

– Kun aliohjelman toiminnot toteuttava ohjelma-koodi esiintyy vain yhdessä paikassa, siinä olevatvirheet tarvitsee korjata vain kerran.

– Ohjelman toiminnan muuttaminen tarvittaessaon helpompaa, koska muutos tarvitsee tehdä vainyhteen paikkaan.

– Aliohjelmat ovat tärkeä työkalu ohjelmanjakamisessa osakokonaisuuksiin (strukturointi)eli niiden avulla ohjelmalle voi antaa hallittavanrakenteen (hajoita ja hallitse).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 94: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 87

Esimerkki

Ratkaistava ongelma

Tee ohjelma, joka ratkaisee yhtälön ax2 + bx + cnollakohdat. Kertoimet a, b ja c kysytään käyttäjältä.

Ohjelma osaa tunnistaa eri vaihtoehdot (0, 1 tai2 reaalijuurta) ja informoida käyttäjää tilanteesta.Seuraavassa esimerkkejä ohjelman suorituksesta:

proffa> ./ratkaisutsyötä kerroin a: 1syötä kerroin b: 2syötä kerroin c: 3Ei reaaliratkaisuja!proffa> ./ratkaisutsyötä kerroin a: 1syötä kerroin b: –4syötä kerroin c: 4Kaksinkertainen ratkaisu: 2proffa> ./ratkaisutsyötä kerroin a: –1syötä kerroin b: 2syötä kerroin c: 3Kaksi erillistä ratkaisua: –1 ja 3

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 95: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 88Taustatietoa

Toisen asteen yhtälöhän ratkaistaan kaavalla:

x =−b±

√b2 − 4 · a · c2 · a

jossa neliöjuuren sisällä olevaa lauseketta b2−4 · a · ckutsutaan diskriminantiksi ja sen arvo määrääreaalisten ratkaisujen lukumäärän:

b2 − 4 · a · c ratkaisujen lkm.

< 0 0

== 0 1

> 0 2

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 96: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 89Ratkaisualgoritmi

Algoritmi: Toisen asteen yhtälön juuret

kysy käyttäjältä kerroin a

a← käyttäjän syöte

kysy käyttäjältä kerroin b

b← käyttäjän syöte

kysy käyttäjältä kerroin c

c← käyttäjän syöte

IF diskriminantti == 0 THEN

tulosta "Kaksinkertainen ratkaisu"

tulosta –b/ (2a)

ELSE IF diskriminantti > 0 THEN

tulosta "Kaksi erillistä ratkaisua"

tulosta

–b +

diskriminantti

2a

tulosta

–b –

diskriminantti

2a

ELSE

tulosta "Ei reaaliratkaisuja!"

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 97: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 90Algoritmin toteutus C++:lla

#include <iostream>

#include <cmath>

using namespace std;

const double EPSILON = 1E–8;

double KysyKerroin(char mika_kerroin);double Diskriminantti(double a, double b, double c);

int main( ) {double a, b, c; // määritelty monta muuttujaa kerralla

a = KysyKerroin(’a’) ;b = KysyKerroin(’b’) ;c = KysyKerroin(’c’ ) ;

if ( abs(Diskriminantti(a, b, c) ) < EPSILON ) { // miksi?cout << "Kaksinkertainen ratkaisu: "

<< –b / (2 * a) << endl;} else if ( Diskriminantti(a, b, c) > 0 ) {

cout << "Kaksi erillistä ratkaisua: "<< ( –b + sqrt(Diskriminantti(a, b, c) ) ) / (2 * a)<< " ja "<< ( –b – sqrt(Diskriminantti(a, b, c) ) ) / (2 * a)<< endl;

} else {cout << "Ei reaaliratkaisuja!" << endl;

}

}▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 98: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 91double KysyKerroin(char mika_kerroin) {

cout << "Anna kerroin " << mika_kerroin << ": " ;double syote;cin >> syote;

return syote;}

double Diskriminantti(double a, double b, double c) {return b * b – 4 * a * c;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 99: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 92Mitä siitä opittiin

▼ C++ tarjoaa mahdollisuuden määritellä ja käyttääfunktioaliohjelmia eli funktioita.

▼ Funktioiden esittelyt ja määrittelyt ovat kutenaliohjelmien määrittelyt, paitsi että funktiolla onaina joku tyyppi (aliohjelman edessähän käytettiinaina varattua sanaa void, kun taas funktion nimenedessä on joku tietotyypin nimi).

▼ Funktiokutsua voi käyttää lausekkeessa sellaisessakohdassa, jossa voisi käyttää jotain muuta samantyyppistä tietoalkiota kuin funktion tyyppi.

▼ Funktioiden rungossa näyttää aina olevankäsky return.

▼ Matematiikkakirjastosta (#include <cmath>)saadaan käyttöön yleishyödyllisiä matemaattisiafunktioita. Esimerkiksi abs ja sqrt.

▼ Reaalilukujen yhtäsuuruutta ei pidä mennävertailemaan ==-operaattorilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 100: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 93

Funktiot

▼ Funktiot ovat lähes joka suhteessa samanlaisia kuinaliohjelmat.

▼ Ainoa ero on, että funktiolla on paluuarvo eli sepalauttaa tietoa siihen kohtaan lauseketta, jossa sitäkutsutaan.

▼ Tai toisin sanoen: funktiokutsulle evaluoituu arvo,jota voidaan käyttää parametrina muille funktioilletai aliohjelmille, operaattoreiden operandina jne.

▼ Funktiot ovat siis jotakuinkin samanlaisia olioita, joitamatematiikassakin kutsutaan funktioiksi.

▼ Funktiot määritellään seuraavasti:funktion_tyyppi FunktionNimi( ) {

funktion_runko

}

tai mikäli funktiolla on parametreja:funktion_tyyppi FunktionNimi(muodolliset_parametrit ) {

funktion_runko

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 101: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 94▼ FunktionNimelle ja muodollisille_parametreille

pätevät kaikki samat säännöt ja ominaisuudet kuinaliohjelmien tapauksessakin (ks. ss. 78–80).

▼ Jokaisen funktion määrittelyyn (ja esittelyyn) kuuluufunktion_tyyppi, joka määrää, minkä tyyppistä tietoafunktio palauttaa kutsujalleen (käytännössä siis sen,minkälaisessa lausekkeessa funktiota saa kutsua).

▼ Funktion_tyyppi saa olla mikä tahansa tietotyyppi.

▼ Funktion_runko saa olla mitä tahansa suoritettavialauseita, kuitenkin niin että yksi return-käsky tulee

aina suoritetuksi (funktion on palautettava arvo).

▼ Yleisesti ottaen return-käsky näyttää seuraavalta:

return paluuarvo;

jossa paluuarvo on mikä vain lauseke, jolle evaluoituvaarvo on tyypiltään sama kuin funktion_tyyppi.

▼ return-käsky lopettaa funktion suorituksen välittö-mästi ➠ jatketaan kutsukohdasta eteenpäin.

▼ Paluuarvo-lausekkeen arvo määrää, mikä arvofunktiolle evaluoituu sitä kutsuvassa lausekkeessa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 102: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 95▼ Funktion rungossa voi siis olla useampiakin return-

käskyjä, mutta funktiosta paluu tapahtuu heti, kunyksikin niistä suoritetaan, esimerkiksi:

double Itseisarvo(double x) {if ( x > 0 ) {

return x;} else {

return –x;}

}

▼ Myös aliohjelman suoritus saadaan return-käskylläkeskeytettyä, mutta tällöin return:ia käytetäänyksinään ilman paluuarvo-lauseketta:

return;

▼ Ainoa todellinen ero aliohjelmien ja funktioidenvälillä on:

– kutsujan ja aliohjelman välillä tietoa siirtyy vainyhteen suuntaan (kutsuja −→ aliohjelma).

– kutsujan ja funktion välillä tietoa siirtyy kahteensuuntaan (kutsuja −→←− funktio).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 103: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 96▼ Funktioidenkin tapauksessa rajoittava tekijä on se,

että funktio voi sanan varsinaisessa merkityksessäpalauttaa vain yhden arvon.

▼ Syvin totuus aliojelmista ja funktioista on se, ettävoid on tosiasiassa tietotyyppi, johon ei kuulumitään arvoja: siis eräänlainen tyhjä tietotyyppi ➠aliohjelman »tyyppi» on void ➠ aliohjelma on siisfunktio, joka ei palauta mitään.

▼ Funktion esittelylle ja määrittelylle pätevät samatsäännöt kuin aliohjelmallekin (ks. s. 84).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 104: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 97

Mistä funktiot tulevat?

▼ Ohjelmaan tarvittavat funktiot löydetään samoinperustein algoritmia tutkiskelemalla kuin aliohjel-matkin löydettiin (ks. s. 85).

▼ Lisäksi pitää miettiä, mitä on se tieto, jota funktiontarvitsee lähettää takaisin kutsujalleen.

▼ Hyvin usein funktio on tunnistettavissa siitä, ettäalgoritmissa toiminto esiintyy osana jotain lauseketta,esimerkiksi:

IF Diskriminantti < 0 THEN· · ·

taiviikonpäivä← päivämäärän pp.kk.vvvv viikonpäivä

taitulosta astelukua vastaava fahrenheit-lämpötila

taisosiaaliturvatunnus← kysy käyttäjän sosiaaliturvatunnus

joissa potentiaaliset funktiot kursiivilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 105: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 98▼ Usein funktio saattaa algoritmissa olla jaettuna

kahdelle tai useammalle riville, kannattaa siis ollatarkkana:

tulosta kehote, joka tiedustelee sosiaaliturvatunnusta

lue käyttäjän näppäilemä syöte

WHILE syöte ei ole laillinen sosiaaliturvatunnus

tulosta ilmoitus virheellisestä syötteestä

tulosta kehote, joka tiedustelee sosiaaliturvatunnusta

lue käyttäjän näppäilemä syöte

sosiaaliturvatunnus← käyttäjän syöttämä tunnus

jossa kursiivit toiminnot yhdessä muodostaisivatfunktion KysySosiaaliturvatunnus( ) .

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 106: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 99

Matematiikkakirjasto

▼ Tarjoaa valmiina tärkeimmät matemaattiset funktiot.

▼ Funktioita voi ohjelmassaan käyttää, kun vain muis-taa lisätä lähdekoodin alkuun rivin #include <cmath>

▼ Seuraavassa funktioista hyödyllisimmät:

funktio kutsulle evaluoituva arvo

double abs(double x) |x |double sqrt(double x)

√x

double pow(double x, double y) xy

double exp(double x) ex

double log(double x) logex

double log10(double x) log10 x

double sin(double x) sin x

double cos(double x) cos x

double tan(double x) tan x

double asin(double x) arcsin x eli sin−1 x

double acos(double x) arccos x eli cos−1 x

double atan(double x) arctan x eli tan−1 x

Trigonometrisissa funktioissa kulmat ovat radiaaneina.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 107: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 100

Miksi reaalilukuja ei saa vertailla

==- ja !=-operaattoreilla?

▼ Tietokone esittää reaaliluvut (kuten kokonaisluvutkin)jollain rajallisella määrällä bittejä (0 ja 1).

▼ Tuosta seuraa luonnollisesti, että laskutoimitustentulokset ovat monissa tapauksissa likiarvoja todellisillevastauksille: oikeassa tuloksessa voi olla enemmänmerkitseviä lukuja kuin mihin esitystarkkuus pystyy.

▼ Toisaalta johtuen tavasta, jolla kymmenjärjestelmänreaaliluvut koodataan vastaaviksi 2-järjestelmänreaaliluvuiksi, se ei ole kaikissa tilanteissa edesmahdollista tarkasti.

▼ Asian syvin olemus on se, että reaaliluvuilla lasket-taessa syntyy aina pyöristysvirheitä ja lopputulos onsiten likiarvo.

▼ Esimerkiksi lausekkeen 20.1 – 20.0 – 0.1 tulos ei vält-tämättä olekaan tasan 0.0, vaan pyöristysvirheidentuloksena 0.0 · · ·

︸︷︷︸paljon nollia

00141553

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 108: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 101▼ Tämän seurauksena vertailuoperaattorit == ja !=

saattavat toimia järjenvastaisesti, esimerkiksi ohjelma

#include <iostream>

using namespace std;

int main( ) {double luku1 = 20.1;double luku2 = 20.0;double luku3 = 0.1;

if ( (luku1 – luku2 – luku3) == 0 ) {cout << "Oikein meni!" << endl;

} else {cout << "Väärin meni!" << endl;

}}

tulostaa suoritettaessa näytölle tekstin »Väärin meni!»

▼ Tästä ikävästä ominaisuudesta selvitään sillä, ettähyväksytään pyöristysvirheiden olemassaolo jatulkitaan kaksi reaalilukua samoiksi, jos ne ovat»riittävän» lähellä toisiaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 109: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 102▼ Tämän seurauksena reaalilukuvertailu a == b pitäisi

siis kirjoittaa |a − b| < ε, jossa ε on jokin riittävänpieni virhetoleranssi, esimerkiksi 1E–8.

▼ C++:lla reaalilukujen a == b siis kirjoitettaisiin// Määritellään jossain ohjelman alussa// virhetoleranssille ε jokin sopiva arvo:const double EPSILON = 1E–8;· · ·

// Myöhemmin ohjelmassa kun halutaan vertailla// kahden reaaliluvun a ja b yhtäsuurutta:abs(a – b) < EPSILON

▼ Erisuuruutta vertailtaisiin vastaavasti:abs(a – b) >= EPSILON

tai! ( abs(a – b) < EPSILON )

▼ Todellisuudessa edellinen ideakin on puutteellinen,koska se tutkii lukujen absoluuttista eroa.

▼ Parempi olisi yhtäsuuruutta tutkittaessa katsoa,kuinka lähellä toisiaan luvut ovat suhteessa niidensuuruusluokkaan:

|a – b|max(|a| , |b|)

< ε

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 110: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 103

Funktion parametrit:

arvo- ja viiteparametrit

▼ Funktioiden ja aliohjelmien parametrit ovat C++-kielessä normaalisti arvoparametreja, millä tarkoi-tetaan sitä, että funktion muuttaessa muodollisenparametrinsa arvoa, todellisen parametrin arvo säilyykuitenkin ennallaan:

void JaaKahdella( int parametri) {parametri = parametri / 2;

}

int main( ) {int luku = 42;

JaaKahdella(luku);cout << luku << endl;

}

▼ Edellisen ohjelman tulostus on siis 42 eli todellinenparametri ei muuttunut.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 111: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 104▼ Usein tulee vastaan tilanne, jossa olisi hyödyllistä, jos

funktio pystyisi muuttamaan todellisen parametrinarvoa.

▼ Esimerkiksi jos funktion tarvitsee palauttaa useampikuin yksi arvo, voitaisiin tietoa »palauttaa» todellistenparametrien arvoja muuttamalla.

▼ C++-kielen normaalin parametrinvälitysmekanismin(arvonvälitys, arvoparametrit) lisäksi kieli tarjoaamyös viitteenvälityksen (viiteparametrit, muuttu-

japarametrit).

▼ Viiteparametrit toimivat juuri siten, että funktionmuuttaessa muodollisen parametrinsa arvoa myöstodellisen parametrin arvo muuttuu.

▼ Parametri voidaan määritellä viiteparametriksilisäämällä sen tyypin ja nimen väliin merkki &.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 112: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 105▼ Edellinen esimerkki voitaisiin siis toteuttaa viitepara-

metreilla seuraavaan tapaan:

// Ainoa muutos alkuperäiseen verrattuna on// seuraavalle riville lisätty &-merkki.void JaaKahdella( int& parametri) {

parametri = parametri / 2;}

int main( ) {int luku = 42;

JaaKahdella(luku);cout << luku << endl;

}

▼ Nyt ohjelma tulostaakin 21 eli funktio JaaKahdella

pystyi muuttamaan todellisen parametrin arvon.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 113: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 106

Laajempi esimerkki

Halutun ohjelman kuvaus

▼ Suunnitellaan ja toteutetaan hiukan totuttuaisokokoisempi esimerkkiohjelma, jossa voidaankäyttää hyväksi kaikkea tähän mennessä opittua.

▼ Periaatteessa olisi tarkoitus saada aikaan seuraavankaltaisesti toimiva ohjelma:

proffa> ./viikonpaivaAnna päivä: 24Anna kuukausi: 2Anna vuosi: 199924.2.1999 on keskiviikkoproffa> ./viikonpaivaAnna päivä: 31Anna kuukausi: 6Anna vuosi: 191231.6.1912 ei ole laillinen päivämäärä!

▼ Ohjelma osaa siis päätellä päivämäärästä, mikäviikonpäivä se on tai että se on laiton.

▼ Sovitaan lisäksi, että ohjelman ei tarvitse toimiakuin päivämäärillä, jotka ovat 1.1.1800 jälkeen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 114: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 107Ratkaisun idea

▼ Ennen kuin ongelmaa voidaan ratkaista edes sillätasolla, että pystytään kirjoittamaan siitä algoritmi,täytyy keksiä idea, jolla ohjelmaa yleensäkäänottaen voisi lähestyä.

▼ Muutenhan seuraavan algoritmin tarvittavienvaiheiden yksityiskohtaistaminen ei onnistu:

Algoritmi: Viikonpäivä

päivä← kysy käyttäjältä päivä

kuukausi← kysy käyttäjältä kuukausi

vuosi← kysy käyttäjältä vuosi

IF annettu päivämäärä on laillinen THEN

tulosta päivämäärän viikonpäivä

ELSE

tulosta virheilmoitus

▼ Mitä ilmeisemmin ennen yhtään pidemmälleetenemistä on syytä tutustua ongelman aihepiiriinja ideoida mahdollisia ratkaisutapoja.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 115: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 108▼ Syntynyt idea esimerkin avulla:

– Oletetaan että käyttäjä haluaa tietää, mikäviikonpäivä oli 8.7.1947.

– Valitaan vertailupäivämääräksi 31.12.1799 jakatsotaan jonkun muun tekemästä kalenterista,että se oli tiistai.

– Lasketaan sen jälkeen montako päivää onkulunut välillä 31.12.1799–8.7.1947:

kuluneet päivätvuosina kuukausina päivinä

1800–1946 01–06/1947 1.8.–8.8.1947

1800 365 01/1947 31 1.7.1947 11801 365 02/1947 28 2.7.1947 11802 365 ... ... 3.7.1947 11803 365 05/1947 31 4.7.1947 11804 366 06/1947 + 30 ... ...

... ... 181 7.7.1947 11944 366 8.7.1947 + 11945 365 81946 + 365

53690

yhteensä: 53879 päivää

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 116: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 109– Nyt tutkitaan mikä on kuluneiden päivien

jakojäännös 7:n (viikonpäivien määrä) kanssa:53879 % 7→ 0.

– Josta päätellään että on kulunut 7:n monikertapäiviä ➠ on kulunut tasamäärä viikkoja ➠ täytyyolla sama viikonpäivä kuin vertailupäivämääränä

➠ 8.7.1947 oli tiistai.

– Jos jakojäännöksen tuloksena olisi syntynytmuita lukuja (1–6), niin niitä olisi tulkittuseuraavasti:

päiviä kulunut % 7 viikonpäivä on

0 tiistai1 keskiviikko2 torstai3 perjantai4 lauantai5 sunnuntai6 maanantai

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 117: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 110Taustatietoa kalenterilaskuista

▼ Kalenteria, jonka mukaan Suomessa nykyääneletään, kutsutaan gregoriaaniseksi kalenteriksi.

▼ Gregoriaanisessa kalenterissa karkausvuosi onsellainen vuosi, joka

– on tasan jaollinen neljällä, mutta ei sadalla tai

– on tasan jaollinen neljällä sadalla.

▼ C++:ssa karkausvuosi tunnistetaan siis loogisellalausekkeella:

vuosi % 4 == 0 && vuosi % 100 != 0| | vuosi % 400 == 0

▼ Karkausvuoden helmikuussa on 29 päivää, kunnormaalissa helmikuussa on 28 päivää.

▼ Karkausvuodessa on 366 päivää, kun normaalissavuodessa on 365 päivää.

▼ Noitahan tarvitaan, kun lasketaan vuosista jakuukausista kertyneitä päiviä ja kun tarkistetaanpäivämäärän laillisuutta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 118: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 111Algoritmi (jatkoa kalvolta 107)

Algoritmi: Onko annettu päivämäärä laillinen

IF päivä < 1 THEN

päivämäärä on laiton

ELSE IF kuukausi < 1 tai kuukausi > 12 THEN

päivämäärä on laiton

ELSE IF vuosi < 1800 THEN

päivämäärä on laiton

ELSE IF (kuukausi on 1, 3, 5, 7, 8, 10 tai 12)

ja päivä > 31 THEN

päivämäärä on laiton

ELSE IF (kuukausi on 4, 6, 9 tai 11) ja päivä > 30 THEN

päivämäärä on laiton

ELSE IF kuukausi on 2 ja vuosi on karkausvuosi

ja päivä > 29 THEN

päivämäärä on laiton

ELSE IF kuukausi on 2 ja vuosi ei ole karkausvuosi

ja päivä > 28 THEN

päivämäärä on laiton

ELSE

päivämäärä on laillinen

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 119: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 112Algoritmi: Onko vuosi karkausvuosi

IF (vuosi jaollinen 4:llä muttei 100:lla)

tai vuosi jaollinen 400:lla THEN

vuosi on karkausvuosiELSE

vuosi on normaalivuosi

Algoritmi: Tulosta päivämäärän viikonpäivä

tulosta päivämäärä

viikonpäivänumero← laske viikonpäivänumero

IF viikonpäivänumero == 0 THEN

tulosta tiistai

ELSE IF viikonpäivänumero == 1 THEN

tulosta keskiviikko

ELSE IF viikonpäivänumero == 2 THEN

tulosta torstai

ELSE IF viikonpäivänumero == 3 THEN

tulosta perjantai

ELSE IF viikonpäivänumero == 4 THEN

tulosta lauantai

ELSE IF viikonpäivänumero == 5 THEN

tulosta sunnuntaiELSE

tulosta maanantai

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 120: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 113Algoritmi: Laske viikonpäivänumero

päiviä kulunut← aikavälin vuosista kertyneet päivät

+ kuukausista kertyneet päivät

+ kuukauden päivä

viikonpäivänumero on: päiviä kulunut % 7

Algoritmi: Aikavälin vuosista kertyneet päivät

päiviä kertynyt← 0

tutkittava vuosi← 1800

WHILE tutkittava vuosi < päivämäärän vuosi

IF tutkittava vuosi on karkausvuosi THEN

päiviä kertynyt← päiviä kertynyt + 366

ELSE

päiviä kertynyt← päiviä kertynyt + 365

tutkittava vuosi← tutkittava vuosi + 1

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 121: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 114Algoritmi: Kuukausista kertynyt päivät

päiviä kertynyt← 0

tutkittava kuukausi← 1

WHILE tutkittava kuukausi < päivämäärän kuukausi

IF tutkittava kuukausi on

1, 3, 5, 7, 8, 10 tai 12 THEN

päiviä kertynyt← päiviä kertynyt + 31

ELSE IF tutkittava kuukausi on 4, 6, 9 tai 11 THEN

päiviä kertynyt← päiviä kertynyt + 30

ELSE IF tutkittava kuukausi on 2

ja vuosi on karkausvuosi THEN

päiviä kertynyt← päiviä kertynyt + 29

ELSE

päiviä kertynyt← päiviä kertynyt + 28

tutkittava kuukausi← tutkittava kuukausi + 1

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 122: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 115Ohjelmakoodi

#include <iostream>

using namespace std;

// Funktioiden ja aliohjelmien esittelytbool OnkoPaivamaaraLaillinen( int pp, int kk, int vvvv);bool OnkoKarkausvuosi(int vuosi) ;void TulostaViikonpaiva( int pp, int kk, int vvvv);int LaskeViikonpaivaNumero( int pp, int kk, int vvvv);int VuosistaKertyneetPaivat( int vvvv);int KuukausistaKertyneetPaivat( int kk, int vvvv);bool OnkoHelmikuu(int kuu);bool OnkoLyhytKuukausi(int kuu); // Onko 30–päiväinen?bool OnkoPitkaKuukausi( int kuu); // Onko 31–päiväinen?

// Vakioiden määrittelytconst int ALOITUSVUOSI = 1800;

const int NORMAALIVUODEN_PITUUS = 365;const int KARKAUSVUODEN_PITUUS = 366;

const int PITKAN_KUUN_PITUUS = 31;const int LYHYEN_KUUN_PITUUS = 30;const int HELMIKUUSSA = 28;const int KARKAUSHELMIKUUSSA = 29;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 123: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 116const int TAMMI = 1;const int HELMI = 2;const int MAALIS = 3;const int HUHTI = 4;const int TOUKO = 5;const int KESA = 6;const int HEINA = 7;const int ELO = 8;const int SYYS = 9;const int LOKA = 10;const int MARRAS = 11;const int JOULU = 12;

const int PAIVIA_VIIKOSSA = 7;

const int MAANANTAI = 6;const int TIISTAI = 0;const int KESKIVIIKKO = 1;const int TORSTAI = 2;const int PERJANTAI = 3;const int LAUANTAI = 4;const int SUNNUNTAI = 5;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 124: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 117int main( ) {

int paiva;cout << "Anna päivä: ";cin >> paiva;

int kuu;cout << "Anna kuukausi: " ;cin >> kuu;

int vuosi;cout << "Anna vuosi: " ;cin >> vuosi;

if (OnkoPaivamaaraLaillinen(paiva, kuu, vuosi) ) {TulostaViikonpaiva(paiva, kuu, vuosi) ;

} else {cout << paiva << "." << kuu << "." << vuosi

<< " ei ole laillinen päivämäärä!" << endl;}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 125: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 118bool OnkoPaivamaaraLaillinen( int pp, int kk, int vvvv) {

if (pp < 1) {return false;

} else if (kk < TAMMI | | kk > JOULU) {return false;

} else if (vvvv < ALOITUSVUOSI) {return false;

} else if (OnkoPitkaKuukausi(kk)&& pp > PITKAN_KUUN_PITUUS) {

return false;} else if (OnkoLyhytKuukausi(kk)

&& pp > LYHYEN_KUUN_PITUUS) {return false;

} else if (OnkoHelmikuu(kk)&& OnkoKarkausvuosi(vvvv)&& pp > KARKAUSHELMIKUUSSA) {

return false;} else if (OnkoHelmikuu(kk)

&& !OnkoKarkausvuosi(vvvv)&& pp > HELMIKUUSSA) {

return false;} else {

return true;}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 126: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 119bool OnkoKarkausvuosi(int vuosi) {

if ( (vuosi % 4 == 0 && vuosi % 100 != 0)

| | vuosi % 400 == 0) {return true;

} else {return false;

}}

int LaskeViikonpaivaNumero( int pp, int kk, int vvvv) {int paivia_kulunut

= VuosistaKertyneetPaivat(vvvv)+ KuukausistaKertyneetPaivat(kk, vvvv)+ pp;

return paivia_kulunut % PAIVIA_VIIKOSSA;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 127: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 120void TulostaViikonpaiva( int pp, int kk, int vvvv) {

cout << pp << "." << kk << "." << vvvv << " on ";

int viikonpaivanumero= LaskeViikonpaivaNumero(pp, kk, vvvv);

if (viikonpaivanumero == MAANANTAI) {cout << "maanantai" ;

} else if (viikonpaivanumero == TIISTAI) {cout << "tiistai" ;

} else if (viikonpaivanumero == KESKIVIIKKO) {cout << "keskiviikko";

} else if (viikonpaivanumero == TORSTAI) {cout << "torstai" ;

} else if (viikonpaivanumero == PERJANTAI) {cout << "perjantai" ;

} else if (viikonpaivanumero == LAUANTAI) {cout << "lauantai" ;

} else {cout << "sunnuntai" ;

}

cout << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 128: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 121int VuosistaKertyneetPaivat( int vvvv) {

int paivia_kertynyt = 0;int tutkittava_vuosi = ALOITUSVUOSI;

while (tutkittava_vuosi < vvvv) {

if (OnkoKarkausvuosi( tutkittava_vuosi) ) {paivia_kertynyt= paivia_kertynyt + KARKAUSVUODEN_PITUUS;

} else {paivia_kertynyt= paivia_kertynyt + NORMAALIVUODEN_PITUUS;

}

++tutkittava_vuosi;}

return paivia_kertynyt;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 129: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 122int KuukausistaKertyneetPaivat( int kk, int vvvv) {

int paivia_kertynyt = 0;int tutkittava_kuu = TAMMI;

while (tutkittava_kuu < kk) {if (OnkoPitkaKuukausi( tutkittava_kuu) ) {

paivia_kertynyt = paivia_kertynyt+ PITKAN_KUUN_PITUUS;

} else if (OnkoLyhytKuukausi(tutkittava_kuu) ) {paivia_kertynyt = paivia_kertynyt

+ LYHYEN_KUUN_PITUUS;} else if (OnkoHelmikuu(tutkittava_kuu)

&& OnkoKarkausvuosi(vvvv) ) {paivia_kertynyt = paivia_kertynyt

+ KARKAUSHELMIKUUSSA;} else {

paivia_kertynyt = paivia_kertynyt+ HELMIKUUSSA;

}

++tutkittava_kuu;}

return paivia_kertynyt;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 130: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 123bool OnkoHelmikuu(int kuu) {

if (kuu == HELMI) {return true;

} else {return false;

}}

bool OnkoLyhytKuukausi(int kuu) {if (kuu == HUHTI | | kuu == KESA

| | kuu == SYYS | | kuu == MARRAS) {return true;

} else {return false;

}}

bool OnkoPitkaKuukausi( int kuu) {return !OnkoHelmikuu(kuu)

&& !OnkoLyhytKuukausi(kuu);}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 131: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 124

Merkkijonotietotyyppi string

▼ C++:ssa on kaksi eri merkkijonotietotyyppiä: tälläkurssilla tutustutaan niistä helppokäyttöisempään elistring-tyyppiin.

▼ string-tietotyyppi on osa C++:n standardikirjastoa: jossitä haluaa käyttää, on muistettava liittää ohjelmanalkuun rivi #include <string>.

▼ Tämän jälkeen tyyppi string käyttäytyy ohjelmassaperusoperaatioiden suhteen ikäänkuin se olisiperustietotyyppi:

– muuttujien määrittely,

– funktion parametrit (myös viiteparametrit) japaluuarvo,

– sijoitus ja alustus toisesta merkkijonomuuttujastatai -literaalista =-operaattorilla,

– tulostus cout:iin,

– voidaan lukea cin:stä >>-operaattorilla, mutta onolemassa varmatoimisempi tapa (getline-funktio).

– vertailu == , != , < , <= , > ja >=-operaattoreilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 132: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 125▼ Perustietotyypeistä tuttujen operaatioiden lisäksi

string-tyypillä on muitakin hyödyllisiä ominaisuuksia.

▼ Lisäominaisuudet on toteutettu siten, että string-kirjasto tarjoaa ison joukon valmiita funktioita, joidenavulla merkkijonoja voidaan käsitellä.

▼ Erikoista on se, että lähes kaikkia string-kirjastonfunktioita kutsutaan eri tavoin kuin tähän saakkakäytettyjä »normaaleja» funktioita.

▼ Kirjastossa on esimerkiksi funktio length(), jonkapaluuarvoksi evaluoituu, kuinka monta merkkiämerkkijono sisältää.

▼ Sitä kutsutaan seuraavasti:string mjono = "a bcdefgh";cout << mjono.length( ) << endl;

▼ Tämän seurauksena näytölle tulostuisi 9, koskamuuttujassa mjono on yhdeksän merkin verrantekstiä (välilyönnitkin lasketaan).

▼ Merkkijonokirjaston funktioiden kutsusyntaksi on

merkkijonomuuttuja . funktion_nimi(mahdolliset_parametrit )

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 133: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 126▼ Jotkut string-funktiot tarvitsevat lisäparametreja ➠

ne kirjoitetaan normaalisti sulkeiden sisään:mjono.replace(4, 3, "xy");

▼ Edellinen replace-funktiokutsu korvaisi merkki-jonossa mjono viidennestä merkistä "d" alkaenkolme seuraavaa merkkiä "def" tekstillä "xy".

▼ Kaikissa niissä funktioissa, joiden parametrit taipaluuarvo viittaavat merkkijonon merkkien sijaintiin(esim. edellä »viidennestä merkistä alkaen»), pitäämuistaa, että numerointi aloitetaan nollasta!

"a b c d e f gh"0 1 2 3 4 5 6 7 8

▼ Viimeisen merkin järjestysnumero (indeksi) onyhtä pienempi kuin merkkijonon pituus eli siis yhtäpienempi kuin length()-funktion paluuarvo.

▼ Merkkijono voi olla myös tyhjä, jolloin se ei sisällämitään tekstiä, eli sen pituus on nolla:

mjono = ""; // Kaksi lainausmerkkiä yhteen kirjoitettuna.cout << mjono.length( ) << endl; // Tulostaa nollan.

▼ Tyhjä merkkijono ei ole sama asia kuin merkkijono,joka sisältää pelkän välilyöntimerkin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 134: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 127▼ Seuraavassa on esitelty lyhyesti olennaisimmat

merkkijonokirjaston funktiot.

▼ Esitys on tarkoituksella listamainen, jottamyöhemmin omia ohjelmia toteutettaessa tieto olisihelposti löydettävissä.

▼ Funktiot on kuvattu funktioiden esittelyn syntaksilla

➠ parametrien ja paluuarvon tyypit näkyvissä.

▼ Usein mukana on tietotyyppi string::size_type.

▼ Kyseessä on string-kirjaston määrittelemä tyyppi,jota on tarkoitus käyttää aina, kun käsitelläänarvoja, jotka kuvaavat merkkijonon indeksejä, eli siismerkkien järjestysnumeroita merkkijonon sisällä.

▼ Tyypin nimi saattaa vaikuttaa oudolta, koska sesisältää kaksoispisteitä, mutta kyseessä on silti vaintietotyypin nimi ➠ sitä voidaan tarvittaessa käyttäämuuttujien, parametrien ja paluuarvojen tyyppinä.

▼ Toteutusteknisesti kyseessä on jokin kokonaisluku-tyyppi ➠ sen avulla voidaan suorittaa laskutoimi-tuksia jne. kuten kokonaisluvuilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 135: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 128

Merkkijonokirjaston funktioita

string::size_type length( );

Paluuarvoksi evaluoituu merkkijonon merkkienlukumäärä (kaikki merkit lasketaan, myös välilyönnitja muut näkymättömät merkit).

string::size_type pituus = mjono.length( );cout << "pituus on " << pituus << " merkkiä" << endl;

bool empty( );

Arvoksi evaluoituu true vain, jos merkkijono onnollan mittainen (tyhjä).

if ( mjono.empty( ) ) {// tähän päästään, jos mjono on tyhjä.

}

string + string

Kahden merkkijonon yhteenlaskun arvoksievaluoituu merkkijonot peräkkäin liimattuina.

mjono = "abc";cout << mjono + "def" << endl; // tulostuu: abcdef

+ on operaattori, ei funktio, mutta se on silti hyvämainita tässä yhteydessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 136: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 129void push_back(char lisays) ;string append(string lisays);

Nämä funktiot lisäävät merkkijonon loppuun yhdenmerkin (push_back) tai merkkijonon (append) ➠kumpikin muuttaa alkuperäistä merkkijonoa. Lisäksiappend-kutsun arvoksi evaluoituu merkkijonon uusimuuttunut sisältö.

mjono = "abc";mjono.push_back(’d’) ;mjono.append("ef") ;cout << mjono << endl; // tulostuu: abcdef

char at(string::size_type indeksi) ;

Paluuarvona on merkkijonon kohdassa indeksi

sijaitseva merkki. Kutsu voi olla myös sijoitusope-raattorin (=) vasempana operandina ➠ voidaanmuuttaa merkkijonon yksittäisiä merkkejä.

cout << "viides merkki on " << mjono.at(4) << endl;mjono.at(1) = ’x’; // toinen merkki muuttuu x:ksi.

Jos parametrina annetaan indeksi, joka on suurempikuin merkkijonon viimeisen merkin indeksi,ohjelman suoritus keskeytyy.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 137: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 130getline(cin, string& rivi) ;

Funktio getline on erikoinen tapaus, sillä sitäkutsutaan normaalifunktioiden tapaan. Se lukeesyötteestä yhden rivin tekstiä ja tallentaa sen(viite)parametriin rivi.

cout << "kuka olet? ";string nimi;getline(cin, nimi);cout << "Hei " << nimi << "!" << endl;

Tässä vaiheessa ensimmäinen parametri on ainacin, mutta myöhemmin aiheesta opitaan lisää.

string substr(string::size_type alkuindeksi) ;string substr(string::size_type alkuindeksi,

string::size_type pituus);

Palauttaa merkkijonon, joka saadaan kun alkuperäi-sestä merkkijonosta otetaan kohdasta alkuindeksi

eteenpäin pituus kappaletta merkkejä. Jos pituus-parametri puuttuu, palautuu koko loppumerkkijono.

mjono = "abcdefgh";cout << mjono.substr(3) << endl; // tulostuu: defghcout << mjono.substr(1, 4) << endl; // tulostuu: bcde

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 138: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 131string replace(string::size_type alkuindeksi,

string::size_type maara,string korvaava);

Korvaa alkuindeksistä alkaen maara merkkiämerkkijonolla korvaava. Paluuarvoksi evaluoituumuuttunut merkkijono.

mjono = "abcdefgh";mjono.replace(2, 4, "xy");cout << mjono << endl; // tulostuu: abxygh

string erase(string::size_type alkuindeksi) ;string erase(string::size_type alkuindeksi,

string::size_type maara);

Poistaa merkkijonosta merkkejä. Ensimmäinenversio poistaa kaikki merkit alkuindeksistämerkkijonon loppuun saakka. Jälkimmäinen poistaaalkuindeksistä alkaen maara seuraavaa merkkiä.Paluuarvoksi evaluoituu muuttunut merkkijono.

mjono = "abcdefgh";mjono.erase(6);cout << mjono << endl; // tulostaa: abcdefmjono.erase(2, 3);cout << mjono << endl; // tulostaa: abf

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 139: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 132void clear( );

Tyhjentää merkkijonon, eli toisin sanoen asettaa senpituuden nollaksi. Aivan sama tulos saataisiin aikaansijoittamalla muuttujan arvoksi tyhjä merkkijono(mjono = "";).

void swap(string& mjono1, string& mjono2);

Vaihtaa kahden merkkijonomuuttujan (viitepara-metreja) sisällöt keskenään. Tämäkin on normaali-funktio siinä mielessä, että molemmat merkkijonotannetaan sille parametreina sulkeiden sisällä.

str_a = "abcd";str_b = "defg";swap(str_a, str_b);cout << str_a << str_b << endl; // tulostaa: defgabcd

string insert(string::size_type indeksi, string lisays);

Lisää kohdassa indeksi olevan merkin eteenparametrissa lisays olevan tekstin. Paluuarvoksievaluoituu muuttunut merkkijono.

mjono = "abef";mjono.insert(2, "cd") ;cout << mjono << endl; // tulostaa: abcdef

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 140: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 133string::size_type find(char etsittava);string::size_type find(string etsittava);string::size_type find(char etsittava,

string::size_type alkuindeksi) ;string::size_type find(string etsittava,

string::size_type alkuindeksi) ;

find-funktiosta on useita eri versioita, mutta kaikilleniille on yhteistä, että ne etsivät merkkijonostahaluttua merkkiä tai alimerkkijonoa ja palauttavattiedon, mistä kohdasta (indeksi) etsitty osa löytyi.

Jos parametreja on kaksi, jälkimmäinen kertoo, senmerkin indeksin, josta eteenpäin etsintä suoritetaan.

Mikäli etsittyä merkkiä tai alimerkkijonoa eilöydy, find palauttaa arvon string::npos, joka onstring-kirjastossa määritelty const-vakio.

getline(cin, mjono);string::size_type paikka = mjono.find("def") ;if ( paikka == string::npos ) {

cout << "merkkijono ei sisältänyt def:ää" << endl;} else {

cout << "def löytyi indeksistä " << paikka << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 141: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 134

Osoitelappuohjelma

Toteutettava ohjelma

Toteutetaan edellisten string-kirjastofunktioidenavulla käyttäjän tekstisyötteitä käsittelevä ohjelma.

Ohjelman olisi tarkoitus toimia seuraavasti:

proffa> ./osoitelappuSyötä osoitetiedot pilkuilla eroteltuina:Teemu Teekkari,Mikontalo,33720 Tampere

Vastaanottaja: Teemu TeekkariMikontalo33720 Tampere

proffa>

Ohjelman avulla on tarkoitus pystyä tulostamaanosoitelappuja, jotka voidaan saksia irti tulosteesta jaliimata sitten kirjekuoreen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 142: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 135Ohjelman toteutus string-kirjaston avulla

#include <iostream>

#include <string>

using namespace std;

bool paloittele(string teksti, string& nimi,string& os, string& pnumero);

void tulosta_osoite(string nimi, string os, string pnumero);

const int PILKKUJEN_LUKUMAARA = 2;

int main( ) {string syote;cout << "Syötä osoitetiedot pilkuilla eroteltuina:" << endl;getline(cin, syote);

string nimi;string osoite;string postinumero;

if ( paloittele(syote, nimi, osoite, postinumero) ) {tulosta_osoite(nimi, osoite, postinumero);

} else {cout << "Virheellinen syöterivi!" << endl;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 143: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 136bool paloittele(string teksti, string& nimi,

string& os, string& pnumero) {

string::size_type alkukohta = 0;int pilkkuja_loytynyt = 0;

while ( pilkkuja_loytynyt < PILKKUJEN_LUKUMAARA ) {

string::size_type loytokohta = teksti.find(’, ’ , alkukohta);

if ( loytokohta == string::npos ) {return false;

}

++pilkkuja_loytynyt;

string kentan_teksti= teksti.substr(alkukohta, loytokohta – alkukohta);

if ( pilkkuja_loytynyt == 1 ) {nimi = kentan_teksti;

} else if ( pilkkuja_loytynyt == 2 ) {os = kentan_teksti;

}

alkukohta = loytokohta + 1;}

pnumero = teksti.substr(alkukohta);

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 144: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 137void tulosta_osoite(string nimi, string os, string pnumero) {

cout << endl<< "Vastaanottaja: " << nimi << endl<< " " << os << endl<< " " << pnumero << endl << endl;

}

Muutama kommentti ohjelmakoodista

▼ Ohjelma (käytännössä paloittele-funktio) on jossainmäärin haastava, mutta myös realistinen esimerkkistring-tyypin käytöstä.

▼ Mikäli ohjelma ei avaudu lukemalla, luennon jälkeenlähdekoodin saa kurssin kotisivuilta, jolloin sitä voitestailla itse.

▼ Hyvä lähestymistapa on tutkia koodin käyttäytymistälisäämällä sinne testitulosteita, joilla seurataanmuuttujien arvojen kehittymistä.

▼ Esimerkiksi paloittele-funktiossa kannattaa seurataainakin muuttujien alkukohta, loytokohta japilkkuja_loytynyt arvoja aina, kun niitä muutetaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 145: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 138

Lokalisaatio

▼ Lokalisaatiokirjasto (#include <locale>) sisältääpalveluita, joita tarvitaan, kun ohjelma halutaansaada toimimaan eri kieli- ja kulttuuriympäristöissä.

▼ Ohjelmointi I -kurssilla lokalisointi (localization,internationalization, i18n) ei ole olennainenasia itsessään, mutta C++:n locale-kirjasto sisältäämuutamia erittäin hyödyllisiä funktioita merkkienkäsittelyyn ➠ tutustutaan niihin lyhyesti.

▼ Katsotaan lyhyt esimerkki siitä, kuinka ohjelmavoidaan säätää toimimaan suhteellisen hyvinlokalisaatiokirjaston avulla, jos käytössä on 8-bittinenmerkkiympäristö (ISO latin 8859-1), kuten kurssillaainakin toistaiseksi on.

▼ Todellisuudessa lokalisointi on erittäin vaikeaaihepiiri, jotain ongelmia on odotettavissa varsinkinskandinaavisten kirjainten (åäöÅÄÖ) kanssa ➠ eistressata asiasta kovin paljoa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 146: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 139

Sanojenerotteluohjelma

Toteutettavan ohjelman kuvaus

Toteutetaan pienimuotoinen sanastonkeruuohjelmalocale-kirjaston merkkienkäsittelyfunktioihintutustumiseksi.

Ohjelman tulisi toimia seuraavasti:

proffa> ./sanojenerotteluSyötä rivillinen tekstiä:Jani-Petteri Äijälä-Mölkky, ikä 6v.JANIPETTERIÄIJÄLÄMÖLKKYIKÄ6Vproffa>

Käytännössä tarkoitus on siis erottaa sanoiksi kaikkikirjain- tai numeromerkeistä koostuvat yhdistelmät,muuttaa kirjainmerkit isoiksi kirjaimiksi ja tulostaasaadut sanat yksi per rivi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 147: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 140Ohjelman toteutus

#include <iostream>

#include <string>

#include <locale> // Tämä tarvitaan!

using namespace std;

// Luodaan suomi–locale, joka esittää suomalaisesta

// kieliympäristöstä riippuvat ohjelman toimintaan

// vaikuttavat asiat (esim. mitkä merkit ovat kirjaimia,

// numeroita, välimerkkejä jne.). Jos haluat selvittää,

// mitä kieliympäristöjä käyttämäsi (Linux– )kone tukee,

// voit syöttää Linux–kehotteeseen komennon "locale –a".

// Komento listaa ison joukon tuettuja kieliympäristöjen

// nimiä. Kannattaa ehkä panna merkille, että suomellekin

// on tarjolla useita eri vaihtoehtoja. Kurssilla käytetään

// "fi_FI" –kieliympäristöä.

const locale SUOMI = locale( "fi_FI" ) ;

// Edellisen olisi voinut määritellä myös muodossa

// const locale SUOMI( "fi_FI" );

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 148: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 141int main( ) {

string syoterivi;cout << "Syötä rivillinen tekstiä:" << endl;getline(cin, syoterivi) ;

bool edellinen_tulostettu_oli_endl = true;string::size_type indeksi = 0;

while ( indeksi < syoterivi.length( ) ) {char merkki = syoterivi.at( indeksi);

if ( ! edellinen_tulostettu_oli_endl&& (isspace(merkki, SUOMI)

| | ispunct(merkki, SUOMI) ) ) {

cout << endl;edellinen_tulostettu_oli_endl = true;

} else if ( isalpha(merkki, SUOMI)

| | isdigit(merkki, SUOMI) ) {

cout << toupper(merkki, SUOMI);edellinen_tulostettu_oli_endl = false;

}

++indeksi;}

if ( ! edellinen_tulostettu_oli_endl ) {cout << endl;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 149: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 142Siitä opittua

▼ Ei varsinaisesti uusi asia, mutta ensimmäinenesimerkki merkkijonon yksittäisen merkinvalitsemisesta at-funktiolla.

▼ Esimerkissä on myös käytetty ovelasti bool-tyyppistä muuttujaa pitämään kirjaa siitä,tulostuiko silmukan edeltäneellä kierroksellarivinvaihto vai ei.

▼ Varsinainen uusi asia on locale-kirjasto ja senis-alkuiset funktiot ja toupper-funktio.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 150: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 143

Merkkien käsittely

locale-kirjaston avulla

▼ locale-kirjastosta löytyvät seuraavat hyödyllisetfunktiot yksittäisten merkkien käsittelyyn (lista ei olekattava, mutta näillä pärjää hyvin).

bool isalpha(char merkki, locale kielialue);

Palauttaa true, vain jos merkki on kirjainmerkki(suomessa: a–ö tai A–Ö).

bool isdigit(char merkki, locale kielialue);

Palauttaa true, vain jos merkki onnumeromerkki (0–9).

bool isspace(char merkki, locale kielialue);

Palauttaa true, vain jos merkki on sanavälimerkki(välilyönti, tabulaattori, rivinvaihto jne.).

bool ispunct(char merkki, locale kielialue);

Palauttaa true, vain jos merkki onvälimerkki ( . , : ; ? ! jne.).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 151: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 144bool islower(char merkki, locale kielialue);

Palauttaa true, vain jos merkki on pieni kirjain(suomessa: a–ö).

bool isupper(char merkki, locale kielialue);

Palauttaa true, vain jos merkki on iso kirjain(suomessa: A–Ö).

char tolower(char merkki, locale kielialue);

Palauttaa merkkiä vastaavan pienen kirjaimen. Josmerkki ei ole kirjainmerkki (isalpha), palauttaasen itsessään.

char toupper(char merkki, locale kielialue);

Palauttaa merkkiä vastaavan ison kirjaimen. Josmerkki ei ole kirjainmerkki (isalpha), palauttaasen itsessään.

▼ Kaikilla edellä kuvatuilla funktioilla jälkim-mäinen parametri kielialue on locale-tyyppinenarvo, joka on alustettu kuvaamaan haluttuakieli/kulttuurialuetta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 152: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 145

Esimerkki

Ohjelman kuvaus

▼ Tee seuraavan kaltaisesti toimiva ohjelma:proffa> ./lampotilagraafianna lampötila kello 0.00: 0.3anna lampötila kello 1.00: –4.1anna lampötila kello 2.00: –8.2anna lampötila kello 3.00: –9.0· · · rivejä pois tilan säästämiseksi · · ·

anna lampötila kello 20.00: 25.5anna lampötila kello 21.00: 15.1anna lampötila kello 22.00: 7.2anna lampötila kello 23.00: 2.7

–40 –30 –20 –10 0 10 20 30 40| | | | | | | | |

0.00: *

1.00: *

2.00: *

3.00: *

· · · rivejä pois tilan säästämiseksi · · ·20.00: *

21.00: *

22.00: *

23.00: *

| | | | | | | | |–40 –30 –20 –10 0 10 20 30 40

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 153: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 146Algoritmi

Algoritmi: Lämpötilagraafi

tunti← 0

WHILE tunti < 24

lämpötila tunti← kysy lämpötila kello tunti

tunti← tunti + 1

tulosta otsikkorivi ylälaitaan

tunti← 0

WHILE tunti < 24

tulosta graafin rivi ajalle tunti

tunti← tunti + 1

tulosta otsikkorivi alalaitaan

▼ Selkeästi joitain kohtia voitaisiin taas yksityiskoh-taistaa, mutta annetaan olla tällä kertaa.

▼ Potentiaaliset funktiot kursiivilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 154: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 147Syntynyt C++-toteutus

#include <iostream>

#include <iomanip>

#include <string>

using namespace std;

// Vakioiden määrittelytconst int YLALAITAAN = 0;const int ALALAITAAN = 1;

const int TUNTEJA_PAIVASSA = 24;

// Funktioiden ja aliohjelmien esittelytdouble KysyLampotila( int tunti) ;void TulostaGraafiRivi( int tunti, double lammot[ ] ) ;void TulostaOtsikkorivi( int minne);

int main( ) {double lampotilat[TUNTEJA_PAIVASSA];

int tunti = 0;while (tunti < TUNTEJA_PAIVASSA) {

lampotilat[tunti] = KysyLampotila( tunti) ;++tunti;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 155: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 148

TulostaOtsikkorivi(YLALAITAAN);

tunti = 0;while (tunti < TUNTEJA_PAIVASSA) {

TulostaGraafiRivi( tunti, lampotilat) ;++tunti;

}

TulostaOtsikkorivi(ALALAITAAN);}

double KysyLampotila( int tunti) {cout << "anna lämpötila kello " << tunti << ".00: ";

double lampo;cin >> lampo;

return lampo;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 156: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 149void TulostaOtsikkorivi( int minne) {

const string VALIT = " "; / / 6 kplconst string VIIVAT = " | | | | "

" | | | | | " ;const string NUMEROT = " –40 –30 –20 –10 "

"0 10 20 30 40";

if (minne == YLALAITAAN) {cout << VALIT << NUMEROT << endl;cout << VALIT << VIIVAT << endl;

} else {cout << VALIT << VIIVAT << endl;cout << VALIT << NUMEROT << endl;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 157: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 150void TulostaGraafiRivi( int tunti, double lammot[ ] ) {

cout << setw(5) << setprecision(2) << fixed<< static_cast<double>(tunti) ;

if ( lammot[tunti] < –40.0 | | lammot[tunti] > 40.0) {cout << endl;return;

}

int valit= static_cast<int>( (lammot[tunti] + 40) / 2 + 0.5);

while (valit > 0) {cout << " ";– –valit;

}

cout << "*" << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 158: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 151

Taulukot

▼ Taulukko on rakenteinen tietotyyppi, jolla onseuraavat ominaisuudet:

– se on järjestetty,

– sillä on joku määrätty koko ja

– tietoalkiot, joista se koostuu, kuuluvat keskenäänsamaan tietotyyppiin.

▼ C++:ssa taulukkomuuttujia määritellään seuraavasti:

alkion_tyyppi nimi[koko];

▼ Tuloksena saadaan taulukkotyyppinen muuttuja nimi,johon voidaan tallettaa koko kappaletta tietoalkioita,joiden tyyppi on alkion_tyyppi.

▼ Alkion tyyppi voi olla mikä tahansa tietotyyppi.

▼ Koon pitää olla vakiolauseke.

▼ Esimerkiksi yhdeksän alkion kokonaislukutaulukkosaataisiin kirjoittamalla:

int luvut[9];

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 159: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 152▼ Intuitiivisesti taulukkoa voi ajatella joukkona

laatikoita, joista jokaisella on järjestysluku, jollalaatikon sisältöä voidaan tutkia ja muuttaa.

▼ Jokaiseen laatikkoon mahtuu yksi tietoalkio, jonkatyyppi on alkion tyyppi.

▼ C++-kielessä laatikoiden numerointi lähtee nollasta

ja päättyy koko – 1:een.

▼ Esimerkiksi int luvut[9] näyttää siis seuraavalta:

luvut:

0 1 2 3 4 5 6 7 8

viimeinen alkio on siis järjestysluvultaan yhtäpienempi kuin taulukon koko.

▼ Taulukon alkioihin viitataan (taulukkoa indeksoi-

daan) hakasulkuoperaattorilla [ ]:

luvut[8] = 2* luvut[0];

joka asettaisi luvut-taulukon viimeisen alkion arvoksisen ensimmäisen alkion arvon kerrottuna kahdella.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 160: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 153▼ Hakasulkuoperaattorin »sisällä» (operandina) voi olla

mikä tahansa lauseke, jonka tyyppi on kokonaisluku.

▼ C++ ei mitenkään tarkasta, onko taulukon käsittelyssäkäytetty indeksi sallituissa rajoissa:

int a = 1000;

luvut[a] = 42; // looginen virhe

joka menisi kääntäjästä läpi virheittä, mutta on siltiväärin: se viittaa alkioon, jota ei ole olemassa.

▼ Luonnollisesti taulukoille pätee sama kuin muuttujilleyleisestikin: taulukko (sen alkiot) pitää alustaa jollainjärkevillä arvoilla ennen kuin sitä voi käyttää.

▼ Taulukko voidaan alustaa määrittelyn yhteydessä:

int luvut[9] = { 1, 3, 5, 7, 9, 2, 4 } ;

josta saataisiin tuloksena taulukko:

luvut: 1 3 5 7 9 2 4 0 0

0 1 2 3 4 5 6 7 8

▼ Jos alustusalkioita on vähemmän kuin taulukon koko,alustetaan loput nolliksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 161: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 154▼ Taulukkoa alustettaessa voidaan koko jättää

kertomatta, jolloin se määräytyy automaattisestialustusalkioiden lukumäärästä:

int luvut[ ] = { 1, 3, 5, 7, 9, 2, 4, 6, 8 } ;

▼ Tämä merkintätapa toimii vain taulukkoa määrittelynyhteydessä alustettaessa: se ei ole yleiskäyttöinentaulukkoon sijoitusmenetelmä.

▼ Kokonaisia taulukoita ei voi sijoittaa toisiinsa=-operaattorilla, eikä niiden yhtä- ja erisuuruutta voivertailla ==- ja !=-operaattoreilla ➠ kaikki tehtäväitse alkio kerrallaan.

▼ Taulukot ovat staattisia tietorakenteita, mikätarkoittaa, että niiden kokoa ei voi enää muuttaa,kun se on kerran määrittelyn yhteydessä annettu.

▼ Staatisen tietorekenteen vastakohta on dynaaminen

tietorakenne, jolla ei ole ennalta määrättyämaksimikokoa.

▼ Dynaamisista rakenteista tulee puhetta mm. kurssillaOHJ-1150 Ohjelmointi II.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 162: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 155

Funktion parametrit: taulukot

▼ Vaikka funktion parametrit C++:ssa ovatkin oletusar-voisesti arvoparametreja, käyttäytyvät taulukotparametrina ollessaan »kummallisesti».

▼ Tämä johtuu tavasta, jolla C++ ajattelee taulukoita.

▼ Tällä kurssilla asiaa ei sen kummemin pohdita,omaksutaan vain faktanomaisesti pari taulukoidenerikoista ominaisuutta:

1. Jos muodollinen parametri on taulukko, siitäei mitenkään voi päätellä, montako alkiotatodellisessa parametrissa on ➠ funktiolle pitääerikseen kertoa alkioiden lukumäärä (globaaliconst-vakio tai ylimääräinen parametri).

2. Jos muodollinen parametri on taulukko ja funktiomuuttaa taulukon yksittäisiä alkioita, niin vastaavatalkiot muuttuvat myös todellisessa parametrissa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 163: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 156▼ Näitä ominaisuuksia havainnollistaa seuraava

yksinkertainen esimerkki:

#include <iostream>

using namespace std;

const int MAX_LUKUJA = 1000;const int VIRHE = –1;const double LOPETUSLUKU = –1.0;

int LueLuvut(double luvut[ ] ) ;double LaskeKeskiarvo(double luvut[ ], int montako);

int main( ) {double luvut[MAX_LUKUJA];int montako_luettiin;

montako_luettiin = LueLuvut(luvut);

if (montako_luettiin != VIRHE) {cout << "Lukujen keskiarvo: "

<< LaskeKeskiarvo(luvut, montako_luettiin)<< endl;

} else {cout << "Virhe: liian monta lukua!" << endl;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 164: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 157int LueLuvut(double luvut[ ] ) {

int montako = 0;

// Monelleko luvulle taulukossa on tilaa?

// Se tiedetään vakiosta MAX_LUKUJA, koska

// pääohjelmassa parametritaulukko on

// määritelty MAX_LUKUJA kokoiseksi.while (montako < MAX_LUKUJA) {

cout << "Syota " << montako + 1 << ". luku: " ;

/ / Luetaan alkio taulukon alkioon, muutos

// näkyy myös pääohjelman todellisessa

// parametrissa johtuen taulukoiden

// kummallisesta ominaisuudesta.cin >> luvut[montako];

// Seuraava rivi tuottaa varoituksen

// kääntäjältä. Miksi?if ( luvut[montako] == LOPETUSLUKU) {

return montako;}

++montako;}

// Jos montako kasvoi liian suureksi, niin

// while–silmukka päättyy ja voidaan palauttaa

// virhe (käyttäjä syötti liian monta lukua).return VIRHE;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 165: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 158double LaskeKeskiarvo(double luvut[ ], int montako) {

double summa = 0.0;int i = 0;

if (montako == 0) {return 0.0;

}

// Tässä funktiossa taulukon koolla ei sinällään

// ole merkitystä, vaan ainoastaan sillä kuinka

// monen taulukon alussa olevan alkion keskiarvo

// pitää laskea.while ( i < montako) {

summa = summa + luvut[i];++i;

}

return summa / montako;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 166: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 159▼ Toinen mahdollisuus LueLuvut-funktion määritte-

lyyn olisi ollut:

int LueLuvut(double luvut[ ], int koko) {int montako = 0;

// Nyt taulukossa oleva tila saadaan parametrina.while (montako < koko) {

cout << "Syota " << montako + 1 << ". luku: " ;cin >> luvut[montako];

if ( luvut[montako] == LOPETUSLUKU) {return montako;

}

++montako;}

return VIRHE;}

▼ Ja sitä olisi pääohjelmassa kutsuttu:

montako_luettiin = LueLuvut( luvut, MAX_LUKUJA);

▼ Usein kannattaa suosia jälkimmäistä tapaa, koska sentuloksena saadaan yleiskäyttöisempi funktio.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 167: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 160

Esimerkki

Ohjelman kuvaus

▼ Tehtävänä on saada aikaan seuraavan kaltaisestitoimiva ohjelma:

proffa> ./tenttituloksetOpiskelijan nimi tai "loppu": Teemu TeekkariOpiskelijanumero: 12345Anna tehtävän 1 pisteet (0 – 6): 5Anna tehtävän 2 pisteet (0 – 6): 3Anna tehtävän 3 pisteet (0 – 6): 0Anna tehtävän 4 pisteet (0 – 6): 212345 Teemu Teekkari: arvosana 0

Opiskelijan nimi tai "loppu": Tiina HumanistiOpiskelijanumero: 23456Anna tehtävän 1 pisteet (0 – 6): 6Anna tehtävän 2 pisteet (0 – 6): 6Anna tehtävän 3 pisteet (0 – 6): 5Anna tehtävän 4 pisteet (0 – 6): 623456 Tiina Humanisti: arvosana 5

Anna opiskelijan nimi tai loppu: loppuproffa>

▼ Pisterajat ovat seuraavat:0–10: 0 14–17: 2 21–22: 4

11–13: 1 18–20: 3 23–24: 5

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 168: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 161Algoritmi

Algoritmi: Tenttitulokset

WHILE opiskelija← lue opiskelijan tiedot onnistui

tulosta opiskelijan tiedot ja laskettu arvosana

Algoritmi: Lue opiskelijan tiedot

opiskelijan nimi← kysy nimi

IF opiskelijan nimi on "loppu" THEN

opiskelijan tietojen lukeminen epäonnistui

opiskelijanumero← kysy opiskelijanumero

tehtävä← 1

WHILE tehtävä ≤ 4

pisteet tehtävästä tehtävä← lue yksi piste

tehtävä← tehtävä + 1

opiskelijan tietojen lukeminen onnistui

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 169: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 162Algoritmi: Laske arvosana

summa← tehtävien 1, 2, 3 ja 4 pisteiden summa

IF 0 ≤ summa ≤ 10 THEN

arvosana on 0

ELSE IF 11 ≤ summa ≤ 13 THEN

arvosana on 1

ELSE IF 14 ≤ summa ≤ 17 THEN

arvosana on 2

ELSE IF 18 ≤ summa ≤ 20 THEN

arvosana on 3

ELSE IF 21 ≤ summa ≤ 22 THEN

arvosana on 4

ELSE IF 23 ≤ summa ≤ 24 THEN

arvosana on 5

ELSE

virheilmoitus "laiton arvosana"

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 170: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 163Syntynyt C++-toteutus

#include <iostream>#include <string>#include <limits>

using namespace std;

// Vakioiden määrittelyt:const string LOPETUSKASKY = "loppu";const unsigned short int PISTEVIRHE

= numeric_limits<unsigned short int>::max( );

// Omien tietotyyppien määrittelyt:struct Opiskelija {

string nimi;unsigned int opnum;unsigned short int t1; // Tehtävän 1 pisteetunsigned short int t2; // jneunsigned short int t3;unsigned short int t4;

};

// Funktioiden esittelyt (tultava tyyppimäärittelyiden// jälkeen, jos käytetään omia tyyppejä):bool LueOpiskelijanTiedot(Opiskelija& opisk);unsigned short int LaskeArvosana(Opiskelija opisk);unsigned short int

LuePisteet(unsigned short int mika_tehtava);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 171: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 164

int main( ) {Opiskelija op;

// Seuraavassa op viiteparametri: funktio muuttaa

// sitä vastaamaan käyttäjältä luettuja arvoja.while (LueOpiskelijanTiedot(op) ) {

unsigned short int arvosana= LaskeArvosana(op);

if (arvosana != PISTEVIRHE) {cout << op.opnum << " "

<< op.nimi << ": arvosana "<< arvosana << endl << endl;

} else {cout << "Virheellinen kokonaispistemäärä!"

<< endl;}

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 172: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 165// Funktio lukee kaikki yhden opiskelijan tiedot.

// Jos lukeminen onnistui, paluuarvo on tosi (true) .

// Käyttäjän syöttäessä LOPETUSKÄSKYN paluuarvo on

// epätosi (false) .bool LueOpiskelijanTiedot(Opiskelija& opisk) {

cout << "Opiskelijan nimi tai \ "loppu\ ": " ;getline(cin, opisk.nimi);

if (opisk.nimi == LOPETUSKASKY) {return false;

}

cout << "Opiskelijanumero: ";cin >> opisk.opnum;

opisk.t1 = LuePisteet(1);opisk.t2 = LuePisteet(2);opisk.t3 = LuePisteet(3);opisk.t4 = LuePisteet(4);

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 173: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 166// Funktio laskee ja palauttaa opiskelijan

// pisteistä määräytyvän arvosanan tai

// virhetilanteessa vakion PISTEVIRHE.unsigned short int LaskeArvosana(Opiskelija opisk) {

unsigned short int summa= opisk.t1 + opisk.t2 + opisk.t3 + opisk.t4;

if (summa <= 10) {return 0;

} else if (11 <= summa && summa <= 13) {return 1;

} else if (14 <= summa && summa <= 17) {return 2;

} else if (18 <= summa && summa <= 20) {return 3;

} else if (21 <= summa && summa <= 22) {return 4;

} else if (23 <= summa && summa <= 24) {return 5;

} else {return PISTEVIRHE;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 174: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 167// Funktio lukee ja palauttaa tehtavän mika_tehtava

// pistemäärän. Hyväksyy vain virheettömän syötteen.unsigned short intLuePisteet(unsigned short int mika_tehtava) {

const unsigned short int PIENIN = 0;const unsigned short int SUURIN = 6;

cout << "Anna tehtävän " << mika_tehtava<<" pisteet ( "<< PIENIN << " – " << SUURIN<< " ): " ;

unsigned short int pisteet;cin >> pisteet;

while (pisteet > SUURIN) {cout << "Virheellinen pistemäärä!" << endl;

cout << "Anna tehtävän " << mika_tehtava<<" pisteet ( "<< PIENIN << " – " << SUURIN<< " ): " ;

cin >> pisteet;}

cin.get( ) ; / / Luetaan yksi merkki cin:stä, mutta

// ei talleteta sitä mihinkään. Miksi?

return pisteet;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 175: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 168Siitä opittua

▼ Tärkein uusi asia esimerkissä on tietue- elistruct-tietotyypit.

▼ Tietueet ovat käyttäjän itse määrittelemiärakenteisia tietotyyppejä, joiden avulla voidaankäsitellä yhtenä kokonaisuutena useita keskenäänmahdollisesti erityyppisiä tietoalkioita.

▼ Realistinen esimerkki viiteparametrien käytöstäLueOpiskelijanTiedot-funktiossa.

▼ unsigned int -tyypit, joiden avulla voidaankäsitellä ei-negatiivisia kokonaislukuja.

▼ limit-kirjaston funktio numeric_limits<int>::min( )

pienimmän int-tyyppisen arvon selvittämiseen.

▼ getline-funktiolla saadaan luettua syötteestä(esim. cin) rivillinen tekstiä merkkijonoon.

▼ cin.get-funktiolla voidaan lukea käyttäjänsyötteestä yksittäinen merkki, joka saadaankäyttöön funktion paluuarvona.

▼ getline:sta ja cin.get:stä lisää tiedostojen käsittelynyhteydessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 176: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 169

unsigned, short ja long

▼ Kokonaisluku- (int) ja joissain tilanteissa merkki-tyyppisen (char) tiedon tyyppiä voidaan tarkentaalisämääreillä unsigned, short ja long.

▼ Nämä lisämääreet informoivat kääntäjää siitä, ettäjos vain suinkin mahdollista, niin rajoitetaan tailaajennetaan syntyvän tietoalkion tai muuttujantyyppiä jollain tavoin:

unsigned int kokonaisluku, esitetään yhtä monellabitillä kuin int, arvoalue: 0 japositiiviset.

short int kokonaisluku, esitetään korkeintaan

yhtä monella bitillä kuin int, arvoalue:esitystarkkuuden rajoissa positiiviset janegatiiviset.

long int kokonaisluku, esitetään vähintään

yhtä monella bitillä kuin int, arvoalue:esitystarkkuuden rajoissa positiiviset janegatiiviset.

unsigned short int kuten short int mutta arvoalue:0 ja positiiviset.

unsigned long int kuten long int mutta arvoalue:0 ja positiiviset.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 177: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 170▼ Lisäksi uudemmissa kääntäjissä on myös tyypit

long long int ja unsigned long long int.

▼ Reaalilukutyyppejäkin on useampia: float ja double.

▼ Lisäksi uudemmat kääntäjät tunnistavat myöslong double -tyypin.

▼ Jos erityistä syytä ei ole, kannattaa pitäytyä double-tyypissä: se on hyvä kompromissi.

▼ Varsinkin float-tyypille on kovin vähän perusteltuakäyttöä ja sitä kannattaa välttää: sen esitystarkkuuson todennäköisesti huonompi kuin double-tyypillä

➠ pyöristysvirheet kumuloituvat nopeammin.

▼ Jos reaalilukulaskuissa tarvitaan suurempaa tarkkuuttaja kääntäjä ja käytetty prosessoriarkkitehtuuri tukevatsitä, long double -tyyppi on mahdollinen valinta.

▼ Reaalilukutyyppien kanssa ei voi käyttää lisämäärettäunsigned.

▼ Se, monellako bitillä kukin tietotyyppi esitetään,riippuu ainakin käytettävästä prosessorista, käyttö-järjestelmästä, kääntäjästä ja kääntäjän versiosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 178: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 171▼ Esimerkkinä muutama käännösympäristö:

Ympäristö Tyyppi Bittejä Pienin Suurin

short int 16 −215 215 − 1Intel int 16 −215 215 − 1Win98 32-bit long int 32 −231 231 − 1(pöytäkone) unsigned short int 16 0 216 − 1

unsigned int 16 0 216 − 1unsigned long int 32 0 232 − 1

Intel short int 16 −215 215 − 1WinXP 32-bit int 32 −231 231 − 1(pöytäkone) long int 32 −231 231 − 1— long long int 64 −263 263 − 1Proffa unsigned short int 16 0 216 − 1Linux unsigned int 32 0 232 − 1(palvelin) unsigned long int 32 0 232 − 1

unsigned long long int 64 0 264 − 1

short int 16 −215 215 − 1int 32 −231 231 − 1

Intel long int 64 −263 263 − 1Linux 64-bit long long int 64 −263 263 − 1(palvelin) unsigned short int 16 0 216 − 1

unsigned int 32 0 232 − 1unsigned long int 64 0 264 − 1unsigned long long int 64 0 264 − 1

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 179: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 172

Perustietotyyppien ääriarvot:

limits-kirjasto

▼ Joskus on tarve saada selville numeerisen tietotyypinmaksimi- ja minimiarvot.

▼ Joihinkin tietotyyppeihin saattaa myös kuuluaerikoisarvoja: esimerkiksi monissa arkkitehtuureissadouble-tyyppi voi esittää arvon∞, joka voi syntyätuloksena vaikkapa nollalla jakamisesta.

▼ Nämä arvot riippuvat monesta muustakin asiastakuin C++-kääntäjästä ➠ kieli ei määrittele arvojayksikäsitteisesti.

▼ Sen sijaan C++-kieleen kuuluu kirjasto limits, jonkaavulla ääri- ja muut erikoisarvot voidaan selvittääohjelmakoodissa.

▼ Kuten muidenkin kirjastojen kanssa, limits-kirjastonkäyttö vaatii ohjelman alkuun sopivan include-rivin:

#include <limits>

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 180: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 173▼ Tämän jälkeen käytettävissä on seuraavat apuvälineet

(ei läheskään kattava lista):

numeric_limits<tyyppinimi>::min( );

Funktio, jonka paluuarvo kertoo pienimmänmahdollisen arvon, jonka tietotyyppi voi esittää:

int pienin_int = numeric_limits<int>::min( );

numeric_limits<tyyppinimi>::max( );

Paluuarvo on suurin mahdollinen arvo, jonkatietotyyppi voi esittää:

cout << numeric_limits<double>::max( ) << endl;

numeric_limits<reaalilukutyyppi>::infinity( ) ;

Jos käännösympäristössä on mahdollista esittääreaalilukutyyppinen arvo∞, se saadaan tämänfunktion paluuarvona:

const doubleAARETON = numeric_limits<double>::infinity( ) ;

· · ·if ( jaettava / jakaja == AARETON ) {

// Oops, jako nollalla?}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 181: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 174const boolnumeric_limits<reaalilukutyyppi>::has_infinity

const-vakio, joka on true vain, jos reaalilukutyyppi

pystyy esittämään arvon∞:

if ( numeric_limits<double>::has_infinity ) {// ääretön voidaan esittää...

} else {// ääretöntä ei voida esittää...

}

numeric_limits<reaalilukutyyppi>::quiet_NaN( );

Jos reaalilukutyyppi pystyy esittämään arvonNaN,✶ se saadaan tämän funktion paluuarvona:

if ( jaettava == 0.0 && jakaja == 0.0 ) {return numeric_limits<double>::quiet_NaN( );

} else {// Tee jotain muuta hyödyllistä...

}

const boolnumeric_limits<reaalilukutyyppi>::has_quiet_NaN

const-vakio, joka on true vain, jos reaalilukutyyppi

pystyy esittämään arvon NaN.✶

✶ Tämä on melkoinen yksinkertaistus, mutta hyväksyttäneen se tässävaiheessa koulutusta. NaN (Not a Number) kuvaa määrittelemätöntäarvoa (esimerkiksi 0.0/0.0,

√–1, jne.).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 182: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 175▼ NaN on erikoinen arvo sikäli, että vertaillaanpa sen

yhtäsuuruutta mihin tahansa toiseen reaalilukuun,tulos on aina false, jopa silloin kun molemmatvertailtavat ovat NaN.

▼ Tai toisin sanoen: NaN ei ole yhtäsuuri edes itsensäkanssa.

▼ Tätä ominaisuuttaa voidaan hyödyntää, jos halutaantietää, onko jonkin reaalilukulausekkeen arvon NaN.

▼ Järkevintä on toteuttaa tähän tarkoitukseen funktio:

bool onko_NaN(double arvo) {if ( arvo != arvo ) {

return true;

} else {return false;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 183: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 176

Tietue- eli struct-tietotyypit

▼ Tietuetyyppejä käytetään silloin, kun on tarvekäsitellä yhtenä kokonaisuutena useita keskenään

mahdollisesti erityyppisiä tietoalkioita.

▼ Tietueita (kuten taulukoitakin) kutsutaan rakentei-

siksi tietotyypeiksi: niillä on ohjelmoijan määräämärakenne.

▼ Tietuetyypin määrittely tapahtuu varatun sananstruct avulla:

struct tyypin_nimi {kentän1tyyppi kentän1nimi;· · ·

kentänntyyppi kentännnimi;} ;

▼ Tämän seurauksena kieleen ilmestyy uusi tietotyyppinimeltään tyypin_nimi, jota voidaan käyttää normaa-listi muuttujien, parametrien jne määrittelyyn:

tyypin_nimi muuttujan_nimi;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 184: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 177▼ Tietuetyypin yksittäiset kentät käyttäytyvät kuten

muuttujat, joiden tyyppi on kentän tyyppi, kun niitäkäsitellään "."-operaattorin (piste) avulla:

struct Opiskelija {string nimi;int opnum;

} ;· · ·Opiskelija opisk; // Luodaan tietuetyyppinen muuttuja· · ·opisk.nimi = "Minna Materialisti";cin >> opisk.opnum;

▼ Tietuetyypin muuttujia voidaan myös alustaamäärittelyvaiheessa vakiolausekkeilla, joiden tyyppion sama kuin vastaavan kentän tyyppi:

Opiskelija opisk = {"Minna Materialisti", 12345

} ;

▼ Kentät alustetaan annetuilla arvoilla siinä järjestyk-sessä, jossa ne esiintyivät tyyppiä määriteltäessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 185: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 178▼ Tietuetyyppisiä muuttujia voi sijoittaa toisiinsa

=–operaattorilla, mutta niitä ei voi vertailla ==– ja!=–operaattoreilla.

▼ Tietueiden kentät saavat olla minkä tahansatyyppisiä, myös taulukoita:

struct Arvosana {string nimi;int tehtavien_pisteet[4];

} ;· · ·Arvosana asana;· · ·asana.tehtavien_pisteet[2] = 5;

▼ Toisaalta, kuten aiemmasta muistetaan, taulukonalkiot saavat olla mitä tahansa tyyppiä, myöstietueita:

Opiskelija opiskelijat[1000];· · ·opiskelijat[0].nimi = "Raimo Rakentaja";cin >> opiskelijat[42].opnum;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 186: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 179

Ohjelmointityyli

▼ Suurin osa ohjelmointikielistä ei aseta vaatimuksiaohjelmakoodin asettelulle ➠ niin kauan kuinohjelmakoodi täyttää kielen syntaktiset ja semanttisetvaatimukset, kääntäjä tai tulkki ei välitä.

▼ Monissa ohjelmointikielissä koko ohjelman voiesimerkiksi kirjoittaa yhdelle pitkälle riville.

▼ Käytännössä ohjelmakoodia kuitenkin aina joutuvatlukemaan ja muokkaamaan myös ihmiset, muutkinkuin koodin alkuperäinen kirjoittaja.

▼ Tämän vuoksi on kriittisen tärkeää, että ohjelmaakirjoitettaessa kiinnitetään huomiota myös koodinulkoasuun ja pyritään tekemään siitä mahdolli-simman selkeä.

▼ Selkeä ja johdonmukainen rakenne auttaa ihmislu-kijaa ymmärtämään koodin tarkoituksen.

▼ Noudattamalla muutamia yksinkertaisia periaatteitakoodista saa selkeää varsin pienellä lisävaivalla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 187: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 180Kommentointi

– Kommentoinnin tarkoituksena on selittäämiksi jokin asia on koodissa tai mikä on sen

tarkoitus: hyvä kommentti on hyvä vastausmiksi-kysymykseen.

– Kommentoitaessa saa olettaa, että lukija ym-märtää käytettyä ohjelmointikieltä suvereenisti.

– Seuraavat kommentit ovat huonoja:

// Sijoitetaan muuttujaan d arvo x*x+y*y.d = x * x + y * y;· · ·

// Palautetaan muuttujan d neliöjuuri.return sqrt(d);

koska ne eivät tarjoa mitään uutta informaatio-sisältöä lukijalle, joka osaa C++:aa.

– Vältä siis koodissasi ohjelmointikielen ominai-suuksien ja ilmiselvyyksien kommentointia.

– Huomaa kuinka paljon hyödyllisempiä seuraavatkommentit ovat:

// Lasketaan hypotenuusan neliö kateeteista x ja y.d = x * x + y * y;· · ·

// Siitä saadaan hypotenuusa.return sqrt(d);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 188: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 181– Nämä kommentit eivät enää keskity itsestään-

selvyyksiin, vaan selittävät yleisemmällä tasollakoodirivien tarkoitusta.

– Ideaalitilanteessa ohjelmakoodi tulisi kommen-toida niin tarkasti, että siitä ei voi esittää "miksi"-tai "mikä on tämän tarkoitus"-kysymystä, johonei löytyisi vastausta kommenteista.

– Yleensä jokaisen lähdekooditiedoston alkuunkannattaa lisätä lyhyt kommentti, joka kertookoodin tekijän ja sen tarkoituksen (siis lyhyenkuvauksen ohjelman toiminnasta).

– Jokaisen aliohjelman ja funktion alkuun onhyvä lisätä kommentti selittämään funktiontarkoitusta, parametreja ja paluuarvoa:

// Funktio laskee pythagoraan lauseella suora-// kulmaisen kolmion hypotenuusan pituuden.// Parametrit: x, y: kateettien pituudet.// Paluuarvo: hypotenuusan pituus.double Pythagoras(double x, double y) {· · ·

}

– Kannattaa pitää mielessä myös se, ettäkommentoinnissakaan määrä ei korvaa laatua.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 189: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 182Sisennykset

– Sisennys tarkoittaa loogisesti yhteenkuuluvienkoodirivien asettelua samalle tasolle (yhtä kauaskoodin vasemmasta laidasta) ➠ ihmislukijanon helppo hahmottaa, mikä on osa mitäkinkokonaisuutta.

– Sisennysten periaate on hyvin yksinkertainen:aina uuden lohkon✶ alussa kasvatetaanrivien sisennystä tietyn vakiomäärän verran(4–5 välilyöntiä) ja lohkon lopussa palautetaansisennys lohkoa edeltäneelle tasolle.

– Sisennykset ovat ehkä tärkein ja helppokäyttöisinyksittänen tekijä, jonka avulla koodista saaselkeämpää.

– Monisteen esimerkit on sisennetty huolellisestija niistä kannattaa ottaa mallia.

– Jotkut editorit (esim. emacs) osaavat auttaakoodin sisentämisessä ➠ viime kädessä vastuuon kuitenkin koodaajan, koska aputyökalut eivätole erehtymättömiä.

✶ Siis aaltosulkuparin { } sisällä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 190: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 183Tyhjä tila

– Tyhjät rivit ja ylimääräiset välilyönnit (muuallakuin rivien alussa) ovat hienovarainen työkalukoodin ulkoasun selkeyttämiseen.

– Tyhjää tilaa on helppo käyttää huonosti ➠ liikaatai liian vähän.

– "Tyylikeino" jonka käyttö vaatii näkemystä ➠vaikea antaa absoluuttisia ohjeita.

– Esimerkiksi seuraava koodi:

int i=0;//Silmukkamuuttuja tulostamiseen.while( i<10) {

cout<<i<<endl;if(i==9) {

TulostaSumma(1,9);}

}

näyttää paremmalta, kun ei nuukaile tyhjäntilan kanssa aivan noin paljon:

int i = 0; // Silmukkamuuttuja tulostamiseen.

while ( i < 10) {cout << i << endl;

if ( i == 9) {TulostaSumma(1, 9);

}} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 191: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 184Rivinpituus

– Pidä koodiriviesi pituus alle 80 merkissä.

– Tämä tyyliohje perityy historian aamuhämärästä,jolloin näyttöpäätteiden leveys oli 80 merkkiä.

– Ohje on kuitenkin pätevä vielä nykypäivänäkin.

– Jos haluaa 19-tuumaiselle näytölle rinnakkainkaksi ikkunaa (esimerkiksi editori ja käännös-ikkuna) eivät ne voi olla juuri 80 merkkiäleveämpiä tai teksti täytyy skaalata niin pieneksi,ettei sitä heikkosilmäinen enää lue.

– Jos koodiisi väkisin tulee C++-lauseita tai-lausekkeita, joiden pituus on yli 79 merkkiä, jaane jotenkin selkeästi useammalle riville.

– Tästä mekanismista on luentomonisteessapaljonkin malleja (esimerkiksi pitkän cout-tulostuksen jakaminen monelle riville).

– Yleensä jatkorivejä kannattaa sisentää enemmänkuin ensimmäistä riviä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 192: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 185Nimeämiskäytäntö

– Muuttujat, funktiot ja tietotyypit on järkevänimetä siten, että niiden nimestä pystyy suoraanlukemaan tarkoituksen.

– Valitsemalla nimiksi selkeitä puhutun kielensanoja tai ilmaisuja koodin lukeminen onhelpompaa.

– C++ ei välitä kirjoittaako koodinconst int m = 12;double f(double a);int o;struct ttt {· · ·

} ;

vaiconst int KUUKAUSIEN_LUKUMAARA = 12;double LaskePolynomiB(double x_koordinaatti) ;int opiskelijanumero;struct Tuote {· · ·

} ;

jälkimmäinen on kuitenkin lukijan kannaltapaljon selkeämpi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 193: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 186– On useita koulukuntia siitä, kuinka valitut nimet

pitäisi kirjoittaa.

– Luentomonisteen tyyli on kirjoittaa

· funktioiden ja tietotyyppien nimissä jokainensana isolla alkukirjaimella ilman sanavälejä,

· muuttujien nimet pienillä kirjaimilla, sanavä-leinä alaviiva ja

· vakioiden nimet kokonaan isoilla kirjaimilla,sanaväleinä alaviiva.

– Tämä ei ole missään tapauksessa ainoa oikeatapa.

– Minkä tavan ikinä valitseekin, tärkeintä onnoudattaa sitä uskollisesti.

– Hyvin valitut nimet vähentävät usein kommen-toinnin tarvetta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 194: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 187Vakiomuuttujat (const-vakiot)

– Vakiomuuttujien avulla voidaan nimetä koodinepämääräiset ja vaikeaselkoiset vakioarvot.

– Hyvin valitut nimet selkeyttävät koodia:int paiva = 29;

on vaikeatajuisempi kuin

const int KARKAUSPAIVA = 29;· · ·

int paiva = KARKAUSPAIVA;

– Jos jotain vakioarvoa täytyy koodissa muuttaa,on se helpompi tehdä kerran const-vakionmäärittelykohdassa kuin käydä koko koodi läpija muuttaa kaikki literaaliarvot käsin.

– Vakiomuuttujienkin nimet kannattaa valitahuolella kuvaamaan niiden tarkoitusta.

– Usein nimittäin näkee aloittelevien ohjelmoijiensyyllistyvän seuraavaan tyylivirheeseen:

const int VIISI = 5;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 195: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 188– Tämä ei tuo ohjelman selkeyteen mitään lisä-

arvoa vaan koodiin on kirjattu itsestäänselvyys.

– Parempi olisi miettiä, mitä literaaliarvo 5 esittää,ja keksiä nimi sen perusteella vaikkapa:

const int TENTTITEHTAVIA = 5;

tai mistä sitten ikinä onkaan kyse.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 196: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 189

Tiedon lajittelu

▼ Tiedon lajittelulla tarkoitetaan (yleensä taulukon)tietoalkioiden järjestämistä jonkin säännön mukai-sesti: esimerkiksi kasvavaan järjestykseen.

▼ Lajitteluongelma on tietojenkäsittelyssä useintoistuva operaatio ja sitä on tutkittu paljon ➠lajittelualgoritmeja on kymmeniä.

▼ Tutustutaan yhteen näistä algoritmeista:valintalajitteluun ja sen toteutukseen C++:lla.

▼ Valintalajittelu ei ole erityisen tehokas algoritmi,itseasiassa se on kurja ja tehoton, varsinkin joslajiteltavia alkioita on paljon.

▼ Pieniin (alkiota alle 1000) lajittelutehtäviin se onkuitenkin riitävä.

▼ Valintalajittelun hyvä puoli on sen helppotajuisuus.

▼ Parempia, tehokkaampia ja elegantimpia algoritmejaon alan kirjallisuus pullollaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 197: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 190▼ Valintalajittelun (kasvavaan järjestykseen) idea:

1. lajiteltavan taulukon kaikki alkiot käydään läpi javalitaan niistä pienin,

2. vaihdetaan löytynyt pienin alkio oikealla paikalleen(ensimmäiseksi),

3. käydään taulukko uudelleen läpi samalla tavoin,mutta aloitetaan ensimmäisestä alkiosta, joka eivielä ole oikealla paikallaan,

4. vaihdetaan jäljellä olevista alkioista löytynyt pieninaloitusalkion kanssa ja

5. jatketaan, kunnes aloitusalkio on viimeinen alkio,joka tietysti on kaikkein suurin ja valmiiksi oikeallapaikallaan.

▼ Sama algoritmi osaisi tietysti lajitella alkiot myöspienenevään järjestykseen, kun vain valitaan ainavaihdettavaksi alkioksi kaikkein suurin alkio.

▼ Pienuus ja suuruus ovat algoritmin toiminnankannalta abstrakteja käsitteitä ➠ algoritmilla voilajitella mitä tahansa tietoalkioita, joille ohjelmoijaosaa määrätä jonkun suuruusjärjestyksen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 198: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 191▼ Algoritmikielellä valintalajittelu näyttää seuraavalta:

Algoritmi: Valintalajittelu

aloitusalkio← 0 // indeksointi alkaa nollasta

WHILE aloitusalkio < alkioiden määrä – 1

pienin← aloitusalkio // pienimmän indeksi

tutkittava← aloitusalkio + 1 // tutkittavan indeksi

WHILE tutkittava < alkioiden määrä

IF alkiot[tutkittava] < alkiot[pienin] THEN

pienin← tutkittava

tutkittava← tutkittava + 1

IF pienin != aloitusalkio THEN

vaihda alkiot[pienin] ja alkiot[aloitusalkio]

aloitusalkio← aloitusalkio + 1

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 199: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 192▼ Kuvallinen esimerkki: kokonaislukutaulukon valinta-

lajittelu kasvavaan järjestykseen:

aloitusalkio

aloitusalkio

aloitusalkio

aloitusalkio

aloitusalkio

aloitusalkio

aloitusalkio

aloitusalkio

pienin

pienin

pienin

pienin

pienin

pienin

pienin

1

1

1

1

1

1

1

1

2

2

2

2

2

2

2

2

3

3

3

3

3

3

3

3

4

4

4

4

4

4

4

4

5

5

5

5

5

5

5

5

6

6

6

6

6

6

6

6

7

7

7

7

7

7

7

7

8

8

8

8

8

8

8

8

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 200: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 193▼ Kokonaislukutaulukon valintalajittelu C++:lla:

#include <iostream>

using namespace std;

void Valintalajittele( int alkiot[ ], int koko);void TulostaTaulukko(int taulukko[ ], int koko);void Vaihda(int& a, int& b);

int main( ) {int taulukko[8] = { 4, 6, 5, 7, 8, 1, 2, 3 };

TulostaTaulukko(taulukko, 8);Valintalajittele( taulukko, 8);TulostaTaulukko(taulukko, 8);

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 201: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 194void Valintalajittele( int alkiot[ ], int koko) {

int aloitusalkio = 0;

while (aloitusalkio < koko – 1) {int pienin = aloitusalkio;int tutkittava = aloitusalkio + 1;

while (tutkittava < koko) {if ( alkiot[tutkittava] < alkiot[pienin] ) {

pienin = tutkittava;}++tutkittava;

}

if (pienin != aloitusalkio) {Vaihda(alkiot[pienin], alkiot[aloitusalkio] ) ;

}

++aloitusalkio;}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 202: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 195// Vaihtaa todellisten parametrien arvot keskenään.void Vaihda( int & a, int & b) {

int apu = a;a = b;b = apu;

}

void TulostaTaulukko(int taulukko[ ], int koko) {int i = 0;

while ( i < koko) {cout << taulukko[i] << " ";++i;

}

cout << endl;}

▼ Huomaathan, että varsinainen lajittelualgoritmitoimii muillakin tietotyypeillä kuin int, kunhan vainlaatikoidut osat koodia muutetaan oikeiksi:

1. int siksi tietotyypiksi, jonka tyyppisiä alkioitasisältävä taulukko halutaan lajitella ja

2. alkiot[tutkittava] < alkiot[pienin] vertaile-maan kahta kyseisen tietotyypin alkiota keskenään.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 203: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 196

Tiedon etsintä

▼ Lajittelun lisäksi toinen tärkeä ja usein vastaantulevatehtävä on tiedon etsintä jonkun osatiedonperusteella, esimerkiksi osoitteita saatettaisiinpostitussovelluksessa etsiä nimen perusteella.

▼ Etsinnän perusteena olevaa osatietoa kutsutaanjoskus hakuavaimeksi tai lyhyesti avaimeksi.

▼ Periaatteessa tietoa voitaisiin etsiä siten, että käydäänhakuaineistoa läpi järjestyksessä, kunnes

1. haluttu avain tulee vastaan tai

2. kaikki tieto on käyty läpi, jolloin tiedetään etteihaettu tieto ollut hakuaineistossa.

▼ Tällainen lineaarinen etsintä/haku on kuitenkintehotonta: pienellä miettimisellä havaitsee, että n:ntietoalkion joukosta täytyy keskimäärin tutkia n / 2

alkiota, ennen kuin haluttu alkio löytyy.

▼ Ikävin tapaus on se, jossa etsittävä tieto ei olehakuaineistossa: kaikki n alkiota pitää asiantoteamiseksi käydä turhaan läpi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 204: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 197▼ Lähtökohta tehokkaammalle tiedon etsinnälle

on, että tieto järjestetään johonkin erityiseenjärjestykseen, josta etsintä on nopeampaa.

▼ Yksinkertainen, mutta silti tehokas etsintäalgoritmi,on puolitushaku, joka vaatii toimiakseen, että tietoon hakuavaimen mukaan kasvavaan tai laskevaanjärjestykseen lajiteltua.

▼ Puolitushakualgoritmi pseudokoodina:

Algoritmi: Puolitushaku

vasen← 0

oikea← alkioiden määrä – 1

WHILE vasen ≤ oikea

keski← (vasen + oikea) / 2

IF alkiot[keski].avain == etsitty avain THEN

tieto löytyi taulukon kohdasta keski

ELSE IF alkiot[keski].avain < etsitty avain THEN

vasen← keski + 1

ELSE

oikea← keski – 1

etsittävä tieto ei ollut taulukossa

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 205: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 198▼ Kuvallinen esimerkki puolitushausta kokonaislu-

kuavaimilla: oletetaan että etsittävä avain on 4taulukosta, jossa on avaimet 0–10:

vasen

vasen

vasen

vasen

keski

keski

keski

keski

oikea

oikea

oikea

oikea

0

0

0

0

1

1

1

1

2

2

2

2

3

3

3

3

4

4

4

4

5

5

5

5

6

6

6

6

7

7

7

7

8

8

8

8

9

9

9

9

10

10

10

10

▼ Etsittävien alkioiden lukumäärä suunnilleen puolittuujokaisella hakukierroksella ➠ puolitushaku erittäintehokas isoillakin tietomäärillä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 206: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 199▼ Esimerkki puolitushausta merkkijonoavaimella:

#include <iostream>

#include <string>

using namespace std;

struct Nimi {string sukunimi;string etunimi;

};

const Nimi NIMET[ ] = {{ "Bubblebottom–SquarePants" , "Claire" },{ "Cheeks", "Sandy" },{ "Krabs", "Eugene" },{ "Neptune", "King" },{ "Plankton", "Sheldon J." },{ "Squarepants" , "Spongebob" },{ "Star" , "Patrick" },{ "Tentacles" , "Squidward" },

};

const int NIMIA = 8;const int TUNTEMATON = –1;const string LOPETUSKASKY = "loppu";

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 207: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 200// Etsii tiedot–taulukosta avainta hakuavain, jos löytyy,

// palauttaa löytökohdan indeksin, jos ei löydy,

// paluuarvo on vakio TUNTEMATON.int Puolitushaku( string hakuavain,

const Nimi tiedot[ ], int koko) {int vasen = 0;int oikea = koko – 1;

while (vasen <= oikea) {int keski = (vasen + oikea) / 2;

if ( tiedot[keski].sukunimi == hakuavain ) {return keski;

} else if ( tiedot[keski].sukunimi < hakuavain ) {vasen = keski + 1;

} else {oikea = keski – 1;

}}

return TUNTEMATON;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 208: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 201int main( ) {

string nimi;

cout << "Syötä sukunimi: ";cin >> nimi;

while (nimi != LOPETUSKASKY) {int indeksi = Puolitushaku(nimi, NIMET, NIMIA);

if (indeksi == TUNTEMATON) {cout << nimi << " tuntematon!" << endl;

} else {cout << NIMET[indeksi].etunimi << endl;

}

cout << "Syötä nimi: ";cin >> nimi;

}}

▼ Huomaa, että Puolitushaku-funktio on taas yleis-käyttöinen, kunhan laatikoidut kohdat muutetaantilanteeseen sopiviksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 209: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 202

Esimerkki

Ohjelman kuvaus

▼ Halutaan tehdä ohjelma, joka lukee annetustatiedostosta (koneen kovalevyltä) tuotteen nimi- jatuotekoodipareja, lajittelee ne nimen perusteellakasvavaan järjestykseen ja tallettaa lajitellussajärjestyksessä tulostiedostoon.

▼ Syötetiedoston rakenne on seuraava:– jokainen tuotekoodi–nimi-pari on omalla

rivillään kaksoispisteellä erotettuna:

tuotekoodi :nimi

– tiedoston rivit eivät välttämättä ole missäänerityisessä järjestyksessä,

– tuotekoodi on luku väliltä 10000–99999 ja

– tuotteen nimi on merkkijono, jossa voi olla mitätahansa merkkejä, paitsi ei kaksoispistettä.

▼ Tulostiedosto on rakenteeltaan vastaava, muttarivit ovat tuotteen nimen mukaisesti kasvavassajärjestyksessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 210: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 203▼ Esimerkiksi jos tiedosto tiedot.dat sisältää rivit:

10005:ruuvi (4mm)43406:mutteri (5mm)57008:prikka (5mm)99478:jatkojohto (3.5m)12345:akku (12V)43407:mutteri (3mm)

ja ohjelma suoritetaan:proffa> ./lajitteletuoterekisteriAnna syötetiedosto: tiedot.datAnna tulostiedosto: tulokset.datproffa>

niin tämän jälkeen tiedostossa tulokset.dat olisiseuraavassa järjestyksessä rivit:

12345:akku (12V)99478:jatkojohto (3.5m)43407:mutteri (3mm)43406:mutteri (5mm)57008:prikka (5mm)10005:ruuvi (4mm)

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 211: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 204Algoritmi

▼ Yleisellä tasolla ratkaisualgoritmi olisi mitäilmeisimmin seuraava:

Algoritmi: Lajittele tuoterekisteri

lue tiedot syötetiedostosta taulukkoon

lajittele taulukko tuotteen nimen mukaan

talleta lajiteltu taulukko tulostiedostoon

▼ Algoritmia kuuluisi tietysti vielä yksityiskohtaistaaroimasti, mutta jo tuollaisena se ilmentää kahtauutta toimenpidettä, jotka eivät vielä ole tuttuja:

1. tiedoston lukeminen ja

2. tiedostoon kirjoittaminen.

▼ Tehdään ohjelma tuon ylimalkaisen algoritminpohjalta, jotta näemme, mitä kaikkea tiedostojenkäsittelyyn liittyy.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 212: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 205Ohjelmakoodi

#include <iostream>

#include <fstream> // Tarvitaan tiedostojen käsittelyyn!

#include <string>

#include <cstdio> // EOF–vakio määritelty täällä

using namespace std;

// Tietotyyppien määrittelytstruct Tuote {

string nimi;int koodi;

};

/ / Vakioiden määrittelytconst int MAX_TUOTTEITA = 1000;const char EROTINMERKKI = ’:’;const int VIRHE = –1;

// Funktioiden esittelytint LueTuotteet(Tuote taulu[ ], int tilaa) ;bool TalletaTuotteet(Tuote taulu[ ], int maara);void LajitteleTuotteet(Tuote taulu[ ], int maara);void Vaihda(Tuote& t1, Tuote& t2);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 213: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 206int main( ) {

Tuote tuotteet[MAX_TUOTTEITA];int montako;

montako = LueTuotteet(tuotteet, MAX_TUOTTEITA);

if (montako != VIRHE) {LajitteleTuotteet( tuotteet, montako);

if ( !TalletaTuotteet(tuotteet, montako) ) {cerr << "Tietokannan talletus epäonnistui!"

<< endl;}

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 214: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 207int LueTuotteet(Tuote taulu[ ], int tilaa) {

string syotetiedoston_nimi;

cout << "Anna syötetiedosto: " ;getline(cin, syotetiedoston_nimi);

// Luodaan (input)tiedosto–olio (stream) ja

// sidotaan se syötetiedostoon.ifstream syotetiedosto(syotetiedoston_nimi.c_str( ) ) ;

/ / ifstream–tyyppinen muuttuja evaluoituu

// ehdossa epätodeksi jos tiedoston avaaminen

// ei jostain syystä onnistunut.if ( !syotetiedosto) {

cerr << "Syötetiedoston " << syotetiedoston_nimi<< " avaaminen epäonnistui!" << endl;

return VIRHE;}

int monesko = 0;

// Niin kauan kuin seuraava merkki

// ei ole tiedoston loppumerkki (EOF).while (syotetiedosto.peek( ) != EOF) {

// Jos tiedostossa oli enemmän rivejä

// kuin mitä taulussa on tilaa.if (monesko >= tilaa) {

cerr << "Liian monta tuotetta!" << endl;return VIRHE;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 215: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 208// Luetaan tuotekoodi.syotetiedosto >> taulu[monesko].koodi;

// Jos tiedostosta lukeminen epäonnistuu, niin

// stream–muuttujan arvo evaluoituu epätodeksi.if ( !syotetiedosto) {

cerr << "Rivillä virheellinen tuotekoodi!"<< endl;

return VIRHE;}

// Luetaan get–funktiolla seuraava merkki.

// Jos se ei ole kaksoispiste, niin rivi

// oli virheellinen.if (syotetiedosto.get( ) != EROTINMERKKI) {

cerr << "Rivillä virheellinen erotinmerkki!"<< endl;

return VIRHE;}

// Luetaan koko loppurivi tuotteen nimeksi.getline(syotetiedosto, taulu[monesko].nimi);

++monesko;}

// Kun tiedostoa ei enää tarvita, suljetaan se.syotetiedosto.close( );

return monesko;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 216: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 209bool TalletaTuotteet(Tuote taulu[ ], int maara) {

string tulostiedoston_nimi;

cout << "Anna tulostiedosto: " ;getline(cin, tulostiedoston_nimi) ;

ofstream tulostiedosto(tulostiedoston_nimi.c_str( ) ) ;

/ / ofstream–tyyppinen muuttuja evaluoituu ehdossa

// epätodeksi, jos tiedoston avaaminen ei onnistunut.if ( !tulostiedosto) {

return false;}

int i = 0;while ( i < maara) {

tulostiedosto << taulu[i].koodi << EROTINMERKKI<< taulu[i].nimi << endl;

// Jos tiedostoon kirjoitus epäonnistuu, niin

// stream–muuttujan arvo evaluoituu epätodeksi.if ( !tulostiedosto) {

return false;}

++i;}

tulostiedosto.close( );

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 217: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 210void LajitteleTuotteet(Tuote taulu[ ], int maara) {

int aloitusalkio = 0;

while (aloitusalkio < maara – 1) {int pienin = aloitusalkio;int tutkittava = aloitusalkio + 1;

while (tutkittava < maara) {if (taulu[tutkittava].nimi < taulu[pienin].nimi) {

pienin = tutkittava;}

++tutkittava;}

if (pienin != aloitusalkio) {Vaihda(taulu[pienin], taulu[aloitusalkio] ) ;

}

++aloitusalkio;}

}

void Vaihda(Tuote& t1, Tuote& t2) {Tuote apu = t1;t1 = t2;t2 = apu;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 218: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 211Siitä opittua

▼ Tiedostosta lukeminen ja tiedostoon kirjoittaminen(tarvittavat esitelyt: #include <fstream>).

▼ Yleisellä tasolla tiedostonkäsittelyn vaiheet ovat:

– avaaminen (stream-muuttujan alustaminen),

– käsittely (luku- ja kirjoitusoperaatiot) ja

– sulkeminen (close).

▼ Virhetilanteiden tunnistaminen ja niihin reagointitiedostojenkäsittelyn yhteydessä.

▼ Ajatus levytiedostosta »tietovirtana» (stream),johon operaatiot (luku ja kirjoitus) kohdistuvatsiihen kohtaan, jossa ollaan menossa.

▼ Virheilmoitusten tulostaminen cerr:iin.

▼ cin, cout ja cerr ovat valmiiksi alustettuja stream-tyyppisiä muuttujia: jokseenkin kaikki, mikä olisallittua niille, on myös sallittua ifstream- jaofstream-tyyppisille muuttujille ja kääntäen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 219: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 212

Tietovirran (stream) idea

▼ Usein ohjelmoidessa tulee tarve

– lukea ohjelman käyttöön tietoa, joka on talletet-tuna tiedostossa koneen kovalevyllä tai

– tallettaa ohjelman tuottamia tuloksia tiedostoonkovalevylle myöhempää käyttöä varten.

▼ Jotta ohjelma voisi käsitellä tiedostoja, täytyyohjelmointikielessä olla tapa esittää reaalimaailmanlevytiedosto (pätkä magneettiraitaa kovalevynpinnalla).

▼ Tavallisesti ohjelmointikielet ratkaisevat tämänongelman erityisellä tietotyypillä, joka tarjoaaoperaatiot tiedon lukemiseen ja kirjoittamiseen.

▼ C++:ssa ja monissa muissa ohjelmointikielissä tällaistatietotyyppiä kutsutaan tietovirraksi (stream).

▼ Itse asiassa tietovirran käsite on laajempi kuin pelkkäliittymä levytiedostoihin: kaikki ohjelman syötteet

ja tulosteet ovat tietovirtoja.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 220: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 213▼ Tietovirran voi määritellä jonona merkkejä, jotka

liikkuvat järjestyksensä säilyttäen yhteen suuntaan ➠

– ainoastaan syötevirran ensimmäisen merkin voilukea (operaatio get) ja

– ainoastaan tulostusvirran perään voi kirjoittaamerkin (operaatio put).

▼ Kaikki muut toimenpiteet voidaan toteuttaa get:in japut:in avulla.

▼ Merkkien järjestyksen säilyminen tietovirrassa onolennainen ominaisuus, esimerkiksi:

– Jos käyttäjä kirjoitaa näppäimistöltä merkkisarjan»abcdef», niin toki ohjelma syötevirtaa (cin)lukiessaan saa merkit käyttöönsä samassajärjestyksessä.

– Jos ohjelma kirjoittaa levytiedostoon sidottuuntulostusvirtaan merkkejä tietyssä järjestyksessä,niin toki on tarkoituksenmukaista, että merkittallettuvat tiedostoon juuri samassa järjestyksessä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 221: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 214▼ Tietovirrat ovat peräkkäissaantirakenteita: niiden

siirtämää tietoa voidaan käydä läpi vain siinäjärjestyksessä, jossa se on virrassa ➠ jos ohjelmaakiinnostaa käyttäjän näppäimistösyötteen viidesmerkki, niin ennen sen lukemista täytyy lukea neljäedeltävää merkkiä.

▼ Sama pätee oletusarvoisesti myös syötevirtaan, jokaon sidottu levytiedostoon: tiedosto on luettava läpijärjestyksessä alusta loppuun.

▼ Tosiasiassa levytiedostoja on mahdollista käsitellämyös hajasaantirakenteina, eli niiden sisältövoidaan lukea ja kirjoittaa hyppien sinne tänne.

▼ Yleensä tietovirta kulkee ohjelman ja jonkinoheislaitteen (näppäimistö, levytiedosto jne) välillä,mutta joskus myös kahden ohjelman välillä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 222: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 215

Tietovirrat ja niiden käyttö C++:ssa

▼ C++-kielessä tietovirrat esitetään tietotyyppeinä, jotkaovat toteutettu kirjastoissa:

#include <iostream>

istream syötevirrat jotka on yleensä valmiiksisidottu näppäimistöön (cin).

ostream tulostusvirrat jotka yleensä valmiiksisidottu näyttöön (cout ja cerr).

#include <fstream>

ifstream syötevirrat jotka käyttäjän on itsesidottava levytiedostoon.

ofstream tulostusvirrat jotka käyttäjän on itsesidottava levytiedostoon.

#include <sstream>

istringstream syötevirrat jotka käyttäjän on itsesidottava merkkijonoon.

ostringstream tulostusvirrat joiden avulla voidaan»tulostaa» merkkijonoon.

▼ Ohjelmoijan ei tarvitse huolehtia cin:in, cout:in jacerr:in sitomisesta: ne ovat #include <iostream>:injälkeen automaattisesti käytettävissä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 223: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 216▼ Tietovirtojen käyttö koostuu yleensä kolmesta

vaiheesta (cin, cout ja cerr siis poikkeuksia):

1. alustaminen (avaaminen, sitominen),

2. käsittely (eli operointi: luku, kirjoitus jne) ja

3. sulkeminen.

▼ Ennen fstream- ja sstream-kirjastojen tarjoamillatietovirroilla operointia, ne on alustettava (vaihe 1):

ifstream Luodaan ifstream-tyyppinen muuttuja jakerrotaan, minkä nimisestä tiedostosta syöteluetaan:

ifstream virran_nimi( tiedoston_nimi) ;

ofstream Luodaan ofstream-tyyppinen muuttuja jakerrotaan, minkä nimiseen tiedostoon syötekirjoitetaan:

ofstream virran_nimi( tiedoston_nimi) ;

istringstream Luodaan istringstream-muuttuja ja kerro-taan merkkijono, josta syöte luetaan:

istringstream virran_nimi(merkkijono) ;

ostringstream Luodaan ostringstream-muuttuja:

ostringstream virran_nimi;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 224: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 217▼ Edellisessä taulukossa tiedoston_nimi ei ole string-

tyyppinen, vaan vanhempi C-kielestä periytyvämerkkijonotyyppi ➠ ohjelmoijan on annettavatiedoston nimi oikean tyyppisenä:

string tiedoston_nimi;cin >> tiedoston_nimi;ifstream tiedosto(tiedoston_nimi.c_str( ) ) ;

c_str( )-funktio palauttaa string-tyyppistä merkki-jonoa vastaavan C-yhteensopivan merkkijonon.

▼ Tiedoston_nimi voi olla myös merkkijonoliteraali:

ifstream tiedosto("syotteet.txt") ;

▼ Alustettuun tietovirtaan voi sitten soveltaa erioperaatioita riippuen sen tyyppistä ja siitä, onko sesyöte- vai tulostusvirta (vaihe 2).

▼ Tietovirroilla operointi on hiukan sekavaa, koskaoperaatioiden merkintätapoja on useita:

operaattorit: cout << "kukkuu";funktiot: getline(cin, mjono);jäsenfunktiot: cout.put(’a’) ;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 225: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 218▼ Operaatiot, jotka voidaan kohdistaa kaiken tyyppisiin

tulostusvirtoihin (esimerkkinä käytetty cout:ia):

cout << arvo << endl Tulostetaan lausekkeen arvo

virtaan: arvo voi olla tyypiltäänperustietotyyppi tai string. Rivin-vaihto saadaan tulostettua endl:navulla.

cout.put(merkki) Tulostetaan yksi merkki (char)virtaan.

cout << setw( leveys) ja kaikki muut sivulla 77 esitellyttulostuksen ohjauskomennot ovatkäytettävissä, kunhan muistaasanoa #include <iomanip>.

▼ Lisäksi ostringstream-tyyppiseen virtaan voidaankohdistaa operaatio:

virta .str( ) Palauttaa kaiken virtaan tulostetuntiedon merkkijonona (string).

▼ Olennaisia tulostukseen liittyviä operatioita ei oletämän enempää: melkein kaiken saa hoidettua<<-operaattorilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 226: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 219▼ Operaatiot, jotka voidaan kohdistaa kaiken tyyppisiin

syötevirtoihin (esimerkkinä käytetty cin:iä):

cin >> muuttuja Luetaan virrasta seuraava sana, tulki-taan se muuttujan tyyppiseksi arvoksi jatalletetaan arvo muuttujaan, joka voi ollatyypiltään perustietotyyppi tai string.

cin.get( ) Lukee ja palauttaa virran seuraavanmerkin. Syötteen lopussa paluuarvo EOF.

cin.get(merkki) Lukee virrasta seuraavan merkin muut-tujaparametriin merkki, jonka on oltavatyypiltään char.

getline(cin, str ) Lukee virrasta rivin tekstiä ja tallettaa senstring-tyyppiseen muuttujaparametriin str.

getline(cin, str, chr )Kuten edellä, mutta lukee vain ensimmäi-seen vastaantulevaan merkkiin chr saakka.

cin.ignore(montako, merkki)Lukee virtaa korkeintaan montako merkkiätai kunnes vastaan tulee ensimmäinenmerkki. Heittää luetut merkit menemään.Montako on tyypiltään int ja merkki char.

cin.peek( ) Paluuarvona on seuraava syötevirrassaoleva merkki. Merkkiä ei lueta poisvirrasta, vaan seuraava lukuoperaatiopalauttaa myös sen. Syötteen lopussapaluuarvo EOF.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 227: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 220▼ Joskus on tarve hypätä virran lukukohdasta

sanavälimerkkien (välilyönnit, rivinvaihdot) ohi:cin >> ws; // Heitetään sanavälimerkit menemään.

jossa ws on samankaltainen ohjauskomentosyötevirroille kuin mitä sivulla 77 on kerrottutulostusvirtojen ohjauskomennoista.

▼ Kun virtaa ei ohjelmassa enää tarvita, se on syytäsulkea (vaihe 3), sillä muuten se jää kuluttamaanjärjestelmän rajallisia resursseja.

▼ Virran sulkeminen voi tapahtua kahdella tavalla:

1. Jos virta on paikallinen muuttuja, C++ sulkeesen automaattisesti, kun sen määrittelylohkostapoistutaan.

2. Tarvittaessa virran voi myös sulkea »käsin»close-jäsenfunktiolla:

ifstream tietokanta("puhelinnumerot.dat");...

/ / Virralla operointi tässä välissä...

tietokanta.close( ) ;

▼ Kun virta on suljettu, sillä ei enää voi operoida, paitsitietenkin, jos sen alustaa uudelleen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 228: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 221

Tietovirtaongelmien havaitseminen

▼ Tietovirroilla operoitaessa voi törmätä seuraavantyyppisiin ongelmatilanteisiin:

1. Yritetään tulostaa tietoa tulostusvirtaan ja epäon-nistutaan (esim. täydelle levylle kirjoittaminen).

2. Yritetään lukea syötevirrasta tietoa, vaikka kaikkion jo luettu (esim. levytiedosto luettu loppuun).

3. Syötevirrasta yritetään lukea väärän tyyppistätietoa (esim. odotetaan näppäimistöltä kokonais-lukua, mutta käyttäjä naputteleekin kirjaimia).

▼ Ongelmien havaitseminen on kuitenkin helppoa,kun tietää seuraavat yksityiskohdat:

1. Kaikkien edellä esiteltyjen tietovirtoihin kohdistu-vien operaatioiden➀ tuloksena evaluoituu se virta,johon operaatio kohdistui.

2. Ehtolausekkeena käytetyn virran arvoksi evaluoituutosi vain, jos sille viimeksi tehty operaatio➁

onnistui.

➀ Paitsi ei peek( ) ja parametriton get( ) .➁ Myös alustus. ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 229: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 222▼ Tämän pohjalta voidaan esittää seuraavat hyödylliset

mallit erilaisten poikkeustilanteiden käsittelystä.

▼ Sidotaan syötevirta levytiedostoon ja luetaan se läpirivi kerrallaan:

ifstream tied("tuotteet.dat") ;

if ( ! tied ) {cerr << "Avaaminen epäonnistui!" << endl;return VIRHE; // Tai tilanteesta riippuen...

}

string rivi;while ( getline(tied, rivi) ) {

...

// Tässä luetulle riville tehdään jotain...

}

▼ Väärän tyyppisen syötteen havaitseminen:cout << "Syötä luku: ";int luku;while ( ! (cin >> luku) ) {

cerr << "Virheellinen syöte, yritä uudelleen!"<< endl;

cin.clear( ) ;cin.ignore(1000, ’\n’) ;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 230: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 223▼ Edellisessä kohdassa oli käytetty virhetilanteesta

»parantumiseen» jäsenfunktiota clear( ) .

▼ Aina, kun tietovirtaa käsitellessä tapahtuu virhe,niin virta menee tilaan, jossa mitkään laillisetkaanoperaatiot eivät enää toimi ➠ joskus tästä tilastapäästään pois clear( )-funktiolla, jonka kutsunjälkeen voidaan (yrittää) jatkaa normaalisti.

▼ Joskus virhe on niin paha, ettei sitä voi clear( ) :llakorjata (esim. levytiedosto luettu loppuun).

▼ Kuinka erottaa toisistaan virran loppuminen ja jokumuu virhetilanne:

while ( getline(virta, rivi) ) {...

}

if ( !virta.eof( ) ) {// Lukeminen epäonnistui jostain muusta// syystä kuin virran loppuminen... virhe

}

▼ Jäsenfunktio eof( ) palauttaa arvon tosi vain, josvirrasta on yritetty lukea sen loputtua.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 231: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 224▼ Myös esimerkkiohjelmassa (s.207) käytetty seuraavan

merkin kurkistaminen peek( ) -jäsenfunktiolla onjoskus käyttökelpoinen tapa päätellä, onko syöte joluettu loppuun vai ei.

▼ Viimeisenä esimerkkinä, kuinka lukea läpi syötevirta,joka muodostuu riveistä:

puhelinnumero1 nimi1puhelinnumero2 nimi2

... ...

▼ Seuraava koodinpätkä havainnollistaa asian:

int numero;string nimi;

while (virta >> numero && getline(virta, nimi) ) {// Käsitellään luettu numero ja nimi...

}

if ( !virta.eof( ) ) {// Virheellinen rivi syötevirrassa...

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 232: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 225

Standardivirrat cin, cout ja cerr

▼ Virrat cin, cout ja cerr ovat ilman muita alustuksiaohjelmoijan käytettävissä #include <iostream>:injälkeen.

▼ cin:iä ja cout:ia käytetään tuttuun tapaan näppäi-mistösyötteen lukemiseen ja näytölle tulostamiseen.

▼ cerr toimii aivan samoin kuin cout, mutta sinne ontarkoitus tulostaa vain ohjelman virheilmoituksia.

▼ Kaikki muut tulosteet laitetaan cout:iin.

▼ Noudata tätä käytäntöä myös omissa ohjelmissasi!

▼ Tuohon käytäntöön on ihan oikea syykin, muttasiitä voidaan jutella joko harjoituksissa tai kurssillaOhjelmointi II.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 233: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 226

Tietovirta funktion parametrina

▼ Tärkein asia joka pitää muistaa, jos haluaa antaafunktiolle parametrina tietovirran: muodollisen

parametrin pitää olla viite- eli muuttujaparametri.

▼ Tuo on järkeenkäypä vaatimus, sillä jos funktio operoitietovirralla, niin virtahan muuttuu ➠ muutoksen onvälityttävä myös todelliseen parametriin.

▼ Pääsääntöisesti todellisen parametrin pitää ollasamaa tyyppiä kuin funktion muodollinen parametri,paitsi jos:

muodollisen para-

metrin tyyppi on

niin todellinen parametrin

tyyppi saa olla myös

istream& ifstream tai istringstream

ostream& ofstream tai ostringstream

▼ Käytännössä tuo mahdollistaa yleiskäyttöisempienfunktioiden kirjoittamisen: sama funktio voi operoidaerityyppisillä virroilla.

▼ Miten ja miksi tämä on mahdollista, siitä enemmänOhjelmointi II -kurssilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 234: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 227▼ Tyydytään tässä pieneen esimerkkifunktioon:

int LueLuku(istream& virta) {int luku;virta >> luku;if ( !virta ) {

return VIRHE;} else {

return luku;}

}

nyt funktiota voitaisiin kutsua eri tyyppisilläsyötevirroilla eli lukea samalla funktiolla syötettäesimerkiksi näppäimistöltä:

int numero;numero = LueLuku(cin);

tiedostosta:

ifstream tietokanta("syoteluvut.txt") ;int numero;numero = LueLuku(tietokanta);

tai merkkijonosta:

istringstream lukujono("12345 67890 101112");int numero;numero = LueLuku(lukujono);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 235: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 228

Esimerkki

Ohjelman kuvaus

▼ Tässä esimerkissä on ajateltu, että käyttäjä ylläpitääkäsin jonkin editorin (Jed, Emacs) avulla yksinkertaistakalenteritiedostoa, jonka rivit ovat muodossa:

päivä/kuu/vuosi :kalenterimerkintä

▼ Lisäksi tiedostossa voi olla #-merkillä alkaviakommenttirivejä ja tyhjiä rivejä, joille ei ole tarkoitustehdä mitään.

▼ Kelvollinen tiedosto voisi näyttää seuraavalta:

################################### Tämä tiedosto sisältää kalenterini. #################################### Kevätlukukausi1/5/2016:Vappu.

# Syyslukukausi22/7/2016:Valmistaudu henkisesti opintoihin.2/11/2016:Aika alkaa lukea tenttiin.24/12/2016:Joulupukki tulee.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 236: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 229▼ Toteutetaan ohjelma, joka tulostaa kalenteritiedoston

hiukan siistimmässä asussa näytölle.

▼ Esimerkiksi, jos edellä havainnollistuksena käytettytiedosto haluattaisiin tulostaa ohjelmalla, näyttäisisuoritus seuraavalta:

proffa> ./kalenteriAnna kalenteritiedoston nimi: kalenteri.txt01.05.2011 Vappu.22.07.2011 Valmistaudu henkisesti opintoihin.02.11.2011 Aika alkaa lukea viimeiseen tenttiin.24.12.2011 Joulupukki tulee.proffa>

▼ Ohjelma siis ei tee muuta kuin muokkaa päivämää-rien tulostusasua, jotta kaikki kalenteritapahtumattulostuvat selkeästi sarakkeisiin.

▼ Tulostusasun muokkaaminen iomanip-kirjastonavulla ei ole mitään uutta, joten ei kannatahämääntyä siitä ➠ tehtävään kätkeytyy montamuuta uutta pikku ideaa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 237: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 230Ohjelmakoodi

#include <iostream>

#include <iomanip>

#include <fstream>

#include <sstream> // istringstream

#include <cstdio> // EOF–vakio

#include <string>

using namespace std;

struct Kalenteritapahtuma {int paiva;int kuu;int vuosi;string merkinta;

};

enum Virhekoodi {// Ei virhettä.OK,

// Virheet jotka liittyvät rivin paloitteluun.LIIKAA_KENTTIA,PUUTTUVA_EROTIN,

// Virheet jotka liittyvät tiedoston lukemiseen.TIEDOSTO_EI_AUKEA,VIRHEELLINEN_PAIVA,VIRHEELLINEN_KUU,VIRHEELLINEN_VUOSI,LIIAN_MONTA_TAPAHTUMAA

};

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 238: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 231

// Seuraavassa tyyppimäärittelyssä kuvattua

// enum–tyyppiä on tarkoitus käyttää myöhemmin

// ovelasti const –vakioiden korvikkeena.

enum Kentta {// Kenttien järjestysnumerot.PAIVA = 0,

KUU = 1,VUOSI = 2,

MERKINTA = 3};

const int MAX_TAPAHTUMIA = 100;const int KENTTIA = 4;

const char KOMMENTTI = ’#’;

Virhekoodi LueTapahtumat(Kalenteritapahtuma taulukko[ ], int tilaa,

int& montako_luettu);

void TulostaTapahtumat(Kalenteritapahtuma taulukko[ ], int montako) ;void TulostaTapahtuma(Kalenteritapahtuma tapahtuma);

Virhekoodi PaloitteleString(string mjono, string erottimet,string kentat[ ], unsigned int tilaa);

bool MuutaStringIntiksi(string mjono, int& tulos) ;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 239: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 232int main( ) {

Kalenteritapahtuma tapahtumat[MAX_TAPAHTUMIA];int tapahtumien_lukumaara = 0;

Virhekoodi status = LueTapahtumat(tapahtumat, MAX_TAPAHTUMIA,tapahtumien_lukumaara);

switch ( status ) {case OK:

TulostaTapahtumat(tapahtumat, tapahtumien_lukumaara);break;

case LIIKAA_KENTTIA:cerr << "Rivillä liian monta kenttää." << endl;break;

case PUUTTUVA_EROTIN:cerr << "Riviltä puuttui erotinmerkki." << endl;break;

case TIEDOSTO_EI_AUKEA:cerr << "Tiedostoa ei saa avattua." << endl;break;

case VIRHEELLINEN_PAIVA:cerr << "Päivä ei ole numero." << endl;break;

case VIRHEELLINEN_KUU:cerr << "Kuu ei ole numero." << endl;break;

case VIRHEELLINEN_VUOSI:cerr << "Vuosi ei ole numero." << endl;break;

case LIIAN_MONTA_TAPAHTUMAA:cerr << "Tiedostossa liian monta tapahtumaa." << endl;break;

default:cerr << "Tuntematon virhe???" << endl;break;

}} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 240: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 233Virhekoodi LueTapahtumat(Kalenteritapahtuma taulukko[ ], int tilaa,

int& montako_luettu) {

cout << "Anna kalenteritiedoston nimi: ";string tiedoston_nimi;

getline(cin, tiedoston_nimi);

ifstream tiedosto(tiedoston_nimi.c_str( ) ) ;if ( ! tiedosto ) {

return TIEDOSTO_EI_AUKEA;

}

Virhekoodi paluuarvo = OK;montako_luettu = 0;

string rivi;

while ( getline(tiedosto, rivi) ) {

if ( rivi.empty( ) | | rivi.at(0) == KOMMENTTI ) {continue;

}

string kentat[KENTTIA];

Virhekoodipaloittelustatus = PaloitteleString(rivi, " //:", kentat, tilaa);

if ( paloittelustatus != OK ) {paluuarvo = paloittelustatus;

break;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 241: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 234int paiva_arvo;if ( ! MuutaStringIntiksi(kentat[PAIVA], paiva_arvo) ) {

paluuarvo = VIRHEELLINEN_PAIVA;break;

}

int kuu_arvo;if ( ! MuutaStringIntiksi(kentat[KUU], kuu_arvo) ) {

paluuarvo = VIRHEELLINEN_KUU;break;

}

int vuosi_arvo;if ( ! MuutaStringIntiksi(kentat[VUOSI], vuosi_arvo) ) {

paluuarvo = VIRHEELLINEN_VUOSI;break;

}

if ( montako_luettu >= tilaa ) {paluuarvo = LIIAN_MONTA_TAPAHTUMAA;break;

}

taulukko[montako_luettu].paiva = paiva_arvo;taulukko[montako_luettu].kuu = kuu_arvo;taulukko[montako_luettu].vuosi = vuosi_arvo;taulukko[montako_luettu].merkinta = kentat[MERKINTA];

++montako_luettu;}

tiedosto.close( ) ;

return paluuarvo;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 242: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 235void TulostaTapahtumat(Kalenteritapahtuma taulukko[ ], int montako) {

for ( int i = 0; i < montako; ++i ) {TulostaTapahtuma(taulukko[i] ) ;

}}

void TulostaTapahtuma(Kalenteritapahtuma tapahtuma) {cout << right << setfill(’0’)

<< setw(2) << tapahtuma.paiva << "."<< setw(2) << tapahtuma.kuu << "."<< tapahtuma.vuosi << " "<< tapahtuma.merkinta << endl;

}

// Funktio paloittelee mjono:n osiin järjestyksessä

// erottimet–merkkijonon merkkien kohdilta. Saadut

// osamerkkijonot talletetaan taulukkoon kentat, jossa on

// tilaa kappaletta alkioita. Paluuarvo kertoo, päättyikö

// prosessi onnistuneesti (OK), oliko erottimet liian

// pitkä verrattuna kentat–taulukon kokoon (LIIKAA_KENTTIA)

// tai puuttuiko mjono:sta jokin erottimet–merkkijonon

// määräämistä erotinmerkeistä (PUUTTUVA_EROTIN).

Virhekoodi PaloitteleString(string mjono, string erottimet,string kentat[ ], unsigned int tilaa) {

// Jos erotinmerkkejä on niin paljon, että paloitellut osat

// eivät voi mahtua kentat–taulukkoon.if ( erottimet.length( ) + 1 > tilaa ) {

return LIIKAA_KENTTIA;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 243: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 236unsigned int kenttia_loytynyt = 0;

string::size_type alkukohta = 0;string::size_type erotinkohta;

// Käydään kaikki kenttiä erottavat merkit järjestyksessä läpi.while ( kenttia_loytynyt < erottimet.length( ) ) {

// Etsitään käsittelyvuorossa olevaa erotinmerkkiä

// kentän alkukohdasta eteenpäin.

erotinkohta= mjono.find(erottimet.at(kenttia_loytynyt), alkukohta) ;

// Etsittyä erotinmerkkiä ei löydy.if ( erotinkohta == string::npos ) {

return PUUTTUVA_EROTIN;}

// Kentän teksti on nyt alkukohdan ja erotinkohdan

// välissä oleva osa mjono–merkkijonosta.

kentat[kenttia_loytynyt]= mjono.substr(alkukohta, erotinkohta – alkukohta) ;

// Seuraava kenttä alkaa erotinmerkkiä

// seuraavasta merkistä.alkukohta = erotinkohta + 1;

++kenttia_loytynyt;}

// Viimeisen kentän perässä ei ole erotinmerkkiä: se on

// koko viimeistä erotinmerkkiä seuraava loppurivi.

kentat[kenttia_loytynyt] = mjono.substr(alkukohta) ;

return OK;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 244: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 237// Funktio muuttaa merkkijonossa mjono olevat numeromerkit

// vastaavaksi int–tyyppiseksi arvoksi ja tallentaa tuloksen

// viiteparametriin tulos. Jos mjono koostui pelkistä

// numeromerkeistä (alussa saa olla etumerkki ja alussa sekä

// lopussa saa olla isspace–merkkejä), paluuarvoksi tulee true.

// Jos mjono sisälsi mitään muuta, paluuarvoksi tulee false.

bool MuutaStringIntiksi(string mjono, int& tulos) {istringstream virta(mjono);

// >>–operaattori hyppää aluksi sanavälimerkit automaattisesti

// yli, joten niistä ei tarvitse murehtia erikseen.

virta >> tulos;

// Jos int–arvon lukeminen virrasta epäonnistui.if ( ! virta ) {

return false;}

// Heitetään lukua mahdollisesti seuraavat sanavälit menemään.

virta >> ws;

// Nyt vastassa pitäisi olla EOF, muuten rivin

// lopussa oli jotain turhaa.

if ( virta.peek( ) == EOF ) {return true;

} else {return false;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 245: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 238Siitä opittua

▼ Luettelo- eli enum-tyypit: ohjelmoija määrää tyypinlailliset alkiot.

▼ Joissain (melko tiukasti rajatuissa) tilanteissa ehdollistasuoritusta saadaan aikaan switch-rakenteella.

▼ for-silmukkarakenne on vaihtoehto while-rakenteelletoiston aikaansaamisessa.

▼ break- ja continue-käskyillä silmukkarakenteidensuoritusta voidaan hienosäätää (mutta näistä on jopuhuttu aiemmin).

▼ break-käskyä käytetään myös switch-rakenteensuorituksen lopettamiseen.

▼ Ohjelma sisältää myös realistisen esimerkinistringstream-virtatyyppin käytöstä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 246: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 239

Luettelo- eli enum-tyypit

▼ Luettelotyyppi on tietotyyppi (vrt.s.46), jonka kaikkialkiot ovat käyttäjän määräämiä.

▼ C++:ssa määrittely varatulla sanalla enum:

enum tyypin_nimi { alkio1, ... , alkion } ;

joka määrittelee uuden tyypin tyypin_nimi, johonkuuluvat alkiot alkio1, ... ja alkion.

▼ Alkiot muistuttavat käyttäytymiseltään kokonaislu-

kuvakioita, joiden arvot C++-kääntäjä määritteleeautomaattisesti: alkio1 = 0, alkio2 = 1 ja niin edelleen.

▼ Tarvittaessa ohjelmoija voi määrätä alkioiden arvot:

enum tyypin_nimi { alkio1 = arvo1, ... , alkion = arvon } ;

▼ Jos numeroinnin lopettaa kesken, niin loput alkiot

C++ numeroi automaattisesti siten, että seuraavaalkio on arvoltaan aina yhtä isompi kuin edellinen:

// PUN← 8, VIH← 9, SIN← –1 ja KEL← 0enum Vari { PUN = 8, VIH, SIN = –1, KEL } ;

▼ Kahdella tai useammalla alkiolla voi olla sama arvo.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 247: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 240▼ Luettelotyypin alkioita voi käyttää kaikkialla, mihin

sopisi kokonaisluku- tai char-tyyppinen arvo ➠ alkio

tulkitaan sitä vastaavaksi kokonaisluvuksi.

▼ Luettelo- ja kokonaislukutyyppisellä tiedolla voirauhassa operoida keskenään ikään kuin ne olisivatkeskenään samaa tyyppiä.

▼ Luettelotyyppisen tietoalkion paikalla ei kuitenkaanvoi sijoituslauseessa tai funktiokutsun todellisenaparametrina käyttää kokonaislukuarvoa ilmaneksplisiittistä tyyppikonversiota:

enum Vuodenaika { TALVI, KEVAT, KESA, SYKSY } ;

void Tulosta(Vuodenaika neljannes);

int luku = KESA; // luku← 2

// vast← KESAVuodenaika vast = static_cast<Vuodenaika>(luku);

// Tulosta(KESA);Tulosta(static_cast<Vuodenaika>(luku) );

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 248: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 241

switch-rakenne

▼ switch-rakenteella saadaan aikaan ehdollistasuoritusta tilanteissa, joissa

1. testattava arvo on tulkittavissa kokonaisluvuksi(int, char tai enum).

2. vaihtoehdot, joihin testattavaa arvoa vertaillaan,ovat kokonaisluvuiksi tulkittavissa olevia vakioita.

➠ C++:n switch ei ole yhtä joustava kuin if–else.

▼ Tiettyihin tilanteisiin se kuitenkin sopii erinomaisesti.

▼ switch-rakenne näyttää seuraavalta:

switch ( testattava_arvo ) {case vaihtoehto1 :

käskyt1 ;break ;

...case vaihtoehton :

käskytn ;break ;

default :käskytdef ;break ;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 249: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 242▼ switch vertaa testattavaa arvoa järjestyksessä

vaihtoehtoihin.

▼ Kun vastaan tulee vaihtoehto, joka on yhtäsuurikuin testattava arvo, niin suoritetaan vastaavaancase-haaraan liittyvät käskyt.

▼ Jos mikään vaihtoehto ei täsmää, suoritetaandefault-haaran käskytdef.

▼ default voi puuttua ➠ on mahdollista, ettäswitch-rakenne ei tee mitään.

▼ Kun suoritettava haara on kerran valittu, suoritusjatkuu, kunnes törmätään break-käskyyn.

▼ break keskeyttää switch-rakenteen suorituksen ➠suoritus jatkuu rakenteen perästä.

▼ Mikäli jostain haarasta puuttuu break, niin suoritus»putoaa» seuraavan haaran puolelle.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 250: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 243▼ Tätä ominaisuutta käytetään usein hyväksi silloin,

kun useaan vaihtoehtoon liittyy samat toiminnot:

switch ( vastaus ) {case ’e ’ :case ’E’ :

suoritettavat toiminnot vastauksen ollessa e tai E

break;...

}

▼ break:in voi jättää pois, mikäli haarasta(tarkemmin: koko funktiosta) poistutaan return:illa:

switch ( kuukausi ) {case 1:

return "tammikuu";case 2:

...case 12:

return "joulukuu";default :

return "virhekuu";}

▼ Esimerkkiohjelmassa tätä ei käytetty hyväksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 251: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 244

for-silmukka

▼ for-silmukan yleinen muoto on:

for (alustus ; ehto ; kasvatus ) {runko ;

}

▼ Alustus suoritetaan vain kerran, juuri ennen kuinehtoa testataan ensimmäistä kertaa.

▼ Kuten while-silmukassakin ehto testataan ainaennen rungon suorittamista.

▼ Jos ehdon arvoksi evaluoituu true, niin suoritetaanrungon käskyt.

▼ Jos ehto on false, niin jatketaan silmukkaa seuraavastakäskystä.

▼ Kun kaikki rungon käskyt on tehty (saavutaanloppuaaltosulkuun), niin suoritetaan kasvatus japalataan takaisin testaamaan ehtoa.

▼ On mahdollista ettei runkoa suoriteta kertaakaan:jos ehto on heti alussa false.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 252: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 245

do–while-silmukka

[bonus: ei esimerkkohjelmassa]

▼ C++:ssa on kolmaskin silmukkarakenne while- jafor-rakenteiden lisäksi.

▼ do–while-silmukan yleinen muoto on:

do {runko ;

} while ( ehto ) ;

▼ Runko koostuu yhdestä tai useammasta käskystä,jotka suoritetaan ainakin kerran.

▼ Jos ehdon arvoksi evaluoituu rungon suorituksenjälkeen true, niin suoritetaan runko uudelleen.

▼ Jos ehdon arvoksi evaluoituu false, niin jatketaansilmukkaa seuraavasta käskystä.

▼ do–while-silmukalle ei ole niin paljon käyttöä kuinmuille silmukkarakenteille, mutta sen olemassaolostaon hyvä olla tietoinen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 253: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 246

break, continue ja silmukat

▼ Silmukan rungon suoritus voidaan keskeyttääbreak- ja continue-käskyillä:

break

lopettaa silmukan suorituksen välittömästi jajatkaa silmukkaa seuraavasta käskystä.

continue

aloittaa uuden silmukan kierroksen(hyppää rungon loppusulkuun).

▼ Käskyt vaikuttavat vain sen sisimmän silmukantoimintaan, jonka sisällä ne suoritetaan.

▼ Tapahtumien kulku eri silmukkarakenteissa:

while-silmukka:

ehto runkotrue

false break

continue

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 254: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 247do–while-silmukka:

ehtorunko

true

false

break

continue

for-silmukka:

ehto runkoalustus

kasvatus

true

false break

continue

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 255: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 248

Käskyt −→←− tieto

▼ Tietokoneohjelmat koostuvat tiedosta ja silläoperoivista toimenpiteistä eli käskyistä (s.46).

▼ Todellisuudessa jako ei ole noin selvärajainen, vaanjoissain tilanteissa tieto voi korvata osan käskyistä taipäinvastoin.

▼ Tätä käytetään hyväksi nk. tieto-ohjatussa suunnitte-lussa ja ohjelmoinnissa (data-driven/data-directed

design/programming).

▼ Tieto-ohjatun ohjelmoinnin idea on suunnitellaja toteuttaa ohjelmaan tietorakenteita, joidenavulla tietoa käsittelevien käskyjen määrä saadaanpienemmäksi ➠ korvataan käskyjä tiedolla.

▼ Tämä kaikki on helpompi ymmärtää muutamanesimerkin avulla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 256: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 249▼ Ajatellaan aluksi funktiota, jossa ei ole hyödynnetty

tieto-ohjatun ohjelmoinnin filosofiaa:enum Osavaltio {

AK, AL, AR, AZ, CA, CO, CT, DE, FL, GA,HI, IA, ID, IL, IN, KS, KY, LA, MA, MD,ME, MI, MN, MO, MS, MT, NC, ND, NE, NH,NJ, NM, NV, NY, OH, OK, OR, PA, RI, SC,SD, TN, TX, UT, VA, VT, WA, WI, WV, WY

};...

/ / Myöhemmin samassa ohjelmassa:// funktio, joka muuttaa osavaltiokoodin nimeksi.string OsavaltioNimeksi(Osavaltio osav) {

switch (osav) {case AK:

return "Alaska";case AL:

return "Alabama";...

92 riviä poistettu tilan säästämiseksi...

case WV:return "West Virginia" ;

case WY:return "Wyoming";

default:return "Virheellinen osavaltiokoodi" ;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 257: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 250▼ Sama ohjelman osa tieto-ohjatun ohjelmoinin

periaatteita soveltaen:enum Osavaltio {

...sama kuin edellisessä

...};

struct OsavaltioInfo {Osavaltio koodi;string nimi;

};

const OsavaltioInfo INFO[ ] = {{ AK, "Alaska" },{ AL, "Alabama" },

...46 riviä poistettu tilan säästämiseksi

...{ WV, "West Virginia" },{ WY "Wyoming" },

};const int MONTAKO = 50;...

string OsavaltioNimeksi(Osavaltio osav) {for (int i = 0; i < MONTAKO; i++) {

if (INFO[i].koodi == osav) {return INFO[i].nimi;

}}return "Virheellinen osavaltiokoodi" ;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 258: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1100 Ohjelmointi I 251▼ Näiden kahden esimerkin ero on selvä: kun nähtiin

hiukan vaivaa sopivan tietorakenteen suunnitelussaja alustamisessa, niin varsinainen OsavaltioNimeksi-funktio supistui minimaaliseksi.

▼ Jos tietorakenne on sopivasti/hyvin suunniteltu, siitäkoituva hyöty voi moninkertaistua uudelleenkäytet-tävyytenä (esim. NimiOsavaltioksi-funktio).

▼ Toteutustekniikkana on aina (tavalla tai toisella)etukäteen prosessoitu informaatio, joka muodostuulähtöarvoista ja niistä seuraavasta lopputuloksesta.

▼ Tieto-ohjatun ohjelmoinnin hyötyjä ovat:

1. Syntyvät ohjelmat ovat yleensä lyhyempiä, muttaniiden selkeys ei silti kärsi.

2. Virheiden mahdollisuus pienenee.

3. Ohjelmien laajennettavuus ja ylläpidettävyys onhelpompaa.

▼ Varma merkki tieto-ohjatun uudelleensuunnitteluntarpeesta ohjelmassa on liian pitkäksi kasvava if- taiswitch-rakenne.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 259: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150Ohjelmointi II

syksy 2013

Luentomoniste

Ari [email protected]

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 260: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 252

Esimerkki: vector-tyyppi

▼ Tutkitaan ennen varsinaiseen asiaan siirtymistäesimerkki vector-kirjastotyypin käytöstä.

▼ Esimerkki johdattelee Standard Template Library

(STL) -kirjaston perusajatuksiin, jotta perässäseuraava laajempi osa asiaa olisi ymmärrettävämpää.

▼ Ajatellaan labyrinttia, jossa voidaan siirtyä seuraavaanristeykseen kertomalla ilmansuunta P (pohj.), I (itä),E (etelä) tai L (länsi).

▼ Kirjoitetaan ohjelma, joka tulostaa optimoidun reitin,kun sille syötetään reitti, joka saadaan kirjaamallajokainen siirtymä matkalla labyrintin alusta loppuun,kun labyrintissa on harhailtu sattumanvaraisesti.

▼ Jos harhailemalla löydetty reitti on esimerkiksi:PLIPIPLIILEILLEI

olisi optimoitu reitti:PI

▼ Siis aina kun reitissä on peräkkäin yhdistelmä LI, IL,PE tai EP, sievennetään se pois, koska ollaan palattutakaisinpäin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 261: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 253▼ Toteutettu ohjelma näyttää seuraavalta:

#include <iostream>#include <vector>#include <string>

using namespace std;

void TulostaReitti(vector<char> reittivektori) ;

int main( ) {string reitti;cout << "Syötä kuljettu reitti: " ;getline(cin, reitti) ;

vector<char> optimoitu_reitti;

for ( string::size_type i = 0; i < reitti.length( ); ++i ) {char uusi_suunta = reitti.at( i) ;

if ( optimoitu_reitti.size( ) == 0 ) {optimoitu_reitti.push_back(uusi_suunta);

} else {char edellinen_suunta = optimoitu_reitti.back( );

if ( edellinen_suunta == ’I’&& uusi_suunta == ’L’ ) {

optimoitu_reitti.pop_back( );

} else if ( edellinen_suunta == ’L’&& uusi_suunta == ’I’ ) {

optimoitu_reitti.pop_back( );

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 262: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 254} else if ( edellinen_suunta == ’P’

&& uusi_suunta == ’E’ ) {

optimoitu_reitti.pop_back( );

} else if ( edellinen_suunta == ’E’&& uusi_suunta == ’P’ ) {

optimoitu_reitti.pop_back( );

} else {

optimoitu_reitti.push_back(uusi_suunta);}

}}

TulostaReitti(optimoitu_reitti) ;}

void TulostaReitti(vector<char> reittivektori) {vector<char>::size_type i = 0;

while ( i < reittivektori.size( ) ) {cout << reittivektori.at(i) ;++i;

}

cout << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 263: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 255

Siitä opittua

▼ Vektori on dynaaminen korvike C++-kielen omalletaulukkotyypille ja se ratkaisee seuraavat taulukoihinliittyvät puutteet:

– Taulukot ovat staattisia rakenteita: alkioidenlukumäärää voi muuttaa vain kääntämälläohjelman uudelleen.

– Taulukkoa ei voi kopioida toiseen taulukkoon=-operaattorilla.

– Kahta taulukkoa ei voi vertailla operaattoreilla==, !=, <, >, <= ja >= .

– Taulukkoa ei voi alustaa (asettaa alkuarvoamäärittelyn yhteydessä) toisesta taulukosta.

– Taulukkoon talletettujen alkioiden lukumäärää eiyleensä saa selville, paitsi pitämällä siitä itse kirjaa.

– Funktion parametrina taulukko käyttäytyyepäjohdonmukaisesti muihin tietotyyppeihinverrattuna: aina "viiteparametri".

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 264: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 256▼ Vektorityypin käyttämiseksi koodin alkuun on

lisättävä:#include <vector>

▼ Vektorimuuttujan määrittely tapahtuu uudellaerikoisella syntaksilla:

vector<alkioiden_tyyppi> muuttuja;

esimerkiksi:vector<int> lottonumerot;

jonka jälkeen lottonumerot-muuttujaan voidaantallentaa kokonaislukuja.

▼ Vektorin loppuun voidaan lisätä alkioita yksikerrallaan push_back-funktiolla:

lottonumerot.push_back(32);

jolloin vektorin koko (siihen talletettujen alkioidenlukumäärä) kasvaa yhdellä.

▼ Viimeinen alkio voidaan poistaa pop_back-funktiolla:lottonumerot.pop_back( );

jolloin vektorin koko pienenee yhdellä

▼ Jos vektori on tyhjä, pop_back-funktion kutsu kaataaohjelman (tarkemmin: aiheuttaa poikkeuksen

s. 476, joka oletusarvoisesti keskeyttää ohjelman).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 265: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 257▼ Vektorin koko saadaan selville size-funktiolla:

lottonumerot.size( ) ;

▼ Jos size-funktion paluuarvo halutaan tallettaamuuttujaan, on kyseisen muuttujan tyypin oltava:

vector<alkiotyyppi>::size_type

siis esimerkiksivector<int>::size_type koko = lottonumerot.size( ) ;

▼ Tietotyyppi vector<alkiotyyppi>::size_type onaritmeettinen tyyppi ja sillä voidaan operoida kutenkokonaisluvuilla yleensä.

▼ Syntaksi on hiukan vaikeaselkoinen, mutta kyseessäon vain yhdistelmä vektorin määrittelynotaatiota:

vector<alkiotyyppi>

ja merkkijonoista tuttua:string::size_type

: : -notaatiota.

▼ Vektorin ensimmäiseen ja viimeiseen alkioonpäästään käsiksi front- ja back-funktioilla:

cout << "eka alkio: " << lottonumerot.front( ) << endl<< "vika alkio: " << lottonumerot.back( ) << endl;

▼ Jos vektori on tyhjä, front- tai back-funktion kutsukaataa ohjelman (aiheuttaa poikkeuksen s. 476).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 266: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 258▼ Vektoria voi indeksoida [ ]-operaattorilla kuten

taulukkoa:cout << lottonumerot[3] << endl;lottonumerot[0] = 5;

▼ Indeksointi alkaa tuttuun tapaan nollasta.

▼ Operaattori [ ] ei tarkista, onko käsiteltävä alkiovektorissa vai ei ➠ tapahtuu kummia jos ei ole ➠vastuu käyttäjällä kuten taulukoiden tapauksessa.

▼ Operaattori [ ] ei lisää alkiota vektoriin, se ainoastaankäsittelee vektorissa jo ennestään olevaa tietoa.

▼ Turvallisempi tapa indeksoida vektoria on at-funktio(string-tyypistä tuttu):

cout << lottonumerot.at(3) << endl;lottonumerot.at(0) = 5;

▼ Tämä eroaa [ ]-operaattorista siten, että laitonindeksi aiheuttaa poikkeuksen (s. 476) ja ohjelmansuoritus keskeytyy ➠ tullaan tietoisiksi siitä, ettäohjelmassa on looginen virhe.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 267: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 259▼ Taulukoista poiketen vektori voi myös olla normaaliin

tapaan funktion arvo- tai muuttujaparametri:void func1(vector<int> arvoparametri) ;void func2(vector<int>& muuttujaparametri) ;

▼ Arvoparametreihin sisältyy kuitenkin pieni kompa:arvoparametri on kopio todellisesta parametrista ➠jos vektori on kooltaan suuri, tehdään paljon työtä,kun todellinen parametri kopioidaan muodolliseenparametriin.

▼ Ongelma vältetään C++:ssa yleensä niin, että josfunktion parametri on kooltaan suuri tietorakenne,jonka ei haluta kopioituvan, tehdään muodollisestaparametrista nk. vakioviite:

void func3(const vector<int>& vakioviiteparametri) ;

▼ Nyt todellinen parametri ei kopioidu muodolliseenparametriin, mutta samalla const estää muodollisenparametrin (ja sitä kautta todellisen parametrin)muuttamisen.

▼ Tämä ei tietenkään ole sama asia kuin arvoparametri,mutta riittävän lähellä useimmissa tapauksissa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 268: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 260▼ Samaa idea toimii aina, kun funktion parametrina

on tietotyyppi, jonka alkiot saattavat olla suuria ➠merkkijonojen kanssa tehdään usein samoin:

void func4(const string& vakioviitemerkkijono);

▼ Huomaa, että labyrinttiesimerkissä vakioviite-parametria ei käytetty yksinkertaisuuden vuoksi ➠noudata silti vakioviite-ideaa omissa ohjelmissasi!

▼ Vektori voi olla myös funktion paluuarvona:vector<int> LueLottonumerotVersio1( );· · ·lottonumerot = LueLottonumerotVersio1( );

▼ Tähän liityy kuitenkin sama kompa kuin arvopara-metreihin: paluuarvo joudutaan kopioimaan funk-tiosta kutsujalle ➠ toteuta suurikokoiset paluuarvotmuuttujaparametrin avulla:

void LueLottonumerotVersio2(vector<int>& numerovek);· · ·LueLottonumerotVersio2(lottonumerot);

▼ Nyt tulokset talletetaan muuttujaparametriin yhdenkerran, eikä niitä tarvitse kopioda erikseen funktiostapalattaessa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 269: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 261

Standard Template Library (STL)

▼ C++:n standardikirjastoon kuuluu osanank. Standard Template Library (STL).

▼ STL tarjoaa ohjelmoijalle valmiit työkalut (tietoraken-teita ja algoritmeja) monimutkaisten ja joustavientietorakenteiden luontiin ja käsittelyyn ➠ kaikkea eitarvitse tehdä alusta pitäen itse.

▼ Loogisesti STL koostuu kolmesta osasta:

– STL-säiliöt (containers) eli varsinaiset yleis-käyttöiset tietorakenteet, joihin käsiteltävä tietovoidaan tallettaa (s. 263).

– STL-iteraattorit (iterators) joiden avulla säiliöidensisältämiä tietoalkioita voidaan käydä yksitellenläpi tai tarvittaessa esittää säiliön alkioiden osaväli(s. 288).

– STL-algoritmit (algorithms) prosessoivat säiliöihintalletettuja alkioita (s. 297). Se, mihin osaan säiliönsisältämistä alkioista algoritmin toimenpiteidenhalutaan kohdistuvan, kerrotaan algoritmilleiteraattoreiden avulla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 270: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 262▼ Iteraattorit luovat yhteyden säiliöiden ja algoritmien

välille.

▼ Tutkitaan seuraavassa kurssin kannalta riittävästi(muttei läheskään täydellisesti) kutakin STL:n osaa.

▼ Päämääränä on paitsi yleissivistää niin myöstarjota hyvät työkalut STL:n käyttöön kurssilla niin,että esim. harjoitustehtävissä voidaan keskittyäolennaisempaan asiaan.

▼ Materiaali on tarkoituksella hiukan «käsikirjamainen»,mikä toivottavasti auttaa käytännön työskentelyäSTL:n kanssa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 271: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 263

STL-säiliöt

▼ Termi säiliö (container) tarkoittaa C++:ssa ja STL:ssätietorakennetta, johon voidaan tallettaa useita jonkinmuun tietotyypin alkioita.

▼ STL-säiliöt ovat geneerisiä (yleiskäyttöisiä/tyyppi-riippumattomia) dynaamisia (alkioden lukumäärääei ole kiinnitetty) tietorakenteita:

Geneerisyys

– STL ottaa vain yleisellä tasolla kantaa siihen,mitä ominaisuuksia tietotyypillä pitää olla, jottasen alkioita voidaan tallettaa STL-säiliöihin.

– Säiliömuuttujan määrittely tapahtuu aina

säiliötyyppi<alkiotyyppi> muuttujan_nimi;

syntaksilla. Esimerkiksi vector, johon talletetaanopiskelijoita:

vector<Opiskelija> opiskelijarekisteri;

jossa Opiskelija on jokin itse määritelty tieto-tyyppi yhden opiskelijan tietojen esittämiseen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 272: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 264Dynaamisuus

– Toisin kuin C++:n omalla taulukkotyyppillä (jokamyös on eräänlainen säiliö), STL-säiliöillä ei olekiinnitettyä maksimikokoa, vaan niiden kokokasvaa ja pienenee automaattisesti, kun uusiaalkiota lisätään tai vanhoja poistetaan.

▼ Säiliötyypit voidaan luokitella ominaisuuksiensa jakäyttäytymisensä perusteella kahteen kategoriaan:

– sarjat (sequence, sequence container)(s.265) ja

– assosiatiiviset säiliöt (associative container)(s.276).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 273: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 265

Sarjat (sequence, sequence container)

▼ Sarjat ovat tietorakenteita, jotka säilyttävät alkioidenjärjestyksen.

▼ Esimerkiksi vector-rakenteeseen ensimmäisenä lisättyalkio pysyy ensimmäisenä, jollei ohjelmoija erikseensuorita operaatiota, joka muuttaa sen paikkaa.

▼ Jokaiselle sarjan alkiolle voidaan ajatella sijain-nista riippuva järjestysnumero, sillä alkiot ovat

rakenteessa peräkkäin (siitä nimi sequence).

▼ STL:ssä sarjoja ovat:

– vector (alkion lisäys ja poisto lopusta nopeaa,voidaan indeksoida kokonaisluvulla),

– deque (alkion lisäys ja poisto alusta ja lopustanopeaa, voidaan indeksoida kokonaisluvulla),

– list (alkion lisäys ja poisto minne/mistä tahansanopeaa, peräkkäissaantirakenne (s.213) ➠ ei voiindeksoida) ja jossain mielessä myös

– C++:n oma taulukkotyyppi voidaan ajatella säiliöksi,vaikka se ei olekaan STL-säiliö.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 274: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 266▼ Sarjojen ominaisuudet ovat keskenään hiukan

erilaisia ➠ kannattaa valita huolella oikea rakenneoikeaan tarkoitukseen.

▼ Esimerkiksi ei ole hyvä ajatus valita tietorakenteeksivector:ia, jos on tarve lisätä usein alkioita rakenteenalkuun (vrt. edellisen sivun ominaisuuslista).

▼ Sarjatyyppeihin voidaan tallentaa minkä tahansatietotyypin alkioita, kunhan kyseisellä tyypillätoimivat sijoitusoperaattori ja alustus toisesta

samantyyppisestä muuttujasta.

▼ Myös toisten STL-rakenteiden tallentaminen sarjoihinon mahdollista.

▼ Kunkin sarjatyypin käyttämiseksi pitää ohjelmanalkuun lisätä kyseisen tyypin include-direktiivi:

#include <vector> // Voidaan käyttää vector-säiliötä,#include <deque> // deque-säiliötä ja#include <list> // list-säiliötä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 275: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 267▼ Tilanteita, joissa sarjat ovat käyttökelpoisia:

– on syystä tai toisesta tarpeen säilyttää järjestys,jossa tietoalkiot lisättiin rakenteeseen,

– tietoalkiot halutaan lajitella (asettaa järjestykseen),

– halutaan käsitellä tietoalkiota, kun sen järjestys-numero (indeksi) on tiedossa (tämä on mahdollistavain vector- ja deque-rakenteilla sekäC++-taulukoilla),

– halutaan tehdä järjestyksessä jotain kaikille alkioille(lineaarinen läpikäynti) ja koska

– vector ja deque ovat oikeastaan kehittyneempiätaulukoita ➠ niillä voidaan tehdä samoja asioita,jotka on totuttu tekemään taulukoiden avulla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 276: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 268

Lyhyitä esimerkkejä sarjoista

▼ Kaikki sarjat (vector, deque ja list) ovat perusoperaa-tioiltaan hyvin samankaltaisia.

▼ Merkittäviä poikkeuksia on oikeastaan vain kaksi:

– vector- ja deque-rakenteiden yksittäisiin alkioihinpäästään suoraan käsiksi indeksoimalla[ ]-operaattorilla tai at-funktiolla, listan alkioita eivoi indeksoida.

– deque- ja list-rakenteisiin alkioita voidaan lisätäja poistaa myös alusta push_front- ja pop_front-operaatioiden avulla, vektoriin näitä operaatioitaei voida kohdistaa.

▼ Oletetaan esimerkeissä, että seuraavat on määritelty:vector<int> ivektori;deque<string> strdeque;list<Opiskelija> olista;

▼ Määrittelyn jälkeen rakenteet ovat automaattisestityhjiä (alkioiden lukumäärä nolla).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 277: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 269▼ Alkioita voidaan lisätä ja poistaa lopusta:

ivektori.push_back(4);strdeque.push_back("the end");olista.push_back(yhden_opiskelijan_tiedot);

ivektori.pop_back( );strdeque.pop_back( );olista.pop_back();

▼ Alkioita voidaan deque- ja list-rakenteen tapauksessalisätä ja poistaa myös rakenteen alusta push_front-ja pop_front-funktioilla:

strdeque.push_front("alussa deque oli autio ja tyhjä");olista.push_front(joku_opiskelija) ;

strdeque.pop_front( );olista.pop_front( ) ;

▼ Kaikkien STL-sarjojen ensimmäinen ja viimeinen alkiosaadaan selville front- ja back-funktioilla:

int i;i = ivektori.front( ) ;

Opiskelija op;op = olista.back( );

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 278: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 270▼ vector- ja deque-rakenteita voidaan indeksoida

[ ]-operaattorilla tai at-funktiolla, kun tiedetäänhalutun alkion indeksi:

i = ivektori[4];ivektori.at(3) = 42;

string str;str = strdeque.at(7);strdeque[666] = "the number of the beast";

▼ Kaikki yksittäisiä alkioita käsittelevät toimenpiteetovat laillisia vain, jos kyseinen alkio on olemassa:

– Indeksointi on laitonta luvulla, jonka mukaistaalkiota rakenteessa ei ole.

– at-funktiolla indeksointi on turvallisempaa kuin[ ]-operaattorilla, koska laiton indeksi keskeyttääohjelman suorituksen.

– front-, back-, pop_front- ja pop_back-funktiotkeskeyttävät ohjelman, jos rakenne on tyhjä.

– Edellä «ohjelman keskeyttäminen» tarkoittaatäsmällisesti ottaen poikkeuksen heittämistä,mutta siitä lisää myöhemmin (s.476).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 279: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 271▼ Rakenteessa olevien alkoiden lukumäärä saadaan

selville size-funktiolla ➠ tätä voidaan hyödyntäävector- ja deque-rakenteiden läpikäynnissä:

// Huomaa että idea on sama kuin taulukoiden// läpikäynnissä: silmukkamuuttuja juoksee// järjestyksessä läpi kaikkien alkioiden indeksit.deque<string>::size_type i = 0;while ( i < strdeque.size( ) ) {

cout << strdeque.at(i) << " ";++i;

}cout << endl;

▼ list-rakenteita voi käydä läpi vain nk. iteraattoreiden

avulla ➠ niistä lisää hetken kuluttua (s.288).

▼ Funktiolla empty voidaan testata onko rakenne tyhjä(ei sisällä yhtään alkiota):

if ( strdeque.empty( ) ) {// Ei alkioita.· · ·

}· · ·while ( !olista.empty( ) ) {

// olista:ssa on alkioita jäljellä.· · ·

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 280: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 272▼ Kaikki STL-säiliöt määrittelevät sijoitusoperaation ja

alustuksen toisesta samantyyppisestä säiliöstä:list<char> merkkilista_1;· · ·// merkkilista_2:n alkuarvoksi sama kuin// mitä merkkilista_1 sisältää.list<char> merkkilista_2(merkkilista_1);· · ·// Sijoitetaan kaikki merkkilista_2:n// alkiot merkkilista_1:een.merkkilista_1 = merkkilista_2;

▼ Alustukseen (siis alkuarvon asettamiseen määrittelynyhteydessä) on muitakin vaihtoehtoja:

– Alkioiden lukumäärä kerrottu:// 500 kappaletta merkkijonoja.vector<string> jasenet(500);

– Alkioiden lukumäärä ja alkuarvo kerrottu:// 24 reaalilukua, jotka alustettu nollaksi.deque<double> lampotilat(24, 0.0);

▼ Jos sarjarakenteelle ei määrittelyn yhteydessä kerrotaalkioiden lukumäärää, rakenne on aluksi tyhjä (muttaalkioitahan voi lisätä).

▼ Vaikka alkioiden lukumäärä on kerrottu, alkioitavoidaan silti myös lisätä ja poistaa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 281: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 273▼ Kaikille STL-sarjoille voi määrittelyn yhteydessä antaa

alkuarvon (alkusisällön) alustuslistan avulla: ✶

vector<int> ivec = { 4, 7, 1 } ;deque<string> strdeq = { "x", "yyyy" } ;list<double> dlist = { 1.2, 3.4, 5.6, 7.8 } ;

▼ Ajatus on täysin analoginen esimerkiksi struct-tyyppisten muuttujien alustukseen verrattuna:aaltosulkeiden sisällä luetellaan pilkuilla eroteltuinakaikki alustusarvot/-alkiot.

▼ Säiliön alkukoko (siis size( )-funktion paluuarvo) onluonnollisesti sama kuin alustusalkioiden lukumäärä.

▼ Alustuslistan avulla alustettuihin säiliöihin voi lisätäja niistä voi poistaa alkioita normaalisti.

▼ Alustuslistan sisältö voidaan myös sijoittaa entuudes-taan olemassa olevaan muuttujaan: ✶

ivec = { 9, 8, 7, 6, 5 } ;strdeq = { "aaa", "bbb", "ccc" } ;dlist = { 9.9, 8.8, 7.7 } ;

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 282: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 274▼ Sijoituksen jälkeen säiliö sisältää pelkästään alustus-

listan alkiot samassa järjestyksessä ja sen koko onsama kuin alustuslistan alkioiden lukumäärä.

▼ Alustuslistan alkioiden ei ole pakko olla literaalisiaarvoja, vaan esimerkiksi seuraava on mahdollista:

int func(string mjono) {· · ·

}· · ·int luku;· · ·ivec = { 1, func("abc"), 2, luku, 3 } ;

▼ Alustuslista voi myös olla funktion todellisenaparametrina, jos muodollisen parametrin tyyppi onSTL-sarja: ✶

void tulosta(const vector<int>& v) {· · ·

}· · ·tulosta( { func("abc") , 2, luku } ) ;

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 283: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 275▼ Säiliö voidaan tyhjentää clear-funktiolla

ivec.clear( ) ;

jonka jälkeen rakenteessa ei ole yhtään alkiota (muttalisäys on edelleen mahdollista).

▼ Kahta samantyyppistä sarjaa voi tutkia vertailu-operaattoreilla:

if ( merkkilista_1 == merkkilista_2 ) {// Listat yhtäsuuria: samat alkiot// samassa järjestyksessä.· · ·

}

▼ Nämä olivat perusoperaatiot STL-sarjoille ➠

– Muihin mahdollisuuksiin palataan iteraattorien(s.288) ja algoritmien (s.297) yhteydessä.

– Kannattaa myös tutustua C++-kirjastoreferenssiinhttp://www.cs.tut.fi/~aps/doc/cppref.pdf

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 284: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 276

Assosiatiiviset säiliöt

(associative container)

▼ Assosiatiiviset säiliöt järjestävät rakenteeseentalletetut tiedot omien tarpeidensa mukaan: sitenettä lisäys- ja hakuoperaatiot ovat mahdollisimmannopeita.

▼ Rakenne ei ole sellainen, jossa alkioiden voisiajatella olevan peräkkäisjärjestyksessä, joten niidenjärjestysnumerosta tai paikasta ei voi puhua.

▼ Assosiatiiviseen säiliöön tieto talletetaan(haku)avaimen perusteella ➠ myös haku tapahtuusaman avaimen avulla.

▼ STL:ssä assosiatiivisia säiliöitä ovat:

– set: analoginen matemaattisen joukon kanssa,

– multiset: joukko, johon sama alkio voi kuuluauseammin kuin kerran,

– map: liittää avainarvoon varsinaisen tietoalkion ja

– multimap: yhteen avainarvoon voi liittyäuseampia tietoalkioita.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 285: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 277▼ Kuten sarjojen kanssa, assosiatiivisten säiliöiden

käyttöönotto tapahtuu include-direktiivillä:#include <set> // sekä set että multiset.#include <map> // sama sekä map että multimap.

▼ set- ja multiset-rakenteet vaativat, että talletettavalleavaimelle toimivat sijoitusoperaattori, alustus javertailu toisen samantyyppisen tietoalkion kanssa.

▼ map- ja multimap-rakenteisiin talletettavaltatiedolta vaaditaan, että sekä avaimelle ettävarsinaiselle tietoalkiolle toimivat sijoitus ja alustustoisesta samantyyppisestä tietoalkiosta. Lisäksiavaimelle pitää toimia vertailu.

▼ map- ja multimap-rakenteisiin talletettava tietokoostuu kahdesta osasta: avaimesta ja varsinaisestatietoalkiosta ➠ map- ja multimap-säiliömuuttujanmäärittely on muotoa:

map<avaintyyppi, alkiotyyppi> map_muuttuja;multimap<avaintyyppi, alkiotyyppi> multimap_muuttuja;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 286: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 278▼ Ideoita assosiatiivisten säiliöiden käyttökohteista:

set

kun on tarpeen selvittää kuuluuko alkio joukkoonvai ei, mutta avaimeen ei liity lisäinformaatiota.Esimerkiksi arvottujen lottonumeroiden joukko:

set<int> arvotut_lottonumerot;

multiset

jos on tarpeen pitää kirjaa joukosta tietoalkioita,kun tietyn niminen/numeroinen/tunnisteinenalkio voi esiintyä joukossa useammin kuin kerran.Esimerkiksi kauppakassin sisältö:

multiset<string> ostokset;

voi sisältää vaikka "maito"-nimisen tuotteenuseammin kuin kerran.

map

sitoo yksikäsitteisen avainarvon ja siihen liittyväntiedon toisiinsa. Esimerkiksi avaimena opiskelija-numero (yksikäsitteinen) ja arvona kyseisenopiskelijan muut tiedot:

map<int, Opiskelija> opiskelijarekisteri;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 287: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 279multimap

kuten map, mutta avain ei ole yksikäsitteinen ➠multimap voi sisältää useita identtisiä avaimia,joihin liittyy eri arvo. Esimerkiksi puhelinluettelo,jossa voi olla useita samannimisiä ihmisiä (avain,joka ei ole yksikäsitteinen), joilla kullakin on omapuhelinnumeronsa:

multimap<string, int> puhelinluettelo;

▼ Vaikka multiset ja multimap ovat hyödyllisiä, niihinei kurssilla puututa sen tarkemmin.

▼ Kannattaa myös pitää mielessä, että STL-säiliöiden(sekä sarjojen että assosiatiivisten säiliöiden) alkiotvoivat olla toisia STL-säiliöitä, esimerkiksi:

– vektori jonka alkiot ovat vektoreita:vector<vector<double>> ratkaisumatriisi;

– map jonka alkiot ovat listoja:map<string, list<double>> pankkitilin_otot_ja_panot;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 288: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 280

Lyhyitä esimerkkejä set-rakenteesta

▼ Määritellään joukko, johon voi tallentaa merkkijonoja:set<string> laiva_on_lastattu;

▼ Määrittelyn jälkeen joukko on automaattisesti tyhjä.

▼ Joukoille toimii alustus ja sijoitus toisesta samantyyp-pisestä joukosta:

set<int> lottonumerot_1;· · ·set<int> lottonumerot_2(lottonumerot_1);· · ·lottonumerot_1 = lottonumerot_2;

▼ Joukkoon saadaan lisättyä uusi alkio insert-funktiolla:laiva_on_lastattu.insert("koirilla") ;

▼ Lisäys toimii silloinkin, jos alkio kuului joukkoon joentuudestaan ➠ se vaan ei tee mitään.

▼ Alkion kuulumista joukkoon voi tutkia find-funktiolla:if ( laiva_on_lastattu.find(sana) == laiva_on_lastattu.end( ) ) {

// sana ei kuulu laiva_on_lastattu-joukkoon· · ·

} else {// sana-merkkijono oli joukossa jo entuudestaan.· · ·

} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 289: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 281▼ Funktio find palauttaa nk. iteraattorin ➠ näistä

hetken päästä lisää (s.288).

▼ Tässä vaiheessa riittää tietää, että paluuarvo onyhtäsuuri kuin kyseisen joukon end-funktionpaluuarvo vain, jos parametri ei kuulu joukkoon.

▼ Yksittäinen alkio voidaan poistaa erase-funktiolla:

if ( laiva_on_lastattu.find(sana) == laiva_on_lastattu.end( ) ) {// Sana ei kuulu joukkoon: ei voi poistaa.· · ·

} else {laiva_on_lastattu.erase(sana);

}

▼ Poistonkin voi tehdä ilman, että erikseen tarkastaa,kuuluuko poistettava alkio joukkoon vai ei ➠ jos eikuulu, ei tehdä mitään.

▼ Joukosta voidaan poistaa kaikki alkiot funktiolla clear

➠ tuloksena tyhjä joukko:

laiva_on_lastattu.clear( ) ;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 290: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 282▼ Keskenään samantyyppisiä joukkoja voi tutkia

vertailuoperaattoreilla:if ( lottonumerot_1 != lottonumerot_2 ) {

// Joukkojen alkioissa eroja.· · ·

} else {// Joukoissa täsmälleen samat alkiot.· · ·

}

▼ Joukkoon kuuluvien alkioiden lukumäärän saa selvillesize-funktiolla:

if ( lottonumerot_1.size( ) != LOTTONUMEROITA ) {// Jokin mättää: väärä määrä lottonumeroita.· · ·

}

▼ Funktio empty selvittää, onko joukko tyhjä.

▼ Kaikki mitä sivuilla 273–274 todettiin alustuslistoista,pätee sellaisenaan myös set-rakenteisiin. ✶

▼ Joukon alkioiden läpikäynti toteutetaan iteraattorinavulla (s.288).

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta. ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 291: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 283

Lyhyitä esimerkkejä map-rakenteesta

▼ Muista esitellyistä STL-rakenteista poiketen, map-rakenteen määrittely sisältää sekä hakuavaimen ettävarsinaisen talletettavan tiedon tyypit:

map<string, unsigned int> puhelinnumerot;

▼ Määrittelyn jälkeen map-rakenne on tyhjä.

▼ Myös map-rakentelle on määritelty alustus ja sijoitustoisesta samantyyppisestä rakenteesta:

map<string, double> hintalista_1;· · ·map<string, double> hintalista_2(hintalista_1);· · ·hintalista_1 = hintalista_2;

▼ map-rakennetta voi indeksoida [ ]-operaattorillakuten vector- ja deque-rakenteita, mutta indeksintyypin on oltava sama kuin hakuavaimen tyyppi:

puhelinnumerot["Matti"] = 123456789;· · ·cout << nimi << " " << puhelinnumerot[nimi] << endl;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 292: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 284▼ Jälkimmäiseen käyttötilanteeseen sisältyy vaara:

kun map:iä indeksoidaan, indeksoitu alkio lisätäänrakenteeseen, vaikka se ei olisi siellä ennestään.

▼ Jos tätä ei haluta, vaan tarkotus on käyttää arvoa vainjos se on rakenteessa, siitä on ensin varmistuttava:

if (puhelinnumerot.find(nimi) == puhelinnumerot.end( ) ) {// Hakuavain nimi ei ole luettelossa.· · ·

} else {cout << nimi << " " << puhelinnumerot[nimi] << endl;

}

▼ Käytetty "find == end"-mekanismi toimii samanidean mukaisesti kuin joukkojen tapauksessa.

▼ Kun tuon vaaran pitää mielessä, indeksointi onhelpoin tapa käsitellä map-rakennetta.

▼ Lisäksi on hyvä oivaltaa, että const- tai const-viite-map:iä ei voi indeksoida [ ]-operaattorilla.

▼ Hakuavain-tieto -parin voi poistaa erase-funktiolla:if ( puhelinnumerot.erase("Ari") ) {

// Poisto onnistui.· · ·

} else {// Hakuavain "Ari" ei map:issä, epäonnistui.· · ·

} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 293: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 285▼ Tarkasti ottaen em. erase palauttaa poistettujen

alkioiden lukumäärän, joka on map-rakenteentapauksessa 0 tai 1.

▼ Kokonaislukujahan voi käyttää C-kielen perintönäehdoissa ➠ nolla on false kaikki muut true.

▼ Poiston voi myös tehdä tarkistamalla ensin käsin,onko avain rakenteessa:

if (puhelinnumerot.find("Ari") != puhelinnumerot.end( ) ) {puhelinnumerot.erase("Ari") ;

} else {// Hakuavain "Ari" ei ole rakenteessa.· · ·

}

▼ Rakenne tyhjennetääm clear-funktiolla:puhelinnumerot.clear( ) ;

▼ Rakenteeseen talletettujen alkioiden lukumäärä jatieto siitä, onko rakenne tyhjä, tuttuun tapaan size-ja empty-funktioilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 294: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 286▼ Myös map-rakenteen alkioiden läpikäynti on toteu-

tettava iteraattorien avulla, kuten set-rakenteellakintehtiin (s.288).

▼ Edellä annetut esimerkit ovat hyvin alkeellinen tapakäsitellä map-rakennetta.

▼ Joustavampi tapa on pair-tyypin käyttö:pair<avaintyyppi, alkiotyyppi> tietopari;

joka on vain STL:n kompakti tapa ilmaista, ettämuuttujan tietopari tyyppi on seuraava tietue:

struct {avaintyyppi first;alkiotyyppi second;

} ;

▼ Edellisen kaltaisia pareja saadaan joustavasti luotuamake_pair-funktiolla:

pair<string, unsigned int> tietopari;tietopari = make_pair("Topi", 212121212);

▼ Koska parit ovat struct-rakenteita, voidaan niitäkäsitellä myös "."-operaattorilla:

tietopari.first = "Topi";tietopari.second = 212121212;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 295: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 287▼ Parin sisältämä hakuavain ja tietoalkio saadaan

lisättyä map-rakenteeseen:puhelinnumerot.insert(tietopari) ;

tai ilman tietopari-apumuuttujaa:puhelinnumerot.insert(make_pair("Topi", 212121212) );

▼ Vaikka pari-käsite tässä vaiheessa tuntuu tarpeet-toman monimutkaiselta, käy ilmi, että map-rakenteita iteraattorien avulla käsiteltäessä tietämyspair-tyypistä on välttämätön paha.

▼ Kaikki mitä sivuilla 273–274 todettiin alustuslistoista,pätee sellaisenaan myös map-rakenteisiin yhdelläpienellä lisäyksellä. ✶

▼ Koska map-rakenne sisältää todellisuudessa pareja,on alustuslistankin muodostuttava pareista:

map<string, unsigned int> puhelinnumerot = {{ "Matti", 12345678 } ,{ "Maija", 87654321 }

} ;

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 296: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 288

STL-iteraattorit

▼ Iteraattorit ovat STL-kirjaston tarjoamia tietotyyppejä,joiden avulla voidaan käsitellä (tutkia ja muuttaa)säiliöihin talletettuja alkioita.

▼ Tarkoituksena on tarjota yhdenmukaiset työkalut,jotta kaikkia säiliöitä voidaan käsitellä lähes samoin.

▼ Iteraattoria voi ajatella kirjanmerkkinä, joka muistaayhden säiliössä olevan alkion sijainnin.

▼ Kahdella iteraattorilla voidaan esittää jokin osavälisäiliöön talletetuista alkioista: mikä on osavälinesimmäinen alkio ja mikä viimeinen alkio.

▼ Jokainen STL-säiliö tarjoaa ohjelmoijalle joukontietotyyppejä ja funkioita, joilla voidaan käsitelläkyseiseen säiliötyyppiin liittyviä iteraattoreita.

▼ Tavallisimmin tarvitut iteraattorityypit ovat:vector<alkiotyyppi>::iteratordeque<alkiotyyppi>::iteratorlist<alkiotyyppi>::iteratorset<alkiotyyppi>::iteratormap<avaintyyppi, alkiotyyppi>::iterator

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 297: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 289▼ Edellisiä iteraattorityyppejä oleviin muuttujiin

voidaan tallentaa tieto alkion sijaintipaikastasäiliössä.

▼ Säiliötyypin jäsenfunktio begin kertoo säiliönensimmäisen alkion sijainnin.

▼ Jäsenfunktio end palauttaa iteraattorin joka osoittaarakenteen loppuun: end ei osoita lailliseen alkioonvaan on eräänlainen loppumerkki.

▼ Esimerkiksi yhdeksänalkioinen kokonaislukuvektori:

vector<int> ivek(9)

ivek.begin( ) ivek.end( )

▼ Iteraattorin osoittamaa alkiota voidaan käsitelläkohdistamalla iteraattoriin unaarinen * -operaattori.

▼ Iteraattori saadaan siirrettyä osoittamaan säiliönseuraavaan alkioon ++-operaattorilla ja edelliseenalkioon –– -operaattorilla.

▼ ==- ja != -operaattoreilla voidaan testata, osoitta-vatko kaksi iteraattoria samaan vai eri alkioon.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 298: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 290▼ Esimerkiksi koodinpätkä, joka käy vektorin alkiot läpi

alusta loppuun, kertoo jokaisen alkion kahdella jatulostaa muutetut alkiot näytölle:

vector<int> lukuvektori;· · ·vector<int>::iterator iter = lukuvektori.begin( );while ( iter != lukuvektori.end( ) ) {

*iter = 2 * *iter; // Alkion muuttaminencout << *iter << endl; // Alkion arvon käyttäminen++iter; // Seuraavaan alkioon siirtyminen

}

▼ Edellisestä näkyy selvästi, kuinka end-iteraattori eienää osoita käsittelyä vaativaan alkioon, vaan senavulla testataan, joko koko rakenne on käyty läpi.

▼ Usein end-arvoa käytetään myös funktion paluu-arvona osoittamaan, että säiliöstä ei löytynyt etsittyäalkiota (s.280).

▼ Edellä esitetty läpikäyntimekanismi toimii kaikillaSTL-säiliöillä ➠ toisena esimerkkinä joukon alkioidentulostaminen (vaihtelun vuoksi for-silmukka):

set<string> nimet;· · ·set<string>::iterator it;for ( it = nimet.begin( ); it != nimet.end( ); ++it ) {

cout << *it << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 299: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 291▼ Jos iteraattori osoittaa alkioon, joka on tietue (tai

myöhemmin myös luokka), voidaan tietueen kenttiinviitata suoraan –> -operaattorilla.

▼ Kuten map-rakenteesta puhuttaessa todettiin, senalkiot ovat todellisuudessa tietueita, jotka koostuvathakuavaimesta (first-kenttä) ja varsinaisestainformaatiosta (second-kenttä).

▼ Tulostetaan puhelinluettelo-map-rakenteestakaikkien "T"-kirjaimella alkavien puhelinnumerot:

map<string, unsigned int> puhelinnumerot;· · ·map<string, unsigned int>::iterator puhiter;puhiter = puhelinnumerot.begin( );while ( puhiter != puhelinnumerot.end( ) ) {

// Avainkenttä: first (string)if ( puhiter–>first.at(0) == ’T’ ) {

// Informaatio: second (unsigned int)cout << puhiter–>second << endl;

}++puhiter;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 300: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 292▼ Tähän mennessä esiteltyjen iteraattoreiden avulla

voidaan operoida vain sellaisiin säiliöihin, joitaon sallittua muuttaa ➠ ongelma jos funktioidenmuodolliset parametrit ovat tehokkyyssyistä const-vakioviitteitä.

▼ Tämä ratkeaa seuraavien iteraattorityyppien avulla:vector<alkiotyyppi>::const_iteratordeque<alkiotyyppi>::const_iteratorlist<alkiotyyppi>::const_iteratorset<alkiotyyppi>::const_iteratormap<avaintyyppi, alkiotyyppi>::const_iterator

▼ Esimerkiksi funktio, joka laskee kokonaislukulistanalkioiden summan:

int Summaa(const list<int>& lukulista) {int summa = 0;list<int>::const_iterator it = lukulista.begin( );while ( it != lukulista.end( ) ) {

summa = summa + *it;++it:

}return summa;

}

▼ const_iterator-tyypit eivät salli iteraattorin osoit-taman alkion arvon muuttamista.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 301: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 293▼ Kaikki STL-säiliöt map-rakennetta lukuunottamatta

voidaan alustaa iteraattorien avulla toisista säiliöistä:vector<double> reavek;· · ·list<double> realista(reavek.begin( ), reavek.end( ) ) ;

▼ Yllä siis realista alustetaan samassa järjestyksessä jasamoilla lukuarvoilla kuin mitä muuttujassa reavek oli.

▼ Kannattaa huomata, että alustuksessa ei ole pakkokäyttää begin- ja end-funktioita, vaan mikä tahansaiteraattoriväli käy.

▼ Esimerkiksi lista olisi voitu alustaa siten, että vektorinensimmäinen ja viimeinen alkio olisi jätetty pois:

vector<double> reavek;· · ·vector<double>::iterator valin_alku = reavek.begin( );++valin_alku;

vector<double>::iterator valin_loppu = reavek.end( );––valin_loppu;

list<double> realista(valin_alku, valin_loppu);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 302: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 294▼ Tai jos sattuu tietämään, että vector- ja deque-

iteraattoreihin voi lisätä tai vähentää koko-

naisluvun ja saada siten uuden iteraattorin, jokaosoittaa kyseisen lukumäärän verran alkioita eteen-tai taaksepäin.

▼ Edellinen esimerkki menisi siis lyhemmin:list<double> realista(reavek.begin( ) + 1, reavek.end( ) – 1);

▼ Vaikka tähän saakka on jatkuvasti käytetty ilmaisua«iteraattori osoittaa säiliön alkioon»:

vector<int> ivek(9)

ivek.begin( ) ivek.begin( )+4 ivek.end( )

▼ Iteraattorien voi myös ajatella osoittavanalkioiden väliin, jolloin unaarinen * -operaattorija –> -operaattori tulkitaan siten, että halutaankäsitellä heti välin perässä seuraavaa alkiota:

vector<int> ivek(9)

ivek.begin( ) ivek.begin( )+4 ivek.end( )

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 303: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 295▼ Tämä näkemys auttaa tulkitsemaan tilannetta

paremmin silloin, kun kahden iteraattorin avullaesitetään osajoukko säiliön peräkkäisistä alkioista.

▼ Jos välttämättä haluaa ajatella iteraattorien osoittavanalkioihin välien sijaan, pitää kahdella iteraattorillaesitetyt alkiojoukot aina tulkita ylhäältä avoimiksi:siis ylempi osoitettu alkio ei enää kuulu käsiteltäviinalkioihin.

▼ Kumpikin esitetty tulkinta on vain tapa ajatellaasiaa, kannattaa valita se, joka tuntuu itselleluonnollisimmalta.

▼ Kirjallisuudessa näkee molempia tapoja, jotenkannattaa olla aina tarkkana siitä, kumpaa tapaakirjoittaja noudattaa.

▼ Vielä yksi olennainen asia, joka on syytä pitäämielessä: jos säiliöön on lisätty tai siitä on poistettualkioita, et voi luottaa siihen, että ennen muutostatalletetut iteraattorit toimisivat muutoksen jälkeenoikein.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 304: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 296▼ Kärjistettynä esimerkkinä: jos iteraattori osoittaa

alkioon, joka poistetaan säiliöstä, mihin iteraattoriosoittaa poiston jälkeen?

▼ Nämä olivat perusideat STL-iteraattoreista ➠

– Muihin käyttötarkoituksiin palataan heti jatkossaalgoritmien yhteydessä.

– Myös C++-kirjastoreferenssi kertoo lisää yksityis-kohtia: http://www.cs.tut.fi/~aps/doc/cppref.pdf

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 305: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 297

STL-algoritmit

▼ STL-kirjasto algorithm tarjoaa valmiina yleisimmätoperaatiot, joita säiliön sisältämille alkioille ontarpeen tehdä.

▼ Algoritmikirjaston käyttämiseksi on koodiin lisättävä:#include <algorithm>

▼ STL:n valmiit algoritmit ovat geneerisiä: ne eivät otakantaa säiliön tyyppiin, vaan ne osaavat operoidamillä tahansa säiliöllä, kunhan säiliön alkioihin

voidaan viitata iteraattorien avulla.

▼ Käsiteltäväksi haluttu osa säiliön alkoista kerrotaanalgoritmifunktiolle iteraattorivälin avulla ➠ jokaisellafunktiolla on aina vähintään kaksi iteraattoripara-metria.

▼ Joskus iteraattoriparametreja on useampiakin, josfunktio tallettaa tuloksia johonkin toiseen säiliöön.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 306: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 298▼ Esimerkiksi algoritmi (siis funktio) sort osaa lajitella

vector- ja deque-rakenteen kasvavaan järjestykseen,kunhan sille kerrotaan iteraattoreilla lajiteltavaksihaluttu osaväli:

vector<int> ivek;deque<double> ddeq;· · ·sort(ivek.begin( ), ivek.end( ) ) ;sort(ddeq.begin( ), ddeq.end( ) ) ;

▼ Listaa ei voi lajitella sort-funktiolla (sort-algoritmi eiosaa lajitella peräkkäissaantirakennetta), mutta silläon jäsenfunktio sort, joka osaa:

list<string> slist;· · ·slist.sort( ) ;

▼ Assosiatiivisia säiliöitä ei voi lajitella, sillä kutenmuistetaan, set- ja map-rakennetta käytettäessäohjelmoija ei voi vaikuttaa alkioiden järjestykseen.

▼ STL-iteraattorit on siinäkin suhteessa nerokkaastimääritelty käsite, että tarpeen vaatiessa myös C++:nomia taulukoita voi ajatella sarjoina ja käsitelläalgoritm-kirjaston funktioilla iteraattorimaisesti.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 307: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 299▼ begin-iteraattoriksi tulkitaan tällöin

taulukkomuuttujan_nimi

ja end-iteraattoriksi lausekkeentaulukkomuuttujan_nimi + alkioiden_lukumäärä

arvo.

▼ Esimerkiksi kokonaislukutaulukko voitaisiin lajitellasort-funktiolla:

int itaulukko[1000];· · ·sort(itaulukko, itaulukko + 1000);

▼ Selitys sille, mitä lauseke itaulukko + 1000

oikeasti tarkoittaa, selviää vasta myöhemmin, kuntutustutaan osoittimiin (s.446).

▼ Seuraavassa on esiteltynä hyvin lyhykäisestikäyttökelpoisimpia algorithm-kirjaston funktioita.

▼ Kannattaa pitää mielessä, että kaikissa tapauksissabegin- ja end-iteraattorien paikalla mikä tahansakahden iteraattorin esittämä osaväli on kelvollinen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 308: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 300▼ count laskee säiliössä olevien tietyn arvoisten

alkioiden lukumäärän:list<string> vihamiehet:· · ·cout << count(vihamiehet.begin( ), vihamiehet.end( ), "Aki")

<< " kappaletta Aki-nimisiä vihamiehiä!" << endl;

▼ find etsii säiliöstä haluttua alkiota ja palauttaaiteraattorin ensimmäiseen löytämäänsä alkioon taiend-iteraattorin, jos ei löydy:deque<string> potilasjono;· · ·deque<string>::iterator iter;iter = find(potilasjono.begin( ), potilasjono.end( ), "Hanski") ;if ( iter == potilasjono.end( ) ) {

// Ei ole Hanskia potilasjonossa.· · ·

} else {// Hanski löytyi ja sijaitse iter:in osoittamassa// paikassa: tulostetaan ja poistetaan jonosta.cout << *iter << endl;potilasjono.erase(iter) ;

}

▼ Edellisessä erase ei ole algorithm-kirjaston funktio,vaan kaikille STL-säiliöille määritelty funktio, jollaiteraattorin osoittama alkio poistetaan säiliöstä(vrt. http://www.cs.tut.fi/~aps/doc/cppref.pdf).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 309: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 301▼ min_element ja max_element etsivät säiliöstä

arvoltaan pienimmän tai suurimman alkion japalauttavat iteraattorin kyseiseen alkioon:set<int> lukum;· · ·set<int>::iterator pienin_it;pienin_it = min_element(lukum.begin( ), lukum.end( ) );cout << "Pienin lukumäärä: " << *pienin_it << endl;

▼ Seuraavat alkioita tai niiden järjestystä muuttavatalgoritmit toimivat vain sarjoilla (miksi?).

▼ remove "poistaa" (siirtää loppuun) säiliöstä kaikkitietyn arvoiset alkiot:deque<string> potilasjono;· · ·remove(potilasjono.begin( ), potilasjono.end( ), "Hanski") ;

▼ replace korvaa tietyt arvot uusilla arvoilla:replace(sanalista.begin( ), sanalista.end( ), "TTKK", "TTY");

jossa siis kaikki sanat "TTKK" korvataan sanalla "TTY".

▼ reverse kääntää alkioiden järjestyksen takaperin:reverse(potilasjono.begin( ), potilasjono.end( ) ) ;· · ·// Taulukon alkiot takaperinint luvut[100];· · ·reverse(luvut, luvut + 100);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 310: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 302▼ random_shuffle sekoittaa alkiot satunnaiseen

järjestykseen:vector<Pelikortti> korttipakka(52);· · ·random_shuffle(korttipakka.begin( ), korttipakka.end( ) ) ;

▼ copy kopioi säiliön alkiot johonkin toiseen säiliöön:list<double> lukulista;· · ·vector<double> lukuvektori(lukulista.size( ) ) ;copy(lukulista.begin( ), lukulista.end( ), lukuvektori.begin( ) ) ;

▼ Kopioinnin kohteessa (siis siellä minne alkiotakopioidaan) pitää olla valmiiksi tilaa tarjolla ➠ yllälukuvektori on valmiiksi alustettu sisältämään yhtämonta alkiota kuin lukulista.

▼ Tämä pätee kaikkiin STL-algoritmeihin, jotkatallettavat tuloksia säiliöön: kohdesäiliössä pitää ollavalmista tilaa kaikille talletettaville alkioille.

▼ Tämä voidaan välttää nk. lisäysiteraattorien avulla:list<double> lukulista;· · ·vector<double> lukuvektori;copy(lukulista.begin( ), lukulista.end( ),

back_inserter(lukuvektori) );

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 311: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 303▼ Jolloin kaikki tallennukset lisäävät uuden alkion

lukuvektorin loppuun ➠ lukuvektorin koko kasvaaniin monella alkiolla kuin mitä copy kopioi.

▼ Tämä toimii myös, jos kohdesäiliössä oli alkioita joennestään.

▼ Kahden säiliön sisältämät alkiot voidaan siis yhdistääkolmanteen:

list<string> ekasailio;vector<string> tokasailio;· · ·deque<string> kolmassailio;copy(ekasailio.begin( ), ekasailio.end( ),

back_inserter(kolmassailio) ) ;copy(tokasailio.begin( ), tokasailio.end( ),

back_inserter(kolmassailio) ) ;

▼ Tämä ei ole ainoa eikä välttämättä paraskaantapa yhdistää säiliöitä, mutta havainnollistaalisäysiteraattoria mukavasti.

▼ On myös olemassa front_inserter-funktio, jokapalauttaa säiliön alkuun lisäykset suorittavaniteraattorin ➠ lisättyjen alkioiden järjestys muuttuupäinvastaiseksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 312: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 304▼ for_each-algoritmi kutsuu käyttäjän määräämää

aliohjelmaa kaikille iteraattorivälin alkioille:set<string> sanajoukko;· · ·cout << "Joukkoon kuuluvat sanat: " << endl;for_each(sanajoukko.begin( ), sanajoukko.end( ),

TulostaYksiString);

▼ Huomaa, että for_each:ille on annettu para-metrina TulostaYksiString-funktio, ei suinkaanTulostaYksiString-funktion paluuarvo.

▼ Kyseessä on nk. funktioparametri.

▼ TulostaYksiString-funktio pitää määritellä seuraa-vasti, jotta sen voisi antaa for_each:ille parametrina:

void TulostaYksiString(const string& str) {cout << str << endl;

}

▼ for_each:ille parametrina annettavan funktion onnoudatettava seuraavia sääntöjä:

– Paluuarvon tyyppi on void.

– Parametrin tyyppi on sama kuin käsiteltävänsäiliön alkioiden tyyppi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 313: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 305▼ Jos for_each:in kutsuman funktion muodollinen

parametri on viite- eli muuttujaparametri, funktiovoi muuttaa alkuperäisen säiliön alkioita:

list<int> lukulista;· · ·// Kerrotaan kaikki lukulistan alkiot luvulla 2.for_each(lukulista.begin( ), lukulista.end( ),

KerroKahdella);

jossa KerroKahdella on määritelty seuraavasti:

void KerroKahdella(int& luku) {luku = 2 * luku;

}

▼ transform kuvaa säiliön alkioiden arvot uusiksiarvoiksi ja tallettaa saadut arvot toiseen säiliöön:

list<string> sanat;· · ·vector<int> pituudet;transform(sanat.begin( ), sanat.end( ),

back_inserter(pituudet), MerkkijononPituus);

jossa MerkkijononPituus olisi määritelty:

int MerkkijononPituus(const string& str) {return str.length( );

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 314: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 306▼ Edellinen koodi siis kuvaisi MerkkijononPituus-

funktion avulla sanat-listassa olevat merkkijonotniiden pituuksiksi ja tallettaisi saadut pituudetsamassa järjestyksessä pituudet-vektoriin.

▼ transform-algoritmin kanssa käytettävän kuvaus-funktion täytyy noudattaa seuraavia sääntöjä:– Parametrin tyyppi on sama kuin lähtöarvosäiliön

alkioiden tyyppi.– Paluuarvon tyyppi on sama kuin kohdesäiliön

alkioiden tyyppi.

▼ Lähes kaikista algorithm-kirjaston funktioista onversio, jonka toimintaa voidaan säätää funktiopara-metrin avulla.

▼ Esimerkiksi count-funktiosta on olemassa versiocount_if, joka laskee vain tietyn ehdon täyttävienalkioiden lukumäärän:

set<int> joukko;· · ·// Montako paritonta luku on joukossaint parittomia = count_if( joukko.begin( ), joukko.end( ),

OnkoPariton);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 315: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 307▼ Edellisessä OnkoPariton olisi määritelty:

bool OnkoPariton(int luku) {// Pariton luku on sellainen, jonka jako-// jäännös kahdella jaettaessa ei ole nolla.return luku % 2 != 0;

}

▼ Tapauksissa joissa edellisen kaltainen valintafunktioon käytettävissä, sen täytyy noudattaa seuraaviasääntöjä:– Paluuarvon tyyppi on bool.– Parametrin tyyppi on sama kuin operoitavan

säiliön alkioiden tyyppi (voi olla myös const-viitekyseiseen tyyppiin).

– Paluuarvo true, jos parametrina saatuun alkioonhalutaan kohdistaa algoritmifunktion mukainentoimenpide, muutoin paluuarvo false.

▼ Ainakin seuraavat valintafunktiota hyödyntävätalgoritmit on käytettävissä: count_if, find_if,

replace_if ja remove_if.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 316: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 308▼ Toinen hyödyllinen tapa säätää joidenkin STL-

algoritmin toimintaa ovat vertailufunktiot: funktiotjotka vertailevat kahden alkion suuruutta.

▼ Esimerkiksi sort-funktiolle voi antaa lisäparametrin,joka kertoo, kuinka alkioiden suuruutta pitäisi tulkita:

struct Opiskelija {string nimi;int opnum;

} ;vector<Opiskelija> rekisteri;· · ·// Lajittelu nimen mukaiseen järjestykseensort(rekisteri.begin( ), rekisteri.end( ), VertaileNimia) ;· · ·// Lajittelu opiskelijanumeron mukaiseen järjestykseensort(rekisteri.begin( ), rekisteri.end( ), VertaileOpnumeja);

jossa funktiot on määritelty:

bool VertaileNimia(const Opiskelija& o1,const Opiskelija& o2) {

return o1.nimi < o2.nimi;}

bool VertaileOpnumeja(const Opiskelija& o1,const Opiskelija& o2) {

return o1.opnum < o2.opnum;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 317: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 309▼ Vertailufunktioiden on täytettävä seuraavat vaati-

mukset:– Paluuarvon tyyppi on bool.– Parametreja on kaksi ja niiden tyyppien oltava

sama kuin käsiteltävän säiliön alkioiden tyyppi.– Paluuarvo on true, jos ensimmäinen parametri

tulkitaan pienemmäksi kuin toinen parametri,false muussa tapauksessa.

▼ Myös min_element- ja max_element-funktiothyväksyvät valinnaisesti kolmannen parametrin, jokaon em. kaltainen vertailufunktio:

// Tulostetaan opiskelijanumeroltaan// suurimman opiskelijan tiedot.vector<Opiskelija>::iterator suurin_opnum;suurin_opnum = max_element(rekisteri.begin( ),

rekisteri.end( ),VertaileOpnumeja);

cout << suurin_opnum–>nimi << " "<< suurin_opnum–>opnum << endl;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 318: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 310▼ Nyt STL-algoritmien perusajatusten pitäisi olla

hallussa ➠

– Hiukan lisäinformaatiota löytyy tutusta osoitteesta:http://www.cs.tut.fi/~aps/doc/cppref.pdf.

– Hyvin yksityiskohtainen ja melko selkeä kuvausC++-standardikirjastosta (STL mukaanlukien)löytyy kirjasta: Josuttis: The C++ Standard Library(Addison-Wesley).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 319: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 311

Monimutkaisten tyyppinimien

yksinkertaistaminen (typedef)

▼ Monimutkaisia tietotyyppejä käytettäessa käy useinniin, että tyyppien nimistä muodostuu pitkiä,vaikeaselkoisia ja/tai työläitä kirjoittaa.

▼ C++:ssa on mekanismi, joilla ohjelmoija voi antaatietotyypeille uusia nimiä, jotka käyttäytyvätidenttisesti alkuperäisen tyypin kanssa.

▼ Ajatellaan seuraavaa määrittelyä:typedef unsigned long int ulong;

▼ Mitä tuossa tapahtuu on se, että tietotyypilleunsigned long int annetaan uusi nimi ulong.

▼ Tämän jälkeen C++ ei näe mitään eroa sillä, kumpaatyyppinimeä käytetään muuttujien jne. määrittelyyn:

unsigned long int jokumuuttuja;

tarkoittaa samaa kuin:ulong jokumuuttuja;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 320: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 312▼ Tyyppien uudelleenimeäminen tapahtuu siis varatun

sanan typedef avulla.

▼ typedef:in syntaktinen logiikka on:

1. Kirjoitetaan muuttujanmäärittely, jossa muuttujantyyppinä on lisänimeä kaipaava (alkuperäinen)tietotyyppi:

unsigned long int ulong;

2. Lisätään edellisen muuttujanmäärittelyrivin eteenvarattu sana typedef, jolloin määrittelyn merkitysmuuttuu tyypin nimeämiseksi:

typedef unsigned long int ulong;

3. Alkuperäisen tietotyypin uusi lisänimi on se,jota kohdassa 1 oli käytetty muuttujan nimenä(ulong).

▼ typedef on hyvä työkalu selkeyttämään ohjelmaasilloin, kun käytettyjen tietotyyppien nimet ovatsyystä tai toisesta hankalia.

▼ Erityisen hyvä esimerkki tästä ovat STL-säiliötja -iteraattorit.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 321: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 313▼ Ajatellaan seuraavia tuttuja STL-määrittelyitä:

vector<int> vek;vector<int>::iterator iter;vector<int>::size_type koko;

▼ Koodia saisi ainakin jossain mielessä selkeämmäksi,jos lisäisi sen alkuun typedef-määrittelyt:

typedef vector<int> int_vector;typedef int_vector::iterator int_vector_iterator;typedef int_vector::size_type int_vector_size_type;

▼ Huomaa kuinka int_vector-tyyppinimeä voi käyttääheti sen määrittelyn jälkeen myös osana toisiatypedef-määrittelyitä.

▼ Myös sivun ylälaidan muuttujamääritelyt voidaannyt kirjoittaa yksinkertaisemmin:

int_vector vek;int_vector_iterator iter;int_vector_size_type koko;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 322: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 314

Muuttujan tyypin

automaattinen määrittely ✶

▼ Jos muuttuja alustetaan määrittelyvaiheessa jollainarvolla, kääntäjä osaa haluttaessa määritellämuuttujan tyyppiksi saman kuin alustuslausekkeentyyppi on.

▼ Tämä tapahtuu merkitsemällä muuttujan tyypiksivarattu sana auto:

auto tulos = 34.5 * a;

▼ Kääntäjää huomaa nyt, että alustuslausekkeen34.5 * a arvo on tyypiltään double, jolloinmuuttujan tulos tyypiksi tulee myös double.

▼ Aivan sama olisi saatu aikaan myös kirjoittamallaperinteisemmin:

double tulos = 34.5 * a;

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 323: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 315▼ Varsinainen hyöty saavutetaan silloin, kun määritel-

lään muuttujia, joiden tyypit ovat monimutkaisia taimuuten vain pitkiä ja työläitä kirjoittaa toistuvasti.

▼ Vertaa esimerkiksi seuraavia täsmälleen samatlopputulokset tuottavia määrittelyitä:

map<string, vector<list<string>>>::iterator m_iter = m.begin( );vector<list<string>>::iterator v_iter = m.begin( ) –>second.begin( );

taiauto m_iter = m.begin( );auto v_iter = m.begin( ) –>second.begin( );

▼ Myös for-silmukan silmukkamuuttujan tyyppivoidaan määritellä vastaavasti:

for ( auto iter = m.begin( ); iter = m.end( ); ++iter ) {...

}

▼ Muuttujan tyypin määräytyminen alustuslausekkeentyypin perusteella on mitä ilmeisimmin elämäähelpottava apuväline.

▼ Siitä ei kuitenkaan kannata tulla liian riippuvaiseksi,koska jossain tilanteissa alkuperäisiä tyyppejä onpakko käyttää (esim. funktioiden muodollistenparametrien määrittely).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 324: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 316

Abstraktiot

▼ Sivistyssanastosta➀ voi löytää seuraavat määritelmät:

abstrakti

ajatuksessa eristetty, semmoisenaan katsottu taiajateltu, käsitteellinen.

abstraktio

epäolennaisten ainesten erottaminen ajatuksessaitse oliosta, käsitteenmuodostus (tai sen tulos),yleistys, käsite.

▼ Määritelmissä ei sinänsä ole mitään vikaa, ne ovatvain liian yleisellä tasolla esitettyjä,➁ jotta niitä voisiymmärtää ilman esimerkkejä.

▼ Tutkitaan muutama esimerkki sekä elävästä elämästäettä tietokoneohjelmoinnin maailmasta.

➀ Hagfors, Manninen: Jokamiehen sivistyssanasto, 11.painos,

WSOY, 1972, ISBN 951–0–01686–1.➁ Siis liian abstrakteja!

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 325: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 317Puhutun kielen sana auto

▼ Sana auto tarkoittaa laitetta, jolla pääsee nopeastipaikasta toiseen.

▼ Jokainen ymmärtää tuon merkityksen ja pystyykeskustelemaan autoista, vaikkei hänellä olisikaanymmärrystä auton todellisesta luonteesta:esim. kuinka polttomoottori tai vaihdelaatikkotoimivat, saatika sitten kuinka suunnitella jarakentaa auto omin käsin.

▼ Auto on siis abstraktio, joka ihmisten ajatusmaa-ilmassa kuvaa erittäin monimutkaisen laitteenniin, että sitä voi ajatella ja siitä voi keskustellatakertumatta epäolennaisiin yksityiskohtiin.

▼ Itse asiassa kaikki puhutun kielen sanat ovatabstraktioita aivan samoilla perusteilla.

▼ Toki samasta asiasta voi olla eri tasoisia abstrak-tioita (abstraktiotasoja) vrt. Risto Rikkaan,Antti Autoilijan, Matti Mekaanikon ja SeppoSuunnittelijan näkemys autosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 326: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 318Abstraktiot ohjelmoinnissa

▼ Kaikki tieto, jota tietokoneohjelmissa käsitellään,on abstraktia.

▼ Esimerkiksi tietotyyppi int.

▼ Paitsi että kokonaisluvut itsessään ovat abstrak-tioita, niin niiden esitys ohjelmointikielessä (siis int)on sitä myös: int:in toteutuksesta konekieli- taipuolijohdetasolla ei ole mitään varmuutta.

▼ Kuitenkin int-tyyppiä voidaan käyttää, kunymmärretään sen käyttäytyvän kuin kokonaisluku.

▼ Usein puhutaan tietoabstraktiosta (data

abstraction).

▼ Ohjelmointiin liittyy myös toinen abstraktio-käsite: toiminnallinen abstraktio (functional

abstraction).

▼ Hyvä esimerkki toiminnallisesta abstraktiosta ovatfunktiot ja aliohjelmat.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 327: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 319▼ Funktio tai aliohjelma on sarjalle toimintoja

annettu abstrakti nimi.

▼ Esimerkiksi, kun on päätetty, että luvun itseisarvosaadaan funktiolla

double Itseisarvo(double d)

niin sen jälkeen on yhdentekevää, kuinka funktioon toteutettu, kunhan se tuottaa itseisarvonmääritelmän mukaisen tuloksen parametristaan:

double Itseisarvo(double d) {if (d < 0) {

return –d;} else {

return d;}

}

tai#include <cmath>double Itseisarvo(double d) {

return abs(d); // kirjastofunktio abs( )}

tai jollain vielä aivan toisella tavalla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 328: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 320▼ Mitä (tietokone)ohjelmointi nyt tämän uuden

tiedon valossa on? (vrt.s.3)

▼ Uusien abstraktioiden opettamistakääntäjälle/koneelle, jotta ohjelmoijan olisihelpompi kuvata halutun ongelman ratkaisumuuten niin suppealla ohjelmointikielellä.

▼ Tosiasiassa abstraktioiden parissa siis painittiinjo koko Ohjelmointi I -kurssi, vaikka asiaa ei näinsyvällisesti ja filosofis–metafyysisesti pohdittukaan.

▼ Kun ohjelmoinnin yhteydessä puhutaan abstrak-tiosta, niin tarkoitetaan toteutuksen ja käytön

erottamista toisistaan:

– tietotyyppejä voi käyttää ja ne toimivatodotetusti ja

– funktioita ja aliohjelmia voi kutsua jane suorittavat tehtävänsa oikein,

vaikka toteutuksen yksityiskohdista ei tiedettäisimitään.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 329: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 321

Abstraktit tietotyypit

▼ Abstraktit tietotyypit ovat ohjelmoijan määrit-telemiä tietotyyppejä, joissa tietoisesti pyritäänsoveltamaan »toteutuksen ja käytön erottelu»-peri-aatetta.

▼ Tarkoitus on suunnitella ja rakentaa tietotyyppejä

1. Joiden toteutuksesta käyttäjällä ei ole tietoa,ja jos onkin, niin hän ei voi vahingossa (taitarkoituksella) käyttää valitun toteutuksenominaisuuksia hyväkseen (tiedon kätkentä,data/information hiding).

2. Ohjelmoija voi kuitenkin hyödyntää abstraktiatietotyyppiä, sillä sen alkuperäisen toteuttaja onkirjoittanut myös joukon funktioita ja aliohjelmia,joilla kaikki tarpeelliset operaatiot saadaan

suoritettua.

▼ Tällaista joukkoa abstraktiin tietotyyppiin liittyviäfunktioita ja aliohjelmia kutsutaan sen rajapinnaksi

tai julkiseksi rajapinnaksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 330: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 322▼ Esimerkki jo entuudestaan tutusta abstraktista

tietotyypistä on fstream-kirjaston ifstream:

1. Sen toteutuksesta ei ole tietoa: jollain »maagisella»tavalla se kuitenkin esittää fyysiset levytiedostotC++-ohjelmasta käytettävässä muodossa.

2. Mukana rajapintafunktiot, joiden avulla fstream-tyyppiä käytetään: getline, peek, ignore ja montamuuta.

▼ Rajapinnan funktiot kuvaavat abstraktin tietotyypinolennaiset ominaisuudet sillä abstraktiotasolla, jollatyyppiä on tarkoitus käyttää.

▼ Usein rajapinnan funktioita kutsutaan myösmetodeiksi tai jäsenfunktioiksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 331: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 323

Yksinkertainen esimerkki

▼ Suunnitellaan ensimmäinen abstrakti tietotyyp-pimme Vektori, mutta ei oteta vielä kantaa sentoteutukseen: katsotaan millainen sen rajapinta onja miten sitä käytettäisiin ohjelmassa.

▼ Vektori on kaksiulotteisen avaruuden vektori, jotaon tarkoitus käyttää seuraavasti:

– ohjelmassa voi olla Vektori-tyyppisiä muuttujia,

– vektorin arvo (double-tyyppiset x- ja y-koordi-naatti) voidaan lukea käyttäjältä näppäimistöltä,

– vektorista on mahdollista saada selville sen x- jay-koordinaatit,

– vektoreita voi tulostaa näytölle x–y-koordinaatti-tai polaarikoordinaattimuodossa ja

– vektoreita voidaan kiertää origon ympäri halutunkulman verran myötäpäivään.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 332: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 324▼ Pieni pääohjelma joka käyttää Vektori-tietotyyppiä:

#include <iostream>#include <cstdlib>#include <cmath>

using namespace std;...

vektori-tietotyypin määrittely puuttuu tästä: ks. s. 327....

int main( ) {Vektori vek;

vek.tulosta_xy_muodossa( ); / / onko alustettu?vek.tulosta_polaarimuodossa( );

if ( !vek.lue_nappaimistolta( ) ) {cerr << "Luku epäonnistui!" << endl;return EXIT_FAILURE;

}

vek.tulosta_xy_muodossa( );vek.tulosta_polaarimuodossa( );

vek.kierra_origon_ympari(25);

vek.tulosta_xy_muodossa( );vek.tulosta_polaarimuodossa( );

double x = vek.hae_x_koord( );double y = vek.hae_y_koord( );

cout << "Koordinaatit: " << x << ", " << y << endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 333: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 325▼ Ohjelman suoritus näyttäisi tältä:

proffa> ./vektorit(x, y) = (1, 0)(a, r ) = (0◦, 1)Syötä vektori: 3.0 4.0(x, y) = (3, 4)(a, r ) = (53.1301◦, 5)(x, y) = (4.4094, 2.35738)(a, r ) = (28.1301◦, 5)Koordinaatit: 4.4094, 2.35738proffa>

▼ Esimerkissä funktioiden kutsunotaatio on string-tyypistä ja tietovirroista tuttu muuttuja. funktio().

▼ Tätä notaatiota tullaan jatkossakin käyttämäänabstraktien tietotyyppien kanssa.

▼ Olennaiset huomiot esimerkistä:– Tietotyyppiä vektori pystyi käyttämään täydellä

teholla ja koodi oli ymmärrettävää, vaikka tyypintoteutuksesta ei ollut mitään tietoa.

– Rajapinnan funktiot määräävät, mitä abstraktillatietotyypillä voi tehdä: kaikki muuttujalle vek

tehdyt operaatiot tapahtuivat sopivaa rajapinnanfunktiota kutsumalla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 334: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 326▼ On hyödyllistä havaita myös, että osa rajapinnan

funktioista voidaan jakaa loogisiin ryhmiin:

rakentajat eli konstruktorit

Alustavat abstraktin tietotyypin muuttujan eliasettavat sille järkevän alkuarvon (esimerkinrakentaja on »piilossa» ➠ katso toteutusta).

valitsimet eli selektorit

Palauttavat toteutukseen kätkettyä tietoa:hae_x_koord( ) ja hae_y_koord( ) .

muuttajat eli mutaattorit

Muuttavat alkion tilaa (eli toteutukseenkätkettyä tietoa): lue_nappaimistolta( ) jakierra_origon_ympari( ) .

purkajat eli destruktorit

Vapauttavat muuttujan varaamat resurssit senjälkeen, kun muuttujaa ei enää tarvita. Esimerkissäei purkajaa (mutta myöhemmin tärkeä käsite).

▼ Muitakin ryhmiä on, mutta ne eivät tässä vaiheessaole tärkeitä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 335: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 327

Vektori-tyypin toteutus▼ C++-kielen työkalu abstraktien tietotyyppien

toteuttamiseen on luokka (class).

▼ Luokkiin sisältyy kuitenkin C++:ssa kiusallisen paljonyksityiskohtia, joten näinkin yksinkertainen esimerkkimuodostuu monimutkaiseksi.

class Vektori {// rajapinnan esittelypublic:

/ / rakentajaVektori( );

/ / valitsimetdouble hae_x_koord( ) const;double hae_y_koord( ) const;

/ / mutaattoritbool lue_nappaimistolta( );void kierra_origon_ympari(double kulma);

// muut rajapinnan tarjoamat palvelutvoid tulosta_xy_muodossa( ) const;void tulosta_polaarimuodossa( ) const;

/ / kätketyt toteutusyksityiskohdatprivate:

double x;double y;

};

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 336: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 328const double PII = 3.14159265358979323846;

// Rakentaja eli konstruktori:

/ / alustus x–akselin suuntaisella yksikkövektorillaVektori::Vektori( ): x(1.0), y(0.0) {}

// Valitsimet eli selektorit:

double Vektori::hae_x_koord( ) const {return x;

}

double Vektori::hae_y_koord( ) const {return y;

}

// Muuttajat eli mutaattorit:

bool Vektori::lue_nappaimistolta( ) {cout << "Syötä vektori: " ;

cin >> x;cin >> y;

if (!cin) {return false;

} else {return true;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 337: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 329void Vektori::kierra_origon_ympari(double kulma) {

double rad = kulma * PII / 180;double uusi_x = x * cos(rad) + y * sin(rad);double uusi_y = –x * sin(rad) + y * cos(rad);

x = uusi_x;y = uusi_y;

}

// Muut rajapinnan tarjoamat yleishyödylliset palvelut:

void Vektori::tulosta_xy_muodossa( ) const {cout << " (x, y) = ( " << x << ", " << y << " ) "

<< endl;}

void Vektori::tulosta_polaarimuodossa( ) const {// Tämä funktio ei tosiasiassa toimi aivan oikein:// jos esimerkiksi toinen koordinaatti on negatiivinen// ja toinen positiivinen, niin kulma saattaa olla// väärässä neljänneksessä. Ei vaikea korjata,// mutta esimerkin kannalta epäoleellinen.double r = sqrt(pow(x, 2) + pow(y, 2) );double a = atan(y / x) * 180 / PII;

cout << " (a, r) = ( " << a << "◦, " << r << " ) "<< endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 338: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 330

Luokat

▼ C++-kielen tarjoama työkalu abstraktien tietotyyppientoteuttamiseen on luokka (class).

▼ Luokka tarjoaa mahdollisuudet

– toteutuksen kätkemiseen käyttäjältä,

– rajapintafunktioiden toteuttamiseen ja

– edellämainittujen kapselointiin (encapsulation)yhdeksi kokonaisuudeksi.

▼ Luokat esitellään varatun sanan class avulla:class luokan_nimi {public:

...rajapinnan funktioiden esittelyt

...private:

...kätkettyjen tietoalkioiden esittelyt

...} ;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 339: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 331▼ Luokan esittelyn seurauksena käyttöön saadaan

uusi abstrakti tietotyyppi luokan_nimi, jolla voidaanoperoida vain rajapinnan funktioiden avulla.

▼ Tyypin toteutus määräytyy muuttujista kätketyt

tietoalkiot, joita ei ohjelmassa voi käyttää suoraan,mutta rajapinnan funktiot pääsevät niihin käsiksi.

▼ Rakentajaa✶ lukuunottamatta kaikkia luokanjäsenfunktioita kutsutaan käyttäen merkintätapaa:

muuttuja . funktio(parametrit ) ;

▼ Luokkaa voi jossain mielessä ajatella tietueena(struct), jonka kenttiin ei pääsekään käsiksi"."-operaattorilla, vaan on käytettävä luokanmukana tulevia rajapinnan funktioita.

▼ Todellisuudessa luokat ovat paljon enemmän, muttaaloittelijan kannalta tuo on hyvä analogia.

▼ Tutustutaan tarkemmin sekä luokan esittelynprivate-osaan että public-osaan ja niihin liittyviinyksityiskohtiin.

✶ ja sivulla 335 mainittua automaattista purkajaa

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 340: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 332

Luokan esittelyn private-osa

▼ Yleensä private-osassa esitellään muuttujat, joihinon tarkoitus tallettaa tietotyypin alkion kuvaava tieto(jäsenmuuttujat tai attribuutit).

▼ Esimerkiksi kaksiulotteisen avaruuden vektori voitiinesittää kahdella reaaliluvulla: sen x- ja y-koordinaatilla.

▼ Luokan käyttäjän kannalta private-osan sisällöllä eikuitenkaan ole merkitystä niin kauan kuin rajapinnanfunktiot toimivat odotusten mukaisesti.

▼ Vektori-tyyppi olisi voitu yhtä hyvin toteuttaa siten,että private-osassa olisikin kirjoitettu:

private:double kulma; // vektorin suuntakulmadouble pituus; // ja sen pituus

taiprivate:

double x_ja_y[2]; // koordinaatit taulukossa

▼ Kun jäsenfunktiot muutetaan uuden toteutuksenkanssa yhdenmukaisiksi, ei käyttäjä huomaa mitään.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 341: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 333▼ Jäsenmuuttujien tärkein ominaisuus on se, että ne

ovat käytettävissä jäsenfunktioissa ➠ voidaankirjoittaa funktioita, jotka pystyvät operoimaankätketyllä informaatiolla.

▼ Jäsenmuuttujien määrä ei ole mitenkään rajoitettu.

▼ Jäsenmuuttujat voivat olla tyypiltään mitä tahansakääntäjän tuntemaa tyyppiä, vaikka toisia luokkia.

▼ Ei ole yksikäsitteisesti oikeaa tapaa valita jonkinabstraktin tietotyypin jäsenmuuttujat (vrt. Vektori-tyypille keksityt kolme erilaista).

▼ Toteutuksen valintaan vaikuttavat ainakin– tehokkuussyyt,– makuasiat/esteettiset syyt,– selkeys/ylläpidettävyys ja– ohjelmoijan kyvyt.

▼ Periaatteessa private-osassa voi esitellä myösjäsenfunktioita ➠ yksityisen rajapinnan funktiot,joita voivat kutsua vain muut jäsenfunktiot.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 342: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 334

Luokan esittelyn public-osa

▼ Luokan public-osassa saa olla vain rajapinnanfunktioiden esittelyitä.

▼ Jäsenfunktioiden esittelyssä vaihtoehdot ovat:

Rakentajat

– Oltava samanniminen kuin luokka, jonkarakentaja se on.

– Rakentajalla ei ole paluuarvoa, eikä sitenpaluuarvon tyyppiä.

– Parametreja voi olla aivan normaalisti.

– Kutsutaan automaattisesti aina, kun ohjelmassaluodaan abstraktin tietotyypin muuttuja.

Valitsimet

– Esitellään kuten funktiot yleensä, muttaesittelyn perässä varattu sana const ➠ kertooettei funktio muuta jäsenmuuttujien arvoja ➠voidaan kutsua const-vakioilla.

– Valitsimilla voi olla parametreja ja paluuarvo.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 343: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 335Mutaattorit

– Esitellään kuten normaalit funktiot.

– Voivat modifioida jäsenmuuttujien arvoja

➠ ei voi kutsua const-vakioilla.

– Mutaattoreilla voi olla parametreja ja paluuarvo.

Purkajat

– Esimerkkiohjelmassa ei käytetty purkajia.

– C++:ssa on rakentajien kanssa analoginenmekanismi, jonka avulla purkajia kutsutaanautomaattisesti, kun abstraktin tietotyypinmuuttujan elinkaari päättyy.

– Purkajiin palataan kurssin loppupuolelladynaamisten tietorakenteiden yhteydessä ➠sitä ennen niille ei ole käyttöä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 344: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 336

Jäsenfunktioiden määrittely

▼ Jäsenfunktiot määritellään muutamaa poikkeustalukuunottamatta kuten funktiot yleensäkin ottaen.

▼ Funktioiden nimen edessä pitää kuitenkin kertoa,minkä abstraktin tietotyypin jäsenfunktiosta on kyse:

bool Vektori::lue_nappaimistolta( ) {...

}

▼ Valitsimissa pitää olla mukana const parametrilistanperässä:

double Vektori::hae_x_koord( ) const {...

}

▼ Funktion runko saa olla normaaliin tapaan mitä vainsuoritettavaa C++-koodia.

▼ Jäsenmuuttujat ovat käytettävissä jäsenfunktioidenrungossa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 345: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 337▼ Jos rakentajan halutaan alustavan jäsenmuuttujia,

niin se saadaan aikaan alustuslistan avulla:

Vektori::Vektori( ) : x(1.0), y(0.0) {}

▼ Eli jäsenmuuttujat, joille halutaan automaattisestiantaa alkuarvo, luetellaan parametrilistan perässäpilkuilla eroteltuina ja tarvittavat alkuarvot kerrottaansuluissa muuttujan nimen jälkeen.

▼ Rakentajalla voi olla parametreja; niistä esimerkkejämyöhemmin.

▼ Rakentajan rungossa voi olla käskyjä, mutta perus-tellusta syystä tätä ominaisuutta ei Ohjelmointi II:ssajuurikaan hyödynnetä (paitsi ehkä muutamassakohdassa).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 346: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 338

Sama esimerkki toisin

▼ Toteutetaan Vektori-tietotyyppi uudelleen havain-nollistaen sen avulla muutama olennainen asia(muutokset alkuperäiseen sävytettynä):

class Vektori {public:

Vektori( );

double hae_x_koord( ) const;double hae_y_koord( ) const;

void aseta_x_koord(double uusi_arvo);void aseta_y_koord(double uusi_arvo);bool lue_nappaimistolta( );void kierra_origon_ympari(double kulma);

void tulosta_xy_muodossa( ) const;void tulosta_polaarimuodossa( ) const;

private:double x;double y;

};

const double PII = 3.14159265358979323846;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 347: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 339

Vektori::Vektori( ): x(1.0), y(0.0) {}

double Vektori::hae_x_koord( ) const {return x;

}

double Vektori::hae_y_koord( ) const {return y;

}

void Vektori::aseta_x_koord(double uusi_arvo) {x = uusi_arvo;

}

void Vektori::aseta_y_koord(double uusi_arvo) {y = uusi_arvo;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 348: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 340

bool Vektori::lue_nappaimistolta( ) {cout << "Syötä vektori: " ;

double luettu_x;cin >> luettu_x;aseta_x_koord(luettu_x);

double luettu_y;cin >> luettu_y;aseta_y_koord(luettu_y);

if (!cin) {return false;

} else {return true;

}}

void Vektori::kierra_origon_ympari(double kulma) {double rad = kulma * PII / 180;double uusi_x = hae_x_koord( ) * cos(rad)

+ hae_y_koord( ) * sin(rad);double uusi_y = –hae_x_koord( ) * sin(rad)

+ hae_y_koord( ) * cos(rad);

aseta_x_koord(uusi_x);aseta_y_koord(uusi_y);

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 349: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 341

void Vektori::tulosta_xy_muodossa( ) const {cout << " (x, y) = ( "

<< hae_x_koord( )<< ", "<< hae_y_koord( )<< " ) "<< endl;

}

void Vektori::tulosta_polaarimuodossa( ) const {double r = sqrt(pow(hae_x_koord( ) , 2)

+ pow(hae_y_koord( ) , 2) ) ;double a = atan(hae_y_koord( ) / hae_x_koord( ) )

* 180 / PII;

cout << " (a, r) = ( " << a << ", " << r << " ) "<< endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 350: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 342

Siitä opittua

▼ Abstraktin tietotyypin jäsenfunktiot voivat kutsuatoisiaan.

▼ Tällöin ei käytetä pistenotaatiota, vaan funktiotakutsutaan »normaaliin» tapaan:

funktio(parametrit ) ;

▼ Tälläkin tavoin kutsuttu jäsenfunktio kohdistuukuitenkin samaan abstraktin tietotyypin muuttujaan,jonka välityksella alkuperäistä jäsenfunktiota

kutsuttiin:muuttuja . jäsenfunktio(parametrit ) ;

▼ Olennaisempi asia esimerkissä oli yksinkertainenluokan sisäinen tiedon kätkentä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 351: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 343

Toteutuksen »kätkeminen»

luokan sisällä

▼ Yksi abstraktien tietotyyppien tärkeistä ominaisuuk-sista on se, että tyypin toteutusta voidaan tarvittaessamuuttaa, kunhan rajapinta pysyy ennallaan.✶

▼ Muutosten tekemiseen tulee tarve esimerkiksihaluttaessa toteuttaa tyyppi tehokkaammin.

▼ Muutostyö on sitä helpompaa, mitä suurempiosa jäsenfunktioiden toteutuksesta voidaan eristäävarsinaisesta kätketystä tiedosta.

▼ Eli käytännössä: mitä suurempi osa jäsenfunktioistavoidaan toteuttaa pelkästään toisten jäsenfunktioidenavulla.

▼ Tämä käy esimerkkien tapauksessa paremmin selvillekuvallisesta esityksestä.

✶ Tai ainakin yhteensopivana alkuperäisen rajapinnan kanssa, jos siihenvaikka uusia jäsenfunktioita lisättäisiinkin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 352: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 344▼ Alkuperäisessä Vektori-luokan toteutuksessa kaikki

jäsenfunktiot käsittelivät suoraan jäsenmuuttujia:

x yhae_x_koord hae_y_koord

lue_nappaimistolta kierra_origon_ympari

tulosta_xy_muodossatulosta_polaarimuodossa

▼ Jos luokan kätkettyä toteutusta (x ja y) nytmuutetaan, niin kaikkia kuutta jäsenfunktiotajoudutaan myös säätämään.

▼ Jos jäsenfunktioita olisi enemmän, niin tehtävienmuutosten määrä kasvaisi tietenkin samassasuhteessa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 353: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 345▼ Uudemmassa versiossa ainoastaan hae- ja aseta-

funktiot käsittelevät x:ää ja y:tä suoraan.

▼ Muut jäsenfunkiot hoitavat työnsä niiden avulla:

x y

hae_x_koord hae_y_koord

aseta_x_koord aseta_y_koord

lue_nappaimistolta kierra_origon_ympari

tulosta_xy_muodossatulosta_polaarimuodossa

▼ Jos kätkettyä toteutusta nyt muutetaan, niinainoastaan hae- ja aseta-alkuisia jäsenfunktioita(4 kpl) pitää säätää, vaikka muita jäsenfunktioita olisienemmänkin, kunhan ne vain on toteutettu samanidean mukaisesti.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 354: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 346▼ Tällaisella luokan sisällä tapahtuvalla toteutuksen

kätkemisellä saavutetaan tietotyypille selkeämpirakenne ja helpompi ylläpidettävyys.

▼ Kuvissa esiintyviä katkoviivoitettuja laatikoitakutsutaan abstraktiorajoiksi (abstraction barrier).

▼ Abstraktiorajat kuvaavat tietotyypin jollain abstrak-tiotasolla ➠ mitä sisempi raja, sitä enemmän seottaa kantaa toteutuksen yksityiskohtiin.

▼ Tai kääntäen, mitä ulompi abstraktioraja, sitäabstraktimpana käsitteenä se tietotyypin esittää.

▼ Abstraktiorajojen rikkomista✶ pidetään yleisestikuolemansyntinä ja se on usein vihje huonostisuunnittelusta tyypistä/rajapinnasta.

▼ Yleensä kannattaa pyrkiä siihen, että tietoa käsitelläänmahdollisimman korkealla abstraktiotasolla ➠ mitäsisempi abstraktioraja, sitä vähemmän sen läpimenee riippuvuutta kuvaavia nuolia.

✶ Kutsutaan funktiota, joka kahta tai useampaa abstraktiotasoa kauempana.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 355: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 347

Mistä abstraktit tietotyypit tulevat?

▼ Aina kun ohjelmassa olisi tarkoituksenmukaistakäyttää rakenteista tietotyyppiä (taulukko tai tietue),se voidaan muuttaa abstraktiksi tietotyypiksi.

▼ Ohjelmissaan kannattaa lähes aina suosia abstraktiatietotyyppiä yli rakenteisen tietotyypin, vaikka sentoteuttamisessa onkin enemmän työtä.

▼ Jos rakenteinen muuttuja kuitenkin on vakio ja sitäkäytetään vain yhdessä kohdassa koko ohjelmassa,niin abstrakti tietotyyppi saattaisi olla yliampumista.

▼ Esimerkiksi seuraava pikku funktio on järkevätoteuttaa pelkän taulukon avulla:

enum Paiva { SU, MA, TI, KE, TO, PE, LA, PAIVAVIRHE };...

Paiva LyhenneViikonpaivaksi(string lyhenne) {const string LYHENTEET[ ] = {

"su", "ma", "ti" , "ke", "to", "pe", " la",};

for (int i = 0; i <= LA; ++i) {if ( lyhenne == LYHENTEET[i] ) {

return Paiva(i) ;}

}

return PAIVAVIRHE;} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 356: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 348

Abstraktien tietotyyppien hyödyt

▼ Abstraktien tietotyyppien suunnitteluun ja toteut-tamiseen liittyy jonkin verran enemmän työtä, kuinabstraktiorajoista piittaamattomaan rakenteistentietotyyppien käyttöön.

▼ Ne ovat kuitenkin ylimääräisen vaivan arvoisia:

– Mahdollistavat toteutuksen muuttamisen.

– Voidaan olla varmoja tiedon eheydestä:konstruktorit ja mutaattorit voivat huolehtia, ettäjäsenmuuttujat saavat vain laillisia arvoja.

– Mahdollistavat yhteenkuuluvien ohjelmistonosien esittamisen kokonaisuutena, mikä yleensäjohtaa ohjelmiston selkeämpään rakenteeseen,helpompaan testaamiseen ja ylläpidettävyyteen.

– Ovat helppokäyttöisempiä ja helpomminymmärrettäviä, koska muistettavia yksityiskohtiaon vähemmän.

– Abstraktit tietotyypit ovat usein uudelleenkäytet-

täviä (reusable).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 357: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 349

Funktioiden kuormittaminen

▼ Funktion kuormittamisella (overloading) tarkoi-tetaan sitä, että ohjelmassa voi olla useita samannimisiä funktioita, kunhan niiden parametrit ovatmäärältään ja/tai tyypiltään erilaisia.

▼ Kun ohjelmassa kutsutaan funktiota, joka onkuormitettu, kääntäjä tutkii kutsun todellistenparametrien määrän ja tyypit ja valitsee niidenpohjalta kutsuttavan funktion oikean version.

▼ Funktioiden kuormittaminen on arvokas työkalu,jos ohjelmassa on tarve suorittaa loogisesti samaoperaatio erityyppisille lähtötiedoille.

▼ Ajatellaan esimerkkinä operaatiota max, jolla ontarkoitus selvittää jonkin alkiojoukon suurin alkio.

▼ Lisäksi suunniteluvaiheessa on havaittu, ettätoteutuksessa täytyy välillä selvittää, mikä onkahdesta kokonaisluvusta suurin, ja välillä taas, mikäon kokonaislukutaulukon suurin alkio.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 358: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 350▼ Molemmat tapaukset ovat loogisesti suurimman

alkion valitsemista, mutta ne valitsevat alkionerityyppisistä lähtötiedoista.

▼ Jos kieli ei tukisi funktioiden kuormittamista, jäisiohjelmoijan vastuulle määritellä kaksi erinimistä

funktiota ja kutsua niitä oikeissa paikoissa:

#include <iostream>

using namespace std;

int max_kahdesta(int luku1, int luku2);int max_taulukosta( int taulukko[ ], int maara);

int main( ) {int i1 = 1000;int i2 = 1001;cout << "Suurin luvuista " << i1 << " ja " << i2

<< " on " << max_kahdesta(i1, i2) << endl;

int taulu[ ] = { 99, 20, 78, 64, 1001, 721 };const int koko = 6;cout << "Taulukon suurin alkio on "

<< max_taulukosta(taulu, koko) << endl;

}

// funktioiden max_kahdesta ja max_taulukosta

// määrittelyt tulevat tähän...

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 359: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 351▼ Kuormitus mahdollistaa saman elegantimmin:

#include <iostream>

using namespace std;

int max(int luku1, int luku2);int max(int taulukko[ ], int maara);

int main( ) {int i1 = 1000;int i2 = 1001;cout << "Suurin luvuista " << i1 << " ja " << i2

<< " on " << max(i1, i2) << endl;

int taulu[ ] = { 99, 20, 78, 64, 1001, 721 };const int koko = 6;cout << "Taulukon suurin alkio on "

<< max(taulu, koko) << endl;

}

// max–funktioiden määrittely tähän.

// Katso seuraavalta sivulta...

▼ Huomaa kuinka molemmat versiot ovat nytnimeltään max, mutta muodollisten parametrientyypeissä on eroja.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 360: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 352▼ Funktioiden toteutus olisi aivan normaali, olkoonkin

että niillä sattuu olemaan samat nimet:

int max(int luku1, int luku2) {if ( luku1 > luku2) {

return luku1;} else {

return luku2;}

}

int max(int taulukko[ ], int maara) {int suurin = taulukko[0];for (int i = 1; i < maara; i++) {

if (suurin < taulukko[i] ) {suurin = taulukko[i];

}}return suurin;

}

▼ Erilainen paluuarvon tyyppi ei tee esittelyltäänmuuten identtisistä funktioista kuormitettuja ➠seuraava yritys tuottaa käännösvirheen:

unsigned int max(int luku1, int luku2);int max(int luku1, int luku2); // VIRHE!

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 361: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 353

Funktion oletusparametrit

▼ Osa tai kaikki funktion parametrit voivat ollaoletusparametreja (default arguments) ➠ josohjelmoija ei funktiota kutsuessaan anna kaikkiatodellisia parametreja, C++ käyttää puuttuvilleparametreille automaattisesti oletusarvoja.

▼ Tutkitaan hieman naiivi esimerkki: oletetaan ettähalutaan tehdä funktio max, jolle voidaan antaaparametrina 2–4 luonnollista lukua, joista sepalauttaa suurimman.

▼ Ongelmaa voisi lähestyä kuormittamalla ➠määriteltäisiin funktiosta max kolme eri versiota:yksi kutakin tilannetta kohti.

▼ Kuormittaminen ei kuitenkaan ole tässä tilanteessahyvä ratkaisu, koska se johtaisi useaan tietyssämielessä identtiseen funktioon.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 362: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 354▼ Seuraava esimerkki havainnolistaa max-funktion

toteutuksen oletusparametreja käyttäen:

#include <iostream>

using namespace std;

unsigned max(unsigned u1, unsigned u2,unsigned u3 = 0, unsigned u4 = 0);

int main( ) {cout << "suurin joukosta (66, 32) on "

<< max(66, 32) << endl;cout << "suurin joukosta (66, 32, 72) on "

<< max(66, 32, 72) << endl;cout << "suurin joukosta (66, 32, 72, 90) on "

<< max(66, 32, 72, 90) << endl;

}

unsigned max(unsigned u1, unsigned u2,unsigned u3, unsigned u4) {

unsigned suurin = u1;

// Pahoittelemme tilanpuuttesta johtuvaa muikeaa if–rakennetta.

if (u2 > suurin) { suurin = u2; }if (u3 > suurin) { suurin = u3; }if (u4 > suurin) { suurin = u4; }

return suurin;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 363: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 355▼ Oletusparametrien arvot kerrotaan funktion

esittelyssä kirjoittamalla muodollisen parametrinperään "=" ja parametrin oletusarvo.

▼ Esimerkin funktiolla max on neljä parametria, muttakutsuttaessa ei välttämättä tarvitse antaa kuin kaksi.

▼ Jos kutsussa ei ole u3:a ja u4:ää vastaavia todellisiaparametreja, niiden tilalla käytetään max:inesittelyssä kerrottuja oletusarvoja (0 ja 0).

▼ Oletusarvoja voi antaa vain loppupään parametreille.▼ Tarvittaessa kaikilla parametreilla voi olla oletusarvo.▼ Oletusparametri voi olla myös lauseke ➠ se evaluoi-

daan uudelleen joka kerta funktiota kutsuttaessa(mikäli oletusparametria tarvitaan).

▼ Kuormittaminen ja oletusparametrit ovat useinkeskenään vaihtoehtoisia ➠ kannattaa harkitatarkkaan kumpi niistä soveltuu tilanteeseen paremin.

▼ Kuormitus ja oletusparametrit voivat toki ollakäytössä yhtä aikaa:

int max(int l1, int l2, int l3 = INT_MIN);int max(int taulukko[ ], int maara);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 364: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 356

Rakentajan parametrit

▼ Koska abstraktin tietotyypin rakentaja on periaat-teessa funktio muiden joukossa, voi silläkin ollaparametreja, sitä voi kuormittaa ja parametreilla voiolla oletusarvoja.

▼ Ajatellaan esimerkkinä luokkaa:

class Murtoluku {public:

Murtoluku( );Murtoluku(int os, int nim = 1);· · · muut jäsenfunktiot tässä · · ·

private:int osoittaja;int nimittaja;

};

Murtoluku::Murtoluku( ):osoittaja(0), nimittaja(1) {

}

Murtoluku::Murtoluku(int os, int nim):osoittaja(os), nimittaja(nim) {

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 365: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 357▼ Mutta mikä on parametrisoidun rakentajan merkitys?

Pääohjelma selvittää asian:

int main( ) {// Alustetaan parametrittomalla rakentajalla// (oletusrakentaja): mla saa arvon 0/1Murtoluku mla;

// Alustetaan parametroidulla rakentajalla// käyttäen oletusparametria: mlb saa arvon 2/1Murtoluku mlb(2);

// Alustetaan parametroidulla rakentajalla käyttäen// molempia parametreja: mlc saa arvon 3/4Murtoluku mlc(3, 4);

· · · esimerkin kannalta epäolennaisia rivejä poistettu · · ·}

▼ Rakentajalle välitettävät parametrit kerrotaan suluissamääriteltävän muuttujan nimen perässä.

▼ Riippuen parametrien määrästä ja tyypeistä kääntäjävalitsee sopivan rakentajafunktion.

▼ Vastaavaan järjestelyyn on törmätty aikaisemminkin:ifstream tietokanta("osoitteet.dat") ;vector<int> ivec(10);string mjono(100, ’*’);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 366: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 358▼ Rakentajia voidaan kutsua eksplisiittisesti ✶ (suoraan):

oletetaan esimerkiksi, että halutaan laskea 12:n ja 5

1:nkeskiarvo, kun käytettävissä on kahden murtoluvunkeskiarvon laskeva funktio Keskiarvo:

· · · aiempi Murtoluku-tyypin määrittely tähän · · ·Murtoluku Keskiarvo(Murtoluku ml1, Murtoluku ml2);

int main( ) {Murtoluku tulos;

// Tapa 1, ei mitään uutta miltään rintamalta:Murtoluku luku1(1, 2);Murtoluku luku2(5);tulos = Keskiarvo(luku1, luku2);

// Tapa 2, rakentajan kutsuminen eksplisiittisesti:tulos = Keskiarvo(Murtoluku(1, 2), Murtoluku(5) );

· · · esimerkin kannalta epäolennaisia rivejä poistettu · · ·}

· · · Keskiarvo-funktion määrittely tähän · · ·

▼ Eksplisiittistä rakentajan kutsua voi käyttää, jostarvitaan abstraktia tietotyyppiä olevaa »literaalia»

➠ vältytään turhien apumuuttujien käytöltä.

✶ Tämä on tarkasti ottaen virheellinen ilmaisu. Kyseessä on nimettömänmuuttujan luonti ja alustus. "Rakentajan eksplisiittinen kutsu" on kuitenkintässä vaiheessa niin havainnollinen ilmaisu, että se suotaneen anteeksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 367: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 359▼ Rakentajan eksplisiittisen kutsun arvoksi evaluoituu

siis abstraktin tietotyypin alkio, joka on alustettuparametrien mukaan sopivaa rakentajaa kutsumalla.

▼ Rakentajan eksplisiittisen kutsun voi tulkita myöstyyppikonversioksi (erityisesti siinä tilanteessa, kunkutsussa annetaan vain yksi parametri).

▼ Esimerkiksi seuraavassa koodissa

int kokonaisluku;Murtoluku murtoluku;

...murtoluku = Murtoluku(kokonaisluku);

rakentajan kutsu muuntaa muuttujan kokonaisluku

arvon vastaavaksi murtoluvuksi kokonaisluku1

.

▼ Myös string-tyypin ja STL-säiliöiden rakentajia voikutsua eksplisiittisesti:

// Tulostetaan 25 ’-- ’-merkkiä ja rivinvaihto.cout << string(25, ’-- ’) << endl;

// 7 riviä × 5 saraketta reaalilukumatriisi// joka kaikki alkiot on alustettu luvulla 1.0.vector<vector<double>> mat(7, vector<double>(5, 1.0));

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 368: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 360

Nimettömät eli lambda-funktiot ✶

▼ Tähänastisen kokemuksen mukaan funktiolla onoltava nimi ennen kuin sitä voi käyttää.

▼ Jos näin ei olisi, funktiota ei voisi kutsua, koskafunktiokutsun syntaksi määrää, että kutsu tapahtuukirjoittamalla koodiin:

funktion_nimi(mahdolliset_muodolliset_parametrit )

▼ Tosiasiassa monissa ohjelmointikielissä raja ohjelmankäsittelemän tiedon ja funktioiden välillä on hyvinepämääräinen tai on kadonnut tyystin.

▼ Funktiotkin ajatellaan tiedoksi, jota voidaan tallentaamuuttujiin, välittää toisille funktioille parametrina janiin edelleen.

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 369: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 361▼ Ohjelmointi I:ssä opittiin joskus käsitteet literaali ja

muuttuja.

▼ Literaali on tietoalkio, jolla on tyyppi ja arvo, muttaei nimeä (1234, "abc").

▼ Muuttuja on tietoalkio, jolla on tyyppi, arvo ja nimi(tulos, i, sukunimi).

▼ Funktioiden yhteydessä voidaan samaa logiikkanoudattaen puhua nimetyistä ja nimettömistäfunktioista.

▼ Nimetyissä funktioissa ei ole mitään uutta: ne ovatniitä samoja tuttuja funktioita, joita on käytetty jaosattu itsekin toteuttaa jo Ohjelmointi I:stä lähtien.

▼ Nimettömät funktiot eli lambda-funktiot ovat erään-laisia funktioliteraaleja: koko funktio määriteltynäjuuri siihen kohtaan koodia, jossa sitä tarvitaan(ilman nimeä).

▼ Ohjelmointi II-kurssin näkökulmasta nimettömienfunktioiden käyttökelpoisuus tulee siitä, että niitä voiantaa parametreina toisille funktioille.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 370: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 362▼ Käytännössä tämä tarkoittaa STL-algorithm-kirjaston

funktioita, joiden käyttäytymistä voidaan ohjatafunktioparametrin avulla.

▼ Esimerkiksi funktio sort, jolle voidaan kahdeniteraattorin lisäksi antaa parametrina vertailufunktio.

▼ Ensin perinteinen toteutus:

bool suurempi(const string& s1, const string& s2) {return s1 > s2;

}· · ·vector<string> svec;· · ·// Lajitellaan laskevaan järjestykseen:// suurin ensin, pienin viimeiseksi.sort(svec.begin( ), svec.end( ), suurempi);

▼ Edellisessä toteutuksessa ei ole mitään vikaa, muttajos suurempi-funktiota ei käytetä ohjelmassamihinkään muuhun, sen määrittely erillisenäfunktiona saattaa tuntua turhalta.

▼ Ainoa syy, miksi esimerkin vertailufunktiolle onannettu nimi (suurempi) on, jotta se voidaankirjoittaa sort-funktion viimeiseksi parametriksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 371: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 363▼ Esimerkissä käytetyn kaltaiselle «kertakäyttö-

funktiolle» ei ole välttämätöntä antaa nimeä, vaansama voitaisiin toteuttaa lambda-funktiona:

sort(svec.begin( ), svec.end( ),[ ] (const string& s1, const string& s2) –> bool {

return s1 > s2;}

) ;

▼ Edellisestä voi periaatteessa jo arvata lambda-funktioiden määrittelysyntaksin:

[ ] ( muodolliset_parametrit ) –> paluuarvon_tyyppi {funktion_runko

}

▼ Nippelitietona voi mainita, että –> paluuarvon_tyypin

voi jättää pois, jos funktion_runko on pelkkä return-käsky, jonka perässä olevan lausekkeen tyyppimäärää myös paluuarvon tyypin:

sort(svec.begin( ), svec.end( ),[ ] (const string& s1, const string& s2) {

return s1 > s2; // >–operaattori → bool}

) ;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 372: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 364▼ Lauseke s1 > s2 on tyypiltään bool, joten se on

edellisessä myös paluuarvon tyyppi.

▼ Lambda-funktioiden määrittelyn syntaksi onvalitettavan vaikeaselkoinen.

▼ Edellä esitetty riittää kuitenkin, jos ainoa mitä niidenavulla haluaa toteuttaa, on «kertakäyttöfunktiot»STL-algoritmien parametreiksi.

▼ Monissa muissakin ohjelmointikielissä✶ lambda-funktiot (tai lambda-lausekkeet) ovat käytettävissäosana kielen työkalupakkia.

▼ Muissa kielissä lambda-funktioiden syntaksi on useinselkeämpi, koska ne ovat olleet mukana kielensuunnittelussa alusta alkaen.

▼ Yleissivistävänä asiana tästä kappaleesta olisi hyväjäädä mieleen, että lambda-funktiot mahdollistavat

funktioiden käsittelyn tietoalkioina ➠ muuttujiintalletus, parametrina välittäminen, funktionpaluuarvo ja niin edelleen.

✶ Aivan erityisesti jokseenkin kaikissa tulkattavissa kielissä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 373: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 365

main-funktion parametrit

▼ Ajatellaan ohjelmaa akro, jolle voitaisiin käynnis-tysvaiheessa syöttää komentoriviltä sanoja, joidenalkukirjaimista se muodostaisi akronyymin:

proffa> ./akro Central Intelligence AgencyCIAproffa> ./akro Adaptive Radio Sampling EquipmentARSEproffa>

▼ Komentorivillä lueteltu tieto saadaan C++:ssaohjelman käyttöön main-funktiolle sopivastimääriteltyjen muodollisten parametrien välityksellä:

int main(int argc, char* argv[ ] ) {...

}

▼ Parametri argc kertoo komentorivillä annettujensanojen määrän (ohjelman nimi mukaanlukien) ➠argc on aina vähintään yksi.

▼ Parametri argv on taulukko, jonka alkiot sisältävätjärjestyksessä kaikki komentorivillä annetut sanat.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 374: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 366▼ Alkiossa argv[0] on ohjelman nimi.

▼ argv:n alkiot ovat C-kielestä periytyvää merkkijo-notyyppiä (char*), eivät kurssilla tutuksi tulluttastring-tyyppiä ➠ jos ja kun ohjelma haluaa käsitelläargv:n alkiota string-tyyppisinä, tyyppimuunnos onohjelmoijan vastuulla.

▼ Esimerkiksi tilanteessa:

proffa> ./akro Central Intelligence Agency

main:in muodollisissa parametreissa on arvot:

– argc:ssä sanojen määrä 4 ja

– argv sisältää merkkijonot:

./akro

Central

Intelligence

Agency

argv[0]

argv[1]

argv[2]

argv[3]

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 375: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 367▼ Akronyymiohjelman toteutus näyttää seuravalta:

#include <iostream>

#include <cstdlib>

#include <string>

using namespace std;

int main(int argc, char* argv[ ] ) {// Onko komentorivillä muuta kuin komennon nimi?if (argc > 1) {

// Silmukka lähtee liikkelle 1:stä, koska

// ohjelman nimeä ei ole tarkoitus käsitellä.for (int i = 1; i < argc; ++i) {

// Alkiossa argv[i] C–merkkijonona oleva

// komentorivin i:s sana muutetaan

// string–tyyppiseksi eksplisiitisellä

// tyyppikonversiolla string(... ).string sana = string(argv[i] ) ;

/ / Tulostetaan sanan ensimmäinen kirjain,

// sillä se on mukana akronyymissä.cout << sana.at(0);

}cout << endl;

}return EXIT_SUCCESS;

}

▼ Olennaiset asiat kommentteina ohjelmakoodissa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 376: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 368▼ Perinteisesti main:in muodollisia parametreja

kutsutaan argc:ksi ja argv:ksi,✶ mutta todellisuudessanimet voivat olla mitä tahansa, kunhan niidenjärjestys ja tyypit ovat oikein (int ja char*[ ]).

▼ Kannattaa vielä kerran korostaa, että main:inargumentit ovat C-merkkijonoja ➠ jos niidensisältämää informaatiota tarvitaan ohjelmassa jonkinmuun tyyppisenä (string, int, double jne) ontyyppimuunnos ohjelmoijan vastuulla.

▼ Lopuksi vielä yksityiskohta, jolla ei varsinaisesti olemitään tekemistä C++:n kanssa, mutta siihen törmääusein käytännön tilanteissa.

▼ Jos UNIX-komentotulkille syöttää käskyn:

proffa> ./etaisyys Boston Los Angeles

niin main-funktio saa argv:ssä neljä sanaa.

▼ Jos halutaan, että Los Angeles tulkitaan yhdeksisanaksi, se on kirjoitettava lainausmerkkien sisään:

proffa> ./etaisyys Boston "Los Angeles"

✶ Lyhenteitä ilmaisuista argument count ja argument vector.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 377: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 369▼ Jos char* -tyyppisten C-merkkijonojen käsittely

tuntuu epämiellyttävältä, voi argv-taulukonmuuntaa helposti STL-vektoriksi:

vector<string> argvec(argv, argv+argc);

▼ Tuloksena saadaan merkkijonovektori argvec, jossaon kaikki argv:n sanat samassa järjestyksessä.

▼ Edellinen alustus perustuu siihen, että

– STL-säiliö voidaan alustaa jossain toisessa säiliössäiteraattorivälillä olevilla alkioilla,

– STL-mahdollistaa taulukoiden käsittelyn säiliöinä,jolloin iteraattorina toimii taulukkomuuttujan nimilisättynä tai vähennettynä jollain kokonaisluvulla ja

– char* -merkkijonosta on määritelty automaattinentyyppikonversio string-merkkijonoksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 378: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 370

main-funktion paluuarvo

▼ C++:ssa main-funktion paluuarvon tyyppi on int:

int main(...

▼ main:in suorituksen pitää siis aina päättyä käskyynreturn int_lauseke, joka määrää minkä arvon main

palauttaa.

▼ Normaalisti funktion paluuarvo evaluoituu funk-tiokutsun arvoksi, mutta koska main:ia kutsutaanautomaattisesti, niin minne sen paluuarvo päätyy?

▼ main:in paluuarvo välitetään tavalla tai toisellaohjelman käynnistäneelle ympäristölle.

▼ Esimerkiksi UNIX-järjestelmissä paluuarvo päätyykäyttäjän komentotulkille, joka voi sitten hyödyntääpaluuarvoa, tai olla hyödyntämättä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 379: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 371▼ Useissa komentotulkeissa on muuttuja $status,✶ jonka

arvo on on viimeisimmän suoritetun komennonmain-funktion paluuarvo (status tai exit-status):

proffa> ./akro New MexicoNMproffa> echo $status0

▼ akro-ohjelman paluuarvo on 0, koska EXIT_SUCCESS

on cstdlib-kirjastossa määritelty jotenkin seuraavasti:

const int EXIT_SUCCESS = 0;

▼ Vastaavasti EXIT_FAILURE on määritelty joksikinnollasta poikkeavaksi arvoksi.

▼ Tämä käytäntö johtuu siitä, että UNIX-järjestelmätulkitsee ohjelman paluuarvon 0 onnistumiseksija kaikki muut arvot ilmaisevat, että ohjelmansuorituksessa meni jotain pieleen (ohjelma päättyivirhetilanteeseen).

✶ On syytä korostaa, että kyseessä on komentotulkin muuttuja, jolla ei olemitään tekemistä C++-ohjelman muuttujien kanssa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 380: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 372▼ main:in paluuarvo on siis tapa palauttaa tietoa

ajonaikaiselle ympäristölle.

▼ Usein ohjelma voi joutua erilaisiin virhetilanteisiin,jotka aiheuttavat sen suorituksen päättymisen

➠ jokaiselle virheelle kannattaa antaa omakokonaislukukoodinsa, jonka main voi sittenvirhetilanteessa palauttaa.

▼ Komentotulkki on ohjelmointikieli itsessään jasisältää mm. oikosulkevat | | - ja &&-operaattorit,jotka toimivat yhteen main:in paluuarvojen kanssa:

– Tiedosto data.txt tulostetaan näytölle vain, jos seon olemassa (»test –f» palauttaa nollan vain, jossen parametritiedosto on olemassa):

proffa> test –f data.txt && cat data.txt

– Tulostetaan ilmoitus »Tiedostoa ei ole» vain, jos»test –f» epäonnistuu (paluuarvo on nollastapoikkeava, jos parametritiedosto ei ole olemassa):

proffa> test –f data.txt | | echo "Tiedostoa ei ole"

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 381: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 373

Modulaarisuus ja moduulit

▼ Ohjelmaa kutsutaan modulaariseksi silloin, kun

1. se on jaettu loogisesti yhteenkuuluviin osiin elimoduuleihin, joita

2. voidaan kehittää ja ylläpitää toisistaan erillään.

▼ Modulaarisuus on malli/päämäärä, jonka mukaanohjelmia tulisi suunnitella ja toteuttaa, jottalopputulos on selkeämpi ja hallitavampi.

▼ Moduuli puolestaan tarkoittaa puhujasta jatilanteesta riippuen jompaa kumpaa tai molempia:

1. Ohjelman looginen osakokonaisuus.

2. Ohjelmointikielen tarjoama työkalu, jolla modu-laarisuus saadaan esitettyä kyseisellä ohjelmointi-kielellä.✶

▼ Esimerkki valaisee käsitteet parhaiten, määritelmiinkannattaa kuitenkin palata esimerkin jälkeen.

✶ Varsinkin C- ja C++-ohjelmoijille tyypillinen näkemys.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 382: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 374

Esimerkki

Ohjelman kuvaus

▼ Tehdään ohjelma, joka osaa lukea seuraavanmuotoisen tietokannan tiedostosta ohjelmat.dat:

* :YLEn uutiset:1:20.30

ma:TV3n uutiset:3:21.00ti–su:TV3n uutiset:3:22.00

pe-ma:Piirrettyjä:BBC Prime:09.00

#En tykkää enää kauniista ja rohkeista#ma–pe:Kauniit ja rohkeat:3:17.30

ti :Kameleontti :2:19.15ti :Makupalat:2:20.00

......monen hyvän ohjelman tiedot puuttuvat tästä...

...

to:Teho-osasto:3:21.00

la:Dr Who:BBC Prime:10.30la:Dr Who:BBC Prime:19.00

su:Kukkulan kuningas:3:14.45su:Simpsonit:3:15.30su:Kova laki:2:19.15su:People’s Century:BBC Prime:20.55

ja kertoa sitten, mitä hyvää televisiossa on tänään.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 383: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 375▼ Tietokannan rivit ovat siis muotoa:

viikonpaivan_lyhenne :ohjelman_nimi :kanava :alkuaika

tai# kommenttirivi

tai

ne ovat tyhjiä/sisältävät pelkkiä välilyöntejä.

▼ Kommenttirivit ja tyhjät rivit ohjelma jättäähuomioimatta.

▼ Viikonpaivän lyhenne-kentän arvo jokin seuraavista:

ma, ti, ke, to, pe, la tai su

tarkoittaa kyseistä viikonpäivää.

päivä1 – päivä2

tarkoittaa mitä tahansa päivää annettujenpäivien välissä päätepisteet mukaanlukien.

* tarkoittaa mitä tahansa viikonpäivää.

▼ Muut kentät saavat olla mitä vain ➠ ohjelma eitee niille sen kummempia virhetarkasteluita.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 384: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 376▼ Ohjelma toimii seuraavan kaltaisesti, kun oletetaan

että viikonpäivä on sunnuntai:proffa> ./tvohjelmat20.30 YLEn uutiset (1)22.00 TV3n uutiset (3)09.00 Piirrettyjä (BBC Prime)14.45 Kukkulan kuningas (3)15.30 Simpsonit (3)19.15 Kova laki (2)20.55 People’s Century (BBC Prime)proffa>

Algoritmi hyvin yleisellä tasolla

▼ Ylimmän tason algoritmi näyttäisi seuraavalta:

Algoritmi: Tulosta TV-ohjelmat

1. ohjelmatiedot← lue ohjelmatietokanta

2. viikonpäivä ← selvitä tämänhetkinen

viikonpäivä

3. tulosta ohjelmatiedoista kyseisen viikonpäivän

ohjelmien tiedot

▼ Yksityiskohtaistamisen varaa olisi vaikka kuinka,mutta tuo palvelee tämän esimerkin tarkoitustariittävän hyvin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 385: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 377▼ Esitetystä algoritmista löytää pienellä miettimisellä

selkeitä loogisia osakokonaisuuksia:

1. ohjelmatietokannan lukeminen ja jäsentely,

2. tietotyyppi, johon ohjelmatiedot talletetaan jakyseisellä tyypillä operointi,

3. viikonpäivän esittävä tietotyyppi ja tämänhet-kisen viikonpäivän selvittäminen sekä

4. toiminnot jotka kontrolloivat edellisten suoritus-järjestystä (siis pääohjelma).

▼ Osakokonaisuudet ovat kuitenkin sen verran suuria,että niiden toteuttaminen vaatii enemmän kuinyhden funktion ➠ ne muodostuvat useammanaliohjelman/tietotyypin yhteistyön tuloksena.

▼ Löydetyt 4 osakokonaisuutta muodostavat tulevanohjelman moduulijaon eli ne ovat sen moduulit.

▼ Nähtäväksi jää enää, kuinka moduulit esitetäänC++-kielellä, siis ohjelman toteutus.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 386: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 378Ohjelman toteutus

// Moduuli: tvohjelmat.cc

// Pääohjelmamoduuli.

#include <cstdlib>

#include <string>

using namespace std;

#include "viikonpaivat.hh"

#include "tietokanta.hh"

#include "ohjelmatiedot.hh"

const string TIETOKANTA = "ohjelmat.dat" ;

int main( ) {Ohjelmatiedot tiedot;

if ( !LueTietokanta(TIETOKANTA, tiedot) ) {return EXIT_FAILURE;

}

Paiva viikonpaiva = MikaViikonpaivaTanaan( ) ;

tiedot.tulosta_paivan_tiedot(viikonpaiva);

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 387: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 379// Rajapinta: viikonpaivat.hh

// Viikonpäivien käsittelyn hoitavan

// moduulin julkinen rajapinta.

#ifndef VIIKONPAIVAT_HH

#define VIIKONPAIVAT_HH

#include <string>

using namespace std;

// Sunnuntain arvo on 0 johtuen anglosakseja

// myötäilevästä kirjastofunktiosta localtime( ).

enum Paiva {SU, MA, TI, KE, TO, PE, LA,

VIRHEELLINEN_VIIKONPAIVA};

Paiva MikaViikonpaivaTanaan( );

Paiva LyhenneViikonpaivaksi(string lyhenne);

#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 388: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 380// Moduuli: viikonpaivat.cc

// Viikonpäivien käsittelyn hoitava moduuli.

#include <string>

// ctime on UNIX–systeemien standardikirjasto,

// joka sisältää ajanlaskun käsittelyyn liittyviä

// tietotyyppejä ja funktioita.

#include <ctime>

using namespace std;

#include "viikonpaivat.hh"

// – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

// Moduulin julkisen rajapinnan funktioiden määrittelyt

// Tätä funktiota ei tarvitse ymmärtää,

// kunhan uskoo sokeasti että se palauttaa

// kutsuhetken viikonpäivän.Paiva MikaViikonpaivaTanaan( ) {

// time( ) palauttaa kellonajan sekunneissa

// vuoden 1970 alusta GMT–aikavyöhykkeellä.

// time_t on tietotyyppi, joka esittää kyseisiä sekunteja.time_t aika = time(0);

// localtime( ) muuttaa sekunnit tietueosoittimeksi,

// joka esittää kellonaikaa paikallisella

// aikavyöhykkeellä ja jossa on viikonpäivän

// kertova kenttä tm_wday (su = 0, ma = 1, ... ).return static_cast<Paiva>(localtime(&aika) –>tm_wday);

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 389: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 381// Funktio selvittää kaksikirjaimista lyhennettä

// vastaan viikonpäivän ja palauttaa sen.

// Virhetilanteessa paluuarvo VIRHEELLINEN_VIIKONPAIVA.

Paiva LyhenneViikonpaivaksi(string lyhenne) {const string PAIVIEN_LYHENTEET[ ] = {

"su", "ma", "ti" , "ke", "to", "pe", "la" ,};

for (int i = 0; i <= LA; ++i) {if (lyhenne == PAIVIEN_LYHENTEET[i] ) {

return static_cast<Paiva>(i) ;}

}

return VIRHEELLINEN_VIIKONPAIVA;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 390: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 382// Rajapinta: tietokanta.hh

// Ohjelmatietokantaa lukevan

// moduulin julkinen rajapinta.

#ifndef TIETOKANTA_HH

#define TIETOKANTA_HH

#include <string>

using namespace std;

#include "ohjelmatiedot.hh"

bool LueTietokanta(string tiedosto, Ohjelmatiedot& tiedot) ;

#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 391: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 383// Moduuli: tietokanta.cc

// TV–ohjelmatietokannan lukemisen

// hoitava moduuli.

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

#include "tietokanta.hh"

#include "ohjelmatiedot.hh"

#include "viikonpaivat.hh"

// – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

// Moduulin yksityisen rajapinnan esittelynamespace {

bool TarvitseekoProsessoida(string rivi) ;

bool HaeKentta(string& rivi, string erotin, string& kentta);bool AsetaAikavali(string mjono, Paiva& alku, Paiva& loppu);

}

// – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

// Moduulin julkisen rajapinnan funktioiden määrittelyt

// Funktio lukee tiedoston läpi rivi kerrallaan, paloittelee rivin ja

// lisää siltä löytämänsä ohjelman informaation tiedot–muuttujaan.

// Jos virheitä ei tapahdu, paluuarvo true. Kaikki virhetilanteet

// palauttavat false.bool LueTietokanta(string tiedosto, Ohjelmatiedot& tiedot) {

ifstream tietokanta(tiedosto.c_str( ) ) ;

if ( !tietokanta) {cerr << "Tietokantaa ei saa avattua luettavaksi."

<< endl;

return false;} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 392: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 384string rivi;

while(getline(tietokanta, rivi) ) {if ( !TarvitseekoProsessoida(rivi) ) {

continue;

}

string paivastr;

if ( !HaeKentta(rivi, " : ", paivastr) ) {cerr << "Rivillä on vain yksi kenttä."

<< endl;return false;

}

Paiva alkupaiva;Paiva loppupaiva;

if ( !AsetaAikavali(paivastr, alkupaiva, loppupaiva) ) {return false;

}

string nimi, kanava;

if ( !HaeKentta(rivi, " : ", nimi) | | !HaeKentta(rivi, " : " , kanava) ) {cerr << "Rivillä liian vähän kenttiä."

<< endl;return false;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 393: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 385string alkuaika = rivi;

// Koska viikonpaivien numerointi alkaa

// joka sunnuntai uudelleen nollasta, aiheuttaa

// viikonlopun yli menevä aikaväli pulmia.if (alkupaiva > loppupaiva) {

// esimerkiksi pe–ma on sama kuin

// pe–la + su–mafor (int i = alkupaiva; i <= LA; i++) {

if ( !tiedot.lisaa_ohjelma(static_cast<Paiva>(i) ,nimi, kanava, alkuaika) ) {

return false;}

}

for (int i = SU; i <= loppupaiva; i++) {if ( !tiedot.lisaa_ohjelma(static_cast<Paiva>(i) ,

nimi, kanava, alkuaika) ) {return false;

}}

// Muutoin käydään normaalisti koko aikaväli läpi.} else {

for (int i = alkupaiva; i <= loppupaiva; i++) {if ( !tiedot.lisaa_ohjelma(static_cast<Paiva>(i) ,

nimi, kanava, alkuaika) ) {return false;

}}

}}

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 394: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 386// – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

// Moduulin yksityisen rajapinnan funktioiden määrittelyt

namespace {

// Tutkii rivin ja päättelee pitääkö sitä

// prosessoida edelleen vai voiko sen heittää menemään.

// Paluuarvo true jos pitää prosessoida, false muuten.bool TarvitseekoProsessoida(string rivi) {

const char KOMMENTTIMERKKI = ’#’;

/ / Kommenttiriviä ei prosessoidaif (rivi.length( ) == 0 | | rivi.at(0) == KOMMENTTIMERKKI) {

return false;}

for (unsigned int i = 0; i < rivi.length( ); ++i) {// Jos i:s merkki ei ole välilyönti,

/ / niin rivi ei muodostunut pelkästään

// välilyönneistä ja se on prosessoitava.

if (rivi.at(i) != ’ ’ ) {return true;

}}

// Tähän päädytään jos rivi oli tyhjä

// tai täynnä pelkkiä välilyöntejä.return false;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 395: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 387// Koska laillinen viikonpäivän merkintä tietokannassa voi olla

// *, ma, ti, .., su tai päivä1–päivä2, tämä funktio tunnistaa

// mjono:sta kyseisen merkinnän ja asettaa alku ja loppu

// muuttujaparametrien arvot vastaavasti. Paluuarvo on true,

// jos mjono oli laillinen merkintä, muussa tapauksessa false.

bool AsetaAikavali(string mjono, Paiva& alku, Paiva& loppu) {const string KAIKKI_PAIVAT = "*";

/ / Rivillä ollut viikonpäivä muotoa: *

if (mjono == KAIKKI_PAIVAT) {alku = SU;

loppu = LA;

// Rivillä ollut viikonpäivä muotoa: paiva1–paiva2

} else if (mjono.find( " – " ) != string::npos) {string apu;

if ( !HaeKentta(mjono, " – ", apu) ) {alku = loppu = VIRHEELLINEN_VIIKONPAIVA;

} else {alku = LyhenneViikonpaivaksi(apu);

loppu = LyhenneViikonpaivaksi(mjono);}

// Rivillä ollut viikonpäivä oli kaksikirjaiminen lyhenne

} else {alku = loppu = LyhenneViikonpaivaksi(mjono) ;

}

if (alku == VIRHEELLINEN_VIIKONPAIVA

| | loppu == VIRHEELLINEN_VIIKONPAIVA) {cerr << "Rivillä virheellinen viikonpäivämerkintä."

<< endl;return false;

}

return true;

}▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 396: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 388// Vanha tuttu HaeKentta( )

bool HaeKentta(string& rivi, string erotin, string& kentta) {string::size_type erottimen_sijainti = rivi.find(erotin);

if (erottimen_sijainti == string::npos) {return false;

}

kentta = rivi.substr(0, erottimen_sijainti) ;

rivi.replace(0, erottimen_sijainti + 1, " " ) ;

return true;

}

} // Tämä on parin sivun takaisen namespace:n loppusulku.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 397: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 389// Rajapinta: ohjelmatiedot.hh

// Abstraktin tietotyypin Ohjelmatiedot

// toteuttavan moduulin julkinen rajapinta.

#ifndef OHJELMATIEDOT_HH

#define OHJELMATIEDOT_HH

#include <string>

using namespace std;

#include "viikonpaivat.hh"

class Ohjelmatiedot {public:

Ohjelmatiedot( );

void tulosta_paivan_tiedot(Paiva paiva) const;

bool lisaa_ohjelma(Paiva paiva, string nimi,string kanavalla, string alkaa);

private:struct Ohjelma {

Paiva paiva;string ohjelman_nimi;string kanava;string alkuaika;

};

enum { MAX_OHJELMIA = 1000 };

Ohjelma tiedot[MAX_OHJELMIA];int montako_kaikkiaan;

};

#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 398: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 390// Moduuli: ohjelmatiedot.cc

// Abstraktin tietotyypin Ohjelmatiedot

// toteuttava moduuli.

#include <iostream>

#include <string>

using namespace std;

#include "ohjelmatiedot.hh"

#include "viikonpaivat.hh"

// – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

// Moduulin julkisen rajapinnan funktioiden määrittelyt

Ohjelmatiedot::Ohjelmatiedot( ): montako_kaikkiaan(0) {}

// Tulostaa rakenteeseen talletetuista ohjelmatiedoista

// kaikki parametripaivan ohjelmat.void Ohjelmatiedot::tulosta_paivan_tiedot(Paiva paiva) const {

for (int i = 0; i < montako_kaikkiaan; ++i) {if (tiedot[i].paiva == paiva) {

cout << tiedot[i].alkuaika << " "

<< tiedot[i].ohjelman_nimi << " ( "<< tiedot[i].kanava << " ) "

<< endl;}

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 399: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 391// Tallettaa tietorakenteeseen ohjelman tiedot:

// esityspäivä, ohjelman nimi, esityskanava, alkuaika.

// Paluuarvo true, jos talletus onnistuu, false

// jos tila loppuu kesken.bool Ohjelmatiedot::lisaa_ohjelma(Paiva paiva, string nimi,

string kanavalla, string alkaa) {if (montako_kaikkiaan >= MAX_OHJELMIA) {

cerr << "Ohjelmatiedoilta loppui tila." << endl;

return false;}

tiedot[montako_kaikkiaan].paiva = paiva;

tiedot[montako_kaikkiaan].ohjelman_nimi = nimi;tiedot[montako_kaikkiaan].kanava = kanavalla;

tiedot[montako_kaikkiaan].alkuaika = alkaa;

++montako_kaikkiaan;

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 400: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 392Ohjelman kääntäminen

▼ Lähdekoodimoduuleja voidaan periaatteessakääntää yksi kerrallaan ja yhdistää näin saadutobjektitiedostot suoritettavaksi ohjelmaksi ➠tästä lisää myöhemmin.

▼ Tässä vaiheessa riittää kuitenkin, että pystytäänkääntämään kaikki moduulit kerralla:

proffa> ohj2c++ –o tvohjelmattvohjelmat.cc viikonpaivat.cctietokanta.cc ohjelmatiedot.cc

proffa>

kirjoitettuna yhdelle rivillä ilman (selkeyden vuoksilisättyjä) rivinvaihtoja ja sisennyksiä.

▼ Tärkeää on huomata, että kääntäjälle syötetään

vain .cc-tiedostot, ei koskaan .hh-tiedostoja.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 401: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 393

Siitä opittua

▼ Abstraktin tietotyypin esittely voi sisältää yksityisessärajapinnassaan (private-osa) myös tietotyyppejä ➠ainoastaan jäsenfunktiot voivat käyttää niitä.

▼ Luettelotyypin alkioita voi käyttää kokonaisluku-

vakioina, mikä onkin suositeltu tapa, jos halutaanluokan sisäisiä vakioita.

▼ Vaikkei esimerkissä näin ollutkaan, niin tosiasiassatietotyyppejä ja const-vakioita voidaan määritellämyös julkisessa rajapinnassa (public-osa): tämä onjoskus hyödyllinen ominaisuus.

▼ Olennaisin uutuus esimerkissä oli C++:n tapamoduulien toteuttamiseen:

1. Moduulin julkisen rajapinnan esittely otsikkotie-dostossa (.hh-tiedosto).

2. Moduulin yksityinen rajapinta ja julkisen raja-pinnan toteutus .cc-tiedostossa.

ja muut niihin liittyvät käytännön yksityiskohdat.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 402: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 394

Moduuleista yleisesti

▼ Moduulit ovat ohjelman loogisia osakokonaisuuksia

➠ joukko funktioita, tietotyyppejä ja tietoa, jotkayhdessä toteuttavat jonkin ohjelman osan.

▼ Moduuleihin liittyvät samat käsitteet kuin abstrak-teihin tietotyyppeihin:

Julkinen rajapinta

Ne moduulin osat (funktiot, tietotyypit ja tieto),joita voidaan käyttää moduulin ulkopuolella.

Yksityinen rajapinta

Ne moduulin osat, joita vain moduuli itsevoi käyttää hyväkseen ➠ käytännössä siistoteutusyksityiskohdat.

▼ Moduulit ovat siis työkalu abstraktioiden luomiseen

➠ taas uusi apuväline, joka auttaa hallitsemaanohjelmalla ratkaistavaan ongelmaan liittyväämonimutkaisuutta abstraktioiden avulla.

▼ Moduuleiden tarkoitusta kuvaa muinainen totuus:hajoita ja hallitse.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 403: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 395▼ Modulaarisuus täytyy ottaa huomioon jo ohjelman

suunnitteluvaiheessa:

– Tunnistetaan ongelman ratkaisun osakokonai-suudet (siis moduulit).

– Määrätään löydettyjen moduulien julkisetrajapinnat: mitä palveluita moduulin täytyy tarjota,jotta kaikki sen edustaman osakokonaisuudentoiminnot saadaan hoidettua.

▼ Kun rajapinta on lyöty suunnitteluvaiheessa lukkoon,niin periaatteessa eri moduuleita voidaan kehittäärinnan ➠ moduulin julkisen rajapinnan käyttäjiäei kiinnosta toteutusyksityiskohdat (yksityinenrajapinta), niin kauan kuin julkinen rajapinta tarjoaasovitut palvelut.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 404: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 396

Moduulien toteuttaminen C++:lla

▼ C++-kielessä moduuli koostuu kahdesta osasta:

esittely- eli otsikko- eli .hh-tiedosto✶

– Julkisen rajapinnan funktioiden ja tietotyyppienesittelyt ja mahdollisesti const-vakioidenmäärittelyjä.

– Ei saa sisältää funktioiden ja muuttujienmäärittelyjä.

määrittely- eli toteutus- eli .cc-tiedosto✶

– Julkisen rajapinnan funktioiden määrittelyt.

– Yksityisen rajapinnan funktioiden ja tietotyyp-pien määrittelyt.

▼ Moduulin esittely- ja määrittelytiedosto on syytänimetä samoin ➠ ainoastaan pääte on erilainen.

▼ Tutkitaan kumpaakin yksityiskohtaisemmin.

✶ Päätteet .hh ja .cc vaihtelevat riippuen systeemistä ja käytetystäkääntäjästä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 405: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 397

Esittely- eli .hh-tiedostot

▼ Moduulin xyz esittelytiedostolla xyz.hh on yleensäseuraavan kaltainen rakenne:

// Tiedoston alussa kommentit, jotka kertovat tiedoston// nimen, tarkoituksen, versionumeron, tekijän jne.

#ifndef XYZ_HH#define XYZ_HH

// .hh–tiedostossa tarvittavien systeemikirjastojen includet#include <...>...

using namespace std;

// .hh–tiedostossa tarvittavien käyttäjän// omien moduulien includet#include "... "...

/ / julkisen rajapinnan tietotyyppien esittelytclass ... {

...};enum ... { ... };

...

/ / julkisen rajapinnan const–vakioiden määrittelytconst int XYZ_VIRHE = –1;...

/ / julkisen rajapinnan funktioiden esittelytvoid xyz_tulosta( ... );

...

#endif ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 406: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 398▼ Esitetty rakenne ja kohtien järjestys riippuu tietysti

tilanteesta.

▼ Esimerkiksi .hh-tiedosto moduulille, joka toteuttaaabstraktin tietotyypin, sisältää tyypillisesti vainosan esitellyistä kohdista (vrt. esimerkkiohjelmanohjelmatiedot.hh).

▼ Jollei erityistä syytä ole, niin kannattaa pitäytyäannetussa järjestyksessä ➠ esittelytiedostoillayhdenmukainen rakenne.

▼ Huomaa, että pääohjelmamoduulilla ei tavallisestiole esittelytiedostoa.

▼ C++-ohjelmissa #-merkillä alkavat rivit ovat käskyjänk. esiprosessorille, joka käy tiedoston läpi ennenkuin se syötetään kääntäjälle.

▼ Esiprosessorin käskyt ovat yksinkertaisia: se suorittaalähinnä tekstin korvausta ja hyvin yksinkertaistamuuttujien✶ käsittelyä.

✶ Esiprosessorin omia muuttujia (makroja), niillä ei ole mitään tekemistäC++-ohjelman muuttujien kanssa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 407: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 399▼ Kurssin kannalta hyödyllisin esiprosessorin käsky on

#include, joka lukee perässään annetun tiedostonsisällön osaksi ohjelmakoodia ➠ sen avulla luetaanmoduulien julkisten rajapintojen esittelytiedot osaksikäsiteltävää lähdekooditiedostoa.

▼ Jos tiedoston nimi on hakasulkeissa

#include <esittelytiedosto>

niin esittelytiedosto haetaan jostain systeemin vakio-paikasta ➠ standardikirjastojen esittelytiedostot.

▼ Huomaa, että standardikirjastojen esittelytiedostojennimissä ei ole .hh-päätettä.

▼ Jos nimi taas on lainausmerkeissä

#include "esittelytiedosto.hh"

niin esittelytiedosto.hh luetaan samasta hakemistosta,jossa käsiteltävä lähdekooditiedosto on ➠ käyttäjänomien moduulien esittelytiedostot.

▼ #ifndef-, #define- ja #endif-rivit pitävät huolta siitä,ettei hämminkiä synny, vaikka sama esittelytiedostoluetaan osaksi samaa lähdekooditiedostoa useamminkuin kerran.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 408: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 400▼ Tuollaistahan saattaa tapahtua kulissien takana lähes

huomaamatta:

tvohjelmat.cc

viikonpaivat.hh viikonpaivat.hh

viikonpaivat.hh

tietokanta.hh

ohjelmatiedot.hh

ohjelmatiedot.hh

▼ Esimerkkiohjelmassa viikonpaivat.hh luetaan siisosaksi tvohjelmat.cc-tiedostoa kolmesti.

▼ Jos tähän ei jotenkin varauduttaisi, niin kääntäjävalittaisi että viikonpaivat.hh:ssa määriteltytietotyyppi Paiva on määritelty useammin kuinkerran.

▼ C++-esittelytiedostoissa tämä hoidetaan idiomilla:

#ifndef MODUULIN_NIMI_ISOILLA_KIRJAIMILLA_HH#define MODUULIN_NIMI_ISOILLA_KIRJAIMILLA_HH

...moduulin julkisen rajapinnan esittely tässä välissä

...#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 409: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 401▼ Tässä kohdassa on hyvä täydentää sivun 29 kaavio

kääntämisen vaiheista vastaamaan C++-totuutta:

Lähdekoodi

Esiprosessori

Kääntäjä

Objektitiedosto Kirjastot

Linkkeri

Suoritettava ohjelma

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 410: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 402

Määrittely- eli .cc-tiedostot

▼ Moduulin xyz määrittelytiedostolla xyz.cc on yleensäseuraavan kaltainen rakenne:

// Tiedoston alussa kommentit, jotka kertovat tiedoston// nimen, tarkoituksen, versionumeron, tekijän jne.

// .cc–tiedostossa tarvittavien systeemikirjastojen includet#include <...>

...

/ / Käytetään "using namespace std" –käskyä uskollisesti/ / vaikkei sitä varsinaisesti ole tarkoitus käyttää näin.using namespace std;

// .hh–tiedostossa tarvittavien käyttäjän omien// moduulien includet, mukana lähes poikkeuksetta// moduulin oma esittelytiedosto.#include "xyz.hh"#include "... "

...

/ / moduulin yksityisen rajapinnan tietotyyppien esittelyt.struct ... {

...};enum ... { ... };

...

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 411: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 403// moduulin yksityisen rajapinnan// const–vakioiden määrittelyt.const int XYZ_MAX = ... ;

...

/ / moduulin yksityisen rajapinnan funktioiden esittelyt.namespace {

void xyz_lajittele( ... );...

}

// moduulin julkisen rajapinnan funktioiden määrittelyt.void xyz_tulosta( ... ) {

...}...

/ / moduulin yksityisen rajapinnan funktioiden määrittelyt.namespace {

void xyz_lajittele( ... ) {...

}...

}

▼ Järjestys ei taaskaan ole kiveen kirjoitettu ja saattaatilanteesta riippuen vaihdella.

▼ Usein jotain kohtia myös puuttuu.▼ Jollei erityistä syytä ole, niin kannattaa taas pitäytyä

esitetyssä järjestyksessä. ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 412: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 404▼ Moduulin määrittelytiedostoihin liittyy vain

muutama uusi asia:

1. Jos moduuli käyttää hyväkseen muita käyttäjänomia moduuleita, niiden julkisen rajapinnanesittelevä .hh-tiedosto pitää muistaa lukea osaksilähdekoodia #include "... "-komennolla.

2. Jos moduulin omassa esittelytiedostossa onesitelty tietotyyppejä tai const-vakioita, on sekinluettava osaksi lähdekoodia ➠ tietotyypit ja vakiotkäytettävissä myös määrittelytiedostossa.

3. Yksityisen rajapinnan funktiot esitellään jamääritellään namespace { ... } -lohkojen sisällä

➠ niiden näkyvyysalue rajautuu kyseisenlähdekooditiedoston/moduulin sisään, eli niitä eivoi kutsua muista moduuleista.

4. Edellinen ei päde luokan yksityisen rajapinnanjäsenfunktioihin, jotka määritellään kuten muutkinjäsenfunktiot ilman namespace -lohkoja.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 413: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 405

Mistä moduulit tulevat?

▼ Ohjelman jako moduuleihin tehdään jo määrittely-ja suunnitteluvaiheessa.

▼ Periaatteessa moduulit löytää miettimällä, mitäloogisia osakokonaisuuksia ohjelmassa tulee olla,jotta se toimisi halutulla tavalla.

▼ Esimerkiksi tvohjelmat jakautui aluksi selkeästikolmeen osaan:

1. pääohjelma,

2. tietokannan käsittely ja

3. tietorakenne, jonne aikataulutiedot talletetaan jajosta niitä etsitään.

▼ Kun näitä kutakin analysoi lisää, niin pian oivalsiviikonpäivien kummittelevan mukana niissä kaikissa.

▼ Koska viikonpäiville suoritettavat operaatiottuntuivat monimutkaisilta, se kannatti toteuttaaomana moduulinaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 414: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 406▼ Moduulien etsinnässä on siis päämääränä jakaa

ohjelma loogisiin osiin, joista kukin

– tekee oman osuutensa kokonaisuudesta ja– on riittävän yksinkertainen.

▼ Jos ongelma on iso, kannattaa moduulit etsiäpilkkomalla ongelmaa aina vaan pienempiin osiin(top-down) ➠ lopulta päädytään niin pieniinpaloihin, että ne pysyvät hanskassa.

▼ Oikea moduulijako ei ole yksikäsitteinen ➠ riippuutilanteesta ja tekijästä.

▼ Joitain hyvin yleisiä suuntaviivoja kokonaisuuksista,jotka kannattaa toteuttaa omana moduulinaan:

– jokainen abstrakti tietotyyppi (luokka)– käyttöliittymä– pääohjelma– vähänkin monimutkaisempi tiedostojenkäsittely– monimutkaisen syötteen jäsentely– yleiskäyttöiset algoritmit (lajittelu, haku)

▼ Lisäksi oman pään käyttö ei ole kiellettyä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 415: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 407▼ Usein selkeän ja toimivan julkisen rajapinnan

löytäminen on huomattavasti vaikeampaa kuinmoduulijaon aikaansaaminen.

▼ Rajapinnan etsimisessä on lähdettävä liikkeellepohtimalla

– mitä palveluita moduulin tulee toisille tarjota ➠rajapinnan funktiot

– mitä tietoa moduuli tarvitsee pystyäkseen palveluntarjoamaan ➠ rajapinnan funktioiden parametritja rajapinnan tietotyypit

– mitä hyödyllistä moduuli mahdollisesti tuottaatoisten käyttöön ➠ rajapinnan funktioidenpaluuarvot ja rajapinnan tietotyypit

▼ Modulaarisuuden onnistunut hyväksikäyttö vaatiihuolellista ennakkosuunnittelua.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 416: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 408

Modulaarisuuden hyödyt

▼ Mahdollistavat moduulin sisäisen toteutuksenmuuttamisen rajapinnan pysyessä ennallaan.

▼ Ohjelmiston loogisesti yhteenkuuluvat osat voidaankoota samaan pakettiin, mikä selkeyttää ohjelmaa jahelpottaa sen testaamista ja ylläpitoa.

▼ Moduulit ovat erinomainen työkalu suurienkokonaisuuksien hallintaan.

▼ Moduuleita voidaan kehittää rinnakkain sen jälkeen,kun julkinen rajapinta on lyöty lukkoon.

▼ Moduuleita voidaan kääntää erikseen, mikänopeuttaa kehitystyötä ja kuluttaa vähemmänresursseja ➠ muutoksen teon jälkeen vain muuttu-neet moduulit tarvitsee kääntää uudelleen.

▼ Usein moduuleita voidaan uudelleenkäyttää jokokokonaan tai ainakin osittain.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 417: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 409

Automatisoitu käännös ja make

▼ Ennen kuin tutustutaan make-komentoon,palautetaan mieleen sivulta 401 vaiheet, joillaC++-lähdekoodista saadaan suoritettava ohjelma.

▼ Yksittäisen lähdekoodimoduulin käännöksentuloksena syntyy nk. objektitiedosto (.o-tiedosto).

▼ UNIX:ssa objektitiedoston nimi saadaan lähdekoodi-tiedoston nimestä muuttamalla .cc .o :ksi.

▼ .o-tiedosto sisältää alkuperäisen lähdekoodin kään-nettynä konekielelle, apuinformaatiota linkkerille jne.

▼ Linkkeri yhdistää sitten objektitiedostot ja kirjastotsuoritettavaksi ohjelmaksi.

▼ Yleensä käännöskomento (esimerkiksi s. 392)proffa> ohj2c++ –o tvohjelmat

tvohjelmat.cc viikonpaivat.cctietokanta.cc ohjelmatiedot.cc

huolehtii kulissien takana automaattisesti kaikistavaiheista ja tuhoaa turhat(?) .o-tiedostot linkityksenvalmistuttua.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 418: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 410▼ Tämä ei kuitenkaan ole taloudellista, jos ohjelma

on suuri (paljon lähdekoodimoduuleja) ➠ ainakun ohjelma käännetään, jokainen moduuli pitäämuuntaa objektitiedostoksi, vaikka sitä ei olisiedellisen käännöksen jälkeen muutettukaan.

▼ Parempi ratkaisu olisi kääntää kaikki .cc-tiedostot.o-tiedostoiksi, linkittää ne suoritettavaksi ohjelmaksija olla tuhoamatta .o-tiedostoja.

▼ Seuraavan kerran kun ohjelma on tarpeen kääntää,objektitiedostoiksi tarvitsee muuntaa vain nelähdekoodimoduulit, joiden sisältöä on muutettusitten edellisen käännöksen ➠ valmis ohjelmasaadaan linkitettyä näistä uusista ja tallessa olevistavanhoista .o-tiedostoista.

▼ ohj2c++:lla lähdekooditiedosto saadaan muutettuaobjektitiedostoksi lisäoptiolla –c, esimerkiksi:

proffa> ohj2c++ –c tvohjelmat.ccproffa> lstvohjelmat.cc tvohjelmat.o

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 419: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 411▼ ohj2c++ osaa hoitaa myös objektitiedostojen

linkityksen suoritettavaksi ohjelmaksi:

proffa> ohj2c++ –o tvohjelmattvohjelmat.o viikonpaivat.otietokanta.o ohjelmatiedot.o

jossa koko komento on kirjoitettu yhdelle riville.

▼ Tämä kaikki liittyy make-komentoon siinä suhteessa,että maken avulla paloissa/osissa tapahtuvakäännösprosessi voidaan automatisoida.

▼ make:lle kuvataan erillisellä Makefile-tiedostolla,minkälaisia riippuvuussuhteita eri lähdekooditiedos-tojen välillä vallitsee.

▼ Kuvatuista suhteista ja tiedostojen muutosajoistamake osaa päätellä, mitkä tiedostot on käännettävä,linkitettävä tai jollain muulla tavoin päivitettävä ajantasalle.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 420: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 412▼ Tutkitaan esimerkki make:n toiminnasta tekemällä

Makefile tvohjelmat-ohjelmistolle:

############################################# Makefile tvohjelmat-ohjelmiston kääntämiseen#

OBJEKTIT = tvohjelmat.o ohjelmatiedot.o \tietokanta.o viikonpaivat.o

tvohjelmat: $(OBJEKTIT)

T ohj2c++ -o tvohjelmat $(OBJEKTIT)

tvohjelmat.o: tvohjelmat.cc viikonpaivat.hh \tietokanta.hh ohjelmatiedot.hh

T ohj2c++ -c tvohjelmat.cc

ohjelmatiedot.o: ohjelmatiedot.cc ohjelmatiedot.hh \viikonpaivat.hh

T ohj2c++ -c ohjelmatiedot.cc

tietokanta.o: tietokanta.cc tietokanta.hh \ohjelmatiedot.hh viikonpaivat.hh

T ohj2c++ -c tietokanta.cc

viikonpaivat.o: viikonpaivat.cc viikonpaivat.hh

T ohj2c++ -c viikonpaivat.cc

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 421: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 413▼ Jos nyt haluttaisiin saada suoritettava ohjelma

tvohjelmat, niin se tapahtuisi komennolla:proffa> make tvohjelmat

tai koska tvohjelman riippuvuudet on määriteltyMakefile:ssä ensimmäisenä, pelkkä make riittäisi:

proffa> make

▼ Makefile:n tärkein osa ovat säännöt, jotka kuvaavatmitkä tiedostot riippuvat toisistaan ja miten:

kohde: riippuvuudet

T päivityskomento

▼ Jos mitä tahansa tiedostoista riippuvuudet on muu-tettu sen jälkeen, kun tiedostoa kohde on viimeksimuutettu, niin make suorittaa päivityskomennot.

▼ Päivityskomennon on siis tarkoitus saattaa kohde ajantasalle riippuvuudet-tiedostoja prosessoimalla.

▼ Riippuvuuksien kuvaukset muodostavat puumaisenrakenteen ➠ ennen kuin yksittäisen säännönpäivityskomentoa suoritetaan, make tarkistaarekursiivisesti onko olemassa sääntöjä, joillariippuvuudet itsessään päivitetään ajan tasalle.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 422: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 414▼ Makefile:n nimen on oltava Makefile tai makefile.

▼ Kaikki teksti rivillä #-merkistä rivin loppuun onkommenttia, eikä siitä välitetä.

▼ Seuraavalle riville jatkuvat rivit ilmaistaan \-merkillärivin viimeisenä merkkinä.

▼ Makefile:ssä voi määritellä myös makroja (käytän-nössä lähes sama asia kuin muuttuja):

muuttujan_nimi = arvo

joiden arvo saadaan kirjoittamalla

$(muuttujan_nimi)

▼ Sääntöön voi liittyä useampikin päivityskomento.

▼ make on työkalu tilanteisiin, joissa useat tiedostotriippuvat jotenkin toisistaan ➠ sitä voi käyttäämuuhunkin kuin C++-ohjelmien kääntämiseen.

▼ Esimerkki-Makefile oli sangen yksinkertainen ➠make tarjoaa »tehokäyttäjälle» paljon monimutkai-sempiakin ominaisuuksia.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 423: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 415

Versionhallinta ja rcs

▼ Versionhallinnan avulla pidetään kirjaa ohjelmistonmoduulien eri versioista eli niiden kehittymisestä.

▼ Versionhallinta tarjoaa tavallisesti ainakin:

– mahdollisuuden tallettaa moduulista useita kehi-tysversioita, joihin kaikkiin päästään tarvittaessakäsiksi myöhemmin,

– mahdollisuuden kommentoida version muutokset,uudet ominaisuudet ja syyt, miksi versio tehtiin,

– automaattisen versionumeroinnin,

– tavan kontrolloida sitä, ketkä saavat muuttaamoduulia ja

– poissulkemisongelman ratkaisun: kaksi taiuseampia henkilöitä ei vahingossa muuta samaamoduulia yhtä aikaa tai että se tapahtuu hallitusti.

▼ Ideana on, että kaikki merkittävät muutoksetlähdekoodimoduuleissa talletetaan versiohallintaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 424: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 416▼ Tutustutaan seuraavaksi (ilmaiseen) versionhallinta-

järjestelmään RCS (Revision Control System).

▼ RCS toimii siisteimmin, jos heti alussa tekee projektintyöhakemistoon alihakemiston nimeltä RCS:

proffa> cd projektin_hakemisto

proffa> mkdir RCS

▼ Tämän jälkeen kaikista projektiin kuuluvistamoduuleista, niiden esittelytiedostoista, Makefile:stäjne. täytyy tallettaa alkutilanne RCS:ään komennollaci (lyhenne sanoista check in).

▼ Tutkitaan nyt (ja jatkossa) esimerkkinä yhdenmoduulin tvohjelmat.cc käyttäytymistä:

proffa> ci tvohjelmat.ccRCS/tvohjelmat.cc,v <–– tvohjelmat.ccenter description, terminated with single ’.’ or ...NOTE: This is NOT the log message!>> TV-Ohjelmat ohjelmiston paamoduuli>> .initial revision: 1.1done

▼ Jos ohjelmistoon lisätään myöhemmin uusiamoduuleita, edeltävä operaatio on tehtävä jokaiselle.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 425: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 417▼ Edellisen ci:n seurauksena tvohjelmat.cc on

kadonnut työhakemistosta ja näin kuuluukin olla ➠RCS-hakemistoon on ilmestynyt versionhallintatieto-kanta tvohjelmat.cc,v.

▼ Jos moduulin sisältöä nyt halutaan tutkia, saadaanviimeisin versio haettua RCS:stä komennollaco (lyhenne sanoista check out):

proffa> co tvohjelmat.ccRCS/tvohjelmat.cc,v ––> tvohjelmat.ccrevision 1.1done

▼ tvohjelmat.cc ilmestyi takaisin työhakemistoon,mutta siihen ei ole kirjoitusoikeuksia ➠ sen voiesimerkiksi kääntää, mutta sitä ei voi muuttaa.

▼ Editointia varten moduuli on lukittava, eli saatettavasellaiseen tilaan, etteivät muut projektin jäsenet voimuuttaa sitä samanaikaisesti (co :n optio –l):

proffa> co –l tvohjelmat.ccRCS/tvohjelmat.cc,v ––> tvohjelmat.ccrevision 1.1 (locked)done

▼ Nyt tvohjelmat.cc:tä voi myös muuttaa normaalisti.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 426: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 418▼ Kun moduuliin on tehty kaikki halutut muutokset

(tai vähintään kerran päivässä), siitä on talletettavauudempi versio RCS:ään komennolla ci:

proffa> ci tvohjelmat.ccRCS/tvohjelmat.cc,v <–– tvohjelmat.ccnew revision: 1.2; previous revision: 1.1enter log message, terminated with single ’.’ or ...>> Korjailtu koodin sisennyksiä siistimmiksi>> ja lisäilty välilyöntejä samasta syystä.>> .done

▼ tvohjelmat.cc katosi jälleen työhakemistosta, muttase on tallessa versionhallintatietokannassa.

▼ Huomaa, että ci pyytää aina kommentteja, joilla voiselittää versioon tehtyjä muutoksia ja niiden syitä.

▼ Kommenttien syöttäminen päätetään antamallariviksi pelkkä piste.

▼ Jos moduulin lukitsemisen jälkeen huomaa, etteimuutoksiin olekaan tarvetta, niin ci:in voi siltisuorittaa ➠ RCS ei tee muutoksia versionhallintaan:

proffa> ci tvohjelmat.ccRCS/tvohjelmat.cc,v <–– tvohjelmat.ccfile is unchanged; reverting to previous revision 1.1done

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 427: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 419▼ Jos taas moduuliin on tehty muutoksia edellisen

lukitsemisen jälkeen, mutta muutokset ovatvirheellisiä/huonoja ja ne halutaan heittää mene-mään, niin silloin auttaa rcs –u :

proffa> rcs -u tvohjelmat.ccRCS file: RCS/tvohjelmat.cc,v1.1 unlockeddone

▼ Koska tehtyjen muutosten unohtaminen on vaaral-lista, toimii rcs –u siten, että se vain avaa lukituksenmutta ei tuhoa moduulia työhakemistosta automaat-tisesti ➠ käyttäjän on tehtävä se itse rm-komennolla:

proffa> rm tvohjelmat.cc

▼ Tämä on ainoa tilanne, jossa versionhallinnassaolevia tiedostoja kannattaa tuhota rm:llä ➠ muutenmokaa jossain vaiheessa ja itkua piisaa.

▼ Jos on tarve poistaa työhakemistosta versionhallinnanpiiriin kuuluvia tiedostoja, komento on rcsclean,joka ei suostu poistamaan lukittuja tiedostoja.

▼ Komento rlog kertoo moduulista koko versiohisto-rian, myös ci:llä asetetut kommentit.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 428: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 420▼ Komento rcsdiff kertoo, mitä muutoksia lukittuun

moduuliin on tehty co –l:n jälkeen.

▼ RCS:llä on vielä yksi hyödyllinen ominaisuus ➠kun co-komento hakee moduulia versionhal-linnasta, se korvaa samalla tiettyjä avainsanojaversiohallintainformaatiolla.

▼ Hyödyllisimpiä näistä ovat:

Avainsana Korvaava teksti

$Revision$ versionumero$Date$ päivämäärä jolloin versio talletettiin ci:llä$Id$ yhden rivin olennainen informaatio versiosta$Log$ koko versiohistoria nokkelasti siten, että sen

saa kommentteina ohjelman osaksi

▼ Ymmärrettävistä syistä tämä oli vain pintavilkaisuRCS:n ominaisuuksiin ➠ lisätietoa saa esimerkiksiUNIX-manuaalisivuilta:

proffa> man ciproffa> man coproffa> man rcs

ja niin edelleen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 429: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 421▼ Kuvallinen havainnollistus RCS-komentojen käytöstä:

en

kyllä

Luontici tiedosto

Haku luettavaksico tiedosto

Haku editoitavaksico – l tiedosto

Versiohistoriarlog tiedosto

Tehdyt muutoksetrcsdiff tiedosto

Hylkää muutoksetrcs – u tiedosto

Talleta muutoksetci tiedosto

Poista tiedostorcsclean tiedosto

Poista tiedostorm –i tiedosto

versiotietokantaolemassa

versiotietokantapäivitetty

hyväksytkömuutokset?

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 430: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 422

Ajonaikaiset virheet ja gdb

▼ Ajonaikaisiksi virheiksi kutsutaan virheitä, joitakääntäjä ei havaitse ➠ ilmenevät vasta valmistaohjelmaa suoritettaessa.

▼ Tyypillisesti ajonaikaisia virheitä on kahdenlaisia:

1. loogiset virheet (ohjelma toimii väärin) ja2. virheet, jotka keskeyttävät ohjelman suorituksen.

▼ Debuggeriksi kutsutaan ohjelmaa, jonka avullavoidaan yrittää paikantaa ajonaikaisia virheitä.

▼ Debuggeri ei ole korvike huolelliselle suunnittelulleja koodaukselle, vaan pikemminkin viimeinen apu.

▼ Debuggeri mahdollistaa ohjelman kontrolloidunsuorittamisen:– muuttujien arvojen selvittäminen,– ohjelman suoritus käsky kerrallaan,– funktioiden kutsuminen jne.eli ohjelman tilan tutkimisen suorituksen aikana.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 431: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 423▼ Jos ohjelma kaatuu kesken suorituksen, niin myös

kaatumisen syyn selvittely (UNIX:issa) syntyväncore-tiedoston avulla on mahdollista.

▼ Tutustutaan lyhyesti gdb-debuggeriin.

▼ Toimiakseen gdb vaatii suoritettavalta ohjelmaltatiettyjä lisäominaisuuksia ➠ lähdekoodimoduulit onkäännettävä objektimoduuleiksi käyttäen kääntäjänlisäoptiota –g joko yhdessä:

proffa> ohj2c++ –g –o tvohjelmattvohjelmat.cc viikonpaivat.cctietokanta.cc ohjelmatiedot.cc

tai erikseenproffa> ohj2c++ –c –g tvohjelmat.ccproffa> ohj2c++ –c –g viikonpaivat.ccproffa> ohj2c++ –c –g tietokanta.ccproffa> ohj2c++ –c –g ohjelmatiedot.ccproffa> ohj2c++ –o tvohjelmat

tvohjelmat.cc viikonpaivat.cctietokanta.cc ohjelmatiedot.cc

▼ Linkitysvaiheessa –g:tä ei tarvita.

▼ Tuloksena saatua ohjelmaa tvohjelmat voidaankäyttää myös ilman gdb:tä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 432: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 424▼ gdb käynnistetään antamalla sille komentorivillä

tutkittavan ohjelman nimi:proffa> gdb tvohjelmat

tai jos ohjelma on suoritettaessa kaatunut ja tiedostocore on olemassa, sitä voidaan tutkia komennolla:

proffa> gdb tvohjelmat core

▼ Kun gdb käynnistyy se tulostaa kehotteen ja sille voialkaa syöttämään komentoja:

GNU gdb Red Hat Linux (6.3.0.0-1.143.el4rh)Copyright 2004 Free Software Foundation, Inc.···

This GDB was configured as "i386-redhat-linux-gnu".(gdb)

▼ Tutustutaan luettelonomaisesti gdb:n perusko-mentoihin ➠ varsinainen tutustuminen ja käytönopiskelu jää lukijan oman harrastuksen varaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 433: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 425▼ Hyödyllisiä komentoja selityksineen:

run (r)Käynnistään ohjelman suorituksen pääohjelman alusta.

break kohta (b kohta)Asettaa keskeytyspisteen haluttuun kohtaan: kun suoritussaavuttaa kohdan, ohjelma pysähtyy. Kohta voi ollarivinumero, tiedostonnimi : rivinumero tai funktion nimi.

info breakpoints (i b)Listaa käytössä olevat keskeytyspisteet.

delete numero (d numero)Poistaa keskeytyspisteen numero.

whereKertoo missä kohdassa suoritus keskeytyi. Toimii myös core-tiedoston kanssa ohjelman kaatumiskohdan selvittämiseksi.

step (s) ja next (n)Jatkavat pysähtyneen ohjelman suorittamista lähdekoodirivikerrallaan. Muuten samat, mutta next suorittaa funktiokutsutsiirtymättä askeltamaan niiden runkoa.

continue (c)Jatkaa normaalia suoritusta pysähtymiskohdasta eteenpäin.

print lauseke (p lauseke)Lausekkeen (myös muuttujan) arvon tulostaminen.

help komento (h komento)Selitys gdb:n komennon toiminnasta.

quit (q)Lopettaa gdb:n ja palaa komentotulkkiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 434: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 426▼ Lisäksi gdb:ssä on sisäänrakennettu komentohistoria,

jonka sisällä on mahdollista liikkua nuolinäppäimilläja editoida vanhoja komentoja.

▼ E näppäimen painallus toistaa viimeisimmänsyötetyn komennon, mikäli se on mielekästä.

▼ T näppäimellä voi laajentaa funktioiden jamuuttujien nimiä, kunhan kirjoittaa nimestä ensinyksikäsitteisen alun.

▼ Debuggeri on hyvä työkalu loogisten virheidenmetsästämiseen, mutta ei kuitenkaan niin suoravii-vainen ja helppo kuin voisi kuvitella.

▼ Ei siis kannata aliarvioida vanhoja konsteja:

– koodin huolellinen lukeminen ja analysointi,

– sopivat testisyötteet ohjelmalle ja

– sopivasti sijoitellut testitulostukset ohjelmansuorituksen aikana.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 435: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 427

Rekursio

▼ Rekursio tarkoittaa jonkin asian määrittelemistäitsensä avulla.

▼ Esimerkiksi matematiikasta tuttu luonnollisen luvunkertoma:

n! = n · (n− 1) · (n− 2) · . . . · 3 · 2 · 1kun lisäksi on määrätty, että 0! = 1.

▼ Nollaa suuremman n:n kertoma on siis n:n ja kaikkiensitä pienempien positiivisten kokonaislukujen tulo.

▼ Esimerkiksi 5! = 5 · 4 · 3 · 2 · 1 = 120.

▼ Kertoma voidaan määritellä myös rekursiivisesti:

n! =

{

1 mikäli n on 0

n · (n− 1) ! mikäli n > 0

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 436: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 428▼ Soveltamalla rekursiivista määritelmää 5!:n laskemi-

seksi saadaan:

5! = 5 · 4!

= 5 ·SSw

4̂ · 3!

= 5 · 4 ·SSw

3̂ · 2!

= 5 · 4 · 3 ·SSw

2̂ · 1!

= 5 · 4 · 3 · 2 ·SSw

1̂ · 0!

= 5 · 4 · 3 · 2 · 1 ·?

1

= 120

▼ Rekursion idea on pyrkiä esittämään ongelmanratkaisu alkuperäisen ongelman kanssa samanmuo-

toisina, mutta ratkaisultaan yksinkertaisempina

osaongelmina.

▼ Saatuihin osaongelmiin voidaan sitten soveltaarekursiivista sääntöä uudelleen, kunnes lopultapäädytään niin yksinkertaiseen tapaukseen, että senratkaisu nähdään suoraan.

▼ Rekursion päämäärä on: hajoita ja hallitse.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 437: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 429

Rekursio ohjelmoinnissa

▼ Kun puhutaan rekursiosta ohjelmoinnin yhteydessä,niin yleensä aihe liittyy funktioihin.✶

▼ Rekursiivinen funktio on määritelty itsensä avulla

➠ se kutsuu itseään.

▼ Toteutetaan edellä esitelty kertoman laskeminenrekursiivisella C++-funktiolla:

unsigned int kertoma(unsigned int n) {if (n == 0) {

return 1;} else {

return n * kertoma(n – 1);}

}

joka siis laskee ja palauttaa parametrinsa n kertoman.

▼ Periaatteessa funktion voi kirjoittaa suoraan kertomanrekursiivisen määritelmän pohjalta (s.427).

▼ Mutta hyödyllisempää olisi ymmärtää, miksi funktiotoimii ja vieläpä oikein.

✶ Tietorakenteetkin voivat olla rekursiivisia, mutta siitä myöhemmin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 438: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 430▼ Oletetaan, että kertoma-funktiota kutsutaan näin:

#include <iostream>

using namespace std;

int main( ) {cout << kertoma(5) << endl;

}

ja tutkitaan vaihe-vaiheelta, kuinka suoritus etenee.

▼ Kun main:in suoritus saavuttaa kohdan, jossakertoma-funktiota kutsutaan, niin havainnollistetaantilannetta seuraavasti:

main

→ cout << kertoma(5) << endl;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 439: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 431▼ Pääohjelman funktiokutsun seurauksena päädytään

suorittamaan kertoma-funktion runkoa:

main

kertoma

// parametrin n arvo on 5

if (n == 0) {return 1;

} else {→ return n * kertoma(n – 1);}

▼ Koska n:n arvo on 5, suoritetaan else-haara japäädytään tekemään rekursiivinen kutsu todellisenparametrin arvolla 4.

▼ Kuvassa peitettynä oleva main-laatikko kuvaa sitä,että main-funktion suoritus on kesken ➠ vastakun sen peittävä kertoma-funktio suorittaa return-käskyn, jatkuu main:in suoritus siitä kohdasta, jossakertomaa kutsuttiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 440: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 432▼ Itse asiassa suoritus etenee tällä rekursiokierroksella

täysin samoin kuin edelliselläkin, paitsi ettämuodollisen parametrin n arvo on nyt 4:

main

kertoma

kertoma

// parametrin n arvo on 4

if (n == 0) {return 1;

} else {→ return n * kertoma(n – 1);}

▼ Suoritus ajautuu siis else-haaraan ja rekursio eteneeaina vain syvemmälle.

▼ Huomaa, kuinka taustalle alkaa kertyä myöskeskeneräisiä kertoma-funktion suorituksia.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 441: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 433▼ Näin ohjelma etenee, kunnes lopulta saavutaan

tilanteeseen, jossa parametrin n arvo on 0:

main

kertoma

kertoma

kertoma

kertoma

kertoma

kertoma

// parametrin n arvo on 0

if (n == 0) {→ return 1;} else {

return n * kertoma(n – 1);}

▼ Enää ei tapahdukaan rekursiivista kutsua, vaankertoma palauttaa suoraan arvon 1 ja keskeneräistenfunktiokutsujen suma alkaa purkautua.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 442: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 434▼ Toiseksi viimeiselle kertoma:n kutsulle palautuu

siis viimeiseltä rekursiiviselta kutsulta arvo 1, jokakerrotaan muodollisen parametrin n arvolla 1:

main

kertoma

kertoma

kertoma

kertoma

kertoma

// parametrin n arvo on 1

if (n == 0) {return 1;

} else {→ return n * kertoma(n – 1)

︸ ︷︷ ︸

1 ∗ 1

;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 443: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 435▼ Seuraavaksi vuorossa oleva keskeneräinen kertoma-

funktio jatkuu samaan tapaan:

main

kertoma

kertoma

kertoma

kertoma

// parametrin n arvo on 2

if (n == 0) {return 1;

} else {→ return n * kertoma(n – 1)

︸ ︷︷ ︸

2 ∗ 1

;}

▼ Huomaa että jokaisella funktiolla on oma paramet-rimuuttuja n, jonka arvo toki on säilynyt ennallaan,kun rekursiivisen funktion kutsusta palataan takaisinsuorittamaan kutsuneen funktion runkoa.

▼ Sama pätee kaikkiin paikallisiin muuttujiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 444: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 436▼ Näin suoritus etenee ja saavuttaa lopulta rekursiossa

ylimmän kertoma-funktion:

main

kertoma

// parametrin n arvo on 5

if (n == 0) {return 1;

} else {→ return n * kertoma(n – 1)

︸ ︷︷ ︸

5 ∗ 24

;}

▼ Joka palauttaa pääohjelmalle 5:n kertoman arvon:

main

→ cout <<

120︷ ︸︸ ︷

kertoma(5) << endl;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 445: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 437▼ Rekursiossa ei ole ohjelmointikielen kannalta mitään

erikoista ➠ rekursiiviset funktiot ovat funktioita siinämissä kaikki muutkin funktiot.

▼ Rekursion vaikeaselkoisuus piilee siinä, että se vaatiiohjelmoijalta ei-luontaista tapaa hahmottaa ongelmaja sen ratkaisu.

▼ Rekursiivisten funktioiden suunnittelua ja ymmärtä-mistä helpottaa, kun pitää mielessään että:

– Funktio on rekursiivinen, jos se kutsuu itseään(suoraan tai epäsuoraan).

– Suorituksen kuluessa rekursiivisesta funktiosta on»käynnissä» yhtä monta instanssia, kuin mikä onkeskeneräisten rekursiivisten kutsujen lukumäärä.

– Jokaisella instanssilla on omat arvonsa muodollisilleparametreille ja paikallisille muuttujille.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 446: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 438▼ Rekursiivisella funktiolla on kaksi olennaista

ominaisuutta, jotka on syytä muistaa:

1. Sillä on oltava lopetusehto (tai ehtoja), jokatunnistaa ongelman triviaalitapaukset ja reagoiniihin ilman uuden rekursiivisen kutsun tarvetta.

2. Jokaisen rekursiivisen kutsun on yksinkertaistettavaratkaistavaa ongelmaa niin, että lopulta päädytääntriviaalitapaukseen.

▼ Esimerkin kertoma-funktiossa näitä kohtia edustivat:

1. if-rakenteen ehto n == 0 ➠ triviaalitapaus onnollan kertoma: sen arvo tiedetään suoraan.

2. Jokaisella rekursiokierroksella selvitettiin yhtäpienemmän luvun kertomaa: kutsuparametripieneni yhdellä.

▼ Jos jomman kumman unohtaa, niin funktiota kutsut-taessa koko ohjelma kaatuu (UNIXissa core dump).

▼ Tämä johtuu siitä, että funktio päätyy kutsumaanitseään loputtomiin (päättymätön rekursio) ➠aiempien kutsukertojen muuttujat✶ kuluttavatmuistia, kunnes se yksinkertaisesti loppuu.

✶ Ja muu aiempiin rekursiokierroksiin liittyvä informaatio.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 447: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 439▼ Rekursiolla saa aikaan toistoa.

▼ Periaatteessa mikä tahansa toistorakenne (silmukka)voidaan korvata rekursiolla.

▼ Parhaiten rekursio sopii kuitenkin sellaisten ongel-mien ratkaisuun, jotka ovat luonteeltaan rekursiivisia

➠ niitä voidaan »luonnollisesti» yksinkertaistaa siten,että jäljelle jäävät osaongelmat ovat alkuperäisenongelman yksinkertaistettuja tapauksia.

▼ Yleensä rekursiivinen ratkaisu on lyhyempi jasiistimpi kuin vastaava silmukkarakenteella toteutetturatkaisu.

▼ Toisaalta, yleensä rekursiivinen ratkaisu on hitaampija kuluttaa enemmän muistia kuin silmukkarakenne.

▼ Rekursiiviset funktiot voidaan ominaisuuksiensaperusteella jaotella ryhmiin, jotka kannattaayleissivistyksen nimissä katsoa läpi.

▼ Suoraksi rekursioksi kutsutaan tapausta, jossafunktio kutsuu itseään omassa rungossaan.

▼ Esimerkin kertoma on suoraan rekursiivinen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 448: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 440▼ Epäsuora rekursio eli rinnakkaisrekursio tarkoittaa

tilannetta, jossa funktio func_A kutsuu funk-tiota func_B, joka taas kutsuu func_A:ta jne:

func_A func_B

▼ Sotkuun voi osallistua useampiakin funktioita ➠syntyvä »kutsusilmukka» voi olla pidempi.

▼ Epäsuoran rekursion käytössä kannattaa ollapidättyväinen, koska se on usein hankalastihahmotettava ➠ ohjelmasta tulee vaikeatajuinen.

▼ Häntärekursioksi (tail recursion) kutsutaantapausta, jossa rekursiivisen kutsun paluuarvostatulee ilman lisäoperaatioita kutsuvan instanssinpaluuarvo.

▼ Esimerkin kertoma-funktio ei ole häntärekursiivinen

➠ rekursiivisen kutsun paluuarvo pitää ensin kertoan:llä, jotta saadaan kutsujan paluuarvo:

return n * kertoma(n – 1);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 449: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 441▼ kertoma voitaisiin toteuttaa häntärekursiivisena:

unsigned inthantakertoma(unsigned int tulos, unsigned int n) {

if (n == 0) {return tulos;

} else {return hantakertoma(tulos * n, n – 1);

}}

▼ jota pitäisi kutsua siten, että ensimmäiseksiparametriksi annetaan 1:

cout << hantakertoma(1, n) << endl;

▼ Häntärekursiivisille funktioille on tyypillistä, ettälopputulosta kerätään ylimääräiseen parametriin(tulos), johon kertynyt arvo voidaan sitten suoraanpalauttaa lopetusehdon täyttyessä.

▼ Tuosta seuraa, että ylimääräisen parametrinalkuarvon tulee olla triviaalitapauksen lopputulos.

▼ Häntärekursio on tärkeä käsite, koska se voidaanmuuttaa mekaanisesti silmukkarakenteeksi ➠saavutetaan rekursion hyödyt mutta päästään eroonsen huonoista puolista.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 450: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 442

Muisti

▼ Kaikki tietokoneen käsittelemä tieto talletetaankoneen (keskus)muistiin.✶

▼ Muistia voi ajatella joukkona numeroituja lokeroita:

· · ·0 1 2 3 4 5 6 7 8 9 · · · n

joista jokaiseen prosessori voi tallettaa pienenmäärän tietoa.

▼ Yhtä lokeroa kutsutaan muistipaikaksi ja senjärjestysnumeroa (muisti)osoitteeksi.

▼ Muistipaikkaan mahtuu tietoa talteen yksi tavu

(byte) joka puolestaan koostuu 8 bitistä.

▼ Yleensä muistia käsitellään kuitenkin tavun moni-kerran kokoisina paloina.

✶ Ei ihan koko totuus, mutta ainakin kaikki lähtötiedot ovat jossain vaiheessatalletettuina keskusmuistiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 451: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 443▼ Kun tiedetään muistiosoite, niin siellä tallessa olevaan

informaatioon päästään käsiksi (haku ja talletus).

▼ Yhteen muistipaikkaan voidaan siis tallettaatietoalkio, joka on esitettävissä 8 bitillä (esim. char)

➠ jos on tarve tallentaa tietoa, joka esitetäänsuuremmalla bittimäärällä, niin käytetään riittävämäärä peräkkäisiä muistipaikkoja.

▼ Esimerkiksi jos int-tietotyypin alkiot ovat 32-bittisiä,voitaisiin yksi kokonaisluku (siis sen binääriesitys)tallettaa neljään peräkkäiseen muistipaikkaan:

32-bittiä︷ ︸︸ ︷

11101· · ·101 · · ·0 1 2 3 4 5 6 7 8 9

▼ Vastaavasti 64-bittinen double voitaisiin tallettaa:

64-bittiä︷ ︸︸ ︷

01010· · ·10100110101· · ·011 · · ·0 1 2 3 4 5 6 7 8 9

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 452: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 444▼ Esimerkeistä huomataan, että samoihin muistipaik-

koihin voidaan tallettaa eri aikoina eri tyyppistäinformaatiota.

▼ Koska tietokoneen uumenissa kaikki tieto esitetäänbitteinä, niin pelkästään muistipaikan sisältöä tutki-malla ei voi päätellä, minkä tyyppistä informaatiotasinne on talletettu.

▼ Tuosta päädytään vanhaan totuuteen: kaikellatiedolla pitää olla tyyppi, jotta sitä osattaisiin käsitelläoikein.

▼ Ohjelmointikielessä muuttujan määrittely on tapaantaa symbolinen nimi jonkin muistipaikan sisällölle

➠ kääntäjä valitsee muuttujalle talletuspaikanmuistissa ja pitää kirjaa tyyppi-informaatiosta.

▼ Tyyppi-informaation perusteella kääntäjä osaakäyttää oikeita konekäskyjä muuttujan arvon(siis muistipaikkojen sisällön) käsittelyyn.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 453: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 445▼ Esimerkiksi kun luodaan kokonaislukumuuttuja:

int luku;

niin kääntäjä etsii jostain riittävän monta vapaataperäkkäistä muistipaikkaa ja varaa ne muuttujanluku talletuspaikaksi:

lukuarvo · · ·

0 1 2 3 4 5 6 7 8 9

▼ Jatkossa aina kun ohjelmakoodissa käytetäänmuuttujaa luku, se tulkitaan tarkoittamaan sillevaratuissa muistipaikoissa olevaa arvoa.

▼ Jatkon kannalta on tärkeää pitää selvinä mielessä:– jokainen muistipaikka identifioidaan yksikäsittei-

sellä muistiosoitteella,– muistipaikassa on tallessa varsinainen tieto ja– muuttuja on symbolinen nimi muistipaikkaan

talletetulle tiedolle.Ja näistä seuraava:– jokaiseen muuttujaan liittyy jokin muistiosoite

(nimittäin se jossa sijaitsevassa muistipaikassamuuttujan arvo on tallettuna).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 454: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 446

Osoittimet

▼ Osoitintietotyypit ovat tietotyyppejä, joidenarvojoukko koostuu tietyntyyppisten muuttujienmuistiosoitteista.

▼ Tai jos sen ilmaisee toisin: osoitintyyppisiinmuuttujiin (osoittimiin, pointtereihin) voidaantallettaa muistiosoitteita.

▼ Osoittimeen voidaan siis tallettaa jonkin tarpeellisentiedon sijainti muistissa.

▼ C++:ssa osoittimia määritellään:

kohdetyyppi* muuttujan_nimi;

eli aivan kuin oltaisiin määrittelemässä normaalistikohdetyyppi-tyyppistä muuttujaa, mutta muuttujan

ja tyypin nimien väliin laitetaan *-merkki.

▼ Tuloksena saadaan muuttuja, johon voidaan tallettaakohdetyyppi-tyyppisen tietoalkion muistiosoite (sensijainti muistissa).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 455: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 447▼ Kohdetyyppi on välttämätön, sillä sen perusteella

osoittimeen talletetusta muistiosoitteesta löytyvääinformaatiota (bittejä) osataan käsitellä oikein.

▼ Kaikista ohjelmassa käytetyistä muuttujistasaadaan selville niiden muistiosoite unaarisella&-operaattorilla.

▼ Osoittimeen talletetussa muistiosoitteessa sijaitsevanmuistipaikan sisältöön päästään käsiksi unaarisella*-operaattorilla.

▼ Tutkitaan triviaali esimerkki:

#include <iostream>

using namespace std;

int main( ) {4 int i;5 int* ip = nullptr; / / nullptr selitetty s. 450

6 i = 5;7 ip = &i;8 *ip = 42;

9 cout << i << "," << *ip << ","10 << ip << "," << &ip << endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 456: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 448▼ Kun ohjelma suoritetaan hypoteettisella tietoko-

neella, ilmestyy näytölle:proffa> ./osoitintesti42,42,0x000002,0x000008

▼ Tutkitaan lähdekoodirivi kerrallaan, mitä suorituksenaikana tapahtuu:

5 Luodaan kokonaislukumuuttuja i: varataan sille tilaamuistista jostain vapaasta kohdasta (0x000002).

6 Luodaan osoitin kokonaislukuun ip: varataan sille tilaamuistista jostain vapaasta kohdasta (0x000008).

7 Sijoitetaan i:hin arvo 5, siis talletetaan 5:n binääriesitysosoitteesta 0x000002 alkaviin muistipaikkoihin.

8 Selvitetään muuttujan i osoite (0x000002) &-operaattorillaja talletetaan se muuttujaan ip eli osoitteesta 0x000008alkaviin muistipaikkoihin.

9 Sijoitetaan ip:hen talletetusta osoitteesta (0x000002)alkaviin muistipaikkoihin kokonaisluvun 42 binääriesitys(samat muistipaikat joissa muuttuja i on tallessa, siis i:narvo muuttuu).

10 ja 11Tulostetaan mielenkiintoiset arvot. Koska osoitin ip onmuuttuja, sen sijainti muistissa saadaan &-operaattorilla.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 457: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 449▼ Kuvallisesti esimerkin muistinkäyttö näyttäisi

lopputilanteessa (rivi 10) seuraavalta:

i ip

42 binäärisenä 0x000002 · · ·0 1 2 3 4 5 6 7 8 9 10 11 12

▼ Esimerkissä on oletettu osoittimen olevan kooltaan4 tavua eli 32-bittiä.

▼ Esimerkistä havaitaan myös, että lausekkeessakäytettynä *ip käyttäytyy kuin int-tyyppinenmuuttuja ➠ sille evaluoituu arvo muistipaikasta,johon ip osoittaa ja siihen voidaan suorittaa sijoitus=-operaattorilla, jolloin arvo tallettuu kyseiseenmuistipaikkaan.

▼ Sama pätee muunkin tyyppisiin osoittimiin.

▼ Osoittimen arvo kertoo, missä jokin tieto sijaitsee.

▼ *-operaattorilla osoitimesta saadaan selville varsi-

nainen osoitettu tieto.

▼ Sanomattakin(?) on selvää, että osoittimeen voitallentaa vain sellaisen muuttujan osoitteen, jonkatyyppi on sama kuin osoittimen kohdetyyppi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 458: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 450▼ Esimerkin rivillä 6 ip-osoittimeen alustetaan arvo

nullptr, tämä on erittäin tärkeä pieni yksityiskohta.

▼ Tälläista osoitinta kutsutaan null- tai nil-pointteriksi.

▼ Kaikkiin osoitinmuuttujiin voidaan tallettaa nullptr

(tai kokonaislukuliteraali 0) ➠ osoittimelle saadaannäin asetettua arvo, joka ei osoita minnekään.➀

▼ Osoittimen yhtä- ja erisuuruutta voi myös ainavertailla nullptr-arvon kanssa ja sitä voi käyttääosoitintyyppisenä todellisena parametrina.

▼ Jos ohjelman suorituksen aikana yritetään »seurata»➁

null-osoitinta, on tuloksena aina ajonaikainen virheja ohjelman päättyminen (core).

▼ Null-osoitinta kannattaa (aina) käyttää osoitinmuut-tujien alustusarvona ja virhepaluuarvona funktioilta,jotka palauttavat osoittimen.

➀ Vanhemmissa kääntäjissä vain literaalinen kokonaisluku nolla (0) kelpaanull-osoittinliteraaliksi. Tämä kannattaa pitää mielessä, jos joutuu joskustilanteeseen, jossa on käytettävä kääntäjää, joka ei tunnista varattua sanaanullptr. Myös cstddef-kirjaston vakio NULL on silloin mahdollinenkorvaava vaihtoehto.

➁ Eli tutkia tietoa, johon osoitin osoittaa.Eli kohdistaa osoittimeen unäärinen *-operaattori tai –> -operaattori.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 459: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 451

Osoittimet struct- ja

class-tietotyyppeihin

▼ Dynaamisten tietorakenteiden yhteydessä joudutaanusein käsittelemään osoittimia tietueisiin ja/tailuokkiin.

▼ Tällaisia osoittimia luodaan aivan tavalliseen tapaan:

struct Opiskelija {string nimi;...

};...Opiskelija* optr = nullptr;

ja

class Polynomi {public:

double evaluoi(double x) const;...

private:...

};...Polynomi* polptr = nullptr;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 460: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 452

▼ Sen jälkeen kun osoittimeen on sijoitettu muisti-osoite, jossa oikeasti on jotain tietoa tallessa, niinkenttiin ja jäsenfunktioihin päästään osoittimenvälityksellä käsiksi:

string opiskelijan_nimi = (*optr).nimi;

ja

double tulos = (*polptr) .evaluoi(2.0);

▼ Sulutus johtuu siitä, että . -operaattorin presedenssion korkeampi kuin unaarisen *-operaattorin

➠ jatkuva sulkujen kirjoittaminen alkaa pianottaa päähän, minkä vuoksi sille on olemassalyhennysmerkintä:

string opiskelijan_nimi = optr –>nimi;

ja

double tulos = polptr –>evaluoi(2.0);

▼ Operaattori –> siis valitsee kentän tai jäsenfunktion(myös jäsenmuuttujan) seuraamalla ensin osoitintatiedon varsinaiseen sijaintipaikkaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 461: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 453

Taulukot ja osoittimet

▼ Luodaan kolmen alkion kokonaislukutaulukko iv jaint-osoitin ip:

int iv[3];int* ip = nullptr;

▼ Kääntäjä sijoittaa taulukon muistiin yhtenä pötkönä

jotenkin seuraavasti:

iv[0] iv[1] iv[2] ipnull · · ·

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

▼ Nyt esimerkiksi seuraava sijoitus ip:hen toimiiodotusten mukaisesti:

ip = &iv[1];*ip = 42;

eli ip:n arvo tulisi olemaan taulukon alkion iv[1]

osoite 8 ja sen välityksellä taulukon alkiota pystytäänmuuttamaan:

iv[0] iv[1] iv[2] ip42 binäär. 0x000008 · · ·

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 462: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 454▼ Erikoisemmaksi asian tekee se, että C++:ssa on

määritelty: taulukon nimi evaluoituu osoittimeksi senensimmäiseen alkioon ➠ seuraavat kaksi tarkoittavatsiis aivan samaa:

ip = &iv[0];ip = iv;

▼ Molemmat asettavat ip:n arvoksi iv:n ensimmäisenalkion osoitteen 4:

iv[0] iv[1] iv[2] ip0x000004 · · ·

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

▼ Hetken mietittyään oivaltaa, että määritelmästäseuraa myös seuraavien identtisyys:

iv[0] = 42;*iv = 42;

▼ Kumpikin asettaa iv:n ensimmäisen alkion arvoksi 42:

iv[0] iv[1] iv[2] ip42 binäär. · · ·

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 463: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 455▼ Josta taas melko pian keksii, että jos on tehty sijoitus:

ip = iv;

niin molemmat seuraavat merkitsevät samaa:ip[0] = 7;*ip = 7;

▼ Sijoittavat iv-taulukon ensimmäiseen alkioon luvun 7:

iv[0] iv[1] iv[2] ip7 binäär. 0x000004 · · ·

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

▼ C++:ssa siis taulukoiden ja osoittimien välillä onyhteys, niitä kumpaakin voidaan käyttää samoillaoperaattoreilla.

▼ Kun lisäksi muistaa, että kääntäjä varaa tauluk-komuuttujan aina yhtenä pötkönä muistista, voiominaisuutta käyttää dynaamisten taulukoidenluonnissa ja käsittelyssä.

▼ Tärkeä ero taulukon ja osoittimen välillä on se,että taulukkomuuttujan määrittelyyn sisältyy ainaautomaattinen muistinvaraus, osoitinmuuttuja

ohjelmoijan pitää alustaa itse.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 464: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 456

Muuttujan näkyvyysalue ja elinikä

▼ Muuttujan näkyvyysalue (scope, visibility) on seosa ohjelmaa, jossa muuttujaa voidaan käyttää:

– Lohkon sisällä (funktion tai kontrollirakenteenaaltosulkeiden sisällä) määriteltyä paikallista

muuttujaa voi käyttää määrittelykohdastaankyseisen lohkon loppuun saakka.

– Luokan jäsenmuuttujia voidaan käyttää senjäsenfunktioissa.

– Moduulin yksityistä muuttujaa voidaan käyttääyhden lähdekooditiedoston (.cc) sisällä.

– Globaalia muuttujaa (määritelty kaikkienfunktioiden ja luokkien ulkopuolella) voi käyttääkaikkialla ohjelmassa.

▼ Edellisessä sana »käyttää» tarkoittaa, että muuttujannimen voi kirjoittaa koodiin, eikä kääntäjä anna siitävirheilmoitusta »tuntematon muuttuja» tms.

▼ Ohjelmassa voi olla useita keskenään samannimisiämuuttujia, kunhan niitä ei ole määritelty samannäkyvyysalueen sisällä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 465: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 457▼ On tärkeätä ymmärtää, että näkyvyysalue määrää

vain, missä muuttujan nimi on käytettävissä.

▼ Aiemmasta on tuttua, että muuttujalle varataanmäärittelyvaiheessa muistia, johon muuttujan arvofyysisesti talletetaan laitteistotasolla.

▼ Muuttujan elinikä määrää, kuinka kauan muuttujaon olemassa ➠ kuinka sen tarvitsema muistipidetään varattuna ➠ kuinka kauan sen arvo säilyy.

▼ On houkuttelevaa tehdä virhepäätelmä, ettänäkyvyysalue ja elinikä tarkoittavat samaa, koska niinsattuu olemaan normaaleille paikallisille muuttujille:

void fun( ) {int i; // näkyvyysalue ja elinikä (muistinvaraus) alkaa

...// kun funktion loppu saavutetaan, niin näkyvyys-// alue päättyy ja muisti vapautetaan

}

▼ Eli i:n näkyvyysalue ja elinikä ovat samat.

▼ Tällaisia muuttujia kutsuaan joskus automaattisiksi

muuttujiksi, koska ne automaattisesti luodaannäkyvyysalueensa alussa ja tuhotaan sen lopussa.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 466: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 458▼ Automaattisille muuttujille varataan muisti aina

uudelleen, kun niiden määrittely »suoritetaan».

▼ Näin ei kuitenkaan välttämättä ole, elinikä voi olla:

– Automaattinen kuten edellä esitettiin.

– Staattinen (static) jolloin elinikä on koko ohjelmansuoritusaika (globaalit ja staattiset muuttujat sekämoduulin yksityiset muuttujat).

– Dynaaminen (dynamic) jolloin ohjelmoija määrääeliniän eksplisiittisillä käskyillä.

▼ Dynaamisiin muuttujiin paneudutaan jatkossaurakalla, tutkitaan tässä pieni hahmotelmaesimerkkistaattisesta paikallisesta muuttujasta:

void JokuFunktio( ) {static bool ensimmainen_kerta = true;

if (ensimmainen_kerta) {// Tee alustustoimet, jotka halutaan suorittaa

// vain funktion ensimmäisellä kutsukerralla.

ensimmainen_kerta = false;}...

}▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 467: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 459

▼ Staattiset muuttujat määritellään lisämääreen static

avulla.

▼ Paikalliset staattiset muuttujat noudattavat normaa-leja näkyvyysaluesääntöjä.

▼ Niiden elinikä on kuitenkin koko ohjelman suori-tusaika ➠ niille varattua muistia ei vapautetamäärittelylohkon lopussa.

▼ Kun näkyvyysalueen sisälle palataan myöhemmin,staattiset muuttujat »muistavat» arvonsa edelliseltäkerralta.

▼ Staattisen muuttujan alustus tapahtuu vain

kerran käännösaikana ➠ ajatuksellisesti sen voitulkita tapahtuvaksi, kun muuttujan määrittelyrivi»suoritetaan» ensimmäisen kerran.

▼ Myöhemmillä kerroilla muuttujan arvona on siihenedellisellä kerralla sijoitettu arvo.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 468: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 460

Dynaaminen muistinhallinta

▼ Joustavien tietorakenteiden toteutus edellyttää, ettäohjelma/ohjelmoija huolehtii itse muistinhallinnasta:– Tietorakenteen koko✶ voidaan määrätä vasta

suorituksen aikana ja koko voi vaihdella.

– Ohjelmoija voi eksplisiittisesti määrätä tieto-alkioiden eliniän.

▼ Edelliset ehdot täyttäviä tietorakenteita kutsutaandynaamisiksi tietorakenteiksi (dynamic data

structures).

▼ Dynaamiset rakenteet ovat entuudestaan tuttujenstaattisten rakenteiden vastakohta ➠ staattistenrakenteiden– koko on oltava tiedossa käännösaikana eikä se

ohjelman suorituksen kuluessa muutu ja

– elinikä määräytyy muuttujan määrittelyhetkellä.

✶ Siis sen käyttöön varatun muistin määrä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 469: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 461▼ C++-kielen työkalut dynaamisen muistinhallinnan

toteuttamiseen ovat operaattorit new ja delete:new tietotyyppi ;

Varaa riittävästi muistia, jotta sinne voidaan tallettaatietotyypin alkio. Jos tietotyypillä on rakentaja, jokaei tarvitse parametreja,✶ niin sitä kutsutaan varatundynaamisen muuttujan alustamiseksi. Muussa tapauksessamuuttujaa ei alusteta. Arvoksi evaluoituu osoitin varattuunmuuttujaan. Esimerkiksi:

int* iptr = new int;Murtoluku* mlptr = new Murtoluku;

new tietotyyppi( rakentajan_parametrit ) ;Kuten edellä, mutta muuttuja alustetaan rakentajalla, jonkaparametrit täsmäävät✶ rakentajan parametrien kanssa:

int* iptr = new int(42);Murtoluku* mlptr = new Murtoluku(2, 3);

delete vapautettavan_muuttujan_osoite ;Vapauttaa dynaamisesti varatun muuttujan, jonka osoitekerrotaan operandilla vapautettavan muuttujan osoite:

delete iptr;delete mlptr;

Vapautettavan muuttujan on oltava new:llä varattu, muutenpahuus voittaa.

✶ Kuormitukset ja oletusparametrit huomioidaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 470: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 462▼ new:stä dynaamisen muuttujan elinikä siis alkaa ja

delete:en se päättyy.

▼ Koska C++ »samaistaa» taulukot ja osoittimet, onnew:stä ja delete:stä olemassa versiot, joilla voidaanvarata ja vapauttaa dynaaminen taulukko:new tietotyyppi [ alkioiden_määrä ] ;

Varaa dynaamisen taulukon, jossa on alkioiden määrä

alkiota, jotka ovat tyypiltään tietotyyppiä. Alkiot alustetaanparametrittomalla rakentajalla,✶ jos sellainen on. Muutoinalkoita ei alusteta. Esimerkiksi:

Murtoluku* mltaulukko = new Murtoluku[1000];

delete [ ] vapautettavan_taulukon_osoite ;Vapauttaa dynaamisesti varatun taulukon, joka sijaitseeannetussa osoitteessa:

delete [ ] mltaulukko;

Vapautettavan taulukon on tuttuun tapaan oltava jokonew[ ]:llä varattu tai null.

▼ Jotta taulukko-new:n ja -delete:n voisi ymmärtää,kannattaa kerrata sivut 452–455.

✶ Kuormitukset ja oletusparametrit huomioidaan.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 471: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 463▼ Dynaamisesti varatun muistin käsittelyyn sisältyy

kaksi tärkeää periaatetta:1. Muistinvarauksen onnistuminen on aina

tarkistettava.

2. Ohjelman on vapautettava kaikki dynaaminenmuisti, jota se ei enää tarvitse.

▼ Jos muistinvaraus epäonnistuu, eikä ohjelmoijavaraudu siihen, on new-operaattorin normaalitoi-minto ohjelman kaataminen (UNIX:ssa core dump).

▼ Jos varattua muistia ei jossain vaiheessa vapautetamutta sitä kuitenkin varataan jatkuvasti lisää, niinjossain vaiheessa vapaa muisti loppuu.

▼ Itse asiassa muistin vapauttamatta jättäminen eiitsessään ole virhe, jos ohjelma tosiaankin käyttääkaikkea varaamaansa muistia.

▼ Ongelma syntyy silloin, kun osoitin dynaamisestivarattuun muuttujaan »hukataan» ➠ muistia ei voidavapauttaa, koska delete tarvitsee vapautettavanmuuttujan osoitteen ➠ tällaista hukkamuistinsyntymekanismia kutsutaan muistivuodoksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 472: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 464▼ Myöhemmin, kun yritetään havainnollistaa dynaa-

misia rakenteita, osoittautuu seuraava visuaalinenesitystapa hyödylliseksi.

▼ Ajatellaan yksinkertaista ohjelmanpätkää:struct Data {

int luku;int* iptr;

} ;

int i = 7;Data data;data.luku = 13;data.iptr = &i;Data* dataptr = &data;

▼ Kun nuo rivit on suoritettu, näyttää muistitilannejotenkin seuraavalta:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

i︷ ︸︸ ︷

luku iptr dataptr

data

7 binäärisenä 13 binäärisenä 0x000002 0x000008 . . .

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 473: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 465▼ Sen sijaan että esitettäisiin tilanne edellisen kaltaisella

sekavalla lokerikolla, merkitään muuttujia laatikoillaja osoittimia nuolilla seuraavaan tapaan:

7

13

dataptr

data

i

luku

iptr

sillä eihän muistiosoitteiden absoluuttisilla arvoillaole sinällään merkitystä ➠ tärkeintä on nähdä, kukaosoittaa minnekin.

▼ Edellisenkaltaisissa kaavioissa null-osoittimelle:int* ip = nullptr ;

käytetään yleensä merkintää:

ip

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 474: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 466

Dynaamiset tietorakenteet

▼ Yksinkertaisissa dynaamisissa tietorakenteissa ontiettyjä yhtäläisyyksiä ➠ ne koostuvat tietue- tailuokkatyyppisistä alkoista, jotka linkittyvät toisiinsaosoittimien avulla.

▼ Lisäksi käytössä on osoitin, joka kertoo missävarsinaisen linkkiketjun ensimmäinen alkio on.

▼ Esimerkiksi jos halutaan tallettaa dynaamiseentietorakenteeseen kokonaislukuja, määriteltäisiinseuraavankaltainen tietue ja osoitinmuuttuja:

struct Alkio {int luku;Alkio* seuraava;

} ;

Alkio* ensimmainen = nullptr ;

jolloin syntyvä rakenne näyttää muutaman luvun(4kpl) lisäämisen jälkeen seuraavalta:

ensimmainen

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 475: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 467▼ Alkio-tietue ja osoitin ensimmäiseen alkioon kätke-

tään abstraktin tietotyypin yksityiseen rajapintaan ➠kaikki operaatiot julkisen rajapinnan kautta.

▼ Syntyvää rakennetta kutsutaan linkitetyksi/ketju-

tetuksi listaksi (linked list) tai tarkemmin yhteen

suuntaan linkitetyksi listaksi (singly linked list).

▼ Myös monimutkaisemmat rakenteet ovat tokimahdollisia: kahteen suuntaan linkitetyt listat, puut,verkot jne ➠ vain ratkaistava ongelma ja mielikuvitusasettavat rajat.

▼ On aika tutkia ensimmäinen kokonainen esimerkki.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 476: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 468

Esimerkki: dynaaminen pino

▼ Yleisesti pino (stack) on tietorakenne, johon voidaankohdistaa kolmenlaisia operaatioita:

push

lisää uuden alkion pinon päällimmäiseksi.

pop

poistaa pinon päällimmäisen alkion ja palauttaa sen.

empty

kertoo onko pino tyhjä vai ei.

▼ Push- ja pop-operaatiot kohdistuvat pinon pääl-limmäiseen alkioon ➠ syvemmällä pinossa oleviinalkioihin päästään käsiksi vain suorittamalla useitaperäkkäisiä pop-operaatioita.

▼ Alkiot saadaan pinosta pois käänteisessä järjestyksessäverrattuna sisäänmenojärjestykseen ➠ pino onlast in–first out -rakenne (LIFO).

▼ Pino on linkitetyistä tietorakenteista helpointoteuttaa, koska kaikki listaa muokkaavat operaatiotkohdistuvat listan alkuun.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 477: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 469▼ Esimerkiksi reaalilukupinon (pino johon voidaan

tallettaa reaalilukuja) esittelytiedosto pino.hh:#ifndef PINO_HH#define PINO_HHclass Pino {public:

/ / Dynaamisella rakenteella on oltava rakentaja,// joka alustaa paallimmainen–osoittimen null:iksi.Pino( );

/ / Paluuarvo true, jos pinossa ei ole alkioita.bool empty( ) const;

/ / Työntää luvun pinon päälimmäiseksi alkioksi./ / Paluuarvo true jos onnistuu, false, jos ei// (muistia ei saada varattua).bool push(double luku);

// Poistaa pinon päällimmäisen alkion ja palauttaa// sen muuttujaparametrissa luku. Paluuarvo true// jos onnistuu, false jos pino oli tyhjä.bool pop(double& luku);

// Dynaamisella tietorakenteella on oltava purkaja,// joka vapauttaa dynaamisesti varatun muistin,// kun sitä ei enää tarvita.~Pino( );

private:struct Alkio {

double data;Alkio* seuraava;

};

Alkio* paallimmainen;};#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 478: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 470▼ Pino:n toteutus pino.cc näyttäisi tältä:

#include "pino.hh"

Pino::Pino( ): paallimmainen(nullptr) {}

bool Pino::empty( ) const {return paallimmainen == nullptr;

}

bool Pino::push(double luku) {Alkio* uusi;

try {uusi = new Alkio;

} catch (... ) {return false;

}

uusi–>data = luku;

uusi–>seuraava = paallimmainen;paallimmainen = uusi;

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 479: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 471bool Pino::pop(double& luku) {

if (paallimmainen == nullptr) {return false;

}

luku = paallimmainen–>data;

Alkio* poistettava = paallimmainen;paallimmainen = paallimmainen–>seuraava;delete poistettava;

return true;}

Pino::~Pino( ) {Alkio* tamanhetkinen = paallimmainen;Alkio* loput = nullptr;

while (tamanhetkinen != nullptr) {loput = tamanhetkinen–>seuraava;delete tamanhetkinen;tamanhetkinen = loput;

}

paallimmainen = nullptr;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 480: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 472▼ Pinoa voidaan testata pienellä pääohjelmalla

pinomain.cc:

#include <iostream>

#include <cstdlib>

using namespace std;

#include "pino.hh"

int main( ) {// Rakentajan Pino( ) kutsu kulissien takana:Pino lukupino;

for (int i = 0; i < 10; i++) {if ( !lukupino.push(static_cast<double>(i) ) ) {

cerr << "push epäonnistui!" << endl;return EXIT_FAILURE;

}}

while ( !lukupino.empty( ) ) {double luku;if ( !lukupino.pop(luku) ) {

cerr << "pop epäonnistui!" << endl;return EXIT_FAILURE;

}cout << luku << endl;

}

// Purkajan ~Pino( ) kutsu kulissien takana.}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 481: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 473

Esimerkin olennaisimmat kohdat

▼ Esimerkkiä ei ole tässä tarkoitus selitellä monisanai-sesti, koska ideana on käydä pino-tyypin toteutus jatoiminta luennolla läpi askel-askeleelta.✶

▼ Pinon toteutukseksi on valittu linkitetty lista, joka onkätketty abstraktin tietotyypin sisään.

▼ Ainoa jäsenmuuttuja paallimmainen kertoo, missälistan ensimmäinen alkio sijaitsee.

▼ Jos lista on tyhjä, paallimmainen on null-osoitin.

▼ Viimeisen alkion seuraava-kenttä on aina null.

▼ Uuden alkion lisäys (push) ja alkion poisto (pop)kohdistuu aina listan alkuun.

▼ new-operaattorin epäonnistumisen testaustalukuunottamatta muu koodi on olennaisilta osiltaanosoittimien päivittelyä oikeassa järjestyksessä, niinettä listan laillinen rakenne säilyy eikä dynaamisestivarattuja muistilohkoja hukata.

✶ b there || b �

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 482: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 474▼ Rakentaja alustaa pinon tyhjäksi eli sijoittaa null:in

osoittimeen paallimmainen.

▼ C++:ssa purkaja (s.326) on jäsenfunktio, jonka

– nimi on sama kuin abstraktin tietotyypin nimi,jonka eteen on lisätty tilde (~) ja jolla

– ei ole paluuarvon tyyppiä.

▼ Purkajaa kutsutaan kulissien takana automaattisesti,

kun abstraktia tietotyyppiä olevan muuttujanelinikä päättyy ➠ kun pinoa ei enää tarvita,sen mahdollisesti varaama dynaaminen muistivapautetaan ~Pino-funktion avulla.

▼ Huomaa kuinka ~Pino asettaa paallimmainen-osoittimen arvoksi null:in ➠ ei jäänneviitteitä eliosoittimia, jotka osoittavat jo vapautettuun muistiin

➠ jatkossa ei voida vahingossa käyttää vapautettuadynaamista muutujaa.

▼ ~Pino-jäsenfunktio huolehtii periaatteen 2 (s.463)toteutumisesta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 483: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 475

new:n onnistumisen tarkistaminen

▼ Jos dynaamisen muistin varaus new:llä epäonnistuu,niin oletusarvoisesti C++ käyttää sen ilmaisemiseenmekanismia, jota kutsutaan poikkeukseksi.

▼ Hyväksytään toistaiseksi totuutena esimerkissä ollutidea, mutta palataan asiaan yksityiskohtaisemminmyöhemmin poikkeuksien yhteydessä:

tyyppi* osoitin_dynaamiseen_muuttujaan ;

try {osoitin_dynaamiseen_muuttujaan = new tyyppi ;

} catch ( ... ) {// Virhetilanteen käsittely: mitä tehdään// jos muistia ei saanut varattua....

}

// Normaalitilanteen käsittely:// muisti saatiin varattua....

▼ Tämä rakenne toteuttaa periaatteen 1 (s.463).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 484: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 476

Poikkeukset

▼ Tutustutaan lyhyesti C++-kielen poikkeusmekanismiinja sen yksinkertaisimpiin käyttötarkoituksiin:

#include <iostream>#include <string>

using namespace std;

class Virhe {public:

Virhe(const string& info);string hae_info( ) const;

private:string info_;

};

Virhe::Virhe(const string& info): info_(info) {}

string Virhe::hae_info( ) const {return info_;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 485: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 477string LueRivi(istream& virta) {

string rivi;

getline(virta, rivi) ;

if ( !virta ) {if ( virta.eof( ) ) {

throw Virhe( "tiedosto loppui" ) ;} else {

throw Virhe( "tuntematon virhe" );}

}

return rivi;}

int main( ) {try {

while ( true ) {string rivi = LueRivi(cin);cout << "Syöte: " << rivi << endl;

}} catch ( const Virhe& virhe ) {

cout << "Virhe: " << virhe.hae_info( ) << endl;}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 486: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 478▼ Poikkeuksien avulla voidaan delegoida virhe-

tilanteiden käsittely jonnekin muualle kohdasta, jossavirhe varsinaisesti havaittiin.

▼ Poikkeuksien avulla voidaan myös välittää tietoavirheen tapahtumiskohdasta/laadusta virhetilanteenkäsittelijälle.

▼ Välitettävä tieto voi olla mitä tahansa tyyppiä,mutta useimmiten käytetään abstraktia tietotyyppiä,sillä sen avulla on helppo esittää ja käsitellämonimutkaistakin virheinformaatiota.

▼ Koodi, jonka suoritus saattaa aiheuttaa poikkeuksen,laitetaan try-lohkon sisään.

▼ Virhetilanteessa poikkeus heitetään throw-komennolla.

▼ Poikkeus voidaan ottaa kiinni (eli käsitellä) try–catch-rakenteen avulla.

▼ Jos/kun poikkeus on heitetty, järjestelmä etsiifunktiokutsujen hierarkiassa viimeisimmän try-catch-rakenteen, jossa catch-komennolla otetaan kiinniheitetyn tyyppinen poikkeus.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 487: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 479▼ Suoritus jatkuu löytyneen catch-haaran perässä

olevan lohkon sisällä.

▼ Käsittelemätön poikkeus ➠ ohjelma kaatuu.

▼ Joskus on tarpeen ottaa kiinni poikkeus riippumattasen tyypistä ➠ catch-osan »muodollisen parametrin»paikalle voi kirjoittaa kolme pistettä:

try {ip = new int;

} catch ( ... ) {cerr << "new-operaattori heitti poikkeuksen!" << endl;

}

▼ Tämä ei yleensä ole suositeltava tapa, koska samallahukataan täsmällinen tieto virheen tyypistä jatyyppiin mahdollisesti sisältyvä lisäinformaatio.

▼ Parempi tapa ottaa kiinni em. dynaamisen muistin-varauksen epäonnistumisesta johtuva poikkeus olisikäyttää bad_alloc-tyyppiä:

#include <new> // bad_alloc määritelty täällä· · ·try {

ip = new int;} catch ( bad_alloc& ) {

cerr << "muistinvaraus epäonnistui!" << endl;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 488: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 480▼ catch-haaran »parametrille» ei ole pakko antaa

nimeä, jos vain sen tyypillä on merkitystä.

▼ Kuitenkin on aiheellista (muutoinkin kuin tehok-kuussyistä) käyttää tyyppeinä viitetyyppejä eli lisätä&-merkki tyypin nimen perään.✶

▼ Yhden try-lohkon suorituksessa saatetaan kohdataerilaisia poikkeuksia ➠ catch-haaroja voi ketjuttaa:

#include <new> // bad_alloc#include <stdexcept> // out_of_range· · ·vector<int> vek;try {

vek.push_back(1); // muisti saattaa loppuavek.at(indeksi) = 4; // indeksi ehkä liian suuri

} catch ( bad_alloc& ) {cerr << "muisti loppui" << endl;

} catch ( out_of_range& ) {cerr << "laiton indeksi" << endl;

} catch ( ... ) {cerr << "tuntematon poikkeus" << endl;

}

▼ Tyypin out_of_range poikkeus heitetään ainakinstandardikirjaston vector- ja string-tyyppienat( ) -funktioissa, jos indeksi on liian suuri.

✶ Vaikka sitä ei kurssin tiedoilla voikaan kattavasti perustella.▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 489: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 481▼ Poikkeuksen heittäminen siirtää ohjelman suorituksen

mahdollisesti hyvinkin kauas heittokohdasta ➠ohjelman selkeys saattaa kärsiä.

▼ Usein sopivasti määritellyt funktioiden paluuarvot janiiden tutkiminen virhetilanteiden tunnistamiseksion vähintään yhtä hyvä ja lähes aina selkeämpi tapa.

▼ Poikkeukset ovat kuitenkin käyttökelpoinenmekanismi, jos:

– virheidenkäsittely halutaan tehdä keskitetystiyhdessä paikassa,

– virhe tapahtuu jossain syvällä funktiokutsuhie-rarkiassa, jolloin tiedon välittäminen tapahtuneestapaluuarvojen avulla virhetilanteen käsittelykohtaanolisi hankalaa,

– ohjelmassa käytetään kirjastoa, joka reagoivirhetilanteisiin heittämällä poikkeuksen tai

– abstraktin tietotyypin rakentajaa kutsuttaessatapahtuu virhe.

▼ Käytä poikkeuksia harkiten jos ollenkaan (ainakaanOhjelmointi II-kurssin tietotaidoilla).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 490: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 482

Pino toteutettuna dynaamisena

taulukkona

▼ Tässä vaiheessa on hyvä varmistaa, että ymmärtääpinon ja listan tarkoittavan eri asiaa.

▼ Lista on toteutusmekanismi, joka perustuu linkki-kenttien käyttöön pidettäessä kirjaa seuraaja-alkionsijainnista.

▼ Listan avulla voidaan toteuttaa pino, mutta listanavulla voidaan toteuttaa muunkinlaisia rakenteita.

▼ Pino puolestaan on toteutustavasta riippumattasellainen abstraktio, jossa ainoastaan viimeisintärakenteeseen lisättyä alkiota päästään suoraankäsittelemään (LIFO).

▼ Jotta tämä varmasti tulee selväksi, toteutetaandynaaminen pino taulukkona listan sijaan.

▼ Samalla tämä toimii esimerkkinä taulukko-new[ ]:nja taulukko-delete[ ] :n käytöstä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 491: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 483▼ Moduulin esittelytiedosto pino.hh

#ifndef PINO_HH#define PINO_HH

// using namespace std; ei pakollinen, koska mitään// kirjastoja ei tässä esittelytiedostossa käytetä.

class Pino {public:

/ / Sama abstraktio kuin alkuperäisessä esimerkissä// ➠ julkinen rajapinta on identtinen.

Pino( );

bool empty( ) const;bool push(double luku);bool pop(double& luku);

~Pino( );

private:/ / Dynaaminen taulukko johon alkiot talletetaan.double* taulukko;

// Montako alkiota pinossa on tällä hetkellä.int alkioita;

// Monelleko alkiolle taulukossa on tilaa.int tilaa_kaikkiaan;

};

#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 492: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 484▼ Moduulin toteutustiedosto pino.cc

#include "pino.hh"

// using namespace std; ei pakollinen, koska mitään

// kirjastoja ei tässä toteutustiedostossa käytetä.

const unsigned int ALKUKOKO = 100;

Pino::Pino( ): taulukko(nullptr) , alkioita(0),tilaa_kaikkiaan(0) {

}

bool Pino::empty( ) const {return alkioita == 0;

}

Pino::~Pino( ) {delete[ ] taulukko;

alkioita = 0;tilaa_kaikkiaan = 0;taulukko = nullptr;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 493: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 485bool Pino::push(double luku) {

// Taulukossa on valmiiksi tilaa uudelle alkiolle.if (tilaa_kaikkiaan > alkioita) {

taulukko[alkioita] = luku;++alkioita;

return true;

/ / Taulukko liian pieni pitää varata uusi isompi.} else {

double* uusi_taulukko;int uusi_tilan_maara;

if ( tilaa_kaikkiaan == 0 ) {uusi_tilan_maara = ALKUKOKO;

} else {// Uusi taulukko on kooltaan kaksi

// kertaa suurempi kuin vanha.uusi_tilan_maara = 2 * tilaa_kaikkiaan;

}

// Varataan uusi isompi taulukko.try {

uusi_taulukko = new double[uusi_tilan_maara];} catch ( ... ) {

return false;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 494: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 486// Kopioidaan uuteen taulukkoon kaikki

// alkiot vanhasta taulukosta.for (int i = 0; i < alkioita; ++i) {

uusi_taulukko[i] = taulukko[i];}

// Vapautetaan vanha taulukko.delete[ ] taulukko;

// Päivitetään jäsenmuuttujat uuden

// taulukon mukaisiksi.taulukko = uusi_taulukko;tilaa_kaikkiaan = uusi_tilan_maara;

// Nokkela rekursio: vältetään kirjoittamasta

// ensimmäisen if–rakenteen runkoa uudelleen.return push(luku);

}}

bool Pino::pop(double& luku) {if (alkioita == 0) {

return false;}

– –alkioita;

luku = taulukko[alkioita];

/ / Huomaa että pinolle varattu tila ei pienene.

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 495: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 487▼ Koska C++:ssa on taulukoiden ja osoittimien välillä

tunnettu yhteys, voidaan dynaamisesti varattuataulukkoa käsitellä osoittimena sen ensimmäiseenalkioon.

▼ Uuden pinotyypin julkinen rajapinta on sama kuinalkuperäisen ➠ alkuperäinen voidaan tarvittaessakorvata uudella tai päinvastoin.

▼ Uusi toteutus yrittää optimoida jatkuvan muistinva-rauksen tarvetta varaamalla kerralla tilaa useammallealkiolle ➠ osaa varatusta muistista ei välttämättäkoskaan käytetä ➠ tuhlausta(?)

▼ Toisaalta alkuperäinen listatoteutuskin käyttääylimääräistä muistia linkkikenttien ylläpitämiseen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 496: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 488

Tietorakenteen kopiointi:

alustus ja sijoitus

▼ Kertaus: alustus tarkoittaa alkuarvon asettamistamuuttujalle sen määrittelyvaiheessa.

▼ Taulukoita lukuunottamatta muuttujia voi alustaaC++:ssa toisella samantyyppisellä arvolla:

int i(5); // Huomaa kaksi eri syntaksia alustamiselle.int j = 6; // Molemmat tarkoittavat samaa.Opiskelija o1;· · ·Opiskelija o2(o1);Opiskelija o3 = o2;

▼ Kannattaa huomata, että alustus tapahtuu myössilloin, kun arvoparametrit alustetaan todellisistaparametreista ➠ muodollisen parametrin arvoksialustetaan todellisen parametrin arvo.

▼ Muuttujaan voi myös sijoittaa toisen samantyyppisenarvon =-operaattorilla:

int i;i = 5;Opiskelija o1, o2;· · ·o2 = o1;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 497: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 489▼ Alustuksen ja sijoituksen oletussemantiikka on, että

kaikki sijoitettavat tiedot kopioidaan tavu-tavultamuistissa lähdemuuttujasta kohdemuuttujaan.

▼ Jos kopioitavana on tietue tai luokka, kukin kenttä taijäsenmuuttuja kopioidaan tavu-tavulta muuttujastatoiseen.

▼ Tällainen kopiointi on ohjelmoijan kannaltapääsääntöisesti järkevä ja looginen toimintatapa.

▼ Jos kuitenkin kopiotava tietoalkio on osoitin,seurauksena on lähes aina ongelmia, erityisesti joskyseessä on osoitin dynaamisesti varattuun muistiin.

▼ Tämä johtuu siitä, että vain osoittimen arvokopioituu, ei osoittimen osoittama tieto (matala-

kopio, shallow copy) ➠ Tämä on C++:ssa alustuksenja sijoituksen oletuskäyttäytyminen.

▼ Havainnollistetaan ongelmaa pienellä koodinpätkällä:

Pino p1;p1.push(1.0);p1.push(2.1);Pino p2(p1);

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 498: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 490▼ Tai aivan sama tilanne, vaikka koodi olisi:

Pino p1;Pino p2;p1.push(1.0);p1.push(2.1);p2 = p1;

▼ Molemmat koodit menevät käännöksestä läpi, muttalähempi tarkastelu tuo ilmi vakavan ongelman.

▼ Pino-luokka koostuu osoitinjäsenmuuttujastapaallimmainen, joka osoittaa linkitetyn listanensimmäiseen alkioon.

▼ Kun tämä osoitin kopioidaan tavu-tavulta muuttu-jasta p1 muuttujaan p2, saadaan kaksi pinoa, jotkamolemmat käsittelevät samaa dynaamista listaa:

p1 p2

2.1 1.0

paallimmainenpaallimmainen

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 499: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 491▼ Syntyneessä tilanteessa esimerkiksi operaatio:

p2.pop(luku);

sotkee tilanteen pahasti:

p1 p2

1.0

paallimmainenpaallimmainen

▼ Pinon p1 paallimmainen-osoitin jää nyt osoittamaanvapautettuun dynaamiseen alkioon (jäänneviite).

▼ Ongelman ratkaisuun on kaksi mahdollisuutta:

– Estetään kopioituminen täysin (siis kielletäänalustus ja sijoitus samantyyppisestä alkiosta).

– Määritellään nk. kopiorakentaja ja sijoitus-operaattori kyseessä olevalle tietotyypille siten,että kopiointi ei tapahdu C++:n oletussemantiikanmukaisesti, vaan tyypin kannalta järkevästi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 500: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 492▼ Kopioitumisen esto on helppo toteuttaa:

class Pino {public:· · ·

private:Pino(const Pino& alustusarvo);Pino& operator=(const Pino& sijoitettava) ;· · ·

} ;

▼ Lisäämällä kopiorakentaja- ja sijoitusoperaattori-funktioiden esittely luokan private-osaan jajättämällä funktiot määrittelemättä, saadaan ainakäännösvirhe, jos rakennetta yritetään tavalla taitoisella kopioida.

▼ Kopiorakentajafunktio on muodoltaan ainaseuraavan näköinen:

Tyyppinimi(const Tyyppinimi& alustusarvo);

▼ Sijoitusoperaattori taas on muotoa:Tyyppinimi& operator=(const Tyyppinimi& sijoitettava) ;

▼ Funktion nimenä oleva operator= on C++:n tapaesittää, että kyseessä ei ole normaalifunktio, vaanettä ollaan kertomassa, kuinka = -operaattori toimiikyseisellä luokalle.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 501: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 493▼ Sijoitusoperaattorin paluuarvon tyypin on oltava

viite käsiteltävään tietotyyppiin, koska se vastaaC++-kielen oman =-operaattorin toimintaa ➠ tätäei ole kriittistä ymmärtää, kunhan muistaa tehdäpaluuarvon tyypistä viitteen.

▼ Jos ei ole erityistä syytä sallia rakenteen kopiointia,edellä esitelty tapa on suositeltava ➠ Estä aina

jatkossa kopioituminen, paitsi jos todella haluat

sallia sen tietotyypillesi.

▼ Uudessa C++-kielen versiossa oletuskopiorakentajanja -sijoitusoperaattorin voi estää myös selkeämmin: ✶

class Pino {public:· · ·Pino(const Pino&) = delete;Pino& operator=(const Pino&) = delete;· · ·

private:· · ·

} ;

✶ Tämä on uuden c++-standardin tuoma ominaisuus, joka toimiiOhjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä. Jos osallistutjatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissaopetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio

kääntäjästä, eikä tämä ominaisuus toimi. Älä siis tule liian riippuvaiseksiominaisuuden olemassaolosta.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 502: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 494▼ Joskus on tarve toteuttaa kopiorakentaja ja

sijoitusoperaattori, jotka kopioivat rakenteen toiseenilman ongelmia.

▼ Tällöin ohjelmoijan on esiteltävä kopiorakentajaja sijoitusoperaattori luokan public-osassa jamääriteltävä ne siten, että kopiointi tapahtuuhalutulla tavalla.

▼ Muutetaan dynaamisena taulukkona toteutettuapinoa siten, että alustus ja sijoitus toisesta pinostatoimivat oikein.

▼ Lisätään kopiorakentajan ja sijoituksen esittelyt Pino-luokan julkiseen rajapintaan pino.hh-tiedostossa:

class Pino {public:· · ·Pino(const Pino& alustusarvo);Pino& operator=(const Pino& sijoitettava) ;· · ·

private:· · ·

} ;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 503: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 495▼ Lisäksi määritellään em. funktiot pino.cc-tiedostossa:

Pino::Pino(const Pino& alustusarvo):taulukko(nullptr) ,alkioita(alustusarvo.alkioita) ,tilaa_kaikkiaan(alustusarvo.tilaa_kaikkiaan) {

// Varataan riittävästi tilaataulukko = new double[tilaa_kaikkiaan];

// Kopioidaan kaikki alkiot alustustarvotaulukosta.for ( int i = 0; i < alkioita; ++i ) {

taulukko[i] = alustusarvo.taulukko[i];}

}

Pino& Pino::operator=(const Pino& sijoitettava) {// Ei olla sijoittamassa muuttujaa itseensä.if ( this != &sijoitettava ) {

alkioita = sijoitettava.alkioita;

// Ei ole valmiina tilaa kaikille

// sijoitettaville alkioille.if ( tilaa_kaikkiaan < sijoitettava.alkioita ) {

// Vapautetaan vanha tila ja varataan

// tarpeeksi uutta tilaa.delete[ ] taulukko;tilaa_kaikkiaan = sijoitettava.tilaa_kaikkiaan;taulukko = new double[tilaa_kaikkiaan];

}

// Jatkuu seuraavalla sivulla...▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 504: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 496// ... jatkoa edelliseltä sivulta

// Kopioidaan kaikki alkiot lähdetaulukosta

// kohdetaulukkoon.for ( int i = 0; i < alkioita; ++i ) {

taulukko[i] = sijoitettava.taulukko[i];}

}

return *this;}

▼ Olennaista edellä on se, että dynaamisesti varatustamuistista tehdään oma dynaaminen kopio kopioinninkohteelle (syväkopio, deep copy).

▼ Jos pinon toteutus olisi ollut linkitetty lista, olisikopionti tietysti hiukan monimutkaisempaa, koskakoko listasta pitäisi tehdä kopio alkio-alkiolta.

▼ Kopiorakentaja on yleensä melko suoraviivainen,koska se vain kopioi tiedot paikasta toiseen.

▼ Sijoitusoperaattori on tavallisesti kopiorakentajaamonimutkaisempi, koska sijoituksen kohde onolemassa oleva muuttuja ➠ operaation otettavakantaa siihen, mitä vanhalle tiedolle tehdään(muistin vapauttaminen yms.)

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 505: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 497▼ Sijoitusoperaattorin toteutukseen liittyy yksi

erityispiirre, jota kannattaa korostaa: mitä tehdä, josohjelmoija jostain syystä sijoittaa muuttujan arvonitseensä:

Pino p;· · ·p = p;

▼ Tämä on laillinen operaatio, mutta sijoitusoperaat-torin kannalta sikäli erikoinen, että sen ei (yleensä)tarvitse tehdä mitään.

▼ «Itseensäsijoitus» huomataan sijoitusoperaattori-funktiossa siten, että vertaillaan osoitinmuuttujanthis arvoa lähtöarvomuuttujan osoitteeseen:

if ( this != &sijoitettava ) {// Mitä tehdään jos sijoitettava ja// sijoituksen kohde ovat eri muuttujia.· · ·

}

▼ Muuttuja this on automaattisesti määriteltynäkaikien luokkien kaikissa jäsenfunktioissa ja seosoittaa siihen muuttujaan, jonka välitykselläjäsenfunktiota kutsuttiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 506: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 498▼ Esimerkiksi jos p, p1 ja p2 ovat tyypiltään luokkia:

// Seuraavassa print-funktion kutsussa this// osoittaa muuttujaan p.p.print( );

// Nyt this osoittaa print-funktiossa muuttujaan p1.p1.print( ) ;

// operator= -funktiossa this osoittaa// muuttujaan p1.p1 = p2;

▼ Jälkimmäinen esimerkki ei ehkä ole itsestäänselvä,mutta se juontaa juurensa siitä, että luokkatyyppisillämuuttujilla seuraavat kaksi tarkoittavat samaa:

p1 = p2; // Tämä on vain lyhyempip1.operator=(p2); // tapa kirjoittaa tämä.

▼ Funktion operator= paluuarvon on aina oltava *this.

▼ Samaa operatorX(. . . )-ideaa voi käyttää muidenkinkielen operaattorien kuormittamiseen luokkatyypeille

➠ tällä kurssilla siihen ei paneuduta enempää.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 507: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 499

Esimerkki: puhelinluettelo listana

▼ Toteutetaan abstrakti tietotyyppi Puhelinluettelo

linkitettynä listana.

▼ Syntyvän rakenne on tuttu yhteen suuntaan linkitettylista, mutta uusina piirteinä:

– Lisättävä alkio menee aina automaattisestiaakkosjärjestyksensä mukaiselle paikalle ➠listan alkiot ovat nimen mukaisessa kasvavassaaakkosjärjestyksessä.

– Puhelinluettelosta voidaan hakea ja poistaa infor-maatiota käyttäen henkilön nimeä hakuavaimena.

– Koko puhelinluettelo voidaan tulostaa näytölle.

▼ Sama henkilö voi myös olla luettelossa useamminkuin kerran ➠ haku ja poisto kohdistuvat kerrallakaikkiin kyseisen henkilön tietoihin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 508: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 500▼ Puhelinluettelo-tietotyypin julkinen rajapinta

(puhelinluettelo.hh):

#ifndef PUHELINLUETTELO_HH

#define PUHELINLUETTELO_HH

#include <string>

class Puhelinluettelo {public:

Puhelinluettelo( ) ;

bool lisaa(string nimi, string numero);bool poista(string nimi);

void tulosta( ) const;void nayta_numero(string nimi) const;

~Puhelinluettelo( ) ;

private:Puhelinluettelo(const Puhelinluettelo& pl) ;Puhelinluettelo& operator=(const Puhelinluettelo& pl) ;

struct Henkilo {string nimi;string numero;Henkilo* seuraava;

};

Henkilo* ensimmainen;};

#endif

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 509: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 501▼ Puhelinluettelon testipääohjelma (puhmain.cc):

#include <cstdlib>

using namespace std;

#include "puhelinluettelo.hh"

int main( ) {Puhelinluettelo luettelo;

// Testimateriaalin alustus luetteloon:

// rumasti mutta tarkoituksiin riittävästi.if ( !luettelo.lisaa( "Teekkari, Tiina", "050 123 4567" )

| | !luettelo.lisaa( "Arkkari, Arto", "040 246 8101" )

| | !luettelo.lisaa( "Teekkari, Teemu", "365 3804" )

| | !luettelo.lisaa( "Ymppäri, Yrjö", "012 135 7911" )

| | !luettelo.lisaa( "Rakentaja, Risto" , "09 765 4321" )

| | !luettelo.lisaa( "Teekkari, Teemu", "123 4567" )

| | !luettelo.lisaa( "Materialisti, Minna", "918 3889" )

| | !luettelo.lisaa( "Opintokanslia" , "1357" )

| | !luettelo.lisaa( "Ymppäri, Yrjö", "975 3100" )

| | !luettelo.lisaa( "Arkkari, Arto", "918 3889" ) ) {return EXIT_FAILURE;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 510: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 502luettelo.tulosta( ) ;

luettelo.nayta_numero( "Tuntematon, Teppo" );luettelo.nayta_numero( "Arkkari, Arto" );luettelo.nayta_numero( "Ymppäri, Yrjö" ) ;luettelo.nayta_numero( "Teekkari, Teemu" );

// Koska poista( ) palauttaa epätoden, jos poistettavaa

// nimeä ei löydy luettelosta, niin kaikissa seuraavissa

// poiston onnistuminen voitaisiin tarvittaessa tarkistaa.luettelo.poista( "Teekkari, Teemu" );luettelo.poista( "Arkkari, Arto" );luettelo.poista( "Ymppäri, Yrjö" );luettelo.poista( "Rakentaja, Risto" ) ;luettelo.poista( "Teekkari, Tiina" );luettelo.poista( "Materialisti, Minna" );

luettelo.tulosta( ) ;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 511: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 503▼ Puhelinluettelon toteutus (puhelinluettelo.cc):

#include <iostream>

#include <string>

using namespace std;

#include "puhelinluettelo.hh"

Puhelinluettelo::Puhelinluettelo( ) : ensimmainen(nullptr) {}

// Lisää henkilön nimi numeroineen puhelinluetteloon

// siten, että luettelon alkiot ovat aina aakkosjärjestyksessä.

// Paluuarvo true, jos lisäys onnistui, muuten false.bool Puhelinluettelo::lisaa(string nimi, string numero) {

Henkilo* uusi = nullptr;

try {uusi = new Henkilo;

} catch ( ... ) {cerr << "Muistinvaraus epäonnistui" << endl;return false;

}

uusi–>nimi = nimi;uusi–>numero = numero;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 512: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 504// Tapaukset 1 ja 2 voitaisiin yhdistää: ne on esitetty

// erikseen vain selvyyden vuoksi. Joka tapauksessa

// listan alkuun lisäys pitää huomioida erikseen, koska

// silloin muutetaan jäsenmuuttujaa ensimmainen.

// Tapaus 1: Lisätään tyhjään puhelinluetteloon

// ensimmäinen henkilöif (ensimmainen == nullptr) {

uusi–>seuraava = nullptr;ensimmainen = uusi;

return true;

// Tapaus 2: Lisäys puhelinluettelon alkuun} else if (ensimmainen–>nimi > nimi) {

uusi–>seuraava = ensimmainen;ensimmainen = uusi;

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 513: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 505// Muussa tapauksessa Etsitään henkilö, jonka jälkeen

// lisättävä henkilö aakkosjärjestyksessä kuuluu.Henkilo* kenen_jalkeen = ensimmainen;while (kenen_jalkeen–>seuraava != nullptr

&& kenen_jalkeen–>seuraava–>nimi < nimi) {

kenen_jalkeen = kenen_jalkeen–>seuraava;}

// Tapaukset 3 ja 4 voitaisiin myös yhdistää.

// Uuden alkion seuraava–kenttään voitaisiin

// suoraan kopioida edeltäjän seuraava kenttä.

// Tapaus 3: Lisäys puhelinluettelon viimeiseksiif (kenen_jalkeen–>seuraava == nullptr) {

uusi–>seuraava = nullptr;kenen_jalkeen–>seuraava = uusi;

return true;

// Tapaus 4: Lisäys puhelinluettelon keskelle} else {

uusi–>seuraava = kenen_jalkeen–>seuraava;kenen_jalkeen–>seuraava = uusi;

return true;}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 514: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 506// Poistaa puhelinluettelosta kaikki tiedot henkilöstä

// nimi. Palautaa arvon true, jos henkilöstä oli

// luettelosta tietoja, muussa tapauksessa false.bool Puhelinluettelo::poista(string nimi) {

bool tehtiinko_poistoja = false;Henkilo* poistettava = nullptr;

// Tapaus 1: Poistetaan yksi tai useampia luettelon

// alusta. Poisto alusta käsiteltävä erikseen, koska

// se modifioi jäsenmuuttujaa ensimmainen.while (ensimmainen != nullptr

&& ensimmainen–>nimi == nimi) {

poistettava = ensimmainen;ensimmainen = ensimmainen–>seuraava;

delete poistettava;

tehtiinko_poistoja = true;}

// Jos poistoja tehtiin listan alusta, voidaan lopettaa,

// koska lista on nimen mukaisessa aakkosjärjestyksessä

// ➠ nimi ei voi enää esiintyä listassa myöhemmin.if (tehtiinko_poistoja) {

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 515: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 507

// Tapaus 2: Poistetaan yksi tai useampia

// muualta luettelosta.Henkilo* edeltaja = ensimmainen;while (edeltaja != nullptr) {

if (edeltaja–>nimi > nimi) {break;

} else if (edeltaja–>seuraava != nullptr&& edeltaja–>seuraava–>nimi == nimi) {

poistettava = edeltaja–>seuraava;edeltaja–>seuraava = poistettava–>seuraava;

delete poistettava;

tehtiinko_poistoja = true;

} else {

edeltaja = edeltaja–>seuraava;}

}

return tehtiinko_poistoja;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 516: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 508// Tulostaa koko puhelinluettelon aakkosjärjestyksessä

// näytölle. Tulostus itsessään on triviaali listan

// läpikäynti, koska lisaa–funktio takaa, että

// lista on valmiiksi aakkosjärjestyksessä.void Puhelinluettelo::tulosta( ) const {

if (ensimmainen == nullptr) {cout << "Luettelo on tyhjä" << endl;return;

}

cout << " – – – – – – – – – – – – – – – – – " << endl<< "Puhelinluettelossa ovat:" << endl<< " – – – – – – – – – – – – – – – – – " << endl;

Henkilo* tulostettava = ensimmainen;while (tulostettava != nullptr) {

cout << tulostettava–>nimi<< ": "<< tulostettava–>numero<< endl;

tulostettava = tulostettava–>seuraava;}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 517: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 509// Tulostaa kaiken puhelinluettelosta löytyvän// informaation henkilöstä nimi.void Puhelinluettelo::nayta_numero(string nimi) const {

Henkilo* tamanhetkinen = ensimmainen;bool loytyiko = false;

while (tamanhetkinen != nullptr) {if (tamanhetkinen–>nimi > nimi) {

break;} else if (tamanhetkinen–>nimi == nimi) {

cout << tamanhetkinen–>nimi << ": "<< tamanhetkinen–>numero << endl;

loytyiko = true;}tamanhetkinen = tamanhetkinen–>seuraava;

}

if ( !loytyiko) {cerr << "Tuntematon henkilö: " << nimi << endl;

}}

Puhelinluettelo::~Puhelinluettelo( ) {Henkilo* vapautettava = ensimmainen;while (vapautettava != nullptr) {

Henkilo* seuraava = vapautettava–>seuraava;delete vapautettava;vapautettava = seuraava;

}ensimmainen = nullptr;

} ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 518: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 510

▼ Esimerkin olennaisimmat kohdat on kommentoitukoodissa.

▼ Yleisellä tasolla ohjelman oli tarkoitus havainnollistaasitä, että linkkikenttiä modifioiviin operaatioihinsisältyy erikoistapauksia, jotka on otettava huomioon.

▼ Erikoistapaukset johtuvat siitä, että usein osa taikaikki operaatioista:– ensimmäisen alkion lisääminen tyhjään listaan,– listan ainoan jäljellä olevan alkion poisto,– listan alkuun lisääminen tai listan ensimmäisen

alkion poisto,– alkion lisääminen tai poistaminen listan keskellä ja– alkion lisääminen tai poistaminen listan lopussajoudutaan toteuttamaan hiukan eri tavoin.

▼ Aina kaikki edellämainitut kohdat eivät vaadi erillistäkäsittelyä ja joskus useampia kohtia voidaan yhdistää,mutta listaoperaatioita toteuttaessaan kannattaakaikki kohdat käydä mielessään läpi ➠ muutenjoskus joku unohtuu ja homma menee happamaksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 519: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 511

Listat ja rekursio

▼ Listat ja hyvin monet muut linkitetyt tietorakenteetovat rakenteeltaan rekursiivisia.

▼ Esimerkiksi yhteen suuntaan linkitetty lista koostuu

– listan kärkialkiosta ja

– listan hännästä (siis lopuista alkioista), jotkaselvästi muodostavat yhtä alkiota lyhyemmän listan.

▼ Kun lista määritellään em. rekursiivisena rakenteena,ajautuu väistämättä pohtimaan mahdollisuuttatoteuttaa listaoperaatiot rekursiivisina funktioinajotenkin seuraavasti:

1. Käsittele listan kärkialkio.

2. Käsittele rekursiivisella funktiokutsulla loput alkiot.

▼ Tämä onkin usein lyhyin, elegantein ja selkein tapatoteuttaa operaatiot linkitetyille tietorakenteille.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 520: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 512▼ Johtuen tavasta jolla linkitetyt rakenteet toteutetaan

(kätketty abstraktin tietotyypin yksityiseen raja-pintaan), ajaudutaan yleensä seuraavaan ratkaisuun:

– Julkisen rajapinnan jäsenfunktio näyttää käyt-täjälle aivan samalta kuin iteratiivisen version(silmukkarakenteeseen perustuvassa) tapauksessa.

– Käytännössä se on kuitenkin vain helppo liittymäyksityiseen jäsenfunktioon, joka on rekursiivinen jasaa alkuparametrinaan osoittimen linkkirakenteenensimmäiseen alkioon.

▼ Yksityisen rekursiivisen funktion paluuarvo riippuutilanteesta, kuten esimerkistä pian huomataan.

▼ Toteutetaan esimerkin vuoksi koko Puhelinluettelo-tietotyyppi rekursion avulla.

▼ Pääohjelma säilyy luonnollisesti ennallaan, sillä eihänjulkinen rajapinta muutu, vain toteutus sen takana.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 521: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 513▼ Uusi versio puhelinluettelo.hh:sta:

#ifndef PUHELINLUETTELO_HH

#define PUHELINLUETTELO_HH

#include <string>

class Puhelinluettelo {public:Puhelinluettelo( );bool lisaa(string nimi, string num);bool poista(string nimi);void tulosta( ) const;void nayta_numero(string nimi) const;~Puhelinluettelo( );

private:Puhelinluettelo(const Puhelinluettelo& pl);Puhelinluettelo& operator=(const Puhelinluettelo& pl);

struct Henkilo {string nimi;string numero;Henkilo* seuraava;

};

Henkilo* lisaa_r(Henkilo* hptr, Henkilo* uusi) ;Henkilo* poista_r(Henkilo* hptr, string nimi, bool& ok);void tulosta_r(Henkilo* hptr) const;void nayta_numero_r(Henkilo* hptr,

string nimi, bool& ok) const;void tyhjenna_r(Henkilo* hptr);

Henkilo* ensimmainen;};#endif ▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 522: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 514▼ Uusi rekursiivinen versio puhelinluettelo.cc:sta,

(funktiot on määritelty tilan optimoimiseksi erijärjestyksessä kuin alkuperäisessä ohjelmassa):

#include <iostream>

#include <string>

using namespace std;

#include "puhelinluettelo.hh"

Puhelinluettelo::Puhelinluettelo( ): ensimmainen(0) {}

Puhelinluettelo::~Puhelinluettelo( ) {tyhjenna_r(ensimmainen);ensimmainen = nullptr;

}

void Puhelinluettelo::tyhjenna_r(Henkilo* hptr) {if (hptr == nullptr) {

return;} else {

tyhjenna_r(hptr–>seuraava);delete hptr;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 523: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 515void Puhelinluettelo::tulosta( ) const {

if (ensimmainen == nullptr) {cout << "Luettelo on tyhjä" << endl;return;

}

cout << " – – – – – – – – – – – – – – – – – " << endl<< "Puhelinluettelossa ovat:" << endl<< " – – – – – – – – – – – – – – – – – " << endl;

tulosta_r(ensimmainen);}

void Puhelinluettelo::tulosta_r(Henkilo* hptr) const {if (hptr == nullptr) {

return;} else {

cout << hptr–>nimi<< ": "<< hptr–>numero<< endl;

tulosta_r(hptr–>seuraava);}

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 524: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 516void Puhelinluettelo::nayta_numero(string nimi) const {

bool loytyiko = false;

nayta_numero_r(ensimmainen, nimi, loytyiko);

if (!loytyiko) {cerr << "Tuntematon henkilö: " << nimi << endl;

}}

void Puhelinluettelo::nayta_numero_r(Henkilo* hptr, string nimi, bool& ok) const {

if (hptr == nullptr) {return;

} else if (hptr–>nimi == nimi) {cout << hptr–>nimi << ": "

<< hptr–>numero << endl;ok = true;nayta_numero_r(hptr–>seuraava, nimi, ok);

} else {nayta_numero_r(hptr–>seuraava, nimi, ok);

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 525: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 517bool Puhelinluettelo::lisaa(string nimi, string numero) {

Henkilo* uusi;

try {uusi = new Henkilo;

} catch ( ... ) {cerr << "Muistinvaraus epäonnistui" << endl;return false;

}

uusi–>nimi = nimi;uusi–>numero = numero;

ensimmainen = lisaa_r(ensimmainen, uusi) ;

return true;}

Puhelinluettelo::Henkilo*Puhelinluettelo::lisaa_r(Henkilo* hptr, Henkilo* uusi) {

if (hptr == nullptr) {uusi–>seuraava = nullptr;return uusi;

} else if (hptr–>nimi > uusi–>nimi) {uusi–>seuraava = hptr;return uusi;

} else {hptr–>seuraava = lisaa_r(hptr–>seuraava, uusi) ;return hptr;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 526: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 518bool Puhelinluettelo::poista(string nimi) {

bool ok = false;

ensimmainen = poista_r(ensimmainen, nimi, ok);

return ok;}

Puhelinluettelo::Henkilo*Puhelinluettelo::poista_r(Henkilo* hptr,

string nimi, bool& ok) {if (hptr == nullptr) {

return nullptr;} else if (hptr–>nimi == nimi) {

Henkilo* seuraava = hptr–>seuraava;delete hptr;ok = true;return poista_r(seuraava, nimi, ok);

} else {hptr–>seuraava = poista_r(hptr–>seuraava, nimi, ok);return hptr;

}}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 527: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 519▼ Esimerkin alkupään rekursiiviset funktiot

(tyhjenna_r, tulosta_r ja nayta_numero_r) ovatsuoraan sivulla 511 esitetyn perusidean mukaisia.

▼ Pieni poikkeus on tyhjenna_r, joka tuhoaa ensinloput alkiot ja vasta sitten ensimmäisen alkion ➠käsittelyvaiheet takaperoisessa järjestyksessä:

1. Käsittele rekursiivisesti listan hännän alkiot.

2. Käsittele listan kärkialkio.

▼ Tuo idea soveltuu aina, kun lista halutaan käsitelläviimeisestä alkiosta ensimmäiseen järjestyksessä.

▼ Hiukan monimutkaisemmin joudutaan toteuttamaanfunktiot, jotka muuttavat listaa (lisaa_r ja poista_r):

– Rekursiivinen kutsu palauttaa osoittimen mahdol-lisesti muuttuneen loppulistan kärkialkioon, joka

– sijoitetaan aiemmalla rekursiokierroksella kyseisenkierroksen alkualkion seuraava-kenttään tai aivanalussa listan ensimmäinen-osoittimeen.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 528: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 520▼ Lisäksi esimerkkiin sisältyi syntaktis–semanttinen

opetus: jos halutaan käyttää jäsenfunktioidenulkopuolella luokan sisäisiä tietotyyppejä, niin setapahtuu kirjoittamalla:

luokan_nimi : : tietotyypin_nimi

▼ Tämä pätee myös silloin, kun kyseistä tietotyyppiä

käytetään jäsenfunktion paluuarvona.

▼ Ilman luokan nimi-etuliitettä tyyppiä voi käyttääjäsenfunktion rungossa ja sen muodollistenparametrien tyyppinä.

▼ Tätä samaa mekanismia käytetään myös, jos halutaankäyttää luokan sisäisten luettelotyyppien alkioitajossain muualla kuin jäsenfunktioissa:

class Luokka {public:

enum Koodi { VIRHE, OK } ;...

} ;...int main( ) {

...Luokka::Koodi status = Luokka::VIRHE;...

}▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 529: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 521

Kahteen suuntaan linkitetty lista

▼ Tutkitaan kahteen suuntaan linkitettyä listaa

(doubly linked list), jonka alkiot ovat kokonaislukuja.▼ Listan alkiot lisätään siten, että ne ovat aina

kasvavassa järjestyksessä.▼ Sama alkio voi olla listassa vain kerran ➠ kyseessä

on kokonaislukujoukko.▼ Toteutus pitää kirjaa sekä listan ensimmäisestä että

viimeisestä alkiosta.▼ Syntyvä linkitetty rakenne näyttää seuraavalta

(tyhjä, 1-alkioinen ja 4-alkioinen joukko):

1 2

3

4 8

first

firstfirst

last

lastlast

data

next

prev

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 530: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 522▼ Tarvittavan abstraktin tietotyypin määrittely:

class Set {public:

Set( ) ;

/ / True, jos parametri kuuluu joukkoonbool member(int number) const;

/ / Tulosta koko joukko näytöllevoid print( ) const;

/ / Lisää alkio oikealle paikalleenbool insert(int number);

// Poista alkio joukostabool remove(int number);

~Set( ) ;

private:Set(const Set& joukko);Set& operator=(const Set& joukko);

struct Node {int data;Node* next;Node* prev;

};

Node* first;Node* last;

};

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 531: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 523▼ Tutkitaan vain keskeisimmät jäsenfunktiot:

bool Set::insert(int number) {// Ei tehokkain mahdollinen idea. Miksei?if (member(number) ) {

return true;}

Node* new_node;try {

new_node = new Node;} catch (... ) {

return false;}

new_node–>data = number;new_node–>next = nullptr;new_node–>prev = nullptr;

/ / Ensimmäinen alkio tyhjään listaanif (first == nullptr) {

first = last = new_node;

// Lisäys listan alkuun} else if (first–>data > number) {

new_node–>next = first;first–>prev = new_node;first = new_node;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 532: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 524

// Lisäys listan loppuun} else if ( last–>data < number) {

new_node–>prev = last;last–>next = new_node;last = new_node;

// Lisäys listan keskelle} else {

// Etsitään uuden alkion tuleva seuraaja–alkioNode* follower = first;while (follower–>data < number) {

follower = follower–>next;}

// ja lisätään uusi alkio sen eteennew_node–>next = follower;new_node–>prev = follower–>prev;follower–>prev–>next = new_node;follower–>prev = new_node;

}

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 533: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 525bool Set::remove(int number) {

// Etsitään poistettava alkioNode* remove = first;while (remove != nullptr

&& remove–>data != number) {remove = remove–>next;

}

// Jos ei löydy tai lista oli tyhjäif (remove == nullptr) {

return false;}

// Onko poistettava listan ainoa alkioif (remove == first && remove == last) {

first = last = nullptr;

/ / Onko poistettava ensimmäinen alkio} else if (remove == first) {

first = remove–>next;remove–>next–>prev = nullptr;

/ / Onko poistettava viimeinen alkio} else if (remove == last) {

last = remove–>prev;remove–>prev–>next = nullptr;

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 534: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 526// Muutoin poistetaan jostain listan keskeltä} else {

remove–>prev–>next = remove–>next;remove–>next–>prev = remove–>prev;

}

// Puhdistetaan jäänneviitteetremove–>next = nullptr;remove–>prev = nullptr;

delete remove;

return true;}

▼ Kahteen suuntaan linkitetty lista on hyödyllinen, jostietoa on tarkoitus käydä läpi molempiin suuntiin.

▼ Käytännössä tutkittu koodi ei käyttänyt hyödyksikahteen suuntaan linkitetyn listan iloja, se olivalitettavasti vain esimerkki esimerkin vuoksi.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 535: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 527

Binäärihakupuu

▼ Binääripuu on juurisolmusta »kasvava» linkitettytietorakenne, jossa jokainen solmu sisältää talletet-tavan tiedon lisäksi osoittimen vasempaan ja oikeaanhaaraan:

0

1

2

3

4 5

6

7

8

9

osoitin juurisolmuun

juurisolmu

lehdet

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 536: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 528▼ Solmuja, jotka eivät enää haaraudu, kutsutaan

lehdiksi (kuvassa harmaalla pohjalla).

▼ Binäärihakupuu on vastaava rakenne sillä lisäeh-dolla, että puun jokaiselle solmulle pitää paikkansa:– Kaikki solmun vasempaan haaraan talletettu

informaatio ≤ solmuun talletettu informaatio.– Kaikki solmun oikeaan haaraan talletettu infor-

maatio > solmuun talletettu informaatio.

▼ Esimerkiksi seuraava on laillinen binäärihakupuu:

1

2

3

4

5

6

7

osoitin juurisolmuun

juurisolmu

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 537: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 529▼ Tasapainoiseksi sanotaan sellaista binääripuuta,

jossa jokaisen solmun vasemman ja oikean haarankorkeusero on enintään yksi.

▼ Jos binäärihakupuu on tasapainoinen tai lähestasapainoinen, on tiedon etsintä siitä erittäintehokasta.

▼ Tämä on helppo ymmärtää, kun miettii binääripuustarekursiivisesti hakuavaimen olemassaoloa tutkivaaalgoritmia:

bool OnkoPuussa(Solmu* solmu, int hakuavain) {if (solmu == nullptr) {

return false;} else if (solmu–>data == hakuavain) {

return true;} else if (solmu–>data > hakuavain) {

return OnkoPuussa(solmu–>vasen, hakuavain);} else {

return OnkoPuussa(solmu–>oikea, hakuavain);}

}

▼ Huomaa, että kyseessä on ulkoasultaan C++-koodinnäköinen algoritmi, ei jäsenfunktio tms.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 538: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 530▼ Koska tasapainoisen binääripuun syvyys

(pisin matka juuresta lehteen) on suurusluokkaalog2 puun alkioiden lukumäärä ➠ rekursio päättyysuunnilleen noin monen kutsun jälkeen ➠ jokolöydetään hakuavain tai tiedetään, että se ei olepuussa.

▼ On olemassa lisäys- ja poistoalgoritmeja, jotkatakaavat, että muutoksen jälkeen puu on tasapaino-tettu.

▼ Algoritmit ovat kuitenkin jonkin verran monimut-kaisia.

▼ Iloinen uutinen on se, että mikäli hakuavaimetlisätään puuhun satunnaisessa järjestyksessä,tuloksena saadaan puu, joka on yleensä melkotasapainoinen.

▼ Tuohon sisältyy kuitenkin riskejä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 539: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 531▼ Edellä esitetty etsintäalgoritmi on todellisuudessa

vastaava kuin lukujoukkotyypin member-funktio

➠ katsotaan tämän idean pohjalta lopuksi,kuinka voitaisiin toteuttaa joukkoon lisäys, mikälijoukkotyyppi olisi toteutettu binäärihakupuuna.

▼ Oletetaan että joukko on määritelty seuraavasti:

class Joukko {public:

Joukko( );...bool lisaa( int luku);...

private:struct Solmu {

int data;Solmu* vasen;Solmu* oikea;

};

Solmu* juuri;};

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 540: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 532▼ Toteutus olisi seuraavan kaltainen:

Joukko::Joukko( ): juuri(nullptr) {}

bool Joukko::lisaa(int luku) {Solmu* uusi;

try {uusi = new Solmu;

} catch (... ) {return false;

}

uusi–>data = luku;uusi–>vasen = nullptr;uusi–>oikea = nullptr;

/ / Tyhjään puuhun lisätään ensimmäinen solmuif ( juuri == nullptr) {

juuri = uusi;return true;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 541: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 533Solmu* isa = juuri;while (true) {

// Luku oli joukossa jo ennestäänif ( luku == isa–>data) {

delete uusi;break;

/ / Oikea paikka vasemmassa haarassa} else if ( luku < isa–>data) {

if ( isa–>vasen == nullptr) {isa–>vasen = uusi;break;

} else {isa = isa–>vasen;

}// Oikea paikka oikeassa haarassa} else {

if ( isa–>oikea == nullptr) {isa–>oikea = uusi;break;

} else {isa = isa–>oikea;

}}

}return true;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 542: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 534

▼ Alkion poistaminen binääripuusta jätetään jatko-kursseille, koska se on hiukan monimutkaisempioperaatio (Miksi?).

▼ Hakupuun alkiot saisi käytyä läpi (esim. tulostettua)hakuavaimen mukaan kasvavassa järjestyksessä:

void TulostaJärjestyksessä(Solmu* solmu) {if (solmu != nullptr) {

TulostaJärjestyksessä(solmu–>vasen);cout << solmu–>data << endl;TulostaJärjestyksessä(solmu–>oikea);

}}

▼ Kyseessä on taas C++-koodin näköinen algoritmi,ei jäsenfunktio tms.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 543: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 535

Geneerisyys

▼ Vaikka sivuilla 468–472 esitelty pinorakenne onkinhieno ja toimiva, niin se voisi olla parempikin.

▼ Nykyinen toteus mahdollistaa vain reaalilukupinojenkäsittelyn ohjelmassa.

▼ Jos tulee tarve luoda pino, johon talletettaisiinvaikkapa string-tyyppisiä arvoja, niin tässä vaiheessaainoa tapa olisi kopioida alkuperäinen pinomoduulija muuttaa sitä sopivilta osin ➠ tuollaisessa käsityössäei ole järkeä ja se on myös virhealtista puuhaa.

▼ Joissain ohjelmointikielissä on mahdollista luoda jakäyttää nk. geneerisiä (generic) eli yleiskäyttöisiä

tietorakenteita ja algoritmeja/funktioita.

▼ Geneerisyys on kansanomaisesti sitä, että kerrankoodattua tietorakennetta tai funktiota voidaanilman muutoksia käyttää useilla eri tietotyypeilläoperointiin.

▼ Tutustutaan seuraavaksi (pinnallisesti) C++:ngeneerisyysominaisuuksiin.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 544: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 536

Esimerkki: geneerinen pino

▼ Testipääohjelma (pinomain.cc):

#include <iostream>

#include <cstdlib>

#include <string>

using namespace std;

#include "genpino.hh"

int main( ) {Pino<double> lukupino;

for (int i = 0; i < 10; i++) {if ( !lukupino.push(double(i) ) ) {

cerr << "push epäonnistui!" << endl;return EXIT_FAILURE;

}}

while ( !lukupino.empty( ) ) {double luku;if ( !lukupino.pop(luku) ) {

cerr << "pop epäonnistui!" << endl;return EXIT_FAILURE;

}cout << luku << endl;

}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 545: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 537Pino<string> merkkijonopino;string rivi;

while ( getline(cin, rivi) ) {if ( !merkkijonopino.push(rivi) ) {

cerr << "push epäonnistui!" << endl;return EXIT_FAILURE;

}}

while ( !merkkijonopino.empty( ) ) {if ( !merkkijonopino.pop(rivi) ) {

cerr << "pop epäonnistui!" << endl;return EXIT_FAILURE;

}cout << rivi << endl;

}

}

▼ Alkuperäisestä esimerkistä sivulla 472 muuttuneet jalisätyt kohdat sävytettyinä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 546: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 538▼ Geneerisen pinon toteutus (genpino.hh):

template <typename TYYPPI> class Pino {public:Pino( );bool empty( ) const;bool push(TYYPPI arvo);bool pop(TYYPPI& arvo);~Pino( );

private:struct Alkio {

TYYPPI data;Alkio* seuraava;

};Alkio* paallimmainen;

};

template <typename TYYPPI>Pino<TYYPPI>::Pino( ): paallimmainen(nullptr) {}

template <typename TYYPPI>bool Pino<TYYPPI>::empty( ) const {

return paallimmainen == nullptr;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 547: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 539template <typename TYYPPI>bool Pino<TYYPPI>::push(TYYPPI arvo) {

Alkio* uusi;

try {uusi = new Alkio;

} catch (... ) {return false;

}

uusi–>data = arvo;

uusi–>seuraava = paallimmainen;paallimmainen = uusi;

return true;}

template <typename TYYPPI>bool Pino<TYYPPI>::pop(TYYPPI& arvo) {

if (paallimmainen == nullptr) {return false;

}

arvo = paallimmainen–>data;

Alkio* poistettava = paallimmainen;paallimmainen = paallimmainen–>seuraava;delete poistettava;

return true;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 548: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 540template <typename TYYPPI>Pino<TYYPPI>::~Pino( ) {

Alkio* tamanhetkinen = paallimmainen;Alkio* loput = nullptr;

while (tamanhetkinen != nullptr) {loput = tamanhetkinen–>seuraava;delete tamanhetkinen;tamanhetkinen = loput;

}

paallimmainen = nullptr;}

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 549: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 541

Geneerisyys C++:ssa

▼ C++:n tarjoama työkalu geneerisyyden toteuttami-seen ovat mallit (template).

▼ Mallit mahdollistavat »tyyppiparametroitujen»tietorakenteiden ja funktioiden määrittelyn kahdenuuden varatun sanan template ja typename avulla.

▼ Yksinkertaisimmillaan geneerisen mallin rakenta-minen (luokalle) tapahtuu seuraavasti:

template <typename muodollinen_tyyppi>class luokan_nimi {

luokan_rakenteen_määrittely

} ;

▼ Jossa luokan rakenteen määrittely on aivan normaali,paitsi että ne tietotyypit joita ei haluta kiinnittää,korvataan muodollisella tyypillä (siis määrittelyngeneeriset kohdat).

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 550: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 542▼ Vastaavasti geneeristen jäsenfunktioiden määrittely:

template <typename muodollinen_tyyppi>paluuarvon_tyyppi luokan_nimi<muodollinen_tyyppi>

:: funktion_nimi(muodolliset_parametrit) {funktion_runko

}

▼ Jossa paluuarvon tyypissä, muodollisissa parametreissa

ja funktion rungossa voi tarvittavissa kohdissa esiintyämuodollinen tyyppi.

▼ Saatu geneerinen tietotyyppi toimii koodissa aivannormaalisti sillä lisäyksellä, että käytön yhteydessäannetaan kulmasuluissa (<>) tieto siitä, mitätietotyyppiä käytetään muodollisen tyypin paikalla.

▼ EsimerkiksiPino<int> kokonaislukupino;Lista<Opiskelija> opiskelijarekisteri;int EtsiPuhNro(Hakupuu<Henkilo> luettelo, string nimi);Pino<string> LueTiedostonRivitPinoon(string tiedosto) ;

▼ Jotka kaikki ovat periaatteessa oikein, mutta kahdenviimeisen kohdalla (ja aina dynaamisen rakenteen

ollessa funktion paluuarvo tai arvoparametri)kannattaa miettiä tarkasti.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 551: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 543▼ Standardi-C++:ssa on mekanismi, joka mahdollistaa

geneeristen esittelyiden ja määrittelyiden sijoitta-misen normaaliin tapaan .hh- ja .cc-tiedostoihin.

▼ Nykyisistä✶ kääntäjistä kuitenkin harva tukee tuotamekanismia, joten geneerisiä rakenteita koodat-taessa myös funktioiden määrittelyt joudutaan

poikkeuksellisesti sijoittamaan .hh-tiedostoon.

▼ Mallilla voi olla myös useampia tyyppiparametreja:template <typename AVAIN, typename TIETO>class Hakupuu {

public:· · ·TIETO EtsiAvaimella(AVAIN haettava) const;· · ·

private:struct Solmu {

AVAIN hakuavain;TIETO data;Solmu* vasen;Solmu* oikea;

} ;

· · ·} ;

✶ Syksy 2008

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 552: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 544▼ Käyttö melko johdonmukaisesti:

Hakupuu<string, Henkilo> henkilorekisteri;

▼ On mahdollista kirjoittaa myös geneerisiä funktioita(eli algoritmeja), joista yksinkertaisena esimerkkinä:

template <typename TYYPPI>TYYPPI max(TYYPPI arvo1, TYYPPI arvo2) {

if (arvo1 > arvo2) {return arvo1;

} else {return arvo2;

}}

▼ Geneeristen tietorakenteiden ja funktioiden toimintaperustuu siihen, että kääntäjä pitää kirjaa kaikistageneerisistä määrittelyistä (malleista) ja luo niistätarvittavat erityistapaukset automaatisesti.

▼ Koko template-mekanismi on pohjimmiltaan vainälykäs korvausmenetelmä, jossa kääntäjä tarvittaessakopioi ja kääntää mallin lähdekoodin ilman, ettäohjelmoijan tarvitsee tehdä käsityötä.

▼ ▼ ▼ ▼ ▼ ▼ ▼

Page 553: kalvot - TUNI...OHJ-1100 Ohjelmointi I 1 Mitä on ohjelmointi? Ohjelmointi tarkoittaa yleisellä tasolla sitä, kun jokin systeemi, laite, ihminen tms. saadaan suorittamaan jonkun

● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●

OHJ-1150 Ohjelmointi II 545▼ Geneerisyyden pointti on tietysti se, että jos on

kerran huolella koodattu ja testattu tietorakennetai algoritmi, niin sitä on helppo käyttää aina vainuudelleen eri tyyppisellä informaatiolla:

1. vältetään turha rutiininomainen käsityö ja

2. siinä helposti syntyvät huolimattomuusvirheet.

▼ Geneerinen ohjelmointi on sangen monimutkaista,vaikka sitä ei tutkituista simppeleistä esimerkeistävälttämättä huomaakaan ➠ älä harrasta sitä ennen

kuin olet perehtynyt aiheeseen syvällisemmin

kuin tällä kurssilla on mahdollista.

▼ Huomaa, että template-mekanismi ei mahdollista»sekarakenteita», siis esimerkiksi sellaista pinoa, johonvoisi tallentaa useamman tyyppistä informaatiota.

▼ Geneerinen ohjelmointi ei varsinaisesti kuulu tämänkurssin aihepiiriin.

▼ ▼ ▼ ▼ ▼ ▼ ▼