C语言的非局部跳转:setjmp和longjmp
来源:互联网 发布:人类文明史图鉴淘宝 编辑:程序博客网 时间:2024/05/16 04:41
C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转(通常情况下,很多人都建议不要使用goto语句,因为采用goto语句后,代码维护工作量加大)。另外,C语言标准中还提供一种非局部跳转“no-local goto”,通过setjmp和longjmp函数来实现。
下面我们来看一个简单的例子。
1 #include <stdio.h> 2 #include <setjmp.h> 3 4 jmp_buf jump_buffer; 5 6 void func(void) 7 { 8 printf("Before calling longjmp\n"); 9 longjmp(jump_buffer, 1);10 printf("After calling longjmp\n");11 }12 void func1(void)13 {14 printf("Before calling func\n");15 func();16 printf("After calling func\n");17 }18 int main()19 {20 if (setjmp(jump_buffer) == 0){21 printf("first calling set_jmp\n");22 func1();23 }else {24 printf("second calling set_jmp\n");25 }26 return 0;27 }
代码的运行结果如下
lienhua34@lienhua34-laptop:~/program/test$ ./test
first calling set_jmp
Before calling func
Before calling longjmp
second calling set_jmp
通过上面这个简单例子的运行结果可以看出。main函数运行的setjmp()宏调用,将当前程序点的系统状态信息保存到全局变量jump_buffer中,然后返回结果0。于是,代码打印出字符串”first calling set_jmp”,然后调用函数func1()。在函数func1中,先打印字符串”Before calling func”,然后去调用函数func()。现在程序控制流转到func函数中,函数func先打印字符串“Before calling longjmp”,然后调用函数longjmp。这时候关键点到了!!!longjmp函数将main函数中setjmp()宏调用设置在全局变量jump_buffer中的系统状态信息恢复到系统的相应寄存器中,导致程序的控制流跳转到了main函数中setjmp()宏调用所在的程序点,此时相当于第二次进行setjmp()宏调用,并且此时的setjmp()宏调用的返回不再是0,而是传递给函数调用longjmp()的第二个参数1。于是程序控制流转到main函数中if语句的else部分执行,打印字符串“second calling set_jmp“。最后,执行main函数中的语句“reture 0;”返回,程序运行结束退出。
从上面的运行过程,我们可以看出在longjmp()函数调用处的程序点嵌套在三层函数调用中:main, func1和func,但是longjmp()函数调用导致程序控制流跳过函数调用func和func1,直接回到main函数中setjmp()宏调用所在的程序点,然后执行main函数中后续的语句,从而忽略了函数func1和func中后续的语句部分。这就是非局部跳转。
- 浅析C语言的非局部跳转:setjmp和longjmp
- C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 【setjmp和longjmp 】 C语言的非局部跳转:setjmp和longjmp(跨函数长跳转)
- (C)非局部跳转语句(setjmp和longjmp)
- 非局部跳转函数 setjmp 和 longjmp
- 非局部跳转函数 setjmp 和 longjmp .
- setjmp longjmp 非局部跳转
- setjmp()和longjmp()--c的非本地跳转
- setjmp和longjmp的"非本地跳转"
- setjmp和longjmp的"非本地跳转"
- C语言接口与实现【第四章】 setjmp/longjmp非局部跳转函数分析
- 使用setjmp()和longjmp()执行非局部跳转
- 非局部跳转语句---setjmp和longjmp函数
- setjmp与longjmp非局部跳转函数的使用
- setjmp/longjmp非局部跳转函数分析
- vb.net LINQ TO XML读写XML
- from one corner to another corner ,please get the shortest path numbers
- UVA-400 Unix ls
- 七月随笔
- 《web scraping with python》笔记--穿越网页表单与登录窗口进行采集
- C语言的非局部跳转:setjmp和longjmp
- 安卓拼图游戏(一)
- 一个例子了解Java反射机制
- OGR API Tutorial
- hdu 2376 Average distance DFS 求树上任意两点距离和
- JavaScript基础知识整理
- Reverse Bits leetcode
- angular用ng-repeat批量处理数据
- [119] Pascal's Triangle II