2009-06-22 37 views
2

今天我写了一些C代码,用一个自定义比较函数使用快速排序来对结构数组进行排序,以确定它们的排序。将内联函数作为C中的参数传递时会发生什么?

起初我与调用比较函数硬编码到快速排序函数写的。然后我认为将这个函数作为一个通用快速排序函数的参数可能会更好。

在我的原代码,我已宣布了比较器功能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

为什么不使用标准库的qsort'()'函数?这可能与您手工制作的一样快,甚至更快,特别是如果您将比较器功能传递到您的功能。它也更可能是无bug的。 – 2009-06-23 00:59:59

+0

你说得对,那可能比我的新代码至少快。我想我的问题可能应该是“如果我将内联函数传递给qsort()会发生什么?” – hatfinch 2009-06-23 13:13:14

回答

13

内联仅仅是对编译器的建议,可以忽略不计。出现这种情况的原因可能有多种,例如功能太复杂,无法安全内联。如果您将它作为参数传递给上述函数,编译器将创建其地址将传递给该函数的非内联版本。

它可能是编译器仍然可以内联函数 - 例如,代码生成期间,编译器可以利用内联函数提示经由函数指针替换呼叫只扩展功能;我不确定目前的编译器是否会这样做。

内联和非内联的版本可以并且经常一个编译的程序内共同存在。

0

的“内联”关键字是一个简单的编译器标志,告诉它,它会在体内复制的功能,不同的方式处理,并用实际的函数调用替换它。如果你有一个小函数可以在你的代码中的许多地方重用,这会提高性能。使用访问器和修饰符是一件很好用的事情。就你而言,我认为你可以保持原样。你没有做任何重要的事情。差异很可能不会引起注意。

+0

再看看我的问题。我知道'inline'呢 - 我只是想知道这是多么有意义通过内联函数作为参数传递给另一个函数。 – hatfinch 2009-06-23 13:23:34

相关问题