Punteros

Anuncio
PROGRAMACIÓN EN ANSI C
José L. Ayala
Departamento de Ingeniería Electrónica
jayala@die.upm.es
Punteros
Gestión dinámica de memoria
C permite crear de forma dinámica espacio para cualquier
tipo de variable y obtener su dirección en un puntero
Funciones de la librería estándar (<stdlib.h>)
void *malloc(size_t size)
void free(void *p)
void *calloc(size_t elem, size_t size)
void *realloc(void *p, size_t size)
Punteros
Gestión dinámica de memoria
#include <stdio.h>
#include <malloc.h>
main(){
int size;
int *arr;
int i = 0;
printf(“Introduzca el numero de elementos del array\n");
scanf("%d",&size);
if ( (arr = (int *) malloc(size*sizeof(int))) == NULL){
printf("Error: No hay memoria suficiente\n");
exit(-1); }
while (i< size) {
printf(”Introduzca numero %d:\n", i);
scanf("%d", arr + i);
++i;
}
}
Punteros
Gestión dinámica de memoria
/* Implementación de una cola con punteros */
#include <stdio.h>
#define FALSE 0
#define NULL 0
typedef struct {
int dataitem;
struct listelement *link;
} listelement;
void Menu (int *choice);
listelement * AddItem (listelement * listpointer, int data);
listelement * RemoveItem (listelement * listpointer);
void PrintQueue (listelement * listpointer);
void ClearQueue (listelement * listpointer);
Punteros
Gestión dinámica de memoria
main () {
listelement listmember, *listpointer;
int data,
choice;
listpointer = NULL;
do {
Menu (&choice);
switch (choice) {
case 1:
printf ("Enter data item value to add ");
scanf ("%d", &data);
listpointer = AddItem (listpointer, data);
break;
Punteros
Gestión dinámica de memoria
case 2:
if (listpointer == NULL)
printf ("Queue empty!\n");
else
listpointer = RemoveItem (listpointer);
break;
case 3:
PrintQueue (listpointer);
break;
case 4:
break;
default:
printf ("Invalid menu choice - try again\n");
break;
}
} while (choice != 4);
ClearQueue (listpointer);
}
Punteros
Gestión dinámica de memoria
void Menu (int *choice) {
char local;
printf ("\nEnter\t1 to add item,\n\t2 to remove
item\n\ \t3 to print queue\n\t4 to quit\n");
do {
local = getchar ();
if ((isdigit (local) == FALSE) && (local != '\n'))
{
printf ("\nyou must enter an integer.\n");
printf ("Enter 1 to add, 2 to remove, 3 to
print, 4 to quit\n");
}
} while (isdigit ((unsigned char) local) == FALSE);
*choice = (int) local – '0';
}
Punteros
Gestión dinámica de memoria
listelement * AddItem (listelement * listpointer, int data) {
listelement * lp = listpointer;
if (listpointer != NULL) {
while (listpointer -> link != NULL)
listpointer = listpointer -> link;
listpointer -> link = (struct listelement *) malloc (sizeof
(listelement));
listpointer = listpointer -> link;
listpointer -> link = NULL;
listpointer -> dataitem = data;
return lp;
}
else {
listpointer = (struct listelement *) malloc (sizeof
(listelement));
listpointer -> link = NULL;
listpointer -> dataitem = data;
return listpointer;
}
Punteros
Gestión dinámica de memoria
listelement * RemoveItem (listelement * listpointer) {
listelement * tempp;
printf ("Element removed is %d\n", listpointer -> dataitem);
tempp = listpointer -> link;
free (listpointer);
return tempp;
}
void PrintQueue (listelement * listpointer) {
if (listpointer == NULL)
printf ("queue is empty!\n");
else
while (listpointer != NULL) {
printf ("%d\t", listpointer -> dataitem);
listpointer = listpointer -> link;
}
printf ("\n");
}
Punteros
Gestión dinámica de memoria
void ClearQueue (listelement * listpointer) {
while (listpointer != NULL) {
listpointer = RemoveItem (listpointer);
}
}
Punteros
Errores frecuentes
No asignar memoria antes de usar
int *x;
int *x;
*x = 40;
MAL
x = &y;
*x = 40; BIEN
Reservar la memoria en la variable apuntada
*x = (int *)malloc(200);
x = (int *)malloc(200);
MAL
BIEN
Punteros
EJERCICIOS PROPUESTOS
1. Reescribir el ejercicio 5.1 usando punteros y
gestión dinámica de memoria. Definir una
función que devuelve el puntero a un
expediente.
2. Reescribir el programa presentado para
gestionar una cola, de manera que ahora
gestione los registros en forma de pila.
Punteros
EJERCICIOS PROPUESTOS
1. Comprobar si un array contenido en una estructura se pasa por
valor o por referencia cuando se pasa la estructura a una
función.
2. Escribir un programa que almacene una lista de expedientes de
alumnos en un array de estructuras. Contemplar las opciones
de alta/baja y consulta (completa y por campo). No usar
punteros.
3. Realizar el ejercicio 2 empleando punteros y gestión dinámica
de memoria.
4. Escribir un programa que ordene de forma ascendente un
fichero de texto por líneas.
5. Escribir 5 funciones que procesan 2 enteros de formas
diferentes para devolver otro entero. Declarar un array de
puntero a funciones que devuelven enteros. Escribir un
programa que acepte dos enteros en línea de comandos y los
procese con las funciones apuntadas en el array.
Preprocesador de C
Visión general
Constantes y macros
Inclusión de ficheros
Selección
Opciones en la llamada
Preprocesador de C
Visión general
/usr/lib/cpp es el preprocesador en Unix
Utilizable con otros compiladores de C
Procesa un fichero de entrada y genera otro de
salida
Puede invocarse de forma independiente (no
recomendable !!)
Además de intrerpretar las directivas del fichero,
admite opciones en la llamada
Preprocesador de C
Constantes y macros
#define FALSE 0
#define TRUE !FALSE
#define MAX(A,B) ( (A > B) ? (A) : (B) )
#define IGUAL ==
#define SIN_FIN while(1)
#define cuadrado(x) (x)*(x)
cuadrado (z+1); /* (z+1)*(z+1) */
cuadrado (z++); /* (z++)*(z++) */
Preprocesador de C
Constantes y macros
Las definiciones pueden eliminarse
#undef FALSE
int FALSE = 0;
Los argumentos de una macro pueden concatenarse
#define Concatena(a1, a2) a1 ## a2
Concatena(123, 45) genera 123452
Preprocesador de C
Inclusión de ficheros
Cualquier tipo de fichero de texto
El directorio de búsqueda depende de < > ó “ “
#include <stdio.h>
#include “funciones.h”
Inclusión condicional
#if defined STANDARD
#include <stdio.h>
#else
#include “miio.h”
#endif
Descargar