![]() |
Rückgabe Funktion = Dynamisches Array
Hallo liebes Forum,
bin VB.net Umsteiger. Hab meine ersten Erfahrungen in Delphi gemacht. Aber ich komme bei diesem Problem irgendwie nicht weiter. Ich habe eine Form unit und eine unit2 der sich eine Klasse befindet. In der Form unit initialisiere ich eine Objektvariable der Klasse aus unit2 und einen Typ (Dynamisches Array). In einem Button Event wird eine Funktion der Klasse aufgerufen. Rückgabe sollte eigentlich ein Dynamisches Array sein. Sobald ich mit SetLength result neu dimensionieren will kommt eine Exception. Was mach ich falsch bzw. wie kann ich es richtig machen? Anbei der Code:
Delphi-Quellcode:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Unit2, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; myClass: TMyClass; test: Tarr; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var i: Integer; const str = 'Dies ist ein Test'; begin test := myclass.myfunc(str); for i := 0 to High(test) do self.Edit1.Text := self.Edit1.Text + IntToStr(test[i]); end; end.
Delphi-Quellcode:
unit Unit2;
interface uses Math, IdHashMessageDigest, idHash, SysUtils, Classes; type Tarr = array of Int64; TMyClass = class(TObject) private public constructor create(); function myfunc(str: string): Tarr; end; implementation constructor TMyClass.create; begin end; function TMyClass.myfunc(str: string): Tarr; var i: integer; asciiArray: array of Int64; begin i := 0; SetLength(asciiArray, Length(str)); for i := 0 to 31 do begin AsciiArray[i] := Ord(str[i + 1]); end; //SetLength(result, high(AsciiArray)); <<<<<< Hier gibt es die Exception! for i := Low(AsciiArray) to High(AsciiArray) do result[i] := AsciiArray[i]; end; end. |
AW: Rückgabe Funktion = Dynamisches Array
Du vergrößerst zwar den temp. Array ( den benötigst du ja eigentlich nicht) aber nicht die Rückgabevariable
|
AW: Rückgabe Funktion = Dynamisches Array
Ok. Hab es gefunden. Die For Schleife lief einfach zu weit. Das dynm. Array 'Test' brauchte ich nicht zu neu zu dimensionieren.
Delphi-Quellcode:
for i := 0 to length(str) - 1 do begin AsciiArray[i] := Ord(str[i + 1]); end;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer; const str = 'Dies ist ein Test'; begin i := 0; test := myclass.myfunc(str); for i := 0 to Length(test) do self.Edit1.Text := self.Edit1.Text + IntToStr(test[i]); end; |
AW: Rückgabe Funktion = Dynamisches Array
Was du da machst ist aber haarscharf an einer Exception vorbei:
Du erzeugst keine Instanz von TMyClass und benutzt diese trotzdem. Das geht auch nur deshalb, weil die Klasse nur eine function beinhaltet. Warum keine Instanz, bzw. Warum überhaupt eine Klasse? Eine schnöde Funktion würde völlig reichen.
Delphi-Quellcode:
unit Unit2;
interface uses Math, IdHashMessageDigest, idHash, SysUtils, Classes; function myfunc(str: string): Tarr; implementation function myfunc(str: string): Tarr; var i: integer; asciiArray: array of Int64; begin i := 0; SetLength(asciiArray, Length(str)); for i := 0 to 31 do begin AsciiArray[i] := Ord(str[i + 1]); end; //SetLength(result, high(AsciiArray)); <<<<<< Hier gibt es die Exception! for i := Low(AsciiArray) to High(AsciiArray) do result[i] := AsciiArray[i]; end; end. |
AW: Rückgabe Funktion = Dynamisches Array
Es ist Unsinn die Länge von Result nicht setzen zu müssen. Das ist ein dynamisches Array. Und dessen Größe muss man setzen, um den Elementen Werte zu weisen zu können. Und es gibt auch keine Exception wenn man die Länge das Results setzt.
Und so funktioniert es:
Delphi-Quellcode:
Außerdem muss die Schleife nur bis Länge der Zeichenkette minus eins laufen. Und ein AnsiString fängt bei eins an, deswegen muss die Schleife von ein mit Länge Zeichenkette laufen. bei der Array Zuweisung muss man natürlich vom Index dann eins abziehen, weil es null basierend ist.
unit Unit3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; type TArr = array of Int64; TMyClass = class(TObject) private public function MyFunc(str: string): Tarr; end; var Form1: TForm1; implementation {$R *.dfm} function TMyClass.MyFunc(str: string): TArr; var i: integer; AsciiArray: array of Int64; begin SetLength(AsciiArray, Length(str)); for i := 1 to Length(str) do begin AsciiArray[i - 1] := Ord(str[i]); end; SetLength(Result, High(AsciiArray) + 1); for i := Low(AsciiArray) to High(AsciiArray) do Result[i] := AsciiArray[i]; end; procedure TForm1.Button1Click(Sender: TObject); var MyClass: TMyClass; arr: TArr; i: Integer; s: string; begin MyClass := TMyClass.Create; try arr := MyClass.MyFunc('test'); for i := 0 to high(arr) do s := s + IntToStr(arr[i]) + ' | '; ShowMessage(s); finally MyClass.Free; end; end; end. Wenn man High benutzt, muss man noch eins dazu addieren, da High den Index des letzten Elementes zurück. Bei einer Array Länge von vier und wenn das Array null basierend ist, wie bei dynamischen Arrays, dann liefert High drei. Das Array hat aber vier Elemente von null bis drei. |
AW: Rückgabe Funktion = Dynamisches Array
Moin,
Zitat:
Code:
Sondern:
Setze die Länge von Array A auf den letzten Index von Array B
Code:
Weil High()+1 muss nicht immer stimmen (ungetestet, kann sein dass ich falsch liege):
Setze die Länge von Array A auf die Länge von Array B
Delphi-Quellcode:
MfG
var
x : array [10..15] of Int64; a : array of Int64; begin SetLength(a, High(x)); // High(x) = 15 ShowMessage('Das temporäre Array a hat die Länge von: ' + IntToStr(Length(a)) + #13#10 + 'Das Array x hat die Länge von: ' + IntToStr(Length(x))); Fabian |
AW: Rückgabe Funktion = Dynamisches Array
OK, ich habe mich auf den gegebenen Code bezogen und da hat es sich um ein dynamisches Array gehandelt. Und bei dynamischen Arrays trifft es zu, da sie immer null basierend sind. Bei statischen Arrays gilt dies natürlich nicht, wie du gezeigt hast. Aber da würde ich die Grenzen sowieso mittels Konstanten setzen und diese dann benutzen.
PS: Danke für den Hinweis bezüglich des Doppelposts. |
AW: Rückgabe Funktion = Dynamisches Array
Was immer funktionieren sollte:
Delphi-Quellcode:
Diese Funktionen gibt es schließlich nicht umsonst. Ich persönlich bin dazu übergegangen, immer Length(), Low() und High() zu verwenden, da ich mir um Array-Grenzen so keine Gedanken mehr machen muss. Das klappt immer, bei dynamischen, offenen und statischen Arrays.
SetLength(a, Length(b));
for i := Low(a) to High(a) do |
AW: Rückgabe Funktion = Dynamisches Array
Bei statischen Arrays funktioniert es eben nicht, wenn sie nicht null basierend sind, wie xZise gezeigt hat:
Delphi-Quellcode:
High wird dir hier 15 ausgeben, das Array ist aber nur fünf Elemente lang.
x : array [10..15] of Int64;
|
AW: Rückgabe Funktion = Dynamisches Array
Moin,
ich glaube du hast Detlef falsch verstanden. Und zwar iteriert er vom untersten (Low()) bis zum höchsten (High()) Wert, aber holt sich mit Length() die Länge. Und natürlich klappt High() + 1, aber da es nicht immer klappen muss eignet sich Length() da besser, weil es damit immer klappt :) @Sir Rufo: Es könnte ja sein, dass noch mehr Fleisch folgt, und er erstmal das zum Laufen kriegen will? MfG Fabian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:13 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