在 C 中,函数是否可以 return 指向自身的指针?

In C is it possible for a function to return a pointer to itself?

背景

所以这就是当你花几年时间编写 Haskell 然后回到裸机 C 代码时会发生什么:

问题

函数的 return 类型是否有可能与函数本身具有相同类型的指针?是吗,语法是什么?

作用域内的函数名是否在函数体内?或者我可以获得当前正在执行的函数的地址吗?

例如

void foo() {
  callmeback(&foo); // is this legal
}

你为什么要这样做?

我有一个状态机可以处理来自一些非常有限的控件的用户输入,这意味着两个输入操作必须服务于几种不同的模式。我正在将充满 switch 语句和全局变量的意大利面条代码重构为更易于维护的代码。如果我在 Haskell 中工作,我会用用户输入调用当前模式函数,并让它 return 一个函数来调用后续输入——它本身或新模式的处理程序。我开始在 C 中执行此操作,并意识到我不知道如何编写处理程序函数的类型。如果这不起作用,我将简单地为下一个处理程序设置一个全局变量并继续生活,但我只需要问它是否可以像我在函数式语言中那样完成。

对于那些好奇的人,这就是 ESP32 上的所有内容 运行,ESP32 是一种功能更强大的处理器,但类似于 Arduino 附带的处理器。

,在C中可以return一个function pointer给自己

您要查找的 return 类型是 void 指针 void*

是的,在 C 中,函数的名称在函数体内也是可见的。如果不是这样,递归之类的事情就不可能实现。

这里有一些代码用于说明:

#include <stdio.h>

void* demo() // See the usage of void pointer
{
    printf("This function returns a pointer to itself");
    return &demo;
    // return demo is also fine
    // don't return demo(), that would be recursion!
}

int main()
{
    // Syntax
    void (*demoPtr)() = demo();

    // Test if it worked
    demoPtr(); // There's no problem in ignoring the return value

    return 0;
}

输出:

这个函数return是一个指向自身的指针

这个函数return是一个指向自身的指针

编辑:

在阅读了提到您对此的需求的问题的第二部分后,我认为您可能正在寻找 recursion or callback。如果是这样,那么你可以在评论中澄清它,我会相应地编辑我的答案。

函数可以使用对自身的引用。 100% OK。

#include <stdlib.h>
#include <stdio.h>

volatile int x;

void foo(void (*fptr)())
{
    printf("Iteration: %d Function:%s\n", x++, __FUNCTION__);
    if(x < 10) fptr(foo);
}

void bar(void (*fptr)())
{
    printf("Iteration: %d Function:%s\n", x++, __FUNCTION__);
    if(x < 10) fptr(bar);
}


int main()
{
    bar(foo);
}

Is it possible for a function to have as its return type a pointer that is the same typs as the function itself? Is so, what is the syntax?

这是递归定义类型的要求,这是不可能的,至少在 C 中是不可能的。this question.

中讨论了将指针返回到函数本身。

就像其他人展示的那样,您需要一些技巧(void*structs)来编译它。那里没有检查标准合规性。

Is the name of the function in scope within the function body?

当然可以。递归在 C 中很好

[…] can I get the address of the function that is currently executing?

只是函数的名称。这是您的场景示例:

#include <stdio.h>

static void caller(void (*callee)(int)) {
  printf("Begin of %s(...)\n", __func__);
  callee(23);
  printf("End of %s(...)\n", __func__);
}

static void to_be_called(int param) {
  printf("Begin of %s(%d)\n", __func__, param);
  if (param == 0) {
    caller(&to_be_called);
  }
  printf("End of %s(%d)\n", __func__, param);
}

int main(void) {
  to_be_called(0);
  return 0;
}

您的计划在嵌入式 C 中并不新鲜:通过设置指向当前状态函数的指针来实现状态机。但是您设置下一个指针 不是通过返回 它,而是通过调用 setter 函数。一些开发人员甚至为此使用全局变量,brr.