Megosztott változók
A programok eljárásokra tagolása persze újabb problémákat szül. Az eljárások ’nem látják’ egymás változóit. Ennek oka a változók hatáskörének problémakörében keresendő.
Minden változónévhez tartozik egy hatáskör. A hatáskör megadja, hogy az adott változót a program szövegében mely részeken lehet ’látni’ (lehet rá hivatkozni). A szabály az, hogy a változók csak az őket tartalmazó blokk-on belül ’láthatók’, vagyis a változók hatásköre az őket tartalmazó blokkra terjed ki.
{
int a=0;
Feltoltes();
Console.WriteLine("{0}",a);
}
static void Feltoltes()
{
a=10;
}
A fenti kód hibás, mivel az ’a’ változó hatásköre a ’Main’ függvény belseje, az ’a’ változóra a ’Feltoltes()’ eljárásban nem hivatkozhatunk. Ha mégis megpróbáljuk, akkor a C# fordító a The name 'a' does not exist ... kezdetű fordítási hibaüzenettel jelzi ezt nekünk.
Ezt (hibásan) az alábbi módon reagálhatjuk le:
{
int a=0;
Feltoltes();
Console.WriteLine("{0}",a);
}
static void Feltoltes()
{
int a=10;
}
Ekkor a ’Feltoltes()’ eljárásban is létrehozunk egy másik, szintén ’a’ nevű változót. Ez a változó sajátja lesz a ’Feltoltes()’-nek, de semmilyen kapcsolatban nem áll a ’Main()’ függvény-beli ’a’ változóval. A nevek azonossága ellenére ez két különböző változó, két különböző adatterületen helyezkedik el. Ezért hiába tesszük bele az ’a’ változóba a ’10’ értéket, ezen érték a ’Feltoltes()’ eljárásbeli ’a’ változóba kerül bele, nem a Main()-beli ’a’ változóba.
Változók megosztása az eljárások között
Mivel a hatáskör-szabály szigorú, és nincs kivétel, ezért mindaddig, amíg az ’a’ változót a Main() függvény blokkjában deklaráljuk, addig e változót más eljárásokban nem érhetjük el. A megoldás: ne itt deklaráljuk!
{
static int a=0;
static void Main(string[] args)
{
Feltoltes();
Console.WriteLine("{0}",a);
}
static void Feltoltes()
{
a=10;
}
}
Azokat a változókat, amelyeket szeretnénk megosztani az eljárásaink között, azokat az eljárásokat összefogó osztály (class) belsejében, de az eljárásokon kívül kell deklarálni. Mivel az eljárásaink static jelzővel vannak ellátva, ezért a közöttük megosztott változókat is ugyanúgy static jelzővel kell ellátni. Ha ezt elmulasztanánk, akkor a static eljárások nem ’látnák’ a nem static változókat.
Nézzünk egy összetett feladatot: kérjünk be egy tíz elemű vektor elemeit billentyűzetről, majd írjuk ki a vektor elemeinek értékét a képernyőre egy sorban egymás mellé vesszővel elválasztva, majd számoljuk ki és írjuk ki a képernyőre a vektor elemeinek összegét.
Figyeljük meg, hogy a Main() függvény nem tartalmaz lényegében semmilyen kódot, a tényleges műveleteket eljárásokba szerveztük, és jól csengő nevet adtunk nekik:
{
static int[] tomb=new int[10];
static int osszeg=0;
//..................................................
static void Main(string[] args)
{
Feltoltes();
Kiiras();
OsszegSzamitas();
Console.WriteLine("A tomb elemek osszege={0}" ,osszeg);
}
//..................................................
static void Feltoltes()
{
for(int i=0;i<tomb.Length;i++)
{
Console.Write("A tomb {0}. eleme=",i);
string strErtek=Console.ReadLine();
tomb[i] = Int32.Parse( strErtek );
}
}
//.................................................
static void Kiiras()
{
Console.Write("A tomb elemei: ");
for(int i=0;i<tomb.Length;i++)
Console.Write("{0}, ",tomb[i]);
Console.WriteLine();
}
//.................................................
static void OsszegSzamitas()
{
osszeg=0;
for(int i=0;i<tomb.Length;i++)
osszeg = osszeg + tomb[i];
}
//..................................................
}
A változók között meg kellett osztani magát a tömböt, mert azt minden eljárás használta. Ezen túl meg kellett osztani egy ’osszeg’ nevű változót is, mert ezen változó értékét az ’OsszegSzamitas()’ eljárás számolja ki, és a Main() függvény írja ki a képernyőre.