Object Pascal im Detail - Datentypen www.delphi-treff.de
59
b1 := True; b2 := True;
if b1 = b2 then ... wird ausgeführt
4.2.2.1.5. xor
o A ti ale z, e klusi es ode ist u das aus de allge ei e “p a hge au h eka te „e t ede ...ode . Der resultierende Wahrheitswert ist genau dann wahr, wenn entweder der eine oder der andere, nicht aber
beide Werte wahr sind also unterschiedlich: var
b1, b2: Boolean; begin
b1 := True; b2 := True;
if b1 xor b2 then ... wird nicht ausgeführt
4.2.2.2. Programmieren mit Boolean-Werten
Genug der grauen Theorie. Sehen wir uns nun einmal an, wo uns beim Programmieren überall Boolean-Werte begegnen:
4.2.2.2.1. Boolean-Variablen
var b: Boolean;
Boolean-Variablen werden genauso deklariert, wie Integer und Stringvariablen z.B. auch. Rechnen kann man damit, wie oben beschrieben, mit den Operatoren and, or, not, xor und =. Dabei ist auch die Klammerung
wichtig. Also im Zweifelsfall lieber mehr Klammern setzen...
4.2.2.2.2. Funktionsrückgabewert
Viele Funktionen liefern als Ergebnis einen Boolean-Wert zurück. Dieser lässt sich dann auch in einer Variablen speichern:
Object Pascal im Detail - Datentypen www.delphi-treff.de
60
var ok: Boolean;
begin ok := OpenDialog1.Execute;
Execute gibt einen Boolean-Wert zurück oder gleich auswerten:
if SaveDialog1.Execute then SaveFile;
4.2.2.2.3. Properties
if CheckBox1.Checked then ...
4.2.2.2.4. Boolean-Ausdrücke
if a b then DoSth;
a b ist hierbei ein Boolean-Ausdruck. Dieser ist genau dann True, wenn a größer als b ist... ;-
4.2.2.2.5. Kurzschluss?
Zur Auswertung von Boolean-Ausdrücken ist noch Folgendes zu sagen: Bei
if a and b then wird u.U. b gar nicht mehr geprüft, wenn a schon false ist. Ebenso ist es mit
if a or b Hier wird die Auswertung unterbrochen, wenn a schon true ist. Dieses Verhalten wird manchmal Kurzschluss-
Auswertung short-circuit evaluation genannt. In den Projektoptionen Projekt--Optionen--Compiler-- Vollst. Boolesche Auswertung kann man dieses Verhalten abstellen. Dies ist jedoch nicht zu empfehlen, da
die VCL diese teilweise recht ausgiebig nutzt. Über entsprechende Compiler-Direktiven lässt sich die Kurzschlussauswertung auch für bestimmte Code-Teile separat ausschalten:
{B} Vollständige Auswertung {B-} Kurzschluss-Auswertung; default
Am einfachsten und übersichtlichsten ist es jedoch, wenn man entsprechende If-Anweisungen einfach schachtelt:
if AssignedObjekt then begin
Object Pascal im Detail - Datentypen www.delphi-treff.de
61
if Objekt.Eigenschaft then begin
... end;
end; statt
if AssignedObjekt and Objekt.Eigenschaft then begin
... end;
So ist auf jeden Fall sicher gestellt, dass auf das Objekt nur zugegriffen wird, wenn dieses auch wirklich existiert...
4.2.2.3. Typische Anfängerfehler
Viele Anfänger haben so ihre Probleme mit den Boolean-Werten. Die wichtigsten Anfänger-Fehler seien hier einmal genannt, damit man auch gleich lernen kann, sie zu vermeiden.
4.2.2.3.1. Doppelt gemoppelt hält besser
if FileExistsFileName = True then ...
oder if FileExistsFileName = False then
... oder
var b := Boolean;
begin b := True;
if b = True then ...
Das alles ist ... falsch, wenn es auch in den meisten Fällen funktioniert. Warum ist es nun falsch?
Das hat im Großen und Ganzen zwei Gründe. Der einleuchtendste zuerst: Ein Boolean ist bereits Boolean. Man schreibt ja auch nicht:
if a b = True then Es ist ei fa h „doppelt ge oppelt .
Für den zweiten Grund gibts erst einmal ein Codebeispiel:
Object Pascal im Detail - Datentypen www.delphi-treff.de
62
Diese Funktion soll das Verhalten mancher WinAPI-Funktionen imitieren: function GaaanzFieseAPIFunktion: Boolean;
asm mov eax, -01
end; procedure TForm1.Button1ClickSender: TObject;
begin if GaaanzFieseAPIFunktion = True then
ShowMessage Pech gehabt. Mich sieht man gar nicht
; if GaaanzFieseAPIFunktion then
ShowMessage Hallo
; end;
Nanu, was passiert denn hier? Es wird ja wirklich nur die zweite Message angezeigt... Das hängt mit der internen Darstellung zusammen. Ein Boolean wird als ganzes Byte gespeichert einzelne Bits
lassen sich nicht direkt speichern. Nun hat aber ein Byte 256 mögliche Werte und nicht nur 2. Es gibt nun ziemlich viele Möglichkeiten, wie man einen Boolean in einem Byte kodieren kann. Nicht alle sind sinnvoll, aber
es gibt immerhin mehrere sinnvolle Möglichkeiten. In Delphi ist False 0 und 1 ist True, wobei alles andere erstmal nicht vorgesehen ist. Das ist aber nicht überall so. Andere Programmiersprachen, Frameworks, APIs
Co. könnten Boolean-Werte ganz anders kodieren und tun dies auch. Sobald man also mit irgendetwas in Berührung kommt, was nicht 100 Delphi ist, muss man vorsichtig sein. Und das ist schneller passiert als man
vielleicht vermutet. Z.B. dann, wenn man auf WinAPI-Funktionen zugreift. Und genau das simuliert dieser Quelltext. Die Dummy-API-Funktion liefert -1 also für die WinApi True zurück.
Da aber -1 1 True ist, funktioniert das nicht ganz so, wie vielleicht gewünscht[4].
Wie macht mans also richtig?
statt if FileExistsFileName = True then
ganz einfach if FileExistsFileName then
statt if FileExistsFileName = False then
richtig: if not FileExistsFileName then
var b := Boolean;
begin b := True;
statt if b = True then
Object Pascal im Detail - Datentypen www.delphi-treff.de
63
richtig: if b then
4.2.2.3.2. für was denn not?