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

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


当前回答

exit()做了什么'return'没有做的特殊事情吗?

对于一些不常见平台的编译器,exit()可能会将其参数转换为程序的退出值,而main()的返回可能只是直接将值传递给宿主环境而不进行任何转换。

The standard requires identical behavior in these cases (specifically, it says returning something that's int-compatible from main() should be equivalent to calling exit() with that value). The problem is that different OSes have different conventions for interpreting the exit values. On many (MANY!) systems, 0 means success and anything else is a failure. But on, say, VMS, odd values mean success and even ones mean failure. If you returned 0 from main(), a VMS user would see a nasty message about an access violation. There wasn't actually an access violation--that was simply the standard message associated with failure code 0.

然后ANSI出现了,并将EXIT_SUCCESS和EXIT_FAILURE作为参数传递给exit()。标准还规定exit(0)的行为应该与exit(EXIT_SUCCESS)相同,因此大多数实现将EXIT_SUCCESS定义为0。

因此,该标准将您置于VMS的约束中,因为它没有留下任何标准方法来返回值恰好为0的故障代码。

因此,20世纪90年代早期的VAX/VMS C编译器不解释main()的返回值,它只是将任何值返回给主机环境。但是如果您使用exit(),它将做标准要求的事情:将EXIT_SUCCESS(或0)转换为成功代码,将EXIT_FAILURE转换为通用的失败代码。要使用EXIT_SUCCESS,你必须将它传递给exit(),你不能从main()返回它。我不知道该编译器的更现代版本是否保留了这种行为。

一个可移植的C程序是这样的:

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

int main() {
  printf("Hello, World!\n");
  exit(EXIT_SUCCESS);  /* to get good return value to OS */
  /*NOTREACHED*/ /* to silence lint warning */
  return 0;  /* to silence compiler warning */
}

旁白:如果我没记错的话,VMS对出口值的约定比奇数/偶数更微妙。它实际上使用低三位来编码一个严重级别。然而,一般来说,奇数的严重级别表示成功或其他信息,偶数的严重级别表示错误。

其他回答

当你的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返回与用相同的值调用exit完全相同。

C标准第5.1.2.2.3节规定:

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

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

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

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

exit()做了什么'return'没有做的特殊事情吗?

对于一些不常见平台的编译器,exit()可能会将其参数转换为程序的退出值,而main()的返回可能只是直接将值传递给宿主环境而不进行任何转换。

The standard requires identical behavior in these cases (specifically, it says returning something that's int-compatible from main() should be equivalent to calling exit() with that value). The problem is that different OSes have different conventions for interpreting the exit values. On many (MANY!) systems, 0 means success and anything else is a failure. But on, say, VMS, odd values mean success and even ones mean failure. If you returned 0 from main(), a VMS user would see a nasty message about an access violation. There wasn't actually an access violation--that was simply the standard message associated with failure code 0.

然后ANSI出现了,并将EXIT_SUCCESS和EXIT_FAILURE作为参数传递给exit()。标准还规定exit(0)的行为应该与exit(EXIT_SUCCESS)相同,因此大多数实现将EXIT_SUCCESS定义为0。

因此,该标准将您置于VMS的约束中,因为它没有留下任何标准方法来返回值恰好为0的故障代码。

因此,20世纪90年代早期的VAX/VMS C编译器不解释main()的返回值,它只是将任何值返回给主机环境。但是如果您使用exit(),它将做标准要求的事情:将EXIT_SUCCESS(或0)转换为成功代码,将EXIT_FAILURE转换为通用的失败代码。要使用EXIT_SUCCESS,你必须将它传递给exit(),你不能从main()返回它。我不知道该编译器的更现代版本是否保留了这种行为。

一个可移植的C程序是这样的:

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

int main() {
  printf("Hello, World!\n");
  exit(EXIT_SUCCESS);  /* to get good return value to OS */
  /*NOTREACHED*/ /* to silence lint warning */
  return 0;  /* to silence compiler warning */
}

旁白:如果我没记错的话,VMS对出口值的约定比奇数/偶数更微妙。它实际上使用低三位来编码一个严重级别。然而,一般来说,奇数的严重级别表示成功或其他信息,偶数的严重级别表示错误。