C中setjmp和longjmp用法

C中提供了goto语法,可以通过goto跳转到函数体内部标记的某一行代码,但是却无法跳出函数之外的任意位置。

为了解决这个限制,C函数库提供了setjmp()和longjmp()函数,它们分别承担非局部位置记录标号和goto作用。

使用这两个函数需要包含头文件<setjmp.h>

int setjmp(jmp_buf env)

建立本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处。这个子程序保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用。如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值。

void longjmp(jmp_buf env, int value)

恢复env所指的缓冲区中的程序调用环境上下文,env所指缓冲区的内容是由setjmp子程序调用所保存。value的值从longjmp传递给setjmp。longjmp完成后,程序从对应的setjmp调用处继续执行,如同setjmp调用刚刚完成。如果value传递给longjmp零值,setjmp的返回值为1;否则,setjmp的返回值为value。

当使用longjmp的时候,j的内容被销毁。

用longjmp只能跳回曾经到过的地方。在执行setjmp的地方仍留有一个过程活动记录。从这个角度上讲,longjmp更象是“从何处来”,而不是“要往哪去”。另外,longjmp接受一个额外的整形参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然执行到这里的。

下面demo演示了setjmp和longjmp的使用

//
//  main.c
//  setjmp&&longjmp
//
//  Created by apple on 15/1/28.
//  Copyright (c) 2015年 cc. All rights reserved.
//

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

//记录恢复的位置变量
jmp_buf buf;

void test() {

    printf("进入test()函数 \n");

    //跳转到buf位置变量记录的位置
    longjmp(buf, 1);

    printf("返回test()函数 \n");
}

int main(int argc, const char * argv[]) {

    //setjmp(buf)如果在setjmp本函数体内返回,则返回0
    //如果通过longjmp函数返回,则返回非0值

    if (setjmp(buf)) {
        //返回了非0值,通过longjmp函数跳转到setjump函数返回
        printf("main()... setjump()函数通过longjmp返回 \n");
    } else {
        //第一次调用setjmp时,必定正常执行完毕返回,即返回0值
        printf("main()... setjump()函数正常执行完毕返回 \n");
        test();
    }

    return 0;
}

打印结果如下。

通过打印的结果可以看出,longjmp函数确实跳转回了记录点的函数体内的那行代码。setjmp和longjmp一般用于异常处理,在发生异常时跳出到标记点,C++中的try catch throw的实现就是在此基础之上的封装,与goto相同,使用longjmp进行跳转破坏了程序的顺序执行结构,并且会造成代码难以理解和调试,所以在C++中不提倡使用这种方式来处理异常,在有些高级的IDE中,使用longjump函数之后的代码都会被标记为警告,比如我使用的XCode就会由警告提示Code
will never be executed,代码永远不会被执行。

本文由CC原创总结,如需转载请注明出处:http://blog.csdn.net/oktears/article/details/43232493

时间: 2024-11-05 02:41:47

C中setjmp和longjmp用法的相关文章

C语言中setjmp与longjmp学习笔记

一.基础介绍 ?? ?头文件:#include<setjmp.h> ?? ?原型:??int?setjmp(jmp_buf envbuf) ?? ?宏函数setjmp()在缓冲区envbuf中保存系统堆栈里的内容,供longjmp()以后使用.首次调用setjmp()宏时,返回值为0,然而longjmp()把一个变原传递给setjmp(),该值(恒不为0)就是调用longjmp()后出现的setjmp()的值. void longjmp(jmp_buf envbuf,int status);

C中的setjmp与longjmp

setjmp与longjmp是属于C语言中的,当然,C++也会有这两个函数了.他们的原型如下: int setjmp( jmp_buf env ); 作用:第一次调佣时,将寄存器的当前状态信息全部存入到env中,并返回0.如果在某处调用了longjmp(env,x),且x!=0,则setjmp的返回值将设为x.而若x==0,则setjmp返回1. void longjmp( jmp_buf env,int value ); 作用:重新存储当前寄存器的状态信息,并将setjmp的返回值设为valu

C语言中利用setjmp和longjmp做异常处理

错误处理是任何语言都需要解决的问题,只有不能保证100%的正确运行,就需要有处理错误的机制.异常处理就是其中的一种错误处理方式. 1 过程活动记录(Active Record) C语言中每当有一个函数调用时,就会在堆栈(Stack)上准备一个被称为AR的结构,抛开具体编译器实现细节的不同,这个AR基本结构如下所示. 每当遇到一次函数调用的语句,C编译器都会产生出汇编代码来在堆栈上分配这个AR.例如下面的C代码: void a(int i) { if(i==0){ i = 1; } else {

C语言中一些乱七八糟的用法与细节(不断更新)

用C语言比较多,这篇是平时攒下的.有些内容在工作后可能会很常见,但是不用容易忘,所以就写篇博客吧. 一.printf的用法 %*可以用来跳过字符,可以用于未知缩进.像下面一样. for(i = 1; i < 10; i++) { printf("%*c\r%*c\n",  9 - abs(i - 5), '*', abs(i - 5) + 1, '*'); } %[]可以用来读取指定的内容,%[^]可以用来忽略指定内容(正则表达式?) %m可以不带参数,输出产生的错误信息 二.关

setjmp()和longjmp()

1.语言没有异常处理机制,可以使用setjmp和longjmp进行模拟,另外,goto语句不能在函数间跳转,可以使用setjmp和longjmp完成函数间的跳转. 使用setjmp()函数需要包含头文件<setjmp.h> setjmp()函数用于建立本地的jmp_buf缓冲区并初始化,用于将来跳转到这个地方. longjmp()函数恢复jmp_buf变量所保存的信息,longjmp()之后返回setjmp()处执行. 1.1使用setjmp处理异常的例子: # include <std

学习之&quot;setjmp和longjmp函数&quot;

Linux学习之"setjmp和longjmp函数" 转贴,原文地址:http://www.cnblogs.com/lq0729/archive/2011/10/23/2222117.html nsetjmp和longjmp函数实现函数之间的跳转(需包含头文件"setjmp.h"): 函数原型:int setjmp(jmp_buf env);   void longjmp(jmp_buf env, int val); setjmp函数用于设置跳转的目的位置,long

非本地跳转之setjmp与longjmp

非本地跳转(unlocal jump)是与本地跳转相对应的一个概念. 本地跳转主要指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上.然而,本地跳转不能将控制权转移到所在程序的任意地点,不能跨越函数,因此也就有了非本地跳转. C语言里面提供了setjmp和longjmp函数来进行跨越函数之间的控制权的跳转,从而称之为非本地跳转. #include <setjmp.h> int setjmp(jmp_buf env); 该函数主要用来保存当前执行状态,作为后续跳

setjmp和longjmp

此文是学习 C专家编程 中的笔记. setjmp和longjmp是C语言所独有的,它们部分弥补了C语言有限的转移能力. 函数说明(来自wiki百科): int setjmp(jmp_buf env) 建立本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处.这个子程序保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用.如果是从setjmp直接调用返回,setjmp返回值为0.如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值. void longjmp

【C语言天天练(五)】setjmp和longjmp

setjmp和longjmp组合可以实现跳转,与goto语句有相似的地方.但有以下不同: 1.用longjmp只能跳回到曾经到过的地方.在执行setjmp的地方仍留有一个过程活动记录.从这个角度看,longjmp更像是"从何处来"而不是"往何处去".longjmp接收一个额外的整型参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然而然来到这里的. 2.goto语句不能跳出C语言当前的函数,而longjmp可以跳的更远,可以跳出函数,