A ’for’ ciklusoperátor
Egy másik ciklusoperátor a ‘for' operátor.
A ' for' operátor formátuma
A 'for' ciklusoperátor teljes formátuma áll - a fejlécből, ami tartalmazza az 1.Kifejezést a Feltételt és a 2.Kifejezést - és áll a végrehajtható ciklustörzsből, amelyet kapcsos zárójelek közé zárunk.
for (1.Kifejezés; Feltételt; 2.Kifejezés) // Ciklusoperátor fejléc
{ // Nyitó kapcsos zárójel
Operátor blokk.. // A ciklustörzs állhat ...
..alkotja a ciklustörzset //... több operátorból is
} // Záró kapcsos zárójel
Ha a 'for' operátorban a ciklustörzs csak egy operátorból áll a zárójeleket elhagyhatjuk.
for (1.Kifejezés; Feltételt; 2.Kifejezés) // Ciklusoperátor fejléc
Egy operátor a ciklustörzs
Az
1.Kifejezés a Feltétel és a
2.Kifejezés
hiányozhatnak a kódból. Azonban
az elválasztó karakternek ";”
(pontosvessző)
maradnia kell a kódban.
for
( ; Feltétel;
2.Kifejezés) // Nincs
1.Kifejezés
{
// Nyitó kapcsos
zárójel
Operátor
blokk..
// A ciklus test állhat
...
..alkotja
a ciklus testet //... több
operátorból is
}
// Záró kapcsos
zárójel
// -
---------------------------------------------------------------------------------
for
(1.Kifejezés; ;
2.Kifejezés) // Nincs Feltétel
{
// Nyitó kapcsos
zárójel
Operátor
blokk..
// A ciklus test állhat
...
..alkotja
a ciklus testet //... több operátorból
is
}
// Záró kapcsos
zárójel
// -
---------------------------------------------------------------------------------
for
( ; ; )
// Nincsenek
Kifejezések sem Feltétel
{
// Nyitó kapcsos zárójel
Operátor
blokk.. // A
ciklus test állhat
...
..alkotja
a ciklus testet //... több
operátorból is
}
//
Záró kapcsos zárójel
A 'for' operátor végrehajtási szabálya
Figyelem!
Amint a vezérlést megkapja a ’for' operátor, a program végrehajtja az 1.Kifejezést. Mindaddig, amíg az operátor Feltétele (Condition) igaz: a vezérlést megkapja az első operátor a ciklus testben; amint minden operátort a ciklus testben végrehajtottak, a programnak végre kell hajtania a 2.Kifejezést és át kell adni a vezérlést a fejlécbe, hogy az tesztelhesse a feltételt. Ha a ‘for' operátor feltétele hamis: a programnak át kell adnia a vezérlést annak az operátornak, amelyik követi a ‘for' operátort.
Gondolkozzunk, hogyan működik a 'for' ciklusoperátor. Oldjunk meg egy feladatot.
Feladat
13. feladat: Nekünk van egy egész számsorunk: 1 2 3 4 5 6 7 8 9 10 11 ... Alkossunk egy programot, ami kiszámítaná ezen sorozat elemeinek az összegét, N1-töl N2-ig.
Ezt a problémát matematika szempontból könnyű megoldani. Tételezzük fel azt, hogy harmadik elemtől a hetedik elemig ki akarjuk számítani az elemek összegét. A megoldás ez lenne: 3 + 4 + 5 + 6 + 7 = 25. Azonban, ez a megoldás csak egy speciális esetben jó, amikor az összeadandó elemek első és utolsó eleme 3 illetve 7. Egy programot, ami ezt a feladatot elvégzi úgy kell megalkotni, hogy a számsor bármely elemét választhassuk kezdő illetve végső értéknek (például 15-től 23-ig), és könnyen megváltoztathassuk a kezdő és végső értéket anélkül, hogy a programsorokat egyéb helyen módosítanánk. Lent van egy ilyen programváltozat (script sumtotal.mq4):
//-----------------------------------------------------------------------------
// sumtotal.mq4
// The code should be used for educational purpose only.
//-----------------------------------------------------------------------------
int start() // Special function start()
{
//-----------------------------------------------------------------------------
int
Nom_1, // Number of the first element
Nom_2, // Number of the second element
Sum, // Sum of the numbers
i; // Formal parameter (counter)
//-----------------------------------------------------------------------------
Nom_1=3; // Specify numeric value
Nom_2=7; // Specify numeric value
for(i=Nom_1; i<=Nom_2; i++) // Cycle operator header
{ // Brace opening the cycle body
Sum=Sum + i; // Sum is accumulated
Alert("i=",i," Sum=",Sum); // Display on the screen
} // Brace closing the cycle body
//------------------------------------------------------------------------------
Alert("After exiting the cycle, i=",i," Sum=",Sum);// Display on the screen
return; // Exit start()
}
//------------------------------------------------------------------------------
A program első soraiban a változókat deklarálunk (a megjegyzések megmagyarázzák a változók értelmét). Ezekben a sorokban:
Nom_1 = 3; // Specify numeric value
Nom_2 = 7; // Specify numeric value
a tartomány első és utolsó elemének számszerű meghatározása történik. Vedd észre, hogy ezeket az értékeket sehol máshol nem kell megadni a programban. Ha szükséges, könnyen meg tudod változtatni ezeket az értékeket (egy helyen) anélkül, hogy a kód bármely másik sorát megváltoztatnád. Ezek után a vezérlést megkapja a 'for' ciklusoperátor:
for(i=Nom_1; i<=Nom_2; i++) // Cycle operator header
{ // Brace opening the cycle body
Sum = Sum + i; // Sum is accumulated
Alert("i=",i," Sum=",Sum); // Display on the screen
} // Brace closing the cycle body
A kulcsmondat - a 'for' operátor végrehajtási szabálya - a következő: A kezdettől… mindaddig… lépj... hajtsd végre a következőt: . A ”lépj…” akkor használható, ha számlálót (például: i++ vagy i=i+2) alkalmazunk a 2.Kifejezésben. A példánkban a kulcsmondat a következő: Kezdetben i egyenlő Nom_1, mindaddig amíg i kevesebb vagy egyenlő Nom_2, lépj1-et, hajtsd végre a következőt: (a ciklustörzs végrehejtása).
A 'for' operátor végrehajtásszabálya szerint végre fogjuk hajtani ezt a blokkot a programból:
1. Az 1. Kifejezés végrehajtása:
i=Nom_1
Az i változó felveszi a Nom_1 változó számszerű értékét, vagyis 3 egész szám értéket. Az 1. Kifejezést csak egyszer hajtjuk végre - amikor a vezérlést megkapja a 'for' operátor. Az 1.Kifejezés nem vesz részt semmilyen rákövetkező eseményben.
2. A Feltételt teszteljük:
i<=Nom_2
A Nom_2 változó értéke az első ismétlésnél 7 (egész szám), míg az i változó egyenlő 3-mal. Ez azt jelenti, hogy a feltétel igaz (3 kevesebb 7-nél), vagyis a vezérlést megkapja a ciklustörzs, hogy azt végrehajtsa.
3. A példánkban a ciklustörzs két operátorból áll amelyeket egyenként végre fogunk hajtani:
Sum = Sum + i; // Sum is accumulated
Alert("i=",i," Sum=",Sum); // Display on the screen
A Sum változó az inicializálásánál nem kapott kezdőértéket, ezért az értéke az első ciklus kezdete előtt egyenlő nullával. A számítások alatt a Sum változó értékét növeljük az i értékével, tehát az első ismétlés végén i egyenlő 3-mal. Ezt az értéket látjuk az Alert() függvény ablakában:
i=3 Sum=3 |
4. Az utolsó esemény a ciklus operátor végrehajtása alatt a 2.Kifejezés végrehajtása:
i++
Az i változó értéke eggyel növekszik. Ezzel az első ismétlésnek vége, a vezérlés teszteli a feltételt.
Ezután a második ismétlés kezdődik a 2-4 lépésekkel. A számítások alatt a változók új értékeket kapnak. Esetünkben a második ismétlésnél az i változó értéke egyenlő 4-gyel, míg Sum egyenlő 7-tel. A megfelelő üzenet szintén meg fog jelenni. Általában véve, a program a lenti blokkdiagram szerint fog tovább haladni:
43. ábra: A
'for' operátor
végrehajtásának a blokkdiagramja a sumtotal.mq4 programban.
A program ciklikusan ismételni fogja a ciklusoperátor végrehajtását, amíg a Feltétel (Condition) hamissá válik. Ez akkor fog megtörténni, amikor az i változó értéke egyenlő lesz 8-cal, vagyis meghaladja Nom_2 változó előre beállított értékét a 7-et. Ebben az esetben a vezérlés a 'for' operátoron kívülre kerül mégpedig ebbe a sorba:
Alert("After exiting the cycle, i=",i," Sum=",Sum);// Display on the screen
és végül a 'return' operátor végrehajtása befejezi a start() különleges függvény munkáját.
Arra lehet használni ezt a programot, hogy bármilyen tartománynak az összegét kiszámítsa. Például, ha kicseréled a 3 és 7 állandókat 10-re és 15-re a program végrehajtása az ezen a tartományon belül értékek összegének a kiszámításával fog végződni.
Néhány
programnyelvben azok a változók, amiket a
ciklusoperátor fejlécében
használnak
elvesztik az értékeiket miután
kiléptünk a ciklusból. Ez nem
így van az MQL4-ben.
Minden változó, ami szerepet játszik
bármilyen számításban,
érvényes és megtartja
az értékét miután
kiléptünk a
ciklusból. Ugyanakkor néhány
sajátosság érinti azon
változók értékeit, amik a
számításokban szerepeltek.
Jegyezd meg, hogy az utolsó két üzenet
sor megmarad
a számítások befejezése
és
a script eltávolítása után
is:
i=7 Sum=25 |
After exiting the cycle, i=8 Sum=25 |
A fentebb két üzenet közül az első még azelőtt megjelent, mielőtt az utolsó ciklus teljesen végrehajtódott, míg az utóbbit az Alert() függvény a program befejezése előtt küldte. Figyelmet érdemel, hogy ezekben a sorokban az i változó különböző értékei szerepelnek. A ciklus végrehajtása alatt ez az érték 7, de 8 lesz amikor kilépünk a ciklusból.Hogy megértsük ez miért történik így, nézzük meg a 43. ábrát még egyszer!
Az utolsó (ebben az esetben, az ötödik) ismétlés a feltétel tesztelésével kezdődik. Az i értéke ebben a pillanatban egyenlő 7-tel. Ez az érték nem nagyobb, mint a Nom_2 változó, a feltétel igaz és a ciklustörzset végre kell hajtani. Amint a ciklustörzset alkotó operátorok közül az utolsót is végrehajtjuk: a 2. kifejezést szintén végre kell hajtani. Ezt még egyszer hangsúlyozni kell:
Figyelem!
Az utolsó esemény, ami lejátszódik a 'for' operátor mindegyik ismétlésénél, a 2.Kifejezés kiszámítása.
Ez ahhoz vezet, hogy az i változó értéke növekszik 1-el és 8-as értéket kap. A feltétel (Condition) következő tesztje (a következő ismétlés kezdetén) azt az eredményt adja, hogy a feltétel most hamis. Ez azt eredményezi, hogy a vezérlés a teszt elvégzése után a ciklusoperátoron kívül kerül. Ugyanakkor, az i változó értékel a ciklusoperátor elhagyásakor 8, míg a Sum változó értéke egyenlő 25-tel, mert a ciklustörzs operátorait már nem hajtjuk végre. Ezt figyelembe kell venni olyan helyzetekben, ahol az ismétlések (iterációk) számát előre nem ismerjük.
Azt hihetnénk, hogy az olyan helyzet, ami hurkolódáshoz vezet kivételes. Ez különféle hibáknál könnyen lehetségessé válik. Például, ha hibásan használod a 2. kifejezést:
i--
mindegyik ismétlésnél a számláló értéke csökkenni fog, és a Feltétel soha nem válik hamissá.
A másik hiba a helytelenül megfogalmazott Feltétel (Condition) lehet:
for(i=Nom_1; i>=Nom_1; i++) // Cycle operator header
Ebben az esetben, az i változó értéke mindig nagyobb vagy egyenlő lesz Nom_1 változó értékével, és a Feltétel mindig igaz lesz.
A 'while' és 'for' ciklus operátorok felcserélhetők
Hogy egyik vagy másik operátort használja a programozó döntésétől függ. Az egyetlen dolog, amit meg kell jegyezni, hogy ezeket az operátorokat szinonimákként használhatjuk; és a cseréjük csak egy kis finomítást jelent a kódban.
Például: a 13. feladat megoldására a 'for' ciklusoperátort használtuk:
for (i=Nom_1; i<=Nom_2; i++) // Cycle operator header
{ // Brace opening the cycle body
Sum = Sum + i; // Sum is accumulated
Alert("i=",i," Sum=",Sum); // Display on the screen
} // Brace closing the cycle body
Lent egy olyan példa látható, ahol ugyanazt a kódrészletet látjuk a 'while' operátor alkalmazásával:
i=Nom_1; // Оператор присваивания
while (i<=Nom_2) // Cycle operator header
{ // Brace opening the cycle body
Sum = Sum + i; // Sum is accumulated
Alert("i=",i," Sum=",Sum); // Display on the screen
i++; // Increment of the element number
} // Brace closing the cycle body
Láthatjuk, hogy az 1.Kifejezés a ciklusoperátort megelőző sorba került, míg a 2.Kifejezés bekerült a ciklustörzsbe. Meg tudod változtatni a példa programot magad is. Indítsd el és futtasd, hogy lásd, az eredménye ugyanaz mindkét verziónak.