首页 > 解决方案 > 指向具有不可指定签名的函数的 C 指针

问题描述

我打算以阶乘为例来解释 C 中递归定理的标准证明。所以我有

#include <stdio.h>

typedef unsigned Nat;
typedef Nat Func();

Nat G(Nat n, Func f){
    if(n) return n * f(n-1, f);
    else return 1;
}

int main(void){
    printf("%u", G(5, G));
    return 0;
}

它在我能找到的每个编译器上都有效(打印 120),但困扰我的是我将一个指向函数的指针传递给一个实际上没有完全指定类型的参数(它是一个返回 Nat 的函数,但是未指定参数类型)。按照标准可以吗(任何标准,但最好是不弃用未指定参数类型的标准,所以我猜是 C89:)?

当然,我更希望能够完全指定 Func,但这似乎是不可能的(显而易见的方式,

typedef Nat Func(Nat, Func);

不起作用)。

标签: function-pointersfunction-prototypesansi-c

解决方案


它不那么漂亮,但是如果将其包装在结构中,则可以具有完全指定的类型。

#include <stdio.h>

typedef unsigned Nat;
typedef struct wrapped_Func Func;
struct wrapped_Func {
  Nat (*call)(Nat, Func);
};
#define FUNC(f) ((struct wrapped_Func){.call=f})

static Nat G(Nat n, Func f){
    if(n) return n * f.call(n-1, f);
    else return 1;
}

int main(void){
    printf("%u\n", G(5, FUNC(G)));
    return 0;
}

(宏中的结构字面量FUNC是 C99 的特性。在 C89 中它会更丑。)


推荐阅读