Nachfolgend findest du ein Beispiel für das vielleicht grundlegendste Skript, das du schreiben kannst:
#include <a_samp>
main(){
print("Hallo Welt!");
return 1;
}
Die verschiedenen Aspekte werden der Reihe nach behandelt, aber wir beginnen mit der ersten Zeile.
#include <a_samp>
Dies lädt grundsätzlich den Code von pawno/includes/a_samp.inc in dein Skript, so dass du alles, was es bereits inkludiert hat, verwenden kannst. Eines der Dinge, die es bereits inkludiert hat, ist:
#include <core>
#include <float>
#include <string>
#include <file>
#include <time>
#include <datagram>
#include <a_players>
#include <a_vehicles>
#include <a_objects>
#include <a_sampdb>
Dies schließt alle anderen Dateien in diesem Verzeichnis ein, so dass du durch Hinzufügen dieser einen Zeile Zugriff auf alle Funktionen in SA:MP hast (mehr zu Funktionen später).
Der nächste Teil hat zwei Seiten eines Funktionsaufrufs. main()
ist eine Funktion, für die du den Code schreibst und die von woanders aufgerufen wird, print(string[]) ist eine Funktion mit dem Code an anderer Stelle, die du aufrufst. Zur Zeit wird damit nur eine Zeichenkette geladen und in der Konsole ausgegeben. (d.h. "Hallo Welt!" wird ausgegeben). (ohne die ""s) (eine Tradition in allen Skriptsprachen)) auf die Serverkonsole und beenden. Das:
return 1;
Übergibt einen Wert (1) zurück an die Stelle, die main()
angerufen hat, um ihr mitzuteilen, was passiert ist (der genaue Wert, der hier übergeben wurde, spielt keine Rolle, aber an anderen Stellen spielt er eine Rolle). Du hast nun dein erstes (sehr einfaches) Skript. Wenn du file->new in pawno anklckst, erhältst du einen viel größeren Startpunkt für alle Rückrufe (siehe unten), einschließlich main (das technisch gesehen kein Rückruf ist, sich aber wie einer verhält).
An den Print- und Return Zeilen steht ein ';' (ein Semikolon) am ende, dies bezeichnet lediglich das Ende eines Statements (ein Statement ist eine Gruppe von einer oder mehreren Funktionen und Operatoren, die zusammen etwas tun, ähnlich wie ein Satz in der allgemeinen Sprache). Die meisten Leute setzen separate Statements auf separate Zeilen, aber das ist nicht erforderlich, es macht die Dinge nur klarer, das Folgende ist gleichermaßen gültig:
main() { print("Hallo Welt!"); return 1; }
Die {}s (Klammern (geschweifte Klammern), nicht [] Klammern (eckige Klammern)) umschließen eine Gruppe von Anweisungen, die zusammen ausgeführt werden sollten (wie ein Absatz in gemeinsamer Sprache). Wenn du dies tätest:
main() print("Hallo Welt!"); return 1;
Du würdest einen Fehler erhalten, weil jetzt das return 1;
-Statement nicht gruppiert ist, also nicht Teil von main()
ist. geschweifte Klammern gruppieren eine Menge von Statements zu einem einzigen Statement (die als zusammengesetzte Anweisung bezeichnet wird) und Funktionen haben ein einziges Statement bei sich. Ohne die geschweiften Klammern sind print und return völlig getrennte Anweisungen, also gibt es zwei oder so, wie eine Funktion nur eine einzige Anweisung haben kann, die zweite ist nicht in einer Funktion, was Code nicht sein kann.
Aber im Allgemeinen kannst du zusammengesetzte Anweisungen mit dem Komma (,) Operator erweitern, aber dies wird nicht empfohlen, da es nicht die beste Kodierungspraxis ist. Es folgt ein Beispiel:
main() print("Hallo Welt!"), return 1;
Eine Funktion ist im Grunde genommen ein Stück Code, das etwas tut und von dem man sagen kann, dass es diese Sache von woanders aus tun soll. Sie kann auch Daten darüber, was sie getan hat, an die Stelle zurückgeben, die sie zum Ausführen angewiesen hat (die Stelle, die sie "aufgerufen" hat).
print("Hallo Welt!");
Wie in Der Anfang beschrieben, ruft dies die Funktion namens "print" auf (definiert in a_samp.inc, weshalb du sie einbinden musst) und teilt ihr mit, dass sie etwas in der Serverkonsole anzeigen soll (das Wort "Hallo").
Eine Funktion besteht aus dem Funktionsnamen (z.B. "print"), der dem System mitteilt, welchen Code-Block du aufrufen willst, und einer Parameterliste, die in ()s hinter dem Funktionsnamen eingeschlossen ist und zusätzliche Daten an die Funktion übergibt, um ihre Ausführung zu erleichtern. Wenn Sie keine Parameter hätten, würdest du Millionen von Funktionen benötigen:
printa();
printaa();
printab();
printac();
etc...
Funktionen können so viele Parameter haben, wie du möchtest, von 0 aufwärts (es kann eine Obergrenze geben, die aber mindestens 128 beträgt):
printf("Hallo Welt!", 1, 2, 3, 4, 5, 6);
Keine Sorge darüber, was diese Funktion im Moment tut, nur dass sie 7 Parameter hat, die jeweils durch ein Komma getrennt sind.
Neben der Möglichkeit, bestehende Funktionen aufzurufen, kannst du auch eigene Funktionen schreiben und aufrufen:
#include <a_samp>
main()
{
return meineFunktion();
}
meineFunktion()
{
print("Hallo Welt!");
return 1;
}
Dieser macht genau dasselbe wie der ursprüngliche Code, ist aber anders angeordnet. Wenn main()
beim Starten des Modus aufgerufen wird (es wird automatisch aufgerufen), ruft es die neue benutzerdefinierte Funktion namens meineFunktion()
auf. Diese Funktion gibt die Nachricht in der Serverkonsole aus und gibt dann die Zahl 1 an main()
zurück. main()
nimmt den zurückgegebenen Wert (1) und gibt ihn dann an den Server selbst zurück (d.h. an die Stelle, die main()
überhaupt erst aufgerufen hat). Da return meineFunktion();
eine einzelne Anweisung ist, die Sie tun könnten:
#include <a_samp>
main() return meineFunktion();
meineFunktion()
{
print("Hallo Welt!");
return 1;
}
Aber die meisten Leute wollen keine Klarheit. du kannst den meineFunktion
-Rückgabewert auch gar nicht verwenden und tun es:
#include <a_samp>
main()
{
meineFunktion();
return 1;
}
meineFunktion()
{
print("Hallo Welt!");
return 1;
}
Parameter sind eine Art Variable, die du nicht deklarieren musst, da sie von der Stelle kommen, die die Funktion aufgerufen hat:
#include <a_samp>
main()
{
return meineFunktion("Hallo Welt!");
}
meineFunktion(string[])
{
print(string);
return 1;
}
Dieser Code macht immer noch dasselbe, aber wir sagen meineFunktion()
jetzt, was angezeigt werden soll. Der Aufruf übergibt die Zeichenkette "Hallo Welt!" an die Funktion, wo sie in einer Variablen namens string gespeichert wird (das [] bedeutet, dass es sich um ein Array handelt, wie später erklärt wird). Die print-Funktion wird aufgerufen und übergibt den Inhalt der String-Variablen. Wir wissen, dass es sich um eine Variable handelt, weil sie nicht mehr das "" hat.
Eine Variable ist im Grunde genommen ein Stück Speicher, in dem Daten gespeichert werden und nach Bedarf geändert und gelesen werden können. Variablen sind eine oder mehrere Zellen, eine Zelle ist 32 Bit (4 Byte) groß und standardmäßig signiert, so dass sie von -2147483648 bis 2147483647 speichern können (obwohl -2147483648 in PAWN schlecht definiert ist und bei Anzeige ungerade Ergebnisse liefert). Eine Variable, die aus mehr als einer Zelle besteht, wird als Array bezeichnet. Strings sind ein spezieller Array-Typ, bei dem jede Zelle ein Zeichen des Strings enthält (oder 4 Zeichen in gepackten Strings, aber sie werden hier nicht behandelt).
Um eine neue Variable zu erstellen, müsst du diese deklarieren:
new meineVariable;
Dies weist das System an, eine neue Variable namens meineVariable
zu erstellen, der Anfangswert dieser Variable wird 0 sein.
new meineVariable = 7;
Dadurch wird eine neue Variable deklariert und ihr Anfangswert auf 7 gesetzt, so dass beim print der Variable jetzt 7 angezeigt wird. Um eine Variable anzuzeigen, bei der es sich nicht um eine Zeichenkette handelt, müssen wir zu der bereits erwähnten Funktion printf() zurückgehen und dies tun:
new
meineVariable = 7;
printf("%d", meineVariable);
Auch hier musst du vorerst nur wissen, dass dadurch der Wert von meineVariable
(d.h. zu diesem Zeitpunkt 7) auf den Server ausge-printed wird.
new meineVariable = 7;
printf("%d", meineVariable);
meineVariable = 8;
printf("%d", meineVariable);
Dieser Code gibt 7 aus, ändert den Wert der Variable in 8 und zeigt den neuen Wert auch im Server-Fenster an. Es gibt viele andere Dinge, die du mit Variablen machen kannst, einige sind unten aufgeführt, die meisten sind an anderer Stelle aufgelistet:
meineVariable = meineVariable + 4;
Setzt den Wert von meineVariable
auf den alten Wert von meineVariable
plus 4, d.h. erhöht seinen Wert um 4. Dies kann auch als geschrieben werden:
meineVariable += 4;
Das bedeutet einfach "meineVariable
um 4 erhöhen".
meineVariable -= 4;
Dadurch wird der Wert um 4 verringert.
meineVariable *= 4;
Dadurch wird der Wert mit 4 multipliziert.
meineVariable /= 4;
Dadurch wird der Wert durch 4 geteilt.
Ein Array ist eine Variable, in der du mehrere Daten auf einmal speichern und dynamisch auf sie zugreifen kannst. Ein gutes Beispiel hierfür ist das sehr verbreitete MAX_PLAYERS-Array, das einen slot für jeden möglicherweise angeschlossenen Player hat, so dass du weißt, dass die Daten für einen Spieler nicht mit den Daten für einen anderen Spieler interferieren (mehr dazu später).
new meinArray[5];
Dieser Code wird ein Array mit 5 Slots deklarieren, so dass du 5 normale Daten auf einmal in diesem Array speichern kannst, was du nicht tun kannst, ist etwas wie das Folgende:
new meineVariable = 5,
meinArray[meineVariable];
Dieser Code sieht so aus, als würde er ein Array in der Größe der in meineVariable
gespeicherten Zahl erzeugen (hier 5, aber es könnte alles Mögliche sein), aber das kannst du nicht tun. In PAWN wird der Speicher für Variablen zugewiesen, wenn du deinen Code kompilierst, das bedeutet, dass Arrays immer eine Größe haben, du kannst die Größe nicht beliebig festlegen, wann immer du willst.
Um einen Wert in einem Array zu setzen, musst du sagen, in welchem Teil des Arrays du die Daten speichern möchtest, dies KANN mit einer anderen Variablen geschehen:
new
meinArray[5];
meinArray[2] = 7;
Dies wird ein Array mit 5 Slots deklarieren und dem DRITTEN Slot den Wert 7 geben, da Variablen immer mit 0 anfangen, ergibt dies die Werte im Array:
0, 0, 7, 0, 0
Warum nicht?
0, 7, 0, 0, 0
fragst du dich? Das liegt daran, dass das Zählen eigentlich bei der Zahl 0 und nicht bei 1 beginnt. Bedenke Folgendes:
2, 4, 6, 8
Wenn du die Liste durchgehst, dann hast du nach der Zahl 2 bereits eine Zahl (die 2), d.h. wenn du die Zahlen zählst, bis du die Zahl 4 erreichst, bist du bereits bei eins, wenn du die 2 erreichst, bist du nicht bei eins, sondern bei null. Die 2 steht also an Position Null und die 4 an Position Eins, und daraus folgt, dass die 6 an Position Zwei steht, also dort, wo die 7 im ersten Beispiel oben steht. Wenn wir die slots für das erste Beispiel beschriften, erhalten wir:
0 1 2 3 4
0 0 7 0 0
Es gibt fünf Slots, aber wie du sehen kannst, und das ist sehr wichtig, gibt es KEINEN Slot FÜNF, wenn du Folgendes tust, könnte dein Server abstürzen:
new meinArray[5];
meinArray[5] = 7;
Wie oben erwähnt, kann der Array-Index (der Index ist der Slot, in den du schreibst) alles sein, eine Zahl, eine Variable oder sogar eine Funktion, die einen Wert zurückgibt.
new meinArray[5],
meinIndex = 2;
meinArray[meinIndex] = 7;
Sobald du ein Array und einen Index hast, kannst du diesen Block genau so verwenden, als wäre er eine beliebige andere Variable:
meinArray[2] = meinArray[2] + 1;
meinArray[2] += 1;
meinArray[2]++;
Wie oben erwähnt, ist ein gebräuchlicher Array-Typ das Array MAX_PLAYERS. MAX_PLAYERS ist keine Variable, es ist eine Definition, die später erklärt wird, aber akzeptiere vorerst, dass es eine konstante Zahl ist, die der maximalen Anzahl von Spielern entspricht, die ein Server halten kann (diese ist standardmäßig 500, auch wenn du die Zahl in deiner server.cfg-Datei änderst). Der folgende Code verwendet normale Variablen, um Daten für 4 Spieler zu halten und etwas mit diesen Spielern in einer Funktion zu tun (nehme der Einfachheit halber an, dass MAX_PLAYERS vorerst 4 ist):
new
gSpieler0,
gSpieler1,
gSpieler2,
gSpieler3;
SetPlayerValue(playerid, value)
{
switch(playerid)
{
case 0: gSpieler0 = value; // ist dasselbe wie if(playerid == 0)
case 1: gSpieler1 = value; // ist dasselbe wie if(playerid == 1)
case 2: gSpieler2 = value; // ist dasselbe wie if(playerid == 2)
case 3: gSpieler3 = value; // ist dasselbe wie if(playerid == 3)
}
}
Siehe den Abschnitt über Kontrollstrukturen für weitere Informationen über das, was dort vor sich geht. Beachte auch, dass dies auch als switch ausgeführt werden könnte, aber das ist für das Beispiel weniger klar und effektiv sowieso derselbe Code.
Vergleiche das nun mit der Verwendung eines Arrays mit einem Slot pro Spieler, wobei zu beachten ist, dass ein Array-Index jeder beliebige Wert sein kann:
new gSpieler[MAX_PLAYERS];
SetPlayerValue(playerid, value)
{
gSpieler[playerid] = value;
}
Dadurch wird ein globales Array (siehe Abschnitt über den scope) mit einem Slot für jeden Spieler erstellt, dann weist die Funktion dem Slot für den angegebenen Spieler das zu, was in der Variablen "value" steht. Das erste Beispiel war groß mit nur vier Spielern, wobei 4 Zeilen pro Spieler verwendet wurden, das sind 2000 Zeilen für 500 Spieler (wenn es weniger sein kann, aber es ist immer noch eine Menge), die zweite Version ist eine einzige Zeile, egal wie viele Spieler du hast.
Eine Zeichenfolge ist eine spezielle Art von Array, das mehrere Zeichen enthält, um ein Wort oder einen Satz oder einen anderen für den Menschen lesbaren Text zu erstellen. Ein Zeichen ist ein Byte groß (obwohl es erweiterte Sätze gibt, in denen ein Zeichen aus mehreren Bytes besteht, aber diese sind in SA:MP nicht gut definiert), und standardmäßig nimmt ein Zeichen eine Zelle ein (eine normale Variable oder einen Array-Slot). Zeichen werden in einem System mit dem Namen ASCII kodiert, das Zeichen "A" wird durch die Zahl 65 dargestellt, wenn man dem System sagt, dass es eine Zahl anzeigen soll, erhält man 65, wenn man dem System sagt, dass es ein Zeichen anzeigen soll, erhält man ein großes a. Wenn ein einzelnes Zeichen eine einzelne Zelle einnimmt, nehmen mehrere Zeichen (d.h. Text) mehrere Zellen ein, Sammlungen von Zellen werden, wie gerade erklärt, als Arrays bezeichnet.
Zeichenketten in PAWN (und anderen Sprachen) werden als "NULL-terminiert" bezeichnet, d.h. wenn 0 erreicht wird, endet die Zeichenkette. Dies ist nicht dasselbe wie das Zeichen "0", dargestellt durch die Zahl 48, dies ist das NULL-Zeichen, dargestellt durch die Zahl 0. Dies bedeutet, dass ein String-Array 20 Zellen groß sein kann, aber nur dann einen String von 3 Zeichen Länge haben kann, wenn das vierte Zeichen das NULL-Zeichen ist, das das Ende des Strings signalisiert. Du kannst jedoch keine 20 Zeichen lange Zeichenfolge haben, wenn das NULL-Zeichen in der Zeichenfolge enthalten sein MUSS. In einem Array mit 20 Zellen kannst du also eine 19 Zeichen lange Zeichenfolge und ein NULL-Abschlusszeichen haben.
new meinString[16] = "Hallo Welt!";
Dieser Code deklariert eine neue Zeichenfolge mit genügend Platz für eine 15-Zeichenfolge und setzt sie zunächst auf die 5-Zeichenfolge "Hallo Welt!", die doppelten Anführungszeichen um den Text herum zeigen an, dass es sich um eine Zeichenfolge handelt. Intern sieht das Array dann so aus:
104 101 108 108 111 0 x x x x x x x x x x
Die "x" bedeuten alles, in diesem Beispiel sind sie alle 0, aber da sie nach dem Null-Zeichen stehen, ist es egal, was sie sind, sie haben keinen Einfluss auf die Zeichenfolge.
Zeichenketten können z.B. wie normale Arrays manipuliert werden:
new meinString[16] = "Hallo Welt!";
meinString[1] = 97;
Ändert das Zeichen in Slot 1 in das Zeichen, das durch die Zahl 97 (ein kleingeschriebenes "a") dargestellt wird, was dazu führt, dass die Zeichenfolge "hallo" lautet. Dies kann viel lesbarer und einfacher zu editieren geschrieben werden als:
new meinString[16] = "Hallo Welt!";
meinString[1] = 'a';
Die einfachen Anführungszeichen um das "a" bedeuten, dass es sich um ein Zeichen und nicht um eine Zeichenkette handelt, Zeichen müssen nicht mit NULL abgeschlossen werden, da sie immer nur eine Zelle lang sind, sie können auch austauschbar mit Zahlen verwendet werden, wenn du weißt, wofür sie stehen.
new meinString[16] = "Hallo Welt!";
meinString[1] = '\0';
\0' besteht aus zwei Zeichen, jedoch ist \ ein Sonderzeichen, das das nächste Zeichen modifiziert, \0 bedeutet NULL, dieser Code ist das Gleiche wie:
new meinString[16] = "Hallo Welt!";
meinString[1] = 0;
Aber das ist NICHT dasselbe wie:
new meinString[16] = "Hallo Welt!";
meinString[1] = '0';
Die erste und die zweite Version führen dazu, dass die Zeichenfolge einfach:
h
Die dritte Version wird die Zeichenfolge ergeben:
h0llo
Wie kurz erwähnt, ist ein Backslash ein Sonderzeichen, nämlich:
'\'
oder
"\"
Gibt einen Compilerfehler aus, weil das \ das nächste Zeichen so verändert, dass diese Konstanten nicht korrekt beendet werden. Dies kann z.B. dazu verwendet werden, Zeichen zu erzeugen, die normalerweise nicht erzeugt werden können:
new meinString[4] = "\"";
Dieser Code erzeugt eine Zeichenfolge, die nur aus einem doppelten Anführungszeichen besteht. Normalerweise signalisiert ein doppeltes Anführungszeichen das Ende einer geschriebenen Zeichenfolge, aber der Backslash macht das doppelte Anführungszeichen unmittelbar danach zu einem Teil der Zeichenfolge, und das doppelte Anführungszeichen danach beendet stattdessen die Zeichenfolge. Andere Sonderzeichen sind:
\0 | NULL-Zeichen | Beendet eine Zeichenfolge |
EOS | NULL-Zeichen | Beendet eine Zeichenfolge |
\n | Zeilenvorschub | \n für eine neue Zeile (Funktioniert in Linux & Windows) |
\r | Zeilenumbruch | \r\n für eine neue Zeile in Windows |
\\ | Backslash | Wird verwendet, um ein Backslash in eine Zeichenkette zu setzen |
\' | Einzelne Anführungszeichen | Wird verwendet, um ein einfaches Anführungszeichen als Zeichen in einfachen Anführungszeichen zu verwenden (Verwendung: '\'') |
\" | Doppeltes Anführungszeichen | Wird verwendet, um ein doppeltes Anführungszeichen in eine Zeichenkette zu setzen |
\xNNN | Hexadezimalzahl | Wird verwendet, um das Zeichen auf das Zeichen zu setzen, das durch die auf NNN angegebene Hex-Zahl dargestellt wird |
\NNN | Zahl | Wird verwendet, um das Zeichen auf das Zeichen zu setzen, das durch die anstelle von NNN angegebene Zahl dargestellt wird (siehe \0) |
Es auch noch andere, aber das sind die wichtigsten.
Ein Tag ist eine zusätzliche Information über eine Variable, die definiert, wo sie verwendet werden kann und Informationen über ihre Funktionalität liefert. Tags können stark (mit einem Großbuchstaben beginnend) oder schwach sein. Zum Beispiel:
new Float:a = 6.0;
Der "Float"-Teil ist der Tag, dieser definiert diese Variable als Float (nicht ganze/reelle Zahl) und bestimmt, wo sie verwendet werden kann.
native SetGravity(Float:gravity);
Das bedeutet, dass die Funktion SetGravity()
einen einzigen Parameter nimmt, der z.B. ein Float sein muss:
SetGravity(6.0);
new Float:fGrav = 5.0;
SetGravity(fGrav);
Dadurch wird die Schwerkraft auf 6 (6,0 als float) und dann auf 5 (5,0 als float) gesetzt. Die Verwendung des falschen Tags an der falschen Stelle führt oft zu einer Fehlanpassung des Tags:
SetGravity(meinTag:7);
Das wird versuchen, die Schwerkraft mit dem Tag "meinTag" auf 7 zu setzen, was eindeutig kein "Float" ist, also falsch ist. Beachte auch, dass bei Tags zwischen Groß- und Kleinschreibung unterschieden wird.
Benutzerdefinierte Tags können von Benutzern definiert werden:
new myTag: variable = 0,
AppleTag: another = 1;
Wenn du diese beiden Variablen jedoch direkt hinzufügst, musst du '_:' verwenden, um sie zu 'de-taggen', andernfalls wird der Compiler eine 'Tag-Mismatch'-Warnung ausgeben.
Scope ist der Bereich, in dem eine Variable verwendet werden kann. Es gibt vier Haupt-Scope: local, local static, global und global static. Alle Variablen können nur verwendet werden, nachdem sie deklariert wurden, so dass dies richtig ist:
new var = 4;
printf("%d", var);
Und das ist falsch:
printf("%d", var);
new var = 4;
Eine lokale Variable ist eine als "new" deklarierte Variable innerhalb einer Funktion oder eines Teils einer Funktion:
MyFunc()
{
new
var1 = 4;
printf("%d", var1);
{
// var1 existiert noch, da dies eine niedrigere Ebene ist
new
var2 = 8;
printf("%d %d", var1, var2);
}
// var2 existiert nicht mehr, da dies eine höhere Ebene ist
}
// var1 existiert nicht mehr
local Variablen werden z.B. jedes Mal zurückgesetzt:
for (new i = 0; i < 3; i++)
{
new
j = 1;
printf("%d", j);
j++;
}
Wird ausgegeben:
1
1
1
Denn j wird erzeugt, ausgegeben, inkrementiert und dann zerstört, dann wird der Code in wiederholt.
Eine "static local" kann an der gleichen Stelle wie ein “local” verwendet werden, vergisst aber z.B. seinen alten Wert nicht:
MyFunc()
{
static
var1 = 4;
printf("%d", var1);
{
// var1 existiert noch, da dies eine niedrigere Ebene ist
static
var2 = 8;
printf("%d %d", var1, var2);
}
// var2 existiert nicht mehr, da dies eine höhere Ebene ist
}
// var1 existiert nicht mehr
Dieser Code wird sich genauso verhalten wie das neue Beispiel, wie auch immer.. Dies:
for (new i = 0; i < 3; i++)
{
static
j = 1;
printf("%d", j);
j++;
}
wird
1
2
3
ausgeben.
Weil j statisch ist, erinnert es sich an seinen alten Wert.
Globale Variablen werden außerhalb einer Funktion deklariert und können in beliebigen Funktionen verwendet werden:
new
gMyVar = 4;
MyFunc()
{
printf("%d", gMyVar);
}
Sie werden niemals zurückgesetzt oder gehen verloren.
“Global static” Variablen sind wie normale “global”, können aber nur in der Datei verwendet werden, in der sie deklariert sind:
Datei1:
static
gsMyVar = 4;
MyFunc()
{
printf("%d", gsMyVar);
}
#include "Datei2"
Datei2:
MyFunc2()
{
// Dies ist falsch, da gsMyVar hier nicht existiert
printf("%d", gsMyVar);
}
"static" kann in gleicher Weise auch auf Funktionen angewendet werden.