need to write function that calculate average of array with numeric values elements without knowing elements type.
This is somewhat broad, yet with a few restrictions, it is doable.
The key is to pass into the average()
, pointers to functions to do the add/divide math. @Eugene Sh..
To minimize memory management, also pass to avg()
, add_ll()
, etc., the destination to store the result.
Minor: use size_t
rather than int
for size data and math as that type is neither too narrow nor too wide.
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
// Return true on failure
// Note that a, b, etc could point to the same object
bool add_ll(void *sum, void *a, void *b) {
// TBD: add code to detect and prevent overflow
*(long long *) sum = *(long long *) a + *(long long *) b;
return false;
}
bool div_ll(void *quo, void *a, size_t n) {
if (n == 0) {
return true;
}
*(long long *) quo = *(long long *) a / n;
return false;
}
bool avg(void *bar, void *a, size_t nmemb, size_t size, bool (add)(), bool (quo)()) {
memset(bar, 0, size); // assume bits all zero is a value of zero
char (*p)[size] = a; // p is a pointer to a character array of size `size`
for (size_t i = 0; i < nmemb; i++) {
if (add(bar, bar, p)) {
return true;
}
p++; // this moves `size` bytes later
}
return quo(bar, bar, nmemb);
}
int main(void) {
long long A[3] = { 3, 600000, 90000000000 };
long long mean;
if (avg(&mean, A, sizeof A / sizeof A[0], sizeof A[0], add_ll, div_ll)) {
puts("Oops");
} else {
printf("Average = %lld\n", mean);
}
return 0;
}
Output
Average = 30000200001
Advanced issues: Code with more error checking would use the below to insure matching of function types and to be const
correct.
bool avg(void *bar, void *a, size_t nmemb, size_t size,
bool (add)(void *sum, void *a, void *b),
bool (quo)(void *quo, void *a, size_t n));
or
bool avg(void *bar, void *a, size_t nmemb, size_t size,
bool (add)(void *sum, const void *a, const void *b),
bool (quo)(void *quo, const void *a, size_t n));