代码之家  ›  专栏  ›  技术社区  ›  John F. Miller

在C语言中,函数是否可以返回指向自身的指针?

  •  1
  • John F. Miller  · 技术社区  · 6 年前

    出身背景

    这就是当你花几年时间写Haskell,然后回到裸机C代码时会发生的事情:

    问题

    函数的返回类型是否可能有一个与函数本身类型相同的指针?那么,语法是什么?

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

    例如。

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

    你为什么要这么做?

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

    对于那些好奇的人来说,这一切都是在ESP32上运行的,ESP32是一种更强大的处理器,但与what Comed and Arduino类似。

    0 回复  |  直到 6 年前
        1
  •  3
  •   Ardent Coder Michael Richardson    6 年前

    ,可以返回 function pointer 用C写的。

    你要找的退货类型是a 空指针 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;
    }
    

    输出:

    此函数返回指向自身的指针

    此函数返回指向自身的指针

    编辑:

    在阅读了你的问题的第二部分,其中提到你需要这个,我想你可能正在寻找 recursion callback .如果是这样的话,你可以在评论中澄清,我会相应地编辑我的答案。

        2
  •  1
  •   the busybee    6 年前

    函数的返回类型是否可能有一个与函数本身类型相同的指针?那么,语法是什么?

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

    就像其他节目一样,你需要一些技巧( void* struct

    作用域中函数的名称是否在函数体中?

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

    []我可以获取当前正在执行的函数的地址吗?

    只需输入函数名即可。以下是您的场景示例:

    #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中,您的计划并不新鲜:通过设置指向当前状态函数的指针来实现状态机。但你将设置下一个指针 不是通过返回 但是打电话给 塞特 作用一些开发人员甚至为此使用了一个全局变量, brr .

        3
  •  0
  •   0___________    6 年前

    函数可以使用对自身的引用。100%没问题。

    #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);
    }