首页 > 解决方案 > 通用数组包含在 C 中

问题描述

我有一个小函数来查找一个数字是否在数组中:

bool val_in_array(int val, int array[], size_t size)
{
    for (int i=0; i<size; i++)
        if (val == array[i])
            return true;
    return false;
}

我怎么能把它变成一个“通用”函数——例如,一个可以在intorfloat或另一种类型上工作的函数?

标签: c

解决方案


嘿,这就是个问题。让我们从标准库中举一个例子:

void *bsearch(const void *needle, const void *array,
                     size_t nmemb, size_t size,
                     int (*compar)(const void *, const void *));

所以这是一个令人印象深刻的标题。但我们可以声明val_in_array如下:

void *val_in_array(const void *needle, const void *array,
                     size_t nmemb, size_t size,
                     int (*compar)(const void *, const void *));

我们将通过返回一个指向该对象的指针(如果我们找到的话)让我们的生活更轻松。

至于实现:

{
    const char *ptr = array;
    for (int i=0; i<nmemb; i++, ptr += size)
        if (!compar(needle, ptr)
            return ptr;
    return NULL;
}

ptr这通过在输入数组上前进并为数组中的每个元素调用比较函数来工作。它知道要预付多少,因为你告诉它预付多少nmemb。调用类似于:

    int int_array[16];
    /* fill int_array */
    if (val_in_array(int_array, sizeof(int), 16, intcomp);

int intcomp(void *a, void *b)
{
    int aa = *(const int *)a;
    int bb = *(const int *)b;
    if (aa < bb) return -1;
    if (aa > bb) return 1;
    return 0;
}

稍后您将不胜感激返回指针。如果它不为空;将其转换回正确的指针类型并从中减去原始数组以获得元素的索引。

    int *found = val_in_array(...);
    if (found) {
        int index = found - int_array;
        /* ... */
    } else {
        /* not found */
    }

bsearch本质上是相同的函数,但对于排序数组并且速度更快,因为它利用了被排序的数组。


推荐阅读