Üdvözlök mindenkit, szeretném leírni nektek a ciklusok használatát ebben a kis leírásban.
Ciklust akkor használunk, ha ugyanazt a feladatot többször kell elvégezni egymás után.
Háromféle ciklus létezik. Ezeket egyenként fogom bemutatni példákkal.
2 nagyobb fajta ciklus van : elöltesztelõs (for,while) és hátultesztelõs (do-while) ciklus.
A program az elöltesztelõs ciklusba csak akkor lép be, ha a feltétel teljesül. A feltétel a ciklus elején található.
A hátultesztelõs ciklus használatakor a program mindenképpen belép a programba és mindaddig ismétli, amíg a feltétel teljesül.
A for ciklus
Ez a legegyszerûbb és a leggyakrabban használt ciklus,és szerintem ezt mindenkinek ismernie kell.
Ez egy elöltesztelõs ciklus.
Nézzük a ciklus felépítését.
for(ciklusváltozó;ciklusfeltétel;posztfix) //vagy prefix
i++ = posztfix
++i = prefix
Különbség: ebben a konkrét példában( for ciklus ) ugyan nincs, de a prefixes alak használatánál a léptetés mûvelet feldolgozása elõtt lejátszódik, így a változó már az új értékkel vesz részt a folyamatban.
new x, y = 5;
x = ++y;
//Az x, és az y értéke is 6 lesz
new x, y = 5;
x = y++;
//Az x értéke 5, az y értéke 6 lesz
//Észrevételt köszönöm Fade-nak,szép megfogalmazást ZeRo-nak.
Példa:
for(new i = 0;i < 10;i++) // Vagy ++i
{
//Ez a ciklustörzs,ide jönnek a feladatok.
printf(\"Az i értéke %d\",i); // A printf függvényel írunk a konzolba.
}
Ez egy nagyon egyszerû kis kód,ami azt eredményezné,hogy addig írjuk ki az i változót a konzolba,ameddig annak értéke kisebb mint 10.Tehát,a ciklus addig fut le amíg a változónk értéke kisebb mint 10.
Mindig azok az utasítások hajtódnak végre,amik a ciklustörzsben vannak.
Ez akkor hasznos a gyakorlatban,hogyha pl. végig akarunk menni az összes játékoson,akik a szerveren tartózkodnak.NEM csak erre lehet használni!
/* Érdekesség:
Egyes paraméterek elhagyhatók,de a pontosvesszõt ( ; ) mindig ki kell rakni!
Példa:
for(;ciklusfeltétel;értékváltoztatás)
Itt elhagyjuk a ciklusváltozót,a ciklus viszont így is mûködik!
*/
Példa a gyakorlatra:
for(new i = 0;i < GetMaxPlayers();i++)
{
SpawnPlayer(i); // Újraspawnoljuk az i-azonosítójú játékost.
}
Ez a példa a gyakorlatban lespawnolja a összes játékost.
Magyarázat:
GetMaxPlayers(); //Ezzel a függvénnyel lekérjük a szerver maximum férõhelyét.Nem vesz fel paramétert.
SpawnPlayer(playerid); //Ezzel a függvénnyel újra lespawnolhatunk egy játékost.Egyetlen paramétere a játékos azonosítója.
A többi szerintem érthetõ,amíg az i értéke kisebb mint GetMaxPlayers(); visszatérési értéke (Pl. 30,vagy 50 stb...),Addig 1 el növeljük és végrehajtjuk a feladatokat,amelyeket a ciklustörzsbe írtunk.Magyarul ha van egy 30 férõhelyes szerverünk,akkor ez a ciklus végigmegy mind a 30-játékoson,és újraspawnolja õket.A ciklus viszont mindenképp lefut 30-szor, akkor is ha az adott azonosítójú játékos nincs csatlakozva.Ezt könnyen megelõzhetjük.
for(new i = 0;i < GetMaxPlayers();i++)
{
// Spawn elõtt ellenõrizzük,hogy a játékos csatlakozva van-e.
if(IsPlayerConnected(i)) SpawnPlayer(i);
}
Így a SpawnPlayer függvény nem fut le ha a játékos nincs csatlakozva.
A while ciklus
Ez a ciklus nagyon hasonlít a feltételes utasításhoz (if).
Ez egy elöltesztelõs ciklus.
if(feltétel)
while(feltétel)
Legalábbis a szerkezete,ugyanis a feltételes utasítás nem fut le ha a feltétel nem teljesül.
A while ciklus ponthogy fut mindaddig,amíg a feltétel teljesül.
Példa:
new i = 0;
while(i != 10) printf(\"i értéke: %d\",i);
Tehát,amíg az i értéke nem 10,addig lefut a ciklus.Talán egyeseknek feltûnhetett valami,még pedig az, hogy ez a ciklus hibás. Mivel ez egy végtelen ciklus!Magyarázat:Nem módosítjuk megfelelõ módon az i értékét,tehát soha nem lesz az értéke 10!
A for ciklusban ez automatikus,itt magunknak kell figyelnünk rá!
new i = 0;
while(i != 10) printf(\"i étéke: %d\",i),i++;
Na ez a ciklus a céljának megfelelõen mûködik,lefut 10 szer.
Összefoglalva,ez a ciklus addig fut le amíg a feltétel teljesül.
Gyakorlatban,mondjuk fájlok olvasásánál használjuk,de ezzel is megoldható a for ciklusnál használt kis spawn kód.
new i = 0;
while(i != GetMaxPlayers())
{
if(IsPlayerConnected(i)) SpawnPlayer(i);
i++;
}
A do-while ciklus
Ez a ciklus ugyanúgy mûködik mint a while ciklus,annyi különbséggel,hogy az itt leírt utasítások
egyszer mindenképp lefutnak, ha teljesül a feltétel,ha nem.
Ez egy hátultesztelõs ciklus.
Szerkezet:
new i = 1;
do
{
printf(\"i értéke %d\",i);
} while(i != 1)
Ez egy egyszerû példa,létrehozunk egy i változót melynek kezdõértéke 1.
Lefut a ciklus,majd ellenõrizzük hogy az i egyenlõ e 1-el.Ha nem,a ciklus újra lefut,amíg a feltétel teljesül.
Ha igen,a ciklus véget is ért.
A feltétel már teljesült,a ciklus mégis lefutott egyszer.
//A gyakorlatban ne felejtsük el megváltoztatni a megfelelõ módon az i-értékét,vagy végtelen ciklust kapunk.
Nézzük csak a spawnolós kódunkat.
new i = 0;
do
{
if(IsPlayerConnected(i)) SpawnPlayer(i);
i++;
} while(i != GetMaxPlayers())
Utószó
Egyenlõre ennyit a ciklusokról,ha valamit elírtam/nem jól fogalmaztam,hibáztam stb.
Akkor kérlek jelezzétek a témában.
Ha eszembe jut még valami a ciklusokról,akkor az tis hozzáírom a leíráshoz.
Próbáltam egyszerûen leírni,hogy a kezdõk is teljesen megértsék.
Szerintem tökéletes leírás lett. ;)
Annyit még hozzáírnék, hogy a ciklusoknak két nagyobb fajtája van, az elöltesztelõ ciklusok( for, while ), és a hátultesztelõ( do-while ), de egyébként szép leírás.
Annyit még hozzáírnék, hogy a ciklusoknak két nagyobb fajtája van, az elöltesztelõ ciklusok( for, while ), és a hátultesztelõ( do-while ), de egyébként szép leírás.
Tudtam hogy kifelejtettem valamit,hozzáírom és kösz hogy szoltál.
Ja és köszönöm a dicséreteket.
Szerk: Leírás kiegészítve. (Magyarázat hozzáadva az elejéhez.)
Szerk2:Apró hiba javítva a while ciklusnál.
Ez sokat segített szép leírás :)
ez télleg tuti :) még énis megértettem :P thx
Ez sokat segített szép leírás :)
ez télleg tuti :) még énis megértettem :P thx
[/quote]
Köszönöm.
Kezdõk megértik szerintem
Amúgy
for(ciklusváltozó;ciklusfeltétel;értékváltoztatás)[/quote]
Inkább:
for(ciklusváltozó;ciklusfeltétel;posztfix) // vagy prefix
i++ = posztfix
++i = prefix
Kezdõk megértik szerintem
Amúgy
for(ciklusváltozó;ciklusfeltétel;értékváltoztatás)
Inkább:
for(ciklusváltozó;ciklusfeltétel;posztfix) // vagy prefix
i++ = posztfix
++i = prefix
[/quote]
Szép leírás grat, majd a while-s-nek hasznát veszem.
Lenne egy kérdésem. A poszfix meg a prefix között mi a külömbség ?
Semmi.
Kezdõk megértik szerintem
Amúgy
for(ciklusváltozó;ciklusfeltétel;értékváltoztatás)
Inkább:
for(ciklusváltozó;ciklusfeltétel;posztfix) // vagy prefix
i++ = posztfix
++i = prefix
[/quote]
Ezt nem írtam bele mert meg akartam magyarázni csak itt megingtam,nem vagyok biztos benne hogy jól tudom,és nem akartam hülyeséget írni...
Ha írsz nekem egy magyarázatot ,hogy mi a különbség a 2 közt,akkor beleírom de a saját baromságomat inkább nem,mert egy leírásba nemakarok esetleg téves dolgot írni.
Semmi.
De van, ebben a konkrét példában( for ciklus ) ugyan nincs, de a prefixes alak használatánál a léptetés mûvelet feldolgozása elõtt lejátszódik, így a változó már az új értékkel vesz részt a folyamatban.
new x, y = 5;
x = ++y;
//Az x, és az y értéke is 6 lesz
new x, y = 5;
x = y++;
//Az x értéke 5, az y értéke 6 lesz
Mégis jól tudtam,csak én nem tudtam volna ijen szépen megfogalmazni.
Átis írom.
Szép tut, grat.
Amit Fade javasolt, azon még lehetne picit csiszolni.
for(ciklusváltozó; ciklusfeltétel; léptetés)
Nagyon szépen összeírtad, grat!
Ez jó szint így van például a c++ nyelvcsaládban is , elõltesztelõs ,stb :)!
Szép tut ,Grat!
Köszönöm a dicséreteket,és Popec,igen így van C++-ban is . :D
(Nagyából...)
Szép, remek, ügyes kis leírás, nagyon hasznos a kezdõknek!
Prototype
Az a baj hogy szerintem a fele fórumnak fogalma sincs hogy mi az a \"ciklus\" !
/Nem lenézésbõl írtam , és ne vegye magára senki/
szerintem azért lett itt elmagyarázva nem?
Ciklus = Ismétlõdõ jelenség,
de szerintem a leírásból kiderül,hogy mire is való,azért hozzáírom és kösz az észrevételt. :)
Edit: Uh most látom,hogy mégs benne volt már kicsit máskép megfogalmazva:
Ciklust akkor használunk, ha ugyanazt a feladatot többször kell elvégezni egymás után. [/quote]
BUMP!
Tudnál írni a do-while-s ciklusra egy konkrét példát, ahol jobb a használata, mint a többinek ?
Mert nemtom eldönteni, hogy hol jobb az. Mivel a végeredmény \"ugyanaz\".
Nem ugyan az.
A do-while ciklus akkor jó,ha egy eseményt úgy akarunk ismételni,hogy egyszer mindenképpen lefusson.
Szóval:
new i = 1;
do
{
i++;
} while(i >= 1)
Így az i értéke már egy,de a ciklus egyszer mégis lefut,mert hátul teszteli a feltételt,így az i értéke 2 lesz.
Még egyszer tömören: Ha azt akarjuk,hogy a ciklus legalább egyszer mindenképpen lefusson,akkor is ha a feltétel már teljesült.
Ha így használtuk volna:
new i = 1;
do
{
i++;
} while(i != 1)
Akkor végtelen ciklust kapnánk,mert 2bõl soha nem lesz 1 ha csak növeljük a változót.
Elolvastam a leírást nekem tetszik. Mondjuk a while ciklus kicsit fölösleges szerintem a SAMP ba. Ha kicsif ifezünk és for ciklust használunk akkor gyorsabb lesz a módunk, de a megírási idõ is kicsit növekszik. De mondjuk ez ember és szerverfüggõ.
Elolvastam a leírást nekem tetszik. Mondjuk a while ciklus kicsit fölösleges szerintem a SAMP ba. Ha kicsif ifezünk és for ciklust használunk akkor gyorsabb lesz a módunk, de a megírási idõ is kicsit növekszik. De mondjuk ez ember és szerverfüggõ.
while ciklus nélkül pl. hogy olvasnál fájlt?
Elolvastam a leírást nekem tetszik. Mondjuk a while ciklus kicsit fölösleges szerintem a SAMP ba. Ha kicsif ifezünk és for ciklust használunk akkor gyorsabb lesz a módunk, de a megírási idõ is kicsit növekszik. De mondjuk ez ember és szerverfüggõ.
while ciklus nélkül pl. hogy olvasnál fájlt?
[/quote]
Ezt elismerem ebbe nálad a pont. De azon kívül nincs más nagy haszna (szerintem).
De van, nagyon is. Az ilyen helyekre jobb, mint a for.
While = Ameddig.
pl:
while(fread(...))
while(mysql_fetch_row(...))
Úgy látszik vita téma lesz ebbõl. Én még kitartok a magam igaza mellett de a vita rontja a közösség értékét tehát abbahagyom.
Vita = Érvelés,ellenérvelés
A veszekedés tiltott,az érvelés nem :)
Különben,while ciklus nélkül te hogy írnál regisztrációs rendszert?A for ciklussal számolgatnád a sorokat? :D
Vagy pl ezt old meg más mijen ciklussal:
new v = 100;
while(v != 50)
{
v--;
}
Ezt úgy kéne elképzelni,hogy a változónak nem ismerjük az értékét de le akarjuk csökkenteni 50 re,így készülnek az In-Game creator cucok,banda zóna létrehozók meg a textdraw makerek is. stb...
Szép, ahogy olvastam.. Csak szemet szúr a sok írási hiba.
Szép, ahogy olvastam.. Csak szemet szúr a sok írási hiba.
Köszi,de már elég rég írtam,szóval majd átnézem. :shy:
Ne fáradozz Chuck, a nagy részét már átírtam. Amúgy jó leírás, régen innen tanultam meg.
Ne fáradozz Chuck, a nagy részét már átírtam. Amúgy jó leírás, régen innen tanultam meg.
:heart:
Köszi :)
Tökéletes leírás :D Szép munka és grat :amazed: Tanultam belõle :shy:
Tökéletes leírás :D Szép munka és grat :amazed: Tanultam belõle :shy:
Köszönöm :)
Hát nekem ez kicsit magas, de kezdem kapisgálni :D
for(new allplayers = 0; allplayers < MAX_PLAYERS; allplayers++)
{
SendClientMessage(allplayers, céklakek, \"Ezt most elküldem az összes játékosnak\");
}
Ezt most fejbõl irtam, hibás?
Meg mit jelent a ++?
Hozzáad az elõzõ értékhez 1et
Vagy: allplayers = allplayers + 1 :D
Írhatnál példát egy végtelen ciklusra is.
while(1) { }
Írhatnál példát egy végtelen ciklusra is.
while(1) { }
Nem pont így,de említettem hogyha nem növeljük az értéket a while ciklusnál végtelen ciklust kapunk :)
Írhatnál példát egy végtelen ciklusra is.
while(1) { }
Nem pont így,de említettem hogyha nem növeljük az értéket a while ciklusnál végtelen ciklust kapunk :)
[/quote]
Elnézést, ez felett elsíklott a figyelmem, Ismét gratulálok a leíráshoz.
Írhatnál példát egy végtelen ciklusra is.
while(1) { }
Nem pont így,de említettem hogyha nem növeljük az értéket a while ciklusnál végtelen ciklust kapunk :)
[/quote]
Elnézést, ez felett elsíklott a figyelmem, Ismét gratulálok a leíráshoz.
[/quote]
Np,emberbõl vagyunk,és köszi ismét ;)
Én még azt nem értem, hogy mért mindenki ( Egypáran nem, de sokan ) a ciklus alatt hozzák létre az új változót ?
Ez szerintem elég nagy hülyeség, mert feleslegesen foglal le ( Pl ) 500-szor memóriát és szabadít fel. Feleslegesen lassít.
Én mindig létrehozom a ciklus felett, aztán a ciklusban csak nullázom. Szerintem ez sokkal jobb, és gyorsabb is.
Az szerintem betudható akár hibának is,mivel leterheli a memóriát teljesen feleslegesen.
Szóval én is mindenkinek kurta módszerét ajánlom. A kezdõknek le is írom:
Rossz módszer:
for(new i;i<500;i++)
{
new a,b,c,d;
GetPlayerHealth(i,a);
GetPlayerArmour(i,b);
//stbstb
}
Jó módszer:
new a,b,c,d;
for(new i;i<500;i++)
{
GetPlayerHealth(i,a);
GetPlayerArmour(i,b);
//stbstb
}
Meg egy másik témában (Fade alternatív ciklusával) Zsolesszka írta, hogy a ciklusok gyorsabbak ha a ciklusban növeljük az értéket.Pl:
new player=0;
for( ; player++ != MAX_PLAYERS; ) SetPlayerHealth(player,0);
Elvileg gyorsabban lefut,persze ezt még mindig lehet variálni:
new player=0,max = GetMaxPlayers();
for( ; player++ != max ; ) SetPlayerHealth(player,0);
És itt még nem ellenörzöm le hogy a játékos ID csatlakozva van-e... Szeretem a ciklusokat mert lehet õket variálni ;)
Jó módszer:
new a,b,c,d;
for(new i;i<500;i++)
{
GetPlayerHealth(i,a);
GetPlayerArmour(i,b);
//stbstb
}
ez nem inkább[pawn] for(new i = 0; i < 500; i++)[/pawn]? vagy ennek nincs jelentõsége?
Teljesen mindegy,mivel a változó alap értéke 0 lesz ha létrehozod,felesleges beállítani neki :)
Akár ezt is lehet csinálni:
[pawn]
new a,b,c,d,i;
for(;i<500;i++)
{
GetPlayerHealth(i,a);
GetPlayerArmour(i,b);
//stbstb
}
[/pawn]
Teljesen mindegy,mivel a változó alap értéke 0 lesz ha létrehozod,felesleges beállítani neki :)
Akár ezt is lehet csinálni:
[pawn]
new a,b,c,d,i;
for(;i<500;i++)
{
GetPlayerHealth(i,a);
GetPlayerArmour(i,b);
//stbstb
}
[/pawn]
Rendben, köszi a magyarázatot :)
Ez viszont érdekes. Lehet, hogy lassú a sok memória szabaddá tétel/lefoglalás, de viszont nagyobb stringeknél meg kell gondolni, hogy a CPU vagy a RAM? Bár ez csak az igénytelenül megírt scripteknél baj.
new player=0;
for( ; player++ != MAX_PLAYERS; ) SetPlayerHealth(player,0);
Végig olvastam és többet tudok mint elõtte, de ezt nem tudom felfogni. Mi a feltétel? Mikor állítja be a játékos életét 0 ra?
new player=0;
for( ; player++ != MAX_PLAYERS; ) SetPlayerHealth(player,0);
Végig olvastam és többet tudok mint elõtte, de ezt nem tudom felfogni. Mi a feltétel? Mikor állítja be a játékos életét 0 ra?
A ciklus középsõ része. Szóval ez:
player++ != MAX_PLAYERS
Képzeld el így:
if(player++ != MAX_PLAYERS)
Természetesen ez nem helyes,csak példaképpen.
A feltétel lemagyarosítva itt az,hogy a játékos id nem egyenlõ-e a MAY_PLAYERS definícióval.Ez alapból definiálva van és az értéke 500. Tehát a feltétel az,hogy amíg player változó nem egyenlõ 500-al. A ++ mûveleti jelek megnövelik a változó értékét minden mûvelet végén. Tehát minden játékos id-jén keresztül megy a folyamat. Ez kicsit pazarló,MAX_PLAYERS helyett én inkább így használnám:
new player=0,maxplayers=GetMaxPlayers();
for( ; player++ != maxplayers; ) SetPlayerHealth(player,0);