Функция, которая берет два void * и сравнивает их - PullRequest
0 голосов
/ 16 марта 2019

У меня проблема с кодированием функции сравнения в задании из моей школы.

Макет:

int compare(const void* s1,const void* s2){
/**
 * Comapares two "entries" based on their votes
 *
 * @return 0 in case if they are same, positive value if first entry is bigger than the 
 * second one, negative value if the second entry is bigger than the first one
 */
}

Так что в основном так выглядит мой макет задачи.Чтобы понять, что означают записи, они не имеют отношения к структурам, где структура в файле .h выглядит следующим образом:

struct student {
    // Name of student
    char name[BUFSIZE];
    // number of votes
    int votes;
};

И я должен взять эти записи и сравнить их на основе их голосов.Проблема в том, что void * "value", потому что я попробовал почти все из функций сравнения памяти, чтобы попытаться сохранить эту запись в этой предопределенной структуре, но если я возвращаю ее, она возвращает большие числа, и в основном я не знаю, как взять эти значения void и сравнитьих.

Я ищу любые предложения о том, как мне поступить в этой ситуации.

Ответы [ 4 ]

1 голос
/ 16 марта 2019

У указателей s1 и s2 есть 2 объекта.

Прежде чем сравнивать объекты, вам нужно в первую очередь прикрепить их типы.

Вы должны знать, какие типы должны иметь те объекты, которые остаются в этих местах, и приводить их к этим типам.

Итак, вам нужно сделать

  TYPE *obj1 = (TYPE*) s1;
  TYPE *obj2 = (TYPE*) s2;

и затем вы можете сравнить их, используя * obj1, * obj2 и т. Д.

Предположим, что в этих указателях находятся объекты типа struct student, тогда вам нужно сделать это

  struct student *a = (struct student*)s1;
  struct student *b = (struct student*)s2;

и сравните их, используя strcmp(a->name, b->name) или a->votes > b->votes a.s.o ..

0 голосов
/ 16 марта 2019

Понял!

Я использовал то, что вы, ребята, прокомментировали, и применил это к структуре так:

struct student s;
s = *(struct student *)s1;

И он работает правильно, когда я пытаюсь получить доступ к значению s.votes, у меня только один вопрос, потому что я не понимаю этот указатель до (), почему он должен быть до (), а не как (struct student *)(*s1)

0 голосов
/ 16 марта 2019

Похоже, что это функция int compare( void *, void * ), передаваемая в функцию qsort().

qsort() - это стандартная функция C :

7.22.5.2 Функция qsort

Сводка

1

      #include <stdlib.h>
      void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));

Описание

2 Функция qsort сортирует массив объектов nmemb, на начальный элемент которых указывает base.Размер каждого объекта определяется размером.

3 Содержимое массива сортируется в порядке возрастания в соответствии с функцией сравнения, на которую указывает compar, которая вызывается с двумя аргументами, указывающими на объектысравниватьФункция должна возвращать целое число меньше, равно или больше нуля, если первый аргумент считается соответственно меньше, равен или больше второго.

4 Если два элемента сравниваются как равныеих порядок в результирующем отсортированном массиве не указан.

Возвращает

5 Функция qsort не возвращает значения.

Учитывая ваш struct:

struct student {
    // Name of student
    char name[BUFSIZE];
    // number of votes
    int votes;
};

Я бы предположил, что поле votes определяет, какой struct "больше", чем другой.

Обратите внимание, что я думаю, что «вернуть 0 в случае, если они одинаковы, положительное значение, если первая запись больше, чем вторая, отрицательное значение, если вторая запись больше первой», это ужасноуказанное заявление.В буквальном смысле, каждый передаваемый указатель struct имеет точно такой же размер, как и каждый struct, поэтому строгое соблюдение этого требования означает, что все ваши функции действительно должны возвращать 0.(Если это классная работа, я очень хочу посоветовать вам включить это предупреждение, в котором вы собираетесь публиковать комментарии своего учителя по этому вопросу ...)

Но, если вы 'Повторное ранжирование в порядке голосов:

int compare( void *p1, void *p2 )
{
    struct student *s1 = p1;
    struct student *s2 = p2;

    return( s1->votes - s2->votes );
}
0 голосов
/ 16 марта 2019

В любом случае вы должны привести void* к struct student типу данных:

Это должна быть ваша реализация функции compare:

// Example program
#include <iostream>
#include <string.h>

struct student {
    // Name of student
    char name[100];
    // number of votes
    int votes;
};

int compare(const void* s1,const void* s2)
{
    // Votes comparison
    if(((struct student*)s1)->votes > ((struct student*)s2)->votes)
    {
        // s1 vote is bigger than s2 vote
        printf("the first vote is bigger than the second\n");
    }

    if(((struct student*)s1)->votes < ((struct student*)s2)->votes)
    {
        // s1 vote is less than s2 vote
        printf("the first vote is less than the second\n");
    }

    if(((struct student*)s1)->votes == ((struct student*)s2)->votes)
    {
        // s1 vote is equals to s2 vote
        printf("the first vote is equals to second\n");
    }

    // Student name comparison
    return (strcmp(((struct student*)s1)->name, ((struct student*)s2)->name));
};

В основном:

int main()
{
    student s1, s2;
    strcpy(s1.name, "a"); s1.votes = 5;
    strcpy(s2.name, "b"); s2.votes = 2;

    printf("%d", compare(&s1, &s2));
}

О strcmp Возвращаемое значение:

Эта функция возвращает следующие значения:

  • если Return value < 0, то это означает, что str1 меньше str2.

  • если Return value > 0, то оноозначает, что str2 меньше str1.

  • , если Return value = 0, то это означает, что str1 равно str2.

Попробуйте это онлайн

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