C语言中的跳转goto&&setjmp&&longjmp sigsetjmp siglongjmp
来源:互联网 发布:js代码测试 编辑:程序博客网 时间:2024/06/10 15:23
C语言中的跳转goto&&setjmp&&longjmp sigsetjmp siglongjmp
1、goto语句,函数内部的短转移
goto语句只能跳转的到本函数内部的标签处,这个没得说,例子如下:
- #include <stdio.h>
- int main()
- {
- int i=0;
- loop: printf("do something %d/n",i);
- i++;
- if(i<6)
- goto loop;
- return 0;
- }
2、setjmp 和 longjmp 实现长跳转
函数原型如下:
#include <setjmp.h>
int setjmp(jmp_buf envbuf);
void longjmp(jmp_buf envbuf, int val);
其中 setjmp用来设置一个供longjmp调至的地址envbuf,初次执行setjmp返回0值,程序继续向下执行,
当遇到longjmp调用返回到该处是,促使该函数返回val值,这也就是longjmp的第二个参数,通过这种方式
使得longjmp在跳转的时候可以传递一定的信息给setjmp,可以用来分析跳转原因,方便程序按照不同的返
回值进行不同的处理。
- #include <setjmp.h>
- #include <stdio.h>
- #include <signal.h>
- jmp_buf buf;
- void handler(int signal)
- {
- if(signal==SIGINT)
- printf("Recived SIGINT ,go back to main/n");
- longjmp(buf,1);
- }
- int main()
- {
- signal(SIGINT,handler);
- if(setjmp(buf))
- {
- printf("Back in main,infinite loop begins/n");
- }
- else
- printf("infinite loop begins/n");
- loop:
- goto loop;
- }
上面的函数通过在信号捕捉函数中调用longjmp使得程序能返回到main函数继续执行,所以
setjmp和longjmp的一个很显然的用途就是,从一些非致命行程序错误中返回,使得程序继续
执行。
但是在上面的例子中存在一个问题,当进程第一次接受到SIG_INT信号(Ctrl+C)后成功返回main中,但是
以后接受到SIG_INT信号却不做任何动作了。原因何在呢?因为:
调用l o n g j m p时有一个问题。当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被
自动地加到进程的信号屏蔽字中。这阻止了后来产生的这种信号中断此信号处理程序。如果用
l o n g j m p跳出此信号处理程序,则对此进程的信号屏蔽字会发生什么呢?一般实现是不会恢复
原来的信号屏蔽字的,所以SIG_INT信号被屏蔽了,以后不再响应了。
在4 . 3 + B S D下,s e t j m p和l o n g j m p保存和恢复信号屏蔽字。但是, S V R 4并不
做这种操作。4 . 3 + B S D提供函数_ s e t j m p和_ l o n g j m p,它们也不保存和恢复信号屏
蔽字。
为了允许两种形式并存, P O S I X . 1并没有说明s e t j m p和l o n g j m p对信号屏蔽字的作用,而是
定义了两个新函数s i g s e t j m p和s i g l o n g j m p。在信号处理程序中作非局部转移时应当使用这两个
函数。函数原型如下:
#include <setjmp.h>
int sigsetjmp( sigjmp_buf * env, intsavemask );
void siglongjmp ( sigjmp_buf * env, int val );
如果调用sigsetjmp时 参数savemask 为非0,则siglongjmp 从信号处理函数返回时,将恢复进程调用sigsetjmp之前的信号屏蔽字。
将上面的例子改成使用这对函数,就可以继续对SIG_INT信号进行捕捉和从其中返回main了。
- #include <setjmp.h>
- #include <stdio.h>
- #include <signal.h>
- sigjmp_buf buf;
- void handler(int signal)
- {
- if(signal==SIGINT)
- printf("Recived SIGINT ,go back to main/n");
- siglongjmp(buf,1);
- }
- int main()
- {
- signal(SIGINT,handler);
- if(sigsetjmp(buf,1))
- {
- printf("Back in main/n");
- }
- else
- printf("infinite loop begins/n");
- loop:
- goto loop;
- }
- C语言中的跳转goto&&setjmp&&longjmp sigsetjmp siglongjmp
- C语言中的跳转goto&&setjmp&&longjmp sigsetjmp siglongjmp
- 非本地跳转函数setjmp,longjmp, sigsetjmp, siglongjmp
- 函数setjmp,longjmp和sigsetjmp,siglongjmp
- csapp读书笔记-使用setjmp/sigsetjmp和longjmp/siglongjmp进行非本地跳转
- C语言的结构跳转 (goto / longjmp)
- C语言中的setjmp与longjmp
- C语言中的setjmp和longjmp函数
- c 语言中的setjmp和longjmp
- c语言中的setjmp和longjmp简介
- c中的setjmp longjmp
- c语言中的函数间的跳转函数setjmp和longjmp
- c语言中的函数间的跳转函数setjmp和longjmp(zz)
- c语言中的函数间的跳转函数setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- uc脚本 1--变量与数据类型
- 【setjmp和longjmp 】 C语言的非局部跳转:setjmp和longjmp(跨函数长跳转)
- 三极管的选型
- 享受寂寞
- 在网页中插入一个透明背景的PNG图片
- C语言中的跳转goto&&setjmp&&longjmp sigsetjmp siglongjmp
- JAVA性能优化需要注意的26个地方
- 纯HTML访问数据库,Sql和Access
- asp.net中GridView删除前的确认操作
- 任务栏程序图标与托盘图标的移动
- linux 源代码目录结构
- 风的世界里有海的七滴泪水
- 计数数据/计量数据
- 正则表达式——详细讲解平衡组