不传递参数比较函数如何工作

without passing arguments how compare funcation work

我想对 struct 数组进行排序,但在理解比较函数的逻辑时我仍然感到困惑,我的困惑是当调用 qsort() 函数而不传递参数时比较函数是如何工作的

在 windows 上的代码块上使用 GCC:

代码

int compare(const void * a, const void * b);

struct cricketers
{
  int avrun;
  char name[30];
  int age;
  int notm;
}india[Max] = {
  122, "Sachin Tendulkar", 30, 67,
  97, "Virendra Sehwag", 35, 56,
  66, "Irfan Pathan", 32, 45,
  153, "Yusuf Pathan", 36, 21,
  101, "Yuvaraj Singh", 32, 45,
};

int main()
{
  int i;
  qsort(india, 5, sizeof(struct cricketers), compare);

  for (i = 0; i < 5; i++)
  {
    printf("Name : %s", india[i].name);
    printf("\nAge : %d", india[i].age);
    printf("\nTotal Test Matches played : %d", india[i].notm);
    printf("\nAverage Run : %d\n\n\n", india[i].avrun);
  }
  _getch();
  return 0;
}

int compare(const void * a, const void * b)
{
  return (*(int*)a - *(int*)b);
}

是函数qsort在内部调用比较函数传递给它的void指针指向数组的两个元素

根据 C 标准(6.7.2.1 结构和联合说明符)结构的第一个成员的地址等于结构类型的整个对象的地址。

15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

因此,例如参数 a 的值转换为类型 int * 会产生结构的数据成员 int avrun 的地址。

然而,由于有符号整数的过度浮动,此表达式 (*(int*)a - *(int*)b) 可以调用未定义的行为。

我会按以下方式编写比较函数。

int compare( const void *a, const void *b )
{
    const struct cricketers *left  = ( const struct cricketers * )a;
    const struct cricketers *right = ( const struct cricketers * )b;

    return ( right->avrun < left->avrun ) - ( left->avrun < right->avrun ); 
}