Szerző Téma: [Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)  (Megtekintve 3610 alkalommal)

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
+3
Eredeti témát Slice írta a hivatalos fórumon.
A további napok folyamán frissíteni fogom, mert még nincs benne minden, de a fõ rész az benne van.
Fordítási hibák szerintem lehetnek, ezért elnézést!
Több dolog egy statmentben
Néhány helyen szükségünk van arra, hogy egy sorba több dolgot is lefuttassunk.
Visszatérni több értékkel, stb. Ha visszatértsz több értékkel, akkor a return mindig az utolsó értékét fogja visszaadni.
Ezt a következõ képpen tudjuk elvégezni:
[pawn]
stock KickEx( playerid, reason[ ] )
    SendClientMessage( playerid, 0xC00000FF, \"Kickelve lettél!! Indok:\" ), SendClientMessage( playerid, 0xC00000FF, reason ), Kick( playerid );
// Két üzenet elküldése, azátn a játékos kirúgása
stock DoStuff( playerid )
    return DoFirstThing( playerid ), DoSecondThing( playerid ), DoThirdThing( playerid ), DoLastThing( playerid );
// DoStuff a DoLastThing értékével fog visszzatérni
public OnPlayerRequestSpawn( playerid )
{
    if ( !IsPlayerLoggedIn( playerid ) )
        return SendClientMessage( playerid, 0xC00000FF, \"Nem vagy bejelentkezve!\" ), 0;
    // Elküldjük az üzenetet és 0-val térünk vissza.
    return 1;
}
[/pawn]
Egyszerû szám -> bool-ra konvertálása
Néha vannak olyan helyzetek, hogy bool-ra kell konvertálni egy megadott számot.
Ezt a következõ képpen teheted meg a legegyszerûbben:
[pawn]
new myInt = 50;
new bool:myBool = !!myInt;
[/pawn]
Vagy akár mûködik egy funkcióval is:
[pawn]
new
    bool:bResult = !!mysql_query_ex(query),
    iCount;
if(!bResult) return SendClientMessage(playerid, COLOR_RED, \"HIBA: Hibás lekérdezés!\");
[/pawn]
De így is:
[pawn]
#define IsValidVehicle(%1) \\
(!!GetVehicleModel(%1))
[/pawn]


Változó tag figyelmeztetés kiküszöbölése
Ha egy elõtagos funckiónak/változónak akarod az értékét kiírni egy olyan funkcióban, ami nem támogatja azt a tagot, akkor a fordító figyelmeztetni fog, hogy itt valami nincs rendben. Itt nem csináltunk semmit se rosszul, csak ez így nem helyes.
Ilyen esetben kell letörölni a tagot a funkció elõl, és minden jól fog mûködni!
Példa:
[pawn]
new Text3D:t3dTest = Create3DTextLabel( .. ), Text:txTest = TextDrawCreate( .. );
printf( \"DEBUG: %d, %d\", _:t3dTest, _:txTest );
[/pawn]
Egyébként ez a dolog szerintem nagyon is hasznos, fõleg a bit flagoknál.
Vegyük azt, hogy van két változónk, két enum taggal. Ha az elsõ váltózónál valamit próbálunk állítani a második enumból, akkor figyelmeztetni fog, mivel az a másodikhoz tartozik és nem pedig az elsõhöz. Persze ha lehagyjuk a tagokat, akkor nemfog. De ilyenkor a bit flagnál nagy keveredések lehetnek, ezért érdemes ott az elõtagokat használni.


\"Char-tömbök\"
PAWN-ban van egy olyan lehetõség, hogy minden cellának egy bájtot foglal le. Ez a csomagolt string. A legtobb SA-MP függvények sajnos nem támogatják ezt és nagyon sokan még nem is hallottak róla. Egy 4bájtos tömbnek az értékei -2,147,483,648 és 2,147,483,647 között lehetnek.
De ha neked nincs szükséged negatív értékekre és a megadott érték kisebb, mint 255, akkor miért is ne spóroljunk memóriát?
Csomagolt stringekkel 0 és 255 között tárolhatunk számokat. ( Nincsenek negatív számok )
Itt is van róla egy példa:
[pawn]
new bool:g_IsPlayerSomething[MAX_PLAYERS]; // 500 cella * 4 bájt cellánként = 2000 bájt! <4 bájtos tömb>
new bool:g_IsPlayerSomething[MAX_PLAYERS char]; // 500 bájt = .. 500 bytes! <Csomagolt string, itt egy cella egy bájt>
[/pawn]
Ha ezt a megoldást használod 50x a normál 4 bájtos tömbök helyett, akkor megspórolsz 75,000 bájtot (~73 kb).
Vigyázz!
Ezekhez a tömbökhöz kapcsos zárójeleket ( { } ) kell használnod a szögletes helyett. ( [ ] ),
Példa:
[pawn]
public OnPlayerConnect( playerid )
{
    g_IsPlayerSomething{ playerid } = false;
//                     ^          ^
}
public OnPlayerSpawn( playerid )
{
//                          v          v
    if ( g_IsPlayerSomething{ playerid } )
    {
        // ..
    }
}
[/pawn]


Bitmûveletek (Bit-flag)
Tudtad, hogy lehet 32 igaz/hamis értéket tárolni egy változóban?  Ezzel nem csak memóriát takarítasz meg, hanem sokkal átláthatóbb lesz a kód.
Ehhez egyáltalán nem kell megértened, hogy hogyan mûködik a kettes számrendszer, de ajánlott.
Ha van 100 hamis/igaz (bool) változód játékosonként, akkor az 195KB memóriát foglal. Bár, ha 4 tömböt használsz ezzel a megoldással, akkor csak 8KB-ot fog használni. Az eredmény ugyanaz lesz, mintha rendes bool tömbökkel csinálnád, csak megspóroltál 187KB-ot.
 

// BitFlag Makrók
#define BitFlag_Get(%0,%1)            ((%0) & (%1))   // Megnézzük, hogy a flag be-e van kapcsolva. Ha igen, akkor visszatér az értékével*, ha nem, akkor 0-val tér vissza.
#define BitFlag_On(%0,%1)             ((%0) |= (%1))  // Bekapcsoljuk a flagot
#define BitFlag_Off(%0,%1)            ((%0) &= ~(%1)) // Kikapcsoljuk a flagot.
#define BitFlag_Toggle(%0,%1)         ((%0) ^= (%1))  // Kicseréljük a flag értékét. Ha igaz volt, akkor hamis lesz, ha hamis, akkor igaz.
// * A flag értéke nem 1 lesz, hanem az, ami itt ez enumban van.
// Ha PLAYER_BLABLA_3-t beállítottuk neki, akkor g_PlayerFlags[playerid] & PLAYER_BLABLA_3 értéke 00000000000000000000000000100000 (32) lesz.
enum PlayerFlags:(<<= 1) // Ez itt azt jelenti, hogy mennyivel növekedjenek az értékek az enum-ban {
    // Ügyelj arra, hogy ezt (<<<=1) semmi képp ne felejtsd el, külömben minden flagod hamis lesz.
// Az kezdõ érték az enum-ban 1 és ezt eltoja mindig eggyel alrébb balra.
// A következõ képpen fognak mindig növekedni:
    PLAYER_IS_LOGGED_IN = 1,   // 0b00000000000000000000000000000001 | 1
    PLAYER_HAS_GANG,           // 0b00000000000000000000000000000010 | 2
    PLAYER_CAN_BUY_PROPERTIES, // 0b00000000000000000000000000000100 | 4
    PLAYER_BLABLA_1,           // 0b00000000000000000000000000001000 | 8
    PLAYER_BLABLA_2,           // 0b00000000000000000000000000010000 | 16
    PLAYER_BLABLA_3,           // 0b00000000000000000000000000100000 | 32
    PLAYER_BLABLA_4,           // 0b00000000000000000000000001000000 | 64
    PLAYER_BLABLA_5,           // 0b00000000000000000000000010000000 | 128
    PLAYER_BLABLA_6,           // 0b00000000000000000000000100000000 | 256
    PLAYER_BLABLA_7,           // 0b00000000000000000000001000000000 | 512
    PLAYER_BLABLA_8,           // 0b00000000000000000000010000000000 | 1024
    PLAYER_BLABLA_9,           // 0b00000000000000000000100000000000 | 2048
    PLAYER_BLABLA_10,          // 0b00000000000000000001000000000000 | 4096
    PLAYER_BLABLA_11,          // 0b00000000000000000010000000000000 | 8192
    PLAYER_BLABLA_12,          // 0b00000000000000000100000000000000 | stb..
    PLAYER_BLABLA_13,          // 0b00000000000000001000000000000000
    PLAYER_BLABLA_14,          // 0b00000000000000010000000000000000
    PLAYER_BLABLA_15,          // 0b00000000000000100000000000000000
    PLAYER_BLABLA_16,          // 0b00000000000001000000000000000000
    PLAYER_BLABLA_17,          // 0b00000000000010000000000000000000
    PLAYER_BLABLA_18,          // 0b00000000000100000000000000000000
    PLAYER_BLABLA_19,          // 0b00000000001000000000000000000000
    PLAYER_BLABLA_20,          // 0b00000000010000000000000000000000
    PLAYER_BLABLA_21,          // 0b00000000100000000000000000000000
    PLAYER_BLABLA_22           // 0b00000001000000000000000000000000
};
new
    // Létrehozink egy tömböt ugyanazzal a taggal, mint ami az enum.
    PlayerFlags:g_PlayerFlags[MAX_PLAYERS]
;
public OnPlayerConnect(playerid) {
    // 0 - Minden flag kikapcsolva (hamis). A PlayerFlags tag kell, miven nélküle warningozni fog a fordító.
    g_PlayerFlags[playerid] = PlayerFlags:0;
}
public OnPlayerLogIn(playerid) {
    BitFlag_On(g_PlayerFlags[playerid], PLAYER_IS_LOGGED_IN);
//  Makró nélkül:
//  g_PlayerFlags[playerid] |= PLAYER_IS_LOGGED_IN;
}
public OnPlayerJoinGang(playerid) {
    BitFlag_On(g_PlayerFlags[playerid], PLAYER_HAS_GANG);
//  Makró nélkül:
//  g_PlayerFlags[playerid] |= PLAYER_HAS_GANG;
}
public OnPlayerLeaveGang(playerid) {
    BitFlag_Off(g_PlayerFlags[playerid], PLAYER_HAS_GANG);
//  Makró nélkül:
//  g_PlayerFlags[playerid] &= ~PLAYER_HAS_GANG;
}
public OnPlayerUpdate(playerid) {
    // Felcseréljük minden frissítésnél a bit flag értékét
    BitFlag_Toggle(g_PlayerFlags[playerid], PLAYER_BLABLA_19);
    if (BitFlag_Get(g_PlayerFlags[playerid], PLAYER_BLABLA_19)) {
        DoSomething();
    }
//  Makró nélkül:
//  g_PlayerFlags[playerid] ^= PLAYER_BLABLA_19;
//
//  if (g_PlayerFlags[playerid] & PLAYER_BLABLA_19) {
//      DoSomething();
//  }
}
« Utoljára szerkesztve: 2011. December 28. - 15:04:17 írta kurta999 »

[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #1 Dátum: 2011. December 06. - 23:27:19 »
0
Nem rossz csak ez szúrt szemet így este:
 

Ezekhez a tömbökhöz szögletes zárójeleket ( { } ) kell használnod a kockás helyett. ( [ ] ).[/quote]
Ezekhez a tömbökhöz kapcsos zárójelet { } kell használnod a szögletes [] helyett.

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #2 Dátum: 2011. December 07. - 11:31:00 »
0
Kösz.
Este volt már és nemvolt azt idõm javítani, egyébkét jót röhögtem rajta.

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #3 Dátum: 2012. Április 19. - 20:55:58 »
0
Részletesebb bitmûveletekrõl ittvan egy példa script.
Ez nem leírás, csak egy példa script, mivel még pár részének a mûködését nemigazán értem, csak azt, hogy hol kell használni :D
Nem kezdõknek való, hanem aki már az alapokat érti.
 

#include <a_samp>
#include <sscanf2>
new
g_iVehicleBits;
#define VEHICLE_FLAG_DATA \\
printf(\"color1 = %d, color2 = %d, paintjob = %d, interior = %d, rcolor: %d, %d, \\n\\nbonnet: %d, boot: %d, stereo: %d, tele: %d\", g_iVehicleBits >> 23, g_iVehicleBits >>> 15 & 0xFF, \\
g_iVehicleBits >>> 12 & 0x7, g_iVehicleBits >>> 7 & 0x1F, g_iVehicleBits >>> 6 & 0x1, g_iVehicleBits >>> 5 & 0x1, g_iVehicleBits >>> 4 & 0x1, g_iVehicleBits >>> 3 & 0x1, g_iVehicleBits >>> 2 & 0x1, g_iVehicleBits >>> 1 & 0x1);
// g_iVehicleBits >>> 15 & 0xFF
// Eltoljuk a biteket jobbra 15-el, a többi ami elõtte van az kiesik, csak az utánna lévõk maradnak.
// Aztán az AND (&)-al megnézzük benne a 0xFF-et (255, mivel ez 8bit) Ezt a részét se vágom, csak példának írtam a scriptet, de az a fõ, hogy mûködik xD
// Ezek pedig a sima egy bites dolgokra vannak, ezt az iMyVal |= e_NO_RAND_COLOR_1, vagy iMyVal &= ~e_NO_RAND_COLOR_1 formában használhatod.
// Errõl itt nem írtam példát, de ha már az alapokat érted, amit a leírás elején leírtam, akkor eztis érteni fogod.
/*
enum
{
e_NO_RAND_COLOR_1 = (1 << 6),
e_NO_RAND_COLOR_2 = (1 << 5),
e_BONNET_STATUS =    (1 << 4),
e_BOOT_STATUS =    (1 << 3),
e_STEREO_STATUS =    (1 << 2),
e_TOGGLE_TELE =    (1 << 1)
}
*/
public OnFilterScriptInit()
{
new
color1 = 123,
color2 = 155,
paintjob = 4,
interior = 0,
randcolor1 = 1,
randcolor2 = 1,
bonnetstatus = 0,
bootstatus = 1,
stereostatus = 0,
allowhcartele = 1;
g_iVehicleBits = color1 << 23 | color2 << 15 | paintjob << 12 | interior << 7 | randcolor1 << 6 | randcolor2 << 5 | bonnetstatus << 4 | bootstatus << 3 | stereostatus << 2 | allowhcartele << 1;
    VEHICLE_FLAG_DATA
   
SetVehicleColor(254, 211);
SetVehiclePaintjob(3);
SetVehicleInterior(15);
ToggleVehicleRandomColor(1, 1);
print(\"lofasz\");
ToggleSpecialItems(1, 1, 1, 1);
return 1;
}
SetVehicleColor(color1, color2)
{
if(!(0 <= color1 <= 255) || !(0 <= color2 <= 255)) return 0;
// Fordítsd le ezt az értéket binárisra, meglátod mit kapsz.
// Ezt a részt még totál nem vágom, de nekem az jött le belõlle, hogy azokat a biteket teszi \"írhatóvá\", amiket 0-ra rakunk
g_iVehicleBits &= 0x7FFF;
g_iVehicleBits = color1 << 23 | color2 << 15 | g_iVehicleBits;
// color1 << 23
// Eltoljuk a color1 bitjeit 23-al és onnan kezdjük írni. Egy cella 32bit, de a 32.bit az azt jelenti, hogy elõjeles-e, ez jelen esetbe hülyeséget csinál
// Azért csak 23-al tolom el.
// Aztán etoljuk a color2-t 15-el és ezt utánna rakjuk.
// Utánna pedig ezt hozzáadjuk a \"g_iVehicleBits\"-hez és ezzel tesszük egyenlõvé a változót.
VEHICLE_FLAG_DATA
return 1;
}
SetVehiclePaintjob(paintjob)
{
if(!(0 <= paintjob <= 4)) return 0;
g_iVehicleBits &= 0x7FFF87FF;
g_iVehicleBits = paintjob << 12 | g_iVehicleBits;
VEHICLE_FLAG_DATA
return 1;
}
SetVehicleInterior(interiorid)
{
if(!(0 <= interiorid <= 19)) return 0;
g_iVehicleBits &= 0x7FFFF07F;
g_iVehicleBits = interiorid << 7 | g_iVehicleBits;
VEHICLE_FLAG_DATA
return 1;
}
ToggleVehicleRandomColor(color1, color2)
{
g_iVehicleBits &= 0x7FFFFF9F;
g_iVehicleBits = color1 << 6 | color2 << 5 | g_iVehicleBits;
VEHICLE_FLAG_DATA
return 1;
}
ToggleSpecialItems(bonnet, boot, stereo, hcartele)
{
g_iVehicleBits &= 0x7FFFFFE1;
g_iVehicleBits = bonnet << 4 | boot << 3 | stereo << 2 | hcartele << 1 | g_iVehicleBits;
VEHICLE_FLAG_DATA
return 1;
}

Nem elérhető Pedró

  • 3341
  • 2014 © Az év Szkriptere
    • Profil megtekintése
[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #4 Dátum: 2012. Április 25. - 18:29:36 »
0
a char tömbökre rátérve lenne egy kérdésem..
mégpedig az, hogy a karakterláncoknál hogyan van ez..
pl:
new szstr[2*256 char];
format(szstr, sizeof szstr, \"asd\");
print(szstr);
kérdések ehez:
ezzel van így probléma?
a char használatával spóroltam memória használatot?
kell valami még kiegészítésnek ehez a kis rövid kódhoz?

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #5 Dátum: 2012. Április 25. - 19:13:44 »
0
A char-t azt nem ilyen helyzetekben szokták használni. Format az \"rendes sztring\"-re mûködik.
Például a verseny neve egy globális sztring, akkor azt tárolód egy char tömbbe, mivel az cellánként egy bájt, nempedig négy, mint a sima változó.
 

new
g_szRaceName[45 char];
MyFunc(..)
{
strpack(g_szRaceName, \"Ez most a verseny neve\", sizeof(g_szRaceName));
}
///// Kibontás
new
szRaceName[45];
strunpack(szRaceName, g_szRaceName, sizeof(g_szRaceName));

 
Mint említettem, egy bájt, azaz 0 és 255 között lehet az értéke. (Jelen esetben elõjel nélküli)
Olyan helyeken nagyon jó, ahol számot tárolunk és ebbe a közbe belefér.
Például:
 
new
    g_pRobCount[MAX_PLAYERS char];
//////
if(++g_pRobCount{i} > 3)
{
print(!\"asd\");
g_pRobCount{i} = 0;
}

Nem elérhető Gabor..

  • 1883
  • Gabor..
    • Profil megtekintése
[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #6 Dátum: 2012. Május 17. - 22:59:11 »
0
Jó leírás, hasznos infók. ;) A Bitmûveletekrõl való leírás jól jött :D
« Utoljára szerkesztve: 2012. Június 13. - 14:28:01 írta Gabor.. »

Nem elérhető Gabor..

  • 1883
  • Gabor..
    • Profil megtekintése
[Leírás] Tippek és Trükkök (\'char\' tömbök, Bit-Flag és Egyéb)
« Válasz #7 Dátum: 2012. Május 17. - 22:59:11 »
0
Jó leírás, hasznos infók. ;) A Bitmûveletekrõl való leírás jól jött :D
« Utoljára szerkesztve: 2012. Június 13. - 14:28:01 írta Gabor.. »

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal