commit e23e6209c260de13339f03b697c9b6ff55f4acf6 Author: tmeissner Date: Mon Mar 31 23:50:03 2014 +0200 initial commit of sources of c-pointers book from o'reilly diff --git a/c_pointers/chapter_3.c b/c_pointers/chapter_3.c new file mode 100644 index 0000000..d19f8c9 --- /dev/null +++ b/c_pointers/chapter_3.c @@ -0,0 +1,181 @@ +#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(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; +} diff --git a/c_pointers/chapter_4.c b/c_pointers/chapter_4.c new file mode 100644 index 0000000..b9724aa --- /dev/null +++ b/c_pointers/chapter_4.c @@ -0,0 +1,33 @@ +#include +#include + + +int main(void) { + + int vector[5] = {1,2,3,4,5}; + int *pv = vector; + + printf("length of vector: %zu\n", sizeof(vector)/sizeof(int)); + + int matrix[2][3] = {{1,2,3},{4,5,6}}; + + for (size_t index = 0; index < 2; index++) { + printf("&matrix[%zu]: %p sizeof(matrix[%zu]): %zu\n", + index, &matrix[index], index, sizeof(matrix[index])); + } + + int value = 3; + for(size_t index = 0; index < sizeof(vector)/sizeof(int); index++) { + *pv++ *= value; + //pv[index] *= value; + //*(pv + index) *= value; + //vector[index] *= value; + } + + for(size_t index = 0; index < sizeof(vector)/sizeof(int); index++) { + printf("vector[%zu]: %d\n", index, vector[index]); + } + + return 0; + +} \ No newline at end of file