A function pointer is a pointer that points to a function
Type (*functionpointer)(Type arg1, Type arg2, ...);
The function pointer's type contains the arguments and return type of the function pointed to
int sum(int a, int b);
int (*sum_ptr)(int,int); // declares a function pointer named `sum_ptr`
sum_ptr = ∑ // `&` is not required
The function pointer can then be used by de-referencing it
printf("The sum of 2 + 3 is %d\n", (*sum_ptr)(2, 3));
printf("The sum of 2 + 3 is %d\n", (sum_ptr)(2, 3)); // `*` is not required
printf("The sum of 2 + 3 is %d\n", sum_ptr(2, 3)); // `()` are not required
#include <stdio.h>
int sum(int a, int b) { return a + b; }
int main(void) {
int (*sum_ptr)(int,int); // declares a function pointer named `sum_ptr`
sum_ptr = sum; // same as `sum_ptr = ∑`
printf("The sum of 2 + 3 is %d.\n", (*sum_ptr)(2, 3));
printf("The sum of 2 + 3 is %d.\n", (sum_ptr)(2, 3)); // `*` is not required
printf("The sum of 2 + 3 is %d.\n", sum_ptr(2, 3)); // `()` are not required
return 0;
}
Download basics.c
qsort(.)
in stdlib.h
takes a function pointer
as argument
void qsort(void* base, size_t nmemb, size_t size,
int (*compar)(const void*, const void*));
strcasecmp(.)
in <strings.h>
(resp. <cstring>
) performs case
insensitive comparison
int strcasecmp(const char* s1, const char* s2);
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
int case_insensitive_compare(const void* a, const void* b) {
return strcasecmp(*(const char**)a, *(const char**)b);
}
int main(void) {
const char* names[] = {"Harry", "Anne", "Mary", "chris", "Pat", "eric", "Lily"};
qsort(names, 7, sizeof(const char*), case_insensitive_compare);
puts("names (sorted ascending)");
for (int i = 0; i < 7; ++i) {
puts(names[i]);
}
return 0;
}
Download an internet resource without a callback
(link against curl
)
#include <stdio.h>
#include <curl/curl.h>
int main(void) {
CURL* curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://study.find-santa.eu/");
res = curl_easy_perform(curl);
if (res != CURLE_OK) // check of errors
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
return 0;
}
Download get_request.c
#include <stdio.h>
#include <curl/curl.h>
size_t write_response(void *ptr, size_t size, size_t nmemb, void *data) {
FILE* f = (FILE *) data;
puts("\033[32mwriting received data to `result.html`\033[0m");
return fwrite(ptr, size, nmemb, f);
}
int main(void) {
CURL* curl;
CURLcode res;
FILE* body;
body = fopen("result.html", "wb");
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://study.find-santa.eu/");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, body);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response);
res = curl_easy_perform(curl);
if(res != CURLE_OK) // check of errors
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
fclose(body);
return 0;
}
Download get_with_callback.c
typedef struct intarray IntArray;
struct intarray {
size_t reserved; // available storage
size_t elements; // current number of elements
int* array;
void (*push_back)(IntArray* self, int elem);
int (*sum)(const IntArray* self);
int (*count)(const IntArray* self, int elem);
IntArray* (*destruct)(IntArray* self);
};
IntArray* ia_construct();
#include <stdio.h>
#include <stdlib.h>
typedef struct intarray IntArray;
struct intarray {
size_t reserved; // available storage
size_t elements; // current number of elements
int* array;
void (*push_back)(IntArray* self, int elem);
long int (*sum)(const IntArray* self);
void (*print)(const IntArray* self);
IntArray* (*destruct)(IntArray* self);
};
IntArray* ia_destruct(IntArray* self) {
free(self->array);
self->array = (int*) NULL;
free(self);
return (IntArray*) NULL;
}
void ia_push_back(IntArray* self, int elem) {
if (self->elements == self->reserved) {
self->reserved *= 2;
self->array = realloc(self->array, self->reserved * sizeof(int));
}
self->array[self->elements] = elem;
self->elements++;
}
long int ia_sum(const IntArray* self) {
long int sum = 0;
for (size_t i = 0; i < self->elements; ++i) {
sum += self->array[i];
}
return sum;
}
void ia_print(const IntArray* self) {
if (!self->elements) {
printf("[]\n");
} else {
printf("[");
for (size_t i = 0; i < self->elements - 1; ++i) {
printf("%d,", self->array[i]);
}
printf("%d]\n", self->array[self->elements - 1]);
}
}
IntArray* ia_construct() {
IntArray* self = (IntArray*) malloc(sizeof(IntArray));
self->reserved = 100;
self->elements = 0;
self->array = (int*) malloc(self->reserved * sizeof(int));
self->print = ia_print;
self->sum = ia_sum;
self->push_back = ia_push_back;
self->destruct = ia_destruct;
return self;
}
int main(void) {
IntArray* ia = ia_construct();
ia->push_back(ia, 10);
ia->push_back(ia, 3);
ia->push_back(ia, 7);
ia->push_back(ia, 12);
ia->push_back(ia, 8);
ia->print(ia);
printf("The sum of all elements is %ld.\n", ia->sum(ia));
ia = ia->destruct(ia);
return 0;
}
Implement or rewrite the entire integer array functionality (second task of Dynamic Memory Management (Free Store) exercise using function pointers.