2011-12-29 13 views
7

ho il seguente frammento di codice:due array bidimensionali e puntatori

char board[3][3] = { 
        {'1','2','3'}, 
        {'4','5','6'}, 
        {'7','8','9'} 
        }; 

printf("address of board : %p\n", &board); 
printf("address of board[0] : %p\n", &board[0]); 

Entrambi printf() dichiarazioni tutti Stampa lo stesso valore: 0x0013ff67

  1. Come per la mia conoscenza, pensione (ie) nome di matrice rappresenta l'indirizzo del primo sottoarray (cioè) board[0] e

  2. board[0] repres Ent l'indirizzo del primo elemento nel primo array (cioè) board[0][0]

Perché mi appare lo stesso indirizzo in tutti i miei printf() affermazioni? Mi aspetto indirizzi diversi per entrambe le dichiarazioni.

Sono abbastanza nuovo a questa roba e non capisco questo comportamento. Gentilmente illuminami

risposta

1

Come per la mia conoscenza, pensione (ie) nome della matrice rappresenta l'indirizzo del primo sottoarray (ie) scheda [0]

Questo è vero solo se board viene utilizzato al di fuori di questi contesti

  • Come operando del & operatore
  • Come operando sizeof

Quando si verifica una delle condizioni, l'espressione board rappresenta la matrice e continua ad avere il tipo di matrice (char[3][3]). Applicando l'operatore & ad esso risulta ottenere l'indirizzo dell'array, che ovviamente corrisponde all'indirizzo del suo primo elemento, semplicemente avendo un tipo diverso (char(*)[3][3] invece di char(*)[3]). Lo stesso che è vero per l'array board è true per il suo primo sub array board[0].

Quando lo si utilizza al di fuori di questi contesti, si ottiene l'indirizzo del primo elemento (subarray nel tuo caso). Quell'indirizzo non è un oggetto ma solo un valore. Il valore non ha indirizzo, ma gli oggetti hanno. Cercando di applicare & su di esso non riuscirebbe. Per esempio

// error: trying to apply '&' on something that has no address 
&(1 ? board : board) 

Si noti che qualsiasi cosa detta sopra si applica a C; non necessariamente in C++.

+0

Ciao grazie per la tua risposta e in parte capisco. Puoi fornire un semplice programma di esempio che spiega il tuo commento. Sarei di grande aiuto. Grazie. – intex0075

+0

@intex la tua domanda * è * il semplice programma di esempio che vorrei fornire. –

5

Sebbene sia un array 2D, all'interno della memoria verrà rappresentato come array lineare. così quando dici, board [0] [0] punta ancora al primo elemento di quell'array lineare e quindi allo stesso indirizzo di memoria.

1

Ovviamente questo stamperà lo stesso indirizzo.
Pensate array 2D come questo per un minuto,

int ** ptr;


L'indirizzo *ptr è uguale &(**ptr).

Perché in pratica, questo è ciò che sta facendo il tuo codice.

e ricorda che in memoria, gli array 2D verranno mappati linearmente.

1

Può darsi che si conosca un linguaggio orientato agli oggetti come Java o Python e ora si sta imparando il linguaggio C. La differenza tra Java e C quando si pensa a char board[3][3] è che in C la variabile board è rappresentata in memoria come 9 caratteri negli indirizzi di memoria adiacenti. In questo modo:

board: 1 2 3 4 5 6 7 8 9 

In C, &board produce lo stesso indirizzo di memoria di &board[0] e &board[0][0].

In contrasto con questo, in Java variabile sarebbe stata dichiarata come char[][] board e la sua rappresentazione della memoria sarebbe concettualmente simile a questa:

board: ptr(A) ptr(B) ptr(C) 
A:  1 2 3 
B:  4 5 6 
C:  7 8 9 

dove ptr(x) punti a indirizzo di memoria di x. Quindi, in Java, board indica un indirizzo di memoria diverso da board[0].


si dice in C, & bordo produce lo stesso indirizzo di memoria di & bordo [0] e & bordo [0] [0]. Ma sono in grado di accedere al primo elemento solo tramite la board [0] [0] (o) * board [0] (o) ** board. Perché è così??

Anche se le espressioni &board e &board[0] e &board[0][0] producono lo stesso indirizzo, il sistema di tipi del linguaggio C impedisce di accedere al valore char. In un compilatore C, i tipi sono (concettualmente):

board:  type char[3][3] 
board[0]: type char[3] 
board[0][0]: type char 

Assumendo una variabile di tipo char, possiamo scrivere:

char c; 
c = board[0][0]; 

ma non può scrivere:

char c; 
c = board; // Error 
c = board[0]; // Error 

perché la digitare sul lato sinistro è incompatibile con il tipo sul lato destro del compito.

Se si è certi che un indirizzo punta a un char, è possibile utilizzare un tipo di getto:

char c; 
c = *(char*)board; // Works OK 
c = *(char*)board[0]; // Works OK 

Lo svantaggio è che tale tipo calchi possono portare a errori di codifica.

+0

Si dice in C, e la scheda produce lo stesso indirizzo di memoria di & board [0] e & board [0] [0]. Ma sono in grado di accedere al primo elemento solo tramite la board [0] [0] (o) * board [0] (o) ** board. Perché è così?? – intex0075

Problemi correlati