从该循环中调用的函数中脱离循环 [英] Breaking out of a loop from within a function called in that loop

查看:135
本文介绍了从该循环中调用的函数中脱离循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试从该循环中调用的函数中找出一种 for 循环的方法。我知道让函数返回一个值,然后检查一个特定的值,然后中断的可能性,但是我想直接在函数内部执行。

I'm currently trying to figure out a way to break out of a for loop from within a function called in that loop. I'm aware of the possibility to just have the function return a value and then check against a particular value and then break, but I'd like to do it from within the function directly.

这是因为我正在为特定的硬件使用内部库,该硬件要求我的函数的功能签名看起来像这样:

This is because I'm using an in-house library for a specific piece of hardware that mandates the function signature of my function to look like this:

void foo (int passV, int aVal, long bVal)

我知道不使用返回值是非常不好的做法,但是可惜情况迫使我这样做,所以请多多包涵。

I'm aware that not using a return value is very bad practice, but alas circumstances force me to, so please bear with me.

考虑以下示例:

#include <stdio.h>

void foo (int a) {
    printf("a: %d", a);
    break;
}

int main(void) {
    for (int i = 0; i <= 100; i++) {
        foo(i);
    }
    return 0;
}

现在,它不会编译。相反,我得到如下编译错误:

Now this does not compile. Instead, I get a compilation error as follows:


prog.c:在函数'foo'中:
prog.c: 6:2:错误:循环或开关中的break语句不是

prog.c: In function 'foo': prog.c:6:2: error: break statement not within loop or switch break;

我知道这是什么意思(编译器表示 foo()中的中断不在 for 循环之内)

I know what this means (the compiler says that the break in foo() is not within a for loop)

现在,我可以从标准中有关break语句的内容中找到以下内容:

Now, what I could find from the standard regarding the break statement is this:


break语句使控制权传递到
最里面的while,do,for或switch语句之后的语句。
语法简直就是断点;

The break statement causes control to pass to the statement following the innermost enclosing while, do, for, or switch statement. The syntax is simply break;

考虑到我的函数是从中调用循环,为什么break语句没有超出for循环?此外,是否可以在不先返回函数的情况下实现类似的功能?

Considering my function is called from within a for loop, why doesn't the break statement break out of said for loop? Furthermore, is it possible to realise something like this without having the function return first?

推荐答案

break goto 一样,只能在同一函数中本地跳转,但是如果绝对需要,可以使用 setjmp longjmp

break, like goto, can only jump locally within the same function, but if you absolutely have to, you can use setjmp and longjmp:

#include <stdio.h>
#include <setjmp.h>

jmp_buf jump_target;

void foo(void)
{
    printf("Inside foo!\n");
    longjmp(jump_target, 1);
    printf("Still inside foo!\n");
}

int main(void) {
    if (setjmp(jump_target) == 0)
        foo();
    else
        printf("Jumped out!\n");
    return 0;
}

longjmp 将导致跳回到 setjmp 调用。 setjmp 的返回值显示它是在设置跳转目标之后返回还是从跳转返回。

The call to longjmp will cause a jump back to the setjmp call. The return value from setjmp shows if it is returning after setting the jump target, or if it is returning from a jump.

输出:

Inside foo!
Jumped out!

正确使用非本地跳转是安全的,但是要仔细考虑以下几点:

Nonlocal jumps are safe when used correctly, but there are a number of things to think carefully about:


  • 由于 longjmp 跳过了<$ c $之间的所有功能激活c> setjmp 调用和 longjmp 调用,如果其中任何一个函数希望能够在当前执行位置之后执行其他工作,

  • 如果调用 setjmp 的函数激活已终止,则行为未定义。任何事情都可能发生。

  • 如果尚未调用 setjmp ,则 jump_target
  • 在某些情况下,名为 setjmp 的函数中的局部变量可能未定义值。

  • 一个词:线程。

  • 其他情况,例如可能不会保留浮点状态标志,并且存在限制

  • Since longjmp jumps "through" all the function activations between the setjmp call and the longjmp call, if any of those functions expect to be able to do additional work after the current place in execution, that work will simply not be done.
  • If the function activation that called setjmp has terminated, the behaviour is undefined. Anything can happen.
  • If setjmp hasn't yet been called, then jump_target is not set, and the behaviour is undefined.
  • Local variables in the function that called setjmp can under certain conditions have undefined values.
  • One word: threads.
  • Other things, such as that floating-point status flags might not be retained, and that there are restrictions on where you can put the setjmp call.

其中大多数自然遵循如果您对机器指令和CPU寄存器级别的非本地跳转有很好的了解,但是除非您对此有所了解,否则已阅读了C标准的内容,但不能保证,我会请多加注意。

Most of these follow naturally if you have a good understanding of what a nonlocal jump does on the level of machine instructions and CPU registers, but unless you have that, and have read what the C standard does and does not guarantee, I would advise some caution.

这篇关于从该循环中调用的函数中脱离循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆