[C con Clase] Capitulo 12

Steven Davidson steven en conclase.net
Mie Ene 31 20:30:37 CET 2007


Hola David,

El pasado 2007-01-31 16:13:12, David escribió:

D> Hola a todos, tengo una duda con un texto que sale en el capitulo 12 de C++ con clase el ejemplo al que se refiere el texto es el siguiente:

Bueno. Reinel y Joaquín ya te han contestado correctamente. Por si todavía tienes dudas, me gustaría agregar a lo que han dicho.

D> El valor es: 9
D> Memoria  es: 0x0012FF58
D> El valor es: 8
D> Memoria  es: 0x0012FF5C
D> El valor es: 7
D> Memoria  es: 0x0012FF60
D> El valor es: 6
D> Memoria  es: 0x0012FF64
D> El valor es: 5
D> Como se puede apreciar el incremento de la dirección de la variable "puntero" es de 4bytes, el siguiente "int" al que se refiere en el texto anterior, pero también, cada vez que ejecuto la siguiente línea "puntero++", me pasa a la siguiente posición de memoria del vector.

Te presento una tabla llamada vector descriptor para que tengas una idea de lo que ocurre en la memoria. Usaremos tu ejemplo:

Dirección
de Memoria   Tipo     Nombre     Valor        Misceláneo
------------------------------------------------------------
0x0012FF54   int *    p          0x0012FF58
0x0012FF58   int      ----       0x09         (int aArr[10])
0x0012FF59   ----     ----       0x00
0x0012FF5A   ----     ----       0x00
0x0012FF5B   ----     ----       0x00
0x0012FF5C   int      ----       0x08
0x0012FF5D   ----     ----       0x00
0x0012FF5E   ----     ----       0x00
0x0012FF5F   ----     ----       0x00
0x0012FF60   int      ----       0x07
0x0012FF61   ----     ----       0x00
0x0012FF62   ----     ----       0x00
0x0012FF63   ----     ----       0x00
0x0012FF64   int      ----       0x06
0x0012FF65   ----     ----       0x00
0x0012FF66   ----     ----       0x00
0x0012FF67   ----     ----       0x00
0x0012FF68   int      ----       0x05
0x0012FF69   ----     ----       0x00
0x0012FF6A   ----     ----       0x00
0x0012FF6B   ----     ----       0x00
...

Bajo Intel y otras arquitecturas basadas en el ordenamiento de bytes "little-endian", verás algo parecido a lo anterior. También nos basamos en la idea de que 'int' ocupa 4 bytes al igual que el tamaño de las direcciones de memoria.

Como puedes ver, en cada dirección de memoria, tenemos un byte que, en nuestro ejemplo, contiene partes de cada 'int' asociado al array 'aArr'. Por esta razón es importante conocer los tipos de cada dato, para poder manipularlos adecuadamente.

Al incrementar el puntero con 'p++', el compilador tiene en cuenta el tamaño del tipo siendo apuntado. Como bien explicó Joaquín, el compilador hace este cálculo internamente:

p += sizeof(int)

Si el puntero fuese a 'char', entonces sí incrementaríamos por cada byte que equivaldría a incrementar la dirección de memoria por uno. Por otro lado, si el puntero fuese a 'long double', entonces cada incremento del puntero resultaría en incrementar 10 bytes = sizeof(long double) la dirección de memoria.

Para terminar, veamos el vector descriptor después de incrementar 'p' una vez; o sea, p++.

Dirección
de Memoria   Tipo     Nombre     Valor        Misceláneo
------------------------------------------------------------
0x0012FF54   int *    p          0x0012FF5C
0x0012FF58   int      ----       0x09         (int aArr[10])
0x0012FF59   ----     ----       0x00
0x0012FF5A   ----     ----       0x00
0x0012FF5B   ----     ----       0x00
0x0012FF5C   int      ----       0x08
0x0012FF5D   ----     ----       0x00
0x0012FF5E   ----     ----       0x00
0x0012FF5F   ----     ----       0x00
...

Obviamente vemos que 'p' apunta al comienzo del valor 8. Cada vez que accedamos a esta dirección de memoria, tomamos 4 bytes ya que es el tipo de tal dato. Nuevamente, el tipo del dato es extremadamente importante y por eso C/C++ son lenguajes fuertemente tipificados.

D> Alguien puede explicarme porque sucede esto, si el puntero no cambia de posición de memoria, no debería mostrar otro valor cuando se coloca *puntero[0];

No. El puntero 'p' sí cambia de valor y por tanto apunta a otra dirección de memoria. El array es quien no puede cambiar de dirección de memoria. Tomando el ejemplo anterior, el array 'aArr' SIEMPRE será 0x0012FF58, mientras que 'p', al ser una variable, puede contener cualquier valor que nosotros indiquemos.


Espero que esto aclare las dudas.

Steven


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