【问题标题】:How to handle unknown type of numbers in C? [duplicate]如何在C中处理未知类型的数字? [复制]
【发布时间】:2018-02-20 08:54:46
【问题描述】:

我需要编写一个方法来计算未知类型数字(double、float、int...)的平均值。我试图做这样的事情,但它只适用于双类型:

double average(void *arr, int length, int bytes) {
    int i;
    double sum = 0;
    double num;
    for (i = 0; i < length; i++) {
        memcpy(&num, (char *) arr, bytes);
        sum += num;
        arr = (char *) arr + bytes;
    }
    return sum / length;
}

有什么建议吗?

【问题讨论】:

  • 这是不可能的。您有一个 void* 指向原始内存。您无法从原始字节中确定存在哪些类型的数字。您可以将原始字节视为一堆整数、浮点数、双精度数或任何疯狂的混合。你到底想做什么?
  • 你有一个不可能完成的任务。区分类型的唯一方法是 bytes 参数,它无法帮助您处理 intfloat,因为它们的大小通常相同。如果可以使用long long,那么它和double 就有问题。如果你传递一个整数数组,它是有符号的还是无符号的?
  • 在 C 中解决此类问题的唯一方法是使用 generic selection
  • 那么可以传递数组的类型吗?

标签: c pointers void-pointers


【解决方案1】:

如果您不知道它们是什么类型,则无法对数组值求和。仅依靠bytes 参数是不够的,因为intfloat 在许多编译器中通常是相同的大小,但它们是非常不同的类型。使用void* 操作时会丢失类型信息。

如果您必须使用void*,解决此问题的唯一方法是传入一个指定数组实际保存的类型的参数,然后相应地转换void*

我建议为每种类型编写一个单独的函数,例如:

enum dataType {dtInt, dtFloat, dtDouble};

double averageInt(int *arr, int length)
{
    double sum = 0;
    for (int i = 0; i < length; ++i)
        sum += arr[i];
    return sum / length;
}

double averageFloat(float *arr, int length)
{
    double sum = 0;
    for (int i = 0; i < length; ++i)
        sum += arr[i];
    return sum / length;
}

double averageDouble(double *arr, int length)
{
    double sum = 0;
    for (int i = 0; i < length; ++i)
        sum += arr[i];
    return sum / length;
}

double average(void *arr, int length, enum dataType arrType)
{
    switch (arrType)
    {
        case dtInt:    return averageInt((int*)arr, length);
        case dtFloat:  return averageFloat((float*)arr, length);
        case dtDouble: return averageDouble((double*)arr, length);
    }
    return 0;
}

或者:

enum dataType {dtInt, dtFloat, dtDouble};

double sumInt(int *arr, int length)
{
    double sum = 0;
    for (int i = 0; i < length; ++i)
        sum += arr[i];
    return sum;
}

double sumFloat(float *arr, int length)
{
    double sum = 0;
    for (int i = 0; i < length; ++i)
        sum += arr[i];
    return sum;
}

double sumDouble(double *arr, int length)
{
    double sum = 0;
    for (int i = 0; i < length; ++i)
        sum += arr[i];
    return sum;
}

double average(void *arr, int length, enum dataType arrType)
{
    double sum;
    switch (arrType)
    {
        case dtInt:    sum = sumInt((int*)arr, length); break;
        case dtFloat:  sum = sumFloat((float*)arr, length); break;
        case dtDouble: sum = sumDouble((double*)arr, length); break;
        default:       sum = 0; break;
    }
    return sum / length;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2010-10-03
    • 1970-01-01
    相关资源
    最近更新 更多