基本上,main() 是特殊的,它有两种标准定义的形式:
int main(int argc, char **argv)
int main(void)
系统可能支持其他形式;环境也可以使用是很常见的:
int main(int argc, char **argv, char **envp)
这些表格是固定的。唯一不寻常的是,系统必须支持前两个中的任何一个(有些系统也支持其他系统)。
与 POSIX 中的 execl() 不同,通过指向字符串的指针数组(即上面的 argv)处理可变数量的命令行参数。
另见:
rahul manglanicommented:
你提到的两个链接很清楚。那里列出了不同的可能方法,但没有提到实际使用的方法。
从某种意义上说,没关系;系统必须工作,而生产“系统”的人必须使其工作。作为使用系统的程序员,你不需要知道它是如何工作的;您可以简单地假设它确实有效。
在幕后,通常会发生调用main() 的“启动”函数进行一些修复工作(特别是在 C++ 程序的情况下,很多修复工作 - 例如确保所有构造函数必须在main()starts 实际上执行之前执行),但以固定顺序结束,例如:
exit(main(argc, argv, environ));
请注意,environ 是一个全局变量,extern char **environ;(在 POSIX 定义的全局变量中是唯一的,因为没有头文件声明它),它包含指向环境变量的指针。 “开始”代码必须确保已设置;因此,将environ 作为参数传递给main() 是微不足道的。
这会使用固定的参数列表调用main(),如果/当它返回时调用exit()。事实上,Apple 更进一步,将第四个参数传递给main()。如果被调用的函数被定义为int main(void) { … },它会简单地忽略它传递的参数;如果它被定义为int main(int argc, char **argv) { … },它可以像往常一样访问命令行参数;如果定义为int main(int argc, char **argv, char **envp) { … },那么它也可以访问环境。
通常,系统的设置是为了避免额外的参数造成损害。这就是为什么 C 在其调用约定中不寻常的原因,也是被调用函数不清理压入堆栈的参数的原因——被调用函数不知道实际压入堆栈的参数有多少。它假定提供了它期望的那些并使用那些没有问题的,但调用代码知道它推送了什么,因此它可以正确清理。如果被调用函数需要 N 个参数,但调用者传递了 M 个参数并且 M