[C con Clase] Puntero a Array

Davidson, Steven srd4121 en njit.edu
Jue Abr 3 18:22:16 CEST 2014


Hola Marving,

2014-04-03 9:29 GMT-04:00 Marving <jr.marving en gmail.com>:

> Hola Steven
> Gracias por tu rápida respuesta.
> La verdad es que no se aclararon mis dudas. Pero no te preocupes no fue
> debido
> a tu explicación. No comprendía nada de tu contestación, ayer.
>

Es normal. Esto de los punteros es un tema difícil de roer, incluso para
veteranos.

Entendía la arrays de dos dimensiones, pero no manejaba los punteros para
> este tipo de arrays.
> Partiendo de esto
> int vector[4];
> int array_2D[3][4]
>
> A veces asociaba la idea de vector, como puntero de arrays de 5 enteros.
>

Bueno, son 4 enteros, según el ejemplo.

Seguidamente, array_2D, era para mi un puntero a un array de dos
> dimensiones.
> Parece ser que estaba equivocado.
>
>
Correcto.

Lo cierto parece ser que es
> vector es simplemente un puntero a un entero. Apunta a los elementos del
> array
>

No tiene por qué ser un array; puede ser simplemente un solo entero. Es
cierto que podemos usar tal 'vector' como puntero al primer entero de un
array de enteros siguientes.

array_2D es un puntero a arrays unidimensionales de 4 elementos
>

Técnicamente, esto no es cierto.

'array_2D' es una dirección de memoria al primer elemento del array; o sea,
al primer entero.


La realidad de la situación es que el compilador hace algunas cosas
implícitamente para nosotros al usar arrays. Por ejemplo,

int matriz[3][3] = { {0} };

matriz[0][0] = matriz[1][1] = matriz[2][2] = 1;

Aquí, 'matriz' es una dirección de memoria al primer entero de nueve que
existen contiguamente en memoria, que el compilador gestionará. Para
entender lo que ocurre, es mejor ver un vector descriptor de lo que ocurre
en memoria:

Dirección de
Memoria           Tipo          Nombre           Valor          Misceláneo
-------------------------------------------------------------------------------------------------------
0x44EEAA00    int             -----                 0               (
matriz[0][0] )
0x44EEAA04    int             -----                 0               (
matriz[0][1] )
0x44EEAA08    int             -----                 0               (
matriz[0][2] )
0x44EEAA0B    int             -----                 0               (
matriz[1][1] )
...
0x44EEAA1C    int             -----                 0               (
matriz[2][1] )
0x44EEAA20    int             -----                 0               (
matriz[2][2] )

No se guarda ninguna dirección de memoria (en memoria) y por lo tanto, no
hay punteros.

Al acceder a los elementos, el compilador se fijará en los tipos de datos y
realizará los cálculos implícitamente. Por ejemplo, matriz[2][2] implica el
siguiente cálculo,

int => 4 bytes

Por lo que obtenemos,

matriz + (2 * 3 + 2) * 4  =  matriz + 32

que en el ejemplo anterior significa,

0x44EEAA00 + 32  =  0x44EEAA20


Ahora bien, las cosas se ponen peliagudas cuando pasamos arrays por
parámetro a las funciones. Para hacer esto, el compilador no crea un array,
sino que crea un puntero. Como un puntero y un array gestionan direcciones
de memoria, es lógico que exista una relación estrecha entre ambos
conceptos. Por lo tanto, se crea un puntero (parámetro local) a partir del
array (parámetro original). Por ejemplo,

void func( int m[][3] );
...
func( matriz );

Realmente, 'm' es un puntero, que guarda la dirección de memoria que ES el
array, 'matriz'. Dicho esto, podríamos haber escrito,

void func( int (*m)[3] );

aunque claro está, el uso de 'm' sería diferente al ser un tipo de puntero,
y además, podríamos hacer que 'm' apuntase a otra dirección de memoria;
cosa que seguramente no nos interesaría.

Los cálculos de la dirección de memoria siguen siendo los mismos
presentados anteriormente en el caso de un array "normal".


Por último, quiero dejar claro que un puntero no es igual que un array.
Como mencioné antes, existe una relación entre punteros y arrays, por lo
que podemos tratarlos de manera parecida, e incluso convertir uno a otro.


Espero haber aclarado un poco más el tema.

Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20140403/4e993c6f/attachment.html>


Más información sobre la lista de distribución Cconclase