Sziasztok,
mivel többen érdeklődtek, hogy mik ezek a bool típusú változók, illetve mire is jók, ezért úgy döntöttem megírom ezt a kis apróságot, törekedtem arra, hogy a lehető legérthetőbb legyen, és ahogyan szépen haladunk a mély vízbe egy példakódon bemutassam, hogy hogyan is lehet szebbé, kedvezőbb memória használatúvá tenni ezt azt.
Először is szeretném kiemelni, hogy a pawn programnyelv sajnálatos módon eléggé típus szegény, és a bool típust sem tartalmazta alapból, ezért egy tag -ként van csak megoldva.
Hogy ez miért is fontos számunkra?
1. Létrehozásukkor ugyanúgy 0 a kezdőértéke, mint egy sima változónak, csak ezt logikai változóknál false értéknek fogjuk hívni.
2. Ugyanannyi memóriát, azaz 4 byte -t ( 32 bit -t) foglal le, mint a sima változók.
Hogyan néz ki ez a tag? ( Csak érdekességképpen )
Most már láttuk, tudjuk az alapokat, szóval kezdjük is:
A logikai változóknak ( bool típusú változók / bináris változók / Boole-féle változók ) 2 értéke lehet, ez nem más mint a 'true' és a 'false', vagy felhasználási területtől függően szokták 'high' és 'low' -ként is alkalmazni, de ezek a kifejezések is csak számokat helyettesítenek:
true / high -> 1
false / low -> 0
Deklarálásnew bool:logikai_valtozo;
//Persze lehet tömbje is ennek a változónak, ha szükséges:
new bool:logikai_valtozo[33];
//És végül, ha true értékkel szeretnénk létrehozni:
new bool:logikai_valtozo = true;
new bool:logikai_valtozo[33] = {true, ...};
Érték adásAz előző részben láthattuk, hogy hogyan is lehet értéket adni egy bináris változónak, amikor true értékkel deklaráltuk, de itt egy példakód, hátha rásegít a megértésre:
#include <amxmodx>
#include <amxmisc>
new bool:logikai_valtozo[33];
public plugin_init()
{
register_clcmd("say /kikapcsol", "Kikapcsol");
register_clcmd("say /bekapcsol", "Bekapcsol");
}
public Kikapcsol(id)
{
logikai_valtozo[id] = false;
client_print(id, print_chat, "Kikapcsoltad!");
}
public Bekapcsol(id)
{
logikai_valtozo[id] = true;
client_print(id, print_chat, "Bekapcsoltad!");
}
Így, ha beírod a chatbe, hogy "/bekapcsol", akkor kiírja hogy "Bekapcsoltad!" és átállítja a változónk értékét true -ra, ha pedig beírod, hogy "/kikapcsol", akkor kiírja hogy "Kikapcsoltad!" és a változónk értéke false lesz.
Logikai változó értékének felcseréléseHa bool típusú változókkal dolgozunk gyakran szükségünk lehet arra, hogy felcseréljük a változó értékét. Erre létezik számos megoldás:
1. Ez a leggyakrabban alkalmazott megoldás amxmodx -es közegben még nem is nagyon láttam mást:
if(logikai_valtozo == true)
{
logikai_valtozo = false;
}
else
{
logikai_valtozo = true;
}
/*Magyarázat:
Megnézzük, hogy ha true a változónk értéke, akkor beállítjuk false -ra, ha pedig más ( false ), akkor pedig beállítjuk true -ra.
*/
2. Ez ugyanaz a megoldás, csak a feltételes / hármas operátor segítségével:
logikai_valtozo = (logikai_valtozo) ? (false) : (true);
/*Magyarázat:
Ugyanaz, mint az előzőnél, csak a hármas operátor segítsége, ennek működési elve:
(feltétel) ? (ha teljesül) : (ha nem)
*/
3. Ez a megoldás már kicsit rövidebb, matematikán alapul:
logikai_valtozo = true - logikai_valtozo;
/*Magyarázat:
Mivel az elején tisztáztuk, hogy a true és a false szó csak számokat helyettesít, ezért ez innentől csak ovis matek:
ha true a változónk értéke:
1 - 1 = 0, szóval false lesz a változónk értéke.
ha false a változónk értéke:
1 - 0 = 1, szóval true -ra változik a változónk értéke.
*/
4. Ez már egy elég pofás, rövid megoldás:
logikai_valtozo = !logikai_valtozo;
/*Magyarázat:
Ez a kis felkiáltójel ( ! ) a logikai tagadás jele:
Ami nem true az false, és ami nem false az true <!-- s:D --><img src=\"{SMILIES_PATH}/icon_e_biggrin.gif\" alt=\":D\" title=\"nagyon boldog\" /><!-- s:D -->
*/
5. Ez a legrövidebb, és valószínűleg a leggyorsabban lefutó megoldás, alapja a bitenkénti "kizáró vagy" ( XOR, ^ ) logikai művelet:
logikai_valtozo ^= bool:1;
logikai_valtozo ^= true;
/*Magyarázat:
Ez a művelet kizárólag akkor ad vissza igaz ( 1 ) értéket, ha az összevetett 2 bit különböző értékű:
Ha true a változónk értéke, akkor így néz ki a művelet:
0000 0000 0000 0000 0000 0000 0000 0001
^0000 0000 0000 0000 0000 0000 0000 0001
=0000 0000 0000 0000 0000 0000 0000 0000
Ha pedig false, akkor így:
0000 0000 0000 0000 0000 0000 0000 0000
^0000 0000 0000 0000 0000 0000 0000 0001
=0000 0000 0000 0000 0000 0000 0000 0001
+a "Tag mismatch" hibák elkerülése érdekében szükséges használni a bool: taget az 1-es elé, vagy true -t írunk a helyére.
*/
Esetleg, ha arra lenne szükségünk, hogy az érték megváltoztatása után tovább fusson a program, és mondjuk kiírja, hogy ki / be kapcsoltad, akkor arra is van lehetőségünk:
if(logikai_valtozo)
{
logikai_valtozo = false;
//Kikapcsoltuk
}
else
{
logikai_valtozo = true;
//Bekapcsoltuk
}
Ez is egy működő kód, de miért ne szakadnánk el az általános megoldásoktól, és használnánk az újonnan megismert érték felcserélési lehetőségeket:
if( ( logikai_valtozo = (logikai_valtozo) ? (false) : (true) ) ) //Ez elég csúnyácska
{
//Bekapcsoltuk
}
else
{
//Kikapcsoltuk
}
if( ( logikai_valtozo = true - logikai_valtozo ) ) //Ez se a legszebb
{
//Bekapcsoltuk
}
else
{
//Kikapcsoltuk
}
if( ( logikai_valtozo = !logikai_valtozo ) ) //Alakul
{
//Bekapcsoltuk
}
else
{
//Kikapcsoltuk
}
if( ( logikai_valtozo ^= true ) )
{
//Bekapcsoltuk
}
else
{
//Kikapcsoltuk
}
Ezek alapján kiegészíthetjük az elején elkezdett kis példakódunkat egy újabb funkcióval:
#include <amxmodx>
#include <amxmisc>
new bool:logikai_valtozo[33]
public plugin_init()
{
register_clcmd("say /atkapcsol", "Atkapcsol");
register_clcmd("say /kikapcsol", "Kikapcsol");
register_clcmd("say /bekapcsol", "Bekapcsol");
}
public Atkapcsol(id)
{
if((logikai_valtozo[id] ^= true))
{
client_print(id, print_chat, "Bekapcsoltad!");
}
else
{
client_print(id, print_chat, "Kikapcsoltad!");
}
}
public Kikapcsol(id)
{
logikai_valtozo[id] = false;
client_print(id, print_chat, "Kikapcsoltad!");
}
public Bekapcsol(id)
{
logikai_valtozo[id] = true;
client_print(id, print_chat, "Bekapcsoltad!");
}
Így, ha beírod chatbe, hogy átkapcsol, akkor átállítja a változónk értékét és kiírja, hogy ki vagy be kapcsoltad.
A memória használatrólMég az elején említettem, hogy a bináris változók is ugyanúgy 4 byte -t foglalnak le maguknak, mint a sima változók.
Hogy ez miért is baj nekünk?
- Mert konkrétan ennek a változó típusnak elég lenne 1 bit is, hogy működjön ( 31 bit fölösleges ).
A pawn programnyelven van lehetőségünk úgy nevezett
char tömbös változókat készíteni, ezzel csak 1 byte * tömb mérete memóriát foglalunk le.
Deklarálás:
new bool:logikai_valtozo[33 char];
//És persze itt is létrehozhatjuk true kezdőértékkel:
new bool:logikai_valtozo[33 char] = {true, ...};
Hivatkozás cellákra:
public client_connect(id)
logikai_valtozo{id} = true;
public client_disconnect(id)
logikai_valtozo{id} = false;
Most, hogy már tudjuk, hogy kompromisszumok nélkül spórolhatunk memóriát tömbös logikai változóknál miért is ne vennénk elő a példakódunkat és alakítanánk át?
#include <amxmodx>
#include <amxmisc>
new bool:logikai_valtozo[33 char]
public plugin_init()
{
register_clcmd("say /atkapcsol", "Atkapcsol");
register_clcmd("say /kikapcsol", "Kikapcsol");
register_clcmd("say /bekapcsol", "Bekapcsol");
}
public Atkapcsol(id)
{
if((logikai_valtozo{id} ^= true))
{
client_print(id, print_chat, "Bekapcsoltad!");
}
else
{
client_print(id, print_chat, "Kikapcsoltad!");
}
}
public Kikapcsol(id)
{
logikai_valtozo{id} = false;
client_print(id, print_chat, "Kikapcsoltad!");
}
public Bekapcsol(id)
{
logikai_valtozo{id} = true;
client_print(id, print_chat, "Bekapcsoltad!");
}
Ahogyan itt láthattuk, fontos, hogy egy char tömbös változónál szögletes ( [] ) helyett kapcsos ( {} ) zárójeleket kell használni!
Fontos: char tömbös változókat csak akkor érdemes használni memória spórolásra, ha a változóban csak 0 és 255 között tárolsz számokat, különben váratlan hibák léphetnek fel! -> bináris változókhoz tökéletes, hiszen itt csak 0 -t vagy 1 -t tárolunk.
Ezen kívül van egy másik megoldás is, ha több logikai változóra lenne szükségünk, amivel egy sima változóban képesek vagyunk akár 32 igaz / hamis értéket is tárolni, ha nem probléma ezt itt nem fejtegetném, itt van egy szép leírás:
[Leírás] Tippek és Trükkök ('char' tömbök, Bit-Flag és Egyéb) - kurta999 és itt az utolsó (Bitműveletek Bit-Flag) rész lesz az ami kell + itt is le van írva ez a char tömbös lehetőség.
Egész számok logikai változóvá konvertálásaIgen, erre is van lehetőségünk, ráadásul elég egyszerű:
public Proba()
{
//Példaként vegyünk 2 változót a szemléltetéshez, az eredményt majd kiiratjuk chatben:
new sima = random(127)
new bool:logikai = !!sima
/*Ahogyan láthatjuk, az egész számot tároló változó vagy maga az egész szám elé kell tennünk két felkiáltójelet, és ezzel visszakapunk egy logikai értéket.*/
client_print(0, print_chat, "%i", logikai);
}
Fontos: Csak és kizárólag akkor kapunk false értéket, ha az átalakítani kívánt szám egyenlő 0 -val, még negatív szám esetén is true értéket ad vissza + float számokkal nem működik.
Részemről ennyi lenne amit tudok, várom az észrevételeket, tanácsokat, illetve ha valamit rosszul írtam le / fejeztem ki, akkor szóljatok.