How can I pass the following argument and what kind is it? - c

I am relatively new in C and found the code of this question. How do you pass the argument double (*f)(double) of the function and how does the pointer works out in this?
Here's the function:
double derivative(double (*f)(double), double x0, int order)
My guess was that first you need something like:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
double f(double x){
return pow(x,2);
}
int main(){
double x = 2;
int order = 2;
derivative(f(x), x , 2);
}
I tried it but it didn't work. Thanks for the help.

double (*f)(double) is a function pointer. It means you need to pass a pointer to (or just the name of) a function. In your attempt, you're calling the function, then passing the return value, which isn't correct.
The correct way would be:
derivative(f, x, 2);

Related

Is it possible to write a function which returns a pointer to a function different from the function in its argument?

I have recently stumbled on this curious thought while handling a C code.
I have written a function which returns a double and takes in as argument the pointer to a function and a certain number of parameters, namely
double template_1(double (*)(double),...);
this function correctly identifies a certain property of a real function
double f(double );
represented as a pointer in template_1, in order to maketemplate_1 valid for every real function I might plug-in.
Now I had to write another function, let it be:
double derivative(double (*)(double),double);
double derivative(double (*f)(double),double x){
double epsilon = ...;
return ( f(x+epsilon)-f(x-epsilon) )/(2.0*epsilon);
}
again with f in the argument to make it work for every f.
My question is: since I would like to use derivative in template_1 without modifying it, is it possible to write a function which takes derivative and spits out something that has the form of double (*)(double ) ?
My idea was to define typedef double (*real_function)(double);
and then to define
real_function g(double (*derivative)(double (*)(double),double ) )
which I'd like it to spit out something like: double derivative_2(double x); so that I could define something like g(derivative) = double (*h)( double); directly in template_1 argument
unfortunately I don't have the faintest idea of how to make this work, or even if it can work.
There are a couple ways to do anonymous functions in C. As the comments said, they aren't portable. But depending on the use case you may find this useful: Anonymous functions using GCC statement expressions
A couple of people have seemed to have similar issues, not sure how portable they are but they may be resourceful:
https://github.com/graphitemaster/lambdapp
https://github.com/Leushenko/C99-Lambda
Basically, if there's a way to architect your program in a way that doesn't require anonymous functions, then do it that way. If you have no other option, then I would give one of these a shot.
Warning: I am a C++ developer with little C knowledge so everything that follows is likely unidiomatic C.
As KerrekSB said, you would need to carry some state with your function. This is not possible with raw functions but you can define a struct that carries the state and add a function that works with this struct. This obviously has the drawback of losing the nice function call syntax. I whipped up an example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef double (*raw_fptr)(double);
struct real_function;
typedef double (*evaluate_function)(struct real_function*, double);
struct real_function {
evaluate_function evaluate;
};
typedef struct real_function real_function;
double evaluate(real_function *f, double x) {
if(f) {
return f->evaluate(f, x);
}
return NAN;
}
struct raw_real_function {
real_function real_function_base;
raw_fptr raw_function;
};
typedef struct raw_real_function raw_real_function;
double evaluate_raw_real_function(real_function *f_base, double x) {
if(f_base) {
raw_real_function *f = (raw_real_function*)f_base;
return f->raw_function(x);
}
return NAN;
}
raw_real_function make_raw_real_function(raw_fptr function) {
raw_real_function result;
result.raw_function = function;
result.real_function_base.evaluate = evaluate_raw_real_function;
return result;
}
struct derive_real_function {
real_function real_function_base;
real_function *function_to_derive;
};
typedef struct derive_real_function derive_real_function;
double derive(real_function *f_base, double x) {
derive_real_function *f = (derive_real_function*)f_base;
double epsilon = 1e-3;
double upper = evaluate(f->function_to_derive, x+epsilon);
double lower = evaluate(f->function_to_derive, x-epsilon);
double result = (upper - lower)/(2.0*epsilon);
return result;
}
derive_real_function make_derivative(real_function * function_to_derive) {
derive_real_function result;
result.real_function_base.evaluate = derive;
result.function_to_derive = function_to_derive;
return result;
}
double x_cubed(double x) {
return x * x * x;
}
int main(int argc, char **argv) {
raw_real_function x_cubed_wrapped = make_raw_real_function(x_cubed);
derive_real_function derived = make_derivative(&x_cubed_wrapped.real_function_base);
derive_real_function derived_twice = make_derivative(&derived.real_function_base);
double x = atof(argv[1]);
double derivative = evaluate(&derived.real_function_base, x);
double second_derivative = evaluate(&derived_twice.real_function_base, x);
printf("derivative of x^3 at %f = %f\n", x, derivative);
printf("second derivative of x^3 at %f = %f\n", x, second_derivative);
return 0;
}
See (a slight variaton, due to input limitations) running here.
How does it work? I faked some inheritance with the structs real_function, raw_real_function and derive_real_function to generate virtual function calls. The struct real_function serves as the container of a virtual function table consisting of only the entry evaluate. This function pointer points to the "derived" structs' relevant evaluate function:
raw_real_function instances point to evaluate_raw_real_function (as initialized in make_raw_real_function. derive_real_function instances point evaluate to derive (as initialized in make_derivative).
When calling evaluate on the real_function_base member, it will call the associated evaluation function, which casts the real_function* to it's associated struct pointer and does what is needed with that information.
Since everything is just a real_function*, we can chain them at will but need to convert "normal" functions into the real_function format, that's what make_raw_real_function does.
If you have a function my_fancy_function:
double my_fancy_function (double x) { return sin(x) + cos(x); }
Then, you can use a helper macro that creates the derived function for you.
#define DEFINE_DERIVATIVE_OF(FUNC) \
double derivative_of_ ## FUNC (double x) { \
return derivative(FUNC, x); \
}
DEFINE_DERIVATIVE_OF(my_fancy_function)
You then pass this newly defined function to your template.
template_1(derivative_of_my_fancy_function, x, y, z);

expected ‘double (*)(double)’ but argument is of type ‘double’ in C

I need help, am trying to calculate the integral of a function using trapezoidal rule in C.
I am trying to use a function as a variable in another function but I am having issues compiling, it gives the same message as the title.
Here's then Code
#include <stdio.h>
#include <math.h>
double test(double x){
return pow(x,2);
}
double tarpez(double a,double b, int n, double (*test)(double )){
/*x[n] represents the parameter
y[n] respresents the parameter ,a initial x,
h is the length of divided spaces*/
double h,x[n],y[n],So,Se;//So-- sum of odd, Se- ...even
h = (b-a)/n;
if (n%2==1){
n+=1;
}
for (int i ; i<=n;i++){
x[i]= a+i*h;
y[i] = test(x[i]);
printf("%lf\n",y[i] );
}
}
int main(void){
double x,a,b,fn;
int n;
fn =
tarpez(a,b,n,test(x));
}
Primo, double (*test)(double ) is type name like int or float. So you need declare double (*test)(double ) foo where foo is variable name (like int n).
Sceundo, name of type can't be name of function. Pointer of function need return tupe, args types and no-reserved name. So try double (*custom_name)(double ).
Tertio, in main function no tarpez(a,b,n,test(x)). Use tarpez(a,b,n,test); You use only name in this space.
PS
Try use typedef.

Function Arguments in C

I'm totally new to C. Here's the question:
Write the function
fzero(double f(double),double x1, double x2)
as we did in class and use it to find all the solutions of
sin( pi*x / (1+x^2) ) = 0.25.
Now, I don't want you to solve the this. I'd missed this lecture and only want to understand what means
double f(double);
In that context, it means that f is a function pointer to a function to that takes one double argument, and returns a double.
As an example:
void foo(double f(double))
{
double y = f(3.0); // Call function through function pointer
printf("Output = %f\n", y); // Prints "Output = 9.0000"
}
double square(double x)
{
return x*x;
}
int main(void)
{
foo(&square); // Pass the address of square()
}
Note that there are two syntaxes for function pointers:
void foo(double f(double))
void foo(double (*f)(double))
These are equivalent.

how to pass element of array as argument to function for it to modify, in ANSI C program?

I understand how to pass an array to a function and let that function update the value of the array. I'm having a tough time understanding how to pass an ELEMENT of an array to a function and have that function update that element. My guess is as below, but produces the following from gcc: "warning: conflicting types for 'CDivide'".
The main() function defines the arrays in question, and passes them (as reference) to fn_v1p0 as complex_real and complex_imag, where they're declared as pointers in the function definition for fn_v1p0. The main() includes prototypes for these functions, as follows.
void fn_v1p0(double *, double *, char *, double *, unsigned int, double *);
void CDivide(double *, double *, double, double, double, double);
However, the main() sits in one file and the other two functions sit in a different file. Only the main file includes these prototypes.
I need to perform complex division (not supported in ANSI C), which is the purpose of function CDivide. There's more to the fn_v1p0 function, but I reduced it to only what's necessary to show for this question.
I've treated complex_real[ii] as simply a double value, hoping that if I put an & in front of it then CDivide could be written as shown. But my guess isn't working. Not sure what's the best way to tackle this.
void fn_v1p0(
double *complex_real, double *complex_imag,
char *selected_form,
double *freq,
unsigned int len_freq,
double *Hparams)
{
int ii = 0;
double a0, b0;
for (ii = 0; ii <= len_freq; ii++) {
CDivide( &complex_real[ii], &complex_imag[ii], b0, 0, a0, freq[ii] );
}
}
where
void CDivide(
double *z_real, double *z_imag, double a, double b, double c, double d)
{
double divisor = c*c + d*d;
*z_real = (a*c + b*d) / divisor;
*z_imag = (b*c - a*d) / divisor;
}
The problem was the prototype for the CDivide function needs to reside in the file containing the CDivide and fn_v1p0 definitions, and not the file containing the main() function. Moving the prototype for CDivide to the file containing CDivide clears the error. Thanks to Adam Rosenfield for flushing out the issue with his comments in the question above.
Take 2 functions double CDivide_real(a,b,c,d) and CDivide_imag(a,b,c,d) or pass a double-pointer-array to CDivide like CDivide(double *x[2],a,b,c,d), and then
for (ii = 0; ii <= len_freq; ii++) {
double *a[]={&complex_real[ii],&complex_imag[ii]};
CDivide( a, b0, 0, a0, freq[ii] );
}
and in CDivide
void CDivide(
double *x[2], double a, double b, double c, double d)
{
double divisor = c*c + d*d;
*x[0] = (a*c + b*d) / divisor;
*x[1] = (b*c - a*d) / divisor;
}

Is it possible pass a function as a parameter in C? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
How do you pass a function as a parameter in C?
Is it possible pass a function as a parameter in C? If yes, how?
No, you can't pass a 'function' as a parameter. You can, however, pass a pointer to a function instead.
When you reference a function by name without the parentheses for a function invocation, you are referencing a pointer to a function. Thus, for example, we could consider a function that generates a table of values for a mathematical function:
#include <math.h>
#include <stdio.h>
static void generator(double lo, double hi, double inc, double (*function)(double))
{
double x;
for (x = lo; x < hi; x += inc)
printf("x = %6g; f(x) = %6g\n", x, (*function)(x))
}
int main(void)
{
generator(0.0, 1.0, 0.02, sin);
generator(0.0, 1.0, 0.02, cos);
generator(0.0, 1.0, 0.02, sqrt);
return(0);
}
Here, the functions 'sin()', 'cos()', and 'sqrt()' all have the same prototype schema: function taking a double argument and returning a double value. Note that if I mistakenly wrote:
generator(0.0, 1.0, 0.02, sin());
I would get a bunch of compilation errors - one because 'sin()' expects an argument, and another because 'generator()' expects a pointer to a function and not a double value as the last argument.
(Also note that a good program would at least identify the function it is calculating, and the repeated increments of a double number is not a good idea for accuracy. It is but an example.)
Use a pointer to function.
Like int (*ptr2_fun)()
Receiving function being:
int execute_your_function(int (*fun)())
Here you have some examples
Use function pointers
Yes. Not a function per se but a pointer to a function instead.
See qsort().
int cmp(const void *a, const void *b) { /* ... */ }
/* ... */
qsort(data, nelems, sizeof *data, cmp); /* pass the function `cmp` to qsort() */
Great function pointer tutorial here:
http://www.newty.de/fpt/index.html
Sure, you can use a function pointer.
#include <stdio.h>
typedef void (*bar_callback)(void);
void foo(void)
{
puts("foo");
}
void bar(bar_callback callback)
{
puts("bar");
callback();
}
int main(int argc,char **argv)
{
bar(foo);
return 0;
}

Resources