Skip to content

Instantly share code, notes, and snippets.

@hosaka
Created August 10, 2015 16:30
Show Gist options
  • Save hosaka/ca9d692e390556662644 to your computer and use it in GitHub Desktop.
Save hosaka/ca9d692e390556662644 to your computer and use it in GitHub Desktop.
Usages of function pointers with structs in C
#include <stdio.h>
#include <stdlib.h>
// function pointers in C
// a function is just another address in memory which contains
// executable code, similar to getting address of a variable by using
// pointers, we can get an addr of function using function pointers
void func()
{
printf("function call\n");
}
// typedefs can be used to make function pointers look more neat
// typedef typedef double (*function)(double, double) etc.
typedef void (*func_p) ();
// a little practical example of a for each iterator on the array of ints
// for each can take a functin pointer indicating which operation is to be
// performed for each value, first typedef the action function:
typedef void (*oper_p) (int*);
// write a generic function that iterates an array and takes an operation
// function pointer that we typedeffed above
void for_each (int *begin, int *end, oper_p oper)
{
while (begin != end)
{
oper(begin);
++begin;
}
}
// printinf operation
void print_int(int *val)
{
printf("int: %d\n", *val);
}
// square all values
void square_int(int *val)
{
*val *= *val;
}
// structures can encapsulate operators and function pointers
// this will change how we pass the data to functions and the callback
// will be performed from the structure function pointer
typedef int (*oper_cb)(int, int);
typedef struct
{
int x, y; // whatever params
oper_cb call; // the function pointer
} oper_t;
// so we can have a function that takes the struct as a parameter and calls
// the function pointer inside
int perform_oper (const oper_t *oper)
{
int ret = oper->call(oper->x, oper->y);
return ret;
}
// let's have an example operation of adding two integers together
int add_oper(int x, int y)
{
return x + y;
}
int sub_oper(int x, int y)
{
return x - y;
}
int main(int argc, char const *argv[])
{
// the pointer follows the function signature void *func_pointer()
// but the * has higher order of presedence than the (), that's why
// the func_pointer needs to be surrounded with another parenthesis'
// (*func_pointer)()
if (0){ void (*func_pointer)() = &func; }
void (*func_pointer)() = func; // equivalent, just deref operator
// or using a typedeffed name
func_p clean_func_pointer = &func;
// we can then invoke the function using the pointer instead of a normal
// function call
(*func_pointer)();
// or call it directly like so
func_pointer();
// call the typedeffed function
clean_func_pointer();
/********************** Various operations **********************************/
// an array of elemets
int elem[] = { 2, 4, 8, 16, 32, 64 };
int size = sizeof(elem)/sizeof(*elem);
// we can use the function pointer to perform different operations on the
// array using the for_each function, even the for_each function was not
// present in our library or came from somewhere else
for_each(elem, elem+size, square_int);
for_each(elem, elem+size, print_int);
/********************* Using Structs with function pointers *****************/
// create the operation structure and it's fields
oper_t new_oper;
new_oper.x = 20;
new_oper.y = 22;
// specify which operation to perform buy func point
new_oper.call = sub_oper;
// operation can be any functin pointer that takes 2 ints and rets an int
new_oper.call = add_oper;
// call the function that performs the operations on struct and it's members
int ret = perform_oper(&new_oper);
printf("operation result: %d\n", ret);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment