Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Pointer :\ (https://www.delphipraxis.net/27627-pointer-%5C.html)

Snoop007 13. Aug 2004 10:18


Pointer :\
 
hi,
eigentlich dürfte das thema kein problem sein aber wieso kann ich den pointer so nicht benutzen ??

ich weiss der code macht so keinen sinn aber ich wollte nicht den kompletten code posten, zumal der Fehler bei fi := fp^; auftritt
Fehlermeldung : Operator auf diesen Operatortyp nicht anwendbar

Code:
var
  fi : File;
  fp : ^File;
begin
  fp := @fi;
  fi := fp^;
  ..
end;

Dannyboy 13. Aug 2004 10:37

Re: Porinter :\
 
Zitat:

ich weiss der code macht so keinen sinn
Dito. :mrgreen:
Meines Wissens kann man keine Pointer auf <File> setzen. Möchtest
Du mit "fi := fp^;" an den Inhalt von der Datei rankommen oder
wie? :gruebel: Mir ist momentan noch nicht ganz klar, was Du machen
möchtest, aber für Dateiverarbeitung sollest Du evtl. Hier im Forum suchenFilestreams
verwenden.

Was genau möchtest Du denn tun? :gruebel: Wenn Du uns das verrätst,
können wir Dir hoffentlich weiterhelfen.

DANNBOY

Nachtrag: Nenn' Deine Überschrift besser "Pointer". Ist aussagekräftiger als "Porinter". :zwinker:

Snoop007 13. Aug 2004 11:06

Re: Pointer :\
 
Prointer .. lol gar net gesehen

ich schreibe eine kompone die daten in eine datei typweise speichert
daher benutze ich in der gasamten komponente die selbe variable vom typ file
daich beim übergeben nicht immer die gesamte variable übergeben möchte wollte ich einen
pointer stattdessen übergeben .. aber wenn das nicht geht :\ schade

Dannyboy 13. Aug 2004 11:19

Re: Pointer :\
 
Zitat:

Prointer .. lol gar net gesehen
Schlimmer noch, es waren sogar "Porinter" :mrgreen:
Wie wäre es denn, wenn Du einen Zeiger auf die Variable
(nicht auf die Datei) an einen FileStream übergibst? :gruebel:
Bei der write-Funktion von TFilestream kannst Du ebenso exakt
die Anzahl der zu schreibenden Bytes (die Quelle wäre dann der
Pointer Deiner Variable) angeben. Ich beschäftige mich z.Zt. auch
mit dem Erstellen einer Datei, in die verschiedene Variablen mit
unterschiedlichen Längen und unterschiedlichen Datentypen
rein kommen. Klappt mit Filestreams ganz easy.

Snoop007 13. Aug 2004 11:20

Re: Pointer :\
 
*g
mh ich hab nu soweit alles mit assign ..reset .. rewrite usw. gemacht
gibts denn einen direkten vorteil gegenüber filestream ?

Dannyboy 13. Aug 2004 11:43

Re: Pointer :\
 
Liste der Anhänge anzeigen (Anzahl: 1)
Dieses ganze AssignFile-reset-rewrite-closeFile-Zeugs stammt
noch aus der Pascal-Zeit. Ich hab's damals auch so gelernt
und hatte kein Bock umzusteigen, aber das mit den Filestreams
ist wirklich (!) ganz einfach und bietet viele Vorteile
der Einfachheit und vor allem in der Geschwindigkeit.
Wenn Du z.B. einen Dateisplitter für beliebige Dateien schreiben möchtest
(siehe Anhang) dann kennst Du die Struktur der Dateien meistens gar nicht.
FileStreams sehen Strukturen einfach als eine Menge von einzelnen
Bytes an. Möchtest Du z.B einen Record speichern, dann machst Du das so:
Delphi-Quellcode:
type TMeinRecord = record
  buchstabe : Char;
  alter : byte;
  groesse : real;
  Daten : array[0..7] of byte;
end;
//...
  var MeinRecord : TMeinRecord;
//...
procedure schreibeMeinRecordInDatei;
  var Filestream: TFileStream;
begin
// FileStream:= TFileStream.create(<Dateiname>, <Zugriff auf Datei>);
   FileStream:= TFileStream.create('C:\test.dat', fmCreate OR fmShareExclusive);
// FileStream.write(<dantenquelle>, <anzahl der bytes>)
  FilStream.write(MeinRecord, SizeOf(TMeinRecord);
// Dateizugriff freigeben
  FileStream.free;
end;
Vorteile von der Pascal-Variante sind mir nicht bekannt. Hab' das aus dem
Kopf geschrieben, ergo ungetestet.
Nachtrag: Musst natürlich noch eventuelle
Exceptions abfangen.

Hansa 13. Aug 2004 11:57

Re: Pointer :\
 
Zitat:

Zitat von Snoop007
ich schreibe eine kompone die daten in eine datei typweise speichert daher benutze ich in der gasamten komponente die selbe variable vom typ file daich beim übergeben nicht immer die gesamte variable übergeben möchte wollte ich einen
pointer stattdessen übergeben .. aber wenn das nicht geht :\ schade

Schreiben mußt du echt noch üben. :lol: Was die Pointer angeht, so habe ich eine dumpfe Ahnung, was du meinst. 8) Das ^ vor einem Typ gibt einen Verweis auf die Stelle einer anderen Variable an. Steht es dahinter, so referenziert man den Inhalt des Pointers.

Nur, was hat das ganze mit Dateien zu tun ? Wahrscheinlich weißt du nicht, wieviel Platz irgendwas zur Laufzeit braucht. Und das soll in eine Datei. Wenn dem so ist, dann willst du das wohl in einer typisierten Datei speichern und das ist auch richtig. Wer weiß beim Programmieren schon, ob eine Rechnung jetzt 1 oder 1000 Positionen hat.

Was du wohl mit "Pointer" meinst, das sind dynamische Datenstrukturen (Listen, Bäume usw.). Da spielt sich aber alles im Hauptspeicher ab.

Soll es längere Zeit gespeichert bleiben, so gehört es in eine Datei / Datenbank. Das alles ist aber auch dynamisch. So, jetzt bin ich mit meinem Latein am Ende, was das ganze soll. :gruebel:

Snoop007 13. Aug 2004 12:04

Re: Pointer :\
 
Zitat:

Zitat von Hansa

Schreiben mußt du echt noch üben. :lol: ..

:stupid: danke ^^

ich wollte einfach statt der variablen File einen pointer übergeben aber so langsam glaub ich, dass das etwas blöd war :gruebel:


@Dannyboy
könnte ich damit auch listen ( arrays ) speichern, sieht bei deinem bsp so aus, wenn dem das so wäre
würde ich sofort darauf umsteigen; gleich mal testen :mrgreen:

Snoop007 13. Aug 2004 12:11

Re: Pointer :\
 
mh, damit kann man leider keine dynamischen listen speichern,
schade .. naja hätte ich mir auch denken können .. egal

dennoch danke euch :)

Dannyboy 13. Aug 2004 12:23

Re: Pointer :\
 
Zitat:

könnte ich damit auch listen ( arrays ) speichern, sieht bei deinem bsp so aus, wenn dem das so wäre
würde ich sofort darauf umsteigen; gleich mal testen
Natürlich geht das:
Delphi-Quellcode:
type TArray = array[0..1000, 3..99999] of integer;
Var meinArray : TArray;
//...
Filestream.write(meinArray, SizeOf(meinArray));
//...
Zitat:

mh, damit kann man leider keine dynamischen listen speichern,
schade .. naja hätte ich mir auch denken können .. egal
Hier geblieben, wir sind noch nicht fertig. :mrgreen:
Du muss nur an den Eintrag der Liste rankommen und dann wie gehabt:
Delphi-Quellcode:
VAR Eintrag : TListEintrag;
//...
FileStream.write(Eintag, SizeOf(Eintrag));
//...
Check this out.
DANNYBOY

Hansa 13. Aug 2004 12:44

Re: Pointer :\
 
Wie man an Dannyboys Beispiel schön sieht : er hat soviel Speicher reserviert, wie er maximal glaubt zu brauchen. Verschätzt er sich so hat er Pech. Ist der Platz zu gering bemessen dann auch.

Jetzt kommen Dateien und Listen ins Spiel. Letzteres ist wohl das, was du unter deinen "Porintern" verstehst. :mrgreen: Das betrifft aber nur den Hauptspeicher. Geht also nur, während das Programm läuft. Soll es gespeichert werden, na dann sind Dateien vorzuziehen.

Dannyboy 13. Aug 2004 13:06

Re: Pointer :\
 
Zitat:

Wie man an Dannyboys Beispiel schön sieht : er hat soviel Speicher reserviert, wie er maximal glaubt zu brauchen. Verschätzt er sich so hat er Pech. Ist der Platz zu gering bemessen dann auch.
@Hansa:
In meinem Beispiel wollte ich illustrieren, dass man ein großes, statisches Array in eine Datei
schreiben kann. Das hat gar nichts mit verschätzen zu tun, da hier gar nix berechnet werden muss
und es ging in meinem Beispiel auch gar nicht um irgend was dynamisches. Es ist einfach
nur ein großes, gefülltes, statisches Array, das in eine Datei geschoben wird.
Da ich die Datenstrukturen von Snoop007 nicht kenne, habe ich exemplarisch (er hatte bisher noch
nichts mit Filestreams gemacht) einfach mal die Größe des kompletten Arrays (bzw. Records)
übergeben. Ich kann bisher noch nicht erkennen, in wiefern ein solcher Stream einem dynamischen
Element (lineare Liste, binärer Baum, etc.) im Wege stehen sollte.
Du, Hansa, schreibst von der Verwaltung von Speicher und ich schreibe von Streams. ... Das eine
hat mit dem anderen erst mal nix zu tun, bis zu dem Zeitpunkt, in dem die Daten in eine Datei
transportiert werden. Ich sehe kein Problem darin, einzelne Einträge einer dynamischen Liste
in einen Stream zu packen und in Datei zu speichern.
Wo hakt's denn? :gruebel:

Hansa 13. Aug 2004 13:26

Re: Pointer :\
 
Zitat:

Zitat von Dannyboy
Wo hakt's denn? :gruebel:

Bei mir nirgends. :mrgreen: Jetzt hat er ja 2 Beispiele. Bzw. nur das von dir und meinen Vorschlag, wie es gehen kann, wenn es eben so nicht geht. :P Und das wird sowieso komplizierter. Also da ist jetzt eher snoop007 gefordert. Los, komm schon und sage uns was du genau willst. :shock:

Dannyboy 13. Aug 2004 13:35

Re: Pointer :\
 
Wir hatten damals im Informatik-Untericht die ganzen Listen und Bäume selbst mit
Zeigern schreiben dürfen (Pascal 7). In Delphi gibt's ja bestimmt vordefinierte
Konstrukte dafür, so dass man sich den Stress sparen kann.

maximov 13. Aug 2004 13:38

Re: Pointer :\
 
Moin,

alle die mit streams dynamische formate schreiben und laden wollen kann ich nur die TFiler klassen (TReader und TWriter) ans herz legen. Die sind wirklich sehr leicht in der handhabung und bieten für alle gängigen stadardtypen entsprechende funktion. Somit muss man sich nicht mehr mit buffern und der länge der daten herrum schlagen und kann sehr schön sequenziell lesen und schreiben.

Hier ein beispiel zum streamen einer 2D map:

Delphi-Quellcode:
Function TMap.SaveToStream(stream: TStream):Boolean;
Var writer : TWriter;
    i     : integer;
begin
  result := true;
  writer := TWriter.Create(stream, $ff);
  try
    try
      writer.WriteSignature;
      writer.WriteListBegin;
      writer.WriteString(ClassName);
      WriteData(writer);
      writer.WriteListEnd;
    except
      result := false
    end;
  finally
    writer.Free;
  end;
end;

Function TMap.LoadFromStream(stream: TStream):Boolean;
Var reader : TReader;
    ctype : TPersistentClass;
    cname : string;
begin
  result := true;
  reader:=TReader.Create(stream,$FFFF);
  try
    with reader do begin
      {read at beginning of file}
      ReadSignature;
      ReadListBegin;
      cname := ReadString;
      ctype := GetClass(cname);
      if Assigned(ctype) then
      begin
        try
          ReadData(reader);
        except
          result := False;
        end;
      end;
      ReadListEnd;
    end;
  finally
    reader.Free;
  end;
end;

procedure TMap.ReadData(reader: TReader);
var x,y,size : integer;
begin
 size := sizeOf(TField);
 with reader do begin
       MapName          := ReadString;
       coment        := ReadString;
       Bounds.X      := ReadInteger;
       Bounds.Y      := ReadInteger;
       //-- Read matrix -----
       SetToBounds(bounds,false);
       for x := 0 to Bounds.X-1 do
         for y := 0 to Bounds.Y-1 do
           Read(matrix[x,y],size);
       //----------------------
       ReadString;
       style         := Readinteger;
       mode          := Readinteger;
       TimeLimit     := Readinteger;
       GUID          := ReadString;
       Creator       := ReadString;
       CreateDate    := ReadDate;
  end;
end;

procedure TMap.WriteData(writer: TWriter);
var x,y,size : integer;
begin
  size := sizeOf(TField);
  with writer do begin
     WriteString(MapName);
     WriteString(coment);
     WriteInteger(Bounds.X);
     WriteInteger(Bounds.Y);
     //-- Write matrix -----
     for x := 0 to Bounds.X-1 do
       for y := 0 to Bounds.Y-1 do
         Write(matrix[x,y],size);
     //----------------------
     WriteString('');
     Writeinteger(style);
     Writeinteger(mode);
     Writeinteger(TimeLimit);
     WriteString(GUID);
     WriteString(Creator);
     WriteDate(CreateDate);
  end;
end;
Nur so als anregung, da ihr grad über dynamische (oder auch nicht) formate redet. Was meint ihr?

Snoop007 13. Aug 2004 13:40

Re: Pointer :\
 
:gruebel: ihr machts einem auch nicht leicht ^^

das mit den pointern habe ich es so gemeint wie ich esgeschrieben hatte, ich kenne den unterschied, *g vielleicht hab ich mich auch falsch ausgedrückt, oder ich habe versucht was unmögliches zu machen, wie es aus sah, also nochmal kurz dazu

ich wollte statt den wert der variabeln vom typ File, einfach einen pointer, der auf diese variable zeigt, übergeben und mit diesem pointer weiter hantieren, scheint aber nicht zu gehen ok, abgehkt :)

zu filestream, die liste sollte schon dynamisch sein, da ich nicht so viel speicher reservieren möchte,
die komponente beinhaltet mehrere dynamische attribute

ich frage mich nur, ob man mit filestream auch dynamische listen recht einfach speichern kann,
recht einfach soll hier heissen, ich gebe einfach nur den typ / das 1. element des array(liste) an
anstatt das gesamte array (liste) zu druchlaufen und jeweils den wert speichern

dass das mit typen ( records die ein "ende" haben ) geht, ist klar

Hansa 13. Aug 2004 13:50

Re: Pointer :\
 
Was du machen willst hört sich wirklich nach der Quadratur des Kreises an. Ich habe so was schon befürchtet. 8)

Also nochmals : was soll gespeichert werden ? Ist die Gesamtgröße stark variabel, oder die einzelnen Elemente ? Sogar in letzterem Fall gibt es noch eine Variante. Nämlich variante Records. Verstehe sowieso nicht ganz, warum du das mit Pointern machen willst. Normalerweise will sich jeder davor drücken. Meist wird nach Auswegen gesucht, um da drumrum zu kommen. :mrgreen:

teebee 13. Aug 2004 13:57

Re: Pointer :\
 
Wenn Dein dynamische Array ausschliesslich Nicht-Zeiger-Typen (keine Strings, Objekte) beinhaltet und auch nur eindimensional ist, kannst Du es mit einer SizeOf*Length-Konstruktion wie beim statischen Array an einen Stream übergeben.
In allen anderen Fällen musst du jeden einzelnen Wert durchlaufen.

Gruß, teebee

Snoop007 13. Aug 2004 14:03

Re: Pointer :\
 
hehe, die komponente sollte so schnell wie möglich daten verarbeiten können

die komponente ist eine klasse, die 2 records beinhaltet,
diese 2 records haben ca. 2 - 3 records und paar dynamische listen
die records der records haben dynamische elemente so und da ich nun alle durcheinander gebracht habe
sell ich das mal grafisch dar :mrgreen:
Code:
Hauptkomponente ( class )
|
--record
|   |
|   |- record
|   |- record
|       |- attribute
|       |- attribute [] ( länge dynamisch )
|   | - record
|   |- attribute
|   |- attribute [] ( länge dynamisch )

|--record
  |- record
  |- attribute
  |- attribute [] ( länge dynamisch )
  |- attribute [] ( länge dynamisch )
gespeichert werden soll die hauptkomponente

ich wollte schon anfangen die listen zu druchlaufen und jedes elemt der liste einzeln zu speichern, wäre ja schönn wenn das mit erspart bliebe :mrgreen:

aber ich glaube das geht nicht

edit : doch, die array bestehen meist aus strings allerding mit "nur" 254 zeichen

teebee 13. Aug 2004 14:11

Re: Pointer :\
 
Ein wichtiges weiteres Problem ist übrigens bei dynamischen Längen das Einlesen: Du musst wissen, von wo bis wo Do einlesen musst, also muss die Länge eines Blocks irgendwo stehen. Ich denke, um eine eigene Speicherlogik wirst Du nicht herumkommen.

Gruß, teebee

maximov 13. Aug 2004 14:18

Re: Pointer :\
 
@Snoop007: hast du mein posting von der letzten seite gesehen? Mit den Filer-klassen sind solche strukturen kein problem -> siehe WriteBegin, WriteListEnd etc. - Schliesslich wurde diese klassen designed um die delphi komponenten-bäume zu speichern (binär wohlgemerkt). Man kann sie aber auch für alle anderen zwecke einsetzen!

Snoop007 13. Aug 2004 14:24

Re: Pointer :\
 
@TeeBee, die struktur der datei und das ganze geplante ist abgeschlossen und wird nun in die tat umgesetzt

@maximov, ich seh bei deinem code keine klasse, keinen record, dein dynamisches element :gruebel:
vielleicht bin ich auch nur bissel doof :stupid:

maximov 13. Aug 2004 14:39

Re: Pointer :\
 
Das array (matrix) ist ein dynamisches array of record und die strings sind auch alle dynamisch und die klassen sind TFiler und TReader (classes.pas). Sieht man doch. Die ganzen deklarationen hab ich weggelassen, weil ich nur den umgang mit den filer-klassen demonstrieren wollte!

Snoop007 13. Aug 2004 14:52

Re: Pointer :\
 
aber so kann ich da nichts erkennen, da ich ja nicht weiss, wie das ganze zusammenhängt
wäre nett, wenn du das evtl. als anhang dran hängen könntest :)

maximov 13. Aug 2004 15:33

Re: Pointer :\
 
Na, ok:

Delphi-Quellcode:
Type
     TField = record
        way  : byte;
        item : byte;
        tag  : byte;
        flags : byte;
        ran  : byte;
     end;


     TMatrix = array of array of TField;

     TMap = class(TDynaVisible)
     Private
       FMapFile: string;
       procedure SetMapFile(const Value: string);
     Public
       MapName        : STring;
       Coment      : String;
       Bounds      : TPoint;
       Matrix      : TMatrix;
       style       : integer;
       mode        : integer;
       TimeLimit   : integer;
       GUID        : STring;
       Creator     : String;
       CreateDate  : TDateTime;
 
       Function SetToBounds(xBounds: TPoint; NoKill: boolean = true):TPoint;
       procedure ReadData(reader : TReader); dynamic;
       procedure WriteData(writer : TWriter); dynamic;
       Function SaveToStream(stream : TStream):Boolean;
       Function LoadFromStream(stream : TStream):Boolean;
       Function LoadFromeFile(const fName: String):Boolean;
       Function SaveToFile(const fName: String):Boolean;

     published
       property iName : string read MapName;
       property iComent: string read Coment;
       property iStyle: integer read style;
       property iMode: integer read Mode;
       property iTimeLimit: integer read TimeLimit;
     end;


...

function TMap.SetToBounds(xBounds: TPoint; NoKill: boolean = true): TPoint;
// setzt die dynamische grössen des map-arrays.

function TMap.LoadFromeFile(const fName: String): Boolean;
var
  stream : TFileStream;
begin
  stream := TFileStream.Create(fname, fmOpenRead);
  try
    LoadFromStream(stream);
  finally
    stream.Free;
  end;
end;

function TMap.SaveToFile(const fName: String): Boolean;
var
  stream : TFileStream;
begin
  stream := TFileStream.Create(fname, fmCreate or fmOpenWrite);
  try
    SaveToStream(stream);
  finally
    stream.Free;
  end;
end;
Die bezeichner der felder und properties sind nicht sehr stardardmässig da der code schon sehr alt ist, aber einer meiner ersten schönen dynamischen streaming-versuche :wink:

Snoop007 13. Aug 2004 19:24

Re: Pointer :\
 
ah super danke :) :thumb:
woher wusstest du das, es TWrite gibt bzw. was es macht ? aus einem tut oder Buch ?

an alle anderen vielen dank !

maximov 13. Aug 2004 23:12

Re: Pointer :\
 
Habs durch zufall gefunden und war begeistert :-D Leider war es damals undokumentiert und die tuts sehr mager. Die filer sind halt coole stream-helper und ganz einfach, wenn man einmal begriffen hat wie sie arbeiten.


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