Created
August 10, 2015 16:30
-
-
Save hosaka/ca9d692e390556662644 to your computer and use it in GitHub Desktop.
Usages of function pointers with structs in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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