Logo
Section 1 / 5

main() 函数的返回值

本节课讲解了 main() 函数的返回值以及如何指定返回值。

导入

main() 函数的返回值

本节课讲解了 main() 函数的返回值以及如何指定返回值。

我们已经了解到 main() 是一个函数。程序的执行从 main() 开始,然后分支到其他函数。到目前为止,我们使用的 main() 函数定义如下:

1void main() { 2 // ... 3}

根据这个定义,main() 不接受任何参数,也不返回值。实际上,在大多数系统中,每个程序在结束时都必须向其运行环境返回一个值,这被称为 退出状态 或 返回码。因此,尽管可以将 main() 的返回类型指定为 void,但它实际上仍会向操作系统或启动环境返回一个值。

main() 的返回值

程序总是由某个环境中的实体启动的。启动程序的实体可能是用户在终端输入程序名称并按下回车键的 shell,也可能是程序员点击 [运行] 按钮的开发环境等。

在 D 语言以及多种其他编程语言中,程序通过 main() 的返回值向其运行环境传递退出状态。

返回码的具体含义取决于应用程序和系统。在几乎所有系统中,返回值为零表示程序成功完成,而其他非零值通常表示某种失败。不过也有例外情况。例如,在 OpenVMS 系统中,偶数值表示失败,奇数值表示成功。但大多数情况下,[0, 125] 范围内的值可以安全地用作返回码,其中 1 到 125 的值具有特定于该程序的意义。

例如,常见的 Unix 命令 ls(用于列出目录内容)返回 0 表示成功,1 表示轻微错误,2 表示严重错误。

在许多环境中,可以通过 $? 环境变量查看最近在终端中执行的程序的返回值。例如,当使用 ls 命令尝试列出一个不存在的文件时,其非零返回值可以通过 $? 观察到,如下所示。

注意: 在下面的命令行交互中,以 # 开头的行表示用户输入的内容。如果你想尝试相同的命令,请输入这些行的内容,但不要包含 # 字符。此外,本课后面的示例会启动一个名为 deneme 的程序;请将其替换为你自己的测试程序名称。
另外,虽然以下示例展示的是 Linux 终端中的交互,但在其他操作系统的终端中,行为类似但不完全相同。

1# ls a_file_that_does_not_exist 2ls: cannot access a_file_that_does_not_exist: No such file or directory 3# echo $? 42 ← ls 的返回值

自动产生的返回值

我们之前编写的一些程序在无法继续执行任务时会抛出异常。如前所述,当抛出异常时,程序将以 object.Exception 错误信息终止。

在这种情况下,即使 main() 被定义为返回 void,程序环境仍会自动返回一个非零的状态码。下面我们通过一个简单的程序来演示这一点,该程序因异常而终止:

1import std.stdio; 2 3void main() { 4 throw new Exception("There has been an error."); 5}

尽管返回类型被声明为 void,但实际返回值是非零的:

1# ./deneme 2object.Exception: There has been an error. 3... 4# echo $? 51

同样地,成功终止的 void main() 函数也会自动返回零作为返回值。下面我们通过一个成功终止的程序来验证这一点:

1import std.stdio; 2 3void main() { 4 writeln("Done!"); 5}

该程序返回零:

1# ./deneme 2Done! 3# echo $? 40

指定返回值

若要让 main() 返回特定的返回码,只需在 main() 中显式返回一个值即可。这一过程与其他函数的返回方式相同。需要将返回类型声明为 int,并通过 return 语句返回具体数值:

1import std.stdio; 2 3int main() { 4 int number; 5 write("请输入一个介于 3 和 6 之间的数字: "); 6 readf(" %s", &number); 7 8 if ((number < 3) || (number > 6)) { 9 stderr.writefln("ERROR: %s 不合法!", number); 10 return 111; 11 } 12 13 writefln("感谢您输入 %s。", number); 14 15 return 0; 16}

当输入的数字在有效范围内时,程序的返回值为零:

1# echo $? 20

当输入的数字超出有效范围时,程序的返回值为 111:

1# ./deneme 2请输入一个介于 3 和 6 之间的数字: 10 3ERROR: 10 不合法! 4# echo $? 5111

上述程序中选择 111 作为返回码是随意的;通常情况下,使用 1 作为失败码就足够了。

标准错误流 stderr

上面的程序使用了标准流之一——stderr。它专门用于输出错误信息:

  • stdin:标准输入流
  • stdout:标准输出流
  • stderr:标准错误流

当程序在终端中运行时,通常写入 stdout 和 stderr 的消息都会显示在终端窗口中。必要时,可以分别重定向这两个输出流,但我们不会在此深入讨论细节。


在下一课中,我们将学习 main() 的参数。

函数参数

main() 函数的参数