计算数字阵列元素的平均值,而不了解元素类型



我需要编写功能,以计算具有数字值元素的数组的平均值,而不了解元素类型。

如果我愿意,需要使用数组,数组元素的数量和其他参数来调用该功能。

所以这就是我到目前为止所拥有的:

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 *,也发送到我的函数中的大小。

在我的计算机中,我可以看到bytes4,因此在4个迭代后,我需要将p转换为Int

所以loop内部的事情开始搞砸了,我不知道如何继续。

需要写入功能,以计算具有数值元素的数字值元素的平均值,而不了解元素类型。

这有些广泛,但是有一些限制,这是可行的。

关键是传递到average(),指示函数进行添加/分割数学。@eugene sh ..

为了最大程度地减少内存管理,也将传递给avg()add_ll()等,是存储结果的目的地。

次要:将size_t而不是int用于 size 数据和数学,因为该类型既不狭窄也不太宽。

#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 = %lldn", 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));

最新更新