Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Profesores
Alfredo Granda
Juan Ramirez
Unidad 06 Variaciones de
las estructuras de datos base
Objetivos
Definicin
Punteros a funciones
Un puntero a una funcin es conocido
tambin como Demonio.
Los punteros a funciones son variables
que almacenan la direccin de memoria
de una funcin.
Al igual que un puntero comn que
necesita saber el tipo de dato al que
apunta, el puntero a funcin necesita
conocer el tipo de funcin al que apunta
Declaracin de punteros a
funciones
Sintaxis
Un puntero a una funcin se define de la siguiente manera:
<tipo retorno> (*<nombre>)(<tipo parmetros>);
Por ejemplo:
int (*puntero1)(int, int);
En este caso el puntero con nombre puntero1 podr apuntar a
cualquiera de las siguientes funciones:
int SumaValores(int a, int b);
int RestaValores(int x, int y);
int DameMayor(int numero1, int numero2);
Ejemplo bsico
Hacer un programa en consola que le pida al usuario un nmero N.
Si N es par imprimir los nmeros pares desde 2 hasta N, de lo
contrario imprimir los impares desde 1 hasta N.
void ImprimePares(int N) {
for (int i=2; i<=N; i+=2)
printf("%d\n", i);
}
void ImprimeImpares(int N) {
for (int i=1;i<=N;i+=2)
printf("%d\n", i);
}
int main()
{
int N;
printf("Ingrese N: ");
scanf("%d", &N);
// Declarar puntero a funcion
void (*pfunc)(int);
// Asignar al puntero la funcion correcta
if (N % 2 == 0)
pfunc = ImprimePares;
else
pfunc = ImprimeImpares;
// Invocar a la funcion
pfunc(N);
return 0;
}
Ejemplos de invocacin
void funcion() {
printf("Una funcion X\n");
}
void (*pfunc)() = funcion;
void (**ppfunc)() = &pfunc;
int main()
{
// Tipos de invocacion.
// Todas las lineas a continuacion invocan a la funcion
funcion();
pfunc();
(*pfunc)();
(**ppfunc)();
(*ppfunc)();
return 0;
}
Sintaxis
La forma en la que definimos una funcin siempre
es igual, lo que cambia es que ahora uno o ms
parmetros a la funcin sern punteros a funciones.
void MiFuncion(int A, bool (*pEsCierto)(int))
Recibe un entero y un puntero a una funcin que tiene
como parmetro un entero y devuelve un booleano.
Utilidad
Sin embargo, la utilidad cobra su
verdadero
significado
cuando
el
argumento no es constante (no se invoca
siempre la misma funcin) sino que es
variable.
Ejemplo
Supongamos que contamos con un arreglo de
enteros llamado vec con una cantidad de
elementos N. Ambas variables han sido
declaradas de forma global por lo que puede
acceder directamente a ellas desde sus funciones.
Implemente las siguientes funciones para consola
utilizando el arreglo:
ImprimirPares
ImprimirImpares
ImprimirMultiplosDe5
ImprimirSiLosDigitosSuman10
void ImprimirPares()
{
for (int i=0; i<N; i++)
if (vec[i] % 2 == 0)
printf("%d\n", vec[i]);
}
void ImprimirImpares()
{
for (int i=0; i<N; i++)
if (vec[i] % 2 != 0)
printf("%d\n", vec[i]);
}
void ImprimirMultiplosDe5()
{
for (int i=0; i<N; i++)
if (vec[i] % 5 == 0)
printf("%d\n", vec[i]);
}
void ImprimirSiLosDigitosSuman10()
{
for (int i=0; i<N; i++) {
if (SumaDigitos(vec[i]) == 10)
printf("%d\n", vec[i]);
}
}
modificar la
funcin para que sea an ms
genrica y no imprima, sino que
haga algo con los datos.
Ejemplo:
ImprimirDatos( EsPar,
ImprimeEnArchivo );
class Cvector
{
private:
int *vec;
int ne;
public:
// Mtodos
void MostrarEnConsola()
{
for (int i=0; i<ne; i++)
printf("%d\n", vec[i]);
}
void MostrarEnListBox(ListBox ^lb)
{
for (int i=0; i<ne; i++)
lb->Items->Add(vec[i]);
}
};
// Programa en consola
int main()
{
Cvector *vec = new Cvector();
// Llenar datos
vec->MostrarEnConsola();
delete vec;
}
// Programa con formularios
public ref class Form1 : System::Windows:Forms:Form
{
private:
Cvector *vec;
System::Windows::Forms::ListBox^ listBox1;
public:
Form1()
{
InitializeComponent();
vec = new Cvector();
}
Void button1_Click(Object^ sender, EventArgs^
{
vec->MostrarEnListBox(listBox1);
}
};
e)
Archivos
GridView
CheckedListBox
Base de datos
ComboBox
class Cvector
{
private:
int *vec;
int ne;
public:
// Mtodos
void MostrarGenerico( void(*pProcesar)(int) )
{
for (int i=0; i<ne; i++)
pProcesar(vec[i]);
}
};
// Programa en consola
void Imprimir(int dato)
{
printf("%d\n", dato);
}
int main()
{
Cvector *vec = new Cvector();
// Llenar datos
vec->MostrarGenerico( Imprimir );
delete vec;
}
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Programa con formularios
public ref class Form1 : System::Windows:Forms:Form
{
private:
Cvector *vec;
public:
System::Windows::Forms::ListBox^ listBox1;
public:
Form1()
{
InitializeComponent();
vec = new Cvector();
}
Void button1_Click(Object^ sender, EventArgs^
{
vec->MostrarGenerico( Imprimir );
}
e)
};
void Imprimir(int dato)
{
Form1 ^frm = (Form1^)Application::OpenForms["Form1"];
frm->listBox1->Items->Add( dato );
}
class Cvector
{
private:
int *vec;
int ne;
public:
void(*OnProcesar)(int);
public:
// Mtodos
Cvector()
{
ne = 0;
OnProcesar = NULL;
}
void MostrarGenerico()
{
for (int i=0; i<ne; i++)
{
if (pProcesar != NULL)
OnProcesar(vec[i]);
}
}
};
// Programa en consola
void Imprimir(int dato)
{
printf("%d\n", dato);
}
int main()
{
Cvector *vec = new Cvector();
vec->OnProcesar = Imprimir;
// Llenar datos
vec->MostrarGenerico();
delete vec;
}
Usos comnes
Ejercicios
Ejercicio 1 - Parte 1
Realizar un programa en C que almacene la informacin de personas recluidas.
Deber hacer uso de punteros a funciones para reducir el tamao de su cdigo.
Cada preso tendr las siguientes caracterstica:
Numero: (correlativo) 1,2,3,4 ...
Das: que han permanecido recluidos: 1 < dias <= 5000
Faltas: o castigos del preso: 0 <= faltas <= 15
Edad: 15 <= edad < 65
Nivel de conducta: 0 <= conducta <= 100 (0 : peor conducta)
Se piden los siguientes datos:
a) Promedio de das que llevan preso.
b) Promedio de faltas o castigos.
c) Promedio de edad.
d) Nmero del interno con menos edad.
e) Nmero del interno con peor nivel de conducta.
f) Nmero del interno con menor cantidad de faltas.
Ejercicio 1 - Parte 2
Los datos de los presos tienen que estar tabulados de manera similar.
El nmero de presos que se ingrese por teclado, tiene que depender de una correcta
salida a pantalla, que permita ver los datos y el informe.
Tener cuidado con los lmites de la asignacin aleatoria!.
Los promedios debern salir a pantalla slo con un decimal.
El cdigo debe estar bien tabulado.