ESTRUCTURAS DINÁMICAS DE DATOS

Anuncio
ESTRUCTURAS DINÁMICAS DE DATOS
Apuntadores
Un apuntador es una variable cuyo valor es la dirección de memoria de otra variable.
Se dice que un apuntador “apunta” a la variable cuyo valor se almacena a partir de la
dirección de memoria que contiene el apuntador. Por ejemplo, si un apuntador p
almacena la dirección de una variable x, se dice que “p apunta a
x”.
Los símbolos * y & pueden ser usados para el contenido y la dirección de una variable,
respectivamente. Por ejemplo,
si "x" es una variable de tipo "int"
y "y" es una variable de tipo "int"
y "px" es una variable de tipo "apuntador a int"
entonces, se podría hacer lo siguiente:
Asignar la dirección de "x" al apuntador "px"
px = &x;
Aumentar en 1, el valor apuntado por "px" (es decir, el valor de "x") y asignarlo a la
variable "y".
y = *px+1;
Aumentar en 1, el valor del apuntador "px" (es decir, el valor de una variable
desconocida) y asignarlo a la variable "y".
Aumentar en 1 el valor apuntado por "px" (es decir, el valor de "x").
*px+=1;
o bien
(*px)++;
Notar que en este último ejemplo es necesario usar paréntesis, debido a que, aunque
la prioridad de "*" y "++" es igual, la asociatividad es de DERECHA a IZQUIERDA. Así, sin
los paréntesis, la expresión "*px++;" se entendería como: "*(px++);".
Qué son los punteros
Ahora ya estamos en condiciones de ver lo que es un puntero. Un puntero es una
variable un tanto especial. Con un puntero podemos almacenar direcciones de
memoria. En un puntero podemos tener guardada la dirección de una variable.
Veamos la diferencia entre una variable puntero y las variables "normales".
En el dibujo anterior tenemos una representación de lo que puede ser la memoria del
ordenador. Cada casilla representa un byte de la memoria. Y cada número es su
dirección de memoria. La primera casilla es la posición 00001. La segunda casilla es la
posición 00002, y así sucesivamente. Supongamos que ahora declaramos una variable:
char numero = 43. El ordenador guardaría, por ejemplo, esta variable en la posición
00003. Esta posición de la memoria queda reservada y ya no la puede usar nadie más.
Además, esta posición a partir de ahora se denomina número. Como le hemos
asignado el valor 43, el valor 43 se almacena en la posición de memoria 00003.
Referenciación
La referenciación es la obtención de la dirección de una variable. En C y C++ esto se
hace a través del operador ‘&’, aplicado a la variable a la cual se desea saber su
dirección. Nótese que se trata de un operador unario. Ejemplo:
Código C
int x = 25;
cout << "La dirección de x es: " << &x << endl;
Para declarar un apuntador se especifica el tipo de dato al que apunta, el operador ‘*’,
y el nombre del apuntador. La sintaxis es la siguiente:
<tipo de dato apuntado> *<identificador del apuntador>
A continuación se muestran varios ejemplos:
Código C
int *ptr1; // Apuntador a un dato de tipo entero (int)
char *cad1, *cad2; // Dos apuntadores a datos de tipo carácter (char)
float *ptr2; // Apuntador a un dato de tipo punto-flotante (float)
Asignación de apuntadores
Se pueden asignar a un apuntador direcciones de variables a través del operador de
referenciación (‘&’) o direcciones almacenadas en otros apuntadores. Ejemplos:
Código C y C++
int i = 5;
int *p, *q;
p = &i; // Se le asigna a ’p’ la dirección de ’i’
q = p; // Se le asigna a ’q’ la dirección almacenada en ’p’ (la misma de ’i’)
Desreferenciación de apuntadores
La Desreferenciación es la obtención del valor almacenado en el espacio de memoria
donde apunta un apuntador. En C y C++ esto se hace a través del operador ‘*’, aplicado
al apuntador que contiene la dirección del valor. Nótese que se trata de un operador
unario. Ejemplos:
Código C
int x = 17, y;
int *p;
p = &x;
cout << "El valor de x es: " << *p << endl; // Imprime 17
y = *p + 3; // A ’y’ se le asigna 20
Otro ejemplo.
Un operador de indirección o de desreferencia:
El operador * aplicado al nombre de un apuntador indica el valor de la variable
apuntada; Regresa el valor del objeto hacia el cual su operando apunta, es decir un
apuntador, ejemplo:
main()
{
int x,y;
int *py;
y = 5;
*py = y;
x = *py + 5;
printf(''%d %d nn'',*py,x);
}
Veamos con un ejemplo en C la diferencia entre todos estos conceptos
Es decir: int x = 25, *pint;
pint = &x;
La variable pint contiene la dirección de memoria de la variable x. La expresión: *pint
representa el valor de la variable (x) apuntada, es decir 25. La variable pint también
tiene su propia dirección: &pint
Otros ejemplos:
float *q; /*apuntador hacia un flotante*/
char *z; /*puntero que contiene la dirección de una variable que guarda un carácter */
Para referirnos a un valor a través de un apuntador, lo hacemos mediante un proceso
llamado indirección.
Por ejemplo, para mandar a impresión el valor entero, hacia el cual a punta “p”, sería
así:
Printf(“%d”,*p);
#include <stdio.h>
main()
{
int numero;
int *punt;
numero = 43;
punt = №
printf( "Dirección de numero = %p, valor de numero = %i\n",
punt, numero );
}
Vamos a analizar línea a línea:



En la primera, int numero;, reservamos memoria para numero (supongamos
que queda como antes, en la posición 00003). Por ahora numero no tiene
ningún valor.
Siguiente línea: int *punt;, reservamos una posición de memoria para
almacenar el puntero. Lo normal es que a medida que se declaran variables se
guarden en posiciones contiguas. De modo que quedaría en la posición 00004.
Por ahora punt no tiene ningún valor, es decir, no apunta a ninguna variable.
Esto es lo que tenemos por ahora:
Tercera línea: numero = 43;. Aquí estamos dando el valor 43 a número. Se
almacena 43 en la dirección 00003, que es la de número.

Cuarta línea: punt = №. Por fin damos un valor a punt. El valor que le
damos es la dirección de numero (ya hemos visto que & devuelve la dirección
de una variable). Así que punt tendrá como valor la dirección de numero,
00003. Por lo tanto tenemos:
Cuando un puntero tiene la dirección de una variable se dice que ese puntero apunta a
esa variable. La declaración de un puntero depende del tipo de dato al que queramos
apuntar. En general, la declaración es:
tipo_de_dato *nombre_del_puntero;
Veamos el siguiente ejemplo. Queremos comprobar si dos variables son iguales
usando punteros:
#include <stdio.h>
main()
{
int a, b;
int *punt1, *punt2;
a = 5; b = 5;
punt1 = &a; punt2 = &b;
if ( punt1 == punt2 )
printf( "Son iguales\n" );
}
Diseñe un programa, que sume dos variables de tipo entero, por medio de
apuntadores.
#include <stdio.h>
#include <conio.h>
main()
{
int a, b, c;
int *p1, *p2, *p3; /*declaración de los punteros */
printf("Ingrese el valor de a:\n");
scanf("%d", &a);
printf("Ahora el valor de b:\n");
scanf("%d", &b);
c=a+b;
printf("a+b=%d\n", c);
/*Asignamos las direcciones a los punteros correspondientes/
p1=&a;
p2=&b;
/*Ahora desreferenciamos el valor de los punteros para sumarlos */
printf("*p1 + *p2=%d\n", *p1+*p2);
p3=&c;
printf(" Dirección de a es %p\n Dirección de b es %p\n Y la de c es %p\n\n", p1, p2,
p3);
getch();
return 0;
}
Descargar