我应该使用exit()还是只是在main()中返回语句?就我个人而言,我更喜欢return语句,因为我觉得它就像阅读任何其他函数一样,当我阅读代码时,流控制是流畅的(在我看来)。即使我想重构main()函数,使用return似乎比exit()更好。

exit()是否做了return没有做的特殊事情?


当前回答

在C语言中,从main返回与用相同的值调用exit完全相同。

C标准第5.1.2.2.3节规定:

如果主函数的返回类型与int兼容 ,从初始调用到main函数的返回值相当于 使用main返回的值调用exit函数 函数作为它的参数;11)到达终止的} Main函数返回值为0。如果返回类型为 与int不兼容,终止状态返回到 主机环境未指定。

c++的规则有点不同,在其他答案中提到过。

其他回答

当你的main函数被多次调用时,在main中exit(0)和return(0)实际上是有区别的。

下面的程序

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc == 0)
    return(0);
  printf("%d", main(argc - 1, argv));
}

运行

./program 0 0 0 0

将导致以下输出:

00000

但是这个:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc == 0)
    exit(0);
  printf("%d", main(argc - 1, argv));
}

不管参数如何,都不会打印任何东西。

如果你确定没有人会显式地调用你的main,一般来说在技术上没有太大的区别,但是保持更清晰的代码退出会看起来更好。如果你出于某种原因想要调用main -你应该调整它来满足你的需要。

解析:选C。

我强烈支持r关于使用exit()的评论,以避免在程序实际结束之前自动回收main()中的存储。返回X;main()中的语句并不完全等同于调用exit(X);,因为main()的动态存储在main()返回时消失,但如果调用exit()则不会消失。

此外,在C或任何类似C的语言中,return语句强烈地暗示读者,执行将继续在调用函数中执行,虽然如果计算调用main()函数的C启动例程,这种执行的继续在技术上通常是正确的,但它并不完全是您想要结束进程的意思。

毕竟,如果你想从除main()之外的任何其他函数中结束程序,你必须调用exit()。在main()中始终如一地这样做也会使你的代码更具可读性,而且它也使任何人都更容易重构你的代码;也就是说,从main()复制到其他函数的代码不会因为意外的return语句而行为不当,而这些return语句应该是exit()调用。

因此,将所有这些点结合在一起,得出的结论是,在main()中使用return语句结束程序是一个坏习惯,至少对C来说是这样。

实际上,有区别,但很微妙。它对c++有更多的含义,但区别是重要的。

当我在main()中调用return时,将为局部作用域的对象调用析构函数。如果我调用exit(),将不会为局部作用域的对象调用析构函数!重读。Exit()不返回。这意味着一旦我调用它,就“没有回手”。在该函数中创建的任何对象都不会被销毁。这通常没有影响,但有时有影响,比如关闭文件(当然您希望将所有数据刷新到磁盘?)

注意,即使调用exit(),静态对象也将被清除。最后请注意,如果使用abort(),则不会销毁任何对象。也就是说,没有全局对象、静态对象和局部对象会调用它们的析构函数。

当选择退出而不是返回时,要谨慎行事。

http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a

我总是使用return,因为main()的标准原型说它确实返回int型。

也就是说,某些版本的标准对main进行了特殊处理,如果没有显式的return语句,则假定它返回0。给定以下代码:

int foo() {}
int main(int argc, char *argv[]) {}

g++仅为foo()生成一个警告,并忽略main的缺失返回值:

% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function

至少有一个偏爱exit的原因:如果你的任何atexit处理程序引用main中的自动存储持续时间数据,或者如果你使用setvbuf或setbuf给一个标准流分配了main中的自动存储持续时间缓冲区,那么从main返回会产生未定义的行为,但调用exit是有效的。

另一种潜在的用法(通常只用于玩具程序)是通过递归调用main退出程序。