How should I use array of function pointers in C?
How can I initialize them?
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
You can also initialize p
as:
int (*p[4]) (int, int) = {sum, subtract, mul, div};
As in:
#include <stdio.h>
// Function declarations
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 (b != 0) ? a / b : 0; }
int main() {
// Array of function pointers initialization
int (*p[4]) (int, int) = {sum, subtract, mul, div};
// Using the function pointers
int result;
int i = 20, j = 5, op;
for (op = 0; op < 4; op++) {
result = p[op](i, j);
printf("Result: %d\n", result);
}
return 0;
}
As note by Gauthier in the comments
You can call functions by a pointer without dereferencing it.
Some might argue that they want the dereference to be explicit, so they know what they're dealing with.
Others would reply that it's a known idiom, and that there isn't much more thatp[op]()
could ever mean.
result = p[op](i, j);
works
Daniel Heimgartner confirms in the comments:
Initializing the array of pointers
p[0] = sum
andp[0] = &sum
are equivalent.
Similarly, when calling a function (via a function pointer) you do not need to dereference(*)
it: See this Stack Overflow question "How come a pointer to a function be called without dereferencing?"
(*p[4]) (int, int) {sum,substract,mul,div}
–
Ogburn p[op]()
could ever mean. result = p[op](i, j);
works. –
Mclane p[0] = sum
and p[0] = &sum
are equivalent. Similarly, when calling a function (via a function pointer) you do not need to dereference (*
) it... See this stackoverflow question. –
Doing 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:
#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
#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");
}
#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.
f1, f2 ...
and in place of then enter 'writefile, readfromfile...'... it becomes more redable –
Sonja 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; }
_t
, although this seems controversial for user defined types. –
Mclane 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;
}
Here is the sample code for invoking functions with different signatures with array of pointers.
#include<stdio.h>
#define TOTAL_FUNCTIONS 3
#define FUNCTION_ADD 0
#define FUNCTION_SUBTRACT 1
#define FUNCTION_MULTIPLY 2
int funcAdd(int a, int b, int c)
{
return a+b+c;
}
void funcSubtract(int a, int b)
{
printf("\nDiffrence = %d\n",a*b);
}
int funcMultiply(int a, int b)
{
return a*b;
}
int main()
{
void* funPtr[3] = {funcAdd, funcSubtract, funcMultiply};
int result = 0;
int index = 0;
while(index < TOTAL_FUNCTIONS){
switch(index){
case FUNCTION_ADD:
result = ((int (*)(int, int, int))funPtr[FUNCTION_ADD])(2,3,4);
printf("\nSum = %d\n", result);
break;
case FUNCTION_SUBTRACT:
((void (*)(int, int))funPtr[FUNCTION_SUBTRACT])(5,3);
break;
case FUNCTION_MULTIPLY:
result = ((int (*)(int, int))funPtr[FUNCTION_MULTIPLY])(2,3);
printf("\nProduct %d\n", result);
break;
default:
break;
}
++index;
}
return 0;
}
void *
is an object pointer), and C does not allow conversion between them. If you turn compiler diagnostics up to -pedantic
level you should see warnings. Such conversion is allowed as a common extension, but not Standard C. But C does allow conversion between function pointers, so instead of an array of void *
you could do something like typedef void (GenFunc)(void); /* ... */ GenFunc *funPtr[3] = { (GenFunc *)funcAdd, /* ... */ };
. –
Loydloydie #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;
}
© 2022 - 2024 — McMap. All rights reserved.