setjmp()和longjmp()

C 标准库 - 

setjmp.h 头文件定义了

  1. 宏 setjmp()
  2. 函数 longjmp() 
  3. 变量类型 jmp_buf

jmp_buf 该变量类型会绕过正常的函数调用和返回规则。

jmp_buf 这是一个用于存储宏 setjmp() 和函数 longjmp() 相关信息的数组类型。

int setjmp(jmp_buf environment);

这个宏把当前环境保存在变量 environment 中,以便函数 longjmp() 后续使用。

  • 返回零:直接调用这个宏
  • 返回非零:调用longjmp() 函数

库函数

void longjmp(jmp_buf environment, int value);

该函数恢复最近一次调用 setjmp() 宏时保存的环境,jmp_buf 参数的设置是由之前调用 setjmp() 生成的。

 

总结:当调用setjmp() 宏时会保存当前环境,用于将来跳转回此处。

实例代码一

#include 
#include 
static jmp_buf buf;

void second(void) {
    printf("second\n");         // 打印
    longjmp(buf,0);             // 跳回setjmp的调用处 - 使得setjmp返回值为1
}

void first(void) {
    second();
    printf("first\n");          // 不可能执行到此行
}

int main() {
    if ( ! setjmp(buf) ) {
        first();                // 进入此行前,setjmp返回0
    } else {                    // 当longjmp跳转回,setjmp返回1,因此进入此行
        printf("main\n");       // 打印
    }

    return 0;
}

输出:

second
main

longjump的第二个参数是影响(而不是被影响)setjmp的返回值的

#include 
#include 
static jmp_buf buf;
int main(void)
{
    int i;
    printf("%d\n",i = setjmp(buf));//第一次输出0,第二次输出longjmp的第二个参数。
    if (i==0)
        longjmp(buf,3);//可自行修改第二参数查看不同结果。
    return 0;
}

运行结果为:

0
3

但是当我没把第二个参数设置为0时该怎么输出

#include 
#include 
static jmp_buf buf;
int main(void)
{
    int i;
    printf("%d\n",i = setjmp(buf));//第一次输出0,第二次输出longjmp的第二个参数。
    if (i==0)
        longjmp(buf,3);//可自行修改第二参数查看不同结果。
    printf("after\n");
    return 0;
}

输出:

0
1
after

实际上并没有产生我们认为的那种无限循环。

于是可以认为第二次返回后,不会执行以前执行过的代码。

 

 

 

 

 

 

你可能感兴趣的:(C/C++)