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:
Related
I am trying to write codes in C for dynamic array (vector), and it runs okay until I add another function pointer into the struct (line29: int (findEle)(vector, int) ), and initialize it (line 153: v->findEle = findEle) to point to the function implementation (line 125: int findEle(vector* v, int value)). The debugger starts returning segmentation fault every time I tried to run it. Please find the code below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef struct Vector vector;
struct Vector
{
int currCapacity;
int currSize;
int *items;
// TODO: Try to add another int field, will cause seg fault
int (*size)(vector*);
int (*capacity)(vector*);
BOOL (*is_empty)(vector*);
void *(*at)(vector*, int);
void (*push)(vector*, int);
void (*insert)(vector*, int, int);
void (*resize)(vector*, size_t);
int (*pop)(vector*);
void (*removeValue)(vector*, int);
void (*delete_ele)(vector*, int);
int (*findEle)(vector*, int);
};
// Vector Functions
int size(vector *v)
{
return v->currSize;
}
int capacity(vector *v)
{
return v->currCapacity;
}
BOOL is_empty(vector *v)
{
if(v->currSize==0){ return TRUE; }
return FALSE;
}
void *at(vector *v, int index)
{
if(index >= v->currSize){return NULL;}
return (int*)(v->items+index);
}
void push(vector *v, int item)
{
if(v->currSize == v->currCapacity)
{
v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
v->currCapacity = v->currCapacity * 2;
}
*(v->items+v->currSize) = item;
v->currSize++;
}
void insert(vector* v, int index, int item)
{
printf("Inserting %d at index %d\n", item, index);
if(v->currSize == v->currCapacity)
{
v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
printf("v->items address: %p\n", v->items);
v->currCapacity = v->currCapacity * 2;
}
int* shift_ptr = v->items+index;
memmove(v->items+index+1, v->items+index, sizeof(int)*(v->currSize-index));
*(v->items+index) = item;
v->currSize++;
}
void resize(vector* v, size_t size)
{
printf("Resizing from %d to %d\n", v->currSize, size);
v->items = (int*)realloc(v->items, sizeof(int)* size);
}
int pop(vector* v)
{
int last = *(v->items + (v->currSize-1));
v->currSize--;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
return last;
}
void delete_ele(vector* v, int index)
{
int *curr_ptr = v->items+index;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
memmove(curr_ptr, curr_ptr+1, sizeof(int)*(v->currSize-(index+1)));
v->currSize--;
}
void removeValue(vector *v, int value)
{
for(int i=0; i<v->currSize; i++)
{
int ptr_value = *(v->items+i);
printf("%d->%d ", i, ptr_value);
if(ptr_value==value)
{
delete_ele(v, i);
--i;
}
}
printf("\n");
}
int findEle(vector* v, int value)
{
for(int i=0; i<v->currSize; i++)
{
if(*(v->items+i)==value)
{
return i;
}
}
return -1;
}
vector *initializeVector()
{
vector *v;
v->currSize = 0;
v->currCapacity = 2;
v->items = (int*)malloc(sizeof(int) * v->currCapacity);
v->size = size;
v->capacity = capacity;
v->is_empty = is_empty;
v->at = at;
v->push = push;
v->insert = insert;
v->pop = pop;
v->removeValue = removeValue;
v->delete_ele = delete_ele;
v->findEle = findEle;
return v;
}
int main()
{
vector *v = initializeVector();
v->push(v, 8);
v->push(v, 25);
v->push(v, 25);
v->push(v, 12);
printf("element 0 :%d\n", *(int*)v->at(v, 0));
printf("element 1 :%d\n", *(int*)v->at(v, 1));
printf("element 2 :%d\n", *(int*)v->at(v, 2));
printf("element 3 :%d\n", *(int*)v->at(v, 3));
v->insert(v, 1, 50);
printf("element 0 :%d\n", *(int*)v->at(v, 0));
printf("element 1 :%d\n", *(int*)v->at(v, 1));
printf("element 2 :%d\n", *(int*)v->at(v, 2));
printf("element 3 :%d\n", *(int*)v->at(v, 3));
printf("element 4 :%d\n", *(int*)v->at(v, 4));
//printf("%d\n", v->pop(v));
printf("%d\n", v->findEle(v, 25));
v->removeValue(v, 25);
for(int i=0; i<v->currSize; i++)
{
int ptr_value = *(v->items+i);
printf("%d->%d ", i, ptr_value);
}
free(v->items);
return 0;
}
I tried to debug using gdb, it returns the below message:
Program received signal SIGSEGV, Segmentation fault.
0x0040189a in initializeVector () at Vector.c:153
153 v->findEle = findEle;
When I tried to get the address of the stated function, it showed the message below:
(gdb) x v->findEle
Cannot access memory at address 0x620000
Can someone kindly advice if I have some issues on memory allocation? Or the issue might be due to some other causes? Thanks!
At least in these functions
void resize(vector* v, size_t size)
{
printf("Resizing from %d to %d\n", v->currSize, size);
v->items = (int*)realloc(v->items, sizeof(int)* size);
}
int pop(vector* v)
{
int last = *(v->items + (v->currSize-1));
v->currSize--;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
return last;
}
void delete_ele(vector* v, int index)
{
int *curr_ptr = v->items+index;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
memmove(curr_ptr, curr_ptr+1, sizeof(int)*(v->currSize-(index+1)));
v->currSize--;
}
you do not update data members currCapacity and currSize
And in this function
vector *initializeVector()
{
vector *v;
v->currSize = 0;
v->currCapacity = 2;
v->items = (int*)malloc(sizeof(int) * v->currCapacity);
v->size = size;
v->capacity = capacity;
v->is_empty = is_empty;
v->at = at;
v->push = push;
v->insert = insert;
v->pop = pop;
v->removeValue = removeValue;
v->delete_ele = delete_ele;
v->findEle = findEle;
return v;
}
there is used the uninitialized pointer v that has an indeterminate value that results in undefined behavior.
Also you need to check the value of the parameter index in each function where it is used.
i am trying to pass an int array as argument of a function who receives a void * array
The function is:
void foo(void *A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", (u32)(long)A[i]);
}
}
Then i call like this:
int A[5] = {11, 12, 13, 14, 11};
foo((void *)A, 5);
but the printed array is: 11 13 11 -2015754187 -274447056 and i dont understand why this numbers are printed.
Reading between the lines, Question 4.13: What's the total generic pointer type? in the C FAQ seems tangentially related:
There is no "total generic pointer type.".
The declaration void *A[] indicates that the function is expecting a list of void pointers, not a generic pointer to data elements. The kind of interface you seem to be seeking to implement can be found in the standard qsort function.
void qsort(void *base, size_t nel, size_t width,
int (*compar)(const void *, const void *));
Note base points to the first element of the array to be sorted. Note also that the second and third arguments are essential for qsort to be able to to different elements of the array when invoking the comparison function compar. We assume compar knows what data type its arguments are supposed to be pointing to.
I recommend studying both the prototype of qsort and compar so that you can better frame the design you are after.
While the example below probably does not correspond directly to what you are trying to do, it should be decent starting point for brainstorming:
#include <stdio.h>
#include <stdlib.h>
enum item_type {
INTARR,
INTARRLIST,
DOUBLEARR,
DOUBLEARRLIST,
};
struct item;
struct item {
enum item_type type;
size_t nelem;
void *item;
};
void
print_int_arr(const int *x, size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
printf("%d\n", x[i]);
}
}
void
print_int_arr_list(const struct item *x[], size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
const struct item *y = x[i];
print_int_arr(y->item, y->nelem);
}
}
void
print_item(struct item *x)
{
switch(x->type)
{
case INTARR:
print_int_arr(x->item, x->nelem);
break;
case INTARRLIST:
print_int_arr_list(x->item, x->nelem);
break;
default:
fprintf(stderr, "Unknown item type '%d'\n", x->type);
exit(EXIT_FAILURE);
}
}
int
main(void)
{
int x[] = {1, 3, 5, 7, 9};
struct item a = { INTARR, 5, x };
struct item b = { INTARR, 3, x };
struct item c = { INTARR, 1, x };
struct item *d[] = { &a, &b, &c };
struct item e = { INTARRLIST, 3, d };
print_item(&a);
print_item(&e);
return EXIT_SUCCESS;
}
Actually i need to be able to receive an array of any type because my intention is not to print them but to enqueue them in a queue.
What your foo function lacking is determining the type of data that should be passed as an argument, without it we cannot extract values properly from void*
Below is one of the ways to achieve what you are asking. Here I am passing the type of data and manipulating.
NOTE: This is not a generic function, it is just made to to handle some known types.
you can add more types (pointers and structs etc.) and experiment.
I am printing the data just to be sure we are extracting what we passed, but you can use them as per your need.
#include <stdio.h>
typedef enum { CHAR = 0, INT, FLOAT, STRING} DataType;
const char* getType(DataType t)
{
if(t == CHAR)
return "CHAR";
else if(t == INT)
return "INT";
else if(t == FLOAT)
return "FLOAT";
else
return "STRING";
}
void foo(void *A, unsigned int array_length, DataType type )
{
printf("type is %s and len = %d\n", getType(type), array_length);
switch(type)
{
case CHAR:
{
char *list = (char *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%c ", list[i]);
}
}
break;
case INT:
{
int *list = (int *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", list[i]);
}
}
break;
case FLOAT:
{
float *list = (float *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%.2f ", list[i]);
}
}
break;
case STRING:
{
char**list = (char**) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%s ", list[i]);
}
}
break;
default:
printf("Invalid type");
break;
}
putchar('\n');
}
int main()
{
int arr_int[] = {11, 12, 13, 14, 11};
//char arr_char[] = {"abcde"}; better way we have '\0' at the end
char arr_char[] = {'a','b','c','d','e'};
float arr_float[] = {11.20, 12.25, 13.70, 14.80, 11.15};
char* arr_strings[] = {"abc","def","ghi","jkl","mno"};
foo(arr_int, sizeof(arr_int) / sizeof(arr_int[0]), INT);
foo(arr_char, sizeof(arr_char) / sizeof(arr_char[0]), CHAR);
foo(arr_float, sizeof(arr_float) / sizeof(arr_float[0]), FLOAT);
foo(arr_strings, sizeof(arr_strings) / sizeof(arr_strings[0]), STRING);
return 0;
}
I think for foo you want an array of integers and not an array of void pointers.
Instead try?
void foo(int A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", A[i]);
}
}
Or if you can't change foo's signature.
void foo(void *A[], unsigned int array_length)
{
int* p = (int*) A;
for (unsigned int i = 0; i < array_length; ++i) {
// printf("%d ", *p++);
printf("%d ", p[i]);
}
}
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;
}
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;
}
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;
}