C语言异常控制:setjmp与longjmp详解
C语言的setjmp与longjmp是独特的控制流机制,允许程序在运行时跳转到之前保存的位置,通常用于集中处理程序中可能出现的深层错误或异常。
核心概念与定义
这两个函数的声明位于头文件 setjmp.h 中。它们的组合使用旨在按照预先设计的意图,实现对异常的集中处理。
第1步:定义缓冲区与环境保存
目的:创建一个环境缓冲区,并记录当前程序的执行状态(主要是栈指针)。
入口:调用 setjmp 函数。
动作:传入一个类型为 jmp_buf 的缓冲区变量,系统会将当前的堆栈内容保存到该变量中。
复制代码 代码如下:
int setjmp(jmp_buf envbuf);
- 参数:
envbuf用于保存堆栈上下文的环境变量。 - 返回值:当首次调用时,
setjmp返回0。
第2步:触发跳转并恢复环境
目的:在非正常路径或发生错误时,跳回之前由 setjmp 保存的位置。
入口:调用 longjmp 函数。
动作:传入先前保存的 envbuf 和期望的返回值。
复制代码 代码如下:
void longjmp(jmp_buf envbuf, int val);
- 参数:
envbuf是由setjmp保存的堆栈环境;val将作为setjmp再次调用时的返回值。 - 执行效果:
longjmp本身无返回值,它结束当前函数调用链,直接跳转到setjmp的位置。此时,setjmp不再返回 0,而是返回val。同时,envbuf中的状态被销毁,不可重复用于跳转。
代码示例与执行流程
以下示例展示了 setjmp 和 longjmp 如何跨函数跳转:
复制代码 代码如下:
#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
void banana() {
printf("in banana()\n");
longjmp(buf, 1); // 触发跳转
// 这行代码永远不会被执行
printf("you'll never see this, because i longjmp'd");
}
int main() {
if (setjmp(buf)) { // 第一次返回0,第二次返回1
printf("back in main\n");
} else {
printf("first time through\n");
banana(); // 进入子函数
}
return 0;
}
执行结果:
- first time through
- in banana()
- back in main
主要应用场景
错误恢复: setjmp/longjmp 的最大用途是实现类似其他语言中 try...catch 的异常处理机制,允许程序从深层嵌套的错误中“抛出”到顶层进行统一处理。
范围优势: 相比于 goto 只能在当前函数内部跳转,setjmp/longjmp 可以在整个函数调用链的任何位置间进行跳转,实现了真正的非局部跳转。
以上就是C语言中setjmp与longjmp函数的详细内容,更多关于C语言异常处理的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













