您当前的位置:首页 > 计算机 > 编程开发 > C语言

有没有办法从一个或多个函数中跳出?

时间:12-30来源:作者:点击数:

在极少数确实需要这样做的情况下,可以利用标准库函数setjmp()和longjmp()实现一种能从一个或多个函数中跳出的跳转(goto)。要正确地使用setjmp()和longjmp()函数,必须满足几个条件。

首先,你必须包含setjmp.h头文件,该文件提供了setjmp()和longimp()函数的原型,并定义了jmp—buf类型。你需要把一个jmp—bur类型的变量作为一个参数传递给setjmp()和longjmp()函数,这个变量将包含使跳转发生所需的信息。

其次,你必须调用setjmp()函数来初始化jmp—bur变量。如果setjmp()函数返回0,则说明jmp_buf变量已被初始化;如果setjmp()函数返回其它值,则说明程序刚才通过调用longjmp()函数跳转到了对应于该值的位置。在后一种情况下,setjmp()函数的返回值就是程序传递给longjmp()函数的第二个参数。

从概念上讲,longjmp()函数的作用就好象是这样:当它被调用时,当前正在执行的函数便会返回;然后,调用这个函数的函数将返回;依此类推,直到调用setjmp()的函数成为正在执行的函数。程序的执行将跳转到调用setjmp()函数的位置,并从setjmp()函数返回那一点继续往下执行,但此时setjmp()函数的返回值已被置为传递给longjmp()函数的第二个参数。

换句话说,如果函数f()调用了setjmp(),然后又调用了函数g(),而函数g()调用了函数h(),函数h()调用了longjmp(),那么程序运行起来就好象h()立即返回了,然后g()立即返回,然后f()执行一次回到调用setjmp()的位置的跳转。

这就是说,为了使对10ngjmp()的调用能正常工作,程序必须已经调用setjmp(),并且还没有从调用setjmp()的函数中返回。如果这些条件得不到满足,那么longjmp()的行为是没有定义的(这意味着你的程序很可能会崩溃)。例12.9中的程序说明了setjmp()和longjmp()的用法。这个程序显然是为此而设计的,因为如果不使用setjmp()和longjmp(),程序就会更简洁些。总的来说,当你想使用setjmp()和longjmp()时,最好先找一种可以不使用它们的编程方法,因为它们容易被误用,并且会使程序难于阅读和维护。

例12.9 一个使用setjmp()和longjmp()的例子

# include <setjmp.h>
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define RETRY_PROCESS 1
# define QUIT_PROCESS 2
jmp_buf env;
int nitems;
int procItem()
{
       char     buf[256];
       if (gets (buf) &&.strcmp(buf, "done"))  {
              if (strcmp(buf, "quit") ==0)
                    longjmp (env, QUIT_PROCESS );
              if (strcmp(buf, "restart") ==0)
                    longjmp(env, RETRY_PROCESS);
              nitems+ + ;
              return 1;
       }
       return 0;
}
void
process()
{
        printf ("Enter items, followed by 'done'. \n") ;
        printf("At any time, you can type 'quit' to exit\n");
        printf ("or 'restart' to start over again\n");
        nitems = 0;
        while (procItem())
}
void
main() {
        for (; ;) {
              switch (setjmp(env)) {
              case 0:
              case RETRY_PROCESS:
                       process () ;
                       printf("You typed in %d items. \n" ,
                             nitems);
                       break ;
              case QUIT_PROCESS:
              default:
                     exit(O);
              }
        }
}

 

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
    无相关信息
栏目更新
栏目热门