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

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. // macro for easier using of saferfree function
  4. #define safeFree(p) saferFree((void**) &(p))
  5. // typedefs
  6. typedef int (*t_fptr)(int);
  7. typedef int (*t_fptr_op)(int, int);
  8. typedef void (*t_fptr_base)();
  9. // function declarations
  10. void allocateArray(int **arr, size_t size, int value);
  11. void allocateArrayWrong(int *arr, int size, int value);
  12. void saferFree(void **pointer);
  13. int square(int num);
  14. int add(int a, int b);
  15. int sub(int a, int b);
  16. //int err(int a, int b);
  17. void err(void);
  18. int operation(t_fptr_op op, int a, int b);
  19. t_fptr_op select(char opc);
  20. void initialiseOperationsArray(void);
  21. int evalArray(char opc, int a, int b);
  22. t_fptr_op operations[128] = {NULL};
  23. // pointer by reference
  24. void allocateArray(int **arr, size_t size, int value) {
  25. int *array = (int*) malloc(size * sizeof(int));
  26. if (array != NULL) {
  27. for (size_t index = 0; index < size; index++) {
  28. array[index] = value;
  29. }
  30. }
  31. *arr = array;
  32. }
  33. // pointer by value -> this will not work
  34. void allocateArrayWrong(int *arr, int size, int value) {
  35. arr = (int*) malloc(size * sizeof(int));
  36. if(arr != NULL) {
  37. for(int i = 0; i < size; i++) {
  38. arr[i] = value;
  39. }
  40. }
  41. }
  42. // safer free version which checks for NULL pointer
  43. // assigns NULL after freeing the pointer
  44. void saferFree(void **pointer) {
  45. if (pointer != NULL && *pointer != NULL) {
  46. free(*pointer);
  47. *pointer = NULL;
  48. }
  49. }
  50. // simple (unsafe) addition function
  51. int add(int a, int b) {
  52. return a + b;
  53. }
  54. // simple (unsafe) subtract function
  55. int sub(int a, int b) {
  56. return a - b;
  57. }
  58. int operation(t_fptr_op op, int a, int b) {
  59. return op(a, b);
  60. }
  61. // simple (unsafe) square function
  62. int square(int num) {
  63. return num * num;
  64. }
  65. // function selector
  66. // returns pointer to selected function
  67. t_fptr_op select(char opc) {
  68. switch (opc) {
  69. case '+': return add;
  70. case '-': return sub;
  71. default : return (t_fptr_op) err;
  72. }
  73. }
  74. // error function
  75. void err(void) { //int a, int b) {
  76. fprintf(stderr, "invalid operation!\n");
  77. //return 42;
  78. }
  79. // evaluate given operation on a & b
  80. // operation is given by function pointer
  81. int eval(char opc, int a, int b) {
  82. t_fptr_op operation = select(opc);
  83. return operation(a, b);
  84. }
  85. // initialise operations array
  86. // with pointers to add & sub functions
  87. void initialiseOperationsArray(void) {
  88. operations['+'] = add;
  89. operations['-'] = sub;
  90. }
  91. // eval function which works with
  92. // the array of function pointers
  93. int evalArray(char opc, int a, int b) {
  94. t_fptr_op operation;
  95. operation = operations[opc];
  96. return operation(a, b);
  97. }
  98. int main (void) {
  99. // variable definitions
  100. size_t size = 8;
  101. int value = 5;
  102. int *vector = NULL;
  103. //int (*fptr0) (int);
  104. t_fptr fptr0;
  105. // print vector address
  106. printf("before malloc: %p\n", vector);
  107. // function calls
  108. allocateArray(&vector, size, value);
  109. //allocateArrayWrong(vector_wrong, size, value);
  110. for (size_t index = 0; index < size; index++) {
  111. printf("%u : %d\n", (unsigned int) index, vector[index]);
  112. }
  113. // print vector address
  114. printf("before safeFree: %p\n", vector);
  115. //saferFree((void**)&(vector));
  116. safeFree(vector);
  117. // print vector address after free
  118. printf("after safeFree: %p\n", vector);
  119. // function pointer fptr0 now points to square()
  120. fptr0 = square;
  121. // call function which fptr0 points to
  122. printf("%d squared is %d\n", value, fptr0(value));
  123. // test of function pointers as function parameters
  124. printf("%u + %d = %d\n", (unsigned int) size, value, operation(add, size, value));
  125. printf("%u - %d = %d\n", (unsigned int) size, value, operation(sub, size, value));
  126. // test of fucntion pointer returning
  127. printf("%d\n", eval('t', size, value));
  128. // function pointer casting
  129. t_fptr_base basePointer;
  130. t_fptr_op fptrFirst = add;
  131. basePointer = (t_fptr_base) fptrFirst;
  132. fptrFirst = (t_fptr_op) basePointer;
  133. printf("%d\n", fptrFirst(5,6));
  134. // return value
  135. return 0;
  136. }