Személyes eszközök
Keresés

 

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
    ...
  }
}
Amennyiben ilyen megosztott változónk van, és azt egy alprogramban kívánjuk használni, értéket tenni bele, vagy kiolvasni a benne szereplő értéket - akkor a változót már az alprogramban tilos újra deklarálni. Amennyiben megtesszük, a frissen deklarált változónk elfedi a külső, megosztott változót, és nem a kívánt eredményt érjük el.


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 megosztott változók több szempontból is különböznek az alprogramokban deklarált változóktól. Ezért a továbbiakban a nevük mező lesz (megkülönböztetésül). Teljes nevük osztályszintű mező, vagy statikus mező, és az OOP félévben több szempontból újra tárgyalásra kerülnek.


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
 
  }           
}


Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp1/page490
Nézetek
nincs sb_3.81.165.210 cikk