C中有返回指令的任何跳转?

时间:2015-12-30 16:53:57

标签: c

我的代码中有多个位置,我希望能够跳转到某个特定位置返回到之前的位置。

函数调用提供了控制流,但对我来说不是一个选项,因为我希望我分支的代码访问许多变量并将所有这些变量作为参数传递给函数调用是不实际或有效的。

goto声明仅用于制作标签,即预期为单程票。

目前,我正在通过以下方式实现我的目标:

void *return_addr;
int x,y;
...
return_addr=&&RETURN_0;
goto SOMEWHERE;
RETURN_0:
...
x+=1;
...
return_addr=&&RETURN_1;
goto SOMEWHERE;
RETURN_1:
...


SOMEWHERE:
y=x;
...
goto *return_addr;

是否有更优雅,更轻松的东西?

4 个答案:

答案 0 :(得分:1)

  

是否有更优雅,更轻松的东西?

您显然正在使用GCC,因为computed goto statement是GCC扩展。使用GCC,我们可以使用nested function并访问局部变量,而无需将它们作为参数传递:

{
    int x, y;

    void SOMEWHERE()
    {
        y = x;
        //...
    }

    //...
    SOMEWHERE();
    //...
    x += 1;
    //...
    SOMEWHERE();
    //...
}

答案 1 :(得分:0)

让我们在结构中收集变量:

struct data_t {
    int a;
    int b;
    /* and so on */
    int x;
    int y;
};

让我们在函数中定义重复的代码:

void func(struct data_t* data) {
    data->y = data->x;
    /* and so on */
}

让我们使用以下功能:

struct data_t data = {1, 2, ..., 24, 25};
func(&data);
data.x += 1;
func(&data);
/* and so on */

答案 2 :(得分:0)

C有longjmp() / struct,可以支持您描述的内容。不要使用它们。然而,更多的是,不依赖于你当前的方法,这不是标准的C,而且形式非常糟糕。

您所描述的功能是什么。如果你有大量的数据必须在调用者和被调用者之间共享,那么

  • 将它们记录在文件范围变量中,以便两个函数都可以直接访问它们,或者
  • 创建一个或多个复杂数据类型(可能是struct),用于保存和组织数据,并通过将指针传递给<Button Content="Blah" HorizontalAlignment="Center" VerticalAlignment="Center" ToolTip="Blah Blah Blah" ToolTipService.Placement="Center"> <Button.Resources> <Style TargetType="{x:Type ToolTip}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToolTip}"> <Grid Margin="0,60,0,0"> <Path Data="M0 0 30 0 50 -15 70 0 100 0 100 30 0 30z" Fill="#3E82C4" Stretch="Fill"/> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,8"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Button.Resources> </Button> 来给予被调用者访问权。

答案 3 :(得分:0)

状态机可以这样写:

typedef enum { start, stop, state1, ... } state;

state s = start;
while (s != stop) {
 switch (s) {
 case start:
   do_stuff; // lots of code
   // computed goto
   s = cond ? state23 : state45;
   break;
   ...

需要一个调用堆栈吗?

 state stack[42]; int sp=0;
 ...
    do_stuff;
    stack[sp++] = state33;
    s = state45; // call
    break;
  case state33:

  case state45:
    do_processing; // some code
    s = stack[--sp]; // ret
    break;

只有在对时间要求严格的代码部分进行基准测试并发现正常的函数调用机制确实是瓶颈之后,才应该这样做。