8.4.2 Muuttujan arvon epäsuora muuttaminen
Tutkitaanpa vaikkapa seuraavaa ohjelmaa:
c-muut\kissaoso.cpp - epäsuora osoitus
// kissaoso.cpp
// Mitä ohjelma tulostaa?
#include <iostream.h>
int main(void)
{
int kissoja,koiria;
int *pElaimia; // Osoitinmuuttuja kokonaislukuun. (p = pointer)
pElaimia = &kissoja;
*pElaimia = 5;
pElaimia = &koiria;
*pElaimia = 3;
cout << "Kissoja on " << kissoja << " ja koiria " << koiria << "." << endl;
return 0;
}
Osoitinmuuttuja määritellään laittamalla *
muuttujan nimen eteen esiteltäessä muuttujaa. Sijoituksessa
osoitin = // tässä tapauksessa pElaimia =
pitää oikealla puolella olla osoite- tyyppiä oleva lauseke
(esim. &kissoja).
Vastaavasti muoto *osoitin ("tähdätään osoitinta
pitkin") tarkoittaa sen muistipaikan sisältöä, johon muuttuja
osoitin osoittaa. Olkoon meillä muisti jakaantunut
käännöksen jälkeen seuraavasti:
Kuva 8.2 Epäsuora osoitus
Osoitinmuuttujia tarvitaan erityisesti aliohjelmien ja taulukoiden
yhteydessä. Tämä esimerkki on itse asiassa varsin huono!
Nimenomaan tällaista moninimisyyttä (aliasing), eli sama
muuttuja voi muuttua useata eri kautta, tulisi välttää, koska se
on omiaan tekemään ohjelmista epäluotettavia ja vaikeasti
ylläpidettäviä. Järkevämmän osoite- esimerkin
otamme heti kun saamme aliohjelmat kunnolla käyttöön.
- Jos edellä voitaisiin sijoittaa
- pElaimia = 100;
- niin mitä tapahtuisi sijoituksella
- *pElaimia = 10;
- Entäpä jos olisi sijoitukset
- pElaimia = 106;
- *pElaimia = 104;
- *pElaimia = 108;
Varoitus! Edellisestä tehtävästä
huolimatta ÄLÄ KOSKAAN mene itse keksimään arvoja, joita
sijoitat osoitinmuuttujalle. Tämä on 99.999% varma tapa saada kone
kaatumaan. Käytännössä osoittimien arvot (osoitteet) ovat
edellä kuvattua esimerkkiä monimutkaisempia.