#include #include // macro for easier using of saferfree function #define safeFree(p) saferFree((void**) &(p)) // typedefs typedef int (*t_fptr)(int); typedef int (*t_fptr_op)(int, int); typedef void (*t_fptr_base)(); // function declarations void allocateArray(int **arr, size_t size, int value); void allocateArrayWrong(int *arr, int size, int value); void saferFree(void **pointer); int square(int num); int add(int a, int b); int sub(int a, int b); //int err(int a, int b); void err(void); int operation(t_fptr_op op, int a, int b); t_fptr_op select(int opc); void initialiseOperationsArray(void); int eval(int opc, int a, int b); int evalArray(int opc, int a, int b); t_fptr_op operations[128] = {NULL}; // pointer by reference void allocateArray(int **arr, size_t size, int value) { int *array = (int*) malloc(size * sizeof(int)); if (array != NULL) { for (size_t index = 0; index < size; index++) { array[index] = value; } } *arr = array; } // pointer by value -> this will not work void allocateArrayWrong(int *arr, int size, int value) { arr = (int*) malloc(size * sizeof(int)); if(arr != NULL) { for(int i = 0; i < size; i++) { arr[i] = value; } } } // safer free version which checks for NULL pointer // assigns NULL after freeing the pointer // hint: check for null before free() isn't neccessary void saferFree(void **pointer) { if (pointer != NULL && *pointer != NULL) { free(*pointer); *pointer = NULL; } } // simple (unsafe) addition function int add(int a, int b) { return a + b; } // simple (unsafe) subtract function int sub(int a, int b) { return a - b; } int operation(t_fptr_op op, int a, int b) { return op(a, b); } // simple (unsafe) square function int square(int num) { return num * num; } // function selector // returns pointer to selected function t_fptr_op select(int opc) { switch (opc) { case '+': return add; case '-': return sub; default : return (t_fptr_op) err; } } // error function void err(void) { //int a, int b) { fprintf(stderr, "invalid operation!\n"); //return 42; } // evaluate given operation on a & b // operation is given by function pointer int eval(int opc, int a, int b) { t_fptr_op operation = select(opc); return operation(a, b); } // initialise operations array // with pointers to add & sub functions void initialiseOperationsArray(void) { operations['+'] = add; operations['-'] = sub; } // eval function which works with // the array of function pointers int evalArray(int opc, int a, int b) { t_fptr_op operation; operation = operations[opc]; return operation(a, b); } int main (void) { // variable definitions size_t size = 8; int value = 5; int *vector = NULL; //int (*fptr0) (int); t_fptr fptr0; // print vector address printf("before malloc: %p\n", vector); // function calls allocateArray(&vector, size, value); //allocateArrayWrong(vector_wrong, size, value); for (size_t index = 0; index < size; index++) { printf("%u : %d\n", (unsigned int) index, vector[index]); } // print vector address printf("before safeFree: %p\n", vector); //saferFree((void**)&(vector)); safeFree(vector); // print vector address after free printf("after safeFree: %p\n", vector); // function pointer fptr0 now points to square() fptr0 = square; // call function which fptr0 points to printf("%d squared is %d\n", value, fptr0(value)); // test of function pointers as function parameters printf("%u + %d = %d\n", (unsigned int) size, value, operation(add, size, value)); printf("%u - %d = %d\n", (unsigned int) size, value, operation(sub, size, value)); // test of fucntion pointer returning printf("%d\n", eval('t', size, value)); // function pointer casting t_fptr_base basePointer; t_fptr_op fptrFirst = add; basePointer = (t_fptr_base) fptrFirst; fptrFirst = (t_fptr_op) basePointer; printf("%d\n", fptrFirst(5,6)); // return value return 0; }