Pages linking to MuuttujienNakyvyys:
s2012

Muuttujien näkyvyys

Pääasiassa muuttujat ovat näkyvissä siinä lohkossa, jossa ne on esitelty. Eli oikeastaan kaikki alla olevat "säännöt" seuraavat tätä soveltaen. Muuttujat ovat olemassa niin kauan kuin lohkosta ei olla poistuttu Aliohjelmakutsun aikana lohkosta ei ole poistuttu, siihenhän tullaan vielä takaisinkin.

Katso esimerkkiohjelmaa MuuttujienNakyvyys.cs

1. Pääohjelman muuttujat

  • pääohjelmassa (tai missä tahansa muussakin aliohjelmassa) esitellyt muuttujat näkyvät vain oman esittelynsä lohkon {} 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)
  • luvut on periaatteessa nähtävissä ja muutettavissa vain pääohjelmassa. Kuitenkin koska taulukkokin on olio C#:issa, se viedään aliohjelmalle viitteenä ja viitteen kautta aliohjelma voi muuttaa pääohjelman taulukon sisältöä.
  • kaikki kolme muuttujaa elävät pääohjelman loppusulkuun } saakka
  • muuttujan luku ARVO kopioidaan aliohjelman vastinmuuttujaan. Siinä mielessä aliohjelma ei näe pääohjelman muuttujaa (vaan sen ARVOn).
  • args 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 Aliohjelman parametrimuuttujat

Aliohjelmakutsussa aliohjelman parametrimuuttujiin kopioidaan kutsussa olevien LAUSEKKEIDEN arvot siinä järjestyksessä kuin ne kutsussa ovat. Pitää muistaa että esim. 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 }

2.2 Aliohjelman lokaalit muuttujat

Aliohjelma voi tarvita myös lokaaleja 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 (vaikka jossakin olisi samanniminenkin muuttuja) eivät millään tavalla vaikuta mihinkään muuhun paikkaan kuin tähän muuttujaan.
  • pääohjelma tai kukaan muukaan ei pääse käsiksi tähän muuttujaan millään tavalla (paitsi tässä tapauksessa kun tuo arvo riippuu parametrina tuodun luku-muuttujan arvosta).

3. Omassa lohkossa esitellyt muuttujat

Joskus voidaan esitellä apulohko, jonka sisällä on omat muuttujat, joihin pääsee käsiksi vain lohkon sisällä. Esim. malliohjelman pääohjelmassa voisi olla

        Muuta(luvut, 2, luku);
        {                          // 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 { } 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++)
        {
            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.2 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 saa käyttää toisessa lohkossa.

5. Attribuutit

Olioiden sisällä voi olla omia muuttujia, joita nimitetään attribuuteiksi. Attribuutit kannattaa lähes poikkeuksetta esitellä privateksi, 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. Tämäkin on vaarallista luokan koon kasvaessa ja attribuutteja pitääkin osata käyttää varoen ja taitavasti.

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.

Linkkejä