Sei sulla pagina 1di 12

Instituto Politcnico Nacional Escuela Superior de Ingeniera Mecnica y Elctrica Programacin orientada a objetos Murillo Hernndez Jess Eduardo

Rodrguez Rosas Edgar Alejandro 2AM4 Punteros o Apuntadores

ndice
Beneficios y dificultades.3 Apuntadores en Lenguaje C..3 Definicin de Apuntador.....3 Declaracin de Apuntador..4 Parmetros de Funciones..4 Grficamente4 Reglas5 Apuntadores y Funciones..6 Arreglos de apuntadores6 Fallas comunes con apuntadores7 Apuntadores: Operaciones Bsicas...9 Programas10

Beneficios:
1) Generar elementos bajo demanda, i.e. asignacin dinmica de memoria 2) Manipular y recorrer grandes espacios de memoria 3) Generar estructuras de datos complejas 4) Parmetros de entrada/salida para funciones, i.e. parmetros por referencia

Dificultades:
1) Programacin avanzada, catica y/o complicada 2) Programacin ms susceptible de errores muy difciles de depurar 3) Dificultad para leer y comprender cdigo

Apuntadores en Lenguaje C
C usa los apuntadores en forma extensiva. Porqu? Es la nica forma de expresar algunos clculos. Se genera cdigo compacto y eficiente. Es una herramienta muy poderosa. C usa apuntadores explcitamente con: Arreglos, Estructuras y Funciones

Definicin de Apuntador
Un apuntador es una variable que contiene la direccin en memoria de otra variable. Se pueden tener apuntadores a cualquier tipo de variable. El operador unario & devuelve la direccin de memoria de una variable. El operador de indireccin o de referencia * devuelve el ``contenido de un objeto apuntado por un apuntador''.

Declaracin de Apuntador
Para declarar un apuntador para una variable entera hacer: int *apuntador; Se debe asociar a cada apuntador un tipo particular. Por ejemplo, no se puede asignar la direccin de un short int a un long int.

Parmetros de Funciones
Por valor: Se le pasa a la funcin una copia del valor (Se crea otra variable con el mismo valor) Por referencia: Se le pasa la direccin de memoria donde se encuentra el valor original

Grficamente

Entonces:

Reglas
Para trabajar con apuntadores tenemos las siguientes reglas: 1) Un apuntador antes de utilizarse, debe inicializarse hacia alguna direccin de memoria, por lo general es una direccin donde se encuentra una variable. 2) Un apuntador nicamente almacena direcciones a diferencia de las variables que almacenan valores. 3) Un apuntador solo puede apuntar a una sola direccin en un instante de tiempo. La direccin a la que se apunta el apuntador, generalmente representa la ubicacin de una variable. 4) Varios apuntadores si pueden apuntar a la misma direccin de memoria. 5) Aunque no siempre, un apuntador debe apuntar al mismo tipo de dato con el cual fue declarado

Apuntadores y Funciones
Cuando C pasa argumentos a funciones, los pasa por valor, es decir, si el parmetro es modificado dentro de la funcin, una vez que termina la funcin el valor pasado de la variable permanece inalterado. Hay muchos casos que se quiere alterar el argumento pasado a la funcin y recibir el nuevo valor una vez que la funcin ha terminado. Para hacer lo anterior se debe usar una llamada por referencia, en C se puede simular pasando un puntero al argumento. Con esto se provoca que la computadora pase la direccin del argumento a la funcin. Para entender mejor lo anterior consideremos la funcin swap() que intercambia el valor de dos argumentos enteros: void swap(int *px, int *py); main() { int x, y; x = 10; y = 20; printf("x=%d\ty=%d\n",x,y); swap(&x, &y); printf("x=%d\ty=%d\n",x,y); } void swap(int *px, int *py) { int temp; temp = *px; /* guarda el valor de la direccion x */ *px = *py; /* pone y en x */ *py = temp; /* pone x en y */ }

Arreglos de apuntadores
En C se pueden tener arreglos de apuntadores ya que los apuntadores son variables. Los arreglos de apuntadores son una representacin de datos que manejan de una forma eficiente y conveniente lneas de texto de longitud variable. Cmo se puede hacer lo anterior? 1. Guardar todas las lneas en un arreglo de tipo char grande. Observando que \n marca el fin de cada lnea. Ver figura 8.1. 2. Guardar los apuntadores en un arreglo diferente donde cada apuntador apunta al primer carcter de cada lnea.

3. Comparar dos lneas usando la funcin de la biblioteca estndar strcmp(). 4. Si dos lneas estn desacomodadas -- intercambiar (swap) los apuntadores (no el texto).

Figura 8.1: Arreglos de apuntadores (Ejemplo de ordenamiento de cadenas). Con lo anterior se elimina:

el manejo complicado del almacenamiento. alta sobrecarga por el movimiento de lnea.

Fallas comunes con apuntadores


A continuacin se muestran dos errores comunes que se hacen con los apuntadores.

No asignar un apuntador a una direccin de memoria antes de usarlo int *x *x = 100;

lo adecuado ser, tener primeramente una localidad fsica de memoria, digamos int y; int *x, y; x = &y; *x = 100;

Direccin no vlida

Supongamos que se tiene una funcin llamada malloc() la cual trata de asignar memoria dinmicamente (en tiempo de ejecucin), la cual regresa un apuntador al bloque de memoria requerida si se pudo o un apuntador a nulo en otro caso. char *malloc() -- una funcin de la biblioteca estndar Supongamos que se tiene un apuntador char *p Considerar: *p = (char *) malloc(100): *p = 'y'; Existe un error en el cdigo anterior. Cul es? El * en la primera lnea ya que malloc regresa un apuntador y *p no apunta a ninguna direccin. El cdigo correcto deber ser: p = (char *) malloc(100); /* pide 100 bytes de la memoria */

Ahora si malloc no puede regresar un bloque de memoria, entonces p es nulo, y por lo tanto no se podr hacer: *p = 'y'; Un buen programa en C debe revisar lo anterior, por lo que el cdigo anterior puede ser reescrito como: p = (char *) malloc(100): /* pide 100 bytes de la memoria */

if ( p == NULL ) { printf("Error: fuera de memoria\n"); exit(1); } *p = 'y';

Apuntadores: Operaciones Bsicas

Programas
//Este programa ilustra punteros #include<stdio.h> int funVal(int,int); int funRef(int*,int*);

int main(){ int a,b,c; printf("\t\t\t\tP12ValRef.c"); printf("\n\t\t\tIlustra punteros"); printf("\n\t\t\t________________"); a= 5; b= 10; c= 0; printf("\n\nEn main: a=%d\tb=%d\tc=%d",a,b,c); printf("\nDirecciones:a=%p\tb=%p\tc=%p",&a,&b,&c); c=funVal(a,b); printf("\n\nEn main: a=%d\tb=%d\tc=%d",a,b,c); printf("\nDirecciones:a=%p\tb=%p\tc=%p",&a,&b,&c); c=funRef(&a,&b); printf("\n\nEn main: a=%d\tb=%d\tc=%d",a,b,c); printf("\nDirecciones:a=%p\tb=%p\tc=%p",&a,&b,&c); return 0; }

10

int funVal(int aa, int bb){

printf("\n\n En funVal: a=%d\tb=%d",aa,bb); printf("\nDirecciones:a=%p\tb=%p",&aa,&bb); aa=aa*2; bb=bb*2; printf("\n\n En funVal final: a=%d\tb=%d",aa,bb); printf("\nDirecciones:a=%p\tb=%p",&aa,&bb); return aa*bb; } int funRef(int *x, int *y){ printf("\n\n En funRef: a=%d\tb=%d",*x,*y); printf("\nDirecciones:a=%p\tb=%p",x,y); *x=*x*3; *y=*y*3; printf("\n\n En funRef: a=%d\tb=%d",*x,*y); printf("\nDirecciones:a=%p\tb=%p\n\n",x,y); system("pause"); return *x*(*y); }

11

//Este programa utiliza punteros para imprimir Los Datos en Memoria: sizeof() #define TYPES 8 int main() { char *tipo[TYPES] = { "char", "short", "int", "long", "float", "double", "long double", "void *" }; int i, tam[TYPES] = { sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(float), sizeof(double), sizeof(long double), sizeof(void *) }; printf("| Tipo-Dato | Bytes |\n"); printf("|-------------|-------|\n"); for (i=0; i<TYPES; i++) printf("| %11s | %2d b. |\n", tipo[i], tam[i]); printf("|-------------|-------|\n"); system("pause"); }

12

Potrebbero piacerti anche