C:是否有可能有一个递归函数,它将一个函数指针数组作为其参数之一?

时间:2014-11-03 09:55:30

标签: c pointers

这是较长的版本。 (TL; DR版本在我的帖子标题中。)

让我们考虑一个递归quick_sort函数,该函数目前设置如下:(i)它需要一个参数 - 一个链表,(ii)它按升序对元素进行排序,以及(iii)它返回已排序的链接列表。下面的说明性代码(我可以根据要求发布实际代码 - 更长时间)。

#include "list.h"  /*our linked-list implementation which includes definitions
                     for `concatenate`, which we use below*/

typedef int (*ordinal(int referenceValue, int currentValue));

int smaller(int referenceValue, int currentValue)
{
  return currentValue <= referenceValue ? 1 : 0;
}

int larger(int referenceValue, int currentValue)
{
  return currentValue > referenceValue ? 1 : 0;
}

List *getElements(List *fullList, ordinal compare)  /*let's assume this function exists*/
  /*implementation of getElements*/

List* quickSort(List* originalList)
{
  /*code to handle the two base cases, i.e., the cases
    in which the input list has either 0 or 1 elements */

  List *pivotElement = List_create();
  List_push(pivotElement, originalList->first->value);

  /*we're simply using the first element in the list as the pivot-point*/

  List *prePivotElements = quickSort( getElements(originalList, smaller) );
  List *postPivotElements = quickSort ( getElements(originalList, larger) );
  List *newList = concatenate(prePivotElements, pivotElement, postPivotElements);

  return newList;
}

现在让我们说我们想要修改我们的quick_sort函数,这样它就需要两个参数:一个链表和一个函数指针数组。想法是使用第二个参数(即函数指针数组)来指定排序顺序。函数调用的语法如下所示:quick_sort(linked_list, increasing[])quick_sort(linked_list, decreasing[])

我应该提一下,我的重点是理解递归传递函数指针数组的正确语法的可行性,而不是算法效率等等。换句话说,让我们试着忽略可怕的效率/记忆 - 快速排序的这个特定实现的管理方面:)

如上所述,为了修改quick_sort,我认为以下代码可能有用......

#include "list.h" 

typedef int (*ordinal(int referenceValue, int currentValue));

int smaller(int referenceValue, int currentValue)
{
  return currentValue <= referenceValue ? 1 : 0;
}

int larger(int referenceValue, int currentValue)
{
  return currentValue > referenceValue ? 1 : 0;
}

/*two new global arrays of function pointers*/
int (*increasing[2]) (int referenceValue, int currentValue) = {smaller, larger};
int (*decreasing[2]) (int referenceValue, int currentValue) = {larger, smaller};

List *getElements(List *fullList, ordinal compare)
  /*implementation of getElements*/

/*updated argument list*/
List* quickSort(List* originalList, ordinal compare[])
{
  /*base cases*/
  List *pivotElement = List_create();
  List_push(pivotElement, originalList->first->value);

  /*updated recursive function call*/
  List *prePivotElements = 
              quickSort( getElements(originalList, compare[0]), compare );
  List *postPivotElements = 
              quickSort ( getElements(originalList, compare[1]), compare );
  List *newList = concatenate(prePivotElements, pivotElement, postPivotElements);

  return newList;
}

...但会导致以下错误:

error: declaration of ‘compare’ as array of functions
   List* quickSort(List* originalList, ordinal compare[])
                                               ^
error: type of formal parameter 2 is incomplete
   List *prePivotElements = quickSort( getElements(originalList, compare[0]), compare );
   ^
error: type of formal parameter 2 is incomplete
   List *postPivotElements = quickSort ( getElements(originalList, compare[1]), compare );
   ^

回顾一下我的问题:C是否允许我们将函数指针数组传递给其他函数?怎么递归呢?如果允许,那么正确的语法是什么?

请原谅长度的帖子,我相信你们其中一位老兵会更加简洁!

(关于all posted code must compile的SO规则:我认为在这种情况下坚持使用概念相关的代码是有意义的。但是,如果人们更喜欢,我可以发布完整的.c文件和.h档案。)

更新 这里要求的是quick_sort的工作版本的相关文件。我还包括shell输出,包括用于编译/链接的命令。仅供参考,代码板给出了一些没有任何意义的奇怪错误(例如,在具有正确/可编译函数头的行上,它声称我缺少一个括号):

1 个答案:

答案 0 :(得分:5)

typedef int (*ordinal(int referenceValue, int currentValue));

不正确。它在语法上是有效的,但是括号没有效果,它只是定义了一个函数类型而不是函数的指针。键入dede函数指针的正确方法是

typedef int (*ordinal)(int, int);

这是括号围绕标识符和仅* (并且参数名称无关紧要)。

使用typedef可以更好地声明函数数组,而不是重复定义。

ordinal increasing[2] = {smaller, larger};