c поиск в массиве универсального типа - PullRequest
3 голосов
/ 02 мая 2019

У меня есть 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 struct, если я изменю сигнатуру функции на:

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

и вызов метода для:

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

, но не для bar struct и наоборот.

Моя цель - создать одну функцию / процедуру без дублирования кода с помощью указателяарифметика.Я думаю, что универсальные типы не существуют в C, поэтому я подумал, что могу использовать размер моей структуры, чтобы использовать арифметику указателей.Помогите, если это возможно?

1 Ответ

3 голосов
/ 02 мая 2019

Вам нужно будет передать размер структуры в функцию и выполнить арифметику указателей на 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;
}

[Пример в реальном времени]


Примечание: вы передаете размер массива как int, а индекс в массив как short.Эти типы должны совпадать, иначе ваш код будет разбит на массивы, размер которых не вписывается в short.

Аналогично, параметр query должен иметь тип unsigned short, а не int,поскольку это то, что на самом деле хранится в структурах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...