在C语言中,有没有一种方法可以引用当前所在的函数?

5

我正在编写一个函数,它只是在表格内查找值。是否可以在其内部调用该函数?我看到了一些关于 thisself 的东西,但不太理解。


2
参考是指“调用”还是指“获取指针”? - cdhowie
this 只在 C++ 中可用,而 self 只在 Objective-C 中可用。它们都不是 C 语言。 :) - user142019
4个回答

12

可以的,它被称为递归。

void foo(){
   foo(); //This is legal.
}

当然你需要从递归函数中返回以避免无限递归调用。如果不返回,将会导致堆栈溢出。以下是一个更好的例子:

当然你需要从递归函数中返回以避免无限递归调用。如果不返回,将会导致堆栈溢出。以下是一个更好的例子:

void foo(int n){
    if (n == 0)
        return;
    foo(--n);
}

10
要理解递归,首先必须理解递归。 - dnatoli
3
除非 n 最初为零,否则它永远不会返回。 n-- 返回 n 并将其递减。 我认为你的意思是 --n - cdhowie
@link664 要使用递归,你必须先使用递归。 - user142019

5

递归 (计算机科学) (维基百科)。

函数内调用函数的示例:

# include<stdio.h>

int factorial(unsigned int number)
{
    if (number <= 1)
        return 1;
    return number * factorial(number - 1);
}

void main()
{
    int x = 5;
    printf("factorial of %d is %d",x,factorial(x));
}

2

其他人已回答了你的问题,但由于这对你来说是陌生的,你可能想要了解递归和递归函数。如果你不知道,可能会遇到一些棘手的问题。

其中最糟糕的是,如果你太深入或者你的函数堆栈分配了很多东西,你很快就会溢出堆栈。如果你计划使用递归实现,请确保你的递归是有界的,并且在堆栈上分配的最少。

你可能需要考虑迭代方法 - 每个递归问题都可以通过一些思考以迭代方式解决。这也通常是一个有趣的练习。

JoshLeaves说递归更快,但通常不是因为需要分配增长的堆栈并设置寄存器。如果你的函数调用自身两次或更多次来计算它的结果,那么迭代解决方案总是更快的。


+1 给迭代的赞。通常更高效。尾递归同样快,但 C 不支持。 - TheIronKnuckle
我明白这为什么是个问题,但这个函数只是从表格中查找一个值。它很简单,不会导致堆栈溢出。 - Kyle Hotchkiss
@Kyle Hotchkiss:如果你的函数基于某个输入'n'而重复执行'n'次,那么就让'n'变得非常大,看它会不会爆炸。或者将其放在一个栈非常小的地方。递归非常危险,除非它被严格限制。 - Adam Hawes
@ThelronKnuckle:至少GCC在某些情况下会进行尾调用优化。了解它是什么以及如何编写您的函数有时可能很有用。但如果可以的话,最好还是采用迭代方式。 - Adam Hawes

1

更新

好的,我以为这是关于“获取每个函数值”的问题。正如其他帖子所说,这被称为递归。不过需要注意以下几点:

递归比迭代更快(我手头没有基准测试结果,但我在一年前在Intel Core i5上运行了它们)。

//Iteration
function do_stuff(i)
{
    //BLABLAH
}

for (i = 0; i <5; i++) {
    do_stuff();
}

//Recursion
function do_stuff(int i)
{
    //BLABLAH
    if (i < 5) {
        do_stuff(i + 1);
    }
}
  • 你可以递归多次,但必须找到一种方法来停止递归或...
  • 如果你的递归深度太深(想象一下“盗梦空间”乘以一百万倍...),你会冒着在进入同一个函数一百万次后溢出可用堆栈内存的风险。

这将为您提供当前函数的名称(作为字符数组char [])。 OP只想调用一个递归函数;也许他想获取当前函数的函数指针。 - Adam Rosenfield
@Adam 抱歉,是的,我看到了并更改了我的答案,以增加对递归函数使用的“智慧”说明。 - red
2
递归只有在执行尾调用时才可能比迭代更快。否则,额外的堆栈帧分配和寄存器重新初始化将消除任何性能优势。 - cdhowie
@cdhowie 我之前从未听说过这个,我的所有递归函数都使用返回值。谢谢你的信息。 - red

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接