Quería asegurarme de entender el concepto del puntero a una array de n elementos, por ejemplo: int (*myarr)[10]; //myarr is a pointer to an array that can hold 10 integer
He probado el siguiente código:
void main(){ int arr[][3] = { { 10, 20, 50 }, { 30, 60, 90 }, { 22, 92, 63 } }; int(*arrptr)[3]; /* a pointer to an array of 3 ints*/ int *ip = arr[0]; arrptr = arr; int index; for (index = 0; index < 9; index++) { printf("[ %d ][ %p ]\n\n", *ip, ip);ip++; } for (index = 0; index < 3; index++) { printf("%x <-> %p,%d\n", *arrptr, arrptr,**arrptr); arrptr++; } }y tengo eso
*[ 10 ][ 001BFA40 ]* [ 20 ][ 001BFA44 ] [ 50 ][ 001BFA48 ] *[ 30 ][ 001BFA4C ]* [ 60 ][ 001BFA50 ] [ 90 ][ 001BFA54 ] *[ 22 ][ 001BFA58 ]* [ 92 ][ 001BFA5C ] [ 63 ][ 001BFA60 ] *1bfa40* <-> *001BFA40*,10 1bfa4c <-> 001BFA4C,30 1bfa58 <-> 001BFA58,22
Según tengo entendido, el arrptr contiene la dirección completa a la que apunta la matriz. Esto significaría que el puntero puede moverse libremente en estos rangos de direcciones.
Pero, ¿por qué el valor de la dirección que contiene arrptr es igual a la dirección que contiene el valor de arr[0] ?
En otras palabras: sé que es normal que *arrptr contenga la dirección de arr[0] , pero la dirección de arrptr que contiene el lugar al que arrptr es la misma donde arr[0] ?!
Una matriz es un área de almacenamiento contigua. Entonces, usando su fragmento de código, estas expresiones
&arr , arr , arr[0] , &arr[0] y &arr[0][0] proporcionan la misma dirección de la memoria de almacenamiento ocupada por el arreglo. Todos ellos apuntan al primer byte del área de almacenamiento.
Consideremos por ejemplo esta afirmación
printf("%x <-> %p,%d\n", *arrptr, arrptr,**arrptr); arrptr es un puntero que tiene tipo int ( * )[3]; . Al eliminar la referencia de este puntero *arrptr , obtendrá una matriz de tipo int[3] que, a su vez, se convierte implícitamente en un puntero a su primer elemento, es decir, esta expresión tendrá el tipo int * y tanto arrptr como *arrptr arrojan el mismo valor. Ese es el valor en sí mismo no se cambia. Es el tipo de la expresión que se cambia. :)
Por lo tanto, como *arrptr tiene tipo int * y es un puntero (después de la conversión implícita de la matriz unidimensional correspondiente; C no tiene referencias a objetos como las tiene C++), entonces la expresión **arrptr produce un objeto de tipo int . De acuerdo con la lógica del fragmento de código, es el primer elemento de cada fila de la matriz bidimensional.
*arrptr es igual (mismo tipo, mismo valor) a arrptr[0] . Dado que asignó arrptr = arr , eso también significa que *arrptr es igual a *arr .
Por cierto, usar %x para imprimir un puntero técnicamente da un comportamiento indefinido (ya que %x es para un valor integral unsigned ). Utilice %p en su lugar. De manera similar, cuando se usa %p , es recomendable convertir el puntero que se está imprimiendo a (void *) .
por qué el valor de la dirección que contiene
arrptres igual a la dirección que contiene el valor dearr[0]
La dirección de una matriz siempre es igual a la dirección de su primer elemento.
Para cualquier
T a[n]; /* n > 0 */la expresion
&a == &a[0]es verdad.
También tenga en cuenta que en C una matriz "2D" es solo una matriz de matrices.