Boolean, Vergleiche und bedingte Verzweigungen

    • Allgemein

    Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von jvbsl.

      Boolean, Vergleiche und bedingte Verzweigungen

      Ziemlich oft bekommt man solchen Code zu sehen:

      VB.NET-Quellcode

      1. If CheckBox1.Checked = True Then
      2. Label1.Visible = True
      3. Else
      4. Label1.Visible = False
      5. End If
      Eigentlich nicht weiter dramatisch, tut was es soll, nur wird daran deutlich, dass der Autor ein paar Verständnis-Lücken im Bereich Boolean, Vergleichen und Code-Verzweigungen aufweist.

      Was ist ein Boolean?
      Boolean ist ein Datentyp, der eine Bedingung ausdrückt. Ein Boolean kann als Wert nur eine von 2 Konstanten aufweisen: True oder False

      Und dieser Datentyp hat eine besondere Besonderheit:
      Boolean ist der Datentyp, mit dem bedingte Programm-Verzweigungen codiert werden - einen anderen Datentyp gibts dafür nicht.

      Was macht ein Vergleichs-Operator?

      Der führt eine Rechnung durch, deren Ergebnis vom Typ Boolean ist

      Was ist nun falsch daran, auf diese Weise bedingt zu verzweigen?

      VB.NET-Quellcode

      1. If CheckBox1.Checked = True Then '...
      Wie gesagt: ist nicht falsch, zeigt aber einen Fehlschluss des Autors, der offenbar denkt, ohne Vergleichs-Operator könne er keine Bedingung formulieren.
      Kanner doch, denn Checkbox.Checked ist ein Boolean - ist also bereits die Bedingung.
      Und diese Bedingung nun nochmal mit True zu vergleichen ist nur eine sinnlose Rechenoperation, bei der garantiert nichts neues rauskommt.
      "Richtig" formuliert reicht also:

      VB.NET-Quellcode

      1. If CheckBox1.Checked Then '...
      Die "falsche" Formulierung ist wie "gestelztes Deutsch":
      "Wenn es wahr ist, dass die Checkbox gecheckt ist..." statt einfach: "Wenn die Checkbox gecheckt ist..."

      Liegt ein Wert vom Typ Boolean vor, so ist ein Vergleichs-Operator nicht erforderlich, um eine Bedingung zu formulieren. Der Boolean ist die Bedingung. (und der Vergleichsoperator ist die Bedingung nicht)

      Ein Vergleichsoperator ist halt ein Operator - der rechnet was aus. Macht nur Sinn, wenn ein Boolean nicht direkt vorliegt, sondern auszurechnen ist (etwa aus 2 Integer):

      VB.NET-Quellcode

      1. If 3 < 9 Then '...


      Klar Soweit?
      https://www.youtube.com/watch?v=wzKWBBKd7pw




      Aber auch nach Korrektur ist das immer noch Unfug:

      VB.NET-Quellcode

      1. If CheckBox1.Checked Then
      2. Label1.Visible = True
      3. Else
      4. Label1.Visible = False
      5. End If
      Denn Label1.Visible ist ja auch ein Boolean! 8o
      Da braucht man doch keine Verzweigung zu schreiben, wenn dieser Boolean denselben Wert bekommen soll wie CheckBox1.Checked!
      Sondern kurz und schmerzlos:

      VB.NET-Quellcode

      1. Label1.Visible = CheckBox1.Checked

      Um einem Boolean-Member einen Wert zuzuweisen bedarf es keiner Verzweigung

      Man kann einem Boolean auch logische Ausdrücke zuweisen, denn ein boolscher Ausdruck ergibt immer einen Boolean (wer hätte das gedacht ;) ) - paar Beispiele:

      VB.NET-Quellcode

      1. Dim a = 9, b = 13
      2. Label1.Visible = a > b 'Label1 nur sichtbar, wenn a größer als b ist
      3. 'Label1 unsichtbar, wenn beide Checkboxen gecheckt sind
      4. Label1.Visible = Not (CheckBox1.Checked AndAlso CheckBox2.Checked)
      5. 'boolsche Ausdrücke können beliebig komplex werden - ihr Ergebnis ist: Boolean - was sonst?
      6. Label1.Visible = a > b AndAlso Not (CheckBox1.Checked AndAlso CheckBox2.Checked)



      Übrigens ist If nicht die einzige Programm-Verzweigung - weitere bedingte Verzweigungsformen sind: Select Case, For Each, For i, While, Do Loop Until / While
      Jeder hats gemerkt: Schleifen-Konstrukte sind auch bedingte Verzweigungen - Ausnahme: das un-bedingte Do Loop
      Wobei bei den For-Schleifen die Bedingung fest eingebaut ist - nur die Schlüsselworte Until und While erwarten explizit einen Boolean
      Hier nochmal kleines Falsch-Richtig-Sample auch für Schleifen:

      VB.NET-Quellcode

      1. Private Sub DontDoSo()
      2. Dim b As Boolean
      3. If b = True Then
      4. End If
      5. If b = False Then
      6. End If
      7. While b = True
      8. End While
      9. While b = False
      10. End While
      11. End Sub

      VB.NET-Quellcode

      1. Private Sub BetterDoSo()
      2. Dim b As Boolean
      3. If b Then
      4. End If
      5. If Not b Then
      6. End If
      7. While b
      8. End While
      9. Do Until b
      10. Loop
      11. End Sub
      Beachte, dass man statt eines While Not b noch eleganter Do Until b formulieren kann.



      Also nochmal die 3 Merksätze
      1. Boolean ist der Datentyp, mit dem bedingte Verzweigungen codiert werden
      2. Liegt ein Wert vom Typ Boolean vor, so ist ein Vergleichs-Operator nicht erforderlich, um eine Bedingung zu formulieren. Der Boolean ist die Bedingung.
      3. Um einem Boolean-Member einen Wert zuzuweisen bedarf es keiner Verzweigung
      Ach - hier noch ein 4. Merksatz:
      4.Vergleiche mit den Konstanten True / False sind immer Unfug
      Beim Vergleich mit True kommt immer dasselbe raus - kann und sollte also weggelassen werden (s.o.: "gestelztes Deutsch").
      Beim Vergleich mit False kommt immer das Gegenteil raus - hierfür verwende man aber den Not - Operator.

      Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von „ErfinderDesRades“ ()

      ErfinderDesRades schrieb:

      Boolean ist der Datentyp, mit dem bedingte Programm-Verzweigungen codiert werden - einen anderen Datentyp gibts dafür nicht.

      Möchte eigentlich nur den Zusatz einbringen, dass dies nicht für alle Sprachen gilt, siehe C++/C oder gar direkt ASM dort ist ein Zahlwert der Datentyp für die IF-Anweisungen, da solche Dinge auch intern mit Zahlen leichter geregelt werden können. Oft kann man nämlich nur überprüfen ob ein Wert 0 ist, kleiner 0 oder größer 0.
      somit wird der Vergleich a > b
      zu a - b > 0

      Bin mir auch nicht sicher, ob das hier nicht fehl am Platz ist, aber auch wenn es im Bereich .Net gepostet würde, sollt man das vlt. auch noch klar machen, dass man in anderen Sprachen nicht auch direkt davon ausgeht.
      Edit: Nach Absprache mit EDR
      Als Beispiel kann man in C und C++(Aufgrund von Abwärtskompatibilität mit C - und jenach Kompileroptionen) folgendes schreiben:

      C-Quellcode

      1. if (9)//true
      2. {
      3. }

      Um zu zeigen wofür soetwas in C Sinn ergibt ein Beispiel:

      C-Quellcode

      1. FILE* fhandle = fopen("Datei.txt","r");
      2. if (fhandle)//fhandle entweder NULL(0) -> Fehler beim öffnen der Datei oder != 0 datei wurde geöffnet
      3. {
      4. //Datei geöffnet
      5. }

      was vollkommen legitim ist. Intern werden Bools auch nicht anders behandelt als ints, somit entspricht false der Zahl 0 und true kann theoretisch alles beliebige sein, was nicht 0 entspricht(heißt sobald ein Bit gesetzt ist entspricht der Zahlenwert true), es wird aber gerne der größtmögliche Zahlenwert für die Konstante true verwendet 0xFFFFFFFF(uint) - entspricht -1(int), da hier alle Bits gesetzt sind.
      Somit können verundungen mit beliebigem int und der konstante true auch nur dasselbe Ergebnis erzielen(so wie es auch erwartet wird).

      C-Quellcode

      1. int val = 11;
      2. val = val & (int)true;//unnötige Operation
      3. //val == 11
      4. if (val == true)//wird nicht wahr ergeben->Achtung Typsicherheit ;)
      5. {
      6. }
      7. bool res = val == 11;
      8. if (res == true)//Redundanter Code
      9. //intern a=0xFFFFFFFF - 0xFFFFFFFF -> a==0?->unnötige Operation
      10. {
      11. }


      Trotzdem sollte man in C++ diese Option nur verwenden, wenn man C Code verwenden muss und nicht die Zeit/das Geld hat diese Dinge zu konvertieren. Denn alle modernen Hochsprachen versuchen möglichst Typsicher zu sein und somit verwendet man bools für Bedingte Verzweigungen und Ints zum Rechnen.
      Ich wollte auch mal ne total überflüssige Signatur:
      ---Leer---

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jvbsl“ ()