-2

关于函数指针的一个很好的教程给出了一个我有疑问的例子。这是一个简单的排序函数,其参数之一是函数。这是函数调用。如您所见, (*compar) 函数有两个“const void*”参数

void qsort(void *base, size_t nmemb, size_t size,
        int(*compar)(const void *, const void *));

稍后调用此函数:

#include <stdlib.h>
int int_sorter( const void *first_arg, const void *second_arg )
{
    int first = *(int*)first_arg;
    int second = *(int*)second_arg;
    if ( first < second )
    {
        return -1;
    }
    else if ( first == second )
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

int main()
{
    int array[10];
    int i;
    /* fill array */
    for ( i = 0; i < 10; ++i )
    {
        array[ i ] = 10 - i;
    }
    qsort( array, 10 , sizeof( int ), int_sorter );
    for ( i = 0; i < 10; ++i )
    {
        printf ( "%d\n" ,array[ i ] );
    }

}

我的问题是编译器如何知道“int_sorter”正在比较哪两个元素?它们没有在初始函数中被调用,我认为这是因为作为参数调用的函数处理了它,但是函数如何知道在这个数组中我们正在比较两个数字?

我也不确定是什么*(int *)意思;我怀疑这是答案的一部分。

4

2 回答 2

3

qsort()函数负责(重复)使用正确的两个指针调用比较器函数。它们是指向传递给的数组的两个元素的指针qsort()。编译器不知道int_sorter()比较的是哪两个元素。

first = *(int *)first_arg;符号将 转换为const void *int *然后取消引用int(读取它,因此不违反const约束),并将值分配给first。参数说“const void *比较器函数不应该修改指针参数指向的数据”。

的设计qsort()允许它对任何类型的数组进行排序;它需要的信息都存在于界面中。

于 2013-09-06T14:54:56.553 回答
2

我的问题是编译器如何知道“int_sorter”正在比较哪些元素?它们没有在初始函数中被调用,我认为这是因为作为参数调用的函数处理了

对,就是这样。该qsort()函数使用您提供给它的函数指针(指向 的指针int_sorter)来调用该函数int_sorter。它通常会调用int_sorter很多次,每次都使用要排序的数组中的不同元素。

但是该函数如何知道在这个数组中我们正在比较这两个数字?

同样,该功能本身并不知道。该qsort()函数决定它必须比较哪些数字,然后比较它们。

如果您查看排序函数的简单实现可能会有所帮助,这样您就可以看到实际的函数调用。

我也不确定 *(int *) 是什么意思

正如另一个答案中所解释的:(int*)意味着“将其转换为'指向int'的指针”。前面的星号是取消引用运算符(从指针到值)。

于 2013-09-06T15:00:01.270 回答