Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Delphi-Anfänger - Was mache ich mit diesem if-Satz falsch?


Timm3r - Fr 10.09.10 18:28
Titel: Delphi-Anfänger - Was mache ich mit diesem if-Satz falsch?
Guten Tag zusammen,

habe gerade das folgende Programm geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm1.AmpelUmschaltenClick(Sender: TObject);
begin
        if
                imAmpelRot.Visible=True

        then begin
                imAmpelRot.Visible:=False
                imAmpelRotGelb.Visible:=True
        end
        else if
                imAmpelRotGelb.Visible=True
        then begin
                imAmpelRotGelb.Visible:=False
                imAmpelGruen.Visible:=True
        end
        else if
                ImAmpelGruen.Visible=True
        then begin
                ImAmpelGruen.Visible:=False
                ImAmpelGelb.Visible:=True
        end
        else
                ImAmpelGelb.Visible:=False
                ImAmpelRot.Visible:=True
        end;                


end.


Das ist halt so ne Ampel die die ganze Zeit umgeschaltet werden soll aber ich rall nicht wierklich was an dem Programm falsch sein soll.

Kann mir einer von euch sagen, wie ich das ändern soll?

Danke im Voraus!

Moderiert von user profile iconKha: Delphi-Tags hinzugefügt


Dude566 - Fr 10.09.10 18:42

Wer sagt denn das etwas falsch ist?


Marc. - Fr 10.09.10 18:43

Hi und :welcome: im Forum!

Zunächst, niemals auf True prüfen! Warum? (Boolean Tutorial) [http://www.delphi-treff.de/tutorials/objectpascal/programmierung-mit-boolean-werten/typische-anfaengerfehler/] :mahn: :zwinker:
Darüberhinaus, was genau funktioniert denn nicht?

Grüße
Marc


mkinzler - Fr 10.09.10 18:58

CrossPost DP [http://www.delphipraxis.net/154442-delphi-anfaenger-mache-ich-mit-diesem-if-satz-falsch.html#post1048751]


jaenicke - Fr 10.09.10 19:09

Erstens fehlen die Semikola am Zeilenende, das sollte dir der Compiler aber auch sagen, dass er jeweils ein ; vermisst.

Zweitens fehlt beim letzten else das begin.

// EDIT:
Ich seh schon, steht auch im Crosspost schon, ganz übersehen.


trm - Fr 10.09.10 19:14

user profile iconMarc. hat folgendes geschrieben Zum zitierten Posting springen:
Hi und :welcome: im Forum!

Zunächst, niemals auf True prüfen! Warum? (Boolean Tutorial) [http://www.delphi-treff.de/tutorials/objectpascal/programmierung-mit-boolean-werten/typische-anfaengerfehler/] :mahn: :zwinker:
Darüberhinaus, was genau funktioniert denn nicht?

Grüße
Marc


Hallo Marc,

Das Tutorial kannte ich nicht. Jedoch habe ich hierzu eine Frage.

Zitat:
In Delphi ist False 0 und 1 ist True, wobei alles andere erstmal nicht vorgesehen ist.

Wenn dem so ist, dürfte man ja von der Definition auch nicht davon ausgehen, dass ein Aufruf, der -1 (wie im Tutorial) zurück gibt, True oder False ist.
Im Beispiel, welches Timmer aufgezeigt hat, kann es nur 2 Zustände geben: Visible oder not(Visible).
Da er ja auf if Visible=True prüft, ergibt das in seinem konkreten Beispiel Wahr oder Falsch.
Ob das bei anderen Dingen später noch genau so funktioniert, ist erst einmal egal.


Warum hast Du aber nicht seine Frage beantwortet ;) ?


user profile iconTimm3r hat folgendes geschrieben Zum zitierten Posting springen:
Guten Tag zusammen,

habe gerade das folgende Programm geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm1.AmpelUmschaltenClick(Sender: TObject);
begin
        if
                imAmpelRot.Visible=True

        then begin
                imAmpelRot.Visible:=False
                imAmpelRotGelb.Visible:=True
        end
        else if
                imAmpelRotGelb.Visible=True
        then begin
                imAmpelRotGelb.Visible:=False
                imAmpelGruen.Visible:=True
        end
        else if
                ImAmpelGruen.Visible=True
        then begin
                ImAmpelGruen.Visible:=False
                ImAmpelGelb.Visible:=True
        end
        else
                ImAmpelGelb.Visible:=False
                ImAmpelRot.Visible:=True
        end;                


end.


Das ist halt so ne Ampel die die ganze Zeit umgeschaltet werden soll aber ich rall nicht wierklich was an dem Programm falsch sein soll.

Kann mir einer von euch sagen, wie ich das ändern soll?

Danke im Voraus!

Moderiert von user profile iconKha: Delphi-Tags hinzugefügt


Ja, kann ich:

beim letzten end else hast Du ein begin und ein end; vergessen. Dadurch wird immer mit ImAmpelRot.Visible:=True die Ampel auf ROT gesetzt, wenn Du einen Button(?) drückst.

Edit: Huch, ein Quersender ;) ?


Jakob_Ullmann - Fr 10.09.10 19:38

user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:

Wenn dem so ist, dürfte man ja von der Definition auch nicht davon ausgehen, dass ein Aufruf, der -1 (wie im Tutorial) zurück gibt, True oder False ist.
Im Beispiel, welches Timmer aufgezeigt hat, kann es nur 2 Zustände geben: Visible oder not(Visible).
Da er ja auf if Visible=True prüft, ergibt das in seinem konkreten Beispiel Wahr oder Falsch.


Also erstmal zu den -1: Soweit ich das in Erinnerung habe, wird beim if / while / usw. 0 als False und alles andere als True interpretiert. Eben deshalb. Wenn er allerdings auf die Konstante True, die als 1 definiert ist, prüft, ist der Vergleich false, da (-1 - 1) alles andere als null ist.
Bei Delphi-only ist das egal. Es ist jedoch sinnvoll, diesen Vergleich wegzulassen. Das hat zwei Gründe:

1. Irgendwann wundert man sich, wenn man mit einem C-Programm kommuniziert (was True nicht als 00000001, sondern als 11111111, also -1, definiert; incl. Windows-API), dass es nicht klappt.

2. Wenn man wirklich verstanden hat, wie Kontrollstrukturen funktionieren, ist es die einzig logische Weise. Du würdest ja auch nicht schreiben


Delphi-Quelltext
1:
2:
3:
4:
if (a = b) = True then
begin
  ...
end;


Anfänger denken meistens, dass muss bei if irgendeine Bedingung sein, irgendwas mit =, <, >, ... Aber sie wissen nicht, dass Boolean dahinter steckt. Und dann kommt auch irgendwann Code wie


Delphi-Quelltext
1:
2:
3:
4:
if a = True then
  b := False
else
  b := True;


anstatt b := not a; heraus. Ich weiß allerdings nicht, in wie weit Delphi da optimiert. Alle, die einen Delphi-Compiler zur Hand haben, können das ja mal eben schnell ausprobieren. Ich könnte mir das durchaus vorstellen, aber es ist trotzdem Schrott, weil es die Lesbarkeit herabsetzt.


jaenicke - Sa 11.09.10 05:29

Hier habe ich mal ein kleines Beispiel gebastelt, wann das mit dem Vergleich auf True schief geht:
http://www.delphi-forum.de/viewtopic.php?p=548760#548760
Und warum das auch vollkommen unlogisch ist:
http://www.delphi-forum.de/viewtopic.php?p=560637#560637


Tranx - Sa 11.09.10 08:06

user profile iconTimm3r hat folgendes geschrieben Zum zitierten Posting springen:
Guten Tag zusammen,

habe gerade das folgende Programm geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm1.AmpelUmschaltenClick(Sender: TObject);
begin
        if
                imAmpelRot.Visible=True

        then begin
                imAmpelRot.Visible:=False
                imAmpelRotGelb.Visible:=True
        end
        else if
                imAmpelRotGelb.Visible=True
        then begin
                imAmpelRotGelb.Visible:=False
                imAmpelGruen.Visible:=True
        end
        else if
                ImAmpelGruen.Visible=True
        then begin
                ImAmpelGruen.Visible:=False
                ImAmpelGelb.Visible:=True
        end
        else
                ImAmpelGelb.Visible:=False
                ImAmpelRot.Visible:=True
        end;                


end.


Das ist halt so ne Ampel die die ganze Zeit umgeschaltet werden soll aber ich rall nicht wierklich was an dem Programm falsch sein soll.

Kann mir einer von euch sagen, wie ich das ändern soll?

Danke im Voraus!

Moderiert von user profile iconKha: Delphi-Tags hinzugefügt


Ich denke, das liegt an dem Quelltext. Das Ganze ist in einer Zeile!!

Schreibe doch besser alles mit begin .. end, dann ist das Ganze übersichtlicher. Ich hoffe, so wie ich es hier schreibe, wird das, was Du willst, klarer:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
        if imAmpelRot.Visible then begin
           imAmpelRot.Visible:=False;
           imAmpelRotGelb.Visible:=True;
        end else if imAmpelRotGelb.Visible then begin
           imAmpelRotGelb.Visible:=False;
           imAmpelGruen.Visible:=True;
        end else if imAmpelGruen.Visible then begin
           imAmpelGruen.Visible:=False;
           imAmpelGelb.Visible:=True;
        end else begin
           imAmpelGelb.Visible:=False;
           imAmpelRot.Visible:=True;
        end;                
//
// "if xx=TRUE then" ist identisch mit "if xx then"
//


Das Entscheidende ist immer die Übersichtlichkeit des Quelltextes. Deswegen mag ich auch C nicht, denn da kann man alles in eine Zeile packen. Wenn dann ein Problem auftritt weiß man nicht, wo dies liegt, weil alles in einer Zeile ist.


jaenicke - Sa 11.09.10 09:51

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
//
// "if xx=TRUE then" ist identisch mit "if xx then"
//
Setzen, 6. Das ist schlicht falsch. Siehe mein Beispiel im Post über dir.

Nur weil es meistens das Gewünschte macht ist es noch lange nicht richtig und schon gar nicht identisch.


Tranx - Sa 11.09.10 10:07

Lieber Sebastian,

Danke für Deine Belehrung. Aber für mich ist - und sicher auch für den Compiler ist es so - dass eine doppelt gemoppelte Schreibweise nicht verkehrt sondern nur unnötig ist. Wahrscheinlich wird der Compiler dies automatisch löschen. Aber dazu weiß ich als einer, der eben eine 6 von einem Oberlehrer bekommen hat, doch wohl zuwenig.

Vielleicht hätte Herr Oberlehrer sich mit den wirklichen Fehlern des Quelltextes auseinandersetzen sollen, statt auf Nickeligkeiten herumzureiten!!!

Aber danke noch mal für die 6.


jaenicke - Sa 11.09.10 10:14

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Aber für mich ist - und sicher auch für den Compiler ist es so - dass eine doppelt gemoppelte Schreibweise nicht verkehrt sondern nur unnötig ist.
In diesem Fall ja. Aber eben nicht immer. Und wenn du dir das Beispiel angesehen (oder ausprobiert hättest, wenn ansehen nicht reicht), dann wäre dir das auch klar...

Wenn man sich das dann als Anfänger angewöhnt, wundert man sich hinterher warum andere Quelltexte mit API-Zugriffen nicht funktionieren.


Tranx - Sa 11.09.10 10:17

Der Hauptfehler war aber nicht - im vorliegenden Fall - die Vergleiche mit TRUE sondern der Befehlscode in einer Zeile. Deshalb hat das Ganze nicht funktioniert. Vielleicht schaust Du mal mein Beispiel an, und den Quellcode des Fragenden.


jaenicke - Sa 11.09.10 10:19

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Der Hauptfehler war aber nicht - im vorliegenden Fall - die Vergleiche mit TRUE sondern der Befehlscode in einer Zeile.
Dass da die Semikola und ein begin fehlten, hatte ich schon gaanz oben geschrieben.


Tranx - Sa 11.09.10 10:22

Und was ist dann konkret an meinem Code-Vorschlag, das Problem zu lösen - abgesehen von meiner unqualifizierten Kommentarzeile! - falsch???

Geht es nicht darum, dem Fragenden eine Lösung anzubieten, oder nicht?


jaenicke - Sa 11.09.10 10:25

Nichts, ich hatte mich verguckt, ich hatte das "=True" auch in deinem Quelltext gesehen. :gruebel:
Tut mir leid, nur wegen dem Kommentar hätte ich das nicht geschrieben.


Jakob_Ullmann - Sa 11.09.10 11:52

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Und was ist dann konkret an meinem Code-Vorschlag, das Problem zu lösen - abgesehen von meiner unqualifizierten Kommentarzeile! - falsch???

Geht es nicht darum, dem Fragenden eine Lösung anzubieten, oder nicht?


Ja, aber nachdem Marc. darauf hingewiesen hatte und die Diskussion in eine unschöne Richtung lief, musste das Problem einfach geklärt werden. Und es ging AUSSCHLIESSLICH darum, denn, wie jaenicke schon sagte, kam die Lösung zum Problem ganz weit oben bereits.

Übrigens muss ich mich korrigieren.

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
1. Irgendwann wundert man sich, wenn man mit einem C-Programm kommuniziert (was True nicht als 00000001, sondern als 11111111, also -1, definiert; incl. Windows-API), dass es nicht klappt.



Auch C++ definiert true als 1.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
#include <iostream>

int main()
{
  bool a = true;
  std::cout << static_cast<int>(a) << std::endl;
  return 0;
}


Und C kennt kein bool. Ändert aber nichts daran, dass API-Funktionen -1 als WAHR nehmen (was meiner Meinung auch mehr Sinn macht, da man dann nicht zwischen bitweisen und logischen Operationen unterscheiden muss).

ÜBRIGENS:

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Das Entscheidende ist immer die Übersichtlichkeit des Quelltextes. Deswegen mag ich auch C nicht, denn da kann man alles in eine Zeile packen. Wenn dann ein Problem auftritt weiß man nicht, wo dies liegt, weil alles in einer Zeile ist.


Du kannst auch in Delphi alles in eine Zeile packen. Ich empfinde C, wenn man halbwegs diszipliniert schreibt, mittlerweile als übersichtlicher, da vieles nicht durch Wörter, sondern durch Symbole ({...} statt begin ... end; &&/& statt and, ...) ausgedrückt wird und du besser Quelltext von Struktur trennen kannst, Wenn du aber alles in eine Zeile packst, brauchst du dich nicht zu wundern, wenn es unübersichtlich wird. Es gibt für C genügend Code-Formatierer für alle möglichen Indent-Styles.


mkinzler - Sa 11.09.10 11:56

False ist 0 und True <> 0.
Deshalb sollte man nie auf True Testen. Zudem liefert eine Vergleich einen Boolean und man braucht, wenn man schoen einen hat, den nicht mehr Testen


trm - Sa 11.09.10 13:21

Hi.

Sollte man also, wenn man nicht auf True prüfen sollte, dann generell auf False prüfen?

Also eben statt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if panel1.visible then
begin
showmessage('panel1 ist sichtbar');
end
else
begin
showmessage('panel1 ist NICHT sichtbar');
end;


..das hier:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if not panel1.visible then
begin
showmessage('panel1 ist NICHT sichtbar');
end
else
begin
showmessage('panel1 ist sichtbar');
end;


Oder sollte man, so wie ich es ganz gern mache - da ich persönlich else - Konstrukte HASSE (wegen der unübersichtlichkeit - folgendes nutzen:


Delphi-Quelltext
1:
2:
3:
4:
Case panel1.visible of
True: showmessage('panel1 ist sichtbar');
False: showmessage('panel1 ist NICHT sichtbar');
end;


Oder als Alternative:


Delphi-Quelltext
1:
2:
3:
4:
if panel1.visible then
showmessage('panel1 ist sichtbar');
if not panel1.visible then
showmessage('panel1 ist NICHT sichtbar');


Was sagen die Profis dazu?


mkinzler - Sa 11.09.10 13:25

Nein, aber nicht

Delphi-Quelltext
1:
if panel1.visible = True then                    


jaenicke - Sa 11.09.10 16:37

user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
Oder sollte man, so wie ich es ganz gern mache - da ich persönlich else - Konstrukte HASSE (wegen der unübersichtlichkeit - folgendes nutzen:
Der Logik wegen sind die aber durchaus sinnvoll. Denn wenn du darauf verzichtest, musst du darauf achten, dass die weiteren if-Abfragen nicht durch das erste if verändert werden (es sei denn das ist gewollt).

Das kann man natürlich auch lösen, ich finde es nur nicht wirklich übersichtlicher als mit else. Aber das ist Ansichtssache.

user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
Case panel1.visible of
True: showmessage('panel1 ist sichtbar');
False: showmessage('panel1 ist NICHT sichtbar');
end;
Genau das ist nicht gut. Denn auch hier prüfst du auf True oder False. Du kannst natürlich noch ein else hinzufügen, aber das ist dann erst recht unübersichtlich.

Die drei anderen Varianten sind alle ok.


mkinzler - Sa 11.09.10 17:09

Bei nur 2 möglichen Werten ist ein Case-konstrkt sowieso überflüssig


jaenicke - Sa 11.09.10 17:33

In diesem Fall sind es ja mehr. :mrgreen:

Aber das ist ja auch genau der Punkt. Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var
  a: Boolean;
  c: PByte;
begin
  c := @a;
  c^ := Byte(-1);
  case a of
    True: ShowMessage('case a: True');
    False: ShowMessage('case a: False');
  else
    ShowMessage('case a: else');
  end;
end;
Es wird else ausgelöst.


mkinzler - Sa 11.09.10 17:55

Aber nur wiel auf True geprüft wird! Ein Boolean hat nur 2 mögliche Werte!


jaenicke - Sa 11.09.10 17:58

Ja, natürlich. ;-)


trm - Sa 11.09.10 18:11

Hm, danke für die Antworten.

Noch eine Frage.

Ich nutze in meinen Variablen meistens Dummy-Vars, die ich z.B. so deklariere:


Delphi-Quelltext
1:
2:
3:
4:
var
Dummy_Bool:Boolean;
Dummy_Int:Integer;
[usw]


Wenn ich nun eine Funktion ausführe, die ich selbst erstellt habe, nur, um ein Ergebnis zu erhalten, ob die Funktion fehlerfrei/fehlerhaft war, gebe ich als Result True oder False zurück.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Dummy_Bool:=meinefunktion(a+b);

//jetzt habe ich ja entweder ein True ODER ein False im Ergebnis Dummy_Bool und setze mein Case-Konstrukt ein.

Case Dummy_Bool of
True: ;
False: ;
end;


Wenn ich nun aber z.B. eine Api-Funktion aufrufe, von der ich den Ergebnistyp nicht kenne, mache ich das dennoch genauso:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Dummy_Bool:=dieapifunktion(a+b)=1;

//jetzt habe ich ja auch wieder ENTWEDER ein True ODER ein False im Ergebnis Dummy_Bool und setze mein Case-Konstrukt ein.

Case Dummy_Bool of
True: ;
False: ;
end;


Demzufolge benötige ich nicht, da ich dennoch auf True teste, einen case-Block.

Und das Beste an der Sache: die Lesbarkeit ist um ein vielfaches höher als in if .. else .. - Konstrukten.
Ansonsten, wenn ich keinen Boolean benötige, sondern einen Integer oder sonstwas, nutze ich ebenfalls einen Case-Block:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Dummy_Int:=irgendeinefunktion(a+b);

Case Dummy_Int of
0..5: ;
6..10: ;
11,12,13,15: ;
14: ;
else: ;
end;


Bei einem if.. else wäre das unglaublich komplizierter zu erstellen UND im Anschluß SCHWER lesbar nachzuvollziehen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Dummy_Int:=irgendeinefunktion(a+b);

if (Dummy_Int = 0or (Dummy_Int = 1or (Dummy_Int = 2or (Dummy_Int = 3or (Dummy_Int = 4or (Dummy_Int = 5then
ShowMessage('0-5')
else if (Dummy_Int = 6or (Dummy_Int = 7or (Dummy_Int = 8or (Dummy_Int = 9or (Dummy_Int = 10then
showmessage('6-10')
else if (Dummy_Int = 11or (Dummy_Int = 12or (Dummy_Int = 13or (Dummy_Int = 15then
ShowMessage('11-13 und 15')
else if (Dummy_Int = 14then
ShowMessage('14')
else
ShowMessage('Nichts von 0-15');



..und das waren 'nur' zwei Typen, die ich als Beispiel benutzt habe.

Viele Grüße
~Mathias


mkinzler - Sa 11.09.10 18:14

Der Case ist trotzdem überflüssig weil Dummy-Bool ja ein Boolean ist!

Delphi-Quelltext
1:
if Dummy then ...                    


Delphi-Quelltext
1:
if not Dummy then ...                    


Jakob_Ullmann - Sa 11.09.10 18:25

user profile icontrm:

Erstens gibt es einen Operator in. Du kannst also genauso gut schreiben:


Delphi-Quelltext
1:
2:
3:
4:
if a in [135..9then
begin
  // Ausgeführt wenn a = 1, 3, 5, 6, 7, 8 oder 9
end;


Dahinter stecken sets.

Und zweitens hast du das Problem offenbar nicht verstanden: True ist 1. dieapifunktion()=1 ist genauso falsch, wenn nicht sogar noch schlimmer. Wenn man sowas oft braucht, kann man ja gerne sowas verwenden:


Delphi-Quelltext
1:
2:
3:
4:
function IsTrue(a: Byte): Boolean;
begin
  Result := not (a = 0);
end;


und das so einsetzen:


Delphi-Quelltext
1:
2:
a := dieapifunktion(arg1, arg2, ..., argn);
bool := IsTrue(a); // bool ist true, wenn a <> 0, und false, wenn a = 0


Aber einen Vergleich auf true sollte man nach wie vor vermeiden.

Ich hoffe, wir können das Thema beenden. Wir sind seid mehr als 50% des Threads off-topic.


Tranx - Sa 11.09.10 18:29

Ich gebe Dir Recht, dass Case für integerabfragen sicher einfacher als if..then..else-abfragen sind. Doch Dein Konstrukt

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Dummy_Int:=irgendeinefunktion(a+b);

if (Dummy_Int = 0or (Dummy_Int = 1or (Dummy_Int = 2or (Dummy_Int = 3or (Dummy_Int = 4or (Dummy_Int = 5then
ShowMessage('0-5')
else if (Dummy_Int = 6or (Dummy_Int = 7or (Dummy_Int = 8or (Dummy_Int = 9or (Dummy_Int = 10then
showmessage('6-10')
else if (Dummy_Int = 11or (Dummy_Int = 12or (Dummy_Int = 13or (Dummy_Int = 15then
ShowMessage('11-13 und 15')
else if (Dummy_Int = 14then
ShowMessage('14')
else
ShowMessage('Nichts von 0-15');


ist doch etwas zu komplex geraten, es ginge auch so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Dummy_Int:=irgendeinefunktion(a+b);

if (Dummy_Int >= 0and (Dummy_Int <= 5then
ShowMessage('0-5')
else if (Dummy_Int >= 6and (Dummy_Int <= 10then
showmessage('6-10')
else if ((Dummy_Int >= 11and (Dummy_Int <= 13)) or (Dummy_Int = 15then
ShowMessage('11-13 und 15')
else if (Dummy_Int = 14then
ShowMessage('14')
else
ShowMessage('Nichts von 0-15');


Aber - wie gesagt, Case ist übersichtlicher und auch leichter zu editieren. Doch manchmal geht es eben nicht, wenn keine aufzählbaren Typen abgefragt werden, oder nicht nur eine Variable oder gar ein Funktionsergebnis. Dann kommt man um if..then..else nicht drum rum, oder?


Jakob_Ullmann - Sa 11.09.10 18:37

Oder so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Dummy_Int:=irgendeinefunktion(a+b);
// 0..5
if Dummy_int in [0..5then
  ShowMessage('0-5')
// 6..10
else if Dummy_int in [6..10then
  showmessage('6-10')
// 1..3, 15
else if Dummy_Int in [11..1315then
  ShowMessage('11-13 und 15')
// 14
else if Dummy_Int = 14 then
   ShowMessage('14')
// sonst
else
  ShowMessage('Nichts von 0-15');


trm - Sa 11.09.10 18:45

Ich wollte noch bemerken, dass es Sets gibt, dachte mir aber, dass dies von Euch nicht gesehen wird ;)

@Jakob:
Danke, habe ich nicht bedacht.

~Für mich ist das Thema hier genug erörtert, danke Euch :)

Viele Grüße
~Mathias


guinnes - Sa 11.09.10 18:49

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Oder so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Dummy_Int:=irgendeinefunktion(a+b);
// 0..5
if Dummy_int in [0..5then
  ShowMessage('0-5')
// 6..10
else if Dummy_int in [6..10then
  showmessage('6-10')
// 1..3, 15
else if Dummy_Int in [11..1315then
  ShowMessage('11-13 und 15')
// 14
else if Dummy_Int = 14 then
   ShowMessage('14')
// sonst
else
  ShowMessage('Nichts von 0-15');
Warum in dem Fall nicht case ?

Delphi-Quelltext
1:
2:
3:
Case Dummy_Int of
  0..5  : Showmessage('0..5');
  6..19 : Showmessage('6..19');


Henneberg - Mi 01.12.10 20:45

Hey ich hab jetzt nochma ne frage dazu..
wir sollten für die schule ein programm mit einigen edits und checkboxen schreiben
allerdings sollte z.B. edit3 nur dann zu sehen sein wenn checkbox1.checked..
also hab ich das so gemacht(Edit3 ist schon auf visible=false)

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormCreate(Sender: TObject);
begin
if Checkbox1.Checked then Edit3.Visible := true else Edit3.Visible := False;
end;
da sieht man es gar nicht egal was man macht..

und wenn ich es so mache

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
procedure TForm1.Button1Click(Sender: TObject);
var Alter, Jahre,Zigaretten  :real;
begin
Alter := StrToFloat (Edit1.Text);
Jahre := 60;
Zigaretten :=StrToFloat (Edit3.Text);

if Checkbox1.Checked then Edit3.Visible := true else Edit3.Visible := False;
if Checkbox1.Checked then
Jahre:=Jahre-15-(Zigaretten*1.5);
if Checkbox2.Checked then
Jahre:=Jahre-5;
if Checkbox3.Checked then
Jahre:=Jahre+10;
If Checkbox4.Checked then
Jahre:=Jahre-20;
If Checkbox6.Checked then
Jahre:=Jahre+15;
If Checkbox8.Checked then
Jahre:=Jahre+15;
If Checkbox7.Checked then
Jahre:=Jahre+2;
if Checkbox9.Checked  then
Edit5.Text:=FLoatToStr (Jahre);

zeigt er es nur an nachdem ich den button geklickt hat.. wieso?


danke im vorraus
henneberg

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


jaenicke - Mi 01.12.10 20:52

user profile iconHenneberg hat folgendes geschrieben Zum zitierten Posting springen:
if Checkbox1.Checked then Edit3.Visible := true else Edit3.Visible := False;
Wie wäre es mit:

Delphi-Quelltext
1:
Edit3.Visible := Checkbox1.Checked;                    


user profile iconHenneberg hat folgendes geschrieben Zum zitierten Posting springen:
da sieht man es gar nicht egal was man macht..
[..]
zeigt er es nur an nachdem ich den button geklickt hat.. wieso?
Wie jetzt? Du schreibst es in OnCreate des Formulars, das ja beim Erzeugen des Formulars ausgeführt wird, und wunderst dich, dass das nicht von alleine auch später plötzlich nochmal ausgeführt wird?
Bzw. du legst es in OnClick des Buttons und wunderst dich, dass es auch erst dann passiert?

Wenn du willst, dass es bei einem Klick auf die CheckBox ausgeführt wird, dann musst du es natürlich auch in das OnClick der CheckBox schreiben. Woher soll denn Delphi wissen, dass der Code dann ausgeführt werden soll, wenn du das nicht schreibst?


Henneberg - Mi 01.12.10 20:55

ah ja ich sehs auch grad. ich habs ins falsche procedure gemacht ;D
danke jetzt funzts ;D


Delphi-Laie - Do 02.12.10 23:23

user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
CrossPost DP [http://www.delphipraxis.net/154442-delphi-anfaenger-mache-ich-mit-diesem-if-satz-falsch.html#post1048751]


Unwichtig und unsubstantiiert. Jeder hat das Recht, an verschiedenen Orten nachzufragen. Es sind zudem sogar denkbar, daß nicht dieselbe Person dahintersteckt.


Delphi-Laie - Do 02.12.10 23:31

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
//
// "if xx=TRUE then" ist identisch mit "if xx then"
//
Setzen, 6. Das ist schlicht falsch. Siehe mein Beispiel im Post über dir.

Nur weil es meistens das Gewünschte macht ist es noch lange nicht richtig und schon gar nicht identisch.


Logisch ist es korrekt, wenn auch redundant. Da if fragt, ob etwas true ist (oder nicht) und damit eigentlich schon ausreicht, muß logischerweise eine if-Abfrage eines Vergleich mit true denselben Wertevorrat haben. Da hilft, tut mir leid, mich hier genötigt zu fühlen, es hier so deutlich zu schreiben, auch keine oberlehrerhafte (und m.E. schon arrogante) Zensierung nicht. So kenne ich Dich, Jänicke, sonst nicht.

Daß der Vergleich mit true in der Praxis dieser Theorie nicht standhält, halte ich inzwischen sogar für einen eindeutigen Compilerfehler, den man allerdings kennen sollte.

Bitte jetzt nicht mit irgendwelchen dahinterstehenden Bytes mit und ohne Vorzeichen kommen, das ist alles irrelevant. Schließlich basiert Delphi auf Pascal als Hoch(!)sprache, in der man sich konstruktionsbedingt nicht mit solchen Untiefen auseinandersetzen muß (oder leider müßte). True und false sind nun einmal die einzigen möglichen Werte boolscher Variablen.

Wenn Anfänger diesen angeblichen Fehler begehen, beweisen sie nur, daß sie (auch) logisch denken können, jedoch (noch?) nicht so betriebsblind sind, logische und demnach Programmierfehler des Compilers als solche gar nicht mehr zu erkennen und die Compiler"logik" mit der generellen Logik fälschlicherweise gleichzusetzen.


Martok - Do 02.12.10 23:45

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Unwichtig und unsubstantiiert. Jeder hat das Recht, an verschiedenen Orten nachzufragen. Es sind zudem sogar denkbar, daß nicht dieselbe Person dahintersteckt.

Richtlinen, 2.3 impliziert, dass Crossposts immer angegeben werden müssen. Erlaubt sind sie natürlich, aber man muss es dranschreiben!

Das Thema Boolean-Vergleiche wurde an anderer Stelle zu Genüge diskutiert, (Hint: du liegst falsch, user profile iconDelphi-Laie), das Hauptthema ist auch durch, also:

*geschlossen*


Viele Grüße,
Martok