Anuncios

Bienvenidos sean a est post, hoy veremos como aplicar operaciones en nuestros apuntadores.

Anuncios
Anuncios

Hasta ahora cuando trabajamos con apunadores los hemos utilizado con el operador de asignacion (=) debido a que las operaciones de adicion o substraccion nos mueven a traves del array, tal como vimos en el post anterior, esto es asi porque un valor entero en un apuntador arimetico representa al elemento que apunta, es decir que cuando agregamos un entero a un apuntador este es automaticamente convertido dentro del tamaño del elemento del apuntador en bytes y agregada al apuntador, lo cual equivale a agregar a incrementar el indice del array.

Anuncios

Podemos considerar que los apuntadores son similares a numeros enteros, ellos pueden ser positivos y a su vez pueden recibir operacciones como la adicion, substraccion o comparacion, pero seran tratados ligeramente diferentes a los numeros enteros cuando la arimetica del apuntdor es ejecutada, veamos algunos resultados de cuando aplicamos una operacion sobre un apuntador con un numero entero:

	apuntador + entero -> apuntador
	entero + apuntador -> apuntador
	apuntador - entero -> apuntador
	apuntador - apuntador -> apuntador
Anuncios

Por esta razon debemos saber diferenciar una cosa, cuando incrememtamos un entero con otro entero lo hacemos sobre el valor, es decir si a 1 le sumamos 1 se transforma en dos pero si a un apuntador lo incrementamos con un entero en realidad le estamos pasando el valor de aplicar sizeof sobre el tipo del valor que apunta nuestro apuntador, vamos a suponer que tenemos un apuntador a un tipo double, si lo incrementamos en 1 lo que estamos haciendo es:

1 * sizeof(double)
Anuncios

Esto equivale a decir 8 bytes, y este es el valor que se incrementara para el proximo valor de tipo double donde apunta el apuntador, en cambio si fuera de tipo byte al incrementarlo en 1, si apliccamos la formula anterior (1 * sizeof(byte)) este se incrementara en 1 byte, por lo tanto con esto podemos decir que podemos usar las operaciones arimeticas en dos formas:

  • Ya sea manteniendo el valor del puntero sin cambios
  • Modificando el valor del puntero a medida que nos movemos a través del array
Anuncios

En el primer enfoque es el que usamos para desplazarnos por el array usando el puntero mas un desplazamiento, tal como vimos en el post anterior, repasemos ese caso:

a_arreglo = arreglo;
*(a_arreglo + 0) = 1; // equivale al primer elemento
*(a_arreglo + 1) = 2; // equivale al segundo elemento
*(a_arreglo + 2) = 3; // equivale al tercer elemento
*(a_arreglo + 3) = 4; // equivale al cuarto elemento
*(a_arreglo + 4) = 5; // equivale al quinto elemento
Anuncios

Como pueden ver simplemente con un nuevo desplazamiento iremos pasando a las distintas posiciones del array donde apuntamos, ahora veamos como seria el segundo enfoque:

a_arreglo = arreglo;
a_arreglo = 1; // equivale al primer elemento
a_arreglo += 1; *a_arreglo = 2; // equivale al segundo elemento
a_arreglo += 1; *a_arreglo = 3; // equivale al tercer elemento
a_arreglo += 1; *a_arreglo = 4; // equivale al cuarto elemento
a_arreglo += 1; *a_arreglo = 5; // equivale al quinto elemento
Anuncios

Observen que este es mas complejo porque primero debemos incrmentar al apuntador simplemente con el operador complementario, esto lo haccemos en uno pero luego tenemos que desreferenciar al apuntador en ese momento para obtener o asignar el valor, es un poco mas complicado que la version anterior pero en algunos momentos lo neccesitaremos de esta forma, para trabajar de esta forma lo podemos hacer de la siguiente manera:

a_arreglo = arreglo;
*a_arreglo++ = 1; // equivale al primer elemento
*a_arreglo++ = 2; // equivale al segundo elemento
*a_arreglo++ = 3; // equivale al tercer elemento
*a_arreglo++ = 4; // equivale al cuarto elemento
*a_arreglo = 5; // equivale al quinto elemento
Anuncios

Esto es como una fusion entre las dos opciones vistas anteriormente, dado que por medio del operador incremental y el desreferenciador podemos asignar el valor sin necesidad del paso adicional visto anteriormente, pero observen que en el primer caso lo incrementamos para que sea la posicion inicial o primera, esto es asi porque en realidad se incrementara solo despues que el operador de asignacion establezca el nuevo valor, esto es asi porque es posfijo, por lo tanto no es necesario incrementarlo en el ultimo caso dado que lo hicimos en el paso anterior, aunque tambien tenemos dos posibilidades:

  • (*a_arreglo)++, en este caso se desreferencia al apuntador y se incrementa el destino del mismo
  • *(a_arreglo++), este es desreferenciado el destino, se accede al valor y luego se incrementa la posicion del mismo
Anuncios

Con todo esto comentado vamos a ver un pequeño ejemplo, para ello generen un nuevo archivo con el nombre ejemplo16.c y le agregaremos el siguiente codigo:

ejemplo16.c

#include <stdio.h>

int main()
{
	int arreglo[] = {1, 2, 3, 4, 5};

	int* aArreglo1 = arreglo;
	int* aArreglo2 = &(arreglo[0]);

	printf("Valores iniciales de los apuntadores \n\n");
	printf("Direccion de arreglo = %#1x, valor de arreglo = %d\n",
		(unsigned long)arreglo, *arreglo);
	printf("Direccion de &arreglo[0] = %#1x, valor de arreglo[0] = %d\n",
		(unsigned long)&arreglo[0], arreglo[0]);
	printf("Direccion de a_arreglo1 = %#1x, valor de a_arreglo1 = %#1x\n",
		(unsigned long)&aArreglo1, (unsigned long)aArreglo1);
	printf("Direccion de a_arreglo2 = %#1x, valor de a_arreglo2 = %#1x\n",
		(unsigned long)&aArreglo2, (unsigned long)aArreglo2);

	return 0;
}
Anuncios
Anuncios

En este codigo primero definimos un array con cinco valores, luego definiremos dos apuntadores al mismo array pero uno lo haremos direcctamente y el otro por medio de la direccion de su primer elemento, despues parece un codigo muy complejo pero no lo es, simplemente mostraremos cada una de las direccciones de memoria y valores de cada uno de los elementos que definimos anteriormente, observen que usamos los operadores correspondientes y los casteos necesarios para mostrar correctamente la informacion, compilemos y veamos como es su salida:

tinchicus@dbn001vrt:~/lenguajes/C$ ./prog/ejemplo16 
Valores iniciales de los apuntadores 

Direccion de arreglo = 0xd3cc9530, valor de arreglo = 1
Direccion de &arreglo[0] = 0xd3cc9530, valor de arreglo[0] = 1
Direccion de a_arreglo1 = 0xd3cc9528, valor de a_arreglo1 = 0xd3cc9530
Direccion de a_arreglo2 = 0xd3cc9520, valor de a_arreglo2 = 0xd3cc9530
tinchicus@dbn001vrt:~/lenguajes/C$
Anuncios

Hasta aca nada de lo que no hayamos visto hasta ahora, lo sigueinte sera agregar un nuevo cordigo entre el codigo anterior y antes del return:

	printf("\n(1) Pasando por array incrementando el indice (i++): \n\n");
	for(int i = 0; i < 5; i++)
	{
		printf("&(arreglo[%1d]) = %#1x, arreglo[%1d] = %1d\n",
			i, (unsigned long)&(arreglo[i]), i, arreglo[i]);
	}
	printf("\n(2) Usando un puntero pasando delimitador (i++): \n\n");
	for(int i = 0; i < 5; i++)
	{
		printf("a_arreglo2+%1d = %#1x, *(aArreglo2+%1d) = %1d\n",
			i, (unsigned long)(aArreglo2+i), i, *(aArreglo2+i));
	}
	printf("\n(3) Usando un apuntador incrementandolo (aArreglo1++) \n\n");
	for(int i = 0; i < 5; i++, aArreglo1++)
	{
		printf("a_arreglo1 = %#1x, *a_arreglo1 = %1d\n",
			(unsigned long) aArreglo1, *aArreglo1);
Anuncios

En este bloque de codigo aplicaremos las tres formas que vimos para poder desplazarnos por un array, asi como tambien por los apuntadores, en todos los casos primero mostraremos un mensaje para identificar que haremos para luego tener un bucle que passara por todos los elemenntos de la coleccion.

Anuncios
Anuncios

En el primer caso pasaremos por todos los elementos del array en su forma mas comun para mostrar su posicion y su valor, en el segundo caso trabajaremos con uno de los de apuntadores donde por medio de un delimitador iremos pasando por todos los elementtos del array que apuntamos, y en el ultimo caso incrementaremos las posiciones del apuntador por medio del operador incremental y para ello aprovecharemos la posibiliddad que nos brinda el bucle for porque por medio de la coma en el ultimo campo nos permite trabajar en la inccrementacion de varios elementos, tal como vemos en el codigo, con todo esto comentado veamos como quedo el codigo final:

ejemplo16.c

#include <stdio.h>

int main()
{
	int arreglo[] = {1, 2, 3, 4, 5};

	int* aArreglo1 = arreglo;
	int* aArreglo2 = &(arreglo[0]);

	printf("Valores iniciales de los apuntadores \n\n");
	printf("Direccion de arreglo = %#1x, valor de arreglo = %d\n",
		(unsigned long)arreglo, *arreglo);
	printf("Direccion de &arreglo[0] = %#1x, valor de arreglo[0] = %d\n",
		(unsigned long)&arreglo[0], arreglo[0]);
	printf("Direccion de a_arreglo1 = %#1x, valor de a_arreglo1 = %#1x\n",
		(unsigned long)&aArreglo1, (unsigned long)aArreglo1);
	printf("Direccion de a_arreglo2 = %#1x, valor de a_arreglo2 = %#1x\n",
		(unsigned long)&aArreglo2, (unsigned long)aArreglo2);

	printf("\n(1) Pasando por array incrementando el indice (i++): \n\n");
	for(int i = 0; i < 5; i++)
	{
		printf("&(arreglo[%1d]) = %#1x, arreglo[%1d] = %1d\n",
			i, (unsigned long)&(arreglo[i]), i, arreglo[i]);
	}
	printf("\n(2) Usando un puntero pasando delimitador (i++): \n\n");
	for(int i = 0; i < 5; i++)
	{
		printf("a_arreglo2+%1d = %#1x, *(aArreglo2+%1d) = %1d\n",
			i, (unsigned long)(aArreglo2+i), i, *(aArreglo2+i));
	}
	printf("\n(3) Usando un apuntador incrementandolo (aArreglo1++) \n\n");
	for(int i = 0; i < 5; i++, aArreglo1++)
	{
		printf("a_arreglo1 = %#1x, *a_arreglo1 = %1d\n",
			(unsigned long) aArreglo1, *aArreglo1);
	}

	return 0;
}
Anuncios

Ahora si compilemos y veamos como es su salida:

tinchicus@dbn001vrt:~/lenguajes/C$ ./prog/ejemplo16 
Valores iniciales de los apuntadores 

Direccion de arreglo = 0xbdf81f20, valor de arreglo = 1
Direccion de &arreglo[0] = 0xbdf81f20, valor de arreglo[0] = 1
Direccion de a_arreglo1 = 0xbdf81f18, valor de a_arreglo1 = 0xbdf81f20
Direccion de a_arreglo2 = 0xbdf81f10, valor de a_arreglo2 = 0xbdf81f20

(1) Pasando por array incrementando el indice (i++): 

&(arreglo[0]) = 0xb11c50a0, arreglo[0] = 1
&(arreglo[1]) = 0xb11c50a4, arreglo[1] = 2
&(arreglo[2]) = 0xb11c50a8, arreglo[2] = 3
&(arreglo[3]) = 0xb11c50ac, arreglo[3] = 4
&(arreglo[4]) = 0xb11c50b0, arreglo[4] = 5

(2) Usando un puntero pasando delimitador (i++): 

a_arreglo2+0 = 0xbdf81f20, *(aArreglo2+0) = 1
a_arreglo2+1 = 0xbdf81f24, *(aArreglo2+1) = 2
a_arreglo2+2 = 0xbdf81f28, *(aArreglo2+2) = 3
a_arreglo2+3 = 0xbdf81f2c, *(aArreglo2+3) = 4
a_arreglo2+4 = 0xbdf81f30, *(aArreglo2+4) = 5

(3) Usando un apuntador incrementandolo (aArreglo1++) 

a_arreglo1 = 0xbdf81f20, *a_arreglo1 = 1
a_arreglo1 = 0xbdf81f24, *a_arreglo1 = 2
a_arreglo1 = 0xbdf81f28, *a_arreglo1 = 3
a_arreglo1 = 0xbdf81f2c, *a_arreglo1 = 4
a_arreglo1 = 0xbdf81f30, *a_arreglo1 = 5
tinchicus@dbn001vrt:~/lenguajes/C$
Anuncios

Aqui podemos ver no solamente cada una de las direcciones de memoria sino que a su vez las distintas formas de como podemos recuperar la informacion de los arrays, ya sea directamente o por medio de un apuntador, ahora les recomiendo tomar este codigo y comenzar a jugar con los parentesis y otras formas de poder recuperar la informacion, especialmente en la seccion de los apuntadores tal como vimos en el post.

Anuncios

En resumen, hoy hemos visto operaciones sobre arrays con apuntadores, cuales podemos aplicar, como las podemos aplicar, como pueden afectar de una forma u otra dependiendo de como la apliquemos y un «pequeño» y «simple» ejemplo para ver como trabaja, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50