Datentyp - primitiv oder komplex

willeswissen

Grünschnabel
hi leute,

ich steige gerade in C# ein und gleich bei den kapiteln über datentypen komme ich ins schwitzen.

mich irritieren aussagen (in vielen büchern über C#), dass die in dort implementierten primitiven datentypen (wie int, long, char) je durch eine struktur implementiert sind.

daraus folgt für mich die frage: was passiert, wenn ich folgendes schreibe?

Code:
int i = 2;

Wieviel Speicherplatz nimmt "i" ein: 4 Bytes (= 32-Bits) oder mehr bzw. soviel, wie für die gesamte Struktur notwendig ist, bswp. 28 Bytes (falls die die Implmentierung der Integer-Struktur 28 Bytes einnehmen sollte) ?

da mir letztendlich schon klar ist, dass jedes Datum (int, long, char) auf die Wort-Größe eines Prozessors abgebildet werden muss, frage ich mal anders:

Würde der o.g Code tatsächlich in folgendes übersetzt werden bzw. wäre mein obiges "i" nur ein Datenfeld einer Struktur oder Klasse ?
Code:
Integer i = new Integer(2);

Da in Java auch Datentyp-Klassen existieren, wie verhält es sich dort?
 
(Ich kenne mich in C# überhaupt nicht aus)

Ein normales int i; belegt 4 Bytes laut MSDN, siehe hier.

Folgendes habe ich auch bei Google gefunden: Click!
Ist zwar auf Englisch, aber ich denke das ist die Antwort zu deiner Frage ;)
 
ok, der zweite link scheint zu bestätigen, dass:

  • int i = 2;
    tatsächlich wie in C/Pascal usw. gespeichert wird und somit kein Attribut eines Objekts ist
  • Integer i = new Integer(2);
    wäre ein Objekt und irgendwo in einem seiner Attribute der Wert 2 gespeichert.

Danke. Fall abgeschlossen !
 
Hi.
ok, der zweite link scheint zu bestätigen, dass:

  • int i = 2;
    tatsächlich wie in C/Pascal usw. gespeichert wird und somit kein Attribut eines Objekts ist
  • Integer i = new Integer(2);
    wäre ein Objekt und irgendwo in einem seiner Attribute der Wert 2 gespeichert.
Ganz so einfach ist es nicht. In C# wird zwischen Werttypen (value types) und Referenztypen (reference types) unterschieden.

Ein Int32 (synonym zu int) ist ein Werttyp (ein struct). Als solcher wird es immer direkt durch den Wert selbst repräsentiert.

Tatsächlich sind deine beiden Anweisungen äquivalent. (siehe z.B. http://www.albahari.com/valuevsreftypes.aspx)

In Java gibt es primitive Typen und entsprechende Wrapper-Klassen.

Gruß
 
Zuletzt bearbeitet:
Dann ist jeder primitive Datentyp also eine Struktur, wie in C oder Pascal: vereinfacht dargestellt, sieht sie also so aus ?

Code:
struct Int32{
   MinValue        // 4 Bytes
   MaxValue        // 4 Bytes
   CurrentValue    // 4 Bytes; das ist der Wert der Variablen "i"
}

Bei der Erstellung von

Code:
int i = 2;

reserviert man also insgesamt 12 Bytes, aber auf jeden Fall mehr als 4 Bytes !******!?

Folglich würde ein lesender Zugriff auf "i" und ein schreibender Zugriff auf "k" in etwa so aussehen?
Code:
int k = i;

Code:
k.setCurrentValue( i.getCurrentValue() );   // indirekter Zugriff über Helfer-Methoden

oder

k.CurrentValue = i.CurrentValue;   // direkter Zugriff auf die Member der Strukturen
Wo ist dann aber die Effizienz bzgl. Speicher (-> 12 Bytes, statt 4 Bytes) und Laufzeit (-> Zugriff über Methoden oder zumindest auf Felder einer Struktur über eine komplexere Adressierungs-Art)?


Jetzt stellt sich noch die Frage, was tatsächlich passiert, wenn ich an irgendeiner Stelle im Programm "i" benutze bzw. wie oft diese Struktur für "i" existiert erstellt wird?


Code:
int i = 2;    // hier wird für i eine Int32-Struktur erstellt
int k = i;    // wird hier für i noch eine Int32-Struktur erstellt
                 // oder nur auf i.CurrentValue zugegriffen ?


Anderes Beispiel:

Code:
int i = 2;    // hier wird für i eine Int32-Struktur erstellt
....
teste(i);    // was wird der Methode übergeben: i.CurrentValue (4 Bytes) 
                // oder  zunächst die Struktur (12 Bytes), aus der dann in
                // einem 2-ten Schritt  i.CurrentValue ausgelesen wird ?

Denn letztendlich ist der Zugriff auf i.CurrentValue; immer notwendig, da ein primitiver Datentyp irgendwann auf die Prozessor-Register abgebildet werden muss. Es stellt sich also die Frage, wie oft die Struktur für "i" erzeugt werden muss ?

Oder anders ausgedrückt: man muss zwischen dem compiler-generierten C#-Code und der syntaktischen Notation in C# (Kurzform-Notation für compiler-generierten Code unterscheiden (s.o. Code-Beispiele). Sehe ich das richtig ?
 
Zuletzt bearbeitet:
Dann ist jeder primitive Datentyp also eine Struktur, wie in C oder Pascal: vereinfacht dargestellt, sieht sie also so aus ?

Code:
struct Int32{
   MinValue        // 4 Bytes
   MaxValue        // 4 Bytes
   CurrentValue    // 4 Bytes; das ist der Wert der Variablen "i"
}

Bei der Erstellung von

Code:
int i = 2;

reserviert man also insgesamt 12 Bytes, aber auf jeden Fall mehr als 4 Bytes !******!?
Nein. MinValue und MaxValue sind const d.h. sie werden beim kompilieren direkt durch den Wert ersetzt und werden nicht nochmal in jeder Instanz gespeichert. Das wäre ja auch ziemlich unsinnig.

Du kannst davon ausgehen, das ein Int32 auch wirklich 32 Bit groß ist.
Folglich würde ein lesender Zugriff auf "i" und ein schreibender Zugriff auf "k" in etwa so aussehen?
Nein. Werttypen werden immer komplett kopiert. (siehe z.B. http://www.albahari.com/valuevsreftypes.aspx) und es gibt auch keine get bzw. set Methoden.

Ein Werttyp repräsentiert direkt die zugrundeliegenden Daten.

Oder anders ausgedrückt: man muss zwischen dem compiler-generierten C#-Code und der syntaktischen Notation in C# (Kurzform-Notation für compiler-generierten Code unterscheiden (s.o. Code-Beispiele). Sehe ich das richtig ?
Was meinst du damit? Welcher Compiler generiert C# Code?

Man muss zwischen dem generierten CIL Code und dem C# Code unterscheiden.

Die CLR ist eine stackbasierte virt. Maschine, ein Int32 wird als Datum auf dem Stack übergeben.

Bsp:
C#:
int i = 32;
CIL Code:
Code:
.locals init ([0] int32 i)
ldc.i4.s   32
stloc.0
Es wird eine lokale Variable auf dem Stack angelegt, der Wert 32 wird auf den Stack gepusht und dann in die Variable Nr. 0 gespeichert. Es wird keine Struktur angelegt, es werden auch nicht irgendwelche Methoden aufgerufen, einfach nur ganz einfach ein paar Bytes kopiert.

Gruß
 

Neue Beiträge

Zurück