Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否可以编写一个将自身作为参数接收的函数?_C_Recursion - Fatal编程技术网

C 是否可以编写一个将自身作为参数接收的函数?

C 是否可以编写一个将自身作为参数接收的函数?,c,recursion,C,Recursion,我在想,您可以将函数作为函数指针传递给函数,如下所示: #include <stdio.h> void loop(void(*f)(), int n){ if(f == NULL) printf("is this cursed use of recursion?\n"); else{ f(); if(n == 0) loop(NULL, n); else l

我在想,您可以将函数作为函数指针传递给函数,如下所示:

#include <stdio.h>
void loop(void(*f)(), int n){
    if(f == NULL)
        printf("is this cursed use of recursion?\n");
    else{
        f();
        if(n == 0)
            loop(NULL, n);
        else
            loop(f, n - 1);
        return;
    }
}
void f(){
    printf("hello world\n");
}
int main(){
    loop(f, 5);
    return 0;
}
所以我想到了一件事,是否真的可以做一个函数,在某种程度上,它在C中作为参数接收自身?

看看:

int f(void (*p)(void), int n)
{
    if (n == 0)
        return 0;

    int (*g)(void (*)(void), int) = p;
    return 2 + g(p, n - 1);
}

int main(void)
{
    void (*p)(void) = f;
    return f(p, 3);
}
注意:我这样写是为了清楚——如果您想删除关于不兼容指针类型的警告,您需要显式地强制转换指针

以下程序的返回代码为6,即3乘以2。如你们所见,我们在main中显式地将f传递给它自己,即ff,3

f本身内部发生的事情更有趣,因为f调用f时使用f作为参数,尽管f不知道这一点。

看看:

int f(void (*p)(void), int n)
{
    if (n == 0)
        return 0;

    int (*g)(void (*)(void), int) = p;
    return 2 + g(p, n - 1);
}

int main(void)
{
    void (*p)(void) = f;
    return f(p, 3);
}
注意:我这样写是为了清楚——如果您想删除关于不兼容指针类型的警告,您需要显式地强制转换指针

以下程序的返回代码为6,即3乘以2。如你们所见,我们在main中显式地将f传递给它自己,即ff,3


f本身内部发生的事情更有趣,因为f调用f时使用f作为参数,尽管f不知道这一点。

这称为递归。你的例子行不通。当n为零时,它将继续调用自身并炸毁堆栈。您将有一个堆栈溢出。您来对了地方。@Hogan它起作用了。:a插入一个类似ifloop==f printfcussed的子句\n;否则f;这段代码很好,这不是问题所在。这叫做递归。你的例子行不通。当n为零时,它将继续调用自身并炸毁堆栈。您将有一个堆栈溢出。您来对了地方。@Hogan它起作用了。:a插入一个类似ifloop==f printfcussed的子句\n;否则f;这段代码很好,不管怎么说,这不是问题所在。函数指针之间的转换是定义的,至少这样,如果您转换回,结果等于原始指针。因此,将参数设为函数指针而不是void*,然后将其转换为所需的函数类型,行为将由C标准定义。函数指针之间的转换已定义,至少这样,如果您转换回,结果等于原始指针。因此,将参数设置为函数指针而不是void*,然后将其转换为所需的函数类型,行为将由C标准定义。