这些C的主要功能是什么?

5

可能重复:
为什么C和C++中的主函数类型由用户定义?

我遇到了许多C语言main函数的风格和写法,但我实际上并不明白这些语法的含义,有人可以简要解释一下每个语法吗? 为什么是void?为什么是int?为什么会有void、int作为参数?

void main() {

}

int main() {

}

int main(void) {

}

void main(void) {

}

int main(int) {

}

int main(int argc, char* argv[]) {

}

2
void main()void main(void) 都是无效的。main 函数必须返回一个 int 类型的值。 - Cody Gray
@CodyGray:...除了在“独立环境”中(5.1.2.1)。 - undur_gongor
@undur_gongor:事实上,一个自由环境甚至可能没有 main() - Alok Save
完整的答案可以在这里找到。那个答案的第一行也适用于在此发布的答案... - Lundin
2个回答

8
有两种符合C标准的实现方式:
  • 托管实现
  • 独立实现
这两种实现是基于C标准定义的两种环境:
  • 托管环境
  • 独立环境
什么是“独立环境”和“托管环境”?
独立实现是为在没有操作系统帮助下执行的程序而设计的。
例如:操作系统内核或嵌入式环境都属于独立环境。
使用操作系统功能的程序通常属于托管实现。
在这两个环境中,C程序如何启动执行有所不同。
对于独立环境,程序启动可以通过任何实现定义的函数进行。甚至没有要求存在main()函数。
因此,上述问题中提到的任何函数定义都可能是有效的,具体取决于该独立环境的实现。它们的函数参数和返回值将具有实现定义的含义,因此您需要查看其文档以了解其精确含义。
参考资料:
5.1.2.1 独立环境
在独立环境中(C程序可以在没有操作系统的任何帮助下执行),在程序启动时调用的函数的名称和类型是实现定义的。除了第4条款规定的最小集之外,任何可用于独立程序的库设施都是实现定义的。
对于托管环境,标准规定程序执行始于执行main()函数,并且还规定了如何定义此函数。
有关此内容的规范在以下位置给出:

C99 Standard: 5.1.2.2 Hosted environment

5.1.2.2.1 Program startup

1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

   int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

   int main(int argc, char *argv[]) { /* ... */ }

or equivalent; or in some other implementation-defined manner.


-1 因为这个答案只适用于托管环境。5.1.2.2.1 是“托管环境”(5.1.2.2)章节的一部分。 - Lundin
2
@Lundin:嗯,早在你发表这个评论之前,我已经在问题下面对独立环境发表了评论。至于答案,它没有说错什么。 - Alok Save
答案严格正确,但是具有误导性和不完整性。有很多程序员错误地认为在C语言中void main()是不允许的,这会给他们带来更多的困扰。 - Lundin
@Lundin:到这儿了。更新了答案并详细说明,因为我认为有很多程序员错误地认为void main()从来不被允许。 - Alok Save
从downvote到upvote没问题。(另外,C和C++标准在这个特定问题上是等价的。) - Lundin

2

void作为返回类型意味着作者的意图是不向程序的调用者返回任何重要的值。根据操作系统的不同,这可能是可接受的,或者可能会导致与启动程序相关的微妙问题。

void作为参数意味着程序将不使用传统的方式检查命令行参数。一些环境提供了获取它们的替代方法;而其他环境则没有。在后一种情况下,这意味着程序忽略任何命令行参数。

main (int)允许程序检查传递给程序的命令行参数数量,但不检查它们的值。这样的安排很少见,但一个在许多实现上执行此操作的程序是Unix/Linux的who命令,它列出已登录的用户,除了who am i只列出当前用户。正如who is you一样(因为两者都有两个参数:

[wally@lenovotower ~]$ who
wally    tty1         2012-01-31 22:24 (:0)
wally    pts/0        2012-01-31 22:24 (:0)
wally    pts/1        2012-01-31 22:33 (:0)
wally    pts/2        2012-01-31 22:34 (msi)
root     pts/3        2012-01-31 22:34 (msi)
[wally@lenovotower ~]$ who am i
wally    pts/0        2012-01-31 22:24 (:0)
[wally@lenovotower ~]$ who are you
wally    pts/0        2012-01-31 22:24 (:0)
[wally@lenovotower ~]$ 

根据操作系统的不同,这可能是可以接受的。但如果您在托管环境中运行操作系统,则必须返回int类型的主函数。参考C99 5.1.2.2.1章节。 - Lundin
@Lundin:并非如此。许多操作系统具有不同的机制来返回程序状态值:pSoS、iRMX86、RT-11、GCOS、许多嵌入式操作系统等。即使是相当符合标准的操作系统OpenVMS,如果main函数的返回值为零,也会进行“翻译”。 - wallyk
没关系。C标准明确告诉我们,在托管环境中,主函数必须返回int。没有其他选择,如果不返回int,你的程序就不符合C标准。特定操作系统的C编译器可能需要将该int转化为无形之物,但这是编译器而不是程序员的问题。 - Lundin
1
@Lundin:OP的问题不是关于标准C,而是关于为实际系统编写的实际程序的现实情况。C标准不是强制性的实现,只针对符合标准的实现 - wallyk
我能说什么呢...只有一种C语言,就是由ISO 9899定义的那个。如果有人将他们的问题标记为C语言,并且我给他们一个用C++、Object C或者MyOwnMumboJumboC编写的答案,那么我认为我的答案是不相关的。关于符合标准的实现所允许的例外也被标准规定在第4章中。 - Lundin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接