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.

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