从C程序中的任何地方调用C编程中的return和exit语句有什么区别?
答案 0 :(得分:133)
main()
函数中两者都做(几乎)同一事件的唯一情况,因为从main执行返回exit()
。
return
的示例:
#include <stdio.h>
void f(){
printf("Executing f\n");
return;
}
int main(){
f();
printf("Back from f\n");
}
如果您执行此程序,则会打印:
Executing f Back from f
exit()
的另一个例子:
#include <stdio.h>
#include <stdlib.h>
void f(){
printf("Executing f\n");
exit(0);
}
int main(){
f();
printf("Back from f\n");
}
如果您执行此程序,则会打印:
Executing f
你永远不会得到“从f回来”。另请注意调用库函数#include <stdlib.h>
所需的exit()
。
另请注意,exit()
的参数是一个整数(它是启动程序进程可以获得的进程的返回状态;传统用法是0表示成功或任何其他错误值)。
return语句的参数是函数的返回类型。如果函数返回void,则可以省略函数末尾的返回值。
最后一点,exit()
有两种_exit()
和exit()
。表单之间的区别在于exit()
(并从main返回)调用使用atexit()
或on_exit()
注册的函数,然后在_exit()
(来自#include <unistd.h>
时真正终止进程}或其同义词_Exit from #include <stdlib.h>
)立即终止进程。
现在还存在特定于C ++的问题。
当C ++从函数(return
- ing)退出时,它执行的工作远远多于C语言。具体来说,它调用本地对象的析构函数超出范围。在大多数情况下,程序员在进程停止后不会太关心程序的状态,因此它没有太大的区别:分配的内存将被释放,文件资源被关闭等等。但是,如果析构函数执行IO,则可能很重要。例如,本地创建的自动C ++ OStream
将不会在调用退出时刷新,并且您可能会丢失一些未刷新的数据(另一方面静态OStream
将被刷新)。
如果您使用的是旧的C FILE*
流,则不会发生这种情况。这些将在exit()
上刷新。实际上,规则与注册的退出函数相同,FILE*
将在所有正常终结点上刷新,其中包括exit()
,但不会调用_exit()
或abort()。
您还应该记住,C ++提供了第三种退出函数的方法:抛出异常。这种退出函数的方式将调用析构函数。如果没有在调用者链中的任何地方捕获,则异常可以转到main()函数并终止进程。
如果在程序中的任何位置调用来自return
或main()
的{{1}},则将调用静态C ++对象(全局变量)的析构函数。如果程序使用exit()
或_exit()
终止,则不会调用它们。 abort()
在调试模式下非常有用,目的是立即停止程序并获得堆栈跟踪(用于事后分析)。它通常隐藏在仅在调试模式下活动的abort()
宏后面。
什么时候退出()有用?
assert()
表示您希望立即停止当前进程。当我们遇到某种不可恢复的问题时,它可以用于错误管理,这些问题不允许代码再做任何有用的事情。当控制流程复杂并且错误代码必须一直向上传播时,它通常很方便。但请注意,这是糟糕的编码习惯。在大多数情况下,静默地结束流程是更糟糕的行为,应该首选实际的错误管理(或者在C ++中使用异常)。
如果在库中完成,对exit()
的直接调用尤其糟糕,因为它会使库用户失败,应该是库用户选择是否实现某种错误恢复。如果您想要一个示例,说明为什么从库中调用exit()
是错误的,那么例如人们就会问this question。
有一个无可争议的合法使用exit()
作为结束fork()在支持它的操作系统上启动的子进程的方法。回到fork()之前的代码通常是个坏主意。这是解释为什么exec()系列的函数永远不会返回给调用者的理由。
答案 1 :(得分:16)
我写了两个程序:
int main(){return 0;}
和
#include <stdlib.h>
int main(){exit(0)}
执行gcc -S -O1
后。在这里我发现了什么
在装配时(只有重要部分):
main:
movl $0, %eax /* setting return value */
ret /* return from main */
和
main:
subq $8, %rsp /* reserving some space */
movl $0, %edi /* setting return value */
call exit /* calling exit function */
/* magic and machine specific wizardry after this call */
所以我的结论是:尽可能使用return
,并在需要时使用exit()
。
答案 2 :(得分:10)
在C中,在程序的启动函数中使用时没有太大区别(可以是main()
,wmain()
,_tmain()
或编译器使用的默认名称。
如果您return
中的main()
,则控件会返回最初启动您的程序的C库中的_start()
函数,然后无论如何都会调用exit()
。所以你使用哪一个并不重要。
答案 3 :(得分:1)
return语句退出当前函数,exit()退出程序
they are the same when used in main() function
return也是一个语句,而exit()是一个需要stdlb.h头文件的函数