Learning by doing: Reading books and trying to understand the (code) examples
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

181 lines
4.0 KiB

#include <stdlib.h>
#include <stdio.h>
// 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(char opc);
void initialiseOperationsArray(void);
int evalArray(char 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
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(char 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(char 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(char 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;
}