Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Rückgabe Funktion = Dynamisches Array (https://www.delphipraxis.net/156339-rueckgabe-funktion-%3D-dynamisches-array.html)

daniel775 28. Nov 2010 19:14

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.

mkinzler 28. Nov 2010 19:24

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

daniel775 28. Nov 2010 20:38

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;

Sir Rufo 28. Nov 2010 21:00

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.

Luckie 29. Nov 2010 01:20

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:
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.
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.

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.

xZise 29. Nov 2010 08:01

AW: Rückgabe Funktion = Dynamisches Array
 
Moin,
Zitat:

Zitat von Luckie (Beitrag 1064704)
[…]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.

Anders ausgedrückt: Wenn du die Länge eines Arrays auf die Länge eines anderen setzen willst, dann machst du ja nicht:
Code:
Setze die Länge von Array A auf den letzten Index von Array B
Sondern:
Code:
Setze die Länge von Array A auf die Länge von Array B
Weil High()+1 muss nicht immer stimmen (ungetestet, kann sein dass ich falsch liege):
Delphi-Quellcode:
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)));
MfG
Fabian

Luckie 29. Nov 2010 08:12

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.

DeddyH 29. Nov 2010 08:20

AW: Rückgabe Funktion = Dynamisches Array
 
Was immer funktionieren sollte:
Delphi-Quellcode:
SetLength(a, Length(b));
for i := Low(a) to High(a) do
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.

Luckie 29. Nov 2010 08:27

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:
x : array [10..15] of Int64;
High wird dir hier 15 ausgeben, das Array ist aber nur fünf Elemente lang.

xZise 29. Nov 2010 08:34

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 00:38 Uhr.
Seite 1 von 2  1 2      

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