退出和退货有什么区别?
从C程序中的任何地方调用时,C编程中的return和exit语句有什么区别?
- return是从函数调用返回的语言的指令。
- 退出是终止当前进程的系统调用(不是语言语句)。
唯一的情况是两者在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回来”。 还要注意调用库函数exit()
所需的#include <stdlib.h>
。
还要注意exit()
的参数是一个整数(它是启动程序进程可以获得的进程的返回状态;传统用法为0表示成功,或者表示任何其他错误值)。
return语句的参数是函数的返回types。 如果函数返回void,则可以省略函数结尾处的返回。
最后一点, exit()
有两个口味_exit()
和exit()
。 forms之间的区别在于,在真正终止进程之前, exit()
(和从main返回)调用使用atexit()
或者on_exit()
注册的函数,而_exit()
(来自#include <unistd.h>
或者其同义_Exit从#include <stdlib.h>
)立即终止进程。
现在也有一些特定于C ++的问题。
当从函数退出( return
-ing)时,C ++比C执行更多的工作。 具体来说,它调用本地对象的析构函数超出范围。 在大多数情况下,程序员在程序停止后并不关心程序的状态,因此分配的内存将被释放,文件重新closures等等。 但是,如果你的析构函数执行IO,这可能很重要。 例如,本地创build的自动C ++ OStream
不会在调用中刷新以退出,而且可能会丢失一些未刷新的数据(另一方面,静态OStream
将被刷新)。
如果您使用的是旧的C FILE*
stream,则不会发生这种情况。 这些将在exit()
上被刷新。 实际上,对于已注册的退出函数, FILE*
将在所有正常终止(包括exit()
上刷新,但不会调用_exit()
或abort()。
你还应该记住,C ++提供了第三种方法来抛出函数:抛出一个exception。 这种走出函数的方式将调用析构函数。 如果它在调用者链中的任何地方都没有被捕获,则exception可以继续到main()函数并终止该过程。
静态C ++对象(全局variables)的析构函数将会在你调用程序中的任何地方调用main()
或者exit()
return
调用。 如果程序使用_exit()
或者abort()
终止,他们不会被调用。 abort()
在debugging模式下非常有用,目的是立即停止程序并获取堆栈跟踪(用于事后分析)。 它通常隐藏在仅在debugging模式下激活的assert()
macros之后。
什么时候exit()有用?
exit()
意味着你要立即停止当前进程。 当我们遇到某种无法恢复的问题时,它可能会有一些用于错误pipe理的function,而这些问题不会让您的代码执行任何有用的操作。 当控制stream程复杂且错误代码必须全部传播时,通常是很方便的。 但请注意,这是不好的编码习惯。 在大多数情况下,无情地结束进程是最差的行为,实际的错误pipe理应该是首选的(或者在C ++中使用exception)。
直接调用exit()
在库中完成是特别糟糕的,因为它将会导致库用户,它应该是库用户select实现某种错误恢复。 如果你想要一个为什么从一个库调用exit()
的例子不好,它会导致例如人们问这个问题 。
有一个无可争议的合法使用exit()
作为结束在支持它的操作系统上由fork()启动的subprocess的方法。 回到fork()之前的代码通常是一个坏主意。 这是解释为什么exec()系列的函数永远不会返回给调用者的原因。
我写了两个程序:
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()
。
在C中,在程序的启动函数(可以是main()
, wmain()
, _tmain()
或编译器使用的默认名称)中使用没有多大区别。
如果你在main()
函数中return
,那么控制权就会返回到最初启动你的程序的C库中的_start()
函数,然后调用exit()
。 所以你使用哪一个并不重要。
return语句从当前函数退出,exit()退出程序
they are the same when used in main() function
return也是一个语句,而exit()是一个需要stdlb.h头文件的函数