C LinkedList добавить заказал - PullRequest
       12

C LinkedList добавить заказал

2 голосов
/ 02 ноября 2010

У меня есть связанный файл List c / head как независимая библиотека, которую я использую для проекта.У меня пока нет метода упорядоченного добавления в библиотеке.Моя проблема - написать функцию сравнения, потому что я хочу сравнивать разные элементы для разных проектов.Как мне создать функцию сравнения в моем main для любого проекта, который я использую, затем передать и использовать эту функцию в метод add_ordered в моей библиотеке связанных списков?Кажется, я не могу найти подходящее решение для передачи функции и использования ее в моем связанном списке.

Вот некомпилированная версия моих методов add_ordered и compareto (сравнение с методом будет различным для каждого файла):

void ll_add_ordered(ll_node *head, void *d){
 ll_node *cur;
 ll_node *temp;

 if(head->size == 0){
  ll_add_first(head, d);
 }else{
  temp = (ll_node *)malloc(sizeof(ll_node));
  temp->data = d;

  for(cur = head->next; cur->data != NULL && compareTo(temp->data, cur->data); cur = cur->next)
   ;

  temp->next = cur;
  temp->prev = cur->prev;
  cur->prev->next = temp;
  cur->prev = temp;

  head->size++;
 }
}

int compareTo(proc *first, proc *second){
 if(first->arrival < second->arrival)
  return -1;
 else if(first->arrival > second->arrival)
  return 1;
 else
  return 0;
}

Ответы [ 3 ]

1 голос
/ 02 ноября 2010

Это определит тип с именем compareFunc:

typedef int(*compareFunc)(void *first, void *second);

Теперь вы переписали бы ll_add_ordered как:

void ll_add_ordered(ll_node *head, void *d, compareFunc compareTo) { . . .

Это будетпозволяют передавать любую функцию, которая соответствует вашей сигнатуре функции CompareTo, в ll_add_ordered и вызывать ее при сравнении.

1 голос
/ 02 ноября 2010

Один из подходов заключается в передаче указателя на функцию, которая принимает пустые * аргументы, например. int (* cmp) (void * lhs, void * rhs). В этом случае ответственность за приведение аргументов к правильному типу будет возложена на cmp.

Возможно, вы сможете сделать что-то более безопасное с помощью макросов и вставки токенов, но лично я считаю это излишним. Если вы создаете экземпляр связанного списка, то вы знаете, что это за типы, и можете передать подходящую функцию сравнения.

0 голосов
/ 02 ноября 2010

Простым решением было бы использовать указатель на функцию и передать указатель на функцию.

Я бы порекомендовал вам также объявить псевдоним для сигнатуры функции, чтобы через некоторое время вы не сошли с ума:)

Я предполагаю, что ll_node.data имеет тип void *.Таким образом, ваш связанный список требует двух вещей:

  1. Функция сравнения берет два пустых указателя, сравнивает их (используя инсайдерские знания).Функция сравнения должна знать, как обращаться с данными.Это требование, конечно, неявно применяется к человеку / коду / злому сотруднику, звонящему ll_add_ordered.
  2. Функция сравнения возвращает 1, 0 или -1.

Псевдоним типа для такого указателя функции будет:

typedef int (*ll_comp_func)(void *, void*);

Если вы думаете, что этовыглядит сумасшедшим, вы совершенно правы.Он служит для того, чтобы сделать вас сумасшедшими убойными поздними ночами, когда ничего не работает.Как бы то ни было, на самом деле он создает typedef для указателя функции и вызывает псевдоним ll_comp_func.

. Затем вы измените ваш ll_add_ordered в следующую форму:

void ll_add_ordered(ll_node *head, void *d, ll_comp_func comparison){
   // Do stuff.
   int order = comparison(temp->data, cur->data);
   // Do even more stuff.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...