Verwendung von For-Loops

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Herzlich Willkommen zu diesem Tutorial!


    In diesem Tutorial versuch ich Anfängern zu erklären was ein For-Loop ist und wie er verwendet wird und Funktioniert.
    Dazu ist nicht viel wissen benötigt und man kann gleich Resultate aus diesem Tutorial erziehlen.
    Falls euch das Tutorial gefällt könnt ihr gern ein Feedback hier drunter schreiben und fragen stellen.




    Was ist eine For-Loop (Schleife)?
    Eine Schleife ist eine Kontrollstruktur d.h sie wird z.B verwendet um Code in einer Anwendung wiederholt auszuführen.
    Darunter fällt in SA-MP z.B das Hochzählen und auswerten von Daten, falls der Code in der Schleife vorhanden ist.
    Mehr dazu gibt es im Wikipedia, aber das grobste sollte erklärt sein. (Hier!)




    Was macht sie?
    Eine For-Loop zählt einen Integer bis zu einen vorgegeben Wert positiv hoch oder negativ runter und Stoppt die Schleife falls dieser Wert erreicht wird.
    Wird dieser Wert nicht definiert läuft der For-Loop so lang bis er unterbrochen wird. (Endlosschleife)




    Wozu verwendet man sie?
    Man verwendet ihn um z.B Datenabgleiche zu machen oder um Zeichenketten zu Zählen und oder sie zu Bearbeiten.
    Man kann ihn ebenso verwenden um Daten zu Zählen oder um Werte verschiedenen Datenstrukturen zuzuweisen.
    Auch wird eine Schleife oft benutzt um Datenstrukturen auszulesen und sie zu Verändern. (Was ist eine Datenstruktur?)




    Wie verwendet man sie und wie erstellt man sie?
    Es gibt verschiedene möglichkeiten einen For-Loop zu verwenden und in zu erstellen.



    Die wohl einfachste und bekannteste Form einen For-Loop zu Initialisieren ist diese:
    for(new i = 0; i < MAX_PLAYERS; i++)



    Ebenso gibt andere Formen einen Loop zu erstellen z.b diese:
    new i = 0;
    for(; i < Max; i++)

    MAX_PLAYERS ist in diesem fall eine Konstante die die maximalen Slots des Servers wiedergibt.



    Aber kommen wir zu verwenden.
    Wir haben ein Array in dem wir die Wörter, "Hallo, ich, bin, ein, Loop" gespeichert haben. (Char-Array)
    Nun möchten wir dieses Array auslesen und uns die Wörter zurückgeben lassen.


    new Words[] = {"Hallo", "ich", "bin", "ein", "Loop!"};


    for(new i = 0; i < sizeof(Words); i++)
    {
    printf("Wort %i: %s", i, Words[i]);
    }



    Ebenso können wir abfragen machen ob ein Wort schon existiert.


    new Words[] = {"Hallo", "ich", "bin", "ein", "Loop!"};


    for(new i = 0; i < sizeof(Words); i++)
    {
    if(strfind("Hallo", Words[i]) != -1)
    {
    printf("Das Wort %s existiert im Array!", Words[i]);
    }
    }



    Geschwindigkeiten?
    Natürlich geht es in SA-MP viel um Geschwindigkeit des Scripts, um eventuell Resourcen zu sparen oder einfach eine besser Peformance zu haben.
    Darunter gibt es wichtige Aspekte die man wenn möglich beachten sollte.


    Die schnellste Form eine Schleife zu verwenden ist es, als Bedinung GetMaxPlayers zu verwenden.
    Dazu definieren wir in den Globals einen neuen Wert also einen Integer in diesem fall und geben GetMaxPlayers darin aus.


    new Max_Players;


    OnGameModeInit(...)
    Max_Players = GetMaxPlayers();


    Somit können wir bei 50 Slots Servern z.B erheblich an Leistung sparen.
    Da MAX_PLAYERS seit SAMP 0.3 als 500 definiert ist und der Loop sonst jedesmal bis 500 Zählt.


    Verwendung von unserer neu definierten Variable:
    for(new i = 0; i < Max_Players; i++)


    Man könnte aber auch MAX_PLAYERS neudefinieren:
    #undef MAX_PLAYERS
    #define MAX_PLAYERS (Slots)




    Anweisungen in der Schleife?

    Es gibt verschiedene Anweisungen die man in einer Schleife verwenden kann.
    Darunter zählen "break, continue".


    Break - Unterbricht die Schleife sofort nach dem Aufruf und beendet sie.
    Continue - Falls continue aufgerufen wird fängt die Schleife mit dem nächsten Loop an. (z.B wenn schleife im 4. loop ist springt sie auf den 5.)


    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(example >= 5)
    {
    break;
    }
    }










    Ich hoffe ich konnte euch dem Loop näher bringen und euch hat dieses kleine Tutorial gefallen!


    Edit 1:
    Max zu MAX_PLAYERS geändert.
    Edit 2:
    Max_Players ( GetMaxPlayers ) hinzugefügt
    Edit 3: Edit Edit :P

    6 Mal editiert, zuletzt von Warren ()

  • Was noch anzumerken sind die Bedinungen und wie schnell diese sind:


    for(new i; i<MAX_PLAYERS; i++)


    Das sieht man ja ganz häufig und das ist auch gut so, da MAX_PLAYERS eine Konstante ist.


    sizeof zählt auch zu einer Konstanten, da dies ein unärer Operator ist.


    new max = MAX_PLAYERS;
    if(new i; i<max; i++)


    Dieser Code zum Beispiel wäre erheblich langsamer, da dies keine Konstante ist.


    for(new i; i<GetMaxPlayers(); i++)


    Dies wäre noch langsamer, da immer wieder ein Funktionsaufruf stattfinden würde, da sollte man doch lieber mit einer Variable arbeiten:


    for(new i,l=GetMaxPlayers(); i<l; i++)


    //Edit:

    Zitat von iFluX

    new Words[] = {"Hallo", "ich", "bin", "ein", "Loop!"};


    Damit man da also schneller durch Loopen kann, sollte man es konstant deklarieren:


    stock const Words[][] = //ja btw das sollte 2 Dimensional sein, damit man auf die einzelnen chars zugreifen kann
    {
    "Hallo", "ich", "bin", "ein", "Loop!"
    };


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

    Einmal editiert, zuletzt von Kaliber ()

  • Man sollte aber auch wissen das mein eine constance variable nicht mit dem Code modifizieren kann.
    In den meisten fällen fällt deshalb die Konstante weg.



    GetMaxPlayers macht die Schleife nicht langsamer sondern schneller soweit ich weiß.

  • In den meisten fällen fällt deshalb die Konstante weg.


    Im Gegenteil.


    Man sollte viel lieber schauen, ob man nicht doch das als Konstante nutzen könnte.


    In den wenigsten Fällen ist eine Variable notwendig als Schleifen-Bedingung ;)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S


  • Damit meinte ich das die Leute die Konstante weg lassen :P
    Konstanten könnte man z.B bei Fraktions Arrays verwenden oder bei sachen die man eh ins Script Hardcoded.


    Ich schau mal wenn ich zuhause bin welches nun wirklich schneller ist.

  • GetMaxPlayers macht die Schleife nicht langsamer sondern schneller soweit ich weiß.


    Nicht wirklich, du rufst jedesmal die Funktion auf, das mag bei niedriger Zahl noch schneller als die direkte Konstante sein, aber das rentiert sich im Grunde nicht.

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • Nicht wenn man es vorerst in eine globale Variable speichert und es im callback ongamemodeinit aufruft.


    Es ging doch gerade eben noch um Die funktion in der Schleife oder irre ich mich :huh:


    Wenn man es so betrachtet, wäre es immer noch besser die MAX_PLAYERS Konstante neu zu deklarieren


    #undef MAX_PLAYERS
    #define MAX_PLAYERS 20 // Oder eine andere Zahl


    Das wäre immer noch "schneller" als dauernd aus dem Speicher zu lesen.


    Wenn man jetzt aber die Funktion benötogt um bspw. durch einen String zu "loopen" sollte man so vorgehen
    for(new i = 0, len = strlen(string); i != len; i++)
    {
    // Hier wird gearbeitet ...
    }


    Das könnte man auch auf GetMaxPlayers beziehen :thumbup:

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • Ich hatte mich oben eben etwas falsch ausgedrückt entschuldigung wenn es falsch aufgenommen wurde.
    Wie oben im Tutorial meinte ich damit die Variable gleich wenn der Server gestartet wird mit GetMaxPlayers zu beschreiben.
    Natürlich ist es besser die Definition von MAX_PLAYERS neu zu definieren, so steht es auch oben im Tutorial.
    Ja, es ist auch schneller wenn man es nicht jedesmal aus dem Speicher lesen muss.
    Eigentlich wollte ich in diesem Tutorial nicht auf Geschwindigkeit beruhen lassen aber ich hab es hinzugefügt.
    Danke für eure Antworten :)


    Es ging doch gerade eben noch um Die funktion in der Schleife oder irre ich mich :huh:


    Nein BlackAce du irrst dich nicht!


    H4rd_B4se wie schon ich denke der Unterschied zwischen einer Variable und einer Funktion sollte allen klar sein?
    Ich weiß nicht für wie dumm einen die Leute abstempeln oder jemanden halten falls man sich mal falsch ausdrückt.

    Einmal editiert, zuletzt von Warren ()