Matroids Matheplanet Forum Index
Moderiert von matph
Informatik » Programmieren » Umwandlung von C in Java-Programm - was bei Beispielen zu beachten
Autor
Kein bestimmter Bereich Umwandlung von C in Java-Programm - was bei Beispielen zu beachten
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Themenstart: 2021-07-24

Hallo Leute! Ich möchte jetzt doch ein C-Programm in ein Java-Programm umwandeln. Was muss ich dabei beachten (Beispiele von mir)? Wie kann ich die C-Befehle in Java-Befehle umsetzen? Das ist aus der Rubrik "verschüttgegangenes Wissen". Ich hatte vor langer Zeit schon mal etwas mit C/C++ und mehr mit Java gearbeitet. \sourceon C (a) machine *schedule; (b) jobstep **jobhead; // was ist der Unterschied zwischen (a) und (b)? (c) int num_of_jobs; // sollte auch in Java so sein(?) (d) typedef struct bnbnode { int value; edgelist *branchlist; struct bnbnode *next; } bnbnode; // kann ich die Struktur so in Java übernehmen? (e) bnblist = bnblist->next; (f) if (munchit(&bestv1, &bestv2, &bestj1, &bestj2, &edges)) { // ich habe vergessen was die "&" bedeuten... \sourceoff Viele Grüße Ronald


   Profil
DerEinfaeltige
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.02.2015
Mitteilungen: 2970
  Beitrag No.1, eingetragen 2021-07-24

\quoteon(2021-07-24 04:18 - Delastelle im Themenstart) \sourceon C (a) machine *schedule; // Pointer auf schedule vom Typ machine (b) jobstep **jobhead; /* Pointer auf Pointer; U.a. verwendet wenn *jobhead Kopf eines dynamischen Arrays ist. */ (c) int num_of_jobs; // Namenskonvention in Java ist CamelCase. Ansonsten passt das. (d) typedef struct bnbnode { int value; edgelist *branchlist; struct bnbnode *next; } bnbnode; // struct entspricht in Java einer sehr einfachen Klasse // struct könnte auch durch eine Map simuliert werden (e) bnblist = bnblist->next; // In Java wird immer der Punkt-Operator verwendet. // bnblist = bnblist.next; (f) if (munchit(&bestv1, &bestv2, &bestj1, &bestj2, &edges)) { // Die Amperesand sind Adressoperatoren. // &bestv1 bspw. gibt den Pointer auf bestv1 zurück. // In Java gibt es keine // rohen Pointer, sondern nur Referenzen. \sourceoff Viele Grüße Ronald \quoteoff Es gibt zwar Tools zum Konvertieren; falls die Programme nicht zu umfangreich sind, würde ich sie jedoch neu implementieren, um menschenlesbaren und natürlich wirkenden Code zu erhalten.


   Profil
AlphaSigma
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 23.11.2012
Mitteilungen: 283
  Beitrag No.2, eingetragen 2021-07-24

Hallo Delastelle, wenn das C-Programm nur einige Hundert Zeilen hat, kann man versuchen es manuell nach Java zu portieren. Bei größeren Programmen würde ich davon abraten. Ist Dir der Unterschied zwischen C und C++ bekannt. C und Java sind komplett unterschiedliche Sprachem mit unterschiedlichen Paradigmen. In C++ kann man auf sehr unterschiedliche Arten programmieren u.a. objektorientiert. Ein C++ Programm, welches objektorientiert programmiert ist, hat am ehesten Gemeinsamkeiten mit Java. In C++, und noch mehr in C, ist aber viel mehr erlaubt als in Java. Pointer, wesentlich in C (und C++), kann man in Java nicht direkt verwenden. Dein Beispiel Code enthält Pointer. \sourceon C int *num; // num ist ein Pointer auf die Integer-Variable *num int nim; // nim ist Integer, &nim liefert die Adresse von nim num = &nim // weist dem Pointer num die Adresse von nim zu \sourceoff


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Beitrag No.3, vom Themenstarter, eingetragen 2021-07-24

Hallo, erst mal Danke. Zum Nachdenken bringt mich Pointer von Pointer. Naja. Mal Sehen. Viele Grüße Ronald


   Profil
AlphaSigma
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 23.11.2012
Mitteilungen: 283
  Beitrag No.4, eingetragen 2021-07-25

\quoteon(2021-07-24 23:55 - Delastelle in Beitrag No. 3) Hallo, erst mal Danke. Zum Nachdenken bringt mich Pointer von Pointer. Naja. Mal Sehen. Viele Grüße Ronald \quoteoff Chapter 22: Pointers to Pointers


   Profil
tactac
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 15.10.2014
Mitteilungen: 2154
  Beitrag No.5, eingetragen 2021-07-25

Java hat auch nativ keine Referenzen auf lokale Variablen oder so. Wenn einem nichts besseres einfällt, kann man sowas aber auch mit dem Holzhammer fast nachbasteln. Kern wären Interfaces wie diese: \sourceon Java interface Ref {T get(); void put(T x);} interface IntRef {int get(); void put(int x);} \sourceoff , die man als Typen für die "Zeiger" verwenden kann, auch verschachtelt, also Ref> pppi ist natürlich möglich. An Stellen, wo C-Code "Adressen" ermittelt (mittels &), müsste der entsprechende Java-Code so ein Referenz-Objekt erzeugen. Und je nachdem, ob über einen Zeiger gelesen oder geschrieben werden soll, ist get oder put zu verwenden. \sourceon C void foo(int* pi) { int x = *pi; *pi = 7; int *y = &x; } \sourceoff \sourceon Java void foo(IntRef pi) { int x = pi.get(); pi.put(7); IntRef y = new IntRef { int get() {return x;} void put(int v) { x = v; } // :( } } \sourceoff Das "einzige" Problem ist nur, dass die mit :( markierte Stelle nicht geht, da Closures nur auf "effectively final" lokale Variablen Zugriff haben. Ein Workaround ist da die Verwendung von einelementigen Arrays.


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Beitrag No.6, vom Themenstarter, eingetragen 2021-07-25

Hallo, Es sind 9 kleinere Files mit etwa 2500 Zeilen. Wobei sich vieles wiederholt oder mir bekannt ist. Z.B. Variable++ \sourceon C (g) while (bnblist) { ... edges = bnbnext->branchlist; (void) doedge(edges); free_bnbnode (bnbnext); if (munchit(&bestv1, &bestv2, &bestj1, &bestj2, &edges)) { printf (" split into %d %d\n",bestv1,bestv2); splitit(&bnblist, bestv1, bestv2, bestj1, bestj2, edges); } else { printf ("%d (%d) killed\n",bnbeval,holdval); fflush (stdout); } (void) undoedge(edges); } \sourceoff Wie sind die beiden void-Befehle zu verstehen? Der Rest dürfte für mich umsetzbar sein. Sind dies neue Prozeduren oder nur Aufrufe von Prozeduren? Viele Grüße Ronald Edit: zu Beitrag 5. Es soll ja etwas berechnet werden (Optimierungsproblem mit vielen Teilproblemen). Ich hoffe nur man kann das gut in Java umsetzen. Wenn der Programmierer freundlicherweise mit Fortran gearbeitet hätte, wäre es für mich einfacher! [Die Antwort wurde nach Beitrag No.4 begonnen.]


   Profil
tactac
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 15.10.2014
Mitteilungen: 2154
  Beitrag No.7, eingetragen 2021-07-25

Die (void) bla machen zur Laufzeit semantisch dasselbe wie bla. Es werden damit höchstens Warnmeldungen von statischen Analyzern (wie u.a. dem Compiler) à la "Achtung: du wirfst da den Rückgabewert weg!" unterdrückt.


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Beitrag No.8, vom Themenstarter, eingetragen 2021-07-25

Danke schön. Und noch eine Frage zur Nacht: es sind im Programm viele ähnliche Teilprobleme zu lösen. Kann Java(welche Version) da 2 oder mehr Prozessoren verwenden (Befehle)?


   Profil
DerEinfaeltige
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.02.2015
Mitteilungen: 2970
  Beitrag No.9, eingetragen 2021-07-25

Java beherrscht natürlich Multithreading. Für parallelisierbare Schleifen etc. gibt es fertige Lösungen.


   Profil
zippy
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 24.10.2018
Mitteilungen: 2592
  Beitrag No.10, eingetragen 2021-07-25

\quoteon(2021-07-25 03:03 - Delastelle in Beitrag No. 8) Kann Java(welche Version) da 2 oder mehr Prozessoren verwenden (Befehle)? \quoteoff Java unterstützt seit Version 1.0 die Verwendung von Threads. Dafür, dass dein Programm von dieser Möglichkeit Gebrauch macht, musst du allerdings selbst sorgen. Java kann ein rein sequentielles Programm nicht "automatisch" parallelisieren. --zippy [Die Antwort wurde nach Beitrag No.8 begonnen.]


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Beitrag No.11, vom Themenstarter, eingetragen 2021-07-25

Ok. Ich habe bisher mehrmals mit Java gearbeitet, aber nie mehrere Prozessoren ausgenutzt. Was spricht eigentlich dafür, nur eine Klasse in Java im Programm zu verwenden. Und was spricht für mehrere Java-Klassen? Falls ich es hinbekomme, reicht vielleicht eine Klasse. Das C-Programm besteht aus mehreren Teilen - dies spricht eher für mehrere Klassen in Java.


   Profil
zippy
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 24.10.2018
Mitteilungen: 2592
  Beitrag No.12, eingetragen 2021-07-25

\quoteon(2021-07-25 11:34 - Delastelle in Beitrag No. 11) Was spricht eigentlich dafür, nur eine Klasse in Java im Programm zu verwenden. Und was spricht für mehrere Java-Klassen? \quoteoff Bei einer solchen Frage würde ich empfehlen, irgendeinen einführenden Text zu Objektorientierung zu konsultieren. Hier im Rahmen eines Beitrags eine wirklich weiterhelfende Antwort zu geben, halte ich für schwierig.


   Profil
AlphaSigma
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 23.11.2012
Mitteilungen: 283
  Beitrag No.13, eingetragen 2021-07-25

Hallo Delastelle, wenn Du es unbedingt nach Java portieren möchtest, dann würde ich an Deiner Stelle auf abstrakter Ebene, d.h. ohne Bezug auf die Syntax von C, analysieren was das Programm macht. D.h. die Daten und den Algorithmus unabhängig von einer speziellen Programmiersprache aufschreiben. Auf der Basis würde ich dann ohne Bezug auf den C-Quelltext das Programm neu in Java implementieren. Auf Rosetta_Code gibt es für viele kleine Programmbeispiele und Algorithmen die Umsetzung in sehr viele unterschiedliche Programmiersprachen. Im Menue unter "Explore -> Tasks" gibt es eine Auflistung aller vorhandenen Programmieraufgaben. Programming_Tasks Auf den Seiten zu den Programmieraufgaben sind die Quelltexte in den unterschiedlichen Programmiersprachen in alphabetischer Reihenfolge beschrieben. Hier z.B. für QR_decomposition. Wenn Du da bei möglichst vielen Beispielen den C mit dem Java Code vergleichst, hilft das evtl. den Unterschied zwischen C und Java zu verstehen. Der Hinweis auf Rosetta_Code ist aber keine Empfehlung den Code Zeile für Zeile, Eins zu Eins nach Java zu konvertieren.


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Beitrag No.14, vom Themenstarter, eingetragen 2021-08-02

Hallo AlphaSigma! Mein Problem ist auch, dass ich weder den C-Quelltext noch den mathematischen Hintergrund voll überblicke. Aber ein Java Quelltext läßt mich einfacher verschiedene Dinge probieren. Dort könnte ich ein einfaches Testbeispiel einfacher Untersuchen. Es gibt Testprobleme für den Algorithmus, die nur 10 Fälle haben statt Millionen Fälle bei großen Beispielen. Was ich momentan z.B. nicht verstehe, ob das Programm wirklich immer mehr Speicherplatz braucht oder ob das schlecht programmiert ist! Viele Grüße Ronald


   Profil
__blackjack__
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.09.2021
Mitteilungen: 25
  Beitrag No.15, eingetragen 2021-09-24 06:41

@Delastelle: Für mehrere Klassen spricht, dass Du anscheinend mehrere ``struct`` in Deinem C-Programm hast. Die wirst Du ja wahrscheinlich mit Klassen abbilden. Das hat DerEinfaeltige zu (d) ja bereits angemerkt. Eine `Map` ist mit mehr Speicher und weniger Geschwindigkeit verbunden, und noch viel wichtiger müssen die Werte alle vom gleichen Typ sein. Da *kann* man natürlich auch `Object` wählen und dann beim Zugriff immer in den richtigen Typ casten, aber das ist aufwändig, sowohl beim schreiben, als auch in der Ausführung, und fehleranfällig. Bei den Zeigern ist die Frage wozu die verwendet werden. Java hat so einen Datentyp nicht, allerdings ist da jedes Objekt im Hintergrund eigentlich ein Pointer. Nur Du hast da als Programmierer keinen Einfluss drauf wann der nicht dereferenziert wird — das wird der einfach bei jedem Zugriff. Das heisst immer wenn in Deinem Programm ein Pointer auf ein `struct` vorkommt, den Du ausser zur Übergabe und Zuweisungen nie als Pointer verwendest, wäre das in Java einfach ein Objekt. Du darfst keine Pointer-Arithmetik damit in C machen, weil das in Java mangels eines Pointers als Datentyp nicht geht. Umgekehrt gibt es in Java keine ``struct`` als Werttypen. Wenn Du so etwas im C-Programm hast, dann muss man da bei jeder Übergabe als Argument oder bei jeder Zuweisung explizit eine Kopie erstellen, beispielsweise durch Implementierung vom `Clonable`-Interface und Aufruf von `clone()`. Falls solche ``struct`` in dem C-Programm mit ``==`` miteinander verglichen werden, muss man in Java `equals()` implementieren und verwenden. Wenn Pointer für Datenstrukturen verwendet werden, dann versuch das so umzuschreiben, dass Du Java's Datenstrukturen verwendest. In C wird da oft die Datenstruktur mit den Objekten vermischt die in der Datenstruktur sind. Zum Beispiel sieht `bnbnode` so aus, als wenn das eine verkettete Liste von diesen Objekten ist, wo jedes Element eine ganze Zahl und eine Kantenliste enthält. Das kann man zwar so übernehmen, man könnte aber auch eine `LinkedList` von Java verwenden und dafür den `next`-Zeiger aus `bnbnode` raus lassen. Bei (e) würde man dann auf dem Iterator, den man sich von der `LinkedList` geben lassen kann, das nächste Element anfordern. Oder wenn das Teil einer Schleife über alle Elemente sein soll, einfach eine ”foreach”-Schleife schreiben. Bei (f) vermute ich man kann die ``&`` einfach weglassen, weil die Argumente ja bereits als Referenz übergeben werden. Das klappt nicht falls `munchit()` nicht nur einen Rückgabewert produziert, sondern Zeiger für ”out”-Parameter verwendet, also mehr als ein Ergebnis liefert. Das wäre in Java so nicht möglich. Und der Aufruf in (g) sieht sehr danach aus als wenn das für `bestv1` und `bestv2` der Fall ist. Wahrscheinlich auch bei `bestj1` und `bestj2`. Ein üblicher Weg so etwas in Java zu lösen sind Datenklassen für den Rückgabewert, die alle Werte zu einem Objekt zusammenfassen. Ansonsten würde ich mich AlphaSigma anschliessen und da keine 1:1-Übersetzung von C nach Java auf Anweisungsebene anraten. So etwas geht nur bei Sprachen die sich sehr ähnlich sind, beziehungsweise wenn die bei der Quellsprache verwendete Untermenge sehr ähnlich ist. Wenn man C 1:1 in Java übersetzt, würde ich sehr stark vermuten, dass das in 99,9% der Fälle langsamer laufen und mehr Speicher verbrauchen wird. Falls Du da algorithmisch nichts verbessern kannst, sehe ich nicht so ganz was das bringen soll. Ausser das C-Programm hat Speicherlecks die Java dann durch die automatische Speicherbreinigung nicht hätte. Aber denen könnte man im C-Programm auch mit Valgrind oder ähnlichem auf die Spur kommen. Hier mal mein Versuch zu den (…)-Fällen: \sourceon java // (a) Machine schedule; // (b) // Hier müsste man wissen warum das ein Zeiger auf einen Zeiger ist. // (c) int numOfJobs; // d class BnbNode { int value; EdgeList branchList; BnbNode next; } // (e) bnbList = bnbList.next; // (f) ist in (g) enthalten. // (g) private static class MunchItResult { public final int bestV1; public final int bestV2; public final int bestJ1; public final int bestJ2; public final EdgeList edges; public final boolean flag; public MunchItResult(int bestV1, int bestV2, int bestJ1, int bestJ2, EdgeList edges, boolean flag) { this.bestV1 = bestV1; this.bestV2 = bestV2; this.bestJ1 = bestJ1; this.bestJ2 = bestJ2; this.edges = edges; this.flag = flag; } } // ... while (bnbList != null) { // ... var edges = bnbList.branchList; doEdge(edges); freeBnbNode(bnbList); var result = munchIt(bestV1, bestV2, bestJ1, bestJ2, edges); bestV1 = result.bestV1; bestV2 = result.bestV2; bestJ1 = result.bestJ1; bestJ2 = result.bestJ2; edges = result.edges; if (result.flag) { System.out.printf(" split into %d %d\n", bestV1, bestV2); bnbList = splitIt(bnbList, bestV1, bestV2, bestJ1, bestJ2, edges); } else { System.out.printf("%d (%d) killed\n", bnbEval, holdVal); System.out.flush(); } undoEdge(edges); } \sourceoff


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 1742
  Beitrag No.16, vom Themenstarter, eingetragen 2021-09-25 01:51

Hallo, wenn ich Zeit finde, werde ich das Programm mal versuchen umzuwandeln. Da erscheint mir zum weiteren arbeiten Java vorteilhaft. Auch habe ich vor Jahren schon 2x C/C++ Programme in andere Programmiersprachen konvertiert und ergänzt. Einmal C/C++ in Turbo Pascal. Das war mal meine Programmiersprache. Das waren Verfahren zur Textkompression. Dann C/C++ in Java. Aber eben Optimierungsprobleme ohne viele Kniffe. Viele Grüße Ronald


   Profil
Delastelle hat die Antworten auf ihre/seine Frage gesehen.

Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2021 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]