Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   const foo: array of TMyRecord = (myArray:???) (https://www.delphipraxis.net/151311-const-foo-array-tmyrecord-%3D-myarray.html)

yankee 12. Mai 2010 11:30


const foo: array of TMyRecord = (myArray:???)
 
Hi @ll,

folgendes Beispiel:
Delphi-Quellcode:
type
  TDynIntegerArray: array of integer;
  TMyRecord = record
    myArray: TDynIntegerArray;
  end;
...
procedure foobar;
const
  foo: array of TMyRecord = (myArray:(1,2,3)); // <-- Falsch. Wie geht es richtig?
begin
...
end;
Dieser code funktioniert so nicht, aber ich hoffe man kann sehen, was ich versuche zu tun. (Mir fällt es nämlich leider etwas schwer das Problem in Worte zu fassen: "Ich hätte gerne einen konstanten dynamischen array...")

Neutral General 12. Mai 2010 11:31

Re: const foo: array of TMyRecord = (myArray:???)
 
Delphi-Quellcode:
foo: array of TMyRecord = (myArray: TDynIntegerArray.Create(1,2,3));
So könnte es evtl. gehen.

PS: So geht es doch nicht. Außerdem kann man dynamische Arrays allgemein nicht initialisieren. D.h. du müsstest schon ein Array[0..Max] of TMyRecord nehmen oder so.

himitsu 12. Mai 2010 11:35

Re: const foo: array of TMyRecord = (myArray:???)
 
ein Laufzeitcode ( .Create ) zum Compilierungs-Zeit ... das kann nicht gehn.

Dynamische Arrays können nicht als Konstante initialisiert werden.
Abgesehn davon, daß ein dynamisches "veränderliches" Array als "statische" Konstannte eh sinnlos ist.


Also entweder ein statisches Array verwenden (siehe Neutral General)
oder du kommst nicht drumrum das Array erst zur Laufzeit via QuellCode zu erstellen.

yankee 12. Mai 2010 11:41

Re: const foo: array of TMyRecord = (myArray:???)
 
Zitat:

Zitat von himitsu
Abgesehn davon, daß ein dynamisches "veränderliches" Array als "statische" Konstannte eh sinnlos ist.

Nicht so ganz, denn ich habe mehrere array Konstanten, die unterschiedlich lang sein sollen. Also mal kurzgefasst in JSON:
Code:
({myArray:[1]},{myArray:[1,2,3]},{myArray:[]})
In der deklaration is myArray dynamisch. Wenn ich es statisch machen würde, dann müssten alle meine Konstanten dieses Typs die gleiche Größe haben oder sehe ich das falsch?

himitsu 12. Mai 2010 11:52

Re: const foo: array of TMyRecord = (myArray:???)
 
Du weißt aber, daß JSON eh keine "echten" Konstanten kennt, da es "nur" ein Format einer ScriptSprache ist und somit alles "nur" dynamisch verwaltet wird.
(dieses JSON-String wird da auch erst zur Laufzeit über einen Parser zerlegt)

Dynamische Array und statische Arrays werden im statisch generierten Delphi-Code nunmal komplett unterschiedlich verwaltet.

Dynamische Arrays werden im Speichermanager verwaltet und dieser existiert nunmal, zum Zeitpunkt der Compilierung, noch nicht.

Was du aber machen kannst:
Die Konstanten als statisches Array anlegen und dann über eine Funktion zur Laufzeit in das dynamische Array umkopieren.

[info]
Ich will nicht sagen, daß es absolut keine Möglichkeit gibt, ein dynArray nicht zur CompileTime statisch vorzubelegen, aber sowas ist mit mehr Schwierigkeiten verbunden, als es Nutzen bringt.

yankee 12. Mai 2010 13:49

Re: const foo: array of TMyRecord = (myArray:???)
 
Zitat:

Zitat von himitsu
Du weißt aber, daß JSON eh keine "echten" Konstanten kennt, da es "nur" ein Format einer ScriptSprache ist und somit alles "nur" dynamisch verwaltet wird.
(dieses JSON-String wird da auch erst zur Laufzeit über einen Parser zerlegt)

Ja, das ist schon klar, ich habe das nur als JSON geschrieben um zu verdeutlichen, was ich nachher im Speicher stehen haben will. Nur um eine Vorstellung zu vermitteln. Ich hätte es natürlich auch auf deutsch ausformulieren können, aber das wäre dann vermutlich auch schlecht zu verstehen gewesen.

Ich habe rein zu Demonstrationszwecken den KMP-Algorithmus implementiert und ein paar einfach test cases geschrieben, die ich einfach zu Demonstrationszwecken drüberrasseln lassen kann.

Delphi-Quellcode:
// == Defining test cases == //
// 1. testcase (pattern + text is identical)
  testCases[0].pattern := 'aababaab';
  testCases[0].text := testCases[0].pattern; // text and pattern is identical
  // there should be exactly one occurence at the first character of the string
  SetLength(testCases[0].occurences, 1);
  testCases[0].occurences[0] := 1;
// 2. testcase (pattern occures somewhere in the middle)
  testCases[1].pattern := 'aababaab';
  testCases[1].text := 'aaa' + testCases[1].pattern + 'aaa';
  // there should be exactly one occurence at the fourth character of the string
  SetLength(testCases[1].occurences, 1);
  testCases[1].occurences[0] := 4;
// 3. testcase: (pattern does not occur in the string)
  testCases[2].pattern := 'aababaab';
  testCases[2].text := 'aaaaaabbbbbbbbaaaabbbbhhhhhaaadddd';
  // there should be no occurences
  SetLength(testCases[2].occurences, 0);
// 4. testcase: (pattern occures several time without overlapping each other)
  testCases[3].pattern := 'aababaab';
  testCases[3].text := 'aa' + testCases[3].pattern + 'a' + testCases[3].pattern;
  // there should be two occurences at the 3rd and 12th character of the string
  SetLength(testCases[3].occurences, 2);
  testCases[3].occurences[0] := 3;
  testCases[3].occurences[1] := 12;
// 5. testcase (pattern occures several times with overlapping each other)
  testCases[4].pattern := 'aababaab';
  testCases[4].text := 'aababaababaab';
  // there should be two occurences at the 1st and 6th character of the string
  SetLength(testCases[4].occurences, 2);
  testCases[4].occurences[0] := 1;
  testCases[4].occurences[1] := 6;
// DONE: Building test cases
Gut, geht natürlich. Aber so richtig hyperübersichtlich ist es dann finde ich doch nicht. Vorallem, weil es auch etwas fehleranfällig ist, wenn man einmal sich beim setlength vertut oder bei einem array index. Das könnte man ja theoretisch auch automatisch auflösen. Also wenn da noch wer eine Idee hat...

himitsu 12. Mai 2010 14:25

Re: const foo: array of TMyRecord = (myArray:???)
 
Sind in FPC auch Record-Methoden möglich?
Wenn ja, dann würde ich eine Verwendung dieser Vorschlagen.

Delphi-Quellcode:
TMyRecord = record
  myArray: TDynIntegerArray;
  procedure Add(Value: Integer);
end;

procedure TMyRecord.Add(Value: Integer);
var
  i: Integer
begin
  i := Length(myArray);
  SetLength(myArray, i + 1);
  myArray[i] := Value;
end;
Delphi-Quellcode:
TTestCases = record
  FData: Array of TData;
  ...
  property Data[index: Integer]: TData read GetData; default;
  function Add(Pattern, Text: String; occurences: array of Integer): Integer;
end;


// == Defining test cases == //
// 1. testcase (pattern + text is identical)
testCases.Add('aababaab', testCases[0].pattern, [1]);
// 2. testcase (pattern occures somewhere in the middle)
testCases.Add('aababaab', 'aaa' + testCases[1].pattern + 'aaa', [4]);
// 3. testcase: (pattern does not occur in the string)
testCases.Add('aababaab', 'aaaaaabbbbbbbbaaaabbbbhhhhhaaadddd', []);
// 4. testcase: (pattern occures several time without overlapping each other)
testCases.Add('aababaab', 'aa' + testCases[3].pattern + 'a' + testCases[3].pattern, [3, 12]);
// 5. testcase (pattern occures several times with overlapping each other)
testCases.Add('aababaab', 'aababaababaab', [1, 6]);
// DONE: Building test cases
Wobei sich das Ganze auch über eine Klasse lösen liese.

implementation 12. Mai 2010 14:44

Re: const foo: array of TMyRecord = (myArray:???)
 
Zitat:

Zitat von himitsu
Sind in FPC auch Record-Methoden möglich?
Wenn ja, dann würde ich eine Verwendung dieser Vorschlagen.

Also bis Version 2.4.0 noch nicht. Muss man evtl. Klassen oder TP-Objekte nehmen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:44 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