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
// `*` is not required
std::cout << "The sum of 2 + 3 is " << (*sum_ptr)(2, 3) << "." << std::endl;
std::cout << "The sum of 2 + 3 is " << (sum_ptr)(2, 3) << "." << std::endl;
std::cout << "The sum of 2 + 3 is " << sum_ptr(2, 3) << "." << std::endl;
#include <iostream>
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 = ∑`
std::cout << "The sum of 2 + 3 is " << (*sum_ptr)(2, 3) << ".\n";
std::cout << "The sum of 2 + 3 is " << (sum_ptr)(2, 3) << ".\n";
std::cout << "The sum of 2 + 3 is " << sum_ptr(2, 3) << ".\n";
return 0;
}
Download basics.cpp
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 <cstdlib>
#include <cstring>
#include <iostream>
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);
std::cout << "names (sorted ascending)" << std::endl;
for (int i = 0; i < 7; ++i) {
std::cout << names[i] << std::endl;
}
return 0;
}
Download an internet resource without a callback
(link against curl
)
#include <iostream>
#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
std::cerr << "curl_easy_perform() failed: "
<< curl_easy_strerror(res) << std::endl;
curl_easy_cleanup(curl);
}
return 0;
}
Download get_request.cpp
#include <cstdio>
#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* req_body;
req_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, req_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(req_body);
return 0;
}
Download get_with_callback.cpp
struct 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* construct();
#include <algorithm>
#include <iostream>
#include <stdlib.h>
using std::cout;
namespace ia {
struct 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* destruct(IntArray* self) {
delete[] self->array;
self->array = (int*) NULL;
delete self;
return (IntArray*) NULL;
}
void push_back(IntArray* self, int elem) {
if (self->elements == self->reserved) {
int* old_data = self->array;
self->reserved *= 2;
self->array = new int[self->reserved];
std::copy_n(old_data, self->elements, self->array);
delete[] old_data;
}
self->array[self->elements] = elem;
self->elements++;
}
long int sum(const IntArray* self) {
long int sum = 0;
for (size_t i = 0; i < self->elements; ++i) {
sum += self->array[i];
}
return sum;
}
void print(const IntArray* self) {
if (!self->elements) {
cout << "[]\n" ;
} else {
cout << "[";
for (size_t i = 0; i < self->elements - 1; ++i) {
cout << self->array[i] << ", ";
}
cout << self->array[self->elements - 1] << "]\n";
}
}
IntArray* construct() {
IntArray* self = new IntArray;
self->reserved = 100;
self->elements = 0;
self->array = new int[self->reserved];
self->print = print;
self->sum = sum;
self->push_back = push_back;
self->destruct = destruct;
return self;
}
} // namespace ia
int main(void) {
ia::IntArray* a = ia::construct();
a->push_back(a, 10);
a->push_back(a, 3);
a->push_back(a, 7);
a->push_back(a, 12);
a->push_back(a, 8);
a->print(a);
cout << "The sum of all elements is " << a->sum(a) << ".\n";
a = a->destruct(a);
return 0;
}
Implement or rewrite the entire integer array functionality (second task of Dynamic Memory Management (Free Store) exercise using function pointers.