2013-07-11 7 views
6

Sto leggendo su array C# quindi la mia domanda è inizialmente sugli array.Che cosa significa in realtà dichiarare e istanziare un array C#?

Che cosa significa dichiarare un array in realtà? So che dichiari una variabile di tipo array. Quando ho il seguente, cosa sta realmente accadendo?

int[] values; 

È in memoria dal momento in cui viene dichiarato? Se no, allora dove si trova? La matrice è effettivamente creata qui?

Poi vado e un'istanza di un matrice e inizializzarlo con alcuni valori come:

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

fa questo in realtà andare e creare l'array adesso? Ho letto che gli array vengono creati quando vengono dichiarati, altri dicono che gli array vengono creati quando vengono istanziati. Sto cercando di ottenere la mia terminologia giusta.

Lo stesso vale per una variabile intera. Se ho:

int value; 

e

int value = 1; 

quando è int creato? Quando viene aggiunto alla memoria?

Ci scusiamo per le domande stupide. Capisco il concetto, ma vorrei conoscere la tecnicità dietro le quinte degli array.

risposta

6

Che cosa significa dichiarare un array in realtà?

Lei non ha in realtà dichiara una matrice, si dichiara una matrice di riferimento . Un grosso problema in .NET, la differenza tra tipi di riferimento e tipi di valore è importante. Il solo fatto che la variabile di riferimento dell'array non sia sufficiente, è necessario un ulteriore passaggio per creare l'oggetto array. Che richiede la nuova parola chiave . Che alloca fisicamente la memoria per l'oggetto array nel punto in cui sono memorizzati gli oggetti del tipo di riferimento, l'heap della garbage collection.

Lo stesso vale per un intero variabile

No, grande differenza. Questo è un tipo di valore. Se non è un campo di una classe, non è chiaro dalla tua domanda, allora è una variabile locale di un metodo. Viene creato quando il metodo inizia a girare e scompare quando il metodo ritorna. Molto ottimizzato, la ragione principale per cui esistono tipi di valore in C#. La posizione di archiviazione fisica è in genere un registro cpu o uno slot nello stack frame se il metodo utilizza troppe variabili locali.

Se è effettivamente un membro di una classe, viene creato quando viene creato l'oggetto classe. Proprio come un array, nell'heap GC con la nuova parola chiave .

+1

Se lo prendi alla lettera, la parola chiave 'new' non è necessaria per creare un oggetto array , puoi anche scrivere qualcosa come 'int [] values ​​= {1, 2, 3};'. Anche se potresti considerarlo come una scorciatoia per la sintassi completa con 'new'. – svick

+0

@Hans: la dichiarazione di un riferimento di matrice occupa memoria? O solo quando viene creato l'array? –

+0

Lo fa, la dimensione di un puntatore. 4 byte nel processo a 32 bit, 8 byte in un processo a 64 bit. L'archiviazione per il riferimento segue le stesse regole di un valore di tipo valore. –

1
int[] values; 

Significa che si dichiara una variabile di tipo int []. Nessuna memoria è ancora occupata, viene creato solo un riferimento. Il codice sopra è inizializzato su un riferimento null.

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

Questo codice dichiara una variabile di tipo int [] e crea immediatamente una matrice. La variabile fa riferimento all'array appena creato.

interi di lavoro un po 'diverso dal momento che sono di valore-tipi. I tipi di valore vengono inizializzati ai valori di default, in caso di numeri interi, il valore 0.

Se si divide la dichiarazione e l'inizializzazione, accade quanto segue.

// 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

Si crea un riferimento null per 'int []' se è un membro di un tipo e quando viene creata un'istanza di quel tipo. Se lo fai all'interno di un metodo non hai nemmeno un riferimento finché non lo inizializzi. – Renan

+0

@ Renan Non sono sicuro di cosa intendi. Il riferimento null non è un membro di alcun tipo (http://ericlippert.com/2013/05/30/what-the-meaning-of-is-is/is). – Maarten

+0

"Nessuna memoria è ancora occupata, viene creato solo un riferimento." Stai dicendo che un riferimento non occupa memoria? – svick

1

Quando si dichiara una matrice, internamente tutto che si crea è un puntatore nullo che è di tipo int[]. Quando si utilizza la parola chiave new come nell'esempio o si utilizza new int[6], in quel momento il sistema alloca la memoria per la dimensione dell'array.

Dichiarazione di un int sarà effettivamente creare la memoria per l'intero con valore predefinito 0.

+1

C# si comporta allo stesso modo, poiché 'int' è un tipo di valore, vedere qui: http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx.Citazione: * A differenza dei tipi di riferimento, un tipo di valore non può contenere il valore nullo. (...) Ogni tipo di valore ha un costruttore implicito predefinito che inizializza il valore predefinito di quel tipo. * – Treb

+0

Il secondo paragrafo non è corretto. int è un tipo di valore che assume come valore predefinito zero. Prova questo: 'void Main() {Console.WriteLine (nuovo X(). I);} classe X {pubblico int i;}' – spender

+0

Grazie per la correzione. Ho pensato di leggere da qualche parte che 'int' era un alias per' Int32' o qualcosa del genere. – Samuel

1

Quando si dichiara in questo modo:

int[] values; 

non si specifica la dimensione, quindi non c'è nessun modo per sapere quanta memoria sarebbe necessaria per un instatiation.Questa informazione è data solo nella riga seguente: requisiti

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

La memoria sono dedotte dal numero di valori instatiation (e dai requisiti di memoria di tipo int, naturalmente).

Quando si dichiara un int come questo: requisiti

int value; 

la memoria sono noti e non può cambiare (dal int è un tipo di valore). Questa variabile può (e verrà) creata immediatamente. Se non si specifica un valore iniziale, avrà il valore predefinito, che perè 0.

+0

Stai dicendo che se scrivi solo 'int [] values', la memoria per quella * variabile * non è allocata? È sbagliato, perché quella variabile contiene un riferimento e la memoria per questo * è * allocata. – svick

+0

Inoltre, non ha senso parlare dei valori di default delle variabili locali, non ne hanno. Ad esempio, non puoi scrivere 'int i; Console.WriteLine (i); '. – svick

+0

@svick: il tuo numero di commento 1: non mi sono espresso abbastanza chiaramente, volevo dire che la memoria ** per l'array ** non è allocata. Il tuo commento numero 2: 'int', come tutti i tipi di valore, * ha * un valore predefinito. Il compilatore C# non ti permette di usare una variabile ** tu ** non inizializzata prima, è corretta. Ma il 'i' nel tuo esempio è ** automaticamente ** inizializzato sul suo valore predefinito, ad esempio 0. Puoi ad esempio controllare questo nel debugger. Sostituisci 'Console.WriteLine (i);' con 'Console.WriteLine (" bla ");', imposta un breakpoint su quella riga e controlla 'i', vedrai che il suo valore è 0. – Treb

Problemi correlati