Személyes eszközök
Keresés

 

A InfoWiki wikiből

(Változatok közti eltérés)
1. sor: 1. sor:
<cim  
<cim  
-
cim3="Előírt lépésszámú ciklusok"
+
cim3="Vektorok"
cim2="Magasszintű Programozási Nyelvek I."  
cim2="Magasszintű Programozási Nyelvek I."  
cim1="Imperatív, procedurális nyelvek alapjai"  
cim1="Imperatív, procedurális nyelvek alapjai"  
15. sor: 15. sor:
-
= Előírt lépésszámú ciklusok =
+
= Vektorok =
-
Tekintsük meg az alábbi kódot:
 
-
 
-
<code lang="csharp">
 
-
int i=0;
 
-
while (i<10)
 
-
{
 
-
  ...
 
-
  i++;
 
-
}
 
-
</code>
 
-
 
-
A fenti ''while'' ciklus a ciklusmagját 10-szer fogja végrehajtani, mivel az ''i'' változó induló értéke 0,
 
-
minden menetben az ''i'' értéke pontosan 1-el nő, és akkor fogja elhagyni a ciklust, ha az ''i'' értéke elérte
 
-
(vagy meghaladta) a 10 értéket.
 
-
 
-
Gyakoriak azok az esetek, amikor előre ismert, hogy a ciklusmag hányszor kerül majd végrehajtásra. Ez esetben
 
-
a fentihez hasonló while ciklus alkalmazható, de nem túl szerencsés az alkalmazása. Az információk, amelyből
 
-
a kiderül, hogy ez a ciklus 10-szer ismétlődik majd - a kódban szétszórtan helyezkedik el. Ráadásul az ''i''
 
-
változó deklarációja meg kell előzze a while ciklus indulását, így hatásköre (és az élettartama) nem a ciklusra
 
-
korlátozódik,  hanem a ciklus lefutása után is megmarad.
 
-
 
-
A fenti problémák kezelésére speciális ciklusfajta szolgál, a '''for''' ciklus.
 
-
 
-
<box type="warn">A FOR ciklus akkor alkalmazható, ha a ciklus futása előre ismert darabszámú, mely darabszám a ciklus indításakor már kiszámolható, és később sem változik. Ha a ciklus futási darabszáma nem előre kiszámítható, vagy esetleg az változhat, akkor inkább WHILE ciklust kell alklamazni.</box>
 
-
 
-
 
-
= FOR fejrésze =
 
-
 
-
A ''for'' ciklus fejrésze három részre osztható, melyeket kettő darab pontosvessző határol. A részek szerepe:
 
-
* az inicializáló utasítás (mely a ciklus kezdetekor egyszer hajtódik végre
 
-
* a ciklus vezérlő feltétele (pozitív vezérlésű a for ciklus)
 
-
* a léptető utasítás (mely a ciklusmag lefutása után automatikusan kerül végrehajtásra)
 
-
 
-
Példa:
 
-
 
-
<code lang="csharp">
 
-
for(int i=0; i<10; i++)
 
-
{
 
-
  Console.Write(i);
 
-
}
 
-
</code>
 
-
 
-
A fenti példa teljesen megfelel a korábban ismertetet while ciklus példában szereplő kód működésével. Az
 
-
''i'' változó azonban itt a ciklusra lokális, tehát a for ciklus törzsén túl már nem terjed a hatásköre.
 
-
A ciklusmag minden lefutása után végrehajtódik az inkrementáló utasítás, vagyis az ''i'' értéke nő 1-el.
 
-
 
-
A példában szereplő for ciklus fejrészében minden információ szerepel, melyből meghatározható, hogy
 
-
ez a for ciklus pontosan 10-szer fog lefutni. A ciklusmagban az ''i'' változó értéke kiolvasható,
 
-
de megváltoztatása tilos. Ennek oka, hogy az ''i'' változó értékének átírása a pontos 10 ismétlést
 
-
módosítaná (vagy kevesebbszer, vagy többször kerülne végrehajtásra).
 
-
 
-
<box type="warn">A ciklusváltozó ciklusmagon belüli módosítása nem szintaktikai, hanem elvi hiba. A fordító eltűri, de ezen tevékenység ellentmond a for ciklus lényegének. Akinek ilyenre van szüksége, az használjon while ciklust.</box>
 
-
 
-
= Példa =
 
-
 
-
Hibás tehát az alábbi példa (bár nem szintaktikailag, hanem elvi, stílusbeli hiba). A programban
 
-
a 10 elemű tömböt csak pozitív számokkal kívánjuk feltölteni. Amennyiben a program kezelője valamely
 
-
elem értékének negatív számot kíván megadni, azt az elemet újra bekérjük:
 
-
 
-
<code lang="csharp">
 
-
int[] tomb = new tomb[10];
 
-
for(int i=0;i<10;i++)
 
-
{
 
-
  Console.Write("{0}. szám értéke:");
 
-
  tomb[i] = int.Parse(Console.ReadLine());
 
-
  if (tomb[i]<0) i--;
 
-
}
 
-
</code>
 
-
 
-
A feltételben az ''i--'' utasítás az ''i'' értékét csökkenti 1-el, amit
 
-
az inkrementáló utasítás (''i++'') meg fog növelni 1-el. E miatt negatív
 
-
szám beírása esetén az ''i'' értéke gyakorlatilag nem fog változni - a ciklus
 
-
következő lefutásakor is ugyanazon ''i'' tömbelem kerül feltöltésre.
 
-
 
-
Ez elegánsabban megoldható while ciklussal:
 
-
 
-
<code lang="csharp">
 
-
int[] tomb = new tomb[10];
 
-
int i=0;
 
-
while (i<10)
 
-
{
 
-
  Console.Write("{0}. szám értéke:");
 
-
  tomb[i] = int.Parse(Console.ReadLine());
 
-
  if (tomb[i]>0) i++;
 
-
}
 
-
</code>
 
-
 
-
Vagyis csak akkor lépünk a következő tömbelem bekérésére, ha ezen tömbelemmel
 
-
elégedettek vagyunk.
 
-
 
-
Másik lehetséges megoldás:
 
-
 
-
 
-
<code lang="csharp">
 
-
int[] tomb = new tomb[10];
 
-
for(int i=0;i<10;i++)
 
-
{
 
-
  do
 
-
  {
 
-
    Console.Write("{0}. szám értéke:");
 
-
    tomb[i] = int.Parse(Console.ReadLine());
 
-
  }
 
-
  while (tomb[i]<0);
 
-
}
 
-
</code>
 
-
 
-
Ez esteben az ''i''-edik tömbelem bekérésől addig nem lépünk tovább, amíg
 
-
annak értékével elégedettek nem vagyunk.
 
-
 
-
= Trükkösebb ciklusok (a) =
 
-
 
-
A for ciklus fejrészében szereplő vezérlő feltétel tetszőlegesen összetett lehet,
 
-
hiszen az gyakorlatilag megfelel a while ciklus vezérlő feltételének szerepkörével:
 
-
 
-
<code lang="csharp">
 
-
int db=0;
 
-
for(int i=0;i<10 && db<3; i++)
 
-
  if (tomb[i]>0) db++;
 
-
</code>
 
-
 
-
Ez a for ciklus legkésőbb 10 menetben leáll. Korábban is leállhat, ha
 
-
a tömbben találtunk 3 pozitív számot.
 
-
 
-
Ez a működés némiképp ellentmond a korábban említett elvvel: a for ciklus
 
-
működésének darabszáma előre kiszámított kell legyen. Nos, a ez a határeset
 
-
kategória. Az ''i'' változó szerepe a tömb elemeinek indexelése, és ez a ciklus
 
-
sorra veszi a tömbelemeket. A ciklus ''maximális'' végrehajtási száma a fejben
 
-
adott (ez 10 darab). A korábbi kilépő feltétel belefér.
 
-
 
-
= Trükkösebb ciklusok (b) =
 
-
 
-
Az inkrementáló lépés nem mindíg az 1-el növelés. Tetszőleges utasítás megadható
 
-
azon a ponton:
 
-
 
-
<code lang="csharp">
 
-
for(double a=0;a<1.5; a=a+0.1) { ... }
 
-
for(int i=10;i>0; i-- ) { ... }
 
-
for(int i=2;i<100; i=i+2 ) { ... }
 
-
for(int i=2;i<100; i=i*2-1 ) { ... }
 
-
</code>
 
-
 
-
= Trükkösebb ciklusok (c) =
 
-
 
-
A C nyelvben szerepel egy misztikus jellemzőjű vessző operátor (, operátor). A
 
-
vessző operátorral lehetséges egyetlen utasítást megengedő helyre több utasítást
 
-
is szerepeltetni. Erre szükség lehet olyan esetekben, amikor adott pontján
 
-
a programnak tilos programblokkot alkalmazni, mégis szeretnénk több utasítást
 
-
is végrehajtani. Ilyen hely a for ciklus léptető (inkrementáló) utasítsása.
 
-
Helytelen az alábbi:
 
-
 
-
<code lang="csharp">
 
-
int ossz=0;
 
-
for( int i=0; i<10; {ossz=ossz+t[i];i++}) {}
 
-
  Console.WriteLine("Az összeg={0}",ossz);
 
-
</code>
 
-
 
-
Ezzel szemben helyes az alábbi:
 
-
 
-
<code lang="csharp">
 
-
int ossz=0;
 
-
for( int i=0; i<10; ossz=ossz+t[i],i++) {}
 
-
Console.WriteLine("Az összeg={0}",ossz);
 
-
</code>
 
-
 
-
A vessző operátor súlyos megkötése, hogy a vesszővel elválasztott utasítások adott
 
-
sorrendben hajtódnak végre (szekvencia szabály speciális esetre alkalmazása). Ezért
 
-
a fenti for ciklus még jól is működik.
 
-
 
-
Vegyük észre, hogy ebben az esetben a for ciklus magja üres. Ez megfelel annak
 
-
az esetnek, amikor a for ciklus magja egyetlen üres utasítást tartalmaz. Ez
 
-
esetben a pontosvessző írása a for ciklus fejrésze után nem hiba, hanem ezen
 
-
üres utasítás lezárása:
 
-
 
-
<code lang="csharp">
 
-
int ossz=0;
 
-
for( int i=0; i<10; ossz=ossz+t[i],i++) ;
 
-
Console.WriteLine("Az összeg={0}",ossz);
 
-
</code>
 
-
 
-
A vessző operátor azonban a C nyelv azon misztikus, és sokat vitatott megoldása,
 
-
amely (mint kiderült) több baj forrása, mint amennnyi problémát megold. Ezért
 
-
a fenti kód a C# nyelvben bár működik, de kerülendő.
 
-
 
-
= A for fejrésze =
 
-
 
-
A for ciklus fejrésze minden esetben három részből áll, akkor is, ha valamely
 
-
utasítás az '''üres''' utasítás. A for ciklus fejrészéből csak a vezérlő
 
-
feltétel nem lehet üres, de mind a kezdőértékbeállítás, mind a léptetés
 
-
üresen hagyható:
 
-
 
-
<code lang="csharp">
 
-
int i=int.Parse(Console.ReadLine());
 
-
for(  ;i<10; i++)
 
-
{
 
-
    ...
 
-
}
 
-
</code>
 
-
 
-
A for ciklus fejrésze ekkor is három részből kell álljon! Vagyis az üres
 
-
utasítást is le kell zárni a pontosvesszővel.
 
-
 
-
<code lang="csharp">
 
-
int i=0;
 
-
for(  ;i<10; )
 
-
{
 
-
    ...
 
-
    i++;
 
-
}
 
-
</code>
 
-
 
-
Ebben a példában szereplő for ciklus fejrészéből már mindkét elhagyható
 
-
utasítás elhagyásra is került. Ez már gyakorlatilag megfelel a korábban
 
-
felírt while ciklus működésének.
 
-
 
-
 
-
<code lang="csharp">
 
-
for(int i=0;i<10; )
 
-
{
 
-
    ...
 
-
    i++;
 
-
}
 
-
</code>
 
-
 
-
Ezek a hiányos for ciklus fejrészek szintaktikai hibát nem okoznak, de
 
-
mivel szintén ellentétben állnak a for ciklus lényegét leíró működésnek,
 
-
használatuk stílustalan, nem javasolt.
 
<alairas>Hernyák Zoltán</alairas>
<alairas>Hernyák Zoltán</alairas>
__NOTOC__
__NOTOC__

A lap 2009. november 14., 19:49-kori változata


Vektorok

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