Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Von C nach Delphi: Benötige Hilfe (https://www.delphipraxis.net/143840-von-c-nach-delphi-benoetige-hilfe.html)

Jazzman_Marburg 24. Nov 2009 14:09


Von C nach Delphi: Benötige Hilfe
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mahlzeit!

Ich möchte einen Teil eines C-Programms nach Delphi konvertieren, aber habe Probleme mit den im C-Teil ab- und an vorkommenden Pointern. Mir ist klar, dass ich auch in Delphi Pointer direkt nutzen kann -- aber da ich sie bisher noch nie gebraucht habe (jedenfalls nicht explizit) wäre es natürlich schön, wenn ich sie nun auch vermeiden könnte.
Es geht schon los mit folgendem:

/* Type declarations for the postfix string, stored in a binary tree */

typedef struct tnode {
int key; /* leaf value */
char op; /* internal node operator */
struct tnode *left, *right; /* left and right children */
} treenode, *treeptr;

/* Type declarations for base modules information */

typedef struct rectangle {
float area; /* rectangle area */
float height; /* rectangle height */
float width; /* rectangle width */
int fixed; /* fixed orientation if == 1 */
treeptr ptr; /* pointer to a tree node */
} base_rectangle;

Wie setze ich treeptr_ptr um?
In Delphi werden die beiden struct wohl RECORDS werden -- aber *left und *right, und *treeptr ?!

Kann da jemand behilflich sein?
Geht das übrhaupt -- auf die expliziten Pointer verzichten, oder muß man dann das ganze Programm komplett umschreiben?
(Achso, nur zum Verständnis: Es geht um binäre Bäume -- falls es jemandem für das Verständnis hilft, das 150 Zeilen C-Programm habe ich hochgeladen.)

Vielen Dank & Tschöh
Jazzman

Medium 24. Nov 2009 14:12

Re: Von C nach Delphi: Benötige Hilfe
 
Bei der Umsetzung mit Records wirst du nicht auf ausgeschriebene Pointer verzichten können. Wenn du nicht 1:1 umsetzen musst, sondern auf Klassen gehen könntest, wäre das schmucker.

himitsu 24. Nov 2009 14:18

Re: Von C nach Delphi: Benötige Hilfe
 
Code:
type name   =  Name: Type;
type *name  =  Name: ^Type;  =  Name: PType[color=#008000]{ein Pointer}[/color];
Code:
typedef struct tnode {
  int key; /* leaf value */
  char op; /* internal node operator */
  struct tnode *left, *right; /* left and right children */
} treenode, *treeptr;
Delphi-Quellcode:
type
  PTreeNode = ^TTreeNode;
  TTreeNode = record
    key: Integer; // leaf value
    op: Char;    // internal node operator
    left, right: PTreeNode; // left and right children
  end;

Mithrandir 24. Nov 2009 14:23

Re: Von C nach Delphi: Benötige Hilfe
 
Delphi-Quellcode:
PTreeNode = TTreeNode;
Haste da nicht ein "^" vergessen?

himitsu 24. Nov 2009 14:28

Re: Von C nach Delphi: Benötige Hilfe
 
nööööööööö :angel2:

Mithrandir 24. Nov 2009 14:32

Re: Von C nach Delphi: Benötige Hilfe
 
:mrgreen:

Jazzman_Marburg 24. Nov 2009 14:36

Re: Von C nach Delphi: Benötige Hilfe
 
Sorry Jungens -- aber ich verstehe eure interne Debatte nicht:
Was hat es mit:
PTreeNode = TTreeNode;
und einem (nicht) vergessenen ^ auf sich?

(bin nur ein wenig irritiert)

Danke & Gruß
Jazzman

mleyen 24. Nov 2009 14:45

Re: Von C nach Delphi: Benötige Hilfe
 
1. himitsu hat den dereferenzierungsoperator ^ vergessen.
2. Daniel G hat ihn darauf hingewiesen.
3. himitsu hat es klammheimlich wegkorrigiert (editiert) und ironischerweise behauptet es wäre schon richtig gewesen.
4. Daniel G hat himitsu darauf hingewiesen, das er den Scherz verstanden hatte.

:cheers:

OnT:
Ich würde mir doch lieber 'kurz' die Zeiger in Delphi aneignen. Ist bestimmt auf Dauer lohnenswerter, als sich jetzt eine Alternative zu suchen.

Mithrandir 24. Nov 2009 14:46

Re: Von C nach Delphi: Benötige Hilfe
 
Zitat:

Zitat von Jazzman_Marburg
PTreeNode = ^TTreeNode;

Man stellt i.d.R. ein "P" vor die Typenbezeichnung, um zu kennzeichnen, dass es sich um einen Pointer auf die Struktur handelt. Das weiß der Compiler aber nicht. Deswegen braucht er ein "^". Das ist gleichbedeutend mit dem "*" aus C.

edit: @mleyen: Oder so. :lol:

Jazzman_Marburg 24. Nov 2009 14:55

Re: Von C nach Delphi: Benötige Hilfe
 
Ok- jetzt habe ich es auch verstanden :wall:

Aber, ich habe immer noch Probleme mit dem folgenden ( :oops: scuzi!):

Delphi-Quellcode:
/* Type declarations for base modules information */ 
typedef struct rectangle { 
float area;    /* rectangle area */ 
float height;  /* rectangle height */ 
float width;   /* rectangle width */ 
int fixed;     /* fixed orientation if == 1 */ 
treeptr ptr;   /* pointer to a tree node */ 
} base_rectangle;
Weil, so wie das obige Beispiel, läßt sich dieses ja nicht umsetzen. Was hat es mit dem abschließenden base_rectangle auf sich?

Danke nochmal
Jazzman

Uwe Raabe 24. Nov 2009 15:37

Re: Von C nach Delphi: Benötige Hilfe
 
Zitat:

Zitat von Jazzman_Marburg
Was hat es mit dem abschließenden base_rectangle auf sich?

In C wird damit gleich eine Variable dieses Typs deklariert.

Delphi-Quellcode:
type
  Float = Single; // oder Double? Vergess ich immer wieder
  TRectangle = record // hier müsste man eventuell noch das Align anpassen
    area: float;    
    height: float;  
    width: float;  
    fixed: Integer;    
    ptr: TTreeNode;   // oder wie der Typ bei dir nun heißt
  end;

var
  base_rectangle: TRectangle;

Mithrandir 24. Nov 2009 15:43

Re: Von C nach Delphi: Benötige Hilfe
 
Zitat:

Zitat von Uwe Raabe
Delphi-Quellcode:
type
  Float = Single; // oder Double? Vergess ich immer wieder
  TRectangle = record // hier müsste man eventuell noch das Align anpassen
    {...}
    ptr: PTreeNode;   // oder wie der Typ bei dir nun heißt <--- Dit is n Pointer... *g*
  end;

var
  base_rectangle: TRectangle;

:mrgreen:

Uwe Raabe 24. Nov 2009 15:58

Re: Von C nach Delphi: Benötige Hilfe
 
Zitat:

Zitat von Daniel G
Delphi-Quellcode:
    ptr: PTreeNode;   // oder wie der Typ bei dir nun heißt <--- Dit is n Pointer... *g*

Stimmt, hatte irgendwie TTreeNode als class im Sinn. Wie komm ich bloß darauf...

Jazzman_Marburg 24. Nov 2009 16:13

Re: Von C nach Delphi: Benötige Hilfe
 
Vielen Dank an alle, aber da hätte ich noch einen :cry: :

Delphi-Quellcode:
treeptr Rootptr()
{
/* initialize the root of the tree */
   treeptr t = (treeptr)malloc(sizeof(*t));
   t->key = -1;
   t->op = '?';
   t->left = NULL;
   t->right = NULL;
   return t;
}
Lauter Böhmische-Döfer...

Lieben Dank
Jazzman

himitsu 24. Nov 2009 16:29

Re: Von C nach Delphi: Benötige Hilfe
 
malloc ist soviel wie Delphi-Referenz durchsuchenGetMem, wobei hier Delphi-Referenz durchsuchenNew sich hier auch gut machen würde.

-> entspricht dem .

Medium 24. Nov 2009 16:32

Re: Von C nach Delphi: Benötige Hilfe
 
Genauer genommen entspricht "->" "^.", aber Delphi dereferenziert glaub ich bei typisierten Pointern implizit.

Jazzman_Marburg 24. Nov 2009 17:02

Re: Von C nach Delphi: Benötige Hilfe
 
Danke.

D.h. obiges sollte in Delphi dann so etwa aussehen:

Delphi-Quellcode:
FUNCTION Rootptr: PTreeNode; // initialize the root of the tree
VAR t : PTreeNode;
BEGIN
  t      := GetMem(PTreeNode, ^t);
  t.key  := -1;
  t.op   := '?';
  t.left := NULL;
  t.right := NULL;
  Result := t;
END;

Vielen Dank
Jazzman

Uwe Raabe 24. Nov 2009 18:45

Re: Von C nach Delphi: Benötige Hilfe
 
Statt NULL solltest du besser nil nehmen. Null ist als function deklariert, die einen Null-Variant zurückgibt.

Jazzman_Marburg 24. Nov 2009 20:22

Re: Von C nach Delphi: Benötige Hilfe
 
Danke - NIL sieht tatsächlich besser aus als NULL.

Aber ich tu mich mit dem folgendem noch schwer:

Code:
treeptr Rootptr()
{
/* initialize the root of the tree */
   treeptr t = (treeptr)malloc(sizeof(*t));
   t->key = -1;
   t->op = '?';
   t->left = NULL;
   t->right = NULL;
   return t;
}
Da sieht mir mein GetMem irgendwie nicht korrekt aus -- und der Compiler meldet in dieser Zeile ein:
Fehler '(' erwartet, aber ',' gefunden
Hier nochmal meine 'Übersetzung':

Delphi-Quellcode:
FUNCTION Rootptr: PTreeNode;
VAR t : PTreeNode;
BEGIN
  t      := GetMem(PTreeNode, SizeOf(^t));
  t.key  := -1;
  t.op   := '?';
  t.left := NIL;
  t.right := NIL;
  Result := t;
END;
Vielleicht jemand eine Idee?

Gruß
Jazzman

wicht 24. Nov 2009 20:39

Re: Von C nach Delphi: Benötige Hilfe
 
GetMem(t, SizeOf(TTreeNode));

Jazzman_Marburg 24. Nov 2009 20:47

Re: Von C nach Delphi: Benötige Hilfe
 
Zitat:

GetMem(t, SizeOf(TTreeNode));
Hhmm, das wiederum führt zu:

E2010 Inkompatible Typen: 'PTreeNode' und 'procedure, untyped pointer or untyped parameter'

Da ist irgendwie der Wurm drin.

Gruß
Jazzman

himitsu 24. Nov 2009 20:54

Re: Von C nach Delphi: Benötige Hilfe
 
GetMem ist eine Prozedur
Delphi-Quellcode:
FUNCTION Rootptr: PTreeNode;
VAR t : PTreeNode;
BEGIN
  GetMem(t, SizeOf(^t));
  t.key  := -1;
  t.op   := '?';
  t.left := NIL;
  t.right := NIL;
  Result := t;
END;
in Delphi beendet Result nicht die Prozedur, also braucht man keine TempVariable
Delphi-Quellcode:
FUNCTION Rootptr: PTreeNode;
BEGIN
  New(Result);
  Result.key  := -1;
  Result.op   := '?';
  Result.left := NIL;
  Result.right := NIL;
END;

Jazzman_Marburg 25. Nov 2009 18:29

Re: Von C nach Delphi: Benötige Hilfe
 
Hallo!

Die Übersetzung macht (dank eurer großen Hilfe) Fortschritte, aber scheitere ich schon wieder.
Kann mir das jemand nach delphianisch übersetzen?

(Statt in einen File, soll alles in eine Liste : TStringList geschrieben werden)
Code:
  fprintf ("Number of modules = %d\n", no_modules);
  fprintf (mod_file,"%e %e %d\n", in_module[i].height, in_module[i].width, in_module[i].fixed);
Für die erste Zeile habe ich es mit:
Liste.Add(FORMAT('Number of modules = %d', IntToStr(no_modules)));
versucht, aber das bringt Fehler: E2250 Es gibt keine überladene Version von 'Format', die man mit diesen Argumenten aufrufen kann

Deshalb habe ich die zweite Zeile erst garnicht erst versucht.

Eine Idee?

Danke & Gruß
Jazzman

DeddyH 25. Nov 2009 18:37

Re: Von C nach Delphi: Benötige Hilfe
 
Delphi-Quellcode:
Liste.Add(FORMAT('Number of modules = %d', [IntToStr(no_modules)])); //die eckigen Klammern nicht vergessen

Jazzman_Marburg 25. Nov 2009 19:09

Re: Von C nach Delphi: Benötige Hilfe
 
Merci.

Jazzman

Jazzman_Marburg 27. Nov 2009 09:40

Re: Von C nach Delphi: Benötige Hilfe
 
Hallo!

Ein weiterer Stolperstein im Projekt C ==> Delphi:

Code:
  float s;  /* real random number */

  s = rand()/(RAND_MAX+1.0);
"RAND_MAX" kennt Delphi ja nicht.
Was wäre dann wohl eine korrekte Übersetzung?

Vielen Dank im voraus :stupid:
Jazzman

DeddyH 27. Nov 2009 09:45

Re: Von C nach Delphi: Benötige Hilfe
 
Dann definier doch einfach eine Konstante mit dem entsprechenden Wert.

Jazzman_Marburg 27. Nov 2009 09:52

Re: Von C nach Delphi: Benötige Hilfe
 
Hallo.

Ähm, was ist denn der "entsprechende" Wert für RAND_MAX?

Oder missverstehe ich den Hinweis?

Gruß
Jazzman

DeddyH 27. Nov 2009 09:56

Re: Von C nach Delphi: Benötige Hilfe
 
Delphi-Quellcode:
const RAND_MAX = $7FFF;
Zumindest bei Microsoft, beim GNU-Compiler wäre das MAXINT, wie ich in einer schnellen Recherche ermitteln konnte.

Jazzman_Marburg 27. Nov 2009 10:19

Re: Von C nach Delphi: Benötige Hilfe
 
Juups - Dankeschön!

Gruß
Jazzman

Jazzman_Marburg 28. Nov 2009 11:16

Re: Von C nach Delphi: Benötige Hilfe
 
Moin, Moin!

Mein Projekt "von C nach Delphi" ist mittlerweile von der 1:1 Übersetzung ins Stadium des Debuggens übergegangen. D.h. die Compilierung ist fehlerfrei -- aber es hackt bei dem Versuch es laufen zu lassen, und da habe ich Zweifel an meinen Übersetzungskünsten bekommen.

Vielleicht kann sich nochmal ein Experte folgendes Coding anschauen - ich zeige nur die relevante Stelle, an der es knallt (Zugriffsverletzung):
Hier der Original (d.h. fehlerfreie) C-Code:

Code:
typedef struct tnode {
   int key;          
   char op;          
   struct tnode *left, *right;
} treenode, *treeptr;  

typedef struct rectangle {
   float area;  
   float height;
   float width;
   int fixed;  
   treeptr ptr;     /* pointer to a tree node */
} base_rectangle;

  base_rectangle in_module[MAXMOD]; /* array of modules */
 
  in_module[j].ptr->key = j;
Und hier meine Delphi-Übersetzung:

Delphi-Quellcode:
TYPE
  PTreeNode = ^TTreeNode;
  TTreeNode = RECORD
    Key  : INTEGER;  
    Op   : CHAR;    
    Left : PTreeNode;
    Right : PTreeNode;
  END; // TTreeNode

TYPE
  Float = Single;    
  TRectangle = record
    Area : Float;    
    Height: Float;    
    Width : Float;    
    Fixed : INTEGER;  
    Ptr  : PTreeNode; // pointer to a tree node
  END; // TRectangle
 
  in_module    : ARRAY [0..MAXMOD] OF TRectangle; // array of modules
   
  in_module[j].ptr.key := j; // hier knallt es!
Es knallt in der o.g. letzten Zeile. Wenn j = 0 läufts gut, denn dann ist ptr = $12FE1D0, und die Zuweisung klappt. Wenn aber j = 1 dann ist ptr = nil, und dann haut es nicht mehr hin.
Aber ich bin mir nicht sicher, ob mein Ausdruck "in_module[j].ptr.key := j;" überhaupt dem C-Ausdruck "in_module[j].ptr->key = j;" equivalant ist?

Wäre großartig wenn sich das mal jemand anschauen würde.

Lieben Dank & Gruß
Jazzman

DeddyH 28. Nov 2009 11:32

Re: Von C nach Delphi: Benötige Hilfe
 
Wenn ich nicht irre:
Delphi-Quellcode:
in_module    : ARRAY [0..MAXMOD - 1] OF TRectangle;
Und die Schleife wäre einmal interessant zu sehen.

Jazzman_Marburg 28. Nov 2009 12:18

Re: Von C nach Delphi: Benötige Hilfe
 
Gute Idee!

Zitat:

in_module : ARRAY [0..MAXMOD - 1] OF TRectangle;
Ich muß alle Arrays mal darauf überprüfen -- aber zunächst hat es noch keine Wirkung gezeigt.
Die Schleife sieht wie folgt aus:

Delphi-Quellcode:
 IF i > to_slice+1 THEN
   BEGIN
     FOR j := to_slice TO i-1 DO
     BEGIN
       in_module[j].height := in_module[j+1].height;
       in_module[j].width := in_module[j+1].width;
       in_module[j].area  := in_module[j+1].area;
       in_module[j].ptr   := in_module[j+1].ptr;
       in_module[j].ptr.key := j;       // <= geht schief
     END;
     in_module[i-1].height := other_cut;
     in_module[i-1].width := width;
     in_module[i-1].area  := other_cut * width;
   END;
In C sieht sie so aus:

Code:
if (i > to_slice+1)

  for (j = to_slice; j < i-1; j++)
  {
    in_module[j].height = in_module[j+1].height;
    in_module[j].width = in_module[j+1].width;
    in_module[j].area = in_module[j+1].area;
    in_module[j].ptr = in_module[j+1].ptr;
    in_module[j].ptr->key = j;
  }
  in_module[i-1].height = height;
  in_module[i-1].width = other_cut;
  in_module[i-1].area = height*other_cut;
}
Dankeschön

Jazzman

DeddyH 28. Nov 2009 12:34

Re: Von C nach Delphi: Benötige Hilfe
 
Delphi-Quellcode:
FOR j := to_slice TO i-2 DO // "< i-1" im C-Code
[edit] Und nicht zuletzt aus Verständnisgründen würde ich die Dereferenzierung auch als solche kenntlich machen.
Zitat:

Delphi-Quellcode:
in_module[j].ptr.key := j;

-->
Delphi-Quellcode:
in_module[j].ptr^.key := j;
[/edit]

Jazzman_Marburg 28. Nov 2009 15:11

Re: Von C nach Delphi: Benötige Hilfe
 
[quote="DeddyH"]
Delphi-Quellcode:
FOR j := to_slice TO i-2 DO // "< i-1 im C-Code
Danke DeddyH!
Nachdem ich nun alle Array-Grenzen und For-Loop Abbruch-Bedingungen nach Deinem Vorschlag modifiziert habe, funktionert es!
Läuft wie von der Tarantel gestochen! Vielen Dank.

Auch an die anderen hilfreichen Geister: Vielen Dank!

Kleine Zusammenfassung meines Projekts "Von C nach Delphi":
Schon ein komisches Volk, diese C-Jünger ;-)
Es war meine erste Erfahrung mit C (Standard C, kein C++). Im Nachhinein, nicht sooo verschieden von Pascal -- aber das was verschieden ist, habe ich dann auch promt verkehrt gemacht (De-Refernzieren, Array-Grenzen, Schleifen Bedingungen). Wenn ich mir den fertigen Code jetzt so anschaue: Ich denke ein komplettes Neu-Schreiben hätte nicht so furchtbar viel länger gedauert -- mit dem Vorteil es wäre lesbarer.
Das ist auch mein Fazit: Delphi Code ist für mich lesbarer als C-Code. C-Coding erscheint mir teilweise sehr kompakt, da es nicht so "prosaisch" ist wie Delphi (oder in diesem Fall Pascal, da kein OOP), aber das macht es nicht unbedingt lesbarer. Aber vielleicht schätzen C-Programmierer genau das an C.

Also nochmals Danke an alle Mitwrikenden.

Delphi-Praxis ist schon ein sehr nettes Forum (da ich gern auch mit LaTex rumspiele, könnt ich euch Geschichten aus anderen Foren erzählen, Du lieber Himmel!).

Schönen Samstag noch weiters!

Gruß
Jazzman


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:35 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz