Osoitin (ohjelmointi)

Wikipedia
Loikkaa: valikkoon, hakuun

Tietojenkäsittelytieteessä osoitin (engl. pointer) on tietotyyppi, joka viittaa keskusmuistissa sijaitsevaan arvoon. Osoitin-tyyppistä muuttujaa voidaan kutsua osoitinmuuttujaksi tai pelkästään osoittimeksi. Osoitinmuuttuja sisältää viitattavan arvon muistiosoitteen. Toisin kuin viitettä, osoitinta voi kasvattaa, sitä voi verrata toiseen osoittimeen ja siihen voi sijoittaa tunnetun muistiosoitteen lukuarvona. Osoittimia käytetään paljon erityisesti C- ja C++-ohjelmointikielillä kirjoitetuissa ohjelmissa.

Keskusmuistia voi ajatella suurena taulukkona, jonka ensimmäisen tavun indeksi on 0, toisen 1 ja niin edelleen. Osoittimet ovat vain indeksejä keskusmuistiin.

Käyttö[muokkaa | muokkaa wikitekstiä]

Osoitteen sijoitus[muokkaa | muokkaa wikitekstiä]

C:ssä ja C++:ssa osoittimeen voidaan sijoittaa muistiosoite seuraavasti:

int luku;
int *osoitin;
osoitin = &luku;

&-merkki luetaan ”address of” eli yllä ”osoitin saa arvokseen muuttujan luku osoitteen”.

Arvon noutaminen[muokkaa | muokkaa wikitekstiä]

Osoitteesta voidaan noutaa arvo (engl. dereference):

int toinen_luku;
toinen_luku = *osoitin;

Yllä oleva luetaan ”toinen_luku saa arvokseen osoittimen osoittaman kokonaislukuarvon”.

Aritmetiikka[muokkaa | muokkaa wikitekstiä]

Useimmissa ohjelmointikielissä osoittimet eivät osoita vain tavuihin, vaan esimerkiksi useita tavuja pitkiin kokonaislukuihin. Osoittimen kasvattaminen yhdellä kasvattaa sitä kokonaisluvun pituuden verran. Tämä yksinkertaistaa taulukoiden läpikäyntiä:

// alustaa taulukon T alkiot luvulla 1
int T[10];
int* p = T;  // T on osoitin, joka osoittaa "taulukon" T alkuun, eli osoitteeseen &T[0]
while (p < T+10) {  // osoittimia voi vertailla kuin lukuja; tarkoittaa samaa kuin p < &T[10]
    *p = 1;
    ++p;  // kasvatetaan osoitinta yhdellä
          // -> osoite kasvaa kokonaisluvun pituuden verran
          //    eli seuraavaan taulukon lukuun
}

Null-osoitin[muokkaa | muokkaa wikitekstiä]

Osoittimelle voidaan antaa arvoksi null, tyhjä. Se on erikoisarvo, joka tarkoittaa että osoitin ei osoita minnekään. Null-arvoa käytetään aliohjelman parametrina ja palautusarvona välittämään jokin erikoismerkitys (”aliohjelma käyttäköön oletusarvoa”, ”muisti loppui”) ja päättämään linkitettyjä tietorakenteita kuten linkitetyn listan.

Sisäisesti null-arvo on usein luku 0, sillä se on käytännössä aina käyttökelvotonta muistia, joka on varattu järjestelmälle tai ohjelmakoodille. Esimerkiksi C++:ssa kielen kehittäjä Bjarne Stroustrup suosittelee pelkän nollan käyttämistä NULL-makron sijaan:

int *p;
p = 0;

Funktio-osoitin[muokkaa | muokkaa wikitekstiä]

Osoitin voi osoittaa myös ohjelmakoodiin. Piirrettä käytetään funktio-osoittimien muodossa:

void draw_directx() {
    // koodia
}
void draw_opengl() {
    // koodia
}

// funktio-osoitin draw saa arvokseen funktion draw_opengl osoitteen
void (*draw)() = draw_opengl;

Funktio-osoittimia käytetään sisäisesti C++:ssa olio-ohjelmointiin liittyvien ominaisuuksien toteuttamiseen.

Suorituskyky[muokkaa | muokkaa wikitekstiä]

Tietokone käsittelee osoittimia kuin kokonaislukuja eikä niihin liity minkäänlaisia tarkistuksia, joten ne ovat hyvin nopeita. Joskus taulukko voidaan periaatteessa käydä läpi nopeammin osoittimilla kuin for-lauseella indeksoimalla, mutta todellisuudessa ero on mitätön, ja kääntäjä kuitenkin optimoi molemmat keinot tehokkaimmaksi mahdolliseksi.

Osoitin vie muistia vain yhden sanan verran: 32-bittisissä koneissa 32 bittiä, 64-bittisissä 64 bittiä. Usein onkin nopempaa antaa aliohjelmalle parametrina vain osoitin tietueeseen kuin monta erillistä parametria, sillä tällöin aliohjelmaa varten riittää työntää ajonaikaiseen pinoon vain yksi muistiosoite.

Turvallisuus[muokkaa | muokkaa wikitekstiä]

Osoittimien huolimaton käyttö saattaa aiheuttaa muistivuotoja ja vaikeasti jäljitettäviä ohjelmointivirheitä, sekä antaa krakkerille mahdollisuuden hyökätä ohjelman käyttäjän koneelle. Niinpä useimmissa sovellus- tai Web-ohjelmointiin suunnatuissa kielissä, kuten Javassa, PHP:ssa, Pythonissa tai Rubyssä, ei ole osoittimia, ja C#-kielessä niitä ei juuri käytetä.

Tuki ohjelmointikielissä[muokkaa | muokkaa wikitekstiä]

Seuraavat ohjelmointikielet tukevat osoittimia:

Katso myös[muokkaa | muokkaa wikitekstiä]

Aiheesta muualla[muokkaa | muokkaa wikitekstiä]

Lähteet[muokkaa | muokkaa wikitekstiä]

  • Bjarne Stroustrup: C++-ohjelmointi. 2. painos. Alkup. The C++ Programming Language – 3rd. ed. Teknolit/Addison-Wesley, 1997. ISBN 0-201-88954-4.