Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de...

22
Estructuras de Datos Punteros y algo más

Transcript of Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de...

Page 1: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Estructuras de Datos

Punteros y algo más

Page 2: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

• Un puntero es una variable que almacena la dirección de memoria de otra variable

• Para obtener la dirección de una variable se utiliza el operador de referencia:

&nombre_variable

• Veamos un ejemplo:

Page 3: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

int A;A=50;cout<<"La dirección de A es: "<< &A;cout<<" El valor de A es: "<<A;

• Esto imprimirá algo como:La dirección de A es: 0x0012FF7C El valor de A es: 50

Page 4: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

• Para declarar un puntero a una variable de un tipo dado se usa la siguiente sintaxis:tipo_var *nombre_puntero;

• Ejemplo:int A=50;int *P;P=&A;

• Se declara un puntero (a entero) P, se le asigna la dirección del entero A, por tanto P queda apuntando a A

Page 5: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

• El operador de indirección * permite acceder a la variable cuya dirección se encuentra guardada en un puntero (ya sea para acceder al valor almacenado en la variable o para modificarlo)

• El operador de indirección usa la siguiente sintaxis:*nombre_puntero

• Veamos un ejemplo:

Page 6: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

int A=50;int *P;

P=&A;cout<< *P; // Imprime 50*P=100;cout<< *P; // Imprime 100 cout<< A; // Imprime 100

Page 7: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Paso de argumentos por referencia

• Con este método la función recibe las direcciones de las variables sobre las cuales se va a operar

• Por lo tanto la función puede cambiar los valores de dichas variables usando el operador *

• Veamos un ejemplo:

Page 8: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Sea la función sumap:

int sumap(int *a, int *b, int c) {

c = *a + *b;/*Dentro de la función, a y b son dos

variables locales de tipo puntero a int*/*a = c;*b = c;return c;

}

Page 9: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

void main(){

int a=3;int b=2;int c=0;int r=0;r=sumap( &a, &b, c );

cout<<”Valores finales: \n“; cout<<”a=”<<a; // Imprime 5 cout<<”b=”<<b; // Imprime 5 cout<<”c=”<<c; // Imprime 0 cout<<”r=”<<r; // Imprime 5}

Page 10: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Aritmética de punteros

• Sobre los punteros es posible sumar y restar números enteros, estas operaciones se usan para cambiar el lugar de la memoria al que apunta el puntero

• La aritmética de punteros tiene en cuenta el tamaño de la variable apuntada.

• Las operaciones sobre punteros deben usarse con precaución, ya que al cambiar indiscriminadamente los lugares de la memoria a los que se apunta se pueden sobrescribir accidentalmente otros datos

Page 11: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

void main(){ int a=654; int *p;

p=&a; p++; cout<< *p << "y" << *(p-1); // Imprimió: 1245120 y 654 }

Page 12: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Arreglos

• El identificador (o nombre) de un arreglo siempre se refiere a la dirección del primer elemento

• Para crear un puntero a un arreglo, simplemente se declara una variable puntero al tipo de los elementos del arreglo

• Este puntero puede ser acompañado de +i para acceder al elemento i del arreglo

Page 13: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Figura 1.4: arreglos y punteros

50 A

[0001]

50

[0003]

50

[0005]

50

[0007]

int *p1; int *p2; int *p3; p1=A; //Dir. ele 1 p2=&p1[1]; //Dir. ele 2 p3=p1+3; //Dir. ele 4

0001 p1

[0023]

0003 p2

[0345]

0007 p3

[0090]

0 1 2 3

Dirección de p1

Las siguientes expresiones son equivalentes:(p1 +3) , (A + 3) y (&p1[3])

A

p1 p2 p3

Page 14: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Recorrido de un vector usando punteros:

void main(){

int A[]={2, 5, 87, 21, 34}; int *p;

p=A;for(int i=0; i<5; i++){

cout<<"Elemento "<<i<<"="<<*p<<"\n";

p++;}

}

Page 15: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Memoria dinámica

• La memoria dinámica (heap) permite a los programas pedir y liberar espacio de memoria durante su ejecución a medida que lo necesiten

• Las variables asignadas dinámicamente, residen en el heap, no están sujetas a las reglas de duración vistas en el módulo anterior

• Útil para declarar el tamaño de arreglos en tiempo de ejecución

Page 16: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

• La función malloc() reserva un espacio de memoria de tamaño dado en el heap y retorna un puntero a dicho espacio (si no había memoria suficiente, retorna NULL) • malloc() utiliza la siguiente sintaxis:

puntero = ( tipo_de_variable * ) malloc ( numero_de_bytes );

• Se requiere incluir stdlib.h• Veamos un ejemplo:

Page 17: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

int *crear_arreglo(int n){

int *p;p=(int *)malloc( n*sizeof(int) );for(int i=0; i<n; i++){ p[i]=1;

}return p;

}void main(void){ int *a; a=crear_arreglo(4); free(a); //Liberar espacio reservado}

Page 18: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

• La función free() libera un espacio de memoria reservado mediante malloc(), no retorna nada y utiliza la siguiente sintaxis:

free( direccion );

• También se puede usar en vez de malloc() la función new() así:puntero= new tipo_de_dato [n];

Page 19: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

El mismo programa anterior hecho con new():

int *crear_arreglo_new(int n){

int *p;p= new int[n];for(int i=0; i<n; i++)

p[i]=1;return p;

}

Page 20: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Recursión

• Un algoritmo es recursivo si se encuentra definido en términos de sí mismo

• Es posible que una función se llame a sí misma, para ello basta con invocarse dentro de la función a ella misma y pasarle los argumentos correspondientes.

• A este tipo de función la denominamos “recursiva”

Page 21: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

Ejemplo: El factorial de un número N sedefine como:

Si N 0 entonces: N! =N*(N-1)! Si N=0 entonces: N! =1

Veamos como programar esta función en C++ recursivamente Es natural hacerlo de manera debido a que la función se define en términos de si misma

Page 22: Estructuras de Datos Punteros y algo más. Un puntero es una variable que almacena la dirección de memoria de otra variable Para obtener la dirección de.

int factorial(int n){

if(n==0) return 1;else return (n*factorial(n-1));

}

void main(){

int a;a=factorial(3);

}

Vamos a realizarle un seguimiento manualmente para ver como evoluciona esta función en el Stack…