Guten Abend Community,
heute möchte ich euch die verschiedenen Variablentypen von Pawn etwas näher bringen. Jeder Typ wird mit einer Beschreibung und Beispielen vorgestellt und ich werde versuchen die Zusammenhänge zu erläutern.
Beginnen wir mit dem Allgemeinen: Was für Variablentypen gibt es?
Pawn kennt im Grunde nur 4 Typen, das wären Integer, Boolean, Floats, und Arrays, welche aber viel eher eine Gruppierung mehrerer Variablen sind, dennoch möchte ich darauf eingehen.
Jetzt, da wir wissen welche Typen es gibt, stelle ich euch direkt den Ersten vor: Integer.
Integer sind immer ein Feld groß, sie sind einzellige Arrays (dazu später mehr). Sie können in Pawn alle numerischen, also Elemente einer natürlichen Zahl, enthalten. Da sie der Standarddatentyp sind, reicht ein simples new um sie zu erstellen. Wird ihnen kein Wert zugewiesen, so ist er 0. Als Platzhalter für Integer kann man sowohl %d als auch %i nutzen, es gibt keinen Unterschied.
Zwei einfache Beispiele wären:
new integer;
printf("Mein Integer: %d", integer); // Schreibt "Mein Integer: 0" in die Server-Console.
new integer = 1;
printf("Mein Integer: %i", integer); // Schreibt "Mein Integer: 1" in die Server-Console.
Eine andere, mögliche Schreibweise wäre die einzelnen Ziffern mit einem Unterstrich (_) zu trennen, das macht für den Compiler keinen Unterschied, ist aber wesentlich übersichtlicher.
new integer = 1_000_000;
// ist das Selbe wie:
new integer = 1000000;
Abfragen kann man sie per If-Statement:
new integer = 351;
if(integer == 351) print("Mein Integer ist 351");
if(integer != 351) print("Mein Integer ist nicht 351");
Zu demonstrationszwecken habe ich keine Else-Abfrage genutzt, aber das ist natürlich ebenso möglich.
Dann möchte ich auch gleich einen kleinen Punkt, der sich auch auf Bools bezieht vorgreifen: Mit Integern sind auch boolsche Abfragen möglich, das bedeutet, dass man wenn man nur Zwei Werte, wenn man nur wahr oder falsch, hat keinen Vergleichs-Operator braucht, zu beachten gilt es, dass alles was nicht 1 (true/Wahr) ist, als 0 (false/Falsch) angesehen wird. Gehen wir davon aus, wir möchten nun einen Integer als Bool nutzen (warum auch immer), so kann man dies wie bei Bools realisieren:
new integer;
if(!Integer) print("Falsch"); // Würde "Falsch" ausgeben, da der Wert nicht 1 und somit false ist.
new integer = 1337;
if(!Integer) print("Falsch"); // Würde "Falsch" ausgeben, da der Wert nicht 1 und somit false ist
// new integer = 1;
if(integer) print("Wahr"); // Würde "Wahr" ausgeben, da der Wert 1 und somit true ist
Außerdem kann man Integern auch einen boolschen Wert zuweisen:
new integer = true;
// wäre das Selbe wie
new integer = 1;
Booleans sind Variablen, die nur zwei Werte, true (1) und false (0) enthalten können. Erstellt man einen Bool (Abkürzung), so ist sein Standardwert, wie bei Integern 0, also false.
Nun stellt sich die Frage: Warum Bools wenn auch Ints (Integer) gehen würden? Nun dazu gibt es nur zwei plausible Erklärungen: Sie sind schneller und ressourcenschonender. Beim erstellen muss der Datentyp definiert werden, dies geschieht via bool:.
Als Beispiel:
new bool:boolean;
if(boolean == true) print("Wahr");
if(boolean == false) print("Falsch);
// Ebenso möglich:
if(boolean) print("Wahr");
if(!boolean) print("Falsch");
Floats, auch genannt Gleitkommazahl, sind eine näherungsweise Darstellung von reellen Zahlen. Oder um es anders auszudrücken: Es sind normale Kommazahlen. Anders als im Deutschen üblich, verwendet man statt einen Komma (,) einen Punkt (.). Im Gebiet des SAMP-Scriptings nutzt man sie meist für Positionen, dennoch sind sie auch für anderes zu gebrauchen.
Der Datentyp muss auch hier bei der Erstellung definiert werden, das geschieht per Float:. Der Standardwert ist wieder 0 (0.0000), zum Abfragen nutzt man wieder ein einfaches If-Statement und als Platzhalter dient %f.
new Float:float;
printf("Mein Float: %f", float); // Schreibt "Mein Float: 0.0000" in die Server-Console.
new Float:float = 1958.3783;
printf("Mein Float: %f", float); // Schreibt "Mein Float: 1958.3783" in die Server-Console.
// Abfrage:
if(float == 1958.3783) print("Mein Float ist 1958.3783");
if(float != 1958.3783) print("Mein Float ist nicht 1958.3783");
Der letzte Daten/Variablentyp sind Arrays, obwohl sie viel eher eine Gruppierung von Variablen des selben Typs sind. Man kann sie auch als Zeichenkette bezeichnen, da in jedem Feld eines Arrays ein Zeichen gespeichert werden kann, aber ebenso ein Zahlenwert, deshalb ist es nicht immer eine Zeichenkette, das aber nur nebenbei.
Vielleicht hat der ein oder andere auch schonmal von mehr- bzw. multidimensionalen Arrays gehört, diese sind genau genommen Arrays von Arrays, darauf möchte ich aber gleich noch genauer eingehen.
Zu Beachten gibt es, dass ein Array, welcher als String dient, immer um 1 größer sein muss, als die eigentliche Zeichenlänge/anzahl, das liegt daran, dass sie immer einen Identifier, welcher sich im letzten Feld befindet, brauchen. Arrays beginnen immer bei 0, das heißt: Will man das erste Feld eines Arrays ausgeben, muss man 0 nutzen.
Als erstes Beispiel möchte ich nun einen String erstellen und ausgeben, doch vorher noch ein wenig auf die Thematik von Strings eingehen. Pawn kennt im Grunde keine Strings, sie sind (nur) Zeichenketten bzw. Integer-Arrays, da in Pawn jedes Zeichen einen Integerwert besitz, das kann man ganz einfach prüfen, indem man ein Zeichen als Integer in der Console ausgibt (print("%d", a), das wäre 97). Man könnte also für ein einzelnes Zeichen auch einen normalen Integer nutzen. Nun aber zurück zum Thema:
new string[5+1]; // Ich nutze "Hallo" zum testen, das heißt wir brauchen einen Array der Größe 5 (Länge von "Hallo") +1 (Identifier)
// Nun könnten wir jedem Feld einzeln ein Zeichen zuordnen, das sähe so aus:
string[0] = 'H';
string[1] = 'a';
string[2] = 'l';
string[3] = 'l';
string[4] = 'o';
// Wir können dem Array aber auch gleich einen Gesamtwert zuweisen.
new string[6] = "Hallo";
// Oder auch
new string[6] = {"H", "a", "l", "l", "o"};
// würden wir nun unsere alt bekannte Print-Probe ausfürhen, so würden alle 3 das selbe Resultat liefern.
print(string);
// Doch wie wäre es, wenn wir nun print(string[0]); machen, wird dann nur dieses Zeichen ausgegeben? Nein! Alles ab 0, somit der gesamte Array wird ausgegeben.
// print(string[1]) würde also "allo" ausgeben
print(string[1]); // Schreibt "allo" in die Server-Console.
Aber wie ich bereits erwähnte, es ist eine Ansammlung von Variablen des selben Typs, so würde:
new Float:position[3];
das selbe sein wie 3 einzelne Variablen. Das ist doch wesentlich kürzer und einfacher, aber nicht nur das: Es ist, wie immer, ressourcenschonender und schneller.
Nun wollen wir mit unserem Array die Position eines Spielers ermitteln:
GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
// Print-Test:
printf("X-Position: %f, Y-Position: %f, Z-Position: %f", pos[0], pos[1], pos[2]); // Würde nun die einzelnen Positionen des Spielers in die Console schreiben.
Einigen sind wahrscheinlich auch PerPlayer-Variablen bekannt, diese sind auch nur Arrays, wobei jeder Spieler ein Feld erhält. Im Normalfall nutzt man also die Sloatanzahl als Größe.
Beispiel:
new perplayerarray[MAX_PLAYERS]; // Erstellt den Array mit der maximalen Slotanzahl (Definition)
perplayerarray[0] = 1337; // Setzt die Variable für den Spieler der ID 0 auf 1337
Multidimensionale Arrays sind, wie oben schon beschrieben, Arrays von Arrays. Ihre Größe beträgt also 1. Größe mal 2. Größe. In Pawn sind maximal 3 Dimensionen möglich. Erstellen wir nun einen PerPlayer-Array, in dem wir die Position des Spielers speichern.
new Float:perplayerpos[MAX_PLAYERS][3]; // Erstellt ein Array mit 2 Dimensionen, der Slot/Spieleranzahl und 3 Feldern (für Position X, Y und Z)
GetPlayerPos(playerid, perplayerpos[playerid][0], perplayerpos[playerid][1], perplayerpos[playerid][2]); // Ermittelt die Position und speichert sie für den Spieler der ID 0 und den 3 Feldern der 2. Dimension
Mit dieser Basis könnten wir nun auch Enum(eratoren) verwenden, dabei möchte ich aber gerne auf diesen Thread verweisen.
Das war meine kurze Einführung zu den Variablen/Datentypen, ich hoffe es wird ein wenig klarer. Fehler und Verbesserungsvorschläge teilt ihr mir bitte mit.
So long,
dead
//Edit: Überarbeitung, Integerschreibweise hinzugefügt (Vielen Dank an Martez), Multidimensionale Arrays hinzugefügt
// Edit 2: PerPlayer-Arrays
// Edit 3: Einen kleinen Schönheitsfehler behoben
// Edit 4: String -> Integerarray, Integer -> boolsche Abfrage (doppelter Dank an LoRdCrUnChEr)
// Edit 5 + 6: Rechtschreibung
// Edit 7: Array -> String verdeutlicht[/size]