在 C 和 C++ 中 main() 应该返回什么?
-
03-07-2019 - |
题
定义的正确(最有效)方法是什么 main()
C 和 C++ 中的函数 — int main()
或者 void main()
——为什么?如果 int main()
然后 return 1
或者 return 0
?
这个问题有很多重复,包括:
- C 的有效签名是什么
main()
功能? - 返回类型为
main()
功能 - 之间的区别
void main()
和int main()
? main()
C++ 中的签名- 正确的声明是什么
main()
? — 对于 C++,确实有一个非常好的答案。 - 风格
main()
C 中的函数 - 返回类型为
main()
C中的方法 int main()
与void main()
在C中
有关的:
解决方案
返回值为 main
应指示程序如何退出。正常退出一般用0返回值来表示 main
. 。异常退出通常由非零返回来表示,但对于如何解释非零代码没有标准。也正如其他人指出的那样, void main()
C++ 标准明确禁止,不应使用。有效的 C++ main
签名是:
int main()
和
int main(int argc, char* argv[])
这相当于
int main(int argc, char** argv)
还值得注意的是,在 C++ 中, int main()
可以不带 return 语句,此时它默认返回 0。C99 程序也是如此。无论 return 0;
是否应该省略还有待商榷。有效的 C 程序主签名的范围要大得多。
另外,效率也不是问题 main
功能。根据C++标准,它只能进入和离开一次(标记程序的开始和终止)。对于C,情况不同,重新输入 main()
是允许的,但应该避免。
其他提示
接受的答案似乎是针对 C++ 的,所以我想我应该添加一个与 C 相关的答案,这在几个方面有所不同。
ISO/IEC 9899:1989 (C90):
main()
应声明为:
int main(void)
int main(int argc, char **argv)
或同等学历。例如, int main(int argc, char *argv[])
相当于第二个。此外, int
返回类型可以省略,因为它是默认值。
如果实现允许的话, main()
可以用其他方式声明,但这使得程序实现被定义,并且不再严格遵守。
该标准定义了 3 个严格符合要求的返回值(即不依赖于实现定义的行为): 0
和 EXIT_SUCCESS
成功终止,以及 EXIT_FAILURE
终止失败。任何其他值都是非标准的并由实现定义。 main()
必须有明确的 return
最后声明以避免未定义的行为。
最后,从标准的角度来看,调用没有任何问题 main()
来自一个程序。
ISO/IEC 9899:1999 (C99):
对于 C99,一切与上面相同,除了:
- 这
int
返回类型不能省略。 - 您可以省略 return 语句
main()
. 。如果你这样做,并且main()
完了,还有一个隐含的return 0
.
标准 C — 托管环境
对于托管环境(这是正常的环境),C11 标准 (ISO/IEC 9899:2011) 规定:
5.1.2.2.1 程序启动
程序启动时调用的函数名为
main
. 。该功能没有声明该功能的原型。它的返回类型应定义为int
并且没有参数:int main(void) { /* ... */ }
或带有两个参数(此处称为
argc
和argv
, ,尽管可以使用任何名称,因为它们是声明的函数本地的):int main(int argc, char *argv[]) { /* ... */ }
或同等学历;10) 或者以其他一些实现定义的方式。
如果声明它们,主要函数的参数应遵守以下约束:
- 的价值
argc
应为非负数。argv[argc]
应为空指针。- 如果值
argc
大于零,数组成员argv[0]
通过argv[argc-1]
应包含指向字符串的指针,这些字符串被赋予 在程序启动前,由主机环境定义的执行值。"(《世界人权宣言》) 目的是向程序提供在程序启动前确定的信息 从托管环境的其他地方获取。如果主机环境无法 提供的字符串既有大写字母,也有小写字母。 应确保以小写字母接收字符串。- 如果值
argc
大于零,指向的字符串argv[0]
代表程序名称;argv[0][0]
应为空字符,如果 程序名称无法从主机环境中获取。如果值argc
是 大于 1 时,由argv[1]
通过argv[argc-1]
代表程序参数。- 参数
argc
和argv
和指向的字符串argv
数组应通过程序进行修改,并在程序启动和程序终止之间保留其最后存储的值。10) 因此,
int
可以用 typedef 名称替换,定义为int
, ,或类型argv
可以写成char **argv
, , 等等。
C99 或 C11 中的程序终止
返回值来自 main()
以实现定义的方式传输到“环境”。
5.1.2.2.3 程序终止
1 如果返回类型
main
函数是兼容的类型int
, 从 首次调用main
函数相当于调用exit
函数的值 返回的main
函数作为其参数;11) 达到}
终止main
函数返回值 0。如果返回类型不兼容int
, ,"...... 返回主机环境的终止状态不明。11) 根据6.2.4,具有自动存储期限的对象的生命周期在
main
在前一种情况下将会结束,即使在后一种情况下他们不会这样做。
注意 0
被强制为“成功”。您可以使用 EXIT_FAILURE
和 EXIT_SUCCESS
从 <stdlib.h>
如果您愿意的话,但是 0 已经很成熟了,1 也是如此。也可以看看 退出代码大于 255 — 可能吗?.
在 C89 中(因此在 Microsoft C 中),没有声明如果 main()
函数返回但不指定返回值;因此它会导致未定义的行为。
7.22.4.4 的
exit
功能¶5 最后,控制权返回到主机环境。如果值
status
为零或EXIT_SUCCESS
, ,状态的实现定义形式 成功终止 被返回。如果值status
是EXIT_FAILURE
, ,状态的实现定义形式 终止失败 被返回。否则,返回的状态是实现定义的。
标准 C++ — 托管环境
C++11 标准 (ISO/IEC 14882:2011) 规定:
3.6.1 主要函数【basic.start.main】
¶1 程序应包含一个名为 main 的全局函数,它是程序的指定开始。[...]
¶2 实现不应预定义主函数。该函数不得超载。它应具有INT类型的返回类型,但否则它的类型已定义。所有实现均应允许以下两个主要定义:
int main() { /* ... */ }
和
int main(int argc, char* argv[]) { /* ... */ }
在后一种形式中
argc
应为从环境中传递给程序的参数个数 在其中运行程序。如果argc
非零这些参数应在argv[0]
通过argv[argc-1]
作为指向空终止多字节字符串 (NTMBS) 的初始字符的指针 (17.5.2.1.4.2) 和argv[0]
应是 NTMBS 初始字符的指针,表示 调用程序或""
. 。的价值argc
应为非负数。的价值argv[argc]
应为 0。[ 笔记:建议在之后添加任何其他(可选)参数argv
. 。-结束 注 ]¶3 功能
main
不得在程序中使用。的联动 (3.5)main
是实现定义的。[...]¶5 在 main 中的 return 语句具有离开 main 函数的效果(销毁任何带有自动 存储时间),并调用
std::exit
以返回值作为参数。如果控制到达终点 而没有遇到返回语句,其效果与执行return 0;
C++ 标准明确指出“它 [主函数] 的返回类型应为 int
, ,但否则其类型是实现定义的”,并且需要与 C 标准相同的两个签名作为选项来支持。因此,C++ 标准直接不允许“void main()”,尽管它无法阻止允许替代方案的非标准实现。注意C++禁止用户调用 main
(但 C 标准没有)。
有一段§18.5 开始和终止 在 C++11 标准中,与 §7.22.4.4 中的段落相同 这 exit
功能 在 C11 标准(上面引用)中,除了脚注(它只是简单地记录了 EXIT_SUCCESS
和 EXIT_FAILURE
定义于 <cstdlib>
).
标准 C——通用扩展
通常,Unix 系统支持第三种变体:
int main(int argc, char **argv, char **envp) { ... }
第三个参数是一个以 null 结尾的字符串指针列表,每个字符串都是一个环境变量,有一个名称、一个等号和一个值(可能为空)。如果您不使用它,您仍然可以通过 'extern char **environ;
'。很长一段时间,没有声明它的标头,但是 POSIX 2008 年标准现在要求在 <unistd.h>
.
这被 C 标准认可为通用扩展,记录在附录 J 中:
J.5.1 环境参数
¶1 在托管环境中,主函数接收第三个参数,
char *envp[]
, 的指针的空端数组。char
, ,其中每个都指向一个字符串 提供了本次程序执行的环境信息(5.1.2.2.1)。
微软C
这 微软VS 2010 编译器很有趣。该网站说:
main 的声明语法是
int main();
或者,可选地,
int main(int argc, char *argv[], char *envp[]);
或者,
main
和wmain
函数可以声明为返回void
(无返回值)。如果你声明main
或者wmain
由于返回 void,因此不能使用 return 语句将退出代码返回到父进程或操作系统。返回退出代码main
或者wmain
被声明为void
, ,您必须使用exit
功能。
我不清楚当程序使用 void main()
确实退出了——微软网站也沉默了。
有趣的是,MS 并没有规定两个参数的版本 main()
C 和 C++ 标准要求的。它只规定了三参数形式,其中第三个参数是 char **envp
, ,指向环境变量列表的指针。
微软页面还列出了一些其他替代方案—— wmain()
它需要宽字符串等等。
微软 Visual Studio 2005 的版本 这一页 未列出 void main()
作为备选。这 版本 来自微软 Visual Studio 2008 以后做。
标准 C — 独立式环境
如前所述,上述要求适用于托管环境。如果您正在使用独立环境(这是托管环境的替代方案),那么该标准就没什么可说的了。对于独立环境,程序启动时调用的函数不需要调用 main
并且其返回类型没有限制。标准说:
5.1.2 执行环境
定义了两个执行环境:独立式和托管式。在这两种情况下、 程序启动时,执行程序会调用指定的 C 语言函数。 环境所有具有静态存储持续时间的对象都应在程序启动之前初始化(设置为其初始值)。否则未指定这种初始化的方式和时间。程序终止将控制权返回给执行环境。
5.1.2.1 独立式环境
在独立环境中(其中 C 程序执行可以在没有操作系统的任何好处的情况下进行),程序启动时调用的函数的名称和类型是实现定义的。除了第 4 条要求的最小集之外,任何可用于独立程序的库设施都是实现定义的。
独立环境中程序终止的效果是由实现定义的。
第 4 条一致性的交叉引用是指:
¶5A 严格遵守程序 应仅使用本国际标准中指定的语言和库的功能。3) 它不应产生依赖于任何未指定、未定义或实现定义的行为的输出,并且不应超过任何最低实现限制。
¶6 一致性实现的两种形式是 主持 和 独立式. 。A 符合托管实施 应接受任何严格符合的程序。A 符合要求的独立实施 应接受任何严格符合的程序,其中库条款(第 7 条)中指定的功能的使用仅限于标准头的内容
<float.h>
,<iso646.h>
,<limits.h>
,<stdalign.h>
,<stdarg.h>
,<stdbool.h>
,<stddef.h>
,<stdint.h>
, , 和<stdnoreturn.h>
. 。符合要求的实现可以有扩展(包括 附加库函数),只要它们不改变任何严格符合要求的程序的行为。4)¶7A 符合程序 是符合一致性的实现可以接受的。5)
3) 严格符合的程序可以使用条件功能(参见 6.10.8.3),前提是该使用受到使用相关宏的适当条件包含预处理指令的保护。例如:
#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */ /* ... */ fesetround(FE_UPWARD); /* ... */ #endif
4) 这意味着符合标准的实现不保留除本国际标准中明确保留的标识符之外的标识符。
5) 严格一致的程序旨在在一致的实现之间最大程度地移植。一致性程序可能依赖于一致性实现的不可移植特征。
值得注意的是,实际定义任何函数的独立环境所需的唯一标头是 <stdarg.h>
(甚至那些可能——而且经常是——只是宏)。
标准 C++ — 独立环境
正如 C 标准识别托管环境和独立环境一样,C++ 标准也是如此。(引自 ISO/IEC 14882:2011。)
1.4 实施合规性[intro.compliance]
¶7 定义了两种实现:A 托管实施 和一个 独立实施. 。对于托管实施,该国际标准定义了一组可用的库。独立式 是一种可以在没有操作系统的情况下执行的实现,它有一套由实现定义的库,其中包括某些语言支持库(17.6.1.3)。
¶8 一致的实现可以具有扩展(包括附加库函数),只要它们不改变任何格式良好的程序的行为。执行程序需要诊断以下程序 使用根据本国际标准不符合格式的扩展名。然而,这样做之后,他们可以编译并执行此类程序。
¶9 每个实现都应包含文档,用于标识其不支持的所有有条件支持的构造,并定义所有特定于语言环境的特征。3
3) 本文档还定义了实现定义的行为;见1.9。
17.6.1.3 独立实现[合规性]
定义了两种实现:托管和独立(1.4)。对于托管实现,本国际标准描述了可用标头集。
独立实现具有一组实现定义的标头。该集应至少包括表 16 中所示的标头。
提供的标头版本
<cstdlib>
应至少声明函数abort
,atexit
,at_quick_exit
,exit
, , 和quick_exit
(18.5)。此表中列出的其他标头应满足与托管实现相同的要求。表 16 — 独立实现的 C++ 头文件
Subclause Header(s) <ciso646> 18.2 Types <cstddef> 18.3 Implementation properties <cfloat> <limits> <climits> 18.4 Integer types <cstdint> 18.5 Start and termination <cstdlib> 18.6 Dynamic memory management <new> 18.7 Type identification <typeinfo> 18.8 Exception handling <exception> 18.9 Initializer lists <initializer_list> 18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool> 20.9 Type traits <type_traits> 29 Atomics <atomic>
使用怎么样 int main()
在C语言中?
C11 标准的标准 §5.1.2.2.1 显示了首选符号 —int main(void)
- 但标准中还有两个例子表明 int main()
: §6.5.3.4 ¶8 和 §6.7.6.3 ¶20. 。现在,重要的是要注意,示例不是“规范的”;而是示例。它们只是说明性的。如果示例中存在错误,它们不会直接影响标准的正文。也就是说,它们强烈地表明了预期的行为,因此如果标准包括 int main()
在一个例子中,它表明 int main()
不被禁止,即使它不是首选符号。
6.5.3.4
sizeof
和_Alignof
运营商…
¶8 示例 3 在此示例中,计算可变长度数组的大小并从函数返回:
#include <stddef.h> size_t fsize3(int n) { char b[n+3]; // variable length array return sizeof b; // execution time sizeof } int main() { size_t size; size = fsize3(10); // fsize3 returns 13 return 0; }
我相信 main()
应该返回 EXIT_SUCCESS
或者 EXIT_FAILURE
. 。它们定义在 stdlib.h
请注意,C 和 C++ 标准定义了两种实现:独立式和托管式。
C90 托管环境
允许的形式 1:
int main (void) int main (int argc, char *argv[]) main (void) main (int argc, char *argv[]) /*... etc, similar forms with implicit int */
评论:
前两者被显式指定为允许的形式,其他形式则隐式允许,因为 C90 允许返回类型和函数参数使用“隐式 int”。不允许有其他形式。
C90独立式环境
main 的任何形式或名称都是允许的 2.
C99 托管环境
允许的形式 3:
int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */
评论:
C99 删除了“隐式 int”所以
main()
不再有效。引入了一个奇怪的、模棱两可的句子“或以其他实现定义的方式”。这可以解释为“参数
int main()
可能会有所不同”或“main 可以具有任何实现定义的形式”。一些编译器选择以后一种方式解释标准。可以说,人们不能轻易地通过引用该标准本身来声明他们没有严格遵守,因为它是含糊不清的。
然而,为了允许完全野生的形式
main()
可能(?)不是这个新句子的意图。C99 基本原理(非规范性)意味着该句子引用了附加参数int main
4.然而,托管环境程序终止部分继续争论 main 不返回 int 的情况 5. 。尽管该部分并未规范如何声明 main,但它绝对意味着即使在托管系统上,也可以以完全实现定义的方式声明 main。
C99独立式环境
main 的任何形式或名称都是允许的 6.
C11托管环境
允许的形式 7:
int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */
C11 独立式环境
main 的任何形式或名称都是允许的 8.
注意 int main()
从未被列为上述任何版本中 C 的任何托管实现的有效形式。在 C 中,与 C++ 不同的是, ()
和 (void)
有不同的含义。前者是一个过时的功能,可能会从语言中删除。请参阅 C11 未来语言方向:
6.11.6 函数声明符
使用带有空括号的函数声明符(不是原型格式参数类型声明符)是一个过时的功能。
C++03 托管环境
允许的形式 9:
int main () int main (int argc, char *argv[])
评论:
请注意第一种形式中的空括号。在这种情况下,C++ 和 C 是不同的,因为在 C++ 中,这意味着该函数不带参数。但在 C 中这意味着它可以接受任何参数。
C++03独立环境
启动时调用的函数的名称是实现定义的。如果被命名为
main()
它必须遵循规定的形式 10:// implementation-defined name, or int main () int main (int argc, char *argv[])
C++11 托管环境
允许的形式 11:
int main () int main (int argc, char *argv[])
评论:
标准的文本已更改,但含义相同。
C++11 独立环境
启动时调用的函数的名称是实现定义的。如果被命名为
main()
它必须遵循规定的形式 12:// implementation-defined name, or int main () int main (int argc, char *argv[])
参考
ANSI X3.159-1989 2.1.2.2 托管环境。“程序启动”
程序启动时调用的函数名为 main。"(《世界人权宣言》) 实现没有为该函数声明原型。它应 定义的返回类型为 int,不带参数:
int main(void) { /* ... */ }
或两个参数(此处称为 argc 和 argv,但可以使用任何名称,因为它们是本地的 的函数):
int main(int argc, char *argv[]) { /* ... */ }
ANSI X3.159-1989 2.1.2.1 独立式环境:
在独立环境中(C 程序的执行可能需要 没有操作系统的地方),名称和类型 的函数是由执行定义的。
ISO 9899:1999 5.1.2.2 托管环境 -> 5.1.2.2.1 程序启动
程序启动时调用的函数名为 main。"(《世界人权宣言》) 实现没有为该函数声明原型。它应 定义的返回类型为 int,不带参数:
int main(void) { /* ... */ }
或两个参数(此处称为 argc 和 argv,但可以使用任何名称,因为它们是本地的 的函数):
int main(int argc, char *argv[]) { /* ... */ }
或等价物;9) 或在其他由实施定义的 方式。
国际标准的基本原理 — 编程语言 — C,修订版 5.10。5.1.2.2 托管环境 --> 5.1.2.2.1 程序启动
main 的参数行为,以及 exit、main 和 atexit 的交互行为 (见第 7.20.4.2 节)已被编入法典,以遏制 argv 表示法中一些不必要的变化。 字符串,以及 main 返回值的含义。
argc 和 argv 作为 main 参数的规范认可了广泛的先前实践。argv[argc] 需要是空指针,以便为列表末尾提供冗余检查,这也是基于常见实践。
main 是唯一可以使用零个或两个参数进行可移植声明的函数。(在调用和定义之间,其他函数的参数数必须完全一致)。 这种特例只是承认了当程序不访问程序参数字符串时省略 main 参数的普遍做法。虽然许多实现支持两个以上的 main 参数,但这种做法既没有受到标准的祝福,也没有受到标准的禁止。使用三个参数定义 main 的程序并不严格遵循(参见§J.5.1.)。
ISO 9899:1999 5.1.2.2 托管环境 --> 5.1.2.2.3 程序终止
如果 main 函数的返回类型是与 int 兼容的类型,则从初次调用 main 函数返回相当于以 main 函数的返回值作为参数调用 exit 函数;11) 到达
}
终止 main 函数返回值 0。如果返回类型与 int 不兼容,则返回到主机环境的终止状态是未指定的。ISO 9899:1999 5.1.2.1 独立式环境
在独立环境中(其中 C 程序执行可以在没有操作系统的任何好处的情况下进行),程序启动时调用的函数的名称和类型是实现定义的。
ISO 9899:2011 5.1.2.2 托管环境 -> 5.1.2.2.1 程序启动
此部分与上面引用的 C99 部分相同。
ISO 9899:1999 5.1.2.1 独立式环境
此部分与上面引用的 C99 部分相同。
ISO 14882:2003 3.6.1 主要功能
实现不应预定义主函数。该函数不得超载。它应具有 int 类型的返回类型,但除此之外,其类型是实现定义的。所有实现都应允许以下两个 main 定义:
int main() { /* ... */ }
和
int main(int argc, char* argv[]) { /* ... */ }
ISO 14882:2003 3.6.1 主要功能
独立环境中的程序是否需要定义主函数是由实现定义的。
ISO 14882:2011 3.6.1 主要功能
实现不应预定义主函数。该函数不得超载。它应具有 int 类型的返回类型,但除此之外,其类型是实现定义的。所有实施均应 兼顾
— () 返回 int 的函数和
— (int, 指向 char 的指针) 返回 int 的函数
作为 main 的类型(8.3.5)。
ISO 14882:2011 3.6.1 主要功能
此部分与上面引用的 C++03 部分相同。
成功时返回 0,错误时返回非零。这是 UNIX 和 DOS 脚本用来查明程序发生了什么情况的标准。
main()
在 C89 和 K&R C 中,未指定的返回类型默认为“int”。
return 1? return 0?
如果你没有写return语句
int main()
, 闭幕式{
默认返回0。return 0
或者return 1
将被父进程接收。在 shell 中,它进入 shell 变量,如果您从 shell 运行程序并且不使用该变量,那么您不必担心返回值main()
.
$ ./a.out
$ echo $?
这样你就可以看到它是变量 $?
它接收返回值的最低有效字节 main()
.
在 Unix 和 DOS 脚本中, return 0
成功时通常返回,错误时通常返回非零值。这是 Unix 和 DOS 脚本使用的标准,用于查明程序发生了什么并控制整个流程。
请记住,即使您返回 int,某些操作系统 (Windows) 也会将返回值截断为单个字节 (0-255)。
操作系统可以使用返回值来检查程序是如何关闭的。
在大多数操作系统中,返回值 0 通常表示 OK(我能想到的操作系统)。
当您自己调用进程时也可以检查它,看看程序是否正确退出并完成。
它是 不是 只是一个编程约定。
返回值 main()
显示程序如何退出。如果返回值为 zero
这意味着执行成功,而任何非零值都表示执行过程中出现问题。
我的印象是,标准指定 main 不需要返回值,因为成功的返回是基于操作系统的(一个中的零可能是另一个中的成功或失败),因此没有返回是一个提示编译器插入成功返回本身。
不过我通常返回0。
返回 0 应该告诉程序员程序已成功完成工作。
忽略 return 0
当 C 或 C++ 程序到达末尾时 main
编译器会自动生成返回0的代码,所以不需要写 return 0;
明确地在末尾 main
.
笔记: 当我提出这个建议时,几乎总是会跟着以下两种评论之一:"我不知道" 或 "这是个坏建议!" 我的理由是,依靠标准明确支持的编译器行为是安全和有用的。对于C,从C99开始;参见 ISO/IEC 9899:1999 第 5.1.2.2.3 节:
[...]从初始调用返回
main
函数相当于调用exit
函数的返回值是main
函数作为其参数;达到}
终止main
函数返回值 0。
对于C++,自1998年第一个标准以来;参见 ISO/IEC 14882:1998 第 3.6.1 节:
如果控制到达 main 末尾而没有遇到 return 语句,则效果是执行 return 0;
此后这两个标准的所有版本(C99 和 C++98)都保持了相同的想法。我们依赖于C++中自动生成的成员函数,很少有人显式地编写 return;
a 末尾的语句 void
功能。反对省略的原因似乎可以归结为 “看起来很奇怪”. 。如果您像我一样对更改 C 标准的理由感到好奇 阅读这个问题. 。另请注意,在 20 世纪 90 年代初期,这被认为是“草率的做法”,因为它在当时是未定义的行为(尽管得到了广泛支持)。
此外, C++ 核心指南 包含多个省略实例 return 0;
在......的最后 main
并且没有写入显式返回的实例。尽管该文件中尚未就这一特定主题提供具体指南,但这似乎至少是对该做法的默认认可。
所以我主张省略它;其他人不同意(通常是强烈反对!)无论如何,如果您遇到省略它的代码,您就会知道它受到标准的明确支持,并且您会知道它的含义。
返回什么取决于您想要对可执行文件执行的操作。例如,如果您通过命令行 shell 使用程序,则需要返回 0 表示成功,返回非零表示失败。然后,您将能够在 shell 中使用该程序,并根据代码的结果进行条件处理。此外,您还可以根据您的解释分配任何非零值,例如,对于严重错误,不同的程序退出点可以终止具有不同退出值的程序,并且调用 shell 可以使用该值,调用 shell 可以通过检查返回的值来决定要执行的操作。如果代码不适合与 shell 一起使用,并且返回值不会打扰任何人,那么它可能会被省略。我个人使用签名 int main (void) { .. return 0; .. }
如果您确实遇到与从进程返回整数的效率相关的问题,您可能应该避免多次调用该进程,以免此返回值成为问题。
如果你这样做(多次调用一个进程),你应该找到一种方法将你的逻辑直接放在调用者内部,或者放在一个 DLL 文件中,而不是为每次调用分配一个特定的进程;在这种情况下,多进程分配会给您带来相关的效率问题。
详细来说,如果您只想知道返回 0 是否比返回 1 效率更高或更低,在某些情况下它可能取决于编译器,但一般来说,假设它们是从同一源读取的(本地、字段、常量、嵌入式)在代码、函数结果等中)它需要完全相同数量的时钟周期。
在 C 和 C++ 中定义 main() 函数的正确(最有效)方法是什么 - int main() 或 void main() - 为什么?
“(最有效)”这几个词不会改变问题。除非您处于独立环境中,否则有一种普遍正确的方法来声明 main()
, ,这就是返回 int。
什么应该
main()
在 C 和 C++ 中返回?
这不是什么 应该 main()
返回,就是这样 做 main()
返回。 main()
当然,是其他人调用的函数。您无法控制调用的代码 main()
. 。因此,您必须声明 main()
使用类型正确的签名来匹配其调用者。你在这件事上根本没有任何选择。您不必问自己什么效率更高或更低,或者什么风格更好或更差,或者诸如此类的问题,因为答案已经由 C 和 C+ 标准为您完美定义。跟着他们就行了。
如果 int main() 那么返回 1 还是返回 0?
0 表示成功,非零表示失败。再说一遍,这不是你需要(或必须)选择的东西:它是由您应该遵守的接口定义的。
这是返回码用法的一个小演示......
使用 Linux 终端提供的各种工具时,可以使用返回代码,例如在进程完成后进行错误处理。假设存在以下文本文件 myfile:
这是一些用于检查 grep 工作原理的示例。
当您执行 grep 命令时,就会创建一个进程。一旦完成(并且没有中断),它会返回 0 到 255 之间的一些代码。例如:
$ grep order myfile
如果你这样做
$ echo $?
$ 0
你会得到 0。为什么?因为 grep 找到匹配项并返回退出代码 0,这是成功退出的常用值。让我们再次检查一下,但其中的内容不在我们的文本文件中,因此不会找到匹配项:
$ grep foo myfile
$ echo $?
$ 1
由于 grep 无法将标记“foo”与文件内容相匹配,因此返回码为 1(这是发生故障时的常见情况,但如上所述,您有很多值可供选择)。
现在,下面的 bash 脚本(只需在 Linux 终端中键入它)虽然非常基本,但应该给出一些错误处理的想法:
$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found
在第二行之后,终端上没有任何内容打印,因为“foo”使 grep 返回 1,我们检查 grep 的返回码是否等于 0。第二个条件语句在最后一行中回显其消息,因为由于 CHECK == 1 而它为 true。
正如您所看到的,如果您正在调用这个和那个进程,有时有必要查看它返回的内容(通过 main() 的返回值)。