我是一般的编程新手,特别是C。我看过的每个例子都有一个“主要”功能 - 这是以某种方式预先定义的,这样名称对编译器或运行时具有特殊意义......或者它只是C程序员中常见的习惯用法(比如使用“foo”和“bar”作为任意变量名)。
答案 0 :(得分:12)
不,您需要在程序中定义main
。但是,由于它是从运行时调用的,因此main
必须提供的接口是预定义的(必须返回int
,必须采用零参数或两个参数,第一个{{1} },第二个是int
或等同于char **
)。 C和C ++标准确实指定具有名为char *[]
的外部链接的函数充当程序 1 的入口点。
至少在通常使用的术语中,预定义的函数可以是标准库中的main
或sin
,因此您可以使用它而无需自己编写。
1 如果你想获得技术,那对于“托管”实现来说也是如此 - 也就是说,我们大多数人在大多数情况下使用它来生成在操作系统上运行的程序。一个“独立”的实现(一个产生直接在“裸机”上运行但没有操作系统的程序)可以自由地定义它认为合适的入口点。独立的实现也可以省略大多数正常的运行时库,只提供少量标题(例如printf
),几乎没有标准库函数。
答案 1 :(得分:8)
是的,main
是“定义”一词意义上的预定义函数。换句话说,C语言标准指定在程序启动时调用的函数应命名为main
。它不仅仅是程序员使用的惯例,就像我们使用foo
或bar
一样。
细则:从C编程上下文中“定义”一词的技术含义来看,main
函数没有“预定义” - 编译器或C库不提供名为main
的预定义函数。您需要定义您自己的main
函数实现(显然,您应该将其命名为main
)。
答案 2 :(得分:2)
通常有一段代码可以将正常的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以及可能与之链接的各种其他语言(特别是构造函数和析构函数调用,以及可能主要在C ++ try / catch块中)所发生的一些事情。
无论如何,这段代码知道main是一个函数并且接受了参数。如果你的主要看起来像:
int main(void) {
然后它仍然会被传递参数,但它们会被忽略。
此代码专门链接,以便在程序启动时调用它。
您可以完全自由地在许多体系结构上编写自己的此代码版本,但它依赖于对操作系统如何启动新程序以及C(和C ++以及可能的Objective C)运行时的深入了解。它可能需要一些汇编编程和/或使用编译器扩展来正确构建。
C编译器驱动程序(通常在调用编译器时调用的命令)将包含所有这些的对象文件(通常称为crt0.0,对于C运行时...)与程序的其余部分一起传递给链接器,除非告诉不要。
构建操作系统内核或嵌入式程序时,通常不希望使用标准的crt * .o文件。如果您使用其他编程语言构建普通应用程序,或者有其他一些非标准要求,也可能不想使用它。
答案 3 :(得分:0)
不,或者你无法定义一个。
它不是预定义的,但它的含义是一个入口点,如果它存在,则被定义。