如何声明一个返回函数指针的函数指针

时间:2018-06-01 08:10:00

标签: c function function-pointers

如何声明一个指向具有相同参数的函数的函数指针,并返回指向具有相同参数的函数的指针。

即。 funcPtr指向func1(int a, int b)func1返回指向另一个函数func2(int a, int b)的指针。 func2还返回一个与func1具有相同签名的函数指针。

TYPE funcPtr = func1;
funcPtr = funcPtr(0, 1);

如何声明funcPtrTYPE应该是什么?

3 个答案:

答案 0 :(得分:18)

无法解析的自我引用

这是不可能直接的。如果您尝试定义函数指针类型,其中函数的返回类型是其自己的类型,您将遇到未解析的自引用,这将需要无限递归来解析。

typedef funcType (*funcType)(void);

返回struct

您可以改为声明该函数返回一个结构,并且该结构可以包含指向这样一个函数的指针。

struct func {
    struct func (*func) (void);
};

struct func foo (void);
struct func bar (void);

struct func foo (void) { return (struct func){ bar }; }
struct func bar (void) { return (struct func){ foo }; }

...
    struct func funcPtr = { foo };
    funcPtr = funcPtr.func();

返回不同的函数指针类型

如果您更喜欢坚持使用严格的指针,则需要使用定义返回不同函数指针类型的函数。因此,调用的结果必须在被调用之前被转换回正确的指针类型。

typedef void (*funcPtrType)(void);
typedef funcPtrType funcType(void);

funcType foo;
funcType bar;

funcPtrType foo (void) { return (funcPtrType)bar; }
funcPtrType bar (void) { return (funcPtrType)foo; }

...
    funcType *p = foo;
    p = (funcType *)p();

返回索引

您可以改为定义函数以将索引返回到表示应该调用的函数的表。

enum funcEnum { fooEnum, barEnum };
typedef enum funcEnum (*funcType)(void);

enum funcEnum foo (void) { return barEnum; }
enum funcEnum bar (void) { return fooEnum; }

funcType funcTable[] = { [fooEnum] = foo, [barEnum] = bar };

...
    funcType p = funcTable[fooEnum];
    p = funcTable[p()];

这是在评论和Paul's answer中提出的,但为了完整性而在此处提供。

答案 1 :(得分:8)

这只是没有typedef的示例。您可以尝试更改函数的参数,但语法很糟糕,通常没用。

char (*(*((*foo)()))())()

foo是指向函数的指针,返回指向函数的指针,返回指向函数返回char的指针

或者你可以使用typedef

例如

typedef int (*foo2)(int, int);

typedef foo2 (*foo1)(int, int);
typedef foo1 (*foo)(int, int);

或更一般

typedef int (*foo`n`)(int, int);
typedef foo`n' (*foo'n-1`)(int, int);

...

typedef foo2 (*foo1)(int, int);
typedef foo1 (*foo)(int, int);

答案 2 :(得分:1)

我认为C中的真正问题是你得到一个无限声明,因为函数返回一个函数指针,并且需要输入函数指针来返回一个需要输入的函数指针....

以下是这种无限声明中的几个步骤,只是为了说明声明如何扩展和扩展:

int f0(int a) {
    return 1;
}
int (*f1(int a))(int) {
    return f0;
}
int (*(*f2(int a))(int))(int) {
    return f1;
}

<小时/> 作为遗留代码的解决方案,它可以返回状态编号,具有函数的表可用于调用为状态定义的函数,例如:

#define STATE0 0
#define STATE1 1

int fx1(int a);
int fx2(int a);

int (*ftab[])(int) = {
    fx1,
    fx2
};

void examplefunc(void)
{
    int x = ftab[STATE1](3);  // example of calling function from table
}