Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem bei logischer abfrage (https://www.delphipraxis.net/82269-problem-bei-logischer-abfrage.html)

richie_k 9. Dez 2006 23:12


Problem bei logischer abfrage
 
Hallo!
Ich wusste nicht, was ich bei der Suche hätte eingeben sollen (also bei "logisches problem" hab ich nix dolles gefunden zB)
Naja mein Problem ist folgendes:
Delphi-Quellcode:
  if
  (cardexistsnoco(14,Club)AND
   cardexistsnoco(2,Club) AND
   cardexistsnoco(3,Club) AND
   cardexistsnoco(4,Club) AND
   cardexistsnoco(5,Club))
  or
  (cardexistsnoco(14,Heart)AND
   cardexistsnoco(2,Heart) AND
   cardexistsnoco(3,Heart) AND
   cardexistsnoco(4,Heart) AND
   cardexistsnoco(5,Heart))
cardexistsnoco ist eine funktion, die true oder false liefert.. ich habe zur überprüfung ein Showmessage in diese Funktion geschrieben.. er kontrolliert nur 14,Club und 14, Heart.. den Rest läuft er leider garnicht durch. Liegts an meinem Quelltext? (ja) was muss ich anders machen?
danke!

Muetze1 9. Dez 2006 23:27

Re: Problem bei logischer abfrage
 
Nein, das ist eine Optimierung. Du hast ja definiert, dass alle Dinger ein True zurück liefern müssen um die Gesamtbedingung zu erfüllen. Warum sollte er also noch die anderen Dinge abprüfen, wenn schon der erste Aufruf False gibt? Dadurch kann er die Bedingung eh nicht mehr erfüllen.

Du kannst in den Projektoptionen unter Compiler die Komplette Boolean Evaluation einschalten, aber im Normalfall ist diese aus.

Martin K 9. Dez 2006 23:32

Re: Problem bei logischer abfrage
 
Wenn cardexistsnoco(14,Club) false ergibt (so wird es hier wohl sein), werden die restlichen mit AND verknüpften Ausdrücke gar nicht erst überprüft, um die Geschwindigkeit zu optimieren (kann man imho irgendwo in den Compiler-Optionen auch abschalten, ist aber sinnlos).
Dasselbe gilt für cardexistsnoco(14,Heart).
Wenn diese beiden Audrücke schon false sind, kann ja die ganze IF-Abfrage auch nur false ergeben.

richie_k 9. Dez 2006 23:37

Re: Problem bei logischer abfrage
 
okay hätte ich dazu sagen müssen.. er gibt nach dem ersten true zurück.. also im prinzip müsste er so wie ich die Werte eingestellt habe auch überall im ersten true wiedergeben.. aber das zweite kommt eben garnicht erst zum aufruf

Muetze1 9. Dez 2006 23:44

Re: Problem bei logischer abfrage
 
Zitat:

Zitat von richie_k
okay hätte ich dazu sagen müssen.. er gibt nach dem ersten true zurück.. also im prinzip müsste er so wie ich die Werte eingestellt habe auch überall im ersten true wiedergeben.. aber das zweite kommt eben garnicht erst zum aufruf

Dann glaube ich einfach nicht, dass er true zurück gibt.

richie_k 9. Dez 2006 23:51

Re: Problem bei logischer abfrage
 
also hab jetzt ein showmessage an den anfang der noco funktion gemacht und bei erfolg auch noch eins.. ich bekomme jetzt

14
14
14=14

zurück..
sprich das mit club gibt false und das mit heart gibt true zurück.. er macht aber nich weiter

mkinzler 9. Dez 2006 23:52

Re: Problem bei logischer abfrage
 
Warum sollte er auch, es reicht ja das einer der beiden wahr ist.

richie_k 9. Dez 2006 23:55

Re: Problem bei logischer abfrage
 
also nochmal:
Delphi-Quellcode:
if
  (cardexistsnoco(14,Club)AND
   cardexistsnoco(2,Club) AND
   cardexistsnoco(3,Club) AND
   cardexistsnoco(4,Club) AND
   cardexistsnoco(5,Club))
  or
  (cardexistsnoco(14,Heart)AND
   cardexistsnoco(2,Heart) AND
   cardexistsnoco(3,Heart) AND
   cardexistsnoco(4,Heart) AND
   cardexistsnoco(5,Heart))
cardexistsnoco müsste bei allen 5 heart-abfragen true geben.. also nach dem schema müsste

14
14
14=14
2
2=2
3
3=3
4
4=4
5
5=5


zurückgegeben werden.. aber wie gesagt hört er nach 14=14 auf..

Martin K 9. Dez 2006 23:58

Re: Problem bei logischer abfrage
 
Wenn cardexistsnoco(14,Club) false ergibt, geht die Überprüfung mit cardexistsnoco(14,Heart) weiter.
Ergibt dies true, müsste als nächstes cardexistsnoco(2,Heart) überprüft werden.

Ich mache mal ein vereinfachtes Beispiel:
Delphi-Quellcode:
var a, b, c, d: Boolean;
{...}

  if (a and b) or (c and d) then
  //...
- Wenn a false ist, wird als nächstes c überprüft. Ist c true, wird d überprüft, wenn c false ist, wird nichts mehr überprüft.
- Wenn a true ist wird b überprüft, wenn b auch true ist, wird nichts mehr überprüft.

richie_k 10. Dez 2006 00:01

Re: Problem bei logischer abfrage
 
und genau das passiert hier leider nicht und ich verstehe nicht warum.. wie gesagt bei club wird nur das erste überprüft - gibt false zurück und wird in ruhe gelassen.. dann kommt das heart dran. es kommt true zurück, aber die zweite abfrage wird nicht mehr überprüft, was sie aber eigentlich werden müsste.
das ist ja gerade das problem ;)

das einzige was ich mir logisch vorstellen kann ist, dass die funktion eigentlich immer false zurückliefert, obwohl sie da deutlich als true deklariert wurde.. oder wie schreibt man das auf, dass die funktion dann true werden soll? (also innerhalb der funktion)

namederfunktion:=true;

oder?

Martin K 10. Dez 2006 00:08

Re: Problem bei logischer abfrage
 
Der Rückgabewert einer Funktion wird mit Result festgelegt.
Damit eine Funktion true zurück gibt, schreibst Du also einfach:
Delphi-Quellcode:
Result := true;
//Edit:
Ob das mit dem Namen der Funktion auch funktioniert, weiß ich nicht - sollte aber eigentlich :gruebel:
Aber einfach mal ausprobieren, indem Du einmal den Namen und einmal Result nimmst und dann guckst, was jeweils dabei raus kommt :wink:

Maja Jessica 10. Dez 2006 00:11

Re: Problem bei logischer abfrage
 
Hi,

getestet, und funktioniert so wie du es erwartest:


Delphi-Quellcode:

function cardexistsnoco(a,b : integer) : boolean;
begin
  showMessage('Bin bei '+IntToStr(a));
  if a = b then result := true else result := false;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
if
  (cardexistsnoco(1,1)AND
   cardexistsnoco(2,2) AND
   cardexistsnoco(3,3333) AND
   cardexistsnoco(4,4) AND
   cardexistsnoco(5,5))
  or
  (cardexistsnoco(6,6)AND
   cardexistsnoco(7,7) AND
   cardexistsnoco(8,8) AND
   cardexistsnoco(9,9) AND
   cardexistsnoco(10,10)) then ShowMessage('fertig');
end;
MJ

richie_k 10. Dez 2006 00:14

Re: Problem bei logischer abfrage
 
oh - mein - gott..
war ne schwere geburt, aber ich hab den fehler.. danke an euch alle - war ein (dummer) denkfehler in einer schleife..
dass man auf sowas immer erst nach stundenlangem suchen kommt.. naja zumindest kann ich delphis logik den fehler nicht in die schuhe schieben ;)

Christian Seehase 10. Dez 2006 00:15

Re: Problem bei logischer abfrage
 
Moin Maja,

Du kannst auch gleich

Delphi-Quellcode:
Result := a = b;
schreiben.

Martin K 10. Dez 2006 00:19

Re: Problem bei logischer abfrage
 
Hab Majas Beispiel anstatt mit result mal mit dem Namen der Funktion getestet und es funktioniert genuso!
Der einzige Vorteil von Result ist wohl, dass es auch noch funktioniert, wenn die Funktion umbenannt wurde :gruebel:

Maja Jessica 10. Dez 2006 00:22

Re: Problem bei logischer abfrage
 
Zitat:

Zitat von Christian Seehase
Moin Maja,

Du kannst auch gleich

Delphi-Quellcode:
Result := a = b;
schreiben.

Ja, stimmt. :-D Ist auch eine Möglichkeit.
Delphi-Quellcode:
function cardexistsnoco(a,b : integer) : boolean;
begin
  showMessage('Bin bei '+IntToStr(a));
  result := a = b;
end;
oder wie Martin K schrieb über den Namen der function

Delphi-Quellcode:
function cardexistsnoco(a,b : integer) : boolean;
begin
  showMessage('Bin bei '+IntToStr(a));
  cardexistsnoco := a = b;
end;
Was ist nun die "beste Version"?

Grüsse, MJ

mkinzler 10. Dez 2006 00:25

Re: Problem bei logischer abfrage
 
Zitat:

Was ist nun die "beste Version"?
Eigentliche keine die Version über den Namen der Funktion ist die klassische von Pascal, das Schlüsselwort result wurde in Delphi eingeführt.

Christian Seehase 10. Dez 2006 00:34

Re: Problem bei logischer abfrage
 
Moin Maja,

spätestens, wenn Du das Ergebnis innerhalb der Funktion noch weiterverwenden willst, wirst Du den Funktionsnamen nicht mehr verwenden können, da, z.b., die Benutzung auf der rechten Seite eines := als Funktionsaufruf interpretiert wird.

Die Verwendung von Result finde ich aber auch aus Gründen der Dokumentation sinnvoll, was besonders bei rekursiven Funktionen interessant wird.

mkinzler 10. Dez 2006 00:36

Re: Problem bei logischer abfrage
 
Zitat:

spätestens, wenn Du das Ergebnis innerhalb der Funktion noch weiterverwenden willst,
Das sollte man mit result aber auch nicht machen.

Martin K 10. Dez 2006 00:42

Re: Problem bei logischer abfrage
 
Zitat:

Zitat von mkinzler
Zitat:

spätestens, wenn Du das Ergebnis innerhalb der Funktion noch weiterverwenden willst,
Das sollte man mit result aber auch nicht machen.

Warum nicht?

So steht es in der Delphi-Hilfe:
Zitat:

Zitat von Delphi-Hilfe
Sie können der Variablen Result oder dem Funktionsnamen im Anweisungsblock mehrmals einen Wert zuweisen. Die zugewiesenen Werte müssen jedoch dem deklarierten Rückgabetyp entsprechen. Sobald die Ausführung der Funktion beendet wird, bildet der Wert, der zuletzt der Variablen Result oder dem Funktionsnamen zugewiesen wurde, den Rückgabewert der Funktion. Zum Beispiel:
Delphi-Quellcode:
function Power(X: Real; Y: Integer): Real;
var
  I: Integer;
begin
  Result := 1,0;
  I := Y;
  while I > 0 do
   begin
    if Odd(I) then Result := Result * X;
    I := I div 2;
    X := Sqr(X);
   end;
end;
Result und der Funktionsname repräsentieren immer denselben Wert. Deshalb gibt die Deklaration
Delphi-Quellcode:
function MyFunction: Integer;
begin
  MyFunction := 5;
  Result := Result * 2;
  MyFunction := Result + 1;
end;
den Wert 11 zurück. Result ist jedoch nicht mit dem Funktionsnamen identisch. Wenn der Funktionsname auf der linken Seite einer Zuweisungsanweisung verwendet wird, verwaltet der Compiler den Funktionsnamen als Variable (wie Result) zur Aufzeichnung des Rückgabewerts. Taucht der Funktionsname dagegen an einer anderen Stelle im Anweisungsblock auf, wird er vom Compiler als rekursiver Aufruf der Funktion interpretiert. Result kann dagegen als Variable in Operationen eingesetzt werden, beispielsweise bei Typkonvertierungen, in Konstruktoren, Indizes und in Aufrufen anderer Routinen.

Wenn die Ausführung einer Funktion beendet wird, bevor Result oder dem Funktionsnamen ein Wert zugewiesen wurde, ist der Rückgabewert der Funktion nicht definiert.


Maja Jessica 10. Dez 2006 00:45

Re: Problem bei logischer abfrage
 
Aha, man lernt ja nie aus :)

Bei einigen Konstruktionen kann es sehr schnell sehr eng werden auf dem Stack, z.B. bei
solchen rekursiven Selbstmordschaltungen:

Delphi-Quellcode:
function cardexistsnoco(a,b : integer) : boolean;
begin
  if cardexistsnoco(a,b) then
    showMessage('Bin bei '+IntToStr(a));
    cardexistsnoco := a = b;
end;
:mrgreen: Achtung Kinder! Nicht zu Hause nachmachen! :mrgreen:

MJ


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:45 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz