Вы находитесь на странице: 1из 38

Repaso Programacin II

Semestre B-2011 Clase 02

Yaneth Moreno Caldera

Punteros
Un puntero es un tipo especial de objeto que contiene, ni ms ni menos que, la direccin de memoria de un objeto (un char, un int, un float, un array, una estructura, una funcin u otro puntero)

NOTA: no usar jams un puntero que no haya sido inicializado correctamente.

Punteros

Punteros
Declaracin de punteros Sintaxis C++ <tipo> *<identificador>;

<tipo>* <identificador>;

<tipo> * <identificador>;

Punteros
Declaracin de punteros Ejemplos int *pEntero; char *pCaracter; struct stPunto *pPunto;

Punteros
Declaracin de punteros Si se declaran en la misma lnea varios objetos: int* x, y; int* x, *y; // O: int *x, *y; // O: int* x; int* y;

Punteros
Obtener punteros a objetos Los punteros apuntan a objetos, por lo tanto, lo primero que tenemos que saber hacer con nuestros punteros es asignarles direcciones de memoria vlidas de objetos. Para averiguar la direccin de memoria de cualquier objeto usaremos el operador de direccin (&), que leeremos como "direccin de". int A; int *pA; pA = &A;

Punteros
Objeto apuntado por un puntero La operacin contraria es obtener el objeto referenciado por un puntero, con el fin de manipularlo, ya sea modificando su valor u obteniendo el valor actual.Para manipular el objeto apuntado por un puntero usaremos el operador de indireccin, que es un asterisco (*). int *pEntero; int x = 10; int y; pEntero = &y; *pEntero = x; // (1)

Punteros
Correspondencia entre arrays y punteros Declaramos un puntero del mismo tipo que los elementos del array.

Reservamos memoria para todos los elementos del array. Los elementos de un array se almacenan internamente en la memoria del ordenador en posiciones consecutivas.

Se inicializa el puntero de modo que apunte al primer elemento del array.

Punteros
Diferencias entre un array y un puntero

Que el identificador de un array se comporta como un puntero constante, es decir, no podemos hacer que apunte a otra direccin de memoria. Que el compilador asocia, de forma automtica, una zona de memoria para los elementos del array, cosa que no hace para los elementos apuntados por un puntero corriente.

Punteros
Ejemplo
int vector[10]; int *puntero;

puntero = vector; /* Equivale a puntero = &vector[0]; esto se lee como "direccin del primer elemento de vector" */ (*puntero)++; puntero++; &vector[1] (3)*/ /* Equivale a vector[0]++; (2) */ /* puntero equivale a asignar a puntero el valor

Punteros
Otro Ejemplo
struct stComplejo { float real, imaginario; } Complejo[10]; stComplejo *pComplejo; /* Declaracin de un puntero */

pComplejo = Complejo; /* Equivale a pComplejo = &Complejo[0]; */ pComplejo++; /* pComplejo == &Complejo[1] */

Punteros
El siguiente Ejemplo tambin es vlido:
int vector[10]; int *puntero;

puntero = &vector[5]; puntero[-2] = puntero[2] = 100;

Punteros
Las siguientes expresiones son equivalentes:
*(puntero + 7); puntero[7];

El siguiente Ejemplo tambin es vlido:


int vector[10]; int *puntero;

puntero = &vector[5]; puntero[-2] = puntero[2] = 100;

Punteros
Operaciones con Punteros Asignacin
int *q, *p; int a;

q = &a; /* q apunta a la direccin de a */ p = q; /* p apunta al mismo sitio, es decir, a la direccin de a */ 0;

Punteros
Operaciones con Punteros Aritmticas
int vector[10]; int *p, *q;

p = vector; /* Equivale a p = &vector[0]; */ q = &vector[4]; /* apuntamos al 5 elemento */ cout << q-p << endl;

Punteros
Operaciones con Punteros Comparaciones
if(NULL != p) if(p) if(NULL == p) if(!p) Nota: No es posible comparar punteros de tipos diferentes, ni aunque ambos sean nulos.

Punteros
Punteros Genricos
void *<identificador>;

Casting con Punteros:


(<tipo> *)<variable puntero>

Punteros
Ejemplo
#include <iostream> using namespace std; int main() { char cadena[10] = "Hola"; char *c; int *n; void *v; } c = cadena; // c apunta a cadena n = (int *)cadena; // n tambin
apunta a cadena
Resultado: carcter: H entero: 1634496328 float: 2.72591e+20

c = cadena; // c apunta a cadena n = (int *)cadena; // n tambin apunta


a cadena

v = (void *)cadena; // v tambin cout << "carcter: " << *c << endl; cout << "entero: " << *n << endl; cout << "float: << endl; return 0; " << *(float *)v

Punteros
Punteros a Estructuras

Los punteros tambin pueden apuntar a estructuras. En este caso, para referirse a cada elemento de la estructura se usa el operador (->), en lugar del (.).

Punteros
Ejemplo
#include <iostream> using namespace std; struct stEstructura { int a, b; } estructura, *e; int main() { estructura.a = 10; estructura.b = 32; e = &estructura; cout << "puntero" << endl; cout << e->a << endl; cout << e->b << endl; cout << "objeto" << endl; cout << estructura.a << endl; cout << estructura.b << endl; return 0; }

Punteros
Ejemplo
#include <iostream> using namespace std; cout << cadena1[1] << endl; cout << cadena2[0] << endl; cout << cadena1 + 2 << endl; cout << cadena2 + 1 << endl;

int main() { char cadena1[] = "Cadena 1"; char *cadena2 = "Cadena 2"; cout << *(cadena1 + 2) << endl; cout << *(cadena2 + 1) << endl; cout << cadena1 << endl; cout << cadena2 << endl; /*cadena1++; Ilegal, cadena1 es constante*/ cadena2++; /* Legal, cadena2 es un puntero*/ cout << cadena1 << endl; cout << cadena2 << endl; return 0; }

Punteros
Objetos dinmicos New y Delete C++ dispone de dos operadores para manejar (reservar y liberar) la memoria dinmica, son new y delete. En C estas acciones se realizan mediante funciones de la biblioteca estndar stdio. Hay una regla de oro cuando se usa memoria dinmica: toda la memoria que se reserve durante el programa hay que liberarla antes de salir del programa. No seguir esta regla es una actitud muy irresponsable, y en la mayor parte de los casos tiene consecuencias desastrosas. No se fen de lo que diga el compilador, de que estas variables se liberan solas al terminar el programa, no siempre es verdad.

Punteros
Ejemplo
#include <iostream> using namespace std; int main() { int *a; char *b; float *c; struct stPunto { float x,y; } *d; a b c d = = = = new new new new int; char; float; stPunto; } *a = 10; *b = 'a'; *c = 10.32; d->x = 12; d->y = 15; cout cout cout cout << << << << << "a = "b = "c = "d = d->y a; b; c; d; " << *a << endl; " << *b << endl; " << *c << endl; (" << d->x << ", " << ")" << endl;

delete delete delete delete

return 0;

Y mucho cuidado: si pierdes un puntero a una variable reservada dinmicamente, no podrs liberarla.

Punteros
Ejemplo
int main() { int *a; a = new int; // variable dinmica *a = 10; a = new int; // nueva variable dinmica, // se pierde el puntero a la anterior *a = 20; delete a; // slo liberamos la ltima reservada return 0; }

Punteros
Ejercicio
De qu tipo es cada una de las siguientes variables?:
a) int* a,b; a puntero, b puntero a puntero, b entero a entero, b puntero a entero, b entero b) int *a,b; a puntero, b puntero a puntero, b entero a entero, b puntero a entero, b entero c) int *a,*b; a puntero, b puntero a puntero, b entero a entero, b puntero a entero, b entero

d) int* a,*b; a puntero, b puntero a puntero, b puntero doble a entero, b puntero a entero, b puntero doble

Punteros
Ejercicio
Considerando las siguientes declaraciones y sentencias: int array[]={1,2,3,4,5,6}; int *puntero; puntero = array; puntero++; a) Cul es el valor de x? *puntero=*puntero+6; 1 puntero=puntero+3; 2 puntero=puntero-puntero[-2]; 3 int x=puntero-array;

b) Cual array[1]? 2 4 6 8

es

el

valor

de

Punteros
Ejercicio
3) Considerando la siguiente declaracin: struct A { struct { int x; int y; } campoB; } *estructuraA; a) Cmo se referenciara el campo x de la estructuraA? estructuraA.x estructuraA.campoB.x estructuraA.campoB->x estructuraA->campoB.x

Punteros
Ejercicio Propuesto
Escribir un programa con una funcin que calcule la longitud de una cadena de caracteres. El nombre de la funcin ser LongitudCadena, debe devolver un int, y como parmetro de entrada debe tener un puntero a char. En esta funcin no se pueden usar enteros para recorrer el array, usar slo punteros y aplicar aritmtica de punteros. En main probar con distintos tipos de cadenas: arrays y punteros.

Punteros
Ejercicio
// Programa que invierte el orden de un vector #include <iostream> using namespace std; void Mostrar(int*, int); void Intercambia(int*, int*); int main() { int vector[10] = { 2,5,6,7,9,12,35,67,88,99 }; int *p, *q; Mostrar(vector, 10); // Mostrar estado inicial p = vector; // Primer elemento q = &vector[9]; // Ultimo elemento while(p < q) { // Bucle de intercambio Intercambia(p++, q--); Mostrar(vector, 10); // Mostrar estado final return 0; } void Mostrar(int *v, int n) { int *f = &v[n]; // Puntero a posicin siguiente al ltimo elemento while(v < f) { cout << *v << " "; v++; } cout << endl; } void Intercambia(int *p, int *q) { // Intercambiar sin usar variables auxiliares: *p += *q; *q = *p-*q; *p -= *q;

}
}

Punteros
Ejercicio Propuesto Mezclar dos vectores ordenados en otro, de modo que tambin est ordenado, como en el caso anterior usaremos slo punteros, sin variables auxiliares enteras.
1 2 3 4 5 8 10 12 1 3 5 8 2 4 10 12

Punteros
Operadores de referencia(&) e Indireccin(*) Sintaxis: &<expresin simple> Ejemplo: int *punt; int x = 10; punt = &x; Sintaxis: *<puntero> Ejemplo: int *punt; int x; x = *punt;

Punteros
Operadores de seleccin(.) e Indireccin(->)
Sintaxis: <variable_estructura>.<nombre_de_variable>

Sintaxis: <puntero_a_estructura>-><nombre_de_variable>

Punteros
Ejemplo:
struct punto { int x; int y; }; punto p1; punto *p2; p1.x = 10; p1.y = 20; p2->x = 30; p2->y = 40;

Punteros
Puntero a Puntero Sintaxis: <tipo> **<identificador> Ejemplo: int **tabla;

Punteros
Ejemplo de Tabla dinmica int **tabla;
/*"tabla" es un puntero que apunta a un objeto de tipo puntero a int. */

int n = 134; tabla = new int*[n];


//"tabla" apunta a un array de punteros a int

int m = 231; for(int i = 0; i < n; i++) tabla[i] = new int[m];


/*Ahora tabla apunta a un array de dos dimensiones de n , m */

Punteros
Ejemplo de Tabla dinmica tabla[21][33] = 123;
/*Accedemos regular */ igual que como lo haramos en un array

for(int i tabla[i];

0;

<

n;

i++)
hay que

delete[]
liberar la

/*antes de abandonar el memoria dinmica usad*/

programa

delete[] tabla;];

Punteros
Ejemplo de Tabla dinmica
#include <iostream> using namespace std; int main() { int **tabla; int n = 134; int m = 231; int i; // Array de punteros a int: tabla = new int*[n]; // n arrays de m ints for(i = 0; i < n; i++) tabla[i] = new int[m]; tabla[21][33] = 123; cout << tabla[21][33] << endl; // Liberar memoria: for(i = 0; i < n; i++) delete[] tabla[i]; delete[] tabla; return 0; }