C语言异常处理和exit()怎样使用?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言异常处理和exit()怎样使用?相关的知识,希望对你有一定的参考价值。
try catch
c语言中exit()函数的用法:用exit()函数可以退出程序并将控制权返回给操作系统,而用return语句可以从一个函数中返回并将控制权返回给调用该函数的函数。如果在main()函数中加入return语句,那么在执行这条语句后将退出main()函数并将控制权返回给操作系统,这样的一条return语句和exit()函数的作用是相同的。下例是一个使用了exit()函数和return语句的程序:
#include <stdio.h>
#include <stdlib.h>
int main (int, char** );
int do_processing (void);
int do_something_daring();
int main (int argc, char** argv)
int ret_code;
if (argc <3)
printf ("Wrong number of arguments used ! \\n");
/* return 1 to the operating system * /
exit(1);
ret_code = do_processing ();
......
/* return 0 to the operating system * /
exit(0);
int do_processing(void)
int rc;
rc = do_aomcthing_daring();
if (rc == ERROR)
printf ("Something fiahy ia going on around here... *\\n);
/* return rc to the operating syatem * /
exit (re);
/* return 0 to the calling function * /
return 0;
在上例的main()函数中,如果argc小于3,程序就会退出。语句“exit(1)”指示程序在退出时将数字1返回给操作系统。操作系统有时会根据程序的返回值进行一些相关的操作,例如许多DOS批处理文件会通过一个名为ERRORLEVEL的全局变量来检查可执行程序的返回值。 参考技术A #include<stdio.h>
#include<iostream.h>
#define epsilon 1.0e-6
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
void Bmi()
//评测体重标准
double height,weight,s;//定义:身高,体重,评测标准变量
printf("请输入身高,单位(M):\n");
scanf("%f",&height);
printf("请输入体重,单位(KG):\n");
scanf("%f",&weight);
s=weight/(height*height);
if(s<18)
printf("体重偏瘦");
if(s>=18&&s<25)
printf("体重正常");
if(s>=25&&s<30)
printf("体重超重");
if(s>=30)
printf("重度肥胖");
int main()
/*printf("abd\n");
int a[30],n;
int k=0;
for(int i=0;;i++)
printf("qingshurushu\n");
scanf("%d",&n);
if(n>20&&n<90)
a[k]=n;
++k;
printf("k=%d",k);
if(k>29)
break;
for(i=0;i<30;i++)
printf("a[%d]=%d\n",i,a[i]);
*/
location1:
int a;
printf("\n");
printf("体重诊断(BMI)应用已启动--\n");
printf("1.BMI体重诊断\n");
printf("2.退出诊断\n");
scanf("%d",&a);
try
if(a==1)
Bmi();//调用评测体重标准的函数
printf("\n");
goto location1;
if(a==2)
exit(0);
catch(int)
printf("请按要求输入正确的选项号!");
return 1;
exit() 和 abort() 有啥区别?
【中文标题】exit() 和 abort() 有啥区别?【英文标题】:What is the difference between exit() and abort()?exit() 和 abort() 有什么区别? 【发布时间】:2010-09-28 15:58:10 【问题描述】:在 C 和 C++ 中,exit()
和 abort()
有什么区别?我正在尝试在出现错误(不是异常)后结束我的程序。
【问题讨论】:
【参考方案1】:abort 发送一个 SIGABRT 信号,exit 只是关闭执行正常清理的应用程序。
您可以随心所欲地处理 abort 信号,但默认行为是关闭应用程序以及错误代码。
abort 不会执行静态和全局成员的对象销毁,但 exit 会。
当然,当应用程序完全关闭时,操作系统会释放所有未释放的内存和其他资源。
在 abort 和 exit 程序终止中(假设您没有覆盖默认行为),返回码将返回到启动您的应用程序的父进程.
看下面的例子:
SomeClassType someobject;
void myProgramIsTerminating1(void)
cout<<"exit function 1"<<endl;
void myProgramIsTerminating2(void)
cout<<"exit function 2"<<endl;
int main(int argc, char**argv)
atexit (myProgramIsTerminating1);
atexit (myProgramIsTerminating2);
//abort();
return 0;
评论:
如果未注释 abort:不打印任何内容,并且不会调用 someobject 的析构函数。
如果 abort 像上面这样注释:someobject destructor will be called 您将得到以下输出:
退出函数2 退出函数1
【讨论】:
这里调用exit function 2 THEN exit function 1. gcc 4, Linux 2.6. atexit 的手册页显示:“[使用 atexit 注册的] 函数以相反的顺序调用;不传递任何参数。” @strager 是对的,atexit 注册的函数应该在调用 exit 或 main 返回时以相反的顺序调用。 运行测试,似乎在所有 atexit 回调之后调用了全局实例的析构函数。 +1 用于提醒人们即使在 abort() 调用之后操作系统最终也会释放所有分配的资源。【参考方案2】:abort()
退出程序而不首先调用使用atexit()
注册的函数,也没有首先调用对象的析构函数。 exit()
在退出你的程序之前两者都做。但它不会为自动对象调用析构函数。所以
A a;
void test()
static A b;
A c;
exit(0);
将正确地破坏a
和b
,但不会调用c
的析构函数。 abort()
不会调用这两个对象的析构函数。不幸的是,C++ 标准描述了另一种确保正确终止的机制:
具有自动存储期限的对象都在一个程序中销毁,该程序的函数
main()
不包含自动对象并执行对exit()
的调用。通过抛出在main()
中捕获的异常,可以将控制直接转移到这样的main()
。
struct exit_exception
int c;
exit_exception(int c):c(c)
;
int main()
try
// put all code in here
catch(exit_exception& e)
exit(e.c);
不要调用exit()
,而是安排代码throw exit_exception(exit_code);
。
【讨论】:
+1 因为,虽然 Brian R. Bondy 很好,但您确实提出了中止/退出的问题(不是调用的堆栈对象的析构函数),并为 RAII 密集型 C++ 进程提供了替代方案。 我正在寻找一种无需调用 dtor 即可退出程序的方法,而您的答案正是我想要的!谢谢 这当然是完全正确的,如果你的自动对象析构函数不被调用真的很重要:-) 据我所知,exit 和 abort 之间的另一个区别是,abort 可能(取决于操作系统配置)导致生成核心转储。【参考方案3】:abort
发送SIGABRT
信号。 abort
不会返回给调用者。 SIGABRT
信号的默认处理程序关闭应用程序。 stdio
文件流被刷新,然后关闭。但是,C++ 类实例的析构函数不是(不确定这一点——也许结果未定义?)。
exit
有自己的回调,用atexit
设置。如果指定了回调(或仅指定了一个),则按照与注册顺序相反的顺序调用它们(如堆栈),然后程序退出。与abort
一样,exit
不会返回给调用者。 stdio
文件流被刷新,然后关闭。此外,还会调用 C++ 类实例的析构函数。
【讨论】:
exit可以有多个通过atexit注册的回调函数,当exit被调用时,所有的回调函数都会按照注册时的相反顺序被调用。 @Gamble,当然,我在几分钟前对@Bondy 的回答的评论中提到了自己。我将编辑自己的答案以反映这一点。【参考方案4】:来自 exit() 手册页:
exit() 函数导致正常的进程终止,并且 status & 0377 返回给父级。
来自 abort() 手册页:
abort() 首先解除对 SIGABRT 信号的阻塞,然后引发该信号 调用进程的信号。这会导致进程异常终止,除非捕捉到 SIGABRT 信号并且该信号 处理程序不返回。
【讨论】:
【参考方案5】:当程序调用exit
()时会发生以下情况:
atexit
函数注册的函数被执行
所有打开的流都被刷新和关闭,tmpfile
创建的文件被删除
程序以指定的主机退出代码终止
abort
() 函数将SIGABRT
信号发送到当前进程,如果它没有被捕获,程序将终止,但不能保证打开的流被刷新/关闭,或者通过tmpfile
创建的临时文件是移除后,atexit
注册的函数不会被调用,并且返回一个非零的退出状态给主机。
【讨论】:
嗯。该标准说,如果信号处理程序“不返回”,程序才不会终止。您对 C 非常熟悉。您能想象任何可以让它继续正常执行而不返回的场景吗?我想象 longjmp,但我不确定它在信号处理程序中的行为。 一般来说,从信号处理程序调用 longjmp 是未定义的,但是当信号是通过 raise/abort 生成时有一种特殊情况,所以我想这在理论上是可能的,虽然我不认为我见过它完成。现在我将不得不尝试一下;) 这似乎有效(由于 300 个字符的限制,分成多个帖子):#include以上是关于C语言异常处理和exit()怎样使用?的主要内容,如果未能解决你的问题,请参考以下文章