How should I use array of function pointers in C?
How can I initialize them?
You have a good example here (Array of Function pointers), with the syntax detailed.
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
[...]
To call one of those function pointers:
result = (*p[op]) (i, j); // op being the index of one of the four functions
The above answers may help you but you may also want to know how to use array of function pointers.
void fun1()
{
}
void fun2()
{
}
void fun3()
{
}
void (*func_ptr[3])() = {fun1, fun2, fun3};
main()
{
int option;
printf("\nEnter function number you want");
printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
scanf("%d",&option);
if((option>=0)&&(option<=2))
{
(*func_ptr[option])();
}
return 0;
}
You can only assign the addresses of functions with the same return type and same argument types and no of arguments to a single function pointer array.
You can also pass arguments like below if all the above functions are having the same number of arguments of same type.
(*func_ptr[option])(argu1);
Note: here in the array the numbering of the function pointers will be starting from 0 same as in general arrays. So in above example fun1 can be called if option=0, fun2 can be called if option=1 and fun3 can be called if option=2.
Here's how you can use it:
New_Fun.h
#ifndef NEW_FUN_H_
#define NEW_FUN_H_
#include <stdio.h>
typedef int speed;
speed fun(int x);
enum fp {
f1, f2, f3, f4, f5
};
void F1();
void F2();
void F3();
void F4();
void F5();
#endif
New_Fun.c
#include "New_Fun.h"
speed fun(int x)
{
int Vel;
Vel = x;
return Vel;
}
void F1()
{
printf("From F1\n");
}
void F2()
{
printf("From F2\n");
}
void F3()
{
printf("From F3\n");
}
void F4()
{
printf("From F4\n");
}
void F5()
{
printf("From F5\n");
}
Main.c
#include <stdio.h>
#include "New_Fun.h"
int main()
{
int (*F_P)(int y);
void (*F_A[5])() = { F1, F2, F3, F4, F5 }; // if it is int the pointer incompatible is bound to happen
int xyz, i;
printf("Hello Function Pointer!\n");
F_P = fun;
xyz = F_P(5);
printf("The Value is %d\n", xyz);
//(*F_A[5]) = { F1, F2, F3, F4, F5 };
for (i = 0; i < 5; i++)
{
F_A[i]();
}
printf("\n\n");
F_A[f1]();
F_A[f2]();
F_A[f3]();
F_A[f4]();
return 0;
}
I hope this helps in understanding Function Pointer.
This "answer" is more of an addendum to VonC's answer; just noting that the syntax can be simplified via a typedef, and aggregate initialization can be used:
typedef int FUNC(int, int);
FUNC sum, subtract, mul, div;
FUNC *p[4] = { sum, subtract, mul, div };
int main(void)
{
int result;
int i = 2, j = 3, op = 2; // 2: mul
result = p[op](i, j); // = 6
}
// maybe even in another file
int sum(int a, int b) { return a+b; }
int subtract(int a, int b) { return a-b; }
int mul(int a, int b) { return a*b; }
int div(int a, int b) { return a/b; }
Here's a simpler example of how to do it:
jump_table.c
int func1(int arg) { return arg + 1; }
int func2(int arg) { return arg + 2; }
int func3(int arg) { return arg + 3; }
int func4(int arg) { return arg + 4; }
int func5(int arg) { return arg + 5; }
int func6(int arg) { return arg + 6; }
int func7(int arg) { return arg + 7; }
int func8(int arg) { return arg + 8; }
int func9(int arg) { return arg + 9; }
int func10(int arg) { return arg + 10; }
int (*jump_table[10])(int) = { func1, func2, func3, func4, func5,
func6, func7, func8, func9, func10 };
int main(void) {
int index = 2;
int argument = 42;
int result = (*jump_table[index])(argument);
// result is 45
}
All functions stored in the array must have the same signature. This simply means that they must return the same type (e.g. int) and have the same arguments (a single int in the example above).
In C++, you can do the same with static class methods (but not instance methods). For example you could use MyClass::myStaticMethod in the array above but not MyClass::myInstanceMethod nor instance.myInstanceMethod:
class MyClass {
public:
static int myStaticMethod(int foo) { return foo + 17; }
int myInstanceMethod(int bar) { return bar + 17; }
}
MyClass instance;
Oh, there are tons of example. Just have a look at anything within glib or gtk.
You can see the work of function pointers in work there all the way.
Here e.g the initialization of the gtk_button stuff.
static void
gtk_button_class_init (GtkButtonClass *klass)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
gobject_class = G_OBJECT_CLASS (klass);
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
gobject_class->constructor = gtk_button_constructor;
gobject_class->set_property = gtk_button_set_property;
gobject_class->get_property = gtk_button_get_property;
And in gtkobject.h you find the following declarations:
struct _GtkObjectClass
{
GInitiallyUnownedClass parent_class;
/* Non overridable class methods to set and get per class arguments */
void (*set_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
void (*get_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
/* Default signal handler for the ::destroy signal, which is
* invoked to request that references to the widget be dropped.
* If an object class overrides destroy() in order to perform class
* specific destruction then it must still invoke its superclass'
* implementation of the method after it is finished with its
* own cleanup. (See gtk_widget_real_destroy() for an example of
* how to do this).
*/
void (*destroy) (GtkObject *object);
};
The (*set_arg) stuff is a pointer to function and this can e.g be assigned another implementation in some derived class.
Often you see something like this
struct function_table {
char *name;
void (*some_fun)(int arg1, double arg2);
};
void function1(int arg1, double arg2)....
struct function_table my_table [] = {
{"function1", function1},
...
So you can reach into the table by name and call the "associated" function.
Or maybe you use a hash table in which you put the function and call it "by name".
Regards
Friedrich
Can use it in the way like this:
//! Define:
#define F_NUM 3
int (*pFunctions[F_NUM])(void * arg);
//! Initialise:
int someFunction(void * arg) {
int a= *((int*)arg);
return a*a;
}
pFunctions[0]= someFunction;
//! Use:
int someMethod(int idx, void * arg, int * result) {
int done= 0;
if (idx < F_NUM && pFunctions[idx] != NULL) {
*result= pFunctions[idx](arg);
done= 1;
}
return done;
}
int x= 2;
int z= 0;
someMethod(0, (void*)&x, &z);
assert(z == 4);
This should be a short & simple copy & paste piece of code example of the above responses. Hopefully this helps.
#include <iostream>
using namespace std;
#define DBG_PRINT(x) do { std::printf("Line:%-4d" " %15s = %-10d\n", __LINE__, #x, x); } while(0);
void F0(){ printf("Print F%d\n", 0); }
void F1(){ printf("Print F%d\n", 1); }
void F2(){ printf("Print F%d\n", 2); }
void F3(){ printf("Print F%d\n", 3); }
void F4(){ printf("Print F%d\n", 4); }
void (*fArrVoid[N_FUNC])() = {F0, F1, F2, F3, F4};
int Sum(int a, int b){ return(a+b); }
int Sub(int a, int b){ return(a-b); }
int Mul(int a, int b){ return(a*b); }
int Div(int a, int b){ return(a/b); }
int (*fArrArgs[4])(int a, int b) = {Sum, Sub, Mul, Div};
int main(){
for(int i = 0; i < 5; i++) (*fArrVoid[i])();
printf("\n");
DBG_PRINT((*fArrArgs[0])(3,2))
DBG_PRINT((*fArrArgs[1])(3,2))
DBG_PRINT((*fArrArgs[2])(3,2))
DBG_PRINT((*fArrArgs[3])(3,2))
return(0);
}
The simplest solution is to give the address of the final vector you want , and modify it inside the function.
void calculation(double result[] ){ //do the calculation on result
result[0] = 10+5;
result[1] = 10 +6;
.....
}
int main(){
double result[10] = {0}; //this is the vector of the results
calculation(result); //this will modify result
}
This question has been already answered with very good examples. The only example that might be missing is one where the functions return pointers. I wrote another example with this, and added lots of comments, in case someone finds it helpful:
#include <stdio.h>
char * func1(char *a) {
*a = 'b';
return a;
}
char * func2(char *a) {
*a = 'c';
return a;
}
int main() {
char a = 'a';
/* declare array of function pointers
* the function pointer types are char * name(char *)
* A pointer to this type of function would be just
* put * before name, and parenthesis around *name:
* char * (*name)(char *)
* An array of these pointers is the same with [x]
*/
char * (*functions[2])(char *) = {func1, func2};
printf("%c, ", a);
/* the functions return a pointer, so I need to deference pointer
* Thats why the * in front of the parenthesis (in case it confused you)
*/
printf("%c, ", *(*functions[0])(&a));
printf("%c\n", *(*functions[1])(&a));
a = 'a';
/* creating 'name' for a function pointer type
* funcp is equivalent to type char *(*funcname)(char *)
*/
typedef char *(*funcp)(char *);
/* Now the declaration of the array of function pointers
* becomes easier
*/
funcp functions2[2] = {func1, func2};
printf("%c, ", a);
printf("%c, ", *(*functions2[0])(&a));
printf("%c\n", *(*functions2[1])(&a));
return 0;
}
This simple example for multidimensional array with function pointers":
void one( int a, int b){ printf(" \n[ ONE ] a = %d b = %d",a,b);}
void two( int a, int b){ printf(" \n[ TWO ] a = %d b = %d",a,b);}
void three( int a, int b){ printf("\n [ THREE ] a = %d b = %d",a,b);}
void four( int a, int b){ printf(" \n[ FOUR ] a = %d b = %d",a,b);}
void five( int a, int b){ printf(" \n [ FIVE ] a = %d b = %d",a,b);}
void(*p[2][2])(int,int) ;
int main()
{
int i,j;
printf("multidimensional array with function pointers\n");
p[0][0] = one; p[0][1] = two; p[1][0] = three; p[1][1] = four;
for ( i = 1 ; i >=0; i--)
for ( j = 0 ; j <2; j++)
(*p[i][j])( (i, i*j);
return 0;
}
#include <iostream>
using namespace std;
int sum (int , int);
int prod (int , int);
int main()
{
int (*p[2])(int , int ) = {sum,prod};
cout << (*p[0])(2,3) << endl;
cout << (*p[1])(2,3) << endl;
}
int sum (int a , int b)
{
return a+b;
}
int prod (int a, int b)
{
return a*b;
}
Related
I have this code which is basically some logical gates and I want the user to give the input values and just the program to print the output.The problem is I wnat two gates to have the same inputs and so I want to give the same values to funcs_ptr[3]->in2 and
funcs_ptr[4]->in1.
#include <stdio.h>
#include <stdlib.h>
typedef int (*CallBack)(int, int);
int myand (int a, int b);
int myor(int a, int b);
int mynand (int a, int b);
int mynor(int a, int b);
int myxor(int a, int b);
typedef struct gate
{
CallBack f;
struct gate * in1 ;
struct gate * in2 ;
} Gate;
int getinput()
{
int x;
scanf("%d", &x);
return x;
}
Gate * creategate(CallBack f)
{
Gate * temp ;
temp = malloc(sizeof (Gate));
temp->f = f;
temp->in1 = NULL;
temp->in2 = NULL;
return temp;
}
int eval(Gate *x)
{
int a, b;
if (x->in1 != NULL)
a = eval(x->in1);
if (x->in2 != NULL)
b = eval(x->in2);
if (x->in1==NULL && x->in2 == NULL)
return (x->f)(0,0);
else
return (x->f)(a,b);
}
int main( )
{
int i;
CallBack funcs[] = {mynor, myand, myor, mynand, myxor};
Gate * funcs_ptr[6 ], * inputs_ptr[6];
for(i=0;i<5;i++)
funcs_ptr[i] = creategate(funcs[i]);
for(i=0;i<6;i++)
inputs_ptr[i] = creategate(getinput);
for(i=0;i<3;i++)
{
funcs_ptr[i]->in1 = inputs_ptr[i];
funcs_ptr[i]->in2 = inputs_ptr[i+1];
}
funcs_ptr[3] = creategate(funcs[3]);
funcs_ptr[3]->in1 = funcs_ptr[0];
/*--*/funcs_ptr[3]->in2 = funcs_ptr[1];
funcs_ptr[4] = creategate(funcs[4]);
/*--*/funcs_ptr[4]->in1 = funcs_ptr[1];
funcs_ptr[4]->in2 = funcs_ptr[2];
funcs_ptr[5] = creategate(funcs[3]);
funcs_ptr[5]->in1 = funcs_ptr[3];
funcs_ptr[5]->in2 = funcs_ptr[4];
printf(">>>%d\n", eval(funcs_ptr[5]));
return 0;
}
int myand (int a, int b)
{
return a * b;
}
int myor(int a, int b)
{
return a+b>0;
}
int mynand (int a, int b)
{
return myand(a,b)==0;
}
int mynor(int a, int b)
{
return myor(a,b)==0;
}
int myxor(int a, int b)
{
if(a!=b) return 1;
return 0;
}
But when I run the code the eval function calls getinput() two times instead of just passing the same value.
How can I pass the same value to both structs?
How should I use array of function pointers in C?
How can I initialize them?
You have a good example here (Array of Function pointers), with the syntax detailed.
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
[...]
To call one of those function pointers:
result = (*p[op]) (i, j); // op being the index of one of the four functions
The above answers may help you but you may also want to know how to use array of function pointers.
void fun1()
{
}
void fun2()
{
}
void fun3()
{
}
void (*func_ptr[3])() = {fun1, fun2, fun3};
main()
{
int option;
printf("\nEnter function number you want");
printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
scanf("%d",&option);
if((option>=0)&&(option<=2))
{
(*func_ptr[option])();
}
return 0;
}
You can only assign the addresses of functions with the same return type and same argument types and no of arguments to a single function pointer array.
You can also pass arguments like below if all the above functions are having the same number of arguments of same type.
(*func_ptr[option])(argu1);
Note: here in the array the numbering of the function pointers will be starting from 0 same as in general arrays. So in above example fun1 can be called if option=0, fun2 can be called if option=1 and fun3 can be called if option=2.
Here's how you can use it:
New_Fun.h
#ifndef NEW_FUN_H_
#define NEW_FUN_H_
#include <stdio.h>
typedef int speed;
speed fun(int x);
enum fp {
f1, f2, f3, f4, f5
};
void F1();
void F2();
void F3();
void F4();
void F5();
#endif
New_Fun.c
#include "New_Fun.h"
speed fun(int x)
{
int Vel;
Vel = x;
return Vel;
}
void F1()
{
printf("From F1\n");
}
void F2()
{
printf("From F2\n");
}
void F3()
{
printf("From F3\n");
}
void F4()
{
printf("From F4\n");
}
void F5()
{
printf("From F5\n");
}
Main.c
#include <stdio.h>
#include "New_Fun.h"
int main()
{
int (*F_P)(int y);
void (*F_A[5])() = { F1, F2, F3, F4, F5 }; // if it is int the pointer incompatible is bound to happen
int xyz, i;
printf("Hello Function Pointer!\n");
F_P = fun;
xyz = F_P(5);
printf("The Value is %d\n", xyz);
//(*F_A[5]) = { F1, F2, F3, F4, F5 };
for (i = 0; i < 5; i++)
{
F_A[i]();
}
printf("\n\n");
F_A[f1]();
F_A[f2]();
F_A[f3]();
F_A[f4]();
return 0;
}
I hope this helps in understanding Function Pointer.
This "answer" is more of an addendum to VonC's answer; just noting that the syntax can be simplified via a typedef, and aggregate initialization can be used:
typedef int FUNC(int, int);
FUNC sum, subtract, mul, div;
FUNC *p[4] = { sum, subtract, mul, div };
int main(void)
{
int result;
int i = 2, j = 3, op = 2; // 2: mul
result = p[op](i, j); // = 6
}
// maybe even in another file
int sum(int a, int b) { return a+b; }
int subtract(int a, int b) { return a-b; }
int mul(int a, int b) { return a*b; }
int div(int a, int b) { return a/b; }
Here's a simpler example of how to do it:
jump_table.c
int func1(int arg) { return arg + 1; }
int func2(int arg) { return arg + 2; }
int func3(int arg) { return arg + 3; }
int func4(int arg) { return arg + 4; }
int func5(int arg) { return arg + 5; }
int func6(int arg) { return arg + 6; }
int func7(int arg) { return arg + 7; }
int func8(int arg) { return arg + 8; }
int func9(int arg) { return arg + 9; }
int func10(int arg) { return arg + 10; }
int (*jump_table[10])(int) = { func1, func2, func3, func4, func5,
func6, func7, func8, func9, func10 };
int main(void) {
int index = 2;
int argument = 42;
int result = (*jump_table[index])(argument);
// result is 45
}
All functions stored in the array must have the same signature. This simply means that they must return the same type (e.g. int) and have the same arguments (a single int in the example above).
In C++, you can do the same with static class methods (but not instance methods). For example you could use MyClass::myStaticMethod in the array above but not MyClass::myInstanceMethod nor instance.myInstanceMethod:
class MyClass {
public:
static int myStaticMethod(int foo) { return foo + 17; }
int myInstanceMethod(int bar) { return bar + 17; }
}
MyClass instance;
Oh, there are tons of example. Just have a look at anything within glib or gtk.
You can see the work of function pointers in work there all the way.
Here e.g the initialization of the gtk_button stuff.
static void
gtk_button_class_init (GtkButtonClass *klass)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
gobject_class = G_OBJECT_CLASS (klass);
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
gobject_class->constructor = gtk_button_constructor;
gobject_class->set_property = gtk_button_set_property;
gobject_class->get_property = gtk_button_get_property;
And in gtkobject.h you find the following declarations:
struct _GtkObjectClass
{
GInitiallyUnownedClass parent_class;
/* Non overridable class methods to set and get per class arguments */
void (*set_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
void (*get_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
/* Default signal handler for the ::destroy signal, which is
* invoked to request that references to the widget be dropped.
* If an object class overrides destroy() in order to perform class
* specific destruction then it must still invoke its superclass'
* implementation of the method after it is finished with its
* own cleanup. (See gtk_widget_real_destroy() for an example of
* how to do this).
*/
void (*destroy) (GtkObject *object);
};
The (*set_arg) stuff is a pointer to function and this can e.g be assigned another implementation in some derived class.
Often you see something like this
struct function_table {
char *name;
void (*some_fun)(int arg1, double arg2);
};
void function1(int arg1, double arg2)....
struct function_table my_table [] = {
{"function1", function1},
...
So you can reach into the table by name and call the "associated" function.
Or maybe you use a hash table in which you put the function and call it "by name".
Regards
Friedrich
Can use it in the way like this:
//! Define:
#define F_NUM 3
int (*pFunctions[F_NUM])(void * arg);
//! Initialise:
int someFunction(void * arg) {
int a= *((int*)arg);
return a*a;
}
pFunctions[0]= someFunction;
//! Use:
int someMethod(int idx, void * arg, int * result) {
int done= 0;
if (idx < F_NUM && pFunctions[idx] != NULL) {
*result= pFunctions[idx](arg);
done= 1;
}
return done;
}
int x= 2;
int z= 0;
someMethod(0, (void*)&x, &z);
assert(z == 4);
This should be a short & simple copy & paste piece of code example of the above responses. Hopefully this helps.
#include <iostream>
using namespace std;
#define DBG_PRINT(x) do { std::printf("Line:%-4d" " %15s = %-10d\n", __LINE__, #x, x); } while(0);
void F0(){ printf("Print F%d\n", 0); }
void F1(){ printf("Print F%d\n", 1); }
void F2(){ printf("Print F%d\n", 2); }
void F3(){ printf("Print F%d\n", 3); }
void F4(){ printf("Print F%d\n", 4); }
void (*fArrVoid[N_FUNC])() = {F0, F1, F2, F3, F4};
int Sum(int a, int b){ return(a+b); }
int Sub(int a, int b){ return(a-b); }
int Mul(int a, int b){ return(a*b); }
int Div(int a, int b){ return(a/b); }
int (*fArrArgs[4])(int a, int b) = {Sum, Sub, Mul, Div};
int main(){
for(int i = 0; i < 5; i++) (*fArrVoid[i])();
printf("\n");
DBG_PRINT((*fArrArgs[0])(3,2))
DBG_PRINT((*fArrArgs[1])(3,2))
DBG_PRINT((*fArrArgs[2])(3,2))
DBG_PRINT((*fArrArgs[3])(3,2))
return(0);
}
The simplest solution is to give the address of the final vector you want , and modify it inside the function.
void calculation(double result[] ){ //do the calculation on result
result[0] = 10+5;
result[1] = 10 +6;
.....
}
int main(){
double result[10] = {0}; //this is the vector of the results
calculation(result); //this will modify result
}
This question has been already answered with very good examples. The only example that might be missing is one where the functions return pointers. I wrote another example with this, and added lots of comments, in case someone finds it helpful:
#include <stdio.h>
char * func1(char *a) {
*a = 'b';
return a;
}
char * func2(char *a) {
*a = 'c';
return a;
}
int main() {
char a = 'a';
/* declare array of function pointers
* the function pointer types are char * name(char *)
* A pointer to this type of function would be just
* put * before name, and parenthesis around *name:
* char * (*name)(char *)
* An array of these pointers is the same with [x]
*/
char * (*functions[2])(char *) = {func1, func2};
printf("%c, ", a);
/* the functions return a pointer, so I need to deference pointer
* Thats why the * in front of the parenthesis (in case it confused you)
*/
printf("%c, ", *(*functions[0])(&a));
printf("%c\n", *(*functions[1])(&a));
a = 'a';
/* creating 'name' for a function pointer type
* funcp is equivalent to type char *(*funcname)(char *)
*/
typedef char *(*funcp)(char *);
/* Now the declaration of the array of function pointers
* becomes easier
*/
funcp functions2[2] = {func1, func2};
printf("%c, ", a);
printf("%c, ", *(*functions2[0])(&a));
printf("%c\n", *(*functions2[1])(&a));
return 0;
}
This simple example for multidimensional array with function pointers":
void one( int a, int b){ printf(" \n[ ONE ] a = %d b = %d",a,b);}
void two( int a, int b){ printf(" \n[ TWO ] a = %d b = %d",a,b);}
void three( int a, int b){ printf("\n [ THREE ] a = %d b = %d",a,b);}
void four( int a, int b){ printf(" \n[ FOUR ] a = %d b = %d",a,b);}
void five( int a, int b){ printf(" \n [ FIVE ] a = %d b = %d",a,b);}
void(*p[2][2])(int,int) ;
int main()
{
int i,j;
printf("multidimensional array with function pointers\n");
p[0][0] = one; p[0][1] = two; p[1][0] = three; p[1][1] = four;
for ( i = 1 ; i >=0; i--)
for ( j = 0 ; j <2; j++)
(*p[i][j])( (i, i*j);
return 0;
}
#include <iostream>
using namespace std;
int sum (int , int);
int prod (int , int);
int main()
{
int (*p[2])(int , int ) = {sum,prod};
cout << (*p[0])(2,3) << endl;
cout << (*p[1])(2,3) << endl;
}
int sum (int a , int b)
{
return a+b;
}
int prod (int a, int b)
{
return a*b;
}
I am attempting to build a composite predicate using function pointers.
I dont know if this is possible.
My predicates are of the form: int (*predicate)(int)
Those work fine.
I want to make a function that takes 2 params of type int (*predicate)(int) and returns a function of type int (*predicate)(int), such that the new function returns the value of a(x) && b(x).
I want to make something that works like this:
int ( *composite(int (*a)(int), int (*b)(int)) )(int x) {
return a(x) && b(x);
}
or:
int ( *negate(int (*a)(int)) )(int x) {
return !a(x);
}
I understand that my attempts are returning a value, not a function, but if I try to make another function for them to return, I end up with the exact same problem.
If I do:
int composed(int (*a)(int), int (*b)(int), int x ) {
return a(x) && b(x);
}
It compiles, but then it is no longer of type int (*predicate)(int) so I cannot use it the way that I want to.
How should I go about doing this?
Complete sample code attached for reference:
#include <stdio.h>
unsigned int count(const int* xs, unsigned int len, int (*predicate)(int)) {
int c = 0;
for(int i = 0; i < len; i++) {
if(predicate(xs[i])) c++;
}
return c;
}
int isEven(int x) { return x % 2 == 0; }
int isOdd(int x) { return !isEven(x); }
int isPos(int x) { return x > 0; }
int isNeg(int x) { return x < 0; }
// int composed(int (*a)(int), int (*b)(int), int x ) {
// return a(x) && b(x);
// }
//
// int ( *composite(int (*a)(int), int (*b)(int)) )(int x) {
// return &composed(a,b)(x)
// }
int main() {
int xs[] = {-5,-4,-3,-2,-1,0,1,2,3,4,5};
const int len = 11;
printf("Even: %d\n", count(xs, len, &isEven));
printf(" Odd: %d\n", count(xs, len, &isOdd));
printf(" Pos: %d\n", count(xs, len, &isPos));
printf(" Neg: %d\n", count(xs, len, &isNeg));
// int (*compositePtr)(int) = composite(&isNeg, &isOdd);
// printf("Odd & Neg: %d", count(xs, len, compositePtr));
}
I once wrote the following code for demonstration purposes:
#include <stdio.h>
/* one int for the implicit parameter n,
* one int as return type,
* one int as parameter.
*/
typedef struct int_int_int_closure {
int (*call)(const struct int_int_int_closure *, int);
int n;
} int_int_int_closure;
static int
adderfn(const int_int_int_closure *cl, int n) {
return cl->n + n;
}
int
main(void)
{
int_int_int_closure a3;
a3.call = adderfn;
a3.n = 3;
printf("%d\n", a3.call(&a3, 2));
return 0;
}
You could generalize this code so that the closure consists of a function pointer, a pointer to its data and the size of the data.
You can't dynamically create closures or functions in C, so you need to do something else. The easiest is to use an extra level of indirection. If you change your predicates to
int (**predicate)(void *, int)
which you call as (**predicate)(predicate, x), then you can create new dynamic predicates quite easily:
typedef int (*predicate_t)(void *, int);
struct compose_fn_data {
predicate_t fn, *a, *b;
};
int and_fn(void *data_, int x) {
struct compose_fn_data *data = data_;
return (**data->a)(data->a, x) && (**data->b)(data->b, x);
}
int or_fn(void *data_, int x) {
struct compose_fn_data *data = data_;
return (**data->a)(data->a, x) || (**data->b)(data->b, x);
}
predicate_t *compose(predicate_t fn, predicate_t *a, predicate_t *b) {
struct compose_fn_data *rv = malloc(sizeof *rv);
rv->fn = fn;
rv->a = a;
rv->b = b;
return &rv->fn;
}
predicate_t *and(predicate_t *a, predicate_t *b) { return compose(and_fn, a, b); }
predicate_t *or(predicate_t *a, predicate_t *b) { return compose(or_fn, a, b); }
On minor annoyance with this is that for simple functions, you need to define an additional one-word data structure to hold the function pointer, just to indirect through it. You usually do this with a global next to the function definition:
int isEven_fn(void *data, int x) { (void)data; return x % 2 == 0; }
predicate_t isEven = isEven_fn;
int isOdd_fn(void *data, int x) { return !isEven_fn(data, x); }
predicate_t isOdd = isOdd_fn;
int isPos_fn(void *data, int x) { (void)data; return x > 0; }
predicate_t isPos = isPos_fn;
int isNeg_fn(void *data, int x) { (void)data; return x < 0; }
predicate_t isNeg = isNeg_fn;
Now you can do things like:
printf("Even: %d\n", count(xs, len, &isEven));
printf("Odd & Neg: %d", count(xs, len, and(&isNeg, &isOdd)));
printf("%d", count(xs, len, or(and(&isNeg, &isOdd), &isEven)));
though the latter do leak memory.
When the syntax for passing function pointers to/from functions was invented, I suspect that lots of unmentionable substances were smoked.
Given a function pointer int (*)(int), a function returning such a function pointer is declared as:
int (*func(void))(int);
1 2 3
Where 1 = return type of the function pointer, 2 is the parameter list of the function and 3 = the parameter list of the function pointer.
Now if you want to make a function returning one such pointer, and take two such pointers as parameters, it is trivial:
int (*func(int(*a)(int), int(*b)(int)))(int)
No, it isn't trivial... this is madness! If you can actually write and understand code like this, then it means you have simply worked far too much with C for your own good.
What you absolutely should do instead, is to use a typedef.
typedef int (predicate_t)(int);
...
predicate_t* func (predicate_t* a, predicate_t* b);
However, I suspect that you actually just need a function which returns an integer and not a function pointer.
Here's a block-based implementation of your effort to create compositions of predicate functions:
//
// ViewController.m
// PredicateFunctionsExercise
//
// Created by James Alan Bush on 3/12/22.
//
#import "ViewController.h"
#import simd;
typedef int (^boolean_expression)(void);
typedef int (^guarded_boolean_expression)(void);
typedef int (^ const (*guarded_boolean_expression_t))(void);
typedef int (^(^conditional_boolean_expression)(guarded_boolean_expression_t))(void);
typedef int (^ const (^ const (*conditional_boolean_expression_t))(guarded_boolean_expression_t))(void);
typedef int (^predicate)(void);
typedef int (^ const (*predicate_t))(void);
static int c = 0;
static int flag = (1 << 0);
guarded_boolean_expression flag_conditional = ^ int { return flag; };
conditional_boolean_expression isEven = ^ (guarded_boolean_expression_t _Nullable x) { return ^ int { int result = (*x)() % 2 == 0; printf("%d %s (%d)\t", flag, (result) ? "is even" : "is not even", result); return result; }; };
conditional_boolean_expression isOdd = ^ (guarded_boolean_expression_t _Nullable x) { return ^ int { int result = (*x)() % 2 == 1; printf("%d %s (%d)\t", flag, (result) ? "is odd" : "is not odd", result); return result; }; };
conditional_boolean_expression isPos = ^ (guarded_boolean_expression_t _Nullable x) { return ^ int { int result = (*x)() > 0; printf("%d %s (%d)\t", flag, (result) ? "is positive" : "is not positive", result); return result; }; };
conditional_boolean_expression isNeg = ^ (guarded_boolean_expression_t _Nullable x) { return ^ int { int result = (*x)() < 0; printf("%d %s (%d)\t", flag, (result) ? "is negative" : "is not negative", result); return result; }; };
static void (^evaluate_predicate)(predicate_t) = ^ (predicate_t p) {
printf("\nresult = %d (%d invocations)\n", (*p)(), c);
};
static int (^(^(^g)(__strong conditional_boolean_expression, __strong conditional_boolean_expression, guarded_boolean_expression_t))(int (^__strong)(conditional_boolean_expression_t, conditional_boolean_expression_t, guarded_boolean_expression_t)))(void) =
^ (conditional_boolean_expression boolean_conditional_a, conditional_boolean_expression boolean_conditional_b, guarded_boolean_expression_t guarded_conditional) {
return ^ (int (^bitwise_operation)(conditional_boolean_expression_t, conditional_boolean_expression_t, guarded_boolean_expression_t)) {
return ^ (int boolean_expression) {
return ^ int {
++c;
return boolean_expression;
};
}(bitwise_operation((conditional_boolean_expression_t)&boolean_conditional_a, (conditional_boolean_expression_t)&boolean_conditional_b, guarded_conditional));
};
};
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// gbe_a is set to a precalculated and stored result
// Invoking gbe_a() merely returns the results without recalculating it -- perfect for use inside the domain of discourse
guarded_boolean_expression gbe_a = g(isEven, isOdd, &flag_conditional)(^ int (conditional_boolean_expression_t boolean_conditional_a, conditional_boolean_expression_t boolean_conditional_b, guarded_boolean_expression_t guarded_conditional) {
return ((*boolean_conditional_a)(guarded_conditional)() & (*guarded_conditional)()) && (*boolean_conditional_b)(guarded_conditional);
});
guarded_boolean_expression gbe_b = g(isPos, isNeg, &flag_conditional)(^ int (conditional_boolean_expression_t boolean_conditional_a, conditional_boolean_expression_t boolean_conditional_b, guarded_boolean_expression_t guarded_conditional) {
return ((*boolean_conditional_a)(guarded_conditional)() & (*guarded_conditional)()) && (*boolean_conditional_b)(guarded_conditional);
});
// Returning a variety of bitwise operations with randomly chosen operands and operators
// to demonstrate that simd vectors can be used combining multiple bitwise operations into a single operation
simd_uint2 bit_vector = simd_make_uint2((gbe_a() << 0), (gbe_b() << 0));
simd_uint2 bit_mask = simd_make_uint2(flag, flag);
simd_uint2 results = simd_make_uint2(bit_vector & bit_mask);
printf("\n%d & %d == %d\t\t\t", bit_vector[0], bit_mask[0], results[0]);
printf("%d & %d == %d\n", bit_vector[1], bit_mask[1], results[1]);
results = simd_make_uint2(bit_vector | bit_mask);
printf("%d | %d == %d\t\t\t", bit_vector[0], bit_mask[0], results[0]);
printf("%d | %d == %d\n", bit_vector[1], bit_mask[1], results[1]);
results = simd_make_uint2(bit_vector ^ bit_mask);
printf("%d ^ %d == %d\t\t\t", bit_vector[0], bit_mask[0], results[0]);
printf("%d ^ %d == %d\n", bit_vector[1], bit_mask[1], results[1]);
}
#end
The console output:
This is probably a very basic question, but I'm having trouble with understanding pointers thoroughly. In my program below, in the main method, I'm just wondering what the right way to test my Qsort function is. Thanks in advance!
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
void swap(void *v[], int i, int j)
{
void *temp;
temp = v[i];
v[i] = v[j];
v[j]=temp;
}
int cmp1 (void *first_arg, void *second_arg)
{
int first = *(int *)first_arg;
int second = *(int *)second_arg;
if ( first < second )
{
return -1;
}
else if ( first == second )
{
return 0;
}
else
{
return 1;
}
}
int cmp2 (void * a, void * b)
{
return ( *(int *)a - *(int *)b );
}
void cmp3 (void *a, void *b)
{
char one = *(char *)a;
char two = *(char *)b;
if (one == two){
printf("The two values are equal");
}
else
{
printf("The two values are not equal");
}
}
void QSort(void *v[],int left, int right, int (*compare)(void *first, void *second))
{
int i, last;
void swap (void *v[],int ,int);
if(left >= right){
return;
}
swap(v,left,(left+right)/2);
last=left;
for(i=left+1;i<=right; i++){
if((*compare)(v[i],v[left])<0){
swap(v,++last,i);
}
}
swap(v,left,last);
QSort(v,left,last-1,compare);
QSort(v,last+1,right,compare);
}
int main()
{
int first = 23;
int second = 4;
int third = 5;
int temp[3];//={22,4,36,64,0};
temp[0] = (void *)&first;
temp[1]=(void *)&second;
temp[2]=(void *)&third;
QSort(temp, 0, 2, cmp1(.....));
for(int n=0;n<3;n++){
printf("%d ",*((int *)temp[n]));
}
return 0;
}
cmp1 is really the best way. It should always perform correctly.
cmp2 is close. It would work most of the time, but if you are dealing with very large integers, the results would be wrong.
cmp3 is definitely not right. The values are actually ints, but are being treated as chars. The results would be meaningless.
QSort(temp, 0, 2, cmp1(.....));
shoud be
QSort(temp, 0, 2, cmp1);
If foo is name of a function, then you use foo() to call it, and use foo to pass it as an argument to another function that requires a function pointer.
temp is not an integer array, it should be array of integer pointers.
line
int temp[3];
should be replaced with
int *temp[3];
How should I use array of function pointers in C?
How can I initialize them?
You have a good example here (Array of Function pointers), with the syntax detailed.
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
[...]
To call one of those function pointers:
result = (*p[op]) (i, j); // op being the index of one of the four functions
The above answers may help you but you may also want to know how to use array of function pointers.
void fun1()
{
}
void fun2()
{
}
void fun3()
{
}
void (*func_ptr[3])() = {fun1, fun2, fun3};
main()
{
int option;
printf("\nEnter function number you want");
printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
scanf("%d",&option);
if((option>=0)&&(option<=2))
{
(*func_ptr[option])();
}
return 0;
}
You can only assign the addresses of functions with the same return type and same argument types and no of arguments to a single function pointer array.
You can also pass arguments like below if all the above functions are having the same number of arguments of same type.
(*func_ptr[option])(argu1);
Note: here in the array the numbering of the function pointers will be starting from 0 same as in general arrays. So in above example fun1 can be called if option=0, fun2 can be called if option=1 and fun3 can be called if option=2.
Here's how you can use it:
New_Fun.h
#ifndef NEW_FUN_H_
#define NEW_FUN_H_
#include <stdio.h>
typedef int speed;
speed fun(int x);
enum fp {
f1, f2, f3, f4, f5
};
void F1();
void F2();
void F3();
void F4();
void F5();
#endif
New_Fun.c
#include "New_Fun.h"
speed fun(int x)
{
int Vel;
Vel = x;
return Vel;
}
void F1()
{
printf("From F1\n");
}
void F2()
{
printf("From F2\n");
}
void F3()
{
printf("From F3\n");
}
void F4()
{
printf("From F4\n");
}
void F5()
{
printf("From F5\n");
}
Main.c
#include <stdio.h>
#include "New_Fun.h"
int main()
{
int (*F_P)(int y);
void (*F_A[5])() = { F1, F2, F3, F4, F5 }; // if it is int the pointer incompatible is bound to happen
int xyz, i;
printf("Hello Function Pointer!\n");
F_P = fun;
xyz = F_P(5);
printf("The Value is %d\n", xyz);
//(*F_A[5]) = { F1, F2, F3, F4, F5 };
for (i = 0; i < 5; i++)
{
F_A[i]();
}
printf("\n\n");
F_A[f1]();
F_A[f2]();
F_A[f3]();
F_A[f4]();
return 0;
}
I hope this helps in understanding Function Pointer.
This "answer" is more of an addendum to VonC's answer; just noting that the syntax can be simplified via a typedef, and aggregate initialization can be used:
typedef int FUNC(int, int);
FUNC sum, subtract, mul, div;
FUNC *p[4] = { sum, subtract, mul, div };
int main(void)
{
int result;
int i = 2, j = 3, op = 2; // 2: mul
result = p[op](i, j); // = 6
}
// maybe even in another file
int sum(int a, int b) { return a+b; }
int subtract(int a, int b) { return a-b; }
int mul(int a, int b) { return a*b; }
int div(int a, int b) { return a/b; }
Here's a simpler example of how to do it:
jump_table.c
int func1(int arg) { return arg + 1; }
int func2(int arg) { return arg + 2; }
int func3(int arg) { return arg + 3; }
int func4(int arg) { return arg + 4; }
int func5(int arg) { return arg + 5; }
int func6(int arg) { return arg + 6; }
int func7(int arg) { return arg + 7; }
int func8(int arg) { return arg + 8; }
int func9(int arg) { return arg + 9; }
int func10(int arg) { return arg + 10; }
int (*jump_table[10])(int) = { func1, func2, func3, func4, func5,
func6, func7, func8, func9, func10 };
int main(void) {
int index = 2;
int argument = 42;
int result = (*jump_table[index])(argument);
// result is 45
}
All functions stored in the array must have the same signature. This simply means that they must return the same type (e.g. int) and have the same arguments (a single int in the example above).
In C++, you can do the same with static class methods (but not instance methods). For example you could use MyClass::myStaticMethod in the array above but not MyClass::myInstanceMethod nor instance.myInstanceMethod:
class MyClass {
public:
static int myStaticMethod(int foo) { return foo + 17; }
int myInstanceMethod(int bar) { return bar + 17; }
}
MyClass instance;
Oh, there are tons of example. Just have a look at anything within glib or gtk.
You can see the work of function pointers in work there all the way.
Here e.g the initialization of the gtk_button stuff.
static void
gtk_button_class_init (GtkButtonClass *klass)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
gobject_class = G_OBJECT_CLASS (klass);
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
gobject_class->constructor = gtk_button_constructor;
gobject_class->set_property = gtk_button_set_property;
gobject_class->get_property = gtk_button_get_property;
And in gtkobject.h you find the following declarations:
struct _GtkObjectClass
{
GInitiallyUnownedClass parent_class;
/* Non overridable class methods to set and get per class arguments */
void (*set_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
void (*get_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
/* Default signal handler for the ::destroy signal, which is
* invoked to request that references to the widget be dropped.
* If an object class overrides destroy() in order to perform class
* specific destruction then it must still invoke its superclass'
* implementation of the method after it is finished with its
* own cleanup. (See gtk_widget_real_destroy() for an example of
* how to do this).
*/
void (*destroy) (GtkObject *object);
};
The (*set_arg) stuff is a pointer to function and this can e.g be assigned another implementation in some derived class.
Often you see something like this
struct function_table {
char *name;
void (*some_fun)(int arg1, double arg2);
};
void function1(int arg1, double arg2)....
struct function_table my_table [] = {
{"function1", function1},
...
So you can reach into the table by name and call the "associated" function.
Or maybe you use a hash table in which you put the function and call it "by name".
Regards
Friedrich
Can use it in the way like this:
//! Define:
#define F_NUM 3
int (*pFunctions[F_NUM])(void * arg);
//! Initialise:
int someFunction(void * arg) {
int a= *((int*)arg);
return a*a;
}
pFunctions[0]= someFunction;
//! Use:
int someMethod(int idx, void * arg, int * result) {
int done= 0;
if (idx < F_NUM && pFunctions[idx] != NULL) {
*result= pFunctions[idx](arg);
done= 1;
}
return done;
}
int x= 2;
int z= 0;
someMethod(0, (void*)&x, &z);
assert(z == 4);
This should be a short & simple copy & paste piece of code example of the above responses. Hopefully this helps.
#include <iostream>
using namespace std;
#define DBG_PRINT(x) do { std::printf("Line:%-4d" " %15s = %-10d\n", __LINE__, #x, x); } while(0);
void F0(){ printf("Print F%d\n", 0); }
void F1(){ printf("Print F%d\n", 1); }
void F2(){ printf("Print F%d\n", 2); }
void F3(){ printf("Print F%d\n", 3); }
void F4(){ printf("Print F%d\n", 4); }
void (*fArrVoid[N_FUNC])() = {F0, F1, F2, F3, F4};
int Sum(int a, int b){ return(a+b); }
int Sub(int a, int b){ return(a-b); }
int Mul(int a, int b){ return(a*b); }
int Div(int a, int b){ return(a/b); }
int (*fArrArgs[4])(int a, int b) = {Sum, Sub, Mul, Div};
int main(){
for(int i = 0; i < 5; i++) (*fArrVoid[i])();
printf("\n");
DBG_PRINT((*fArrArgs[0])(3,2))
DBG_PRINT((*fArrArgs[1])(3,2))
DBG_PRINT((*fArrArgs[2])(3,2))
DBG_PRINT((*fArrArgs[3])(3,2))
return(0);
}
The simplest solution is to give the address of the final vector you want , and modify it inside the function.
void calculation(double result[] ){ //do the calculation on result
result[0] = 10+5;
result[1] = 10 +6;
.....
}
int main(){
double result[10] = {0}; //this is the vector of the results
calculation(result); //this will modify result
}
This question has been already answered with very good examples. The only example that might be missing is one where the functions return pointers. I wrote another example with this, and added lots of comments, in case someone finds it helpful:
#include <stdio.h>
char * func1(char *a) {
*a = 'b';
return a;
}
char * func2(char *a) {
*a = 'c';
return a;
}
int main() {
char a = 'a';
/* declare array of function pointers
* the function pointer types are char * name(char *)
* A pointer to this type of function would be just
* put * before name, and parenthesis around *name:
* char * (*name)(char *)
* An array of these pointers is the same with [x]
*/
char * (*functions[2])(char *) = {func1, func2};
printf("%c, ", a);
/* the functions return a pointer, so I need to deference pointer
* Thats why the * in front of the parenthesis (in case it confused you)
*/
printf("%c, ", *(*functions[0])(&a));
printf("%c\n", *(*functions[1])(&a));
a = 'a';
/* creating 'name' for a function pointer type
* funcp is equivalent to type char *(*funcname)(char *)
*/
typedef char *(*funcp)(char *);
/* Now the declaration of the array of function pointers
* becomes easier
*/
funcp functions2[2] = {func1, func2};
printf("%c, ", a);
printf("%c, ", *(*functions2[0])(&a));
printf("%c\n", *(*functions2[1])(&a));
return 0;
}
This simple example for multidimensional array with function pointers":
void one( int a, int b){ printf(" \n[ ONE ] a = %d b = %d",a,b);}
void two( int a, int b){ printf(" \n[ TWO ] a = %d b = %d",a,b);}
void three( int a, int b){ printf("\n [ THREE ] a = %d b = %d",a,b);}
void four( int a, int b){ printf(" \n[ FOUR ] a = %d b = %d",a,b);}
void five( int a, int b){ printf(" \n [ FIVE ] a = %d b = %d",a,b);}
void(*p[2][2])(int,int) ;
int main()
{
int i,j;
printf("multidimensional array with function pointers\n");
p[0][0] = one; p[0][1] = two; p[1][0] = three; p[1][1] = four;
for ( i = 1 ; i >=0; i--)
for ( j = 0 ; j <2; j++)
(*p[i][j])( (i, i*j);
return 0;
}
#include <iostream>
using namespace std;
int sum (int , int);
int prod (int , int);
int main()
{
int (*p[2])(int , int ) = {sum,prod};
cout << (*p[0])(2,3) << endl;
cout << (*p[1])(2,3) << endl;
}
int sum (int a , int b)
{
return a+b;
}
int prod (int a, int b)
{
return a*b;
}