2012-06-24 25 views
5

Ho un esempio che riguarda un puntatore a un array 2D. Qualcuno può aiutarmi a capire cosa sta succedendo in questo esempio?Array 2D e puntatore in C - come accedere agli elementi?

int main() 
{ 

    int i = 0, j=0, sum0=0, sum1=0; 
    int data[4][3] = { {23,55,50},{45,38,55},{70,43,45},{34,46,60}}; 
    int *Ptr; 
    Ptr = *data; //Why is the indirection operator used here? 
        // Does Ptr = 23 by this assignment? 

    for (i=0; i<4; i++) { 
     sum1 = 0; 
     for (j = 0; j < 3; j++) { 
      sum1 += data[i][j]; 
     } 
     if (sum1 > sum0) { 
       sum0 = sum1; 
       Ptr = *(data + i);  // Seems like this statement makes Ptr 
     }        // point one row below ... what syntax 
    }         // can you use to access columns then? 
             // Is it possible to use pointer arithmetic 
    for (i=0; i<3; i++)     // to access elements of data[i][j] that 
     printf("%d\n", Ptr[i]);   // are not at j = 0? 

    return 0; 
} 
+0

È questo [tag: compiti a casa]? – Alexander

+0

Sì! Stavo seguendo un corso introduttivo di CS e questo era solo un esempio dato dai miei appunti di lezione. – shafools

risposta

13

data è un array di 2 dimensioni, che ha 4 righe e ogni riga ha 3 elementi (cioè 4 X 3).

Ora, Ptr = *data; significa che si sta memorizzando l'indirizzo iniziale della prima riga sulla variabile del puntatore Ptr. Questa affermazione è equivalente a Ptr = *(data + 0). Ptr = *(data + 1) - questo significa che stiamo assegnando l'indirizzo di partenza della seconda riga.

Quindi *Ptr o *(Ptr + 0) ti darà il valore del primo elemento della riga a cui punta. Allo stesso modo, *(Ptr + 1) ti darà il valore del secondo elemento della riga.

Il ciclo for nel programma viene utilizzato per identificare quale riga ha il valore massimo della somma dei suoi elementi (3 elementi). Una volta che il controllo è uscito dal ciclo for, Ptr punta alla riga che ha la somma massima dei suoi elementi e sum0 avrà il valore della somma.

Si consideri un array int a[5];, spero che tu sappia che a[0] e 0[a] è lo stesso. Questo perché a[0] significa *(a+0) e 0[a] significa *(0 + a). Questa stessa logica può essere utilizzata nell'array bidimensionale.

data[i][j] è simile a *(*(data + i) + j). Possiamo scrivere anche come i[data][j].

Per ulteriori dettagli si prega di fare riferimento al libro "capire i puntatori in c" di yashwant kanetkar.

1

data è un array di array 3-elemento di interi. In contesti che prevedono un "puntatore a pippo", puoi usare un "array of foo" e si comporterà come un puntatore al suo primo elemento, quindi *data è un puntatore al primo elemento di data, ovvero (per così dire) {23,55,50}.

Quindi, la risposta alla prima domanda nei commenti: No, non è vero che Ptr = 23. (Non poteva essere; Ptr è un int * e 23 è una int.)

Lei ha ragione che rende Ptr = *(data+i)Ptr scegliere il i esima riga di data. Più precisamente, data è una matrice di matrici a 3 elementi di int, che si comporta come un puntatore a matrici a 3 elementi di int; aggiungendo i a questo si sposta oltre i tali matrici.

Il solito modo per accedere ad altre colonne dell'array è l'ordinario indicizzazione di array. Se si fa riferimento a data[i][j], si ottiene la colonna j della riga i. Se si desidera eseguire l'aritmetica con puntatori espliciti, si noti che (ad esempio) Ptr nel codice di esempio è di tipo "puntatore a numero intero", quindi Ptr+1 (ad esempio) è l'elemento 1 di qualsiasi riga a cui punta Ptr. (Ma, per questioni di stile, non dovresti in genere eseguire un'aritmetica puntata esplicita quando non ne hai realmente bisogno.)

0

Nel tuo esempio il ciclo passa attraverso tutte le righe della matrice per trovare quello la cui somma di tutti gli elementi detiene il valore massimo.

All'inizio un puntatore alla prima fila è assegnato:

Ptr = *data; 

Il che significa che le seguenti condizioni:

(Ptr[0] == 23 && Ptr[1] == 55 && Ptr[2] == 50) 

noti che Ptr è un puntatore in modo che detiene una indirizzo di memoria, quindi Ptr è diverso da (a meno che l'indirizzo di memoria non sia , che è improbabile che accada).

4

Ptr = *data; è l'abbreviazione di *(data+0)+0 che è un puntatore per il primo elemento di colonna della prima riga. il primo 0 aggiunto con i dati è il numero di riga, che è indiretto e ci porta alla prima riga. * (data+0) è ancora un indirizzo e non un valore a cui punta (per array 2D). Quindi, Ptr ora punta all'indirizzo della prima colonna nella prima riga. Il secondo zero è il numero della colonna. Quindi, viene scelto l'indirizzo di memoria della prima riga e della prima colonna. L'uso di indirection (*) ancora una volta solo darebbe valore che l'indirizzo detiene. come * (*(data+0)+0) o **data.

Generalmente, se p è nome puntatore, i numero di riga e di colonna j,

  1. (*(p+i)+j) darebbe un indirizzo di memoria di un elemento nella matrice 2D. Io sono la riga n. e j è col no.,
  2. *(*(p+i)+j) darebbe il valore di quell'elemento.
  3. *(p+i) accedere alla riga di iro
  4. per accedere alle colonne, aggiungere il numero di colonna a *(p+i). Potrebbe essere necessario dichiarare il puntatore come (*p)[columns] anziché solo *p. In questo modo, stai dichiarando il puntatore a un array 2D.

L'utilizzo dell'aritmetica del puntatore sta trattando l'array 2D come un array 1D. Puntatore di inizializzazione * Ptr sul primo elemento (int *Ptr = *data) e quindi aggiungere un n. (Ptr + n) per accedere alle colonne. L'aggiunta di un numero superiore al numero di colonna continuerebbe semplicemente a contare gli elementi dalla prima colonna della riga successiva, se questo esiste.

Problemi correlati