君子性非异也,善假于物也。

如有恒,何须三更起,半夜眠;最怕莫,三天打鱼两天晒网,竹篮打水一场空!
posts - 31, comments - 23, trackbacks - 0, articles - 30
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

C中的跳转语句[非goto]

Posted on 2006-11-04 21:18 neter 阅读(1164) 评论(4)  编辑 收藏 引用 所属分类: 程序设计
 1 #include  < stdio.h >
 2 #include  < setjmp.h >
 3 jmp_buf buf;
 4
 5 static   void  babana()
 6 {
 7     printf( " in babana()\n " );
 8     longjmp(buf, 1 );
 9     printf( " never see me\n " );
10 }

11
12 int  main()
13 {
14      if (setjmp(buf))
15      {
16         printf( " back in main\n " );
17     }

18      else
19      {
20         printf( " first time through\n " );
21         babana();
22     }

23      return   0 ;
24 }
 setjmp()首先被调用,并且返回0.
goto是不能跳出当前函数的,而longjmp甚至可以跳到其他文件的函数中去(估计就是为什么要在名字里加个long的原因吧,:)).
但 longjmp只能跳回到曾经去过的地方,而setjmp正是标记到过的地方,所以从这角度来想的话,longjmp更像是"从何处来"而不是goto"去哪里".

这也可以所就是C++中" catch "," throw " 的一个起源吧.

Feedback

# re: C中的跳转语句[非goto]  回复  更多评论   

2006-11-06 10:54 by 蓝色feel's Blog
没有用过
但是跨函数的跳转会不会出问题呢
栈上东西怎么办?

# re: C中的跳转语句[非goto]  回复  更多评论   

2006-11-06 11:18 by shaohua
to:@蓝色feel's Blog
不会出问题的;
这个只是用于跳转的,栈上的数据当然就是离开后被销毁了啊,没有办法做保存的.

# re: C中的跳转语句[非goto]  回复  更多评论   

2006-11-07 10:37 by 蓝色feel's Blog

嗯,刚才实验了一下,此话只对了一半
确实是被销毁了,但是没有调用析构函数
而C++中 throw catch 是能够将栈上的对象正确析构的

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

jmp_buf buf;

class Foo
{
public:
Foo() { std::cout << "Ctor" << std::endl; }
~Foo(){ std::cout << "Dtor" << std::endl; }
};

static void babana()
{
Foo foo;
printf( " in babana()\n " );
longjmp(buf, 1 );
printf( " never see me\n " );
}


int main()
{
if (setjmp(buf))
{
printf( " back in main\n " );
}
else
{
printf( " first time through\n " );
babana();
}
return 0;
}

# re: C中的跳转语句[非goto]  回复  更多评论   

2006-11-07 10:47 by shaohua
to:@蓝色feel's Blog
的确正如你说的那样的,但我们平常一般都不会显式地去释放栈上的内存的,如果一定要这样做的话也是没有错的,但其实没有多大的必要的,因为系统自己会对栈进行很好的管理的.

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理