Tömbök, Stringek, Többdimenziós tömbökTömbökA tömb azonos típusú adatok halmaza, amelyek a memóriában folytonosan helyezkednek el. A tömb elemeire a tömb nevével és az indexelő operátorral ([]) hivatkozhatunk.
A tömböket nullától indexeljük. A fordító nem ellenőrzi a tömbindexeket, ezért hibás indexeléssel is lefordul a program, de futás közben ez több problémát is okozhat. Egyrészt felülírhatjuk a memóriában előtte vagy utána lévő adatainkat, másrészt akár olyan memóriaterületre próbálhatunk meg írni (vagy onnan olvasni), amely nem a pluginhoz tartozik, ekkor az AMX Mod X megszakítja a plugin futását és ezt az error logba jelzi.
Kód:
// Player tömb létrehozása, 32 tömbelemmel
new Players[32]
// Most már van egy 32 elemu tömbünk, az elemeire 0-ról n-1-ig (jelen esetben 0-tól 31-ig) hivatkozhatunk.
// Tehát minden tömb elso eleme a 0. indexű elem.
// 0. indexű elemet 5re állítjuk.
Players[0] = 5
// Az 1. indexű elembe belepakoljuk a 0. indexű elemet.
Players[1] = Players[0]
// Példa hibás indexelésekre:
// Egy 32 elemű tömb első eleme a 0. utolsó a 31.
// Ez a kód nem fordul le, már fordítási időben hibát dob, mivel fix az értéke.
Players[32] = 15
// Ez a kód lefordul, de futási idoben hibát dob. Eredménye: AMX Native Error 4 - AMX_ERR_BOUNDS
new A=33
Players[A] = 15
// Ez abszolút hibás
Players[-1] = 6
// Változót nem adhatunk meg csak úgy egy tömb deklarálásakor, mivel nem lehet meghatározni a méretét. Ha a változó konstans, vagy fordítási direktíva a mérete, akkor gond nélkül lefordul, mivel előre meghatározott értéket vehet fel. (Előbbi esetben futási időben, utóbbi esetben a fordító illeszti bele az értéket a fordítandó kódba)
// Ez se nem konstans, se nem #DEFINE => Fordítási hiba
new a = 3
new BadArray[a]
// Ez egy jó, lefordítható kód.
new const b = 3
new GoodArray[b]
// Fordítási direktívával (lásd később)
Kód:
#define ARRAY_SIZE 3
new Array[ARRAY_SIZE]
Lehetőség van a tömb feltöltésére a deklarálás mellett. Az alábbi példa demonstrálja, miként tehetjük meg ezt:
Kód:
new Numbers[4] = {0,1,2,3}
// Megjegyzés: Ekkor pont annyi elemet kell megadni, ahány elemű a tömbünk.
Természetesen Float és Boolean típusú tömb is létrehozható, értékadással megspékelve
Kód:
// Float tömb:
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}
// Boolean tömb
new bool:playerHasGun[33] = {true, ...}
// Megjegyzés: A Boolean tömb ekként való definiálása estén nem kell kiírni az összes true értéket, ugyanis ekkor az össze elem true lesz.
StringekÉszrevehetted, hogy a legfontosabb adattípus kihagytam: a karakterek. A Pawn nyelvben a karaktereket a számok reprezentálják, míg a stringeket a karakterek tömbje.
Példák:
Kód:
// Létrehozunk egy "myString" nevu számtömböt ami a "Hello" karaktersorozatot fogja tárolni.
// 6 eleme lesz a tömbnek, ebből 5 a karaktereknek van fenntartva.
// Az utolsó tömbelem a 0 értéket veszi fel, ami jelzi a Pawn motorjának, hogy ez a tömb egy stringet tartalmaz.
// Ebben az esetben nem kell kitenni a deklarációkor a tömb méretet, mivel maga a karaktersorozat fogja meghatérozni a tömbméretet.
new myString[] = "Hello"
A most következő kód ugyanazt fogja csinálni, mint az előző. Hosszabb, és a több véthető hibalehetőség miatt nem ajánlott.
Kód:
new myString[6]
myString[0] = 'H'
myString[1] = 'e'
myString[2] = 'l'
myString[3] = 'l'
myString[4] = 'o'
myString[5] = 0
// Megjegyzés: mint írtam, az utolsó 0 jelzi, hogy a tömb egy stringet tartalmaz. Ha nem tennénk ki, nem lehetne stringként használni.
Az alábbi sorok kerülendők, mivel lehet, hogy lefordulnak, de futási időben könnyen túlcsordulási hibákat okozhatnak
Kód:
new myString[6]
myString = "Hello" // INVALID!
myString[0] = "Hello" // INVALID!
// Egy stringnek szánt tömbe adatot az alábbi módon rakhatunk:
new goodString[7]
copy(goodString, 6, "Hello")
// Megjegyzés:Itt 6 hosszú stringet pakolunk be a tömbbe. Figyeljünk arra, hogy 7 byte másolása esetén a copy függvén képes egy extra byteot másolni a tömbbe a null karakter miatt, ami túlcsordulást okozhat.
További példák:
Kód:
// A copy egy függvény, ami 3 paraméterből áll:
copy(destination[], length, source[])
// a source tömbből legfeljebb length hosszú stringet másol a destination tömbbe
// Végül megmutatom, miként reprezentálják a számok a karaktereket:
new metal[6]
metal[0] = 77
metal[1] = 69
metal[2] = 84
metal[3] = 65
metal[4] = 76
metal[5] = 0
// Ez a metal tömbbe beállítja a "METAL" stringet
Többdimenziós tömbökA Pawn lehetőséget nyújt többdimenziós tömbök létrehozására. A titok annyi, hogy több [x] literálokat pakolunk a tömbünkhöz, s így egy n dimenziós tömböt kaphatunk. A most következő sorok taglalják ennek előnyeit és működését, a példákat kétdimenziós tömbbel mutatom be
Kétdimenziós tömbÁltalában ilyen típusú tömböket használunk, ugyanis ezzel reprezentálhatunk egy táblázatot, ahol az első "dimenzió" határozza meg a sort, míg a második az oszlopot. (Szokás nxm es Mátrixnak is nevezni)
Kód:
// Ez deklarál egy 50 sorból és 50 oszlopból álló táblát (aka kétdimenziós tömb)
new BigArray[50][50]
// Float típusú tömb, 25 sorral és 10 oszloppal
new Float:BigArray[25][10]
Példa egy 3x3as Mátrixra
Kód:
new BigArray[3][3]
BigArray[0][0] = 10
BigArray[0][1] = 20
BigArray[0][2] = 30
BigArray[1][0] = 40
BigArray[1][1] = 50
BigArray[1][2] = 60
BigArray[2][0] = 70
BigArray[2][1] = 80
BigArray[2][2] = 90
// Így képzelhető el a változónk tartalma:
0 1 2
0 10 20 30
1 40 50 60
2 70 80 90
Fontos megjegyezni, hogy néhány egydimenziós tömbökre implementál függvény nem működik a többdimenziós tömbökre.
Kód:
// Például ilyen a sum_of_array() függvény, ami visszaadja az első n elem összegét.
new sum = sum_of_array(BigArray, 9) // INVALID
// Igy használható, de ekkor csak egy részét summázva:
new sum = sum_of_array(BigArray[2], 3)
Ekkor a BigArray[2] tartalmazza a 2. egydimenziós tömbünket {7,8,9}. Természetesen van arra lehetőség, hogy saját függvényt implementáljunk a kétdimenziós tömbökre.
Például:
Kód:
sum_of_table(array[][], rows, cols)
{
new i, j, sum
// Egymásba ágyazott for ciklusok segítenek abban, hogy végigiteráljunk a tömb elemein
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
sum += array[i][j]
}
}
return sum
}
Kétdimenziós tömbben is lehetséges a stringek tárolása:
Kód:
new StringList[3][] = {"Hello", "my", "friend"}
/*
StringList [0][0]-tól [0][5]-ig tartalmazza a "Hello" stringet
StringList [1][0]-tól [1][2]-ig tartalmazza "my" stringet
StringList [2][0]-tól [2][6]-ig tartalmazza "friend" stringet
*/
Ekkor a StringList az alábbi adatot tartalmazza: 0 1 2 3 4 5 6 0 H e l l o \0 1 m y \0 2 f r i e n d \0
Adatok összehasonlítása hasonlóan működik, mint az egydimenziós társaiknál.
Kód:
if (StringList[0] == "Hello") //INVALID
if (StringList[0][0] == "Hello") //INVALID
if (equali(StringList[0], "Hello")) //Valid
Updated: 2012.02.13