A InfoWiki wikiből
Megosztott változók
Amennyiben a programunkat több alprogramból áll, komoly kihívás előtt állunk. Az alprogramok egymás által kiszámolt értékekre hivatkoznak. Az egyik alprogramban kiszámolt értékeket egy másik alprogramban is fel kell használnunk. Sajnos, a változódeklaráció ekkor már kevés lesz! Ugyanis a változódeklaráció során valamely alprogramban deklarálunk egy változót, melynek hatásköre a befoglaló kapcsos zárójelen túl nem terjed - amely legjobb esetben is a befoglaló alprogram törzsének befejező kapcsos zárójele:
class Program { static void Egyik() { int a=3; // az 'a' valtozo hatáskörének kezdete ... } // és vége static void Masik() { ... a++; // HIBA: itt nem tudunk az 'a' változóra hivatkozni ... } }
Ezen az sem segít, ha a Masik() alprogramban is deklarálunk egy a nevű változót. Az ugyanis nem a fenti 'a' változót fogja jelölni, hanem egy másik változót.
class Program { static void Egyik() { int a=3; // a saját 'a' változónk Masik(); // ő egy másikat használ Console.Write(a); // a sajátunk még mindíg 3 ... } static void Masik() { ... int a=4; // ez itt egy másik 'a' változó ... } }
Megosztott változók deklarálása
Amennyiben olyan változókra van szükségünk, amelyek közösek (megosztottak) a különböző alprogramok között, azokat az alprogramokon kívül, de az osztályunk belsejében kell deklarálni. Ez esetben a static kulcsszót is ki kell tenni a változóink deklarációja során. Ennek oka, hogy ezen változók a static jelzőjű alprogramok között kerül megosztásra (részletesebb indoklása a következő félévben várható):
class Program { static int a; static void Egyik() { a=3; // a közös 'a' változónk Masik(); // ő is ezt használja Console.Write(a); // ezért itt már 4 lesz ... } static void Masik() { ... a++; // a közös 'a' változót növeljük ... } }
Megosztott változók hatásköre
A megosztott (osztály belsejében deklarált static változók) hatásköre a teljes osztályra kiterjed. Tehát nem a deklaráció pontos helye a döntő (nem ettől a sortól kezdődik a hatásköre), hanem az adott osztályban szereplő minden alprogramra kiterjed!
class Program { static void Egyik() { a=3; // az 'a' hatásköre ide is kiterjed Masik(); // ő is ezt használja Console.Write(a); ... } static int a; static void Masik() { ... a++; // és ide is ... } }
Ez a változók esetén nem így van, ott az attól a sortól kezdődik a hatáskör, ahol a változót deklaráltuk, és a befoglaló kapcsos zárójelig tart. A megosztott változók hatásköre azonban felfele is terjedhet, a teljes osztályt átfogja.
A változók élettartama
Egy ilyen static változó élettartama a teljes program futásának idejére kiterjed. Vagyis mikorra a Main() függvényünk elindul, ez a változó már a memóriában van, és amíg a program fut, végig ott is marad. Ezt az élettartamot statikus élettartamnak (teljes futási idő) nevezzük.
Az alprogramok belsejében deklarált változók élettartama teljesen eltér ettől. Először is csak akkor kerülhetnek be a memóriába, ha az adott alprogram elindul. Valamint amint az alprogram befejeződik, a benne deklarált változók automatikusan kikerülnek (törlődnek) a memóriából. Ezt dinamikus élettartamank nevezzük.
A dinamikus élettartam jellemzője, hogy amennyiben egy alprogramot többször is elindítunk, minden induláskor a benne deklarált változók bekerülnek a memóriába, befejezésekor pedig mindíg törlődnek. Ezért uyganaz az alprogram egymás utáni indítása során a korábbi változóiba elhelyezett értékekhez ő maga sem tud már hozzáférni. Minden futása során vadonatúj garnitúrával dolgozik.
A statikus élettartam rosszabb a memóriagazdálkodás szemszögéből. A változók végig a memóriában vannak, végig foglalják a helyet. A dinamikus változók által foglalt memóriaterület futás közben felszabadul, a helyükre más alprogramok változói kerülhetnek. Íly módon a memóriaterület időben nem átfedő módon újrahasznosításra kerül. Ez természetesen takarékosabb. Ezért csak azokat a változókat szoktuk statikus élettartamra tenni, amelyeknél ez indokolt!
A mezők kezdőértéke
A mezők abban is különböznek a változóktól, hogy kezdőértékkel rendelkeznek. A kezdőértékük a típusukhoz illeszkedő nulla érték:
- egész számok esetén nulla
- tört számok esetén nulla egész nulla
- karakterek esetén a nulla kódú karakter
- logikai típus esetén a false
- string-ek esetén a null érték
A kezdőérték azt jelenti, hogy nem jelez definiálatlan változó hibát a fordító, ha egy mező értéké kiolvassuk mielőtt a program abba értéket helyezett volna el:
class Program { static int db; static void Main() { db++; // ez nem hibás, 0-ról 1-re növelés int a; a++; // ez viszont hibás, 'a' nem definiált } }
A mezők értékét a változók kezdőértékéhez hasonló módon direkt (implicit) módon is beállíthatjuk kezdőértékadás segítségével:
class Program { static int legkisebb_prim = 2; static string nev = "lajos"; static void Main() { legkisebb_prim = 5; } }
Más osztályok esete
Ha egy idegen (más) osztály mezőjére kívánunk hivatkozni, az alapvetően nem tehetjük meg, csak ha ezt megengedjük. Az engedély kulcsszava itt is a public. Ennek hiányában a mezőre csak a saját osztályában lévő alprogramok hivatkozhatnak. A publikus mezők esetén ebbe a mezőbe bármely (más) osztály alprogramjai is helyezhetnek értéket, kiolvashatják a benne lévő értéket. Ekkor (hasonlóan mint az alprogramok esetén) ki kell írni a mezőt tartalmazó osztály nevét is.
class Sajat { static double d; public static int x; static void akarmi() { x = 23; // ezt szabad d = 12.4; // itt ez is működik } } class Program { static void Egyik() { Sajat.x = 12; // ez működik, public Sajat.d = 23.4; // ez nem működik kívülről .. } }
Konstansok
A helyzet a konstansokkal ugyanaz, mint a mezőkkel. A konstansok deklarálását jellemzően az osztályok belsejében szoktuk elhelyezni. Ha a konstans értékét más osztályok is kiolvashatják, akkor a public kulcsszóval erre engedélyt kell adni:
class Math { public const double Pi = 3.1415927; ... } class Program { static void Egyik() { double kerulet = 14.5*2*Math.Pi; ... } }
Vegyük észre, hogy a konstansok és a mezők kezdőértéke is beállítható, de a konstansok értékét nem lehet módosítani, míg a mezőkét igen!
class Program { const int labak_szama = 4; static int fizetes = 1000000; static void Egyik() { fizetes = fizetes+20000; // ezt lehet labak_szama++; // HIBA: ezt nem } }