2015-08-11 7 views
8

Come programmatore principiante mi sto occupando di alcuni semplici problemi relativi ai puntatori. Nel seguente codice ho trovato il valore di *a e a sono gli stessi in formato esadecimale. Ma non riesco a capire la ragione.Puntatore nell'array 2D

#include <stdio.h> 
#include <stdlib.h> 

main(){ 
    int a[5][5]; 
    a[0][0] = 1; 

    printf("*a=%p a=%p \n", *a, a); 

    return 0; 
} 

Ecco l'output:

*a=0x7ffddb8919f0 a=0x7ffddb8919f0 
+1

C o C++? Cose diverse – yizzlez

+0

In effetti, è perché l'indirizzo di 'a' e il valore contenuto in' * a' sono gli stessi. –

risposta

5

in C e C++ valori lingue di matrice tipo T [N] sono implicitamente convertiti in valori di tipo puntatore T * nella maggior parte dei contesti (con poche eccezioni). Il puntatore risultante punta al primo elemento dell'array originale (indice 0). Questo fenomeno è noto informalmente come decadimento del tipo di matrice .

L'argomento printf è uno di questi contesti quando si verifica il decadimento del tipo di matrice .

array A 2D di tipo int [5][5] non è altro che una "matrice 1D di array 1D", cioè esso è un array di 5 elementi e ogni elemento stesso essendo un array di 5 int s.

La regola di decadimento del tipo di matrice sopra si applica naturalmente a questa situazione.

L'espressione a, che in origine ha il tipo di matrice int [5][5], decade a un puntatore del tipo int (*)[5]. Il puntatore punta all'elemento a[0], che è l'inizio della sottoschera a[0] in memoria. Questo è il primo puntatore che stampi.

L'espressione *a è un operatore di dereferenza applicato alla sottoespressione a. La sottoespressione a in questo contesto si comporta esattamente nello stesso modo di prima: decade al puntatore del tipo int (*)[5] che punta a a[0]. Quindi il risultato di *a è a[0] stesso. Ma a[0] è anche un array. È un array di tipo int[5].È anche soggetto al decadimento del tipo di array. Decade per puntatore di tipo int *, che punta al primo elemento di a[0], ad esempio a[0][0]. Questo è il secondo puntatore che stampi.

La ragione per cui entrambi i valori dei puntatori sono gli stessi numericamente è che l'inizio della sottoschera a[0] corrisponde alla stessa posizione di memoria dell'elemento a[0][0].

1

a può essere considerato un pointer to a pointer to an int (in realtà, si tratta di un array of array of int, ma abbastanza vicino).

Quindi a e *a entrambi puntano allo stesso indirizzo (che risulta essere a[0][0]).

*a è ancora un puntatore e a[0] è lo stesso indirizzo di a[0][0].

+0

Questo è troppo fuorviante per essere utile. – juanchopanza

+0

@juanchopanza Mi scusi? Potresti spiegare perché? – Jashaszun

+0

Risposta assolutamente incorpore. 'a' non può essere considerato" un puntatore a un puntatore ". L'array 2D in C e C++ non è in alcun modo correlato a "puntatore a puntatore" – AnT

9

Un array e il primo elemento hanno lo stesso indirizzo. :)

Per questa dichiarazione

int a[5][5]; 

espressione a utilizzato nella chiamata printf è implicitamente convertito al puntatore al suo primo elemento. Expression *a restituisce il primo elemento dell'array che a sua volta è un array unidimensionale che viene anche convertito in un puntatore al suo primo elemento.

espressioni Così a e *a hanno lo stesso valore di espressione &a[0][0]