Сегодня я написал код C для сортировки массива структур с помощью quicksort с пользовательской функцией компаратора, чтобы определить их порядок.Что происходит, когда встроенная функция передается как параметр в C?
Сначала я написал его с вызовом функции компаратора, жестко закодированным в функцию быстрой сортировки. Тогда я подумал, что было бы лучше передать эту функцию в качестве аргумента для общей функции quicksort.
В моем первоначальном коде я объявил функцию компаратора inline
. В моем новом коде я сохранил объявление inline
, хотя это и не имело для меня большого смысла, учитывая, что функция передавалась как параметр. Однако компилятор не жаловался!
Мой вопрос: есть ли заявление inline
, имеющее какой-либо эффект здесь, или это просто рекомендация компилятору, который игнорируется?
Оригинальный код:
typedef struct _CGRect {
CGPoint origin;
CGSize size;
} CGRect;
typedef enum _NSComparisonResult {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
} NSComparisonResult;
static inline NSComparisonResult CGRectCompareRowsFirst(CGRect r1, CGRect r2)
{
if (r1.origin.y < r2.origin.y)
return NSOrderedAscending;
else if (r1.origin.y > r2.origin.y)
return NSOrderedDescending;
else
{
if (r1.origin.x < r2.origin.x)
return NSOrderedAscending;
else if (r1.origin.x > r2.origin.x)
return NSOrderedDescending;
else
return NSOrderedSame;
}
}
static void CGRectQuicksortRowsFirst(CGRect *left, CGRect *right)
{
if (right > left) {
CGRect pivot = left[(right-left)/2];
CGRect *r = right, *l = left;
do {
while (CGRectCompareRowsFirst(*l, pivot) == NSOrderedAscending) l++;
while (CGRectCompareRowsFirst(*r, pivot) == NSOrderedDescending) r--;
if (l <= r) {
CGRect t = *l;
*l++ = *r;
*r-- = t;
}
} while (l <= r);
CGRectQuicksortRowsFirst(left, r);
CGRectQuicksortRowsFirst(l, right);
}
}
static void CGRectSortRowsFirst(CGRect *array, int length)
{
CGRectQuicksortRowsFirst(array, array+length-1);
}
Новый код:
static inline NSComparisonResult CGRectCompareRowsFirst(const void *s1, const void *s2)
{
CGRect r1 = *(CGRect *)s1, r2 = *(CGRect *)s2;
if (r1.origin.y < r2.origin.y)
return NSOrderedAscending;
else if (r1.origin.y > r2.origin.y)
return NSOrderedDescending;
else
{
if (r1.origin.x < r2.origin.x)
return NSOrderedAscending;
else if (r1.origin.x > r2.origin.x)
return NSOrderedDescending;
else
return NSOrderedSame;
}
}
static void quick(CGRect *left, CGRect *right, NSComparisonResult(*f)(const void *, const void *))
{
if (right > left) {
CGRect pivot = left[(right-left)/2];
CGRect *r = right, *l = left;
do {
while (f(&*l, &pivot) == NSOrderedAscending) l++;
while (f(&*r, &pivot) == NSOrderedDescending) r--;
if (l <= r) {
CGRect t = *l;
*l++ = *r;
*r-- = t;
}
} while (l <= r);
quick(left, r, f);
quick(l, right, f);
}
}
static void CGRectSortRowsFirst(CGRect *array, int length)
{
quick(array, array+length-1, CGRectCompareRowsFirst);
}
Почему бы не использовать стандартную библиотеку 'qsort()' function? Скорее всего, это будет быстро, если не быстрее, чем у вашей ручной работы, особенно если вы передадите функцию компаратора в вашу функцию. Это также скорее всего будет ошибкой. –
Вы правы, это, вероятно, быстрее, чем мой новый код. Думаю, мой вопрос, вероятно, был бы «что произойдет, если я передам встроенную функцию qsort()?» – hatfinch