这是无条件跳跃的好方法吗?

时间:2009-11-08 12:15:14

标签: c

我在func.c文件中有一个函数f(),在另一个文件funcs.h中有函数f1(),f2(),f3(),f4()。 (假设所有函数都接收/返回值而不失一般性)。

  1. 函数f()调用f4()
  2. f4()以任意顺序调用f1(),f2(),f3(),
  3. 在执行期间的某个时间点,f3()检测到算法的完成,并且必须“终止”算法的执行。在一个独立的情况下,它应该在打印解决方案后退出程序。但是在这里,我需要f3()来返回到f()。
  4. 这是我的解决方案:

    在这种情况下,我不能简单地返回到f4()(由f()调用的原始函数,因为已经存在f1(),f2(),f3(),f4()的函数调用堆栈,等待“弹出”)。所以,我做的是:

    1. 在调用f4()
    2. 之前,我在f()中做了setjmp( )
    3. 然后,当我检测到算法完成时,我在f3()中做了longjmp( )
    4. 我的问题是:这是在这种情况下实现这一目的的正确方法吗?

6 个答案:

答案 0 :(得分:4)

TBH我个人觉得最好从函数返回一个bool,如果返回为true,则从下面的函数返回true,依此类推,直到它返回到原始函数。这正确地展开了堆栈,我不确定setjmp / longjmp是做什么的。

一般情况下,如果在f()函数返回后你不打算继续做事,那么无论如何都应该有效。我只是认为它不是一个非常好的方法来做事情,因为读取代码的人不会发现它像返回bool的函数一样显而易见。

答案 1 :(得分:1)

您可以使用getcontext/setcontext。它们可能被视为setjmp / longjmp的高级版本;而后者只允许单个非局部跳转堆栈,setcontext允许创建多个协作控制线程,每个控制线程都有自己的堆栈。

另请参阅其他相关调用,例如makecontext(),swapcontext() 这是一个示例代码,用于说明如何使用这些函数(抱歉编码错误)。希望这对你有所帮助。

    #include <stdio.h>
    #include <ucontext.h>

    void func(void);

    int  x = 0;
    ucontext_t context, *cp = &context;

    int main(void) {

      getcontext(cp);
      if (!x) {
        printf("getcontext has been called\n");
        func();
      }
      else {
        printf("setcontext has been called\n");
      }

    }

    void func(void) {

      x++;
      setcontext(cp);

    }

  Output:

  getcontext has been called    
  setcontext has been called

答案 2 :(得分:0)

  

f4()以任意顺序调用f1(),f2(),f3(),

“任意顺序”是什么意思?除非您正在编写多线程程序,否则调用1,2和3的顺序应该是确定性的;函数在C中同步执行。

答案 3 :(得分:0)

你没有提到你在做什么或者你正在实施什么算法但是......

你可以使用带有函数指针的全局结构,f1,f2,f3,f4知道它的存在,你可以从f4()调用f1()来做类似的事情:

global.functionPointers[0]("parameters.for.f1");

答案 4 :(得分:0)

你是否还需要一个标志才能知道你不应该第二次再次拨打f4?

int solution_found=0;

f(){
  setjmp();
  if (!solution_found)
    f4();
  /* continue here... */
}

除此之外,setjmp / longjmp可能是昂贵的调用。它们在程序的可读性方面也有代价。我肯定会考虑让f1,......如果我是你的话,那就是以正常的方式将自己弹出堆栈。

答案 5 :(得分:0)

我会这样做:

struct solution { ... }

solution *f() {
    solution *result;
    if (something) {
        result = f3();
        if (result != NULL)
            return result;
    }
    else {
        result = f3();
        if (result != NULL)
            return result;
    }
    return f();
}

或者你的算法可能是什么。