2013-07-11 15 views
6

Ich lese gerade auf C# -Arrays, so meine Frage ist zunächst auf Arrays.Was bedeutet eigentlich das Deklarieren und Instanziieren eines C# -Arrays?

Was bedeutet eigentlich das Deklarieren eines Arrays? Ich weiß, dass Sie eine Variable vom Typ Array deklarieren. Wenn ich folgendes habe, was passiert eigentlich?

int[] values; 

Ist es im Speicher, bis es erklärt wird? Wenn nicht, wo ist es dann? Ist das Array tatsächlich hier erstellt?

Dann gehe ich und instanziiert ein das Array und initialisiert es mit einigen Werten wie:

int[] values = new int[] { 1, 2, 3 }; 

Enthält diese tatsächlich gehen und das Array jetzt schaffen? Ich habe gelesen, dass Arrays erstellt werden, wenn sie deklariert werden, andere sagen, dass Arrays erstellt werden, wenn sie instanziiert werden. Ich versuche, meine Terminologie richtig zu machen.

Das Gleiche gilt für eine Integer-Variable. Wenn ich habe:

int value; 

und

int value = 1; 

Wenn int erstellt? Wann wird es dem Speicher hinzugefügt?

Sorry für die dummen Fragen. Ich verstehe das Konzept, möchte aber die technischen Hintergründe von Arrays kennen.

Antwort

6

Was bedeutet eigentlich, ein Array zu deklarieren?

Sie haben nicht wirklich ein Array deklarieren, deklariert ein Array Referenz. Big Deal in .NET, der Unterschied zwischen Referenztypen und Werttypen ist wichtig. Wenn die Array-Referenzvariable nicht ausreicht, ist ein zusätzlicher Schritt erforderlich, um das Array-Objekt zu erstellen. Das erfordert das neue Schlüsselwort. Der Speicherplatz, der den Speicher für das Array-Objekt physisch an der Stelle reserviert, an der Referenztyp-Objekte gespeichert sind, ist der Garbage-Collected-Heap.

Das gleiche gilt für eine ganzzahlige Variable

Nein, großer Unterschied. Das ist ein Werttyp. Wenn es kein Feld einer Klasse ist, das ist nicht klar aus Ihrer Frage, dann ist es eine lokale Variable einer Methode. Es wird erstellt, wenn die Methode gestartet wird und wenn die Methode nicht mehr existiert. Sehr hoch optimiert, der Hauptgrund, warum Werttypen in C# existieren. Der physische Speicherort ist normalerweise ein CPU-Register oder ein Steckplatz im Stapelrahmen, wenn die Methode zu viele lokale Variablen verwendet.

Wenn es tatsächlich ein Mitglied einer Klasse ist, wird es erstellt, wenn das Klassenobjekt erstellt wird. Genau wie ein Array, auf dem GC-Heap mit dem neuen Schlüsselwort.

+1

Wenn man es wörtlich nimmt, ist das Schlüsselwort 'new' nicht nötig um ein Array Objekt zu erstellen , Sie können auch etwas wie 'int [] values ​​= {1, 2, 3}; 'schreiben. Obwohl Sie das als eine Abkürzung für die vollständige Syntax mit 'new' betrachten könnten. – svick

+0

@Hans: Bedeutet das Deklarieren einer Array-Referenz irgendeinen Speicher? Oder nur wenn das Array erstellt wird? –

+0

Es tut, die Größe eines Zeigers. 4 Bytes im 32-Bit-Prozess, 8 Bytes in einem 64-Bit-Prozess. Der Speicher für die Referenz folgt denselben Regeln wie für einen Werttyp Wert. –

1
int[] values; 

Bedeutet, dass Sie eine Variable vom Typ int [] deklarieren. Es ist noch kein Speicher belegt, nur eine Referenz wird erstellt. Der obige Code wird mit einer Nullreferenz initialisiert.

int[] values = new int[] { 1, 2, 3 }; 

Dieser Code deklariert eine Variable des Typs int [], und erzeugt sofort ein Array. Die Variable verweist auf das neu erstellte Array.

Ganzzahlen funktionieren ein wenig anders, da sie Werttypen sind. Werttypen werden auf ihre Standardwerte initialisiert, bei Ganzzahlen der Wert 0.

Wenn Sie die Deklaration und die Initialisierung teilen, passiert Folgendes.

// This declares a variable 
int[] values; 
// This creates the array, and initializes the variable with the newly created array. 
values = new int[] { 1, 2, 3 }; 
+1

Sie erstellen nur einen Nullverweis für 'int []', wenn es ein Member eines Typs ist und wenn eine Instanz dieses Typs erstellt wird. Wenn Sie das innerhalb einer Methode tun, haben Sie nicht einmal eine Referenz, bis Sie sie initialisiert haben. – Renan

+0

@Renan Ich bin mir nicht sicher, was du meinst. Die Nullreferenz ist kein Mitglied eines beliebigen Typs (http://ericlippert.com/2013/05/30/what-the-meaning-of-is-is/). – Maarten

+0

"Es ist noch kein Speicher belegt, nur eine Referenz wird erstellt." Wollen Sie sagen, dass eine Referenz keinen Speicher belegt? – svick

1

Wenn Sie ein Array deklarieren, intern alle, die erstellt wird, ist ein Null-Zeiger, der int[] vom Typ ist. Wenn Sie das Schlüsselwort new wie in Ihrem Beispiel verwenden oder new int[6] verwenden, weist das System zu diesem Zeitpunkt Speicher für die Größe des Arrays zu.

ein int Deklarieren tatsächlich den Speicher für die ganze Zahl mit Standardwert von 0.

+1

C# verhält sich genauso, da 'int' ein Werttyp ist, siehe hier: http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx.Quote: * Im Gegensatz zu Referenztypen kann ein Werttyp nicht den Nullwert enthalten. (...) Jeder Werttyp hat einen impliziten Standardkonstruktor, der den Standardwert dieses Typs initialisiert. * – Treb

+0

Ihr zweiter Absatz ist falsch. int ist ein Werttyp, der standardmäßig auf Null gesetzt wird. Versuchen Sie Folgendes: 'void Main() {Console.WriteLine (neues X(). I);} Klasse X {public int i;}' – spender

+0

Danke für die Korrektur. Ich dachte, ich hätte irgendwo gelesen, dass "int" ein Alias ​​für "Int32" oder so war. – Samuel

1

erstellen Wenn Sie es wie folgt erklären:

int[] values; 

Sie nicht über die Größe angeben, so dass es keine Möglichkeit zu wissen, wie viel Speicher für eine Installation benötigt wird.Diese Informationen werden nur in der folgenden Zeile angegeben:

values = new int[] { 1, 2, 3 }; 

Die Speicheranforderungen sind von der Anzahl der instatiation Werte abgeleitet (und von dem Speicherbedarf des Typs int, natürlich).

Wenn Sie deklarieren einen int wie folgt aus:

int value; 

die Speicheranforderungen sind bekannt und nicht ändern kann (da int ein Werttyp ist). Diese Variable kann (und wird) sofort erstellt werden. Wenn Sie keinen Anfangswert angeben, wird der Standardwert verwendet, der für int0 ist.

+0

Sie sagen, dass, wenn Sie nur 'int [] Werte schreiben, dann der Speicher für diese * Variable * nicht zugeordnet ist? Das ist falsch, weil diese Variable eine Referenz enthält und der Speicher für das * ist * zugewiesen. – svick

+0

Es macht auch keinen Sinn über Standardwerte von lokalen Variablen zu sprechen, sie haben keine. Zum Beispiel können Sie nicht schreiben: int i; Console.WriteLine (i); '. – svick

+0

@svick: Deine Kommentarnummer 1: Ich habe mich nicht deutlich genug ausgedrückt, ich meinte, dass der Speicher ** für das Array ** nicht belegt ist. Ihre Kommentarnummer 2: 'int', wie alle Werttypen, * hat * einen Standardwert. Der C# -Compiler erlaubt es Ihnen nicht, eine Variable zu verwenden, die Sie vorher noch nicht initialisiert haben, das ist richtig. Aber das 'i' in Ihrem Beispiel wird ** automatisch auf seinen Standardwert, d. H. 0, initialisiert. Sie können dies zum Beispiel im Debugger überprüfen. Ersetzen Sie 'Console.WriteLine (i);' mit 'Console.WriteLine (" bla ");', setzen Sie einen Haltepunkt auf dieser Zeile und überprüfen Sie "i", Sie werden sehen, dass der Wert 0 ist. – Treb