jueves, 8 de diciembre de 2016

Capítulo 87: Aritmética de punteros en C


Diario de un programador. Día 189


Operaciones de aritmética con punteros en C.


Siguiendo con el tema de los punteros en C, debemos mencionar que se pueden realizar ciertas operaciones aritméticas con los punteros, por ejemplo. Se pueden sumar o restar, debido a esto, se está permitido utilizar los incrementos ++ o decrementos --
Cabe hacer presente que estas operaciones solamente son válidas y tienen sentido cuando se trabajan con arreglos. Vamos a mostrar algunos ejemplos para entender el por qué.
Supongamos que declaramos el siguiente arreglo:

int arreglo[10];

También vamos a suponer, por cuestiones de hacerlo simple, que su primer elemento, o sea arreglo[0], está en la posición de memoria 1000000.
Entonces, crearemos un puntero que apunte a la primera posición del arreglo. Esto lo lograríamos de la siguiente manera:

*pArreglo = &arreglo[0];

Entonces, al tratar de hacer esto...

pArreglo++;

Es lo mismo que estuviera haciendo pArreglo + 1 o en el caso de sumar en la memoria, estaría sumando 1000000 + 1 (suponiendo como dijimos, que la posición estuviese en 1000000).
En aritmética convencional, esto daría como resultado 1000001, pero no es el caso de los punteros. En la aritmética de los punteros, lo que se suma (o resta según el caso) es el tamaño del tipo de dato. Por lo general los enteros tienen un valor de 4 bytes (en algunas máquinas valen 2 mientras que en otras valen 8). Por lo tanto el resultado de esto sería 1000004, y si sumamos pArreglo +2 daría como resultado 1000008, si sumamos +3 daría 1000012 y así sucesivamente. Entonces esto sería algo así:

1000000 + 1 = 1000000 + (1 * 4) = 1000004
1000000 + 2 = 1000000 + (2 * 4) = 1000008
1000000 + 3 = 1000000 + (3 * 4) = 1000012


Con un dibujo quizás quede un poco más claro


Veamos un ejemplo con un código. Voy a crear un arreglo de 5 elementos, luego los voy a rellenar usando un ciclo for y luego veré en qué posición de memoria quedaron alojados esos valores.
El código es el siguiente:

#include<stdio.h>

int main(void){

int arreglo[5];
int *pArreglo = &arreglo[0];
int i;

for (i = 0; i < 5; i++){
    //relleno el arreglo con valores
    arreglo[i] = i;
}
for (i = 0; i < 5; i++){
    //muestro la posición de los valores
    printf("%d\n", &arreglo[i]);
 }
return 0;
}

Al ejecutar este código estas son las posiciones de memoria que me muestra en mi caso:


La primera termina en 508, luego sigue 512 y así sucesivamente se va incrementando de 4 en 4, por lo que se deduce que en este caso, el valor del entero es de 4 bytes.

Ahora voy a modificar este programa, añadiendo un incremento al puntero pArreglo y luego mostraré el resultado. Esto es lo que me muestra el programa:


#include<stdio.h>

int main(void){

int arreglo[5];
int *pArreglo = &arreglo[0];
int i;

for (i = 0; i < 5; i++){
    arreglo[i] = i;
}
for (i = 0; i < 5; i++){
    pArreglo++;
    printf("%d  ", &arreglo[i]);
    printf("%d\n", &pArreglo[i]);
}
return 0;
}


La columna de la izquierda es el valor original, mientras que la columna de la derecha se ve el incremento que se realizó.
La primera posición se aumentó en 4 bytes, la segunda en 8 y así sucesivamente quedando de la siguiente manera:

1 -> 4
2 -> 8
3 -> 12
4 -> 16
5 -> 20

Como mencioné anteriormente, en algunos computadores los enteros son de 4 bytes, mientras que en otros son de 2 o de 8, pero ¿cómo podemos saber el valor de los tipos de datos en nuestro equipo? En casos como estos podemos utilizar el operador sizeof el cual nos sirve para obtener el tamaño de un tipo de datos. Este operador regresa un entero, el cual corresponde al número total del tamaño de bytes.
A continuación un ejemplo:

#include<stdio.h>

int main(void){
  printf("int = %d\n", sizeof(int));
  printf("short = %d\n", sizeof(short));
  printf("long = %d\n", sizeof(long));
  printf("char = %d\n", sizeof(char));
  printf("float = %d\n", sizeof(float));
  printf("double = %d\n", sizeof(double));
  printf("long double = %d\n", sizeof(long double));

return 0;
}

Al compilar y ejecutar este programa, estos son los valores que me muestra:


Dejaremos esto hasta aquí el día de hoy ya que aún hay mucho más que ver con esto de los punteros.
Saludos.


Gustavo J. Cerda Nilo
Diciembre 2016



No hay comentarios:

Publicar un comentario

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...