【问题标题】:In the main function of a C++ program, what does `return 0` do and mean? [duplicate]在 C++ 程序的主函数中,`return 0` 是什么意思? [复制]
【发布时间】:2012-01-31 13:46:08
【问题描述】:

可能重复:
What is the proper declaration of main?

没有特别引用任何代码,我正在寻找对以下示例的解释:

#include <iostream>

int main()
{
    std::cout << "Hello world" << std::endl;
    return 0;
}

我不明白return 0 做了什么。你能用尽可能简单的英语解释一下吗?

【问题讨论】:

  • 简单的英语:函数main返回值0。 C++ 标准描述了宿主环境如何解释它。
  • 在 Unix shell 中,它可以让你判断命令是否成功,如果失败,可能会告诉你为什么失败。如果退出状态(从main() 返回的值或指定为exit()_exit()_Exit() 的参数)为零,则调用环境(shell)将其解释为成功。如果传递的值为EXIT_FAILURE,则调用环境会将其解释为失败。 Unix 允许退出状态的值为 0..255(尽管有时将其解释为 -128..+127)。在大多数 shell 中,您可以在 $? 中获取实际值。信号使事情复杂化。
  • 解释:您计算机上的某个进程(A)启动了另一个进程(B)。当 B 退出时,它总是会在某处存储一种“退出状态”(这是 main 返回的内容,或者您​​的程序实际作为参数提供给 exit 函数的内容)。父进程 (A) 可以读取该值,并相对于它采取行动:例如:Windows“.bat”脚本可能会读取 %ERRORLEVEL% 事物并对其采取行动。一个 UNIX shell 脚本可能会读取 $?事情,并采取行动。
  • 当我们谈到这个主题时,stackoverflow.com/questions/3309042/what-does-main-return 是一个完全不同的问题。
  • 好的,谢谢 Johnsyweb。

标签: c++


【解决方案1】:

这定义了进程的exit status。尽管是 int,但在类 Unix 系统上,该值始终在 0-255 范围内(请参阅 Exit and Exit Status)。在 Microsoft 系统上,您可以使用 32-bit signed integers as exit codes,您可以使用 %ERRORLEVEL% 进行检查。为了便携性,我建议坚持使用 0-255 范围。

这是一个简单的例子:

$ cat -n exit_code.cpp 
     1  int main()
     2  {
     3      return 42;
     4  }
     5  

构建:

$ make exit_code
g++ exit_code.cpp -o exit_code

运行(在 bash 中):

$ ./exit_code

检查退出状态:

$ echo $?
42

通常,状态为零表示成功和非零失败。这在 shell 脚本等中很有用,以指示故障级别(如果有):

$ ./exit_code
exit_status=$?
if [[ ${exit_status} ]] ; then
    echo "The process failed with status ${exit_status}."
else
    echo "Success!"
fi
The process failed with status 42.

按照下面的cmets...

在标准C++header &lt;cstdlib&gt;中,定义了以下宏:

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

但是,GNU C Library documentationExit Status 部分描述了相同的宏,明智地指出:

可移植性说明:一些非 POSIX 系统对退出状态值使用不同的约定。为了获得更大的可移植性,您可以使用宏 EXIT_SUCCESS 和 EXIT_FAILURE 分别作为成功和失败的常规状态值。它们在文件 stdlib.h 中声明。

【讨论】:

  • 谢谢!但是编码员为什么要定义错误代码呢?
  • +1 得到一个很好的明确答案 :) 作为 OP 的一个侧面,虽然 42 在这里很好地说明了这一点,但我想我记得说唯一的可移植返回码是 0,EXIT_SUCCESS和 EXIT_FAILURE - 如果您希望代码可移植,请不要使用其他东西。
  • @frunsi:请您引用该规则的标准吗?
  • @Johnsyweb:是的,但是 AFAIK 这三个是 ISO C++ 标准中提到的三个可移植返回码。可悲的是,我没有这个临时的参考,尽管快速谷歌的“c++ 便携式返回主要退出成功”似乎确实让我相信我想说的话。此外,有用和便携不一定是一回事。
  • 感谢各位的评论。希望我更新的帖子@DustinStalin 有足够的信息来回答他的问题。
【解决方案2】:

一般returning

每个函数都有一个返回类型

在下面的例子中,类型是void,这是一个没有值的“不完整类型”;使用 this 作为返回类型意味着函数没有返回值:

void foo() {
   std::cout << "Hello world\n";
}

但是,在下面的示例中,返回类型是int

int foo() {
   return 3;
}

return 语句确定调用函数foo 的值将计算为什么值。因此,std::cout &lt;&lt; foo() 将导致“3”被打印到标准输出。


return来自main,具体来说

当有问题的函数恰好是“main”函数,或者程序的入口点时,它有点特别,因为“main”函数的“返回值”被认为是程序的“退出代码” — 它告诉调用环境(例如终端会话)程序的执行是否被认为是成功的。必须是int0 的值在这里表示“一切正常”:

值得注意的是,您实际上可以在“main”函数中完全省略return 0;,因为它将被隐式包含。但是,如果您想 return 1; 或其他一些值,这对您没有多大帮助,并且它不会与其他功能一起使用。


引文

[C++11: 3.6.1/5]: main 中的 return 语句具有以下效果 离开主要功能(自动销毁任何对象 存储持续时间)并调用std::exit,返回值作为 论点。 如果控制到达main 的末尾而没有遇到 return 语句,效果就是执行return 0;

[C++11: 18.5/8]:

       [[noreturn]] void exit(int status)

函数exit() 在此国际标准中有其他行为

  • 首先,销毁具有线程存储持续时间并与当前线程关联的对象。
    接下来,销毁具有静态存储持续时间的对象,并调用通过调用atexit 注册的函数。销毁和调用的顺序见 3.6.3。 (调用 exit() 不会破坏自动对象。)
    如果由于该函数没有为抛出的异常提供处理程序而控制退出由 exit 调用的已注册函数,则应调用 terminate() (15.5.1)。
  • 接下来,带有未写入缓冲数据的所有打开的 C 流(由 &lt;cstdio&gt; 中声明的函数签名介导)被刷新,所有打开的 C 流都被关闭,并且通过调用 tmpfile() 创建的所有文件都被删除。李>
  • 最后,控制权返回到宿主环境。如果状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果状态为EXIT_FAILURE,则返回状态未成功终止的实现定义形式。否则返回的状态是实现定义的。

引导笔记

我建议使用these resources 之一,因为这类事情在任何经过​​同行评审的C++ 书籍中都有适当的解释; YouTube 教程不是学习 C++ 的好方法,Stack Overflow 的贡献者通常希望你有一本像样的书来形成你之前的研究,然后再寻求帮助。

【讨论】:

  • 对于托管程序,没有什么“常规”——标准非常清楚地描述了 main 的返回值应该达到的目标......
  • @TomalakGeret'kal: 18.5 "最后,控制权返回给宿主环境。如果状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果状态为EXIT_FAILURE,返回状态不成功终止的实现定义的形式。否则返回的状态是实现定义的。"
  • @frunsi:它总是有一个类型,它可能并不总是返回一个void 是一种类型。
  • @frunsi: C++11 §3.9.1\9 "void 类型有一组空值。void 类型是不完整的类型,无法完成。它用作返回不返回值的函数的类型。” C++ 标准对我来说似乎很清楚 void 确实是一种类型。我可以看到将“void”视为无类型构造是多么容易,所以这个错误是可以理解的。
  • 返回类型为 void 的函数表示没有返回值的函数。 void not 不代表没有类型。它代表没有
【解决方案3】:

使用它是因为您可以将程序用作命令行工具。如果有另一个进程在等待你的程序的输出,你可以选择如果一切都成功则返回 0,如果有错误则返回 -1 或任何其他常量,根据你想要传达的内容。

【讨论】:

    【解决方案4】:

    想想你的老板告诉你去取邮件。收到邮件后,你告诉老板一切都好。

    操作系统是老板,程序是你。而return 0 所做的只是告诉操作系统一切正常。

    【讨论】:

    • 这让我畏缩了一些慢性病。我的错,不是你的。
    • 使用这个类比,1 会是什么?邮件被老鹰拦截了,所以在你清除老鹰之前无法完成工作?
    【解决方案5】:

    在windows下你可以按如下方式测试返回值(在批处理脚本中):

    MyAppTest.exe
    @if "%ERRORLEVEL%" == "0" goto success
     echo Failure
     goto end
    :success
     echo Success
    :end
    

    【讨论】:

      【解决方案6】:

      main()返回与调用std::exit()并将返回值作为status参数传递的效果相同。

      std::exit 的行为在第 18.5 节 ([support.start.term]) 中有详细说明,并描述了状态码:

      最后,控制权返回到宿主环境。如果状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果状态为EXIT_FAILURE,则返回状态未成功终止的实现定义形式。否则返回的状态是实现定义的。

      【讨论】:

        【解决方案7】:

        return 用于转义函数。返回值 0 只是允许它以代码 0 退出。此外,返回 0 表示应用程序成功退出。

        【讨论】:

          【解决方案8】:

          取决于操作系统,但退出代码 0 表示在 UNIX、VMS 和 Windows 上成功

          【讨论】:

            【解决方案9】:

            主函数的返回值被返回给调用应用程序或进程(很多时候这是一个 shell 脚本)。返回值用于指示应用程序的退出状态。

            对于返回值应该是什么没有严格的规则,但按照惯例,返回值为零表示正常的应用程序退出。任何非零值都表示应用程序异常退出。

            【讨论】:

              【解决方案10】:

              在像您这样的简单应用程序中,返回值没有任何意义。如果有一个观察过程(例如一个程序启动另一个程序),这可能是一种获取状态或错误代码的简单方法。

              对于没有状态或错误代码的简单应用程序,大多数人return 0 表示正常的应用程序退出(通常是成功),return 1 如果应用程序退出。无法正确执行。

              【讨论】:

                【解决方案11】:

                0 是一个整数。

                你的主函数必须返回一个整数。

                看看:

                int main()
                

                int代表整数,在这种情况下return返回0:一个整数来终止程序。

                通常对于一个错误你必须返回1; 0 是成功的常规值。

                【讨论】:

                  【解决方案12】:

                  在现代操作系统上,每个程序都会以特定的“退出代码”退出。

                  免责声明 NO 1.:该概念的实际规范(根本没有退出代码)完全超出了任何编程语言规范的范围。所以:任何人再次向我询问对标准的引用,都可以退回到自己,并暂时考虑一个更好的答案。

                  DISPLAIMER NO 2.:这些退出代码的实际值未在非实际“编程语言规范”中指定,因为这超出了“编程语言规范”的范围。

                  长期以来,实践表明,退出代码“0”表示“成功”,任何其他代码都表示错误...

                  【讨论】:

                    猜你喜欢
                    • 2019-12-08
                    • 2011-05-14
                    • 2021-09-30
                    • 2013-11-18
                    • 2020-05-26
                    相关资源
                    最近更新 更多