Breve 8 Punteros Fundamentos de Informática Indice • • • • ¿Qué es un puntero? Declaración de punteros Operadores unarios: & y * Operaciones con punteros – Aritmética de punteros • • • Punteros y funciones Punteros y vectores Asignación dinámica de memoria Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros 2 ¿Qué es un puntero? • • Es un tipo de variable un poco especial, ya que en lugar de almacenar valores (como una variable de tipo “int” o “double”) los punteros almacenan direcciones de memoria Mediante una variable de tipo puntero, se puede manipular tanto direcciones de memoria como valores. 10000 ‘A’ 10001 123 10005 10034 10009 ‘G’ 1000A 33 • Sus ventajas: – – – 10034 34.22 10038 ‘F’ Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Mediante los punteros es posible que las funciones devuelvan más de un valor Permiten definir vectores y matrices de tamaño variable, que utilizan sólo la cantidad de memoria necesaria y cuyo tamaño puede reajustarse dinámicamente. Permiten definir estructuras de datos más complejas, como listas o árboles. Breve 8: Punteros 3 Declaración de punteros • Los punteros se declaran igual que las variables normales, pero con un asterisco (*) delante del nombre de las variables: tipo *nombre_puntero; donde tipo indica el tipo de datos al que “apuntará” el puntero • Ejemplos: double *puntd; int *punti; Dirección Valor Variable Dirección Valor ? C2B8 punti C2B8 123 ? C37A puntd C37A 7.4e-3 Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros Variable 4 Operadores unarios: & • Operador &: – Operador unario de dirección. – Obtiene la dirección de memoria de su operando, es decir, la dirección de memoria de la variable sobre la que se aplica. • Ejemplo 1: numero esta en la dirección 34FF después de la int numero; asignación punt int *punt; tendrá el valor 34FF numero = 10; punt = &numero; /*asignar la direcc de numero a una variable punt*/ • Ejemplo 2: int n; printf(“Introduzca el valor de n”); scanf(“%d”, &n); scanf() necesita conocer la dirección de la variable donde almacenar el valor leído del buffer de teclado Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros 5 Operadores unarios: * • Operador * : – Operador unario de indirección. Complemento del operador &. – Proporciona el valor de la dirección de memoria a la que apunta el puntero sobre el que se aplica, es decir, permite acceder al valor por medio del puntero • Ejemplo: int var1, var2; int *p; var1 = 5; p = &var1; var2 = *p; *p = 10; … Dirección ? Valor 34FF 5X 10 34FF 5 Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros Variable p var1 var2 6 Punteros y funciones • Los punteros permiten realizar un paso por referencia de parámetros a funciones: – Es posible cambiar el valor de una variable en el interior de una función y conservar su valor una vez terminada la ejecución de la función. – En lugar de pasar la variable como parámetro real a la función (paso por valor) se pasa un puntero a la dirección en la que se encuentra la variable (parámetro por referencia). – En el paso por valor: se copia el valor del parámetro real sobre el parámetro formal, de manera que cualquier cambio en el parámetro formal NO afecta al parámetro real. – En el paso por referencia: se pasa la dirección de la variable, de manera que los cambios se pueden hacer manipulando el puntero y afectan directamente al contenido de la variable apuntada. Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros 7 Punteros y funciones Ejemplo paso por referencia: #include <stdio.h> void Cambiar (int *x, int *y); int main(void) { int a, b; a = 3; b= 5; printf(“ \nAntes de intercambiar: a = %d, y b = %d”,a,b); Cambiar(&a, &b); /* Se pasa la direc. de las 2 variables */ printf(“\nDespués de intercambio: a = %d, y b = %d”,a,b); return 0; } void Cambiar(int *x, int *y) { int aux; aux = *x; /* A través del puntero x, puedo acceder al valor original */ *x = *y; *y = aux; } Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros 8 Asignación dinámica de memoria • calloc: Inicializa el bloque con ceros void *calloc (size_t num_elem, size_t tamaño_elem); malloc: NO inicializa el void *malloc(size_t tam_bloque); bloque con ceros Solicitar memoria: devuelven un puntero al principio del bloque solicitado o NULL si no hay suficiente memoria (VERIFICAR). Librería stdlib.h • Liberar la memoria asignada dinámicamente: void free (void *puntero_al_bloque); Ejemplo: Crea un vector de n enteros Verifica si se ha reservado memoria int *punt; punt = (int *) malloc (n * sizeof(int)); int n; Cast al tipo del vec scanf(“%d”,&n); punt = (int *) calloc (n, sizeof(int)); if (punt == NULL) { printf(“Error: No hay suficiente memoria “) }else{ /* Si hay memoria se puede usar el vec creado */ punt[0] =23; /*...*/ free(punt); Libera la } memoria Departamento de Sistemas Informáticos Escuela Técnica Superior de Ingeniería ICAI Breve 8: Punteros 9