180 likes | 400 Views
PUNTEROS Y REFERENCIAS. Ing. Betty Suárez Torres. Un puntero es una variable como cualquier otra, contiene una dirección que apunta a otra posición en memoria, en esa posición se almacenan los datos a los que apunta el puntero, es decir, un puntero apunta a una variable de memoria
E N D
PUNTEROS Y REFERENCIAS Ing. Betty Suárez Torres
Un puntero es una variable como cualquier otra, contiene una dirección que apunta a otra posición en memoria, en esa posición se almacenan los datos a los que apunta el puntero, es decir, un puntero apunta a una variable de memoria Declaración de punteros Al igual que cualquier variable, las variables punteros han de ser declaradas antes de utilizarlas. La declaración de una variable puntero debe indicar al compilador el tipo de dato al que apunta el puntero; para ello se hace preceder a su nombre con un asterisco (*), mediante el siguiente formato: <tipo de dato apuntado> *<identificador de puntero> Algunos ejemplos de variables punteros: int* ptrl; //Puntero a un tipo de dato entero (int) long* ptr2; //Puntero a un tipo de dato entero largo (long int) char* ptr3; //Puntero a un tipo de dato char float *f; //Puntero a un tipo de dato float CONCEPTOS BÁSICOS
La inicialización de un puntero proporciona a ese puntero la dirección del dato correspondiente. Después de la inicialización, se puede utilizar el puntero para referenciar los datos direccionados. Para asignar una dirección de memoria a un puntero se utiliza el operador de referencia &. por ejemplo: &valor significa «la dirección de valor». El método de inicialización (iniciación), también denominado estático, requiere: Asignar memoria (estáticamente) definiendo una variable y a continuación hacer que el puntero apunte al valor de la variable. int i; //define una variable i int *p; //define un puntero a un entero p p = &i; //asigna la dirección de i a p Asignar un valor a la dirección de memoria: *p = 50 El asterisco delante de la variable puntero indica «e/ contenido de de la memoria apuntada por el puntero y será del tipo dado. No se puede liberar la memoria reservada para una variable. El puntero a esa variable se puede cambiar, pero permanecerá la cantidad de memoria reservada. INICIALIZACIÓN DE PUNTEROS
&<var> devuelve la dirección de memoria donde empieza la variable <var>. El operador & se utiliza habitualmente para asignar valores a datos de tipo puntero. int i, *ptri; ptri = &i; i es una variable de tipo entero, por lo que la expresión &i es la dirección de memoria donde comienza un entero y, por tanto, puede ser asignada al puntero ptri. Se dice que ptri apunta o referencia a i. OPERADOR DE DIRECCIÓN &
*<puntero> devuelve el contenido del objeto referenciado por <puntero>. char c, *ptrc; ptrc = &c; *ptrc = ’A’; // equivalente a c = ’A’ ptrc es un puntero a caracter que contiene la dirección de c, por tanto, la expresión *ptrc es el objeto apuntado por el puntero, es decir, c. Un puntero contiene una dirección de memoria y se puede interpretar como un número entero aunque un puntero no es un número entero. No obstante existen un conjunto de operadores que se pueden realizar sobre un puntero: +,-,++,–, !=, == OPERADOR DE INDIRECCIÓN *
#include <stdio.h> #include <conio.h> char c; //variable global de tipo carácter void main(){ char *pc; //un puntero a una variable carácter*/ pc = &c; for (c='A';c<='Z';c++){ printf ("%c",*pc) ; } getch();} La ejecución de este programa visualiza el alfabeto. La variable puntero pc es un puntero a una variable carácter. La línea pc = &c asigna a pc la dirección de la variable c (&c) . El bucle for almacena en c las letras del alfabeto y la sentencia print f ( "%c" , *pc ) ; visualiza el contenido de la variable apuntada por pc. EJEMPLO
Asignar puntero de distinto tipo int a=10, *ptri; float b=5.0, *ptrf; ptri = &a; ptrf = &b; ptrf = ptri; // Error en compilación Uso de punteros no inicializados Es un error asignar un valor, a un contenido de una variable puntero si previamente no se ha inicializado con la dirección de una variable, o bien se le ha asignado dinámicamente memoria (malloc / new). Por ejemplo: float* px; *px = 23.5; //error, px no contiene dirección Asignación de valores al puntero y no a la variable. int y=5, *nptr =&y; //CORRECTO nptr = 9; //ERROR ERRORES COMUNES
#include <stdio.h> void main(){ int n = 75; //visualiza el valor de n printf("n= %d\n",n) ; //visualiza dirección de n printf("&n= %p\n",&n); } EJEMPLO Ejecución n = 45 &n = Ox4fffd34 0x4 f f f d3 4 es una dirección en código hexadecimal. “Ox" es el prefijo correspondiente al código hexadecimal.
#include <stdio.h> #include <conio.h> void main(){ int n = 75; //*p variable puntero, tiene dirección de n int* p = &n; printf("n = %d, &n = %p, p = %p\n",n,&n,p); printf ("&p = %p\n",&p); getch(); } 0012FF70 0012FFF6C n 0012FFF6C p 75 int * int EJEMPLO EJECUCIÓN n= 75, %p= 0012FFF6C, p= 0012FFF6C, &p= 0012FF70
ARREGLOS Y PUNTEROS Un nombre de un array es simplemente un puntero. Supongamos que se tiene la siguiente declaración de un array: int lista[5] = {10, 20, 30, 40, 50}; lista + 0 lista[0] (*lista) lista + 1 lista[1] lista lista + 2 lista[2] lista + 3 lista[3] lista + 4 lista[4]
int v[0] ; int *p; p = v; (v+4); //apunta al 5" elemento p = p+6; //contiene la dirección del 7º elemento A una variable puntero se le puede aplicar el operador ++, o el operador - - . Esto hace que contenga la dirección del siguiente o anterior elemento: float m[20]; float *r; r = m; r++; //contiene la dirección del elemento siguiente EJEMPLO
Los punteros se pueden utilizar en lugar de índices de arrays. Ejemplo: char alfabeto [27] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Declaremos ahora p un puntero a char char *p; Se establece que P apunta al primer carácter de alfabeto escribiendo p = &alfabeto[0]; //o también p = alfabeto de modo que si escribe la sentencia printf("%c \n", *p) ; se visualiza la letra A, ya que p apunta al primer elemento de la cadena. Se puede hacer también p = alfabeto[15]; de modo que p apuntará al carácter 16º (la letra Q). Sin embargo, no se puede hacer p = &alfabeto; ya que alfabeto es un array cuyos elementos son de tipo char, y se produciría un error al compilar (tipo de asignación es incompatible). PUNTEROS A CADENAS
Cuando se pasa una variable a una función (paso por valor) no se puede cambiar el valor de esa variable. Sin embargo, si se pasa un puntero a una variable a una función (paso por direccición) se puede cambiar el valor de la variable. Ejemplo: Considere la siguiente definición de la función incrementar que incrementa una variable en 5. void Incrementar(int *i){ *i += 5; } La llamada a la función será: int i; i = 10; Incrementar(&i) ; PUNTEROS COMO ARGUMENTOS
struct temperatura{ float alta; float baja ; }; void registrotemp(struct temperatura *t){ float actual ; leertempactual(actual); if (actual > t -> alta) t - > alta = actual; else if (actual < t -> baja) t -> baja = actual; } La llamada a la función sería: struct temperatura tmp; registrotemp(&tmp); EJEMPLO CON STRUCT
#include <stdio.h> #include <conio.h> struct persona{ char nombre [30]; int edad; float altura; int peso; }; typedef struct persona persona; void mostrar_persona(persona *ptr); void main(){ int i; persona empleados [ ] = {{"Juan Perez", 47, 1.82, 85},{"Luis García", 39, 1.70, 75},{"Tomás Jimenez",18, 1.75, 80}} ; persona *p; //puntero a estructura p = empleados; for (i = 0; i < 3;i++, p++){ mostrar_persona(p); } getch();} EJEMPLO void mostrar_persona(persona *ptr){ printf ("\nNombre : %s\n",ptr -> nombre) ; printf ("\tEdad: %d\n", ptr -> edad); printf ("\tAltura: %f\n",ptr -> altura) ; printf ("\tPeso: %d\n",ptr -> peso); }
Encuentra los errores en la siguiente declaración de punteros: int x, *p, &y; char *b = “Cadena larga”; char* c= ‘C’; float x; void *r = &x; EVALUACIÓN