1 / 123

Olio-ohjelmoinnin perusteet luento 2: Muuttujista ja funktioista

Olio-ohjelmoinnin perusteet luento 2: Muuttujista ja funktioista. Jani Rönkkönen LTY/Tietotekniikan osasto Kalvot on muokattu Sami Jantusen luentokalvoista viime vuodelta. VAROITUS!!!!!!. Tällä luennolla käsitellään perusasioita, joilla ei ole sinänsä paljon tekemistä oliopohjaisuuden kanssa!

Download Presentation

Olio-ohjelmoinnin perusteet luento 2: Muuttujista ja funktioista

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Olio-ohjelmoinnin perusteetluento 2: Muuttujista ja funktioista Jani Rönkkönen LTY/Tietotekniikan osasto Kalvot on muokattu Sami Jantusen luentokalvoista viime vuodelta.

  2. VAROITUS!!!!!! • Tällä luennolla käsitellään perusasioita, joilla ei ole sinänsä paljon tekemistä oliopohjaisuuden kanssa! • Esimerkit ovat esitetty ei-oliopohjaisella tavalla! • Tarkoitus on vain havainnoillistaa perusasioita • Toivottavasti osaat soveltaa näitä jatkossa, kun puhumme lisää luokista!

  3. Sisältö • Muuttujat • Muuttujien määrittely ja tietotyypit • Osoittimet (pointer variables) • Viittaukset (reference variables) • Funktiot • määrittely ja tiedon välitys • muuttujien näkyvyysalueet • oletusparametrit (default parameters) • uudelleenmäärittely (overloading) • avoimet funktiot (inline) • rekursio

  4. Muuttujista… • Tietokoneohjelmat manipuloivat tietoa • Meillä on siis tarve tallettaa tietoa • Muuttujat: • Kuvaavat tiettyä muistin muistipaikkaa • Sisältävät tietyn tiedon • Kun määrittelet muuttujan: • Varaat tilaa muistista • Annat muuttujalle nimen • Teet tämän kerran kutakin muuttujaa kohden

  5. Kuinka luodaan muuttuja • Formaatti: <tietotyyppi> <muuttujan nimi>; • Muuttujan nimeksi voit valita melkein mitä vaan • Esimerkkejä: byte age; float gpa; String name; char letterGrade; • Nyt kun muuttujat on määritelty • Ei tarvitse määritellä niitä uudestaan • Voit käyttää muuttujan nimeä jatkossa tiedon lukemisessa ja kirjoittamisessa Computer's Memory age gpa ? ? name letterGrade ? ?

  6. C++ varatut sanat • Näitä sanoja et kuitenkaan voi käyttää sellaisenaan muuttujien nimissä: • auto, bool, break, case, catch, char, class, const, continue, default, do, double, else, enum, extern, float, for, friend, goto, if, inline, int, long, namespace, new, operator, private, protected, public, register, return, short, signed, sizeof, static, struct, switch, template, this, throw, try, typedef, union, unsigned, void, volatile, while

  7. Sallittuja muuttujien nimiä • Ei saa olla varattu sana • Ei saa alkaa numerolla • Ei saa sisältää symboleja kuten • Kuten #, @, !, ^, &, /, ), tai välilyönti • Poikkeukset: alaviiva _, ja dollarimerkki $ • Esimerkkejä: byte $theValue; // legal char test_value; // legal double double; // not legal int rum&coke; // not legal bool true or false; // not legal for two reasons!

  8. Muuttujien alustamisesta • Tarkoittaa alku-arvon antamista muuttujalle • Arvo annetaan = -operaattoria käyttäen • Kopioi oikealla olevan tiedon vasemmalla määriteltyyn muuttujaan. Muuttujan tyyppi ja tiedon formaatti pitää olla yhteensopiva • Alustettava tieto voi olla vakio tai toinen muuttuja! • Esimerkkejä: int age; age = 15; char letterGrade = ‘B’; char yourGrade = letterGrade;

  9. Tietotyypeistä • Tietotyyppi kertoo mikälaista tietoa muuttuja voi pitää sisällään • Jotkin tietotyypit ovat “sisäänrakennettuja” ohjelmointikieleen • Voimme myös määritellä tietotyyppejä itse (puhutaan tästä lisää myöhemmin) • Erilaisia tietotyypin muotoja: • Yksinkertaiset tietotyypit • Monimutkaiset tietotyypit (Valmistettu yksinkertaisista tietotyypeistä)

  10. Yksinkertaiset tietotyypit • Sisäänrakennettuja • Numerot: • short (melko pienet numerot) • int (suuret numerot) • long (TOSI suuret numero)

  11. Yksinkertaiset tietotyypit • Desimaaliluvut: • float (Ei niin tarkka kuin double ) • double (Aika tarkka) • Tarkkuudella tarkoitetaan kuinka monta lukua tulee desimaalin jälkeen • Muita: • char (pitää sisällään merkkejä kuten ‘a’, ‘A’, ‘1’, ‘ ‘) • bool (pitää sisällään totuusarvon true tai false)

  12. No kuinka iso se on?: sizeof( ) • sizeof( ) kertoo kuinka paljon tietotyyppi vie tavuja • Esimerkki: int myInt; cout << sizeof (myInt) << endl;

  13. Etumerkki vai ei? • C++ -kielessä voi määritellä merkki- ja kokonaislukumuuttujat etumerkittömäksi. • Etumerkillisille ja etumerkittömille kokonaisluvuille varataan yhtä paljon muistitilaa • Luvut ovat oletusarvoisesti etumerkillisiä • Etumerkittömän edut: • Etumerkittömät tietotyypit voivat siis sisältää suuremman joukon positiivisia lukuja

  14. Perustietotyypeistä • Se kuinka monta tavua kukin tietotyyppi vie tilaa on riippuvainen kääntäjästä ja käyttöjärjestelmästä! • Tässä kuitenkin esimerkkejä:

  15. Miksi koolla on väliä • Eri tietotyypit vie eri määrän tavuja muistista • Et voi laittaa suuritilaisemman muuttujan sisältöä pienenpään muistitilaan: short s = 5; long l = 5; long l = s; short s = l; long long long short short short

  16. Tyyppimuunnos (Type Casting) • Tapahtuu kun pistät jotain enemmän tilaa vievää tietoa pienempään muistipaikkaan • Tiedon tarkkuustaso saattaa heikentyä • Formaatti: <pienempi muuttuja> = (<pienempi tietotyyppi>)<isompi muuttuja>; • Esimerkki: long myLong = 17; short myShort = (short)myLong; // We are squeezing myLong into myShort!

  17. short vai long? • Jos on pienikin mahdollisuus, että muuttujaan tulee suurempi arvo kun tietotyyppiin mahtuu, niin valitse isompi tietotyyppi.

  18. Etumerkittömien kokonaislukujen ylivuoto Sama ilmiö kun auton matkamittarissa: • Kun on maksimi saavutettu, niin aloitetaan uudestaan nollasta • Esim: unsigned intmyInt =65535;cout<< myInt << endl;myInt++;cout<< myInt << endl;myInt++;cout<<myInt<<endl; Mitä tapahtuu?? Tuloste: 65535 01

  19. Etumerkillisten kokonaislukujen ylivuoto • Suurinta positiivista arvoa seuraa negatiivisin mahdollinen arvo • Esim: int myInt =32767;cout<< myInt << endl;myInt++;cout<< myInt << endl;myInt++;cout<<myInt<<endl; Mitä tapahtuu?? Tuloste:32767-32768-32767

  20. unsigned short int luku1;unsigned short int luku2;unsigned short int luku3; • Liian työlästä? • Altis kirjoitusvirheille • Ratkaisuehdotuksia: • unsigned short int luku1, luku2, luku3; • Peitenimi (Typedef)

  21. Peitenimi (Typedef) #include <iostream.h> typedef unsigned short int USHORT; void main() { USHORT Leveys = 5; USHORT Korkeus; ...

  22. Yhteenveto • Muuttujat ovat nimettyjä soluja tietokoneen muistissa • On olemassa erilaisia tietotyyppejä säilyttämään erilaista tietoa • Eri tietotyypit vievät eri määrän tilaa • Kaikki muuttujat määritellään samanlaisen formaatin mukaisesti

  23. VakioistaMiksi vakioita? -Esimerkki • Oletetaan, että koulussa yhdelle luokalle hyväksytään 15 oppilasta • Oletetaan myös, että koulun oppilasmäärä saadaan kerrottuna luokkien lukumäärä luokan koon kanssa: int luokkienLukumaara = 20; int oppilasmaara = 15 * luokkienLukumaara; • Mikä vikana?

  24. Miksi vakioita? • Emme halua kovakoodata arvoja • Työlästä muuttaa • Emme myöskään halua laittaa pysyviä arvoja muuttujiksi • Joku saattaa vahingossa muuttaa niiden arvoja

  25. #define • Hieman vanhentunut tapa määritellä vakio • Esim:#define oppilaitaLuokassa 15 • Ei ota mitään kantaa tietotyyppiin • Esikäsittelijä pelkästään korvaa tekstin toisella • Kääntäjä siis näkee oppilaitaLuokassa-tekstin sijasta luvun 15

  26. Const • Suositeltavampi tapa #define sijasta:const unsigned short int oppilaitaLuokassa = 15; • Kääntäjä tietää minkä tyyppinen vakio on.osaa valvoa, että vakiota käytetään oikein • Vakiota ei voi muuttaa ohjelman suorituksen aikana. Jos vakio halutaan muuttaa, tulee ohjelma kääntää uudestaan.

  27. Luetellut vakiot • Muuttujatyyppi, johon voi sijoittaa vain etukäteen määriteltyjä arvoja. • Luetellun vakion määrittely:enum VARI {PUNAINEN, SININEN, VIHREA, VALKOINEN, MUSTA}; • Määrittelee sanan VARI • Määrittelee vakiot PUNAINEN (arvo 0), SININEN (arvo 1),… • Kullekin vakiolle on mahdollista määritellä arvo erikseen:enum VARI {PUNAINEN=100, SININEN, VIHREA=500, VALKOINEN=501, MUSTA=700}; • Lause tuottaa vakiot PUNAINEN=100, SININEN=101, VIHREA=500, VALKOINEN=501 ja MUSTA=700 • Luetellut vakiot ovat käteviä kun käsitellään rajallista alijoukkoa (värejä, viikonpäiviä, ym…) • Ohjelmakoodin luettavuus paranee

  28. Luetellut vakiot käyttöesimerkki #include <iostream.h> void main() { enum Paivat {Sunnuntai, Maanantai, Tiistai, Keskiviikko, Torstai, Perjantai, Lauantai }; Paivat vapaaPaiva; cout << “Minkä päivän haluat pitää vapaata (0-6)? “; cin >> vapaaPaiva; if (vapaaPaiva == Sunnuntai || vapaaPaiva == Lauantai) cout << “Viikonloppu on vapaata muutenkin!” << endl; else cout << “OK. pannaan asia muistiin” << endl; }

  29. Lisäys- ja vähennysoperaattorit • ++ korottaa muuttujan arvoa yhdellä int counter = 5; int counter = 5; counter++; counter = counter +1; • += korottaa muuttujan arvoa annetulla määrällä int counter = 5; int counter = 5; counter += 3; counter =counter + 3; Sama kuin Sama kuin Huomaa: Myös --, -=, %=, /= versiot

  30. Lisäys- ja vähennysoperaattorit • Voidaan toteuttaa joko etuliitteenä (esim. ++counter;) tai jälkiliitteenä (esim. counter++;) • Lopputulos sama paitsi jos muuttujaa käytetään samassa tilanteessa vielä arvon muutoksen lisäksi johonkin muuhun

  31. Etu- ja jälkiliitelisäys esimerkki … void main() { int minunIka=40; int sinunIka=40; cout << “minun ikä on:” << minunIka++ << endl; cout << “sinun ikä on:” << ++sinunIka << endl; … } Mitä tapahtuu?? Tuloste: minun ikä on:40 Sinun ikä on:41

  32. OsoittimistaOletteko nähneet tällaista? • Ohjelmoijan painajainen! • Johtuu osoittimen väärinkäytöstä

  33. Tarkastellaan hieman muistia!Muistin osoite sinisellä, Arvot mustalla, Muuttujan nimi punaisella 1 -4717 2 -901 3 76 4 -0 5 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25 -4717 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  34. Määritetään int-muuttujaint myInt; 1 -4717 2 -901 3 76 4 -0 5 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt -4717 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  35. Mitä tuli tehtyä? • Määrittelemällä int- muuttujan varasimme juuri ja juuri tarpeeksi muistitilaa int- luvulle • Ei hajuakaan missä päin muistia muuttujamme sijaitsee • Tietokone valitsee muistiosoitteen “satunnaisesti” • Mikä arvo on varaamassamme muistipaikassa? • Voimmeko tulostaa muistipaikan arvon? • Tulostaisimme –4717! (roskaa)

  36. Kopioidaan 42 muuttujan osoittamaan muistipaikkaanmyInt = 42; 1 -4717 2 -901 3 76 4 -0 5 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25 myInt 26 -19 27 21511 42 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  37. Osoittimet (Pointers) • Antaa mahdollisuuden päästä käsiksi muistipaikkaan, missä tieto sijaitsee • Osoitin määritellään seuraavanlaisella formaatilla: <tiedon tyyppi> *<muuttujan nimi>; • Example: int *ptr;

  38. Määritetään int osoitinint *ptr; 1 -4717 2 -901 3 76 4 -0 5ptr 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  39. Mitä nyt tuli tehtyä? • Loimme uuden muuttujan joka tulee osoittamaan int tietoon • Huomaa, että osoitin ei vielä osoita myInt sisältämään tietoon • Mitä jos yritämme tulostaa osoittimen sisällön?

  40. cout << ptr;(ptr:n arvoksi tulostuu 98131) 1 -4717 2 -901 3 76 4 -0 5ptr 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  41. Ongelma • Kuinka voimme saada myInt osoitteen, jotta ptr voi osoittaa sinne? • Muista, että voimme vielä käyttää myInt:ä suoraankin int someInt = myInt; • Tarvitsisimme todella keinon tallettaa myInt-muuttujan osoite • Meidän ei tarvitse tallettaa myInt muuttujan arvoa osoittimeen (vain osoite)

  42. & operaattori • & operaattorin avulla päästään käsiksi muuttujan muistiosoitteeseen • Mitä seuraavanlainen komentorivi tulostaisi näytölle? cout << &myInt << endl;

  43. Mitä tapahtuisi?cout << &myInt; 1 -4717 2 -901 3 76 4 -0 5ptr 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  44. Laitetaan osoitin osoittamaan… • Nyt pitäisi laittaa “ptr” osoittamaan myInt -muuttujan sisältämään tietoon ptr = &myInt; ptr on osoitin, joten se olettaa että sen arvoksi annetaan osoite & -operaattorilla saamme myInt muuttujan osoitteen ja kopioimme osoitetiedon ptr-osoittimen arvoksi

  45. Ennen 1 -4717 2 -901 3 76 4 -0 5ptr 98131 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  46. Jälkeenptr = &myInt; 1 -4717 2 -901 3 76 4 -0 5ptr 25 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  47. Mitäs tämä tekisi?ptr = myInt; 1 -4717 2 -901 3 76 4 -0 5ptr 98186 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  48. Hupsista!ptr = myInt; 1 -4717 2 -901 3 76 4 -0 5ptr 42 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

  49. Osoittimen sisältö • Kuinka osoittimen sisältö saadan luettua? • Käytetään *-operaattoria • Esimerkki: cout << *ptr << endl; //Tulostaa ptr-osoittimen //osoittaman muistipaikan sisällön!

  50. Seurataan osoitinta ja tulostetaancout << *ptr << endl; 1 -4717 2 -901 3 76 4 -0 5ptr 25 6 -1038 7 -554 8 7462 9 312 11 3619 10 -6 12 -4717 13 60981 14 4148 21 -78781 15 86851 16 -5155 17 95151 18 -47 19 2251 20 0 28 -9 22 -901 23 -6 24 6720 25myInt 42 26 -19 27 21511 32 9 35 7851 29 17 31 -651 34 -896761 30 -6561 33 761 37 9996 38 674547 39 -6868 40 -1 41 5431 42 -4717 36 -6

More Related