Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Funktionen mit Record-Result


Bestzeller - So 07.06.09 19:09
Titel: Funktionen mit Record-Result
Guten Abend
Ich will eine Fuktion erstellen die mir zwei Integer-Werte zurückgibt. Ich hab sie auch schon erstellt, aber sie gibt mir falsche Werte zurück.Könntet ihr vielleicht einmal drüber gucken und mir sagen wo der Fehler ist?

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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
type

 PZeiger=^element;
  element=record
   data:string;
   links,rechts:pzeiger;
  end;


  Tresults = record
    tiefe1,reihe1 : integer;
  end;


  TBaum = class(tobject)
   wurzel,tmp: pzeiger;
   Blatt:Timage;
   Farbe:Tcolor;
   bmp:Tbitmap;
   Name:string;
   constructor init;
   constructor create(x,y:integer;text:string;Colour:Tcolor);
   procedure BAellipse;
   procedure einfuegen(var pt:pzeiger);
   function suchen(var w:pzeiger; counter,row:integer):Tresults;
   end;
....
function TBaum.suchen(var w:pzeiger;counter,row:integer):Tresults;
Begin
If Name=w^.data then
 begin
  result.tiefe1:=counter;
  result.reihe1:=row;
 end else
  If Name < w^.data then
   If w.links <> nil then result:=suchen(w.links,counter+1,row)
  else
   If w.rechts <> nil then result:=suchen(w.rechts, counter+1, row+1)

end;


Der Aufruf zum testen lautet wie folgt:

Delphi-Quelltext
1:
2:
3:
4:
var temp:Tresults;

temp:=baum.suchen(baum.wurzel,0,1);
showmessage(inttostr(temp.tiefe1)+'   '+inttostr(temp.reihe1));


Bei der Showmessage kommt halt 0 0 raus statt 0 1.

Moderiert von user profile iconNarses: Titel erweitert.


jaenicke - So 07.06.09 19:13

Ja, hast du mal debuggt was da passiert? :gruebel:

Ich meine, vielleicht wird eben nichts gefunden...
// EDIT:
Zum Beispiel, wenn Name >= w^.data ist, passiert ja gar nichts. ;-) Deine Einrückung der If-Abfragen ist da irreführend.


Tropby - So 07.06.09 19:18

Wenn ich das richtig sehe ist das Problem einfach, dass "0 0" rauskommt was aber eigendlich garnicht der fall sein dürfte bei einem übergabewert von "0, 1"

Die erste Abfrage gibt die gleichen Werte zurück und die 2 anderen geben nur Werte zurück die mit 1 addiert wurden.



Edit:
Sry, mein Fehler... Der wird warscheinlich 0, 0 zurückgeben da er warscheinlich durch alle Abfragen durchgeht ohne, dass result geändert wird. Dann kommt 0,0 zurück.

Der Kompiler sagt warscheinlich auch, dass der Rückgabewert womöglich undefiniert ist.


Bestzeller - So 07.06.09 19:22

Das fänd ich dann etwas komisch, wenn er nichts finden würde, weil lediglich ein Element im Baum ist und w^.data = Name ist den am string wurde noch nicht verändert.
P.S:Wie geht debuggen^^


jaenicke - So 07.06.09 19:22

user profile iconTropby hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich das richtig sehe ist das Problem einfach, dass "0 0" rauskommt was aber eigendlich garnicht der fall sein dürfte bei einem übergabewert von "0, 1"
Ja, aber was, wenn schlicht nie etwas zugewiesen wird...
Ich rücke mal korrekt ein um das Problem zu verdeutlichen. Dazu kommt noch, dass ein Vergleich von Strings auch keine so gute Idee ist.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
if Name = w^.data then
begin
  Result.tiefe1 := counter;
  Result.reihe1 := row;
end
else if Name < w^.data then
  if w.links <> nil then
    Result := suchen(w.links, counter + 1, row)
  else if w.rechts <> nil then
    Result := suchen(w.rechts, counter + 1, row + 1)

// EDIT:
Debuggen geht, indem du einen Haltepunkt setzt (F5), dann das Programm startest und wenn es bei dem Haltepunkt ankommt, zeilenweise durchgehst (F8 ) und schaust was passiert. Wenn du die Maus über die Variablen hältst, siehst du deren aktuelle Werte, du kannst auch etwas markieren und mit Strg + F7 dessen Wert auswerten.


Bestzeller - So 07.06.09 19:31

Hm w^.data hat bei derFunktion als string '', aber bei einfuegen steht bei w^.data:=Name für Name 'Peter'. Jetzt weis ich auch nicht mehr...


jaenicke - So 07.06.09 19:33

Erst einmal solltest du vielleicht mal noch den Fall Name > w^.data behandeln, und dann kannst du ja schauen, ob es dann schon geht...


Bestzeller - So 07.06.09 19:38

Ja mit > klappt es! Könnte der fehler daran liegen das die Klasse zwei Constructors hat?
Ich brauchte nämlich einen um die Wurzel auf nil zu setzen.


jaenicke - So 07.06.09 19:42

user profile iconBestzeller hat folgendes geschrieben Zum zitierten Posting springen:
Ja mit > klappt es! Könnte der fehler daran liegen das die Klasse zwei Constructors hat?
Welcher Fehler? Ich denke der fehlende Fall mit > war der Fehler? :gruebel:

Oder funktioniert es so (wie du es jetzt ja wohl hast) doch nicht?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
if Name = w^.data then
begin
  Result.tiefe1 := counter;
  Result.reihe1 := row;
end
else if Name < w^.data then
begin
  if w.links <> nil then
    Result := suchen(w.links, counter + 1, row)
end else if w.rechts <> nil then
  Result := suchen(w.rechts, counter + 1, row + 1);


Bestzeller - So 07.06.09 19:46

Ne das = muss stehen bleiben, aber w^.data hat keinen Wert, obwohl ich w^.data=Name zugewiesen habe. Und bei der Funktion hab ich jetzt ein paar else ergenzt dann passt das mit dem >.


jaenicke - So 07.06.09 19:48

Reservierst du denn auch korrekt Speicher für den Record usw.?


Bestzeller - So 07.06.09 19:50

Ich weis jetzt nicht was du meinst, da ich nicht viel Ahnung hab.^^

Vielleicht liegt es am Aufruf, aber ein Error oder ein Verweis bekomm ich nirgends angezeigt.

Delphi-Quelltext
1:
2:
TBaum.init;
baum:=TBaum.create(200,200,'Peter',Clred);


jaenicke - So 07.06.09 19:54

Naja, da du einen Pointer auf einen Record benutzt, musst du ja irgendwo auch den Speicher reservieren... wie benutzt du das denn?


Bestzeller - So 07.06.09 19:58

Mit new(pt):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TBaum.einfuegen(var pt:pzeiger);
begin

 If pt <> nil then
   If Name<=pt^.data then einfuegen(pt^.links)
    else einfuegen(pt^.rechts)
 else
  Begin
   new(pt);
   pt^.rechts:=nil;
   pt^.links:=nil;
   pt^.data:=Name;
  end;

end;