可能重复:
C、C++、Java、C# 中的 main()
我一般是编程新手,尤其是 C 语言。我看过的每个示例都有一个“main”函数 - 这是以某种方式预定义的,因此该名称对编译器或运行时具有特殊含义......或者它仅仅是 C 程序员之间的常见习语(比如使用“foo”和“bar”作为任意变量名)。
可能重复:
C、C++、Java、C# 中的 main()
我一般是编程新手,尤其是 C 语言。我看过的每个示例都有一个“main”函数 - 这是以某种方式预定义的,因此该名称对编译器或运行时具有特殊含义......或者它仅仅是 C 程序员之间的常见习语(比如使用“foo”和“bar”作为任意变量名)。
不,你需要main
在你的程序中定义。但是,由于它是从运行时调用的,因此您main
必须提供的接口是预定义的(必须返回 an int
,必须采用零个或两个参数,第一个是 an int
,第二个是 achar **
或等价的char *[]
)。C 和 C++ 标准确实指定具有名为的外部链接的函数main
充当程序1的入口点。
至少正如通常使用的术语一样,预定义函数将是标准库中的一个sin
或printf
那个,因此您可以使用它而无需自己编写它。
1如果您想获得技术知识,那仅适用于“托管”实现——即我们大多数人大部分时间使用的那种生成在操作系统上运行的程序的类型。“独立”实现(一个生成直接在“裸机”上运行的程序,其下没有操作系统)可以自由定义它认为合适的入口点。一个独立的实现也可以省略大部分正常的运行时库,只提供少量的头文件(例如,<stddef.h>
)并且几乎没有标准库函数。
是的,main
是“定义”一词一般意义上的预定义函数。换言之,C 语言标准规定程序启动时调用的函数应命名为main
。它不仅仅是程序员使用的约定foo
or bar
。
细则:从 C 编程上下文中“定义”一词的技术含义来看,没有main
函数不是“预定义的”——编译器或 C 库不提供名为main
. 您需要定义自己的main
函数实现(显然,您应该命名它main
)。
通常有一段普通 C 程序链接到的代码:
extern int main(int argc, char * argv[], char * envp[]);
FILE * stdin;
FILE * stdout;
FILE * stderr;
/* ** setup argv ** */
...
/* ** setup envp ** */
...
/* ** setup stdio ** */
stdin = fdopen(0, "r");
stdout = fdopen(1, "w");
stderr = fdopen(2, "w");
int rc;
rc = main(argc, argv, envp); // envp may not be present here with some systems
exit(rc);
请注意,此代码是 C,而不是 C++,因此它期望 main 是 C 函数。另请注意,我的代码不进行错误检查,并遗漏了许多可能发生的其他系统相关内容。它还忽略了 C++、目标 C 和可能与其链接的各种其他语言发生的一些事情(特别是构造函数和析构函数调用,并且可能有 main 在 C++ try/catch 块中)。
无论如何,这段代码知道 main 是一个函数并接受参数。如果你的主要看起来像:
int main(void) {
然后它仍然得到传递的参数,但它们被忽略了。
此代码专门链接,以便在程序启动时调用它。
您可以在许多架构上完全自由地编写自己的代码版本,但它依赖于对操作系统如何启动新程序以及 C(以及 C++ 和可能的 Objective C)运行时的深入了解。可能需要一些汇编编程和/或使用编译器扩展才能正确构建。
C 编译器驱动程序(您通常在调用编译器时调用的命令)将包含所有这些内容的目标文件(通常称为 crt0.0,对于 C 运行时 ...)与程序的其余部分一起传递给链接器,除非被告知不要。
在构建操作系统内核或嵌入式程序时,您通常不想使用标准 crt*.o 文件。如果您正在用另一种编程语言构建普通应用程序,或者有一些其他非标准要求,您也可能不想使用它。
不,或者你无法定义一个。
它不是预定义的,但定义了它作为入口点的含义(如果存在)。