#include "stdio.h"
int add(int x, int y)
{
return x + y;
}
int withFive(int x, int (*func))
{
return (*func)(x,5);
}
int main()
{
void (*funcptr)(int) = &add;
printf("%d", withFive(10,funcptr));
return 0;
}
This code seems like it would compile based on my understanding of function pointers but there is an error that a function or function pointer isn't being passed to withFive. How should I write withFive so that the compiler will accept the argument as a function ptr?
The definition should be
int withFive(int x, int (*func)(int, int ) )
or
int withFive(int x, int (*func)(int x, int y) )
like in a variable definition.
Btw: void (*funcptr)(int) = &add; should be int (*funcptr)(int,int) = &add; as well or just int (*funcptr)(int,int) = add;
int withFive(int x, int (*func))
You want, as an argument, a function func that returns int and takes two int as parameter.
So you need:
int withFive(int x, int (*func)(int, int))
Then:
{
return (*func)(x,5);
}
You don't need to dereference func. Just write
return func(x, 5);
Then:
void (*funcptr)(int) = &add;
That's the wrong type again. And you don't need to take the address of add. Just write:
int (*funcptr)(int, int) = add;
Or you could just write:
printf("%d", withFive(10,add));
Generally speaking, to make handling the somewhat awkward function pointer syntax easier and the result more readable, you could use a typedef. All together, and some other minor edits included:
#include <stdio.h>
typedef int (*binary_func_t)( int, int );
int add( int x, int y )
{
return x + y;
}
int withFive( int x, binary_func_t func )
{
return func( x, 5 );
}
int main()
{
printf( "%d\n", withFive( 10, add ) );
return 0;
}
In your case it would have to be int withFive(int x, int (*func)(int,int)). However, using the raw function pointer syntax of C is quite unreadable. The recommended practice is to always use typedefs, like this:
typedef int operation_t (int x, int y); // function type acting as "template"
int add (int x, int y);
int withFive(int x, operation_t* op); // op is a pointer to function
...
withFive(10, add);
Related
I'm a bit confused as to how to implement the following. I want to have a function, func2, return a function that with call func1 with the specified parameters:
int func1(int x, int y, int z, int type){
// Calculations
}
int ((*func2)(int x, int y, int z))(int type){
// Return a pointer to func1 that with get x, y, z as parameters
// when called later, with type = type being fixed
}
Use:
my_func = func2(3);
printf("result = %d\n", my_func(1,2,3));
For this to work you need something called a closure which is basically a record with the function and the type as fields. Below is an example to illustrate the idea. In a real program you also need to check that malloc doesn't return NULL, and free the memory.
#include <stdio.h>
#include <stdlib.h>
typedef struct ClosureDesc *Closure;
struct ClosureDesc {
int type;
int (*function)(Closure c, int x, int y, int z);
};
int func1(Closure c, int x, int y, int z)
{
return c->type;
}
Closure func2(int type)
{
Closure c;
c = malloc(sizeof *c);
c->type = type;
c->function = func1;
return c;
}
int main(void)
{
Closure my_func;
my_func = func2(3);
printf("result = %d\n", my_func->function(my_func, 1,2,3));
return 0;
}
Function pointers syntax is a bit confusing but you can make it easier typedefing the functions itself. Then you can use "normal" pointer syntax.
typedef int func(int,int,int);
int func1(int x, int y, int z){
// Calculations
return 1;
}
int func2(int x, int y, int z){
// Calculations
return 2;
}
int func3(int x, int y, int z){
// Calculations
return 3;
}
func *selectfunc(int type)
{
func *f = NULL;
switch(type)
{
case 1:
f = func1;
break;
case 2:
f = func2;
break;
case 3:
f = func3;
break;
}
return f;
}
int main(void)
{
int type = rand()%3;
printf("%d", selectfunc(type)(1,2,3));
}
or
func *fptr = selectfunc(2);
fptr(1,2,3);
Here’s what I think you’re going for:
int func1( int x, int y, int z )
{
...
}
/**
* func2 takes an integer parameter and returns a
* pointer to a function that takes 3 integer
* parameters and returns int
*/
int (*func2(int type))(int, int, int)
{
/**
* This example is based on what you wrote in your
* question. Regardless of how you actually select
* which function to return based on the input, the
* return statement will be the same.
*/
switch ( type )
{
case 3:
return func1;
break;
default:
break;
}
return NULL;
}
int main( void )
{
int (*my_func)(int, int, int);
...
my_func = func2( 3 );
if ( my_func )
printf( "result = %d\n", my_func( 1, 2, 3 ) );
...
}
If you write func2 such that it can never return NULL and you want your co-workers to throw things at you, you can dispense with the my_func variable and just write
printf( "result = %d\n", func2(3)(1, 2, 3));
I wouldn’t recommend it though, unless you like rude comments in code reviews.
How does the function pointer in the declaration of any_function receive any value? In the main function, any_function is never given any function pointers, only functions themselves. Does this mean the function pointer any_function is recursively calling itself?
#include <stdio.h>
int sum(int, int);
int product(int, int);
int difference(int, int);
int any_function(int(*pfun)(int, int), int x, int y);
int main(void)
{
int a = 10; /* Initial value for a */
int b = 5; /* Initial value for b */
int result = 0; /* Storage for results */
int (*pf)(int, int) = sum; /* Pointer to function */
/* Passing a pointer to a function */
result = any_function(pf, a, b);
printf("\nresult = %d", result );
/* Passing the address of a function */
result = any_function(product,a, b);
printf("\nresult = %d", result );
printf("\nresult = %d\n", any_function(difference, a, b));
return 0;
}
/* Definition of a function to call a function */
int any_function(int(*pfun)(int, int), int x, int y)
{
return pfun(x, y);
}
/* Definition of the function sum */
int sum(int x, int y)
{
return x + y;
}
/* Definition of the function product */
int product(int x, int y)
{
return x * y;
}
/*Defintion of the function product*/
int difference(int x, int y)
{
return x - y;
}
How does the function pointer in the declaration of any_function receive any value?
Because the function call specified a value. Same as any other parameter.
E.g. when you write:
int my_function(int x) {
return x + 1;
}
// in main
printf("%d\n", my_function(5));
it prints 6. But how did x in the declaration of my_function receive any value? Well, it was specified when we wrote my_function(5).
In the main function, any_function is never given any function pointers, only functions themselves.
If you use a function like that it is converted to a pointer automatically. In other words pf = sum; is short for pf = ∑
Does this mean the function pointer any_function is recursively calling itself?
No, where did that idea come from?
I was working of functions pointers examples and I developed 4 simple functions and assigned them to a function pointer array, then I ran the code and worked for the 4 functions, but then I thought to also print the names of the functions.
I learned about __func__ and it only prints the name of the current function, so is there anyway to assign __func__ to the function pointer or another method to print the names of the functions?
This is the example I'm working on right now:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
int main() {
int m = 6;
int n = 10;
int res,i;
int (*fun[4])(int,int)={add,sub,mul,divide};
for (i=0;i<4;i++)
{
printf("result of %s operation\n",__func__=fun[i]);
}
}
int add(int x, int y) {
int result = x + y;
return result;
}
int sub(int x, int y) {
int result = x - y;
return result;
}
int mul(int x, int y) {
int result = x * y;
return result;
}
int divide(int x, int y) {
int result = x / y;
return result;
}
As you can see I'm trying to assign the __func__ to the functions pointer but of course it's not working.
The __func__ constant in every function is only accessible in runtime. Meaning that if you want to use that one, you have to grab it while calling the function. Like this:
typedef int calc_func_t (int x, int y, const char** func);
int add(int x, int y, const char** func);
...
calc_func_t* fun[4] = {add,sub,mul,divide};
for (i=0;i<4;i++)
{
const char* func;
int result = fun[i](1,1,&func);
printf("result of %s operation %d\n", func, result);
}
...
int add(int x, int y, const char** func)
{
int result = x + y;
*func = __func__;
return result;
}
...
If you wish to know what the functions are named at compile-time and then later on use that information, the easiest and best way would be to create a look-up table:
typedef struct
{
calc_func_t* func;
const char* name;
} calc_func_info_t;
const calc_func_info_t func_info [] =
{
{add, "add"},
{sub, "sub"},
...
};
Compiled code doesn't contain functions and symols names by default. You can use some macros to create constant strings containing functions names to be included in the compiled binary:
#include <stdio.h>
// function call type
typedef void fn_call();
// record describing one function
typedef struct fn_record {
const char *name; // function's name as a constant string
fn_call *call; // function call
} fn_record;
// the functions to be called and named
void fna() { printf("called fna\n"); }
void fnb() { printf("called fnb\n"); }
void fnc() { printf("called fnc\n"); }
// macro, that generates record for each function, it creates
// string like { "fna", fna } to save You typing
#define FN_RECORD(f) { #f, f }
// now define array of functions records
fn_record fns[3] = {
FN_RECORD(fna),
FN_RECORD(fnb),
FN_RECORD(fnc)
};
// ... which becomes:
// fn_record fns[3] = {
// { "fna", fna },
// { "fnb", fnb },
// { "fnc", fnc }
// };
int main(void) {
int i;
// ... use it whatever You like
for (i = 0; i < 3; i++) {
printf("%s\n", fns[i].name);
fns[i].call();
}
return 0;
}
Basically, there is no way.
// A function declaration
void MyFunction(void);
// a pointer to the function
void (*fnPointer)(void) = MyFunction;
// No way to retrieve function name "MyFunction" from fnPointer
Ofcourse, if you have a known set of possible functions that might be assigned to the pointer, you could compare them explicitely.
Also, you can change the stored function pointer to be combined with the function name. Could be something similar to the following:
struct FunctionPointerContainer
{
void (*fnPointer)(void);
char* fnName;
};
#define MakeFunctionPointer(fn) FunctionPointerContainer { fn, #fn }
// later
struct FunctionPointerContainer myPointer = MakeFunctionPointer(MyFunction);
myPointer.fnPointer(); // call
myPointer.fnName; // the function name
I was working of functions pointers examples
So, as I understand, your example is done for educational purposes, aren't you? In that case I would do it as simple as it can be to not confuse the students who use your example to learn how function pointers work.
I learned about __func__ and it only prints the name of the current function
Despite other answers show very nice and smart solutions how to have the function name outside of it, from the perspective of simplicity I would still use the __func__ as it normally works, inside the called function:
#include <stdio.h>
#define print_info(format, ...) \
printf("Function '%s' is called with parameters: "format"\n", \
__func__, __VA_ARGS__)
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
int main() {
int m = 6, n = 10, i;
int (*fun[4])(int,int) = { add, sub, mul, divide };
for (i = 0; i < 4; ++i)
printf("-- result is: %d\n", fun[i](n, m));
return 0;
}
int add(int x, int y) {
print_info("%d, %d", x, y);
return x + y;
}
int sub(int x, int y) {
print_info("%d, %d", x, y);
return x - y;
}
int mul(int x, int y) {
print_info("%d, %d", x, y);
return x * y;
}
int divide(int x, int y) {
print_info("%d, %d", x, y);
return x / y;
}
I am having problem in understanding function pointer for passing any arguments. Please find the sample program for your reference. Here I want to print the sum of two numbers. print() accepts a function pointer as its argument. But I am not able to pass the argument from main() to the function.
#include<stdio.h>
int sum(int, int);
void print(int (*p)(int,int));
int main()
{
int a=2;
int b=5;
print(sum(a,b));
}
void print(int (*p)(int a,int b))
{
printf("%d",p(a,b)); //a and b are not defined as per compiler
}
int sum(int a, int b)
{
return a+b;
}
When you make this declaration
void print(int (*p)(int a,int b))
you declare a function print that takes a function pointer p that takes two ints and return an int. The names a and b do not represent anything in particular - the compiler ignores them. In fact, you could omit them:
void print(int (*p)(int,int))
If you would like to pass two numbers to be added, pass them as separate parameters:
void print(int (*p)(int,int), int a, int b)
Now your print will compile. The call will need to look like this:
print(sum, a, b);
This is because when you write print(sum(a, b)) you are instructing the compiler to call sum with parameters a and b, obtain its result, and pass to print. However, when you pass sum by itself, with no parentheses, it represents the function pointer.
The program will look like
#include<stdio.h>
int sum( int, int );
void print( int ( * )( int, int ), int, int );
// or more simpler
void print( int ( int, int ), int, int );
int main()
{
int a = 2;
int b = 5;
print( sum, a, b);
}
void print( int ( *p )( int,int ), int a, int b )
{
printf( "%d", p( a, b ) ); //a and b are not defined as per compiler
}
int sum( int a, int b )
{
return a + b;
}
Take into account that these declarations are equivalent and declare the same function
void print( int ( * )( int, int ), int, int );
// or more simpler
void print( int ( int, int ), int, int );
As for your original code then function print only has one parameter: a function pointer. So you may pass to function print only one argument: some function. You could define function print the following way
void print( int ( *p )( int,int ) )
{
int a = 2, b = 5;
printf( "%d", p( a, b ) ); //a and b are not defined as per compiler
}
Or you can define function print with three parameters that the user of the function could himself specify arguments to the called function within the body of print.
void print( int ( *p )( int,int ), int a, int b )
{
printf( "%d", p( a, b ) ); //a and b are not defined as per compiler
}
Let's start with a basic function which we will be pointing to:
int addInt(int n, int m) {
return n+m;
}
First thing, lets define a pointer to a function which receives 2 ints and returns and int:
int (*functionPtr)(int,int);
Now we can safely point to our function:
functionPtr = &addInt;
Now that we have a pointer to the function, lets use it:
int sum = (*functionPtr)(2, 3); // sum == 5
Passing the pointer to another function is basically the same:
int add2to3(int (*functionPtr)(int, int)) {
return (*functionPtr)(2, 3);
}
We can use function pointers in return values as well (try to keep up, it gets messy):
// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
printf("Got parameter %d", n);
int (*functionPtr)(int,int) = &addInt;
return functionPtr;
}
But it's much nicer to use a typedef:
typedef int (*myFuncDef)(int, int);
// note that the typedef name is indeed myFuncDef
myFuncDef functionFactory(int n) {
printf("Got parameter %d", n);
myFuncDef functionPtr = &addInt;
return functionPtr;
}
Disclaimer: this code was not necessarily compiled, if you see any errors, feel free to edit.
how to pass array as arguments in C?
int a,b,c[10];
void Name1(int x, int y, int *z)
{
a = x;
b = y;
c = z;
}
I try to pass it as argument, but it does not build, how to fix it?
And is the declaration of void Name1(int x, int y, int *z); is the same as void Name1(int x, int y, int z[])? does the void Name1(int x, int y, int z[]) will be treated as void Name1(int x, int y, int *z); by compiler?
When you pass array as an argument to function it decays as an pointer to its first element.
So,
void Name1(int x, int y, int *z)
will work.
But arrays are not assignable so:
c = z;
does not work, you will need to explicitly copy each array element from source to destination.
Doing c = z;, you're assigning to a non l-value, which is not allowed. It's like doing &c[0] = &z[0];.
There are a couple of answers here, but I don't think any of them are completely sufficient, so...
basically you can either copy the array or use the pointer, but either way you will need to keep track of the length.
int a,b, *c, len;
void Name1(int x, int y, int *z, int z_len)
{
a = x;
b = y;
c = z;
len = z_len;
}
//usage:
int arr[5];
Name1(1,2,arr /* or &arr[0] ,*/, sizeof(arr )/ sizeof (int));
if you never need to add items this will be sufficient... If you do it gets more complicated...
it is important to keep the length around so that you know how many elements you have, even if you are going to copy them.
c=z; is invalid
c pointer doesnt have memory to save the z address.
you can say:
int a,b,*c;
c=(int *)calloc(10,sizeof(int) );
void Name1(int x, int y, int *z)
{
a = x;
b = y;
c = z;
}