退出和退货有什么区别?

时间:2010-08-11 23:08:03

标签: c

从C程序中的任何地方调用C编程中的return和exit语句有什么区别?

4 个答案:

答案 0 :(得分:133)

  • 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回来”。另请注意调用库函数#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()函数并终止进程。

如果在程序中的任何位置调用来自returnmain()的{​​{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头文件的函数