【问题标题】:Why don't you need to pass arguments to a qsort comparator function?为什么不需要将参数传递给 qsort 比较器函数?
【发布时间】:2012-07-06 09:13:54
【问题描述】:

以下代码取自here

* qsort example */
#include <stdio.h>
#include <stdlib.h>

int values[] = { 40, 10, 100, 90, 20, 25 };

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

int main ()
{
  int n;
  qsort (values, 6, sizeof(int), compare);
  for (n=0; n<6; n++)
     printf ("%d ",values[n]);
  return 0;
}

我们有一个比较函数,它的签名中有参数,但是当我们在 qsort 中调用它时,没有传递任何参数。 ab 的值是如何传递给函数的?谢谢

【问题讨论】:

  • 与您的问题无关,但您的比较函数有一个重大错误,除非您先验地知道数组中的整数范围受INT_MAX 的限制。
  • @R.. 我刚从 cpluscplus.com 拿了它,不过谢谢
  • cplusplus.com 是一个非常糟糕的 C 和 C++ 信息来源的另一个原因......

标签: c parameters parameter-passing void-pointers qsort


【解决方案1】:

在这个表达式的上下文中:

qsort (values, 6, sizeof(int), compare);

标识函数的子表达式compare 衰减为指向该函数的指针(而不是函数调用)。该代码实际上等效于:

qsort (values, 6, sizeof(int), &compare);

这与数组用作函数的参数时发生的情况完全相同(您以前可能见过也可能没见过,但被问得更频繁):

void f( int * x );
int main() {
   int array[10];
   f( array );      // f( &array[0] )
}

【讨论】:

  • 那么写一个没有和号的函数指针只是懒惰的做法?
  • 在函数调用中,编译器将函数转换为指向函数的指针。原因是,就像数组一样,函数不能真正按值传递,因此语言具有特定的规则,可以在函数声明和调用中执行该转换。 typedef void function(); void f( function f ); 在声明中被翻译成typedef void function(); void f(function* f);`,f( myvoidfunction ) 在被调用的地方被翻译成f( &amp;myvoidfunction )
  • 我不会称之为懒惰的方式;我会称之为一致的方式。 () 运算符(即函数调用运算符)将函数指针作为其操作数。除非您每次进行函数调用时都写(&amp;function)(...);,否则当您想将函数的地址用于非调用目的时,写&amp;function是不一致的。
  • @R.. 我不太确定。标准明确规定,对于常规函数调用,后缀表达式应为函数或函数指针,因此func() 在第一个帐户上是正确的。另一方面,只能将函数指针作为参数传递给另一个函数。也就是说,标准非常明确,可以调用函数,但只能传递指向函数的指针。无论你喜欢一种还是另一种语法是一个不同的问题,但如果目标是一致性,那么你应该通过&amp;func
  • 你从哪里得到的? C99 6.5.2.2 读取(在约束下):“表示被调用函数80 的表达式应具有指向返回 void 或返回数组类型以外的对象类型的函数的类型指针。”脚注 80 写道:“大多数情况下,这是转换作为函数指示符的标识符的结果”,即如果表达式只是一个函数名称,它会通过衰减变为函数指针。
【解决方案2】:

当调用 qsort 时,你传递了一个指向函数的指针,这就是你不指定任何参数的原因。

在 qsort 实现内部,从“values”数组中选择值并调用“compare”函数。这就是“a”和“b”的传递方式。

【讨论】:

    【解决方案3】:

    qsort 传递要比较的数组中任何项目的地址。例如,&amp;values[3]&amp;values[5]

    由于它并不真正知道数组中项目的实际类型,它使用size 参数来正确计算地址。例如看这个实现:http://insanecoding.blogspot.ie/2007/03/quicksort.html

    【讨论】:

      猜你喜欢
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多