Hola a todos,
Tenía una duda sobre este codigo:
#include <stdio.h>
double inversos(int k);
double cuadrados(int k);
double funcsuma(int n,double (*f)(int k));
int main(){
printf("Suma de cinco inversos: %.3f \n",funcsuma(5,inversos));
printf("Suma de tres cuadrados: %.3f \n",funcsuma(3,cuadrados));
}
double funcsuma(int n,double(*f)(int k)){
double s= 0;
int i;
for (i=1;i<=n;i++)
s+=f(i);
return s;
}
double inversos(int k){
return 1.0/k;}
double cuadrados(int k){
return (double) k* k;
}
Resulta que no tengo ni idea de que realiza funcsuma(osea,lo de dentro del codigo si,lo que no entiendo es como luego se puede unir a las otras dos funciones) y porque luego se pone:
printf("Suma de cinco inversos: %.3f \n",funcsuma(5,inversos));
printf("Suma de tres cuadrados: %.3f \n",funcsuma(3,cuadrados));
Si alguien me lo pudiera explicar me haría un gran favor.
Gracias por adelantado.
Un saludo
Esta usando un puntero a función.
#include <stdio.h>
double inversos(int k);
double cuadrados(int k);
double funcsuma(int n,double (*f)(int k)); //f es un puntero a funcion
int main(){
printf("Suma de cinco inversos: %.3f \n",funcsuma(5,inversos)); //Pasa la direccion de inversos
printf("Suma de tres cuadrados: %.3f \n",funcsuma(3,cuadrados)); //Pasa la direccion de cuadrados
}
double funcsuma(int n,double(*f)(int k)){ //f recibe la dirección de la función
double s= 0;
int i;
for (i=1;i<=n;i++)
s+=f(i); //Llamada a la función correspondiente pasandole el valor de i
return s;
}
double inversos(int k){
return 1.0/k;}
double cuadrados(int k){
return (double) k* k;
}
En este caso el valor de retorno y los parámetros son exactamente los mismos por lo que es sencillo hacer una especie de puntero a función "genérico".
Busca sobre punteros a función.
Saludos!
Si se te complica entender un poco, personalmente me gusta más manejar las cosas así, aunque basicamente es la misma, pero bueno, me ayuda a entender.
#include <stdio.h>
double inversos (int k);
double cuadrados (int k);
double funcsuma (int n, double (*f) (int k)); //f es un puntero a funcion
int main ()
{
double (*pf)(int, double (*)(int)) = &funcsuma;
printf ("Suma de cinco inversos: %.3f \n", pf(5, inversos)); //Pasa la direccion de inversos
printf ("Suma de tres cuadrados: %.3f \n", pf(3, cuadrados)); //Pasa la direccion de cuadrados
return 0;
}
double funcsuma (int n, double (*f) (int k))
{ //f recibe la dirección de la función
double s = 0;
int i;
for (i = 1; i <= n; i++)
s += f (i); //Llamada a la función correspondiente pasandole el valor de i
return s;
}
double inversos (int k)
{
return 1.0 / k;
}
double cuadrados (int k)
{
return (double) k *k;
}
Gracias a ambos por contestar,he estado buscando y buscando y nada,que no me entra,he encontrado un ejemplo en este mismo foro:
int (*punt) (int,int);
int suma(int a , int b){
return a+b;
}
int resta(int a , int b){
return a-b;
}
*punt=suma;
punt(2,3);
*punt=resta;
punt(5,1);
Este lo entiendo bien pero el que puse....Se me hace un poco complicado y eso que he buscado,incluso por youtube para ver si habia algun tutorial pero sin resultados...
Mis dudas principalmente son estas:
Dentro de la funcion double funcsuma (int n, double (*f) (int k))
No se que pinta ahi el f(i),deduzco que f es el puntero pero no se...
Y luego esto:
printf ("Suma de cinco inversos: %.3f \n", pf(5, inversos)); //Pasa la direccion de inversos
printf ("Suma de tres cuadrados: %.3f \n", pf(3, cuadrados)); //Pasa la direccion de cuadrados
Aunque Leo me ha pasado otro pero sigo sin entenderlo...
printf ("Suma de cinco inversos: %.3f \n", pf(5, inversos)); //Pasa la direccion de inversos
printf ("Suma de tres cuadrados: %.3f \n", pf(3, cuadrados)); //Pasa la direccion de cuadrados
Gracias a ambos.
Un saludo
Te dejo el código que use comentado para que se entienda un poco mejor:
#include <stdio.h>
double inversos (int k);
double cuadrados (int k);
double funcsuma (int n, double (*f)(int k));
/* f es un puntero a función que acepta como argumento un int y que devuelve un double */
/* Es la manera correcta de describir ese parámetro en la función funcsuma */
int main(void)
{
double (*pf)(int, double (*)(int)) = &funcsuma;
/* pf es un puntero a función */
/* pf acepta como argumentos :
{
un int
un puntero a función que acepta un int y que devuelve un double
}
Al puntero a función pf le asignamos la dirección de memoria de la función funcsuma
De ahí que usemos el operador &, aunque se puede omitir.
*/
/* Invocamos a la función funcsuma a través del puntero que acabamos de declarar que apunta hacia ella */
/* Como puedes ver, utilizamos los mismos argumentos que la función necesita
int double (*)(int)
pf( 5, &inversos )
Pasamos por referencia la función inversos
*/
printf ("Suma de cinco inversos: %.3f \n", pf(5, &inversos)); //Pasa la direccion de inversos
printf ("Suma de tres cuadrados: %.3f \n", pf(3, &cuadrados)); //Pasa la direccion de cuadrados
return 0;
}
double funcsuma (int n, double (*f) (int k))
{ //f recibe la dirección de la función
double s = 0;
int i;
for (i = 1; i <= n; i++)
s += f (i); //Llamada a la función correspondiente pasandole el valor de i
/*
s += f(i);
Se llama a la función correspondiente, según hallamos invocado.
pf(5, &inversos) -> s += inversos(i);
pf(3, &cuadrados) -> s += cuadrados(i)
*/
return s;
}
double inversos (int k)
{
return 1.0 / k;
}
double cuadrados (int k)
{
return (double) k *k;
}
Osea,que inversos es un puntero a una funcion que acepta un int y devuelve un double¿no?
Y pf guarda la direccion de memoria de funcsuma¿no?
La verdad es que me esta costando aprenderlo,el otro ejemplo que puse que vi por el foro no era tan complicado >:(
Un saludo y gracias