Your SlideShare is downloading. ×
Introducción a los Punteros en el lenguaje C
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Introducción a los Punteros en el lenguaje C

134
views

Published on

Presentamos una introducción al concepto de puntero y su uso con el lenguaje C.

Presentamos una introducción al concepto de puntero y su uso con el lenguaje C.

Published in: Education

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
134
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Facultad de Informática, Electrónica y Comunicación Estructuras de datos -Inf200 e Inf212 Apuntadores Diego Santimateo G. / Giannina Núñez M. 1 Punteros o apuntadores o pointers Un puntero es una variable que contiene una dirección de memoria. Normalmente, esa dirección es la posición de otra variable en la memoria. Si la variable p de tipo float, está en la dirección 1111 y la variable ptr en la dirección 1021, entonces, si el contenido de ptr es la dirección de p, es decir 1111, decimos que ptr es un apuntador a p. Algunas consideraciones para utilizar punteros o apuntadores:  Existen dos operadores especiales de punteros: & y *. El operador de dirección (&) devuelve la dirección de memoria de su operando. El operador de indirección (*) devuelve el contenido de la dirección apuntada por el operando.  Los punteros apuntan a un tipo de variable, el cual se define en la declaración, por ejemplo;  int *ptr1; /* apunta solo a variables tipo int */  float *ptr; /* apunta solo a variables tipo float */  char *prt2; /* apunta solo a variable tipo char */  El operador de dirección & delante del nombre de una variable nos devuelve la dirección de la variable, ejemplo;  int a; ptr1 = &a;  float p, q; ptr = &p;  El valor apuntado por un puntero se obtiene con el operador de indirección *. Si usamos la ilustración anterior *ptr corresponde al valor 45.23 de la variable p. Si hacemos q = *ptr; entonces q y p tienen el mismo valor, pero ptr no apunta a q, sino a p.  En conclusión, si ptr contiene la dirección de memoria de la variable p, entonces ptr apunta a p y *ptr indica el contenido de p, es decir, cuando se modifica o cambia el valor de *ptr se cambia también el valor de la variable p. Concretamente si hacemos *ptr = 100; entonces, el valor de la variable p también es 100. Todo esto se da porque ptr a punta a p o de manera equivalente, porque ptr contiene la dirección de p. De manera general una declaración de un puntero consiste en un tipo base(int, char, flotat), un asterisco * y el nombre de la variable. La forma general es: tipo *nombre_de _variable; Se pueden declarar apuntadores a una estructura: typedef struct { int edad; float salario; /* declaración de tipo estructura global */ char nom[15]; }xxx; xxx *ptr3; /* apuntador al tipo de estructura xxx */ 1111 1021 45.23 1111ptr p
  • 2. Facultad de Informática, Electrónica y Comunicación Estructuras de datos -Inf200 e Inf212 Apuntadores Diego Santimateo G. / Giannina Núñez M. 2 Asignación de punteros Como en el caso de cualquier otra variable, un puntero puede utilizarse a la derecha de una declaración de asignación para asignar su valor a otro puntero. Por ejemplo: int x; int *p1,*p2; p1=&x; p2=p1; Tanto p1 como p2 apuntan a x. Operaciones con punteros Existen sólo dos operaciones aritméticas que se pueden usar con punteros: la suma y la resta. Cada vez que se incrementa en una unidad un puntero, apunta a la posición de memoria del siguiente elemento de su tipo base(int, flota, char). Cada vez que se disminuye en una unidad, apunta a la posición del elemento anterior. Con punteros a variables del tipo char(un byte) parece una aritmética normal, sin embargo, el resto de los punteros aumentan o decrecen dependiendo de la longitud del tipo de datos a los que apuntan, piense en el tamaño de un registro. Por ejemplo, si asumimos que los enteros son de dos bytes de longitud y p1 es un puntero a entero con valor actual 2000. Entonces, después de la expresión p1++; p1 contiene el valor 2002, no 2001. Las variables punteros pueden ser comparadas siempre que éstas apunten a un mismo tipo de datos, por ejemplo; Int *ptr1, *ptr2; Podemos usar las siguientes expresiones lógicas:  ptr1 < ptr2 ptr2 >= ptr1  ptr1 == ptr2 ptr2 != ptr1  ptr == NULL Punteros y arrays Existe una estrecha relación entre los punteros y los arreglos. Recuerde que el nombre de un arreglo se considera puntero a la primera posición. char linea[80], *prt2; prt2 = linea; Aquí, prt2 ha sido asignado a la dirección del primer elemento del vector linea. Para acceder al quinto elemento de linea se escribe linea[4] o *(prt2 + 4). Los punteros pueden almacenarse en arreglos como cualquier otro tipo de datos. Por ejemplo, para un arreglo de 10 punteros a tipo entero, la declaración es: int *x[10]; Para asignar la dirección de una variable entera llamada var al tercer elemento de x se escribe: x[2] = &var; El valor de la variable var corresponde a *x[2];(valor que es apuntado por x[2]). Indirección múltiple Se puede hacer que un puntero apunte a otro puntero que apunte a un valor de destino. Esta situación se denomina indirección múltiple o punteros a punteros. Una variable que es puntero a puntero tiene que declararse como tal. Esto se hace colocando un asterisco (*) adicional en frente del nombre de la variable. Por ejemplo, la siguiente declaración indica al compilador que ptr es un puntero a puntero de tipo float: float **ptr; Funciones de asignación dinámica, malloc() y free() Hasta el momento hemos trabajado con estructuras de datos estáticas, no obstante los punteros proporcionan el soporte necesario para manejar estructuras de datos dinámica en C. La asignación dinámica es la forma en la que un programa puede obtener memoria mientras se está ejecutando y también puede liberarla cuando sea necesario.
  • 3. Facultad de Informática, Electrónica y Comunicación Estructuras de datos -Inf200 e Inf212 Apuntadores Diego Santimateo G. / Giannina Núñez M. 3 El centro del sistema de asignación dinámica está compuesto por las funciones (existentes en la biblioteca stdlib.h)  malloc(), que asigna memoria y devuelve un puntero a un char.  free() que la devuelve o la libera. Podemos invocar a la función malloc() así: ptr =malloc( n * sizeof(tipo de dato)); Tras una llamada fructífera, malloc() devuelve un puntero a un caracter, de manera que en el ejemplo, la declaración de ptr es char *ptr. Si no hay suficiente memoria libre para satisfacer la petición de malloc(), se devuelve el apuntador nulo. En el siguiente código se asigna en tiempo de ejecución 50 posiciones enteras (un vector de 50 posiciones) int *ptr2; ptr2 = (int *) malloc(50 * sizeof(int)); Nótese que se ha hecho una conversión del tipo char que devuelve malloc, a tipo int de ptr2. Después de la asignación, ptr2 apunta a la primera posición entera de las 50 solicitadas. La función free() es la opuesta de malloc() porque devuelve al sistema la memoria previamente asignada. Una vez que la memoria ha sido liberada, puede ser reutilizada en una posterior llamada a malloc(). El prototipo de la función free() es: void free (void *p); free(p); Listas dinámicas Si se desea crear una lista dinámica cuyos nodos contengan diferentes tipos de datos, entonces, es necesario definir una estructura o registro que contenga un apuntador para ir enlazando los nodos, tal como se muestra en el diagrama: La siguiente declaración se ajusta al diagrama: struct elementonodo { int inf; struct elementonodo *sig; }; typedef struct elementonodo nodo; /* nodo es un tipo de estructura */ nodo *inicio, *ptr; / declara apuntadores al tipo nodo */ Para crear cada nodo se usa: inf. sig inf. sig inf. sig inf sig Nodo1 Nodo2 Nodo3 Nodo4 Inicio Null
  • 4. Facultad de Informática, Electrónica y Comunicación Estructuras de datos -Inf200 e Inf212 Apuntadores Diego Santimateo G. / Giannina Núñez M. 4 ptr = (nodo * ) malloc (sizeof(nodo)); /* reserva espacio para un nodo */ La primera vez inicio = ptr; Podemos acceder a un campo de la estructura así: ptr -> inf = 100; ptr -> sig = NULL; ¿Cómo hacer para ir añadiendo nodos a la lista? ... escriba el código necesario. Ejemplos de uso de la función malloc #include <stdio.h> #include <stdlib.h> void main() { int *pint; float *preal; char *pcar; typedef struct{ int num; char nombre[10]; } estructura; estructura *pestr; // apuntador a tipo estructura struct datos{ //estructura que incluye un puntero int num; char nombre[10]; struct datos *liga; }; typedef struct datos nodo; nodo *nuevo; // crea área de memoria para un entero pint = (int *)malloc (sizeof(int)); scanf ("%d", pint); printf ("%dn", *pint); pcar = (char *)malloc(sizeof(char)); *pcar = 'a'; printf("%cn",*pcar); preal = (float *)malloc(sizeof(float)); scanf ("%f",preal); printf("%fn",*preal); // crea área para un tipo estructura pestr = (estructura *)malloc(sizeof(estructura)); scanf ("%d",&pestr->num); printf("%dn",pestr->num); scanf ("%s",pestr->nombre); printf("%sn",pestr->nombre); nuevo = (nodo *)malloc(sizeof(nodo)); scanf ("%d",&nuevo->num); printf("%dn",nuevo->num); scanf ("%s",nuevo->nombre); printf("%sn",nuevo->nombre); nuevo ->liga = NULL; printf ("n fin"); }