Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Bei einer Funktion <string or dynamic array> übergeben. (https://www.delphipraxis.net/9415-bei-einer-funktion-string-dynamic-array-uebergeben.html)

overmoon 25. Sep 2003 22:33


Bei einer Funktion <string or dynamic array> übergeben
 
Ich schreibe an einer Funktion, die an einem Array unabhängig vom Inhalt arbeiten soll. Nach einem gewissen Muster sollen die Elemente innerhalb des Arrays vertauscht werden.

Nur die ersten Probleme treten schon beim Header der Funktion auf. Prinzipiell bräuchte ich den Typ <string or dynamic array>. Und ich weiß auch, dass es die Möglichkeit geben muss; ich weiß nur leider nicht wie.

In Delphi selber sind solche Funktionen vorhanden. Nur um zwei Beispiele zu nennen:

1. SetLength
2. Length

Beiden kann man ein beliebiges Array oder einen String übergeben. :witch:

Um mich an ihnen zu orientieren, habe ich in die Hilfe geschaut.
Dort sehen die Header folgendermaßen aus:
Delphi-Quellcode:
procedure SetLength(var S; NewLength: Integer);
function Length(S): Integer;
Das diese Art der Deklaration nicht funktioniert, musste ich dann leider feststellen. Nur um zu gucken, ob dies gültiger Syntax ist, habe ich mal folgendes gemacht:
Delphi-Quellcode:
function MyLength(S): Integer;
begin
     result := Length(S);
end;
Dies führt aber gleich zu zwei Fehlern: 1.) „Missing Paramter Type“ und 2.) „Incombatible Types“. So geht es also nicht. :evil:
Auch wenn ich S durch var S ersetze (von wegen beliebiger Typ und so) bleibt die zweite Fehlermeldung. So geht’s also nicht.

Wie übergebe ich nun also <string or dynamic array> wie es z.B. bei Length() der Fall ist ??? :?:

overmoon :roll:

ps:
Ich habe schon mit dem Gedanken des Überladens gespielt; es aber dann verworfen: Das wird ja super heftig: array of real, array of char, array of int, array of... Mal abgesehen davon, dass man dann neue Arrays einen selbstdefinierten Typs nicht so ohne weiteres übergeben kann. :!:

LKutscher 26. Sep 2003 08:25

Re: Bei einer Funktion <string or dynamic array> überg
 
Aus der Hilfe von D5:

- Wertparameter sind immer typisiert, während Variablen-, Konstanten und Ausgabeparameter auch untypisiert sein können.
- Für Array-Parameter gelten spezielle Regeln. Weitere Informationen finden Sie unter Array-Parameter.

Mit den untypisierten var oder const Parametern wäre ich sehr vorsichtig.
Mir scheint es sicherer, einen Array- oder Stringtyp anzugeben. Spontan fallen mir zwei Arten ein, dies für Array-Typen zu machen:

1. als offener Array-Parameter eines bestimmten typs:
Delphi-Quellcode:
procedure Prc(Arr: array of TMyType);
2. durch vorherige Deklaration eines Array-Typs:
Delphi-Quellcode:
type
 AMyArray = array [12..99] of TMyType;

procedure Prc(Arr: AMyArray);
:wink: In der Delphi-Hilfe steht sonst auch noch einiges zu den Themen
unter "untypisierte Parameter" (stichwort im Hilfe-Index)
oder "Object Pascal-Referenz\Prozeduren und Funktionen\Parameter\Parametersemantik"

Tonic1024 26. Sep 2003 10:49

Re: Bei einer Funktion <string or dynamic array> überg
 
Moin...

Ich glaube du hast des mit dem [string od Dynamic Array] Missverstanden. Ein String ist in dem Sinne Ein dynamisches Array inwieweit du mit
Delphi-Quellcode:
MyString[i]
auf einzelne Zeichen im String zugreifen kannst. Desshalb ist [String or dynamic Array] kein eigener Datentyp sondern einfach[dynamic Array].

Übergebe doch einfach ein Array mit strings und als Flag den Typ. dann kannst du innerhalb der funktion mit "IntToStr" oder solchen Teilen den Typ ändern.

Mein Tip: Informiere dich mal über das Thema Typenkonvertierung und mache deine Schnittstelle (im Header) statisch an einem Typ fest. Du ersparst dir viel ärger...

Zitat:

Das wird ja super heftig: array of real, array of char, array of int, array of... Mal abgesehen davon, dass man dann neue Arrays einen selbstdefinierten Typs nicht so ohne weiteres übergeben kann. :!:
Wiso kann man das nicht?

Bis denne...

Sourcemaker 26. Sep 2003 11:42

Re: Bei einer Funktion <string or dynamic array> überg
 
Sind variante Arrays indiskutabel ?

Mfg.

Frank

overmoon 26. Sep 2003 14:54

Re: Bei einer Funktion <string or dynamic array> überg
 
Das Stichwort
Zitat:

"untypisierte Parameter" (stichwort im Hilfe-Index)
hat mir ein bisschen weitergeholfen. Ich könnte nämlich einen Header der Methode dann nach folgendem Muster aufbauen:
Delphi-Quellcode:
function Testing(var Target; Length, ElementSize: Integer):Boolean;
Length ist in diesem Fall die Länge des Arrays und ElementSize die Größe eines ArrayElementes. Auf diese Weise könnte ich mit dem Array arbeiten und machen, was ich möchte. Schon mal gar nicht so schlecht.

Das Problem ist nun aber, dass ich die Länge des Arrays und die Größe eines Array-Elementes übergeben muss. Ich muss sie übergeben, weil weder Length() noch SetLength() auf Target in der Funktion anwendbar sind.

Nagut, eines von beiden kann ich aussparen, da SizeOf() auch auf Target anwendbar ist. Wenn ich also die Gesamtgröße habe, und Length ODER Elementsize übergeben werden, dann kann ich damit das fehlende ausrechnen, da gilt: Gesamtgröße = Length * ElementSize.

Schöner wäre es aber, wenn ich nichts dergleichen übergeben müsste; bei Length() ist das ja schließlich auch nicht der Fall !

Und übrigens:
Wenn man im Code SetLength( schreibt, dann öffnet sich eine nette kleine Hilfebox, die mir folgendes sagt:
Zitat:

var S: <string or dynamic array>; NewLength: Integer
Normalerweise stehen dort die zulässigen Typen. Und wenn die Funktion überladen wäre, dann in mehreren Zeilen; wie z.B. bei IntToStr()
Zitat:

Value: Integer;
Value: Int64;
Das bei Length() keine überladene Funktion vorliegt, das erkennt man auch daran, dass man auch einen neuen Typen deklarieren kann und sie funktioniert trotz alledem.

Z.B:
Delphi-Quellcode:
Type TmyNew = record
     Eins: Byte;
     Zwei: Integer;
End;

Type TMyNewArray = array of array of TmyNew;
Dann funktioniert folgendes:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var b: array of TmyNewArray;
     Huhu: Integer;
begin
     SetLength(b,5);
     Huhu := Length(b);
end;
Bei einer überladenen Funktion würde das nicht gehen. Man muss die Funktion dann entsprechend noch mal für den entsprechenden Typ überladen. Das ist aber nicht so gut. Außerdem geht es ja auch anders.

Es MUSS also irgendwie gehen !
Nur wie ??

Variante Arrays habe ich auch schon probiert. Also derart:
Delphi-Quellcode:
Procedure Testing(var MyArray: array of const);

Bzw.

Procedure Testing(var MyArray: array of TvarRec);
(Ist ja beides das selbe.)

Hier gibt es aber auch ein paar „Probleme“.

1.) Muss ich jedes Array, welches ich übergeben möchte zunächst in ein TVarRec Array umwandeln.

Ich kann z.B. nicht ein „array of integer“ übergeben, sondern muss dieses erst umwandeln.

2.) Bei einem „Array of array of Integer” ist die Funktion bereits erledigt. Length() und SetLength() übrigens nicht.


Wenn ich richtig Variants benutze, dann geht das natürlich. Und (fast) alle Probleme wären gelöst.

Also derart:
Delphi-Quellcode:
V: Variant;
...
V := VarArrayCreate([0,9], varInteger);
Hier könnte ich statt varInteger natürlich auch varVarinat angeben und so könnte ich beliebig Dimensionale Arrays übergeben, mit denen ich dann arbeiten kann und die ich dann in der ersten Ebene vertauschen kann. Soweit wunderbar.

Nur: Ich müsste dann komplett mit Variants arbeiten; und so schön ist das nicht, aber: Es würde tatsächlich funktionieren.

Trotzdem:

Es geht auch anders. Siehe SetLength() und Lenght() .

Nur wie ??

Chewie 26. Sep 2003 15:59

Re: Bei einer Funktion <string or dynamic array> überg
 
Tja, leider sind Funktionen wie SetLength() nicht als Quellcode in einer Unit definiert, sondern direkt Bestandteil des Compilers, sog. "Compiler Magic". Es ist also durchaus möglich, dass Delphi Prouzeduren bereitstellt, die nicht mit Pascal-Code reproduziert werden können.

Christian Seehase 26. Sep 2003 16:03

Re: Bei einer Funktion <string or dynamic array> überg
 
Moin Zusammen,

Zitat:

Zitat von Chewie
Tja, leider sind Funktionen wie SetLength() nicht als Quellcode in einer Unit definiert, sondern direkt Bestandteil des Compilers, sog. "Compiler Magic". Es ist also durchaus möglich, dass Delphi Prouzeduren bereitstellt, die nicht mit Pascal-Code reproduziert werden können.

was man z.B. gerade am Beispiel von SetLength daran sehen kann, dass man ein dynamisches Array mit mehreren Dimensionen mit einem Befehl Dimensionieren kann. SetLength erlaubt eine variable Anzahl Parameter (ohne dass man overload bräuchte).

Delphi-Quellcode:
var
  da : array of array of integer;

begin
  SetLength(da,2,2);
end;

overmoon 26. Sep 2003 16:37

Re: Bei einer Funktion <string or dynamic array> überg
 
Ich weiß, dass man in C++ dieses Problem über Template-Klassen lösen würde.

In Delphi habe ich aber noch nichts Vergleichbares gefunden.

Gibts sowas ?

Christian Seehase 26. Sep 2003 16:40

Re: Bei einer Funktion <string or dynamic array> überg
 
Moin Overmoon,

soweit ich weiss gibt's, zumindest standardmässig, in Delphi keine Templates.

overmoon 26. Sep 2003 17:34

Re: Bei einer Funktion <string or dynamic array> überg
 
Stimmt leider.

Siehe hier:
Delphi/C++-Vergleich

Wäre doch mal eine sinnvolle Erweiterung für Delphi !


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:26 Uhr.

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