我需要编写函数,用数值元素计算数组的平均值而不知道元素类型。
如果需要,需要使用数组,数组元素数和其他参数调用函数。
所以这就是我现在所拥有的:
int arr[2] = { 3,7 };
avarage(arr, 2, sizeof(int));
void * avarage(void * arr, int elements, int bytes)
{
int i;
char *p = (char *)malloc(bytes);
char *tmp = (char *)arr;
char *n;
int sum = 0;
for (i = 0; i < elements * sizeof(bytes); i++)
{
p[i] = tmp[i];
}
}
因为我不知道使用常规指针的元素类型:void *
并且还将我的类型的大小发送到我的函数中。
在我的计算机中,我可以看到bytes
为4
所以经过4次迭代后我需要将p
转换为Int
。
所以在loop
内部开始变得混乱,我不知道如何继续。
答案 0 :(得分:0)
需要编写用数值元素计算数组平均值而不知道元素类型的函数。
这有点宽泛,但有一些限制,它是可行的。
关键是传入average()
,指向函数的指针来进行加/减数学运算。 @Eugene Sh.
为了最大限度地减少内存管理,还要传递到avg()
,add_ll()
等目的地来存储结果。
轻微:对于 size 数据和数学,请使用size_t
而不是int
,因为该类型既不太窄也不太宽。
#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;
}
输出
Average = 30000200001
高级问题:具有更多错误检查的代码将使用以下内容来确保函数类型的匹配并且const
正确。
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));
或
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));