AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi boolsche Variable abfragen, aber wie genau(Anfängerfrage...)
Thema durchsuchen
Ansicht
Themen-Optionen

boolsche Variable abfragen, aber wie genau(Anfängerfrage...)

Ein Thema von juergen · begonnen am 28. Aug 2006 · letzter Beitrag vom 29. Aug 2006
Antwort Antwort
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#1

boolsche Variable abfragen, aber wie genau(Anfängerfrage...)

  Alt 28. Aug 2006, 22:29
Hallo zusammen,
"irgendwann" und "irgendwo" hatte ich hier in den letzten Tagen etwas gelesen, wo darauf hingewiesen wurde, dass man boolsche Variablen nicht direkt abfragen soll:
Delphi-Quellcode:
if MyBoolVar = true then
  begin...
(meine bisherige Verfahrensweise)

sondern einfach:

Delphi-Quellcode:
if MyBolVar then
  begin...
Irgendwie ging mir das ganze nicht mehr aus dem Kopf, allzumal ich (leider nicht nachvollziehbar) ein einziges Mal in einem kl.Prog von mir einen für mich bis heute nicht nachvollziehbaren Fehler hatte/habe...
Im Nachhinein könnte das ganze sogar mit der Abfrage einer Varibale zu tun haben, welche ich im OnCreate der Hauptform abfrage.

Ist es nun Gesetz eine boolsche Variable nicht direkt abzufragen und wenn ja warum?
Muss eine boolsche Variable überhaupt initialisiert werden?

Schon mal Danke für die Antworten!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.195 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 28. Aug 2006, 22:36
In Delphi/Pacal oder anderen Sprachen die einen vernünftigen Boolean-Typ haben ist es egal.
Gefährlich kann es in C/(C++ glaube ich auch nicht) werden da es dort ja keinen Boolean-Typ gibt und TRUE/FALSE nur 2 Integer-Konstanten sind und in jedem Projekt so ziemlich 100 mal Boolean definiert wird.

Sinnvollerweise sollte es so sein:

Code:
  FALSE = 0;
  TRUE != FALSE;
oft wird aber auch

Code:
  FALSE = 0;
  TRUE = 1;
genommen und wenn dann eine Funktion als Boolean-Wert 2 zurückgibt steht man vor einem Problem
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 28. Aug 2006, 22:36
Das Vergleichen einer Boolean-Vraibale mit True oder False ist unnötig, da ein Vergleich auch ein Boolean als Ergebnis liefert.

if MyBoolVar = true wird dann zu if True=True was das selbe wie if True ist.

Zitat:
Muss eine boolsche Variable überhaupt initialisiert werden?
Ja.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#4

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 28. Aug 2006, 22:45
initialisieren?

Du musst gar nix initilisieren. eine nicht initialisierte variable solltest du aber immer als undefiniert betrachten.

Den vergleich "SomeBool = true" sollte man deswegen nicht machen, weil es ziemlich viele verschiedene Booleans "da draussen" gibt und evtl. eben irgendwann DIESER Vergleich fehlschlägt, obwohl die Variable auf einem zulässigen True-Wert steht und der normale Vergleich auch dieses Ergebnis hätte. True hat nänmlich einen bestimmten Wert, nämlich 1, während alle Werte außer False (0) per definitionem als True auszuwerten sind. Dannn sind die Aussagen "Das Flag ist gesetzt" und "Das Flag hat den Wert True" nicht äquivalent.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von Sharky
Sharky

Registriert seit: 29. Mai 2002
Ort: Frankfurt
8.252 Beiträge
 
Delphi 2006 Professional
 
#5

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 29. Aug 2006, 07:30
Hai juergen,

hier einmal ein Beispiel was passieren kann wenn man auf xxx = True prüft. (Das ist natürlich eine Vergewaltigung einer Bool-Variablen was ich da macht *g*)
Delphi-Quellcode:
var
  myBool: Boolean;

procedure TDemo_Form.FormCreate(Sender: TObject);
begin
  myBool := False;
  SetLabelText;
end;

procedure TDemo_Form.SetLabelText;
begin
  if (myBool) then
  begin
    Label1.Caption := 'myBool ist True';
  end
  else
  begin
    Label1.Caption := 'myBool ist nicht True';
  end;

  if (myBool = True) then
  begin
    Label2.Caption := 'myBool ist True';
  end
  else
  begin
    Label2.Caption := 'myBool ist nicht True';
  end;

  Label3.Caption := Format('myBool hat den "Wert" %d', [Integer(myBool)]);
end;

procedure TDemo_Form.SpinButton1DownClick(Sender: TObject);
begin
  if (myBool) then
    Dec(myBool);
  SetLabelText;
end;

procedure TDemo_Form.SpinButton1UpClick(Sender: TObject);
begin
  Inc(myBool);
  SetLabelText;
end;
Angehängte Dateien
Dateityp: zip demoform_100.zip (6,4 KB, 10x aufgerufen)
Stephan B.
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#6

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 29. Aug 2006, 08:54
Mal abgesehen von den Fehlermöglichkeiten ist die einfache Variante IMHO auch die natürlichere. Du sagst doch "Wenn meine Form den Fokus hat, dann..." und nicht "Wenn es wahr ist, dass meine Form den Fokus hat, dann...". Folglichif MyForm.IsFocused then statt if MyForm.IsFocused = True then .

Uli.
Uli Gerhardt
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#7

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 29. Aug 2006, 09:33
Zitat von juergen:
Muss eine boolsche Variable überhaupt initialisiert werden?
Hi,
ich denke hier sollte nocheinmal klar gesagt werden, dass du boolsche Variablen immer initialisieren solltest! Hier wurde zwar schon gesagt, dass die sonst undefiniert sind, aber die Konsequenzen sollten einem auch klar sein.
Instanzvariablen (also Variablen die zu einer Klassen-Instanz gehören) werden immer initialisiert. Hast du hier einen Boolschen Wert ist der auch initialisiert, die Frage ist also nur True oder False?
Da man mit boolschen Werten i.d.R. einen Zustand anzeigt und man diesen wiederum für den Programmstart leicht festlegen kann, sollte man hier die Variable auch im Konstruktor initialisieren.
Verzichtet man darauf, schafft man sich einen Fehler der nicht immer leicht zu finden ist.

Das Problem lässt sich sogar verallgemeinern! Du solltest jede Variable initialisieren! Das der Wert einer Variablen nicht definiert ist störrt dein Programm sehr wenig. Legst du eine lokale Variable an, so wird einfach ein Speicherbereich genommen, der gerade frei ist, in den diese Variable reinpasst. Natürlich wird der gleiche Speicher immer wieder mal von irgendeinem Programm benutzt (darum kümmert sich Windows). Wird ein Programm / eine Prozedur beendet, werden die verwendeten Speicherbereiche nur als frei markiert. Das heißt die alten Werte stehen hier immer noch.
Ja, dein Programm macht auch das, was es immer tut: Es nimmt den Speicher und interpretiert den vorgefundenen Wert. Mit etwas Glück startest du das Programm und es kracht. Mit etwas Pech passiert nichts und alles läuft wie erwartet.
Gut, letzteres klingt erstmal gar nicht so schlimm. Das Problem ist nur, du hast ein Programm das nicht mehr terminiert. Irgendwann (gerne beim Kunden) ist der Speicher mal mit einem falschen Wert initialisiert, was dann? Hier kann es zu einer Exception kommen, aber auch zu einer Schleife die einfach mal 2.000.000.000 Durchläufe mitmacht oder zu allem anderen.
Hier den Fehler zu finden ist auch um einiges schwieriger, da es ein semantischer Fehler ist, der sich nicht mal ohne weiteres reproduzieren lässt. Je nachdem welcher Wert gerade im entsprechenden Speicher steht geht alles gut oder es treten ganz verschiedene Fehler auf.

Delphi-Quellcode:
procedure doFoo;
var i : Integer;
begin
  // ganz schlecht
  // i wird nicht initialisiert, könnte auch -2^{31} sein
  // das wären eine ganze Menge durchläufe!
  while (i < 10) do
  begin
  end;
  
  // besser:
  i := 0;
  while (i < 10) do
  begin
  end;

  // oder
  for i := 0 to 10 do
  begin
  end;
end;

procedure doMoreFoo;
var bitmap : TBitmap;
begin
  if assigned(Bitmap) then
  begin
    // tja, sehr hohe Chance hier zu landen
    // natürlich wurde die Bitmap nicht angelegt!
    // aber assigned prüft ob die Referenz <> nil ist
    // nil ist dabei die Adresse 0x00000000
    // Das heißt es gibt 2^{32} - 1 Möglichkeiten die ungleich 0 sind.
    // da auf die 0 zu hoffen ist schlecht!
  end;
end;
Deshalb ist die goldene Regel alles zu initialisieren, was man verwendet! Das gilt insbesondere dann auch wieder, wenn du eine Variable freigibst, die noch gelesen werden könnte (und damit implizit für alle Instanzvariablen, die eine Klasse als Datentyp haben). Wenn du diese mittels Free freigibst, dann wird auch schön der Speicher als frei markiert, in dem die Variable lag. Die Referenz die du als Variable speicherst, die wird nicht verändert. Für eine solche Variable ist es nicht möglich zu sagen, ob sie gültig ist oder nicht. Genaugenommen musst du denken die ist gültig. Die zeigt dann auf einen freien (oder anders verwendeten) Speicher und das geht auch nicht gut! Deshalb beim freigeben solcher Variablen FreeAndNil verwenden.

Delphi-Quellcode:
type
  TMyClass = class(TObject)
    private
      FBitmap : TBitmap;
    protected
      procedure createBitmap;
      procedure doFoo;
      procedure FreeBitmap;
  end;

...

procedure TMyClass.createBitmap;
begin
  // Fehler1 : nicht freigeben der alten Bitmap!
  self.FBitmap := TBitmap.Create;
  self.FBitmap.Width := 512;
  self.FBitmap.Height : 512;
  self.FBitmap.PixelFormat := pf32Bit;
  
  // so, würde zweimal hintereinander createBitmap aufgerufen werden,
  // würde die erste Instanz bis zum Programmende im Speicher liegen
  // das heißt man verschwendet hier 4 Byte * 512 * 512, also ein kleines MByte
  // wenn ich diese Operation jetzt mehrfach aufrufe....


  // besser:
  // erst aufräumen
  FreeAndNil(self.FBitmap);

  // dann neu anlegen
  self.FBitmap := TBitmap.Create;
  self.FBitmap.Width := 512;
  self.FBitmap.Height : 512;
  self.FBitmap.PixelFormat := pf32Bit;
end;

procedure TMyClass.FreeBitmap;
begin
  // 1:
  self.FBitmap.Free;

  // 2:
  FreeAndNil(self.FBitmap);
end;

procedure TMyClass.doFoo;
begin
  // mögliche Probleme nach Aufruf von
  // FreeBitmap
  if assigned(self.FBitmap) then
  begin
    // Probleme variieren zwischen 1 und 2
    // 2 funktioniert immer wie gewünscht!

    // bei 1 wird nur der Speicher auf den self.FBitmap zeigt freigegeben
    // die Adresse, die implizit in self.FBitmap steht bleibt erhalten
    // wurde hier also mittel createBitmap einmal eine gültige Adresse zugewiesen,
    // so würde diese Bedingung wahr sein

    with self.FBitmap do
    begin
      ...
      // dies würde jetzt für 1 zu einem Problem werden!
      // es gibt schließlich keine Bitmap mehr!
    end;
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: boolsche Variable abfragen, aber wie genau(Anfängerfrage

  Alt 29. Aug 2006, 19:54
Hallo zusammen,
für die ganzen Antworten: allen herzlichen Dank!!!

Mir ist eines klar gewurden:
ich muss unbedingt meine Einstellung zur boolschen Variable ändern!
Das Beispiel von Sharky ist hier (für mich) sehr anschaulich.
Schnell erkennt man, dass jeder Wert einer boolschen Varibale <> 0 dann auch immer true ist und eine Prüfung impliziet auf
(myBool = True) hier einen falschen Wert liefert.

@ Der_Unwissende
du weißt schon, dass deine ausführlichen Beschreibungen auch etwas "Angst" in mir geweckt haben?
Bis jetztb hatte ich "Zahlen"- und Stringvariablen auch immer schön initialisiert.
Auch evtl. vorhandene Variablen die eine Klasse als Datentyp haben, hatte ich immer schön per FreeAndNil freigegeben.
Die boolschen Variablen hatte ich leider nicht immer initialisiert...
Da werde ich einiges nacharbeiten.

Grüße und einen schönen Abend!
Jürgen
Jürgen
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz