Schule: Structures in Java

  • Java

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Schule: Structures in Java

    Wir hatten gerade einen Theorie-Test in Programmieren.
    Eine Aufgabe hat mich ziemlich aufgeregt:

    Quellcode

    1. Erklären Sie den Unterschied folgender Deklarationen! Erweitern Sie den Java-Code, um dasselbe Resultat wie in C/C++ zu erhalten.
    2. | Java: | C/C++ |
    3. | Adresse name; | adresse name; |

    Es steht nicht dabei, was Adresse (bzw. adresse) sein soll. Der Lehrer hat mir nach mehrmaligem Nachfragen erklärt, dass Adresse bei Java eine Klasse ist und adresse bei C/C++ eine Structure.
    Ich habe gefragt, woher wir das wissen sollen. Seine Antwort:
    Steht im Skriptum
    (Das Skriptum ist ein Word-Dokument, das verteilt wurde. Siehe weiter unten).
    Darauf habe ich gefragt, woher wir wissen sollen, dass bei der Aufgabe eine Angabe in dem Skriptum gemeint ist. Seine Antwort:
    Wenn Du es [das Skriptum] gelesen hättest, würdest Du es wissen.

    Ok, da konnte ich in dem Moment nicht weiter argumentieren, weil ich das Skriptum nur überflogen habe.

    Jetzt nach dem Test hab ich es mir angesehen. Im Anhang der Auszug aus dem Word-Dokument, der mit den Verbund-Datentypen zu tun hat. Namen habe ich zensiert.

    Es wird zwar erwähnt, dass es in Java keine richtigen Verbunddatentypen gibt, sondern dass stattdessen Klassen verwendet werden, aber was das konkret bedeutet, wird einfach unter den Teppich gekehrt.
    Kein Wort darüber, wie Structures funktionieren oder worin der Unterschied zu Klassen besteht.

    Später wird dann in Java eine Klasse Adresse deklariert und in C/C++ eine Struct adresse (ja, klein geschrieben).
    Java:

    C-Quellcode

    1. class Adresse {
    2. String vorname;
    3. String nachname;
    4. int plz;
    5. String ort;
    6. String strasse;
    7. }
    C/C++

    C-Quellcode

    1. struct adresse {
    2. string vorname;
    3. string nachname;
    4. int plz;
    5. string ort;
    6. string strasse;
    7. };
    Darunter diese Codeschnipsel:
    Bei Java:

    C-Quellcode

    1. Adresse name;
    2. name = new Adresse();
    Bei C/C++

    C-Quellcode

    1. adresse name;

    Es wird dann folgender Unterschied erklärt:
    Bei Java:
    Der Speicher wird erst beim Erstellen des Objektes (new) reserviert. Die Variable enthält nur einen Verweis auf den Speicherbereich.
    Bei C/C++
    Bei der Deklaration wird automatisch der Speicher für den gesamten Verbunddatentyp reserviert.

    Auch hier fehlt die Erklärung, was der eigentliche Unterschied ist. Es wird so dargestellt, als ob bei C/C++ name = new adresse(); automatisch passieren würde. Und das verwirrt viele der Schüler in der Klasse hier.


    Ich wollte jetzt erst mal die Meinung anderer einholen, bevor ich den Lehrer frage.

    *Topic verschoben*
    Dateien
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Auch wenn ich dich verstehe und auch der Meinung bin, dass es mehr oder weniger das gleiche ist,
    wirst du dennoch einsehen müssen, dass du nur schwer gegen den Lehrer ankommen wirst!

    Die sitzen meist am längeren Hebel und wenn du das ganze dann noch weiter ziehst - zB. zu einem anderen Lehrer gehst - kann das schön in die Hose gehen!
    Ja, da ist doch auch nichts falsches daran, es ist doch eine Erklärung. In Java gibt es keine Strucs da werden dafür Klassen verwendet.
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    Wies in Müll-Java läuft, weiß ich nicht, aber in C++ gibts gar keinen Unterschied zwischen Struct und Class (außer dass Member bei ner Struct standardmäßig public sind). Während z.B. in C# dazwischen Unterschieden wird, weil das eine im Stack und das andere im Heap liegt, so wird das in C++ ja über Pointer realisiert. Man kann aber nicht! anhand dieser zeile bestimmen, ob es eine Struct oder Class ist, da die sich wie gesagt absolut identisch verhalten. Beides würde in diesem Fall auf dem Stack landen, wenn du ne Referen im C#-Sinne einer Klasse haben willst, dann müsste das ein Pointer sein, aber das würde ebenso mit Class und Struct in C++ funktionieren.
    Ich denke er wollte mit dieser Aufgabe überprüfen ob du (Die Schüler) das Skript durchgelesen haben.
    Vielleicht dachte er durch die Gross-Kleinschreibung würde man darauf kommen , das dies im Script auch so verwendet wurde.

    Wenn die Aufgabe genau so war wie du sie gepostet hast und bei java new Adress(); nicht stand wäre ich auch nicht darauf gekommen.
    Hey,
    für structs gibts in C++ einem Defaultinitializer

    C-Quellcode

    1. address a = {};
    und generell Werte Typen und Klassen type t = t();. Ansonsten wird nach Deklaration direkt der Standardkonstruktor aufgerufen, falls einer existiert und zugreifbar ist. Sonst kommt halt irgendein Überladener oder der Kopierkonstruktor. New legt dir das Ganze auf den Heap und gibt dir den Zeiger.

    C-Quellcode

    1. address* a = new address();
    2. delete address;


    Um Artentus Beitrag nochmal hervorzuheben, guck dir mal is_class<>, is_class<>::value ist true bei structs und classes. Beide sind identisch
    Yay. Wiedermal ein perfektes Beispiel für den typischen Verlauf eine VBP-Threads in letzter Zeit: Eine Frage wird gestellt, ein paar Antworten kommen, irgendwer bezieht sich auf ein Teilaspekt (unnötig) einer Antwort, und voilà, es hagelt massenhaft OT-Posts die absolut NICHTS mit der ursprünglichen Frage zutun haben! Ich habe es in letzter Zeit schon oft genug gesagt: Bitte lasst das doch einfach mal sein. Wenn euch ein Thema so aufregt, erregt, was auch immer, dann eröffnet gefälligst einen neuen Thread, bzw. schreibt in einen bereits existierenden passenden Thread eure Meinung. Denn euer Senf interessiert zwar alle, aber nur, so lange er auch zum Thema passt; ansonsten stört es einfach nur und dient vermutlich nur zur Demonstration des E-Penisses. Danke für's Lesen.
    @Don_Batisto: Mein Ziel ist es nicht, den Lehrer zu provozieren, sondern herauszufinden, wie er denkt und warum... und ihm eventuell sogar erklären, warum ich damit nicht einverstanden bin.

    @Andy16823: Du hast das Problem nicht verstanden. Wenn ich Dich frage, wo der Unterschied zwischen Dim sup As Foo in VB und foo sup; in C# ist, was antwortest Du dann?
    Woher soll ich das wissen?
    vielleicht? Dann werde ich antworten, dass ich bei mir ein Word-Dokument habe, wo das drin steht:

    VB.NET-Quellcode

    1. Public Class Foo
    2. End Class

    C-Quellcode

    1. public struct foo { }

    Ja, woher sollst Du das wissen?

    @Artentus: Könntest Du mich genauer über die Funktionsweise von Klassen und Strukturen in C und C++ aufklären? Genaugenommen: Was passiert in C bei Foo Bar;, wenn Foo eine Klasse ist und wenn Foo eine Struktur ist? Und selbiges mit C++: Was passiert, wenn es eine Klasse/Struktur ist?
    Laut dem, was ich gelesen habe, gibt's da Unterschiede zwischen C und C++.

    @Lingo: Ich glaube nicht, dass er das wollte. Wir haben hier nicht mal Anwesenheitspflicht, also theoretisch könnten wir einfach zum Test kommen, eine positive Note schreiben. Das heißt, er dürfte es eigentlich nicht vom Skriptum abhängig machen.
    Ich vermute eher, dass er prüfen wollte, ob wir verstehen, dass man Objekt-Variablen in Java erst eine Instanz zuweisen muss (z.B. mit Variable = new Typ();).

    @Gonger96: Ok, das erklärt, was in C++ passiert. Gilt das nur für Strukturen oder auch für Klassen? Wie sieht's dann in C aus?
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Niko Ortner

    Genau das denke ich auch.
    Aber dein Lehrer hat in der Aufgabe ja nur folgende Tabelle gezeigt:

    Erklären Sie den Unterschied folgender Deklarationen! Erweitern Sie den Java-Code, um dasselbe Resultat wie in C/C++ zu erhalten.
    | Java: | C/C++ |
    | Adresse name; | adresse name; |


    Erklären Sie den Unterschied folgender Deklarationen!
    - Wie willst du einen Unterschied erklären wenn seine dekleration nicht einmal vollständig ist?^^

    Erweitern Sie den Java-Code, um dasselbe Resultat wie in C/C++ zu erhalten.
    - Ja ich denke hier wollte er Variable = new Typ(); sehen
    Ja, es gibt Unteschieder zwischen C und C++, sogar ziemlich große.
    In C gibt es überhaupt keine Klassen, weil C nicht mal objektorientiert ist. Wäre in der Aufgabenstellung also konkret von C die Rede, so wäre die Antwort tatsächlich eindeutig. Es gibt dort Sctrucs, allerdings sind das wirklich Structs im ursprünglichen Sinne, nämlich lediglich Gruppierungen von Bytes. Eine Struct kann dort nur Variablen enthalten, die Struct wird vom Compiler dann einfach aufgelöst, als hätte man diese Variablen alle einzeln deklariert.
    In C++ sind die Schlüsselwörter Struct und Class identisch bis auf die Tatsache, dass Member von Structs standardmäßig public und Member von Classes standardmäßig private sind, und dann noch die Sache mit dem Konstruktor siehe Gonger. Egal ob Struct oder Class, eine Variable liegt immer auf dem Stack. Nur Pointer zeigen auf den Heap, das funktioniert aber auch mit Structs und Classes. Folglich lässt sich für C++ nicht entscheiden, ob in diesem Fall "adresse" eine Struct oder Class ist.
    Nein, eben nicht, das ist nur in C# (und allgemein .Net) so. In C++ muss man sich mittels Pointern selbst darum kümmern, dass man einen Verweis bekommt, ansonsten ist alles ein einfacher Wert, auch ne Class. Umgekehrt kann dort aber auch ne Struct als Verweis gespeichert werden, weil Pointer auch dafür funktionieren. ;)
    Den Ausdruck "Wertetyp" und "Verweistyp" gibts so halt in C++ nicht.
    Aber ist auch egal, vielleicht hab ich dich auch einfach falsch verstanden, jedenfalls will ich jetzt nicht schon wieder ins OffTopic gehen, bevor ich wieder Stress mit den Mods bekomme. :P
    @Lingo: Auch wieder wahr. Ich werde nächste Woche nachfragen.

    @Artentus: Ok, dann hab ich das richtig gelesen. Danke für die Erklärung.

    @Coldfire: Jetzt, wo ich sicher bin, kann ich auch mitreden ;)
    Vergleiche dieses Codeschnipsel in C# und in C++:

    C-Quellcode

    1. static void DoStuff()
    2. {
    3. Foo MyFoo;
    4. Bar MyBar;
    5. }
    6. struct Foo
    7. {
    8. public byte F1;
    9. public byte F2;
    10. public byte F3;
    11. }
    12. class Bar
    13. {
    14. public byte B1;
    15. public byte B2;
    16. public byte B3;
    17. }

    In der DoStuff-Methode wird bei Zeile 3 sowohl bei C# als auch bei C++ auf dem Stack Platz für 3 Bytes reserviert, nämlich für F1, F2 und F3 aus der Foo-Structure. Hingegen wird bei Zeile 4 bei C# Platz für einen Pointer reserviert, also so, wie man das erwartet. Der Pointer kann dann irgendwo in den Heap zeigen, wo dann die 3 Bytes B1, B2 und B3 liegen. Dagegen wird bei C++ immer noch Platz für 3 Bytes reserviert, nämlich B1, B2 und B3. Eben weil es in C++ keinen Unterschied gibt. Möchte man in C++ einen Pointer haben, der dann in den Heap zeigen kann, müsste man sowas schreiben:

    C-Quellcode

    1. Bar *MyBar;
    2. // Oder war es so?
    3. Bar MyBar*;
    4. // Oder so irgendwie:
    5. Bar &MyBar;

    Jedenfalls sieht man's am Namen... Aha, laut dieser Seite ist es Bar *MyBar;.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Zu Info noch: das * hinter einer Variablen ist der Dereferenzierungs-Operator, also er löst den Pointer auf in den eigentlichen Wert. Möchte man auf Member eines Objektes zugreifen, das nur durch einen Pointer bekannt ist, dann schreibt man also (obj*).member. Kürzer ist jedoch obj->member, der ->-Operator ist Dereferenzierungs-Operator und der Punkt (k.A. wie man den nennt) gleichzeitig.
    & ist der Referenzierungs-Operator, also das genaue Gegenteil. Er kopiert einen Wert in den Heap und gibt einen Pointer darauf zurück. Er wird häufig eingesetzt für das, was man als ref/ByRef aus .Net kennt.
    Ist ein bisschen kompliziert, dieser Pointer-Stuff.

    ich würde übrigens den Stern hinter den Typen setzen, nicht vor den Variablennamen, also Bar* myBar, ganz einfach weil der Stern den Pointer-Typen anzeigt, er hat nichts mit dem Namen zu tun.
    Nochmal zum Begriff Wert- und Referenztyp: In C++ gibts einmal fundamentale Datentypen (int, short, long, char, double und Co - Alles Zahlen) dann natürlich noch Klassen, Structs und Unions. Alle werden immer per value übergeben. void print(string s) {cout << s;}; string f = "Hallo"; print(f); hier würde der String per Kopierkonstruktor kopiert werden, dass ist natürlich Schwachsinn (zudem noch Performance und Speicher fressend). In C würde man den Zeiger reingeben, in C++ die Referenz void print(const string& s). So ist alles erstmal n Werttyp, als Referenz n Referenztyp und als Zeiger halt n Zeiger