为什么函数名称 main() 在 C、C++、Java 等许多语言中都保留?为什么该功能没有其他名称?所有这 3 个 main() 是否有任何共同的结构(在 C、C++、Java 中)
18 回答
另请注意,虽然名称main
是一种约定,但您可以随意命名您的入口函数,只要您告诉链接器入口点实际上是什么。请参阅以下片段man ld
:
-e 条目 --entry=条目 使用 entry 作为开始执行你的显式符号 程序,而不是默认入口点。如果没有符号 bol 命名条目,链接器将尝试将条目解析为数字, 并将其用作入口地址(该数字将被解释为 以 10 为基数;您可以使用前导 0x 作为基数 16,或前导 0 以 8 为基数)。
此外,FWIW,ld
的首选入口点是(有时)一个实际调用的函数_start
(但我认为它实际上是一个依赖于平台的值)。
并查看这个邮件帖子ld
,它为's-e
选项添加了更多解释:
-e
代替_start
, notmain()
. 您必须知道系统运行时如何将参数传递给程序并复制 crt[01in].o 和 crt{begin,end}.o 的一些功能来调用 main。
我在 gcc 手册页中找不到它的记录位置,但您也可以传递-e
给 gcc 以指定入口点;但是,当您围绕 C 的魔力工作时,它最终会成为一项相当复杂的任务main
。
$猫垃圾.c 诠释垃圾() { 返回 8; } $ gcc -nostdlib -e _junk junk.c -o junk && (./junk; echo $?) 8
因为 C 做到了,C++ 保留了它以保持兼容,而 Java 这样做是为了简化从 C++ 的过渡。早在 Java 的早期,雇主经常雇佣有 C++ 经验的人,因为它是如此相似。不像今天,他们希望新人拥有比 Gosling 更多的 Java 经验。
并且不要忘记 PL/1 出于相同目的使用了“程序选项 main”。(伙计,那是在刷新一些好久没碰过的记忆细胞!)
您如何命名程序的主要功能?
或者,更迟钝的,我们为什么要在路边开车?
答:我们必须选择一些东西。
它并不总是 main()。
Java Applet 使用 init() 和 start() 来连接外部调用者。
Servlet 通过 init() 和 service() 方法启动。
(服务将调度到更熟悉的 doGet 和 doPost 方法)
当然,这些异常确实依赖于操作系统以外的某个容器来调用这些方法。
更有趣的问题是......
你离一些几乎很有趣的问题太近了……
- 是
main
语言还是图书馆的一部分? - 我的程序如何开始?
- 之前有什么运行
main()
吗? - 第一种使用的语言是
main()
什么? - 我可以编写一个不使用库的程序吗?它需要一个
main()
吗? - 当我从 main() 返回时会发生什么?
- 为了给女孩留下好印象,我怎么能把名字从更酷的名字改成
main()
更酷的名字呢?
因为它是主要功能。至少从 1960 年代开始使用术语主函数。在 PL/I 中,开始执行的函数具有以下标头:
FOO: PROCEDURE OPTIONS(MAIN);
FOO
函数名在哪里。
快速回答:
- 为什么不?
- 为什么要改变它?到什么?
- 因为这是 C、C++ 和 Java 都具有共同祖先的症状之一(具体来说,C 对其他两个产生了很大的影响)。例如,您不会在 Scheme 或 Prolog 中看到 main()。
就个人而言,我认为问题 2a 和 2b 的答案是最重要的。如果你真的想破坏世界上的每一个 C/C++/Java 程序,以修复你认为有缺陷的单一函数名称美学,我会问你是否有你的优先顺序....; -)
语言设计者必须选择“一些”名称,而 main() 听起来像 Main 函数,因为这是执行开始的地方:)
可能是因为它是必须运行的主要功能。C++ 继承了 C 的名称,Java 继承了 C++ 的名称(程序员不喜欢更改)。
你必须给它起个名字。我想不出更好的名字,因为这是主程序流程开始的地方。
没有共同的结构,除了可能接受论点的能力。也不应该有一个共同的结构,因为程序的全部意义在于做程序员想要的任何事情。即,任何东西。
好吧,它要么必须有一个固定的名称,要么你必须给程序员一种指定名称的方法。
如果程序员可以选择名称,那么语言中必须有一个额外的语句或某种特性来处理它。会得到什么?可以说我们的情况会更糟:那么当你想找到这个函数时,你首先必须寻找说明它被调用的东西,然后你必须寻找函数本身,所以会有两个步骤而不是一个。
鉴于它将有一个固定的名称,因此必须有人选择该名称。可以想到许多候选人:“开始”、“跑步”等等。我怀疑选择“主要”是否有任何压倒一切的原因。有人必须选择一些东西,这是一个很好的选择。
有时最好不要仅仅为了改变它而改变它。
不幸的是,我(还)不能直接发表评论,所以我必须在不知道你的问题答案的情况下给出完整的答案。
但是,然而,我想向所有人指出“除了main()之外,它应该变成什么?” 确实根本不需要命名函数。{}
按照惯例,这些匿名括号内的代码很可能是主要功能,仅此而已。(因此,它不仅暗示int
何时缺少返回类型,还暗示main()
何时缺少函数名。)
因为它和其他任何东西一样好。另一种方法是使用未命名的块,如在 Pascal 及其派生类中,或在大多数脚本语言中,其中“主函数”(如果允许这样调用)只是文件的开头。然后,你必须关心你从哪里得到程序参数(一些库或全局变量),你可以问他们为什么选择args
而不是arguments
or argv
orparam
等。
真诚地,我从没想过有人会关心这种几乎无关紧要的传统主义xD
如果您开发嵌入式系统,您可能会看到其他名称。
生态系统用途
cyg_user_start().
(或 main(),取决于设置)。
Linux 内核模块使用标有 __init 的函数(尽管这不是一回事,因为模块通常是事件驱动的)。
因为 C、C++ 和 Java 需要一种方法来知道主函数在哪里......
然而,许多其他语言允许它以您喜欢的方式命名,并有办法告诉编译器哪个函数是入口点(编译器选项、编译指示、特殊语句......)。