2012-07-05 113 views
1

以下代码取自here为什么不需要将参数传递给qsort比较器函数?

* 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的值是如何传递给函数的?由于

+0

与你的问题没有关系,但是你的比较函数有一个主要的错误,除非你事先知道你的数组中的整数范围受到'INT_MAX'的限制。 – 2012-07-06 03:42:12

+0

@R ..我只是把它从cpluscplus.com,谢谢您的好意 – Steve 2012-07-07 00:17:00

+0

另一个原因cplusplus.com是C和C++信息的残暴恶劣源... – 2012-07-07 00:59:41

回答

4

在该表达式中的上下文:

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]) 
} 
+0

所以写一个函数指针无符号只是偷懒的方法做到这一点? – Steve 2012-07-05 22:21:54

+1

在函数调用中,编译器将函数的指针转换为该函数的指针。原因是,就像数组一样,一个函数不能真正被值传递,所以语言具有特定的规则,这些规则将在函数声明和调用中执行转换。 'typedef void function(); void f(function f);'在声明中被转换为'typedef void function();'void f(function * f);'并且'f(myvoidfunction)'被转换为'f(&myvoidfunction)'召唤地点。 – 2012-07-05 22:25:09

+0

我不会称之为懒惰的方式;我会称之为一致的方式。 '()'运算符(即函数调用运算符)将函数指针作为其操作数。除非你到处去写作'(功能)(...);'每次进行函数调用时,它是不一致的,当你想用一个函数的地址非呼叫目的写'&function'。 – 2012-07-06 03:40:40

1

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

因为它并没有真正了解实际类型的数组中的项目,它采用了size参数正确计算的地址。看到这个实现,例如:http://insanecoding.blogspot.ie/2007/03/quicksort.html

3

当调用快速排序,你传递一个指针,这就是为什么你不指定任何参数的函数。

里面的qsort实现从“价值”阵列的动产价值和所说的“比较”功能。这就是'a'和'b'如何通过。

相关问题