Osoitin ja viittaus C++:ssa



Samankaltaiset tiedostot
Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

Tietueet. Tietueiden määrittely

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

5.6. C-kielen perusteet, osa 6/8, Taulukko , pva, kuvat jma

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

Taulukot. Jukka Harju, Jukka Juslin

12 Mallit (Templates)

Virtuaalifunktiot ja polymorfismi

Osoittimet. Mikä on osoitin?

C++11 lambdat: [](){} Matti Rintala

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

4. Luokan testaus ja käyttö olion kautta 4.1

Luokat. Luokat ja olio-ohjelmointi

Osa III. Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat:

Table of Contents. T Olio-ohjelmointi C/C++ perusteita Jukka Jauhiainen OAMK Tekniikan yksikkö 2010, 2011

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Operaattoreiden uudelleenmäärittely

Lyhyt kertaus osoittimista

Olio-ohjelmointi Syntaksikokoelma

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Osa III. Olioiden luominen vapaalle muistialueelle

Ohjelmoinnin perusteet Y Python

Jakso 4 Aliohjelmien toteutus

Muuttujien roolit Kiintoarvo cin >> r;

Java-kielen perusteet

Rakenteiset tietotyypit Moniulotteiset taulukot

7. Oliot ja viitteet 7.1

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Java-kielen perusteet

Ohjelmoinnin peruskurssi Y1

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

13 Operaattoreiden ylimäärittelyjä

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

1. Esittelyt ja vakiot 1.1 Esittelyt (declarations) Ennen nimen, tunnuksen (identifier) käyttöä se on

Luento 4 Aliohjelmien toteutus

Ohjelmointi funktioiden avulla

Rajapinta (interface)

Kääntäjän virheilmoituksia

Metodien tekeminen Javalla

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Osoittimet ja taulukot

Geneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö.

Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia?

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

\+jokin merkki tarkoittaa erikoismerkkiä; \n = uusi rivi.

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Ohjelman virheet ja poikkeusten käsittely

Ohjelmointi 1 Taulukot ja merkkijonot

ITKP102 Ohjelmointi 1 (6 op)

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

Ohjelmoinnin perusteet Y Python

T Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

Olio-ohjelmointi Javalla

Sisältö. 2. Taulukot. Yleistä. Yleistä

Osoittimet ja taulukot

ITKP102 Ohjelmointi 1 (6 op)

2. Olio-ohjelmoinista lyhyesti 2.1

Listarakenne (ArrayList-luokka)

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne.

Zeon PDF Driver Trial

Jakso 4 Aliohjelmien toteutus

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

C-ohjelmointi: Osoittimet

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Tietorakenteet ja algoritmit

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin

Mallit standardi mallikirjasto parametroitu tyyppi

15. Ohjelmoinnin tekniikkaa 15.1

ITKP102 Ohjelmointi 1 (6 op)

UNIVERSITY OF OULU DEPARTMENT OF INFORMATION PROCESSING SCIENCE

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Tietotyypit ja operaattorit

Dynaaminen muisti Rakenteiset tietotyypit

1. Olio-ohjelmointi 1.1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

Sisältö. 22. Taulukot. Yleistä. Yleistä

14. oppitunti. Operaattorin ylikuormitus. Osa. Operaattorin ylikuormittaminen

Omat tietotyypit. Mikä on olio?

Sisällys. 19. Olio-ohjelmointia Javalla. Yleistä. Olioiden esittely ja alustus

Luento 4 (verkkoluento 4) Aliohjelmien toteutus

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

Taulukot. Taulukon käsittely. Tämän osan sisältö. Esimerkki. Taulukon esittely ja luonti. Taulukon alustaminen. Taulukon koko

Javan perusteita. Janne Käki

Luento 4 (verkkoluento 4) Aliohjelmien toteutus

Ohjelmoinnin perusteet Y Python

Algoritmit 2. Luento 7 Ti Timo Männikkö

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Ohjelmoinnin perusteet Y Python

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

Transkriptio:

Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja i ja osoitin kokonaislukuun *p. Ohjelmassa pyritään kasvattamaan muuttujan arvoa yhdellä eri tavoilla. int i=1; //Kokonaislukumuuttuja int *p; //Osoitin kokonaislukuun p=&i; //Sijoitetaan i:n osoite p:n arvoksi //Kasvatetaan muuttujan i arvoa yhdellä. //Oikeita tapoja: //Tapa 1: i++; //Tapa 2: Kasvatetaan p:n osoittaman muistipaikan arvoa (*p)++; //Väärä tapa. Miksi? *p++; //Myös tämä on väärin. Miksi? *(p++);

return 0; Ohjelman tulostus näyttää seuraavalta: Mieti, mitä kahdessa viimeisessä tapauksessa oikeastaan tapahtuu. Tässä nähdään osoittimiin liittyvä suurin vaara. Varsinkin aloittelevan ohjelmoijan on hyvin helppo siirtää osoitin osoittamaan väärään muistipaikkaan. Tässä tapauksessa kaksi viimemainittua lausetta siirtävät ensin osoitinta seuraavaan muistipaikkaan ja sitten tulostavat uuden muistipaikan sisällön. Osoitin taulukkoon Seuraava erimerkki liittyy taulukon alkioiden osoittamiseen: #include <iostream> int luvut[]=100,200,300,400,500; //Kokonaislukutaulukko int *p; //Osoitin kokonaislukuun int i=0; p=luvut; //Mihin p osoittaa? cout << *p << endl; //Tulostetaan sen sisältö return 0;

Esimerkissä on määritelty kokonaislukutaulukko luvut[] ja alustettu sen arvot. Taulukon koko on 5. Lisäksi on määritelty osoitinmuuttuja *p. Ensimmäinen tulostus kertoo, mihin p osoittaa sijoituksen p=luvut jälkeen. Sijoituslause p=luvut; Asettaa osoittimen osoittamaan taulukon 1. alkioon. Saman asian voi tehdä myös lauseella p=&luvut[0]; Miksi näin? C/C++:ssa taulukon nimi on OSOITIN TAULUKON ENSIMMÄISEEN ALKIOON. Taulukon alkiot voidaan tulostaa osoittimen avulla siirtämällä osoitinta taulukon alkioista toiseen lauseella p++; Esimerkiksi toteutus while-silmukalla: while (i<5) cout << *p << endl; p++; //Siirtää osoittimen seuraavaan taulukon alkioon i++; //Kasvattaa silmukkalaskurin arvoa yhdellä Osoittimet funktion parametreina Funktiolle voidaan välittää tietoa kahdella mekanismilla:

Arvoparametrina: Parametreina annettavien muuttujien arvot kopioidaan toisiin muistipaikkoihin. Funktio käsittelee alkuperäisten muuttujien kopioita, ei itse alkuperäisiä muuttujia. Tästä seuraa, että funktio ei pysty muuttamaan alkuperäisiä (parametreina välitettäviä) arvoja. Muuttujaparametrina: Parametreina annetaan muuttujien keskusmuistiosoitteet. Funktio käsittelee siten alkuperäisiä muuttujia suoraan muistissa. Funktio pystyy muuttamaan muuttujien arvoja. #include <iostream> void f1(int); //Arvoparametri void f1(int *); //Muuttujaparametri int a=1; f1(a); f1(&a); return 0; void f1(int a) void f1(int *a) (*a)++; Esimerkkiohjelmasta kannattaa huomata muutama juttu. Samasta funktiosta on tässä kaksi erilaista versiota. Toinen ottaa parametrinaan kokonaisluvun ja toinen osoittimen. Tätä kutsutaan funktion ylikuormaamiseksi (function overloading). Funktioiden tulee erota toisistaan parametrien tyypin tai lukumåärän perusteella. Paluuarvon tyyppien ero ei riitä.

Ensimmäinen funktiokutsu arvoparametrilla tekee muuttujasta a kopion, joka lähetetään funktiolle. Funktiossa käsitellään samannimistä muuttujaa a, mutta se on kopio, ei alkuperäinen. Muuttujan arvon kasvattaminen muuttaa kopion, ei alkuperäisen arvoa. Jälkimmäisessä funktiokutsussa välitetään alkuperäisen muuttujan a osoite. Nyt funktio kasvattaa alkuperäisen muuttujan arvoa. Viittaukset C++:ssa on osoittimien lisäksi toinenkin tapa suoraan muistiosoitukseen. Viittaus (reference) on tunnuksen vaihtoehtoinen nimi. Viittausmuuttuja on alustettava määrittelyn yhteydessä ja se viittaa aina samaan alustuksen yhteydessä määriteltyyn muuttujaan. Sitä ei voi vaihtaa osoittamaan johonkin toiseen muuttujaan. Viittausta käytetään hyvin paljon C++:n metodien yhteydessä. #include <iostream> void f1(int); void f1(int *); void f2(int &); int a=1; f1(a); f1(&a); f2(a); return 0;

void f1(int a) void f1(int *a) (*a)++; void f2(int &a) Tässä edelliseen esimerkkiin on lisätty viittausmuuttujaa käyttävä funktio f2. Olisiko ollut mahdollista tehdä kolmas ylikuormattu versio funktiosta f1? Ei, koska funktiota, jonka parametrina on tavallinen muuttuja ja viittausmuuttuja kutsutaan samalla tavalla eli niitä ei voi erottaa toisistaa parametrien tyypin perusteella. Viittauksen ongelma on, että funktiokutsun perusteella ei voi tietää, käytetäänkö viittausta vai tavallista muuttujaa. Funktio voikin yllättäen muuttaa muuttujan arvoa käyttäjän tietämättä. Jos halutaan varmistaa, että näin ei vahingossa käy, voidaan viittausparametri määritellä vakioksi: void f3(const int &a) Edellinen määritys johtaa kääntäjän virheilmoituksen. Koska funktiossa yritetään muuttaa vakioksi määriteltyä arvoa. Jatkossa luokkien yhteydessä sekä tavallisia että vakioviittauksia käytetään jatkuvasti. Miksi niitä käytetään eikä tavallisia muuttujia? Syy on se, että viittausta käytettäessä ei tietoja kopioida kuten tavallista muuttujaa käytettäessä. Lienee selvää, että tietojen jatkuva kopiointi muistissa on paljon hitaampaa kuin yhden viittauksen tekeminen tietoon. Varsinkin jos ohjelmassa käsitellään suuria tietomääriä tai luodaan ja tuhotaan olioita dynaamisesti ohjelman ajon aikana. Siksi on hyvä opetella oikeaoppinen viittauksen käyttö heti olio-ohjelmoinnin aluksi.