为什么函数main()的名称叫做main?

7

为什么许多语言(如C、C++和Java)都保留了函数名main()?为什么不使用其他名称来命名该函数?这三个main()函数是否有共同的结构(在C、C++和Java中)?


10
如果你不喜欢它,可以随意开发一种语言,其语法与原语言相同,除了主函数以外。 :-) - Brian Knoblauch
12
在C/C++中,你可以简单地使用#define theNameOfTheThing main来设置并使用。 - R. Martinho Fernandes
+1,因为这个真正的问题仍然得到了许多有趣的回答 :) - MAK
我很惊讶这个问题到现在还没有被关闭。 - Kelly S. French
16个回答

33

这里有很多愚蠢且不太尊重的答案,而原本是一个合理的问题。

C并非从无处而来。它的直接祖先是由Ken Thompson编写的B语言。这是B手册的链接。B程序的基本结构是:

main(); exit();

程序员提供了main(),库提供了exit()。这似乎是main()首次作为B、BCPL的前身没有此概念的出现。我猜你需要问Ken Thompson为什么选择了main()而不是其他名称。

4
有趣的是它不是enter(),作为exit()的反义词。 - caf
2
也许这是编写 PDP-8 汇编语言时使用的约定。请参阅 http://en.wikipedia.org/wiki/PDP-8,其中使用 MAIN 作为入口点的 Hello World 程序。 - Tim Allman
如果我没记错的话,为什么一个应用于PDP-8的规定会适用于一种最初在PDP-11上实现的语言呢? - JUST MY correct OPINION

26
请注意,尽管名称main是某种约定,但您可以为入口函数命名任何您想要的内容,只要告诉链接器实际的入口点是什么。请查看来自man ld的此代码片段:
       -e entry
       --entry=entry
       将entry用作程序开始执行的显式符号,而不是默认的入口点。如果没有名为entry的符号,
       链接器将尝试将entry解析为一个数字,并使用其作为入口地址(该数字将以基数10解释;
       您可以在基数16的情况下使用前导0x,或在基数8的情况下使用前导0)。

另外,ld入口点的首选项(有时)也是一个名为_start的函数(但我认为这实际上是一个因平台而异的值)。

请参见此邮件帖子,它对ld-e选项进行了更详细的说明:

-e指定了_start的替代项,而不是main()。您必须知道系统运行时如何将参数传递给程序并复制一些功能, 以调用主函数,包括crt[01in].o和crt{begin,end}.o的某些功能。


我找不到在gcc手册页中记录的位置,但您也可以向gcc传递-e以指定入口点;然而,在绕过C的main魔法时,这最终是一个相当复杂的任务。

$ cat junk.c
```html junk() { 8; } $ gcc -nostdlib -e _junk junk.c -o junk && (./junk; $?) 8 ```
这段代码定义了一个名为 `junk` 的函数,它返回整数值 `8`。接下来通过 `gcc` 命令编译程序,并使用参数 `-nostdlib` 去除标准库的链接以及参数 `-e _junk` 指定入口点为 `_junk`,将编译后的可执行文件命名为 `junk`。最后使用括号将执行可执行文件命令和输出退出码的命令组合在一起,可以看到程序运行并输出了 `8`。

很棒的答案,它也增加了我的知識! - Xolve
2
当C语言被创造时,gcc并不存在。 - Tim Allman
在程序开发中,最好坚持使用名为“main”的程序入口点,因为这是惯例。其他任何名称都会让下一个人困惑于它的起始位置。 - hookenz
1
@Matt H:我不明白。我以为“把下一个人搞糊涂”才是目标。至少,这似乎是我要处理的大部分代码的意图。 - Jay

10

因为C语言这么做了,所以C++保留了它以保持兼容性,而Java则是为了简化从C++转换过来的操作。在Java的早期,雇主通常会聘请有C++经验的人,因为两者非常相似。与今天不同,现在他们希望新员工拥有比高斯林更多的Java经验。

不要忘记PL/1也使用“procedure options main”来实现同样的目的。(哇,这让我想起了很久以前没有碰过的记忆!)


1
这会引发一个新的问题:为什么C使用“main”作为名称呢?=) - BalusC
2
我怀疑这可以简化为“他们必须使用某些东西”和“主要听起来不错”。 - Michael Kohne
2
@BalusC:除了“这就是B中的情况”之外,回答这个问题会很困难。对于那些本身并不重要的任意决定的“为什么”问题(例如,在美国,我们开车靠右并不重要,只要我们都在同一侧行驶),很少有成果。 - David Thornley
1
@David:有一些证据表明,你行驶的道路一侧确实会对安全产生轻微影响。这是因为驾驶者的主导眼睛所致。http://en.wikipedia.org/wiki/Right-_and_left-hand_traffic#Safety_factors - rmeador

8
为什么我们在道路的某一侧行驶?
答案:我们必须选择一边。

2
其实我认为这与拔剑和大多数人惯用右手有关... 以前每个人都习惯于左侧行走/骑行,但后来拿破仑改变了这种习惯,使得在街上战斗更加困难。至少这是我听到的故事... 我相信Snopes网站会有自己的看法。 - Brian Postow
1
@Brian:1967年瑞典从左侧行驶改为右侧行驶时,最流行的理由是这样做可以更安全地让乘客从路缘侧下车(即使我们在左侧行驶,除了公共汽车外,大多数车辆(方向盘在左侧)都是如此)。 - Fredrik

6

并不总是main()。

Java Applets使用init()和start()作为外部调用者的钩子。

Servlet通过init()和service()方法启动。

(service将分派到更熟悉的doGet和doPost方法)

当然,这些异常确实依赖于某些容器而不是操作系统来调用这些方法。


3

因为这是主函数。术语“主函数”至少自20世纪60年代以来一直被使用。在PL/I中,启动执行的函数具有以下标题:

 FOO: PROCEDURE OPTIONS(MAIN);

这里的 FOO 是函数名称。


3
但是,如果我们将主函数重新命名为FOO,那么我们应该如何称呼那些不会执行任何有用功能的临时小函数呢? - Brian Postow

3

快速回答:

  1. 为什么不这样做?
  2. 为什么要改变它?改成什么?
  3. 因为这是C、C++和Java共同祖先的症状之一(具体而言,C对其他两种语言的影响很大)。例如,在Scheme或Prolog中,你看不到main()。

就个人而言,我认为问题2a和2b的答案最重要。如果你真的想打破世界上每一个C/C++/Java程序,只为了修复你认为有缺陷的单个函数名称的美学,那我必须问你是否有正确的优先级.... ;-)


有许多好的答案可以回答“做什么?”这个问题,有些更好,有些更差:program()start()run()... - R. Martinho Fernandes
@Martinho,不,那些不是更好的选择。“program”意味着源代码的集合。“start”和“run”是Thread使用的关键字。无论如何,你能想到一个新词并不能回答之前的问题:“为什么要改变它?”答案还必须平衡考虑这样一个事实,即即使你可以在Java(例如)中更改“main”,你将破坏世界上每个Java程序。单个名称的美学真的值得吗? - Bob Cross
@Bob,你现在是事后诸葛亮。我们讨论的是“为什么main()要以这种方式命名?”,这个问题至少可以追溯到40年前,当时还没有Java和Thread。 - Adriano Varoli Piazza

2
语言设计者必须选择一个名称,而main()听起来像是主函数,因为那里是程序执行的起点 :)

2

可能是因为这是必须要运行的主要函数。C++从C继承了这个名称,Java从C++继承了它(程序员不喜欢变化)。


2

你必须给它命名。我想不到更好的名称,因为那是主程序流程开始的地方。

除了可能具有接受参数的能力外,没有共同的结构。也不应该有共同的结构,因为程序的整个目的是做任何程序员想做的事情。


实际上,可以想到一个更好(高度主观!)的名称:“主程序流开始的地方”-> program()start() - R. Martinho Fernandes
1
这实际上不仅是程序的起点,而是整个程序的主体。你可以在 main() 之外添加函数,但程序的主要流程(至少在 C 和 C++ 中)都在其中。 - Adriano Varoli Piazza

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