2013-08-23 1 views
1

Вот функция пузырьковой сортировки я просто написал:Эквивалент кода C для Шаблонного C++

template <class iter> 
void bubble_sort(iter begin, iter end, int (*cmp)(void *, void *)) { 
    bool didSwap; 
    do { 
     didSwap = false; 
     for (iter temp = begin; (temp + 1) != end; ++temp) 
      if ((*cmp)((temp+1), (temp))) { 
       std::swap(*(temp+1), *temp); 
       didSwap = true; 
      } 
     --end; 
    } while (didSwap); 
} 

мне было интересно, если это возможно для такой вещи, чтобы быть сделаны в C. Функция сравнения отлично работает до тех пор, поскольку он не используется со стандартными контейнерами stl, такими как deque, vector, list и т. д. Но это iter begin и iter end, о которых я беспокоюсь. Поскольку вы не можете выполнить арифметику указателя с void, как я могу это сделать? Можно ли сделать это?

+0

Читайте о 'qsort'. –

+0

Это ['qsort()'] (http://en.cppreference.com/w/c/algorithm/qsort) доступно в стандартном C и было для * десятилетий *, заставило бы меня поверить в ответ на ваш вопрос просто «да, его возможно, потому что это уже реальность». И ответить, как вы указатель арифметики с 'void *'. вы этого не делаете. Вы пишете свою функцию, чтобы потребовать «размер элемента» и использовать ее с помощью математики с 'unsigned char *', отличным от вашего 'void *'. – WhozCraig

+0

Вау, как я забыл про qsort, когда писал функцию сортировки? – smac89

ответ

1

Вы можете сделать это так, как это делает функция qsort, и передать размер для типа и размера массива, а также указатель на начало массива.

void bubble_sort(void* begin, size_t num, size_t size, int (*cmp)(void*,void*)); 
+0

Не могли бы вы уточнить? Что вы подразумеваете под размером указателя? – smac89

+0

@ Smac89 Я поставил синтаксис, а также ссылку на qsort, которая объясняет использование примерами ... –

+0

@ Smac89, просто чтобы вы знали, что нужно увеличить его, чтобы перейти к следующему элементу, а не, скажем, на полпути , – chris

0

Вы, безусловно, можете получить эквивалентный результат, используя C. На самом деле, под капотом большая часть кода, который у вас есть, будет использовать основы языка C, такие как работа с указателями.

Что касается iter begin, iter end, под капотом они по существу являются C указателями. Существует встроенная процедура в C под названием qsort, чья функциональная подпись аналогична коду, который вы предоставили.

0

Это работает:

void bubble_sort(void *array, size_t num, size_t ptr_size, int (*cmp)(void *, void *)) { 
    bool didSwap; 
    do { 

     didSwap = false; 
     for (size_t temp = 0; (temp+1) < num; ++temp) 
      if ((*cmp)((bool *)(array+(temp*ptr_size)), (bool *)(array+(-~temp*ptr_size)))) { 
       std::swap(*(bool *)(array+(temp*ptr_size)), *(bool *)(array+(-~temp*ptr_size))); 
       didSwap = true; 
      } 
     --num; 
    } while (didSwap); 
} 

Хотя кто-то что-то упоминал о литье в char *, затем увеличивающиеся, char * не работал очень хорошо для этого, только bool.

Это, как я называю эту функцию в основной:

bubble_sort(arr, 20, sizeof(int), (int (*)(void *, void *))compare);