今天我编写了一些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);
}
答案 0 :(得分:14)
Inline只是对编译器的推荐,可以忽略。这可能由于多种原因而发生,例如,如果函数太复杂而无法安全地内联。如果将它作为参数传递给上面的函数,编译器将创建非内联版本,其地址将传递给函数。
编译器可能仍然可以内联函数 - 例如,在代码生成期间,编译器可以利用内联函数提示通过函数指针替换调用仅扩展函数;我不确定当前的编译器是否会这样做。
内联和非内联版本可以并且经常在一个已编译的程序中共存。
答案 1 :(得分:0)
'inline'关键字只是一个编译器标志,告诉它以不同的方式处理它,因为它将复制函数体并将其替换为实际的函数调用。如果您有一个小函数可以在代码中的许多位置重用,则可以提高性能。使用存取器和修改器是一件很好的事情。在你的情况下,我认为你可以保持原样。你没有做任何沉重的事情。这种差异很可能不会引人注意。