恢复 C 中的递归函数 (gcc)



我在linux下使用gcc(gnu99)。假设我有一个简单的函数来计算(比如打印)一些值。为了在不诉诸阶乘的情况下修复想法,让我提出这个小玩具函数:

void rec(int val, int nd)
{
   val *= 10; nd++;
   for (int u=0; u<=9; u++, val++)
       if (val && 0==(val%(nd*nd)))
       {
         printf("%dn",val);
         rec(val,nd);
       }
}

它被称为 rec(0,0),将打印 86 个正数,其属性是每个长度为 k 的前缀都可以被 k^2 整除(最大为 6480005)。

问:有没有一种标准方法可以将其转换为可以重复调用的例程,每次返回一个新值,直到它以某种方式发出没有更多值的信号?

在实践中,我需要一种方法来调用 rec(),获取一个值,然后能够从它的位置恢复执行,获取下一个值等等。

我想过使用 setjmp()、longjmp()、setcontext() 等的组合,但这些主题的例子让我有点困惑。谢谢。

在不诉诸setjmp()及其同类的情况下,我会想到两种可能性来实现您的目标。

定义对其进行操作的结构和函数

您可以定义一个包含您感兴趣的状态的结构:

struct S {
  int *  numbers;
  size_t length;
  size_t current;
}

以及一组对其进行操作的函数:

// Basically your rec(val,nd) function
int initialize(int val, int nd, S* s);
// Get the next value
int getNextValue(const S* s);
...
// Free memory
void Sfree(S* s);

将状态嵌入到您自己的函数中

在这种情况下,您将持久状态(使用某些static变量)直接嵌入到函数rec()中。持久化此状态将在对函数的不同调用中保留,并允许您跟踪调用函数的次数以及您可能需要的任何其他信息。请注意,如果在多线程环境中使用,此解决方案需要特别小心。

在C++中,这是通过一个保存state(变量)的类来完成的。

在 C 语言中,首选的操作方法是将此statecontext传递给函数。

不要使用全局状态,因为稍后您会发现它会导致太多问题。

例:

int foo(struct fooContext* c, int arg1, int arg2) {
}

最新更新