2011-12-29 14 views
7

tengo el siguiente fragmento de código:matrices de dos dimensiones y punteros

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]); 

Ambos printf() declaraciones todo Imprimir el mismo valor: 0x0013ff67

  1. Según mi conocimiento, tabla (es decir) nombre de la matriz representa la dirección del primer subconjunto (es decir) board[0] y

  2. board[0] repres Ents la dirección del primer elemento de la primera matriz (es decir) board[0][0]

¿Por qué aparece la misma dirección en todos mis printf() declaraciones? Espero diferentes direcciones para ambas declaraciones.

Soy bastante nuevo en esto y no entiendo este comportamiento. Amablemente ilumíname.

Respuesta

1

Según mi conocimiento, tabla (es decir) nombre de la matriz representa la dirección de la primera submatriz (IE) de la junta [0]

Esto sólo es cierto si board se utiliza fuera de estos contextos

  • Como operando del operador
  • & como operando de sizeof

Cuando se aplica algo de eso, la expresión board representa la matriz y sigue teniendo el tipo de la matriz (char[3][3]). Aplicando el operador & resulta en obtener la dirección de la matriz, que por supuesto es igual a la dirección de su primer elemento, simplemente teniendo un tipo diferente (char(*)[3][3] en lugar de char(*)[3]). Lo mismo que es cierto acerca de la matriz board es verdadera acerca de su primera matriz secundaria board[0].

Cuando lo utiliza fuera de esos contextos, obtiene la dirección del primer elemento (subcampo en su caso). Esa dirección no es un objeto sino solo un valor. El valor no tiene dirección, pero los objetos sí. Intentar aplicar & en ella fallaría. Por ejemplo

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

Tenga en cuenta que todo lo anterior se aplica a C; no necesariamente a C++.

+0

Hola, gracias por su respuesta y entiendo parcialmente. ¿Puede proporcionar un sencillo programa de muestra que explique su comentario? Yo sería de gran ayuda. Gracias. – intex0075

+0

@intex su pregunta * es * el programa de ejemplo simple que proporcionaría. –

5

Aunque es una matriz 2D, dentro de la memoria se representará como una matriz lineal. así que cuando dices, tablero [0] [0] aún apunta al primer elemento en ese conjunto lineal y, por lo tanto, a la misma dirección de memoria.

1

Por supuesto, esto imprimirá la misma dirección.
Piense acerca de las matrices 2D como esto por un minuto,

int ** ptr;


La dirección *ptr es igual &(**ptr).

Porque básicamente, eso es lo que está haciendo su código.

y recuerde que en la memoria, las matrices 2D se mapearán linealmente.

1

Puede ser que conozcas un lenguaje orientado a objetos como Java o Python, y ahora estás aprendiendo el lenguaje C. La diferencia entre Java y C cuando se piensa en char board[3][3] es que en C la variable board se representa en la memoria como 9 caracteres en direcciones de memoria adyacentes. Al igual que:

board: 1 2 3 4 5 6 7 8 9 

En C, &board se obtiene la misma dirección de memoria como &board[0] y &board[0][0].

En contraste con esto, en Java la variable podría ser declarado como char[][] board y su representación en la memoria se vería conceptualmente como esto:

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

donde ptr(x) apunta a la dirección de memoria de x. Por lo tanto, en Java, board apunta a una dirección de memoria diferente que board[0].


Dices En C, & junta se obtiene la misma dirección de memoria como & bordo [0] y & bordo [0] [0]. Pero puedo acceder al primer elemento solo a través de la placa [0] [0] (o) * placa [0] (o) ** placa. ¿¿Por que es esto entonces??

Aunque las expresiones &board y &board[0] y &board[0][0] producen la misma dirección, el sistema de tipos del lenguaje C que le impide acceder al valor de char. En un compilador de C, los tipos son (conceptualmente):

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

Suponiendo una variable de tipo char, podemos escribir:

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

pero no pueden escribir:

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

porque el tipo en el lado izquierdo es incompatible con el tipo en el lado derecho de la tarea.

Si está seguro de que una dirección apunta a un char, se puede utilizar un tipo de reparto:

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

La desventaja es que este tipo de moldes de tipo pueden dar lugar a errores de codificación.

+0

Usted dice In C, & board produce la misma dirección de memoria que & board [0] y & board [0] [0]. Pero puedo acceder al primer elemento solo a través de la placa [0] [0] (o) * placa [0] (o) ** placa. ¿¿Por que es esto entonces?? – intex0075