【发布时间】:2011-07-14 20:20:39
【问题描述】:
为什么main() 是用户定义的函数?
我什么时候使用void main() 和int main()?
【问题讨论】:
-
every 非库函数的类型留给用户定义。
main的不同之处在于选择范围更窄。
为什么main() 是用户定义的函数?
我什么时候使用void main() 和int main()?
【问题讨论】:
main 的不同之处在于选择范围更窄。
编辑这个答案并不完整,因为它并没有真正解决奇怪的句子“或以某种实现定义的方式”。我现在写了一个more complete answer,它还涉及 C90、C11 和 C++。 编辑结束
以下是 C 标准 (ISO C 9899:1999):
5.1.2.1 独立环境
在独立的环境中(在 哪个C 程序执行可能发生 没有任何操作的好处 系统),名称和类型 程序启动时调用的函数是 实现定义。 / .. / 效果 在一个程序终止 独立的环境是 实现定义。
5.1.2.2 托管环境
无需提供托管环境,但 应符合以下 规格(如果有)。
5.1.2.2.1 程序启动
程序启动时调用的函数名为 主要的。实现声明没有 这个函数的原型。它应 用 int 的返回类型定义 并且没有参数:
int main(void) { /* ... */ }
或带两个参数(指 这里是 argc 和 argv,尽管有 可以使用名称,因为它们是本地的 到它们所在的功能 声明):
int main(int argc, char* argv[]) { /* ... */ }
C++ 标准中的文本或多或少是相同的。 请注意,文本中的“程序启动”是托管环境的子条款。
这意味着:
如果您的程序在无主机环境中运行(您的程序是嵌入式系统或操作系统),它可能有任何返回类型。 void main() 是最常见的。
如果您的程序在托管环境中运行(在操作系统之上),main() 必须返回 int,并且可能有其他参数。
【讨论】:
main 的返回类型是实现定义:这并不意味着由程序员来决定,而是由强加该平台。编译器手册应指定这一点。在托管环境中,选择实际上是在两个给定的参数替代方案之间。如果有参数,这些参数必须正好是两个并且具有给定的类型。顺便说一句,在我看来你错过了* 的argv。
main 的返回类型不同于int。 5.1.2.1 的措辞模棱两可,但 5.1.2.2.3 开头是“如果 main 函数的返回类型是与 int ... 兼容的类型”
void main(void)。 (并且您描述的行为不会使 Turbo C 不合格;如果实现没有记录它具有未定义的行为,则定义 void main(),但它不需要诊断。)
Lundin 关于 C 的说法是正确的,但在 C++ 中,措辞足够不同,足以产生影响:
[C++11: 3.6.1/1]:程序应包含一个名为main的全局函数,它是程序的指定开始。 独立环境中的程序是否需要定义main函数由实现定义。
[C++11: 3.6.1/2]:实现不应预定义main函数。此功能不得重载。 它的返回类型应该是int,否则它的类型是实现定义的[..]
第一个加粗的段落不会覆盖或取消第二个。
main 在 C++ 中总是返回 int。
【讨论】:
void...除非你不能。
Note: In a freestanding environment, start-up and termination is implementation-defined”。我不知道为什么在 C++11 中更改了措辞,但这只能合理地解释为“独立实现可以完全按照他们的意愿声明 main”。对于没有任何操作系统的程序或操作系统本身来说,返回一个 int 是没有意义的。他们会将 int 归还给谁?
main 以外的函数的情况下,或者以其他方式发生),但是当存在一个全局main函数时,它的返回类型是int。总是。从明确的措辞中可以看出这一点。
void main()。你不想回到你的入口点。如果 main 的类型是 int,那么调用约定可能不得不强制将一个无用的垃圾 int 永远保留在堆栈上,这将是愚蠢的。
main,它是全局的,那么它必须有返回类型int。他们可以随意称呼它为void。
main 的返回类型由实现决定,而不是程序员。检查您的编译器文档以查看 main 的合法签名是什么。不要以为void main() 就是其中之一。在托管环境中,main 通常返回 int。在独立环境中,入口点甚至可能不命名为main,但其返回类型仍将由实现决定,而不是由程序员决定。
【讨论】:
有3种情况:
在 1. 中根本不需要名为 main 的函数。实现定义了程序如何启动。
在 2. 中,程序开始执行名为 main 的函数,该函数使用以下 2 个“签名”之一定义:int main(void) 或 int main(int argc, char **argv)
在 3. 中,程序开始在名为 main 的函数处执行,该函数定义为实现所允许的。此函数必须返回 int 以符合标准。例如:int main(int argc, char **argv, char **envp) 或 int main(wchar_t**)。请注意,使用这些形式的程序不一定在所有托管实现中都有效(如果实现发生变化,可能对原作者无效)。
【讨论】:
void main(void) 仍然无效。该标准允许托管实现接受main 的实现定义参数,但不接受不同的返回类型。
main 才能返回int; C 允许实现定义的表单返回其他类型。
({...}) 似乎与语言的任何要求没有冲突,但我会犹豫将使用它们的程序称为“有效 C”,即使它是用于通常使用 gcc 的平台。跨度>
最初,在 C 语言中,没有 void 这样的类型,因此函数必须返回 int。
实际上,返回int 允许您从您的进程中运行另一个进程(使用fork 和exec),如果您可以从该进程中获得返回结果,您将知道它是否有效。
【讨论】:
许多编译器不支持 void main(),因此您应该始终使用 int main()。
【讨论】: