Überprüfung eines if-else-Statements (mit zwei über und verbundenen Bedingungen)

  • GM 8
  • Überprüfung eines if-else-Statements (mit zwei über und verbundenen Bedingungen)

    Das interessiert mich generell. Ich habe folgende Art von Code

    GML-Quellcode

    1. if (bla == true && keks == true)
    2. {//tu irgendwas}
    3. else
    4. {//irgendwas anderes}

    Bei dem else: wird es ausgelöst wenn bla und keks false sind oder "reicht" eine falsche Bedingung das, dass else ausgelöst wird?

    Mir fällt es schwer mich vernünftig auszudrücken (wie ihr vielleicht merkt :))
    GML lernen geht leicht :)
    1. http://www.gm-d.de/help/ (deutsch)
    2. gm-d.de/wbb/index.php/Thread/2270/ (Einsteiger-Referenz)
    3. docs.yoyogames.com/ (Hilfe auf Englisch von GM:S)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Sk.Info.k.P. ()

  • Achtung, monströse Textwand direkt voraus!


    Okay, dann hier mal ein kleiner Crashkurs in logischen Verknüpfungen. ;)

    (a && b) (AND) - Der ganze Ausdruck ist true, wenn sowohl a als auch b true sind. Ansonsten false.
    (a || b) (OR) - Dieser Ausdruck ist true, wenn a oder b oder beide true sind. Der einzige false-Fall ist, wenn sowohl a als auch b false sind.
    (a ^^ b) (X-OR) - Dieser Ausdruck ist true, wenn a und b verschiedene Werte haben - also eines true ist und das andere false.
    !(a) (NOT) - Dieser Ausdruck ist true, wenn a false ist - und umgekehrt.

    Und nun kann man für a und b im Prinzip beliebig andere logische Verknüpfungen einfügen, die dann verrechnet werden. Ich nehm mal ein ganz absurd komplexes Beispiel und lös es dir schrittweise auf - der Compiler geht im Prinzip genauso vor:

    Nehmen wir mal an, dass a true ist, b false, c false, d true und e wieder false:
    Dann ist ein möglischer logischer Ausdruck, der hinter einem if-Statement stehen könnte:
    !((a||(b^^c)&&!e)&&(b||d)^^(!a||!b)&&(c^^!e)) - erstmal ganz schön unübersichtlich, oder? Aber gehen wir ihn mal der Reihe nach durch.

    1) (b^^c) ist (false XOR false) - die Werte sind gleich, also kommt false raus. Man kann also schreiben:
    !((a||false&&!e)&&(b||d)^^(!a||!b)&&(c^^!e))

    2) && bindet stärker als ||, das bedeutet (false && !e) wird zuerst ausgewertet. Und (false AND NOT false) ist (false AND true), also insgesamt wieder false. Bleibt also:
    !((a||false)&&(b||d)^^(!a||!b)&&(c^^!e))

    3) (true OR false) ergibt insgesamt true, d.h. die erste Klammer ist vollständig aufgelöst.
    !((true)&&(b||d)^^(!a||!b)&&(c^^!e))

    4) Wie gesagt, && ist der stärkere Operator vor || und dementsprechend auch vor ^^ - das ist ja im Prinzip nur ein Spezialfall von ||. Nachdem man also (b||d) als true erkannt hat, ist die nächste Verknüpfung:
    !(true&&true^^(!a||!b)&&(c^^!e))

    5) (true && true) ergibt wieder true, nun interessiert uns also die andere Seite des ^^-Operators. Fangen wir vorne an. (NOT a ist false, NOT b ist true, also ist (!a OR !b) ebenfalls true. Das kann man sogar verallgemeinern: Wenn du zwei Bedingungen hast, die unterschiedliche Bool-Werte erzeugen - also einer true, der andere false - kannst du beide negieren und kriegst trotzdem noch das selbe Ergebnis raus.
    Jedenfalls, das Monstrum wird noch etwas kleiner:
    !(true^^true&&(c^^!e))

    6) Nicht vergessen, && ist der stärkste, also gucken wir uns jetzt (c^^!e) an, also (c XOR (NOT e)) - c und e sind beide false, das negierte e ist also true - und (false XOR true) ergibt true. Jetzt wird's langsam übersichtlich!
    !(true^^true&&true)

    7) (true AND true) ergibt true, (true XOR true) ergibt false, ganz am Ende bleibt also übrig:
    !(false)

    - und das ist true; die if-Bedingung wird also ausgeführt.

    Und nun der Clou: Die else-Bedingung wird nur ausgeführt, wenn in Schritt 7, also gaaaaaaaaaaaaaaaaaaaaaaaanz am Ende ein false rauskommt. Der Weg durch diese ganzen höllisch kompliziert aussehenden Rechnungen ist dem Ding da völlig egal - einzig und allein das Endergebnis zählt.

    So, das war jetzt wahrscheinlich viel zu ausführlich und bei meinem Glück hab ich auch irgendwo noch nen Faselfehler drin und werde dafür von boxxar ausgelacht oder sowas. Zum guten Schluss sei aber noch gesagt, dass diese a,b,c,d und e im Prinzip durch beliebige Codeschnipsel ersetzt werden können; z.B. (global.HP>=0) oder (x mod 31 == 10) oder (instance_create(x,y,foo)!=0). Die Arbeitsweise ist immer die gleiche: Es wird alles von innen nach außen ausgewertet, Rechenregeln werden beachtet und erst das, was ganze am Ende rauskommt, zählt für den weiteren Programmverlauf.

    Wenn du da noch ein bisschen drüber lesen willst: Das Schlüsselwörtchen ist Boolesche Algebra (das ist allerdings ganz schöner Mathesprech auf dieser Wikiseite - es gibt bestimmt auch Online-Tutorials, die da nen besseren Überblick schaffen.)


    Edit:
    wtf ey, hab ich jetzt echt 30 Minuten an diesem Post rumgeschreibselt? Hoffentlich hat's wenigstens was gebracht. ^^