从 main 返回零是不是必要,从 main 的返回值如何有用?

Posted

技术标签:

【中文标题】从 main 返回零是不是必要,从 main 的返回值如何有用?【英文标题】:Is returning zero from main necessary, and how can the return value from main be useful?从 main 返回零是否必要,从 main 的返回值如何有用? 【发布时间】:2010-09-25 11:03:12 【问题描述】:

我知道 C89 中的惯例是在 C 程序中始终从 main 返回一个 0 整数值,如下所示:

int main() 

    /* do something useful here */

    return 0;

这是向操作系统返回一个“成功”的结果。我仍然认为自己是 C 的新手(或充其量是中级程序员),但迄今为止我从未完全理解为什么这很重要。

我的猜测是,如果您将此程序的输出绑定到另一个程序的输入,这是一个有用的返回结果,但我不确定。我从来没有发现它有用,或者我只是不明白它的意图是什么。

我的问题:

    C 程序是否总是需要返回零? main() 的返回值有什么用处?

【问题讨论】:

***.com/questions/204476/… 【参考方案1】:

在编写脚本时(例如在 Bash 中,或在 Windows 上的 CMD.exe) 您可以使用 && 和 || 链接一些命令运营商。

规范地,如果a 的结果为零,a && b 将运行b,如果a 返回非零,a || b 将运行b

如果您希望在前一个命令成功的情况下有条件地运行命令,这很有用。例如,如果文件包含单词 foo,您想删除它。然后你将使用:

grep foo myfile && rm myfile

grep 匹配时返回 0,否则返回非零。

【讨论】:

我觉得你的回答很有用,但不是很清楚。你可以给我一个例子吗?看起来您从护目镜搜索中剪切并粘贴了一些文本... 不,我没有剪过去,但我不是以英语为母语的人,因此有时会让一些读者感到困惑。 很公平,我认为他在解释返回值可能对条件有用。 规范地,如果 a 的结果为零,a && b 将运行 b 它不是一个关系运算符,它只会在 a 返回 1 而不是零时运行? 【参考方案2】:

返回 0 是一个约定。当程序返回 0 时,可以假定它运行良好,而无需实际查看程序做了什么(咳咳:D)。

作为一种广泛使用的约定,这种假设存在于很多地方。正如 Benoit 指出的,shell(UNIX 和 Windows)和操作系统的其他部分就是这种情况。

所以回答你的问题:

    对于 C 程序,您必须返回 EXIT_SUCCESS 或 EXIT_FAILURE。 但是您甚至可以返回 EXIT_FAILURE 如果您的程序运行正常。 如果你 不要返回 0 (EXIT_SUCCESS), 其他的很有可能 程序将假定您的程序 失败。

有一个与 C++ 和 C 相关的问题很好的回答

What should main() return in C and C++?

【讨论】:

【参考方案3】:

在现代 C aka C99(不确定 C89)中,main 的所有三个终止符都是等效的:

刚刚结束main最后 return 0 exit(0)

所有这一切背后的想法是(正如其他人提到的)为调用程序提供返回状态。

【讨论】:

第一个不正确。除非有明确的 return,否则 C 函数将返回它评估的最后一个东西。 int main() printf("Hello, world!\n"); 实际上会以 14 退出,因为 printf() 返回了它。 (如果您按照应有的方式打开了编译器警告,那么编译它会抱怨控制到达非 void 函数的末尾。)第二个仅在 main() 中是正确的。 第一个 is 在 C99 中是正确的(但在 C89 中不是):“如果主函数的返回类型是与 int 兼容的类型,[...]到达终止主函数的 返回值 0。” (C99 5.1.2.2.3)【参考方案4】:

返回值是程序执行的“结果”,0表示成功终止,非零返回值表示失败或意外终止。

当你正常调用你的程序时,返回值对系统来说并不重要,但它可以有两个目的。其中之一是调试。在 MSVC(C++ 最常用的编译器)中,您会在程序执行完毕后看到程序返回值。这有助于了解程序退出的“方式和原因”。

另一种用途是从其他程序调用您的应用程序时,返回值可能表示成功或传递结果。

【讨论】:

【参考方案5】:

您好,就像您说的那样,主要是将该程序用作更广泛的程序网络的一部分。将零返回到程序环境让网络知道一切正常(就像你说的那样)但是你也可以让它返回 1、2、3...(取决于发生了什么错误)让你的代码网络知道某事出错了。等效地,您可以在“主”程序的末尾使用 exit(0) 或 exit(1) 来执行完全相同的操作。您可能会发现这很有用: http://en.wikipedia.org/wiki/Exit_status 希望有帮助。杰克

【讨论】:

【参考方案6】:

您应该在程序正确完成时使用 EXIT_SUCCESS,在没有正确完成时使用 EXIT_FAILURE。 EXIT_SUCCESS 为零,零可移植到任何操作系统,而 EXIT_FAILURE 则从 UNIX 更改为 Windows。这些常量在stdlib.h 标头中定义。

#include <stdlib.h>

int main()


    int toret = EXIT_SUCCESS;

    if ( !( /* do something useful here */ ) ) 
        toret = EXIT_FAILURE;
    

    return toret;

在为控制台编写程序时,程序的返回码更有用。如今,除非您在非常专业的环境中工作,否则这种情况已很少见(即使现在这种情况也在发生变化,工作流程工具可用)。

正如@Benoit 所说,退出代码告诉操作系统何时操作成功与否。如果退出代码意味着失败,那么您可以中断批处理程序的流程,因为它不太可能成功。

例如,如果编译成功,编译器的退出代码可以为零,如果编译不成功,则可以有任何其他值。在 Windows 中,这可以通过操作系统变量“errorlevel”来访问:

gcc helloworld.cpp -ohelloworld.exe
goto answer%errorlevel%
:answer0
copy helloworld.exe c:\users\username\Desktop
echo Program installed
goto end
:answer1
echo There were errors. Check your source code.
:end
echo Now exiting...

编译成功后,此 Windows 批处理文件会在桌面“安装”helloworld.exe。由于您可以通过双击触发批处理文件的执行,因此可以避免触摸命令行进行编译。

当然,考虑到集成环境可以更好地管理(如果退出代码不存在,它们将无法正常工作)。另请注意,ma​​ke 是该领域的佼佼者:

https://en.wikipedia.org/wiki/Make_(software)

使也需要退出代码才能正确运行。

【讨论】:

正确的 C 包含文件是“stdlib.h”而不是“cstdlib.h” 我发现您声称退出代码“非常罕见”非常奇怪。当然有许多领域不再广泛使用它们,但这些领域与 C 本身不再广泛使用的领域相同。在大多数情况下,如果您使用 C,您很可能也会关心退出代码。 @Porculus,我试图传达的(我想我已经说清楚了)是它在标准用户中并不常见,而是在高级用户中。【参考方案7】:

我们可以从main() 返回任何整数。 现在,如果我们没有明确提及 main() 函数返回任何特定值,默认情况下 main() 函数返回 0。

return 0 实际上类似于程序成功终止而没有任何错误,尽管它不是规则,但这是它的工作方式。

如果我们显式返回一个非零数字,那么即使程序运行正确但在内部它实际上意味着程序因某些错误而终止或程序因意外结果而终止。如果另一个程序被基于在我们当前的程序上使用 '&&' 或 '||' 返回值在我们的命令行中。

您还可以使用以下命令检查您之前在 linux 上执行的程序的返回值:

echo $?

【讨论】:

以上是关于从 main 返回零是不是必要,从 main 的返回值如何有用?的主要内容,如果未能解决你的问题,请参考以下文章

main函数的传参与返回

如何从 Main Activity 到 Fragment,并从同一个 Fragment 返回到 Main Activity?

从 main 调用带有返回变量的方法

从函数返回一个字符串到main

TFS——级联分支的可持续性

main 函数不返回任何内容。为啥? [复制]