AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Rückgabe Funktion = Dynamisches Array

Rückgabe Funktion = Dynamisches Array

Ein Thema von daniel775 · begonnen am 28. Nov 2010 · letzter Beitrag vom 29. Nov 2010
Antwort Antwort
Seite 1 von 2  1 2   
daniel775

Registriert seit: 27. Nov 2010
46 Beiträge
 
#1

Rückgabe Funktion = Dynamisches Array

  Alt 28. Nov 2010, 20:14
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.

Geändert von mkinzler (28. Nov 2010 um 20:25 Uhr) Grund: Code-Tags durch Delphi-Tags ersetzt
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.794 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Rückgabe Funktion = Dynamisches Array

  Alt 28. Nov 2010, 20:24
Du vergrößerst zwar den temp. Array ( den benötigst du ja eigentlich nicht) aber nicht die Rückgabevariable
Markus Kinzler
  Mit Zitat antworten Zitat
daniel775

Registriert seit: 27. Nov 2010
46 Beiträge
 
#3

AW: Rückgabe Funktion = Dynamisches Array

  Alt 28. Nov 2010, 21:38
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;

Geändert von mkinzler (29. Nov 2010 um 05:20 Uhr) Grund: Code-Tags durch Delphi-Tags ersetzt
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Rückgabe Funktion = Dynamisches Array

  Alt 28. Nov 2010, 22:00
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.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Alt 29. Nov 2010, 02:10     Erstellt von Luckie
Dieser Beitrag wurde von Luckie gelöscht.
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

AW: Rückgabe Funktion = Dynamisches Array

  Alt 29. Nov 2010, 02:20
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.
Michael
Ein Teil meines Codes würde euch verunsichern.

Geändert von Luckie (29. Nov 2010 um 02:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Rückgabe Funktion = Dynamisches Array

  Alt 29. Nov 2010, 09:01
Moin,
[…]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
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

AW: Rückgabe Funktion = Dynamisches Array

  Alt 29. Nov 2010, 09:12
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.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.270 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Rückgabe Funktion = Dynamisches Array

  Alt 29. Nov 2010, 09:20
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.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

AW: Rückgabe Funktion = Dynamisches Array

  Alt 29. Nov 2010, 09:27
Bei statischen Arrays funktioniert es eben nicht, wenn sie nicht null basierend sind, wie xZise gezeigt hat:
x : array [10..15] of Int64; High wird dir hier 15 ausgeben, das Array ist aber nur fünf Elemente lang.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#10

AW: Rückgabe Funktion = Dynamisches Array

  Alt 29. Nov 2010, 09:34
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
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 16:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf