【问题标题】:c search in array of generic typec 在泛型类型的数组中搜索
【发布时间】:2019-09-20 19:28:40
【问题描述】:

我有 2 个结构,

typedef struct
{
    unsigned short id;
    char name[10];
    char email[10];
} foo;

typedef struct
{
    unsigned short id;
    char test[10];
    float ok;
} bar;

我需要创建一个可重用函数/过程,在这些结构的两个数组中搜索一个值。

这是我的功能:

short search_array(const int *array, const int dim, int query)
{
    short idx = -1;

    if (query >= 0)
    {
        for (int i = 0; i < dim; i++)
        {
            /*
             * since array is a generic pointer,
             * take:
             *  pointer to the position array+ i
             *  convert the value to unsigned short
             *  finally get final value of short
             */
            if ((*(unsigned short *) (array + i)) == query)
            {
                idx = i;
                i = dim;
            }
        }
    }

    return idx;
}

这是我的主要内容:

int main()
{
    foo a = {10, "ok", "pippo"};
    foo b = {50, "si", "gino"};
    foo c = {30, "si", "peppo"};

    foo foos[3] = {a, b, c};

    bar a1 = {6, "mario", 5.5};
    bar b2 = {56, "mimmo", 0};
    bar c3 = {69, "maronno", 9};

    bar bars[3] = {a1, b2, c3};

    int x = search_array((const int *) foos, 3, 50);
    int x1 = search_array((const int *) foos, 3, 9999999);

    int y = search_array((const int *) bars, 3, 69);
    int y1 = search_array((const int *) bars, 3, 9999999);

    return 0;
}

如果我将函数的签名更改为:它适用于 foo 结构:

short search_array(const foo *array, const int dim, int query)

并调用方法:

int x = search_array(foos, 3, 30);

但不适用于bar 结构,反之亦然。

我的目标是通过使用指针算法创建一个函数/过程并且没有代码重复。 我认为 C 中不存在泛型类型,所以我认为我可以使用我的结构的大小来使用指针算术。可以的话帮忙吗?

【问题讨论】:

  • 如果对数组进行排序并不重要,您可以简单地使用标准库中的bsearch(以及可选的qsort)。

标签: c arrays search


【解决方案1】:

您需要将结构的大小传递给函数,并对char 大小的单位进行指针运算:

short search_array(const void *array, const int dim, const int item_size, int query)
{
    short idx = -1;

    if (query >= 0)
    {
        for (int i = 0; i < dim; i++)
        {
            /*
             * since array is a generic pointer,
             * take:
             *  pointer to the position array+ i
             *  convert the value to unsigned short
             *  finally get final value of short
             */
            if ((*(unsigned short *) ((const char*)array + i * item_size)) == query)
            {
                idx = i;
                i = dim;
            }
        }
    }

    return idx;
}


int main()
{
    foo a = {10, "ok", "pippo"};
    foo b = {50, "si", "gino"};
    foo c = {30, "si", "peppo"};

    foo foos[3] = {a, b, c};

    bar a1 = {6, "mario", 5.5};
    bar b2 = {56, "mimmo", 0};
    bar c3 = {69, "maronno", 9};

    bar bars[3] = {a1, b2, c3};

    int x = search_array(foos, 3, sizeof foos[0], 50);
    int x1 = search_array(foos, 3, sizeof foos[0], 9999999);

    int y = search_array(bars, 3, sizeof bars[0], 69);
    int y1 = search_array(bars, 3, sizeof bars[0], 9999999);

    return 0;
}

[Live example]


旁注:您将数组大小传递为int,但数组的索引为short。这些类型应该匹配,否则你的代码会因为数组的大小不适合short而中断。

同样,参数query 应该是unsigned short 类型而不是int,因为这是结构中实际存储的内容。

【讨论】:

  • 谢谢;现在我将函数参数更改为size_t dimunsigned short query。 2个问题:我可以用sizeof(foo)代替sizeof(foos[0])吗?你为什么使用char 大小的单位?是因为 char 大小为 1 吗?
  • @user3744384 是的,你当然也可以使用sizeof(foo)。我选择了sizeof foos[0] 使其面向未来。 foos 类型的变化。对于第二个问题:由于sizeof 的值是以char 为单位的,因此您需要对char* 进行基于大小的指针运算(而不是基于项的指针运算)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 2015-07-25
  • 2011-10-20
  • 2011-04-20
  • 2021-01-29
  • 1970-01-01
相关资源
最近更新 更多