2011-01-30 11 views
5

Sto avendo un sacco di difficoltà a comprendere gli array multidimensionali Sia una matrice siaarray multi-dimensionale in C++, un mistero per me :(

x[2]; // now x is constant pointer to first element i.e x's name is address of x[0] 

Ora matrice bidimensionale:.

x[2][5]; // here x is address of x[0] which contains the address of first element of array x[][0]; 

Ora il puntatore

int(*y)[5]; 

è un puntatore ad un array di interi 5. Come è possibile scrivere y = x?

Ora stavo facendo qualche pratica per capire questo in VS, che è qui, e la mia domanda principale è nell'immagine:

http://img184.imagevenue.com/img.php?image=96382_first_122_1120lo.jpg

Si prega di rispondere alla domanda concettualmente; come negozi C++ array multi-dimensionale, ecc

Io apprezzo tutto l'aiuto molto :)

+0

Si prega di leggere http://c-faq.com/aryptr/index.html –

+1

Si consiglia di leggere la [FAQ] (http://stackoverflow.com/questions/4810664/) sull'utilizzo di matrici in C++;) – fredoverflow

risposta

6

sguardo: qualsiasi array multi-dimensionale è l'array di array. Per esempio. x[2][5] sarà uguale a questa tabella:

x[0][0]x[0][1]x[0][2]x[0][3]x[0][4]

x[1][0]x[1][1]x[1][2]x[1][3]x[1][4]

assegnazione Pointer sarebbe esattamente lo stesso: x[0] è la prima riga della tabella 2x5, così int *y = x[0] oppure int *y = x[1] copierà l'indirizzo della prima riga a .

Ma se lo fai int (*y) = x allora memorizza l'indirizzo di x[0][0] in y variabile (int y crea un'istanza int mentre int (*y) ti dà l'indirizzo di questa istanza).

UPD: Lascia che sia variabile int **x. Non importa di quale dimensione ha. Prendi questo come una verità che x, x[0] e x[0][0] ti forniranno lo stesso indirizzo. Questo potrebbe essere spiegato come Pointer name means its address. Multi-dimensional array is a pointer to pointer. Its name means address of pointer it's pointing on which means address of the last pointer' first element. (scusa per la complicità).

+0

+1 per quantità di esempi –

3

Poiché il nome di un array monodimensionale è considerato il puntatore del primo elemento, la costruzione x [0] è il puntatore al primo array del proprio array 2d e x [1] è il puntatore al secondo array. Quindi, pensa a x [0] dato che è il nome del tuo primo array. L'aggiunta di un'altra coppia di parentesi (come x [0] [0]) restituirà il valore dell'elemento. E l'indirizzo del primo elemento sarebbe & x [0] [0] o semplicemente x [0].

7

Come altri hanno sottolineato, una matrice multidimensionale è una matrice di matrici, non una matrice di puntatori.

Penso che la causa principale del fraintendimento sia il concetto che qualsiasi array sia effettivamente un puntatore.Ma non è strettamente vero. Un array è una variabile che contiene un insieme contiguo di dimensioni fisse di elementi dello stesso tipo. Quindi quando dichiari un array come int x[2] stai dichiarando una variabile che contiene due interi. Si noti che non contiene alcun puntatore.

Ora la radice di questo comune equivoco è che in C/C++ un nome di matrice valuta all'indirizzo del suo primo elemento e pertanto può essere utilizzato come puntatore. In altre parole, quando si scrive x, si intende implicitamente &x o &x[0]. Questo probabilmente è stato fatto per rendere le espressioni più leggibili.

Un array multidimensionale è semplicemente una matrice di matrici. In altre parole, la stessa logica si applica a loro, non c'è nulla di speciale. Leggi la dichiarazione C/C++ a partire dal nome e vai fuori, applicando i modificatori mentre li incontri, prima [] e(), poi *, quindi scrivi, quindi interpreti una matrice multidimensionale come questa (ordine di lettura specificato esplicitamente):

int    x  [    2]   [   5]; 
6. "of type int" 1. "x" 2. "is an array" 3. "of 2". 4. "arrays" 5. "of 5 elements" 

Quindi non v'è alcuna cosa come array multidimensionali in C/C++, ma c'è cosa come array monodimensionale di matrici unidimensionali. Come da regole per gli array monodimensionali, x, &x e &x[0] tutti valutano l'indirizzo del primo elemento. Ma poiché il primo elemento è un array, x[0] valuta l'indirizzo di quell'array, cioè l'indirizzo del suo primo elemento che è un int. Lo stesso vale per &x[0] e &x[0][0]. Ecco perché il valore di x[0] è lo stesso del suo indirizzo - perché x[0] è un array.

Si noti che mentre queste cose valutano lo stesso indirizzo, hanno tipi diversi. x è un puntatore a un array di 5 pollici, nonché a &x[0], in quanto entrambi valutano l'indirizzo del primo elemento di x. x[0] valuta l'indirizzo del primo elemento di x[0], quindi è un puntatore a int, lo stesso vale per &x[0][0]. Questo esempio compila bene e stampa lo stesso indirizzo per tutti e 4 i puntatori:

int x[2][5]; 
    int (*y1)[5] = x; 
    int *y2 = x[0]; 
    int (*y3)[5] = &x[0]; 
    int *y4 = &x[0][0]; 
    printf("%p %p %p %p\n", y1, y2, y3, y4); 

Ora, ci sono diversi layout di memoria per le matrici utilizzate in diverse lingue. Ad esempio, per un array bidimensionale è possibile raggruppare gli elementi per righe o colonne. In C/C++, poiché non ci sono matrici "vere" multidimensionali, il layout della memoria è definito implicitamente dalle regole sopra. Dal int x[2][5], che può essere considerato come un array bidimensionale con 2 righe e 5 colonne, in realtà è un array di 2 array, ognuno dei quali rappresenta una riga, si ottiene il layout "gruppo per righe", che viene presentato in la risposta di shybovycha.

Si noti che è anche possibile creare un array di puntatori e utilizzarlo come array multidimensionale. Le differenze rispetto agli array "consueti" multi-dimensionali sono:

  1. Una serie di puntatori contiene effettivamente puntatori all'interno. Cioè, indirizzi dei primi elementi dei sotto-array.
  2. Il layout di memoria non è contiguo. Ogni sub-array può essere assegnato ovunque, ad esempio usando malloc() o new [].
  3. I sotto-array possono essere di dimensioni diverse.

Il vantaggio di questo approccio è che è possibile utilizzare questo array come un puntatore a puntatore (per esempio, int **y), che rende tutte le matrici multidimensionali di questo tipo compatibili tra loro, anche se hanno differenti dimensioni.Ma le dimensioni devono essere memorizzate separatamente in questo caso.

Problemi correlati