Muuttujien näkyvyys

Muuttujien näkyvyydellä (engl. scope) tarkoitetaan sitä, missä tilanteessa muuttuja on näkyvissä (tai käytettävissä). Jos muuttuja on näkyvissä, niin koodissa kyseisessä kohdassa voi käyttää muuttujaa. Vastaavasti, jos muuttuja ei ole näkyvissä tietyssä kohdassa, ei muuttujan sisältämään arvoon ole mahdollista päästä käsiksi. Konkreettisia esimerkkejä on esitetty alla.

Pääasiassa muuttuja on näkyvissä siinä lohkossa, jossa se on esitelty. Lohkolla tarkoitetaan aaltosulkeiden rajaamaa aluetta koodissa. Perusperiaatteena voi pitää sitä, että muuttuja on näkyvissä niin kauan kuin lohkosta ei olla poistuttu. Alla olevat säännöt seuraavat tästä periaatteessa.

# Plugin1

1. Pääohjelman muuttujat

Pääohjelmassa (tai missä tahansa muussakin aliohjelmassa) esitellyt muuttujat näkyvät vain oman esittelynsä lohkon (alkaa aaltosululla { ja päättyy aaltosululla }) sisällä esittelynsä jälkeen:

public static void Main(String[] args)
{
    int luku = 9;  
    double d = 5.5;
    int[] luvut = { 1, 2, 3 }; 
    Muuta(luvut, 2, luku);
 ...
}

Edellä luku ja d ovat nähtävissä ja muutettavissa vain pääohjelmassa (paitsi jos viedään C#:issa out-parametrina). Muuttuja luvut on periaatteessa käytettävissä (ja muutettavissa) vain pääohjelmassa.

Kuitenkin, koska taulukkokin on olio C#:issa, se viedään aliohjelmalle (kuten tässä Muuta-aliohjelmalle) viitteenä. Viitteen kautta aliohjelma voi muuttaa pääohjelman taulukon sisältöä, koska Muuta-aliohjelman parametrimuuttuja ''viittaa'' samaan taulukko-olioon, kuin pääohjelman muuttuja.

Kaikki edellä esitellyt kolme muuttujaa elävät pääohjelman loppusulkuun } saakka. Muuttujan luku sisältämä arvo kopioidaan aliohjelman vastinmuuttujaan. Aliohjelma ei näe pääohjelman muuttujaa, vaan aliohjelma saa tiedokseen vain sille välitetyn arvon.

args-taulukko on pääohjelman parametrimuuttuja (ks. alla), joka viittaa pääohjelman kutsussa käytettyihin merkkijonoihin.

2. Aliohjelman muuttujat

Aliohjelmalle tärkeimmät muuttujat tulevat parametrin välityksen kautta. Toki aliohjelmaan tarvitaan usein omia apumuuttujia ongelman selvittämiseksi.

2.1 Parametrimuuttujat

Aliohjelmakutsussa aliohjelman parametrimuuttujiin kopioidaan kutsussa olevien lausekkeiden arvot siinä järjestyksessä kuin ne kutsussa ovat. Pitää muistaa että esimerkiksi taulukkokin on arvo, eli sen taulukon viitearvo, jossa välitettävä taulukko "asuu".

public static void Muuta(int[] luvut, int paikka, int luku)
{
    luvut[paikka] = luku; // viitteen ansiosta pääohjelman taulukko muuttui
    paikka--;             // ei vaikuta pääohjelmaan
    int uusiarvo;         // aliohjelman lokaali muuttuja
    uusiarvo = luku +3;
    luvut[paikka] = uusiarvo; // muuttaa pääohjelman taulukkoa
    luku = 12;            // ei vaikuta pääohjelmaan 
}

Esimerkissä parametrimuuttujan (taulukkoviitteen) nimi on sama luvut kuin pääohjelmassakin, mutta nimi voisi olla mikä tahansa muukin. Oleellista on, että kutsussa aliohjelman vastaavassa paikassa olevaan viitemuuttujaan sijoitetaan sama viite kuin kutsuvassakin ohjelmassa.

paikka on myös parametrimuuttuja, samoin kuin luku. Vaikka muuttujaan luku sijoitettaisiin jotakin, se ei vaikuta kutsuvaan ohjelmaan, koska luku on oma muuttuja aliohjelmassa ja on olemassa vain siihen saakka kun kunnes tullaan aliohjelman loppusulkuun }.

Parametrimuuttujien muuttamista ei yleisesti pidetä hyvänä tyylinä. Jos parametrimuuttujia pitää muuttaa, parempi on tehdä niistä paikallinen kopio ja muuttaa sitä, näin aliohjelman lopussa parametreilla on samat arvon kuin aliohjelmaan tultaessakin.

2.2 Paikalliset muuttujat

Aliohjelma voi tarvita myös paikallisia apumuuttujia "ongelman" ratkaisemiseen:

paikka--;             // ei vaikuta pääohjelmaan
int uusiarvo;         // aliohjelman lokaali muuttuja
uusiarvo = luku + 3;
luvut[paikka] = uusiarvo; // muuttaa pääohjelman taulukkoa

Tässä apumuuttuja uusiarvo on näkyvissä aliohjelmassa esittelyrivinsä jälkeen, mutta lakkaa olemasta kun tullaan aliohjelman loppusulkuun }. Tähän muuttujaan tehdyt muutokset eivät millään tavalla vaikuta mihinkään muuhun paikkaan kuin tähän muuttujaan, siitäkään huolimatta että jossain toisaalla sattuisi olemaan samanniminen muuttuja. Pääohjelma tai mikään muu ohjelman osa ei pääse käsiksi tähän muuttujaan, muuten kuin epäsuorasti, kuten tässä tapauksessa kun tuo arvo riippuu parametrina tuodun luku-muuttujan arvosta.

3. Omassa lohkossa esitellyt muuttujat

Lohkon (esimerkiksi aliohjelmaa rajaavien sulkeiden) sisälle voidaan määritellä uusi lohko. Tämän uusi lohko muodostaa oman näkyvyysalueensa, jonka sisällä määriteltyihin muuttujiin pääsee käsiksi vain lohkon sisältä. Esimerkiksi malliohjelman pääohjelmassa voitaisiin määritellä uusi lohko seuraavasti.

    Muuta(luvut, 2, luku); // huom. aliohjelmakutsu, ei esittelyrivi!
    {                          // apulohko, jossa omia muuttujia
        int uusi = 3;          // muuttuja joka näkyy vain tässä lohkossa
        Console.WriteLine(uusi);
    }                          // nyt uusi-muuttuja lakkaa olemasta
    // Nyt muuttujaa uusi ei ole olemassakaan

Nyt muuttuja uusi on olemassa vain sulkujen { ja } välisen ajan ja sulkujen ulkopuolelta niihin ei pääse käsiksi.
Tehty lohko ei mitenkään liity aliohjelman Muuta kutsuun, vaikka visuaalisesti voisi siltä näyttääkin. Useimmiten tätä erillisen lohkon ominaisuutta käytetään ehtolauseiden tai silmukoiden sisällä olevissa lohkoissa.

4. Silmukan muuttujat

Silmukoissa on yleensä silmukkamuuttuja, jonka täytyy muuttua silmukan aikana, jotta silmukka ei ole ikuinen. Lisäksi ongelman selvittämiseksi silmukassa voi olla tarvittavia apumuuttujia.

int luku = 9;
...
// Täytetään taulukkoa
int edellinen = 0;
for (int i = 0; i < luvut.Length; i++) // i näkyy vain silmukan sisällä
{
    int nyt = luvut[i];     // on olemassa silmukan sisällä
    int iso = 3 * nyt;      // on olemassa silmukan sisällä
    luvut[i] += iso; 
    edellinen = nyt + luku; // silmukan ulkopuolella määritelty muuttuja
}

4.1 Silmukkamuuttujat

Edellisessä esimerkissä muuttuja i on olemassa ja käytettävissä koko silmukan ajan, mutta ei enää silmukan loppusulun } jälkeen.

4.2 Silmukan ulkopuolella esitellyt muuttujat

luku ja edellinen ovat olemassa ennen silmukkaa, sen aikana ja sen jälkeen mikäli i:n arvoa tarvittaisiin silmukan jälkeenkin, pitäisi se esitellä silmukan ulkopuolella:

int i;
for (i = 0; i < luvut.Length; i++)
{
   ...
}
/// Nyt i on täällä vielä olemassa ja sen arvo voidaan esim katsoa

Tämän ulkopuolella esitellylle silmukkamuuttujan hinta on se, että ei voida enää käyttää samaa nimeä samassa lohkossa olevalle toiselle silmukkamuuttujalle. Jos silmukkamuuttujat esitellään for-lauseen sisällä, voidaan samaa nimeä käyttää seuraavassakin for-silmukassa.

for-silmukan ulkopuolella esiteltyä silmukkamuuttujaa tarvitaan useimmiten silloin, kun silmukan suoritus katkaistaan break-lauseella ja silmukan jälkeen pitäisi tietää, mihin indeksiin saakka silmukkaa suoritettiin.

4.3 Silmukan sisällä esitellyt muuttujat

Lohkon sisällä määritellyt muuttujat nyt ja iso ovat olemassa vain lohkonsa sisällä ja niiden mahdollinen arvo häviää jokaisen silmukan kierroksen päätteeksi. Lopputulos on aivan vastaava, vaikka muuttujat esiteltäisiin silmukkalohkon ulkopuolella:

int luku = 9;
...
// Täytetään taulukkoa
int edellinen = 0;
int nyt;
int iso;
for (int i = 0; i < luvut.Length; i++)
{
    nyt = luvut[i];   
    iso = 3 * nyt;    
    luvut[i] += iso; 
    edellinen = nyt + luku; 
}

Haittana ulkopuolella esittelylle on se, että nyt samoja nimiä ei voi käyttää toisessa lohkossa.

5. Attribuutit

Olioiden sisällä voi olla omia muuttujia, joita nimitetään attribuuteiksi. Kirjallisuudessa käytetään myös nimeä "kenttä" (engl. "field"). Attribuutit kannattaa lähes poikkeuksetta esitellä private-määreellä, jolloin kukaan ulkopuolinen ei pääse niihin käsiksi. Attribuutit ovat olemassa koko olion elinkaaren ajan, ja jokainen olion (luokkaan kirjoitettu) metodi (siis ei-static aliohjelma) pääsee niihin käsiksi. Attribuuttien runsas käyttö on kuitenkin sekin vaarallista luokan koon kasvaessa. Attribuutteja pitääkin osata käyttää varoen ja taitavasti, ja mielellään vain harvoissa erityistilanteissa.

Metodien (olion omien aliohjelmien) sisällä esitellyt muuttujat ja metodien parametrimuuttujat käyttäytyvät kuten aikaisemmissa kohdissa on kuvattu.

6. Globaalit muuttujat

Muuttuja voidaan esitellä myös kaikkien aliohjelmien ulkopuolelle ja tällöin muuttuja on globaali. Tällaista esittelyä tulee KAIKIN KEINOIN VÄLTTÄÄ. Tuloksena on vain iso tukku ONGELMIA. Kaikkein hankalimmin paikannettavat virheet liittyvät globaaleihin muuttujiin.

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.