快速总结:如果你不想使用命令行参数,你应该写:
int main(void) {
/* body of main function */
}
如果你这样做:
int main(int argc, char *argv[]) {
/* ... */
}
这些是唯一定义main函数的可移植方式。
您应该可能在末尾有一个return 0;,尽管这不是绝对必要的。返回0 表示执行成功。有办法表明执行失败;在这里我就不多说了。
这背后有一些历史。 main 函数的有效定义规则在 C 标准的不同版本中有所改变。
在 1989 年引入第一个 C 官方标准之前,最常见的形式是:
main()
{
/* ... */
}
或者,如果您想使用命令行参数:
main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
/* ... */
}
没有办法定义不返回值的函数。如果您没有指定返回类型,则默认为int。
1989 年的 ANSI C 标准(作为 1990 年的 ISO C 标准重新发布并进行了编辑修改)引入了原型、指定参数类型的函数声明和定义。 main 有两个同样有效的定义。您可以根据是否需要使用命令行参数来使用其中一种:
int main(void) {
/* ... */
}
或
int main(int argc, char *argv[]) {
/* ... */
}
(char *argv[]也可以写成char **argv。这条规则只适用于参数定义。)
给定的编译器可能会或可能不会选择允许其他形式。例如,一些编译器支持第三个参数envp。
不知何故,一些作者认为void main() 或void main(void) 是有效的。 对于某些特定的编译器可能是有效的,但前提是该编译器明确支持它。它不是便携式的。奇怪的是,最初引入void 关键字的同一标准同时建立了main 的返回类型为int 的规则。
void main() 可用于指示您正在阅读的书的作者不太了解 C 语言,并且您应该另找一本书。
“独立”(嵌入式)系统的情况有所不同。对于这样的系统,程序的入口点完全由实现定义,甚至可能不称为main。将其定义为void main(void) 很可能是有效的对于此类系统。
1999 年 ISO C 标准删除了“隐式 int”规则。利用该规则可能一开始就不是一个好主意。从 ISO C 1990 开始,您可以合法使用:
main(void) { /* ... */ }
因为它相当于:
int main(void) { /* ... */ }
从 1999 年标准开始,int 是强制性的。
1999 标准还增加了一个特殊情况规则:到达main 函数的结束} 等效于执行return 0;。添加显式 return 0; 仍然不是一个坏主意,特别是如果您的代码可能使用 C99 之前的编译器进行编译。
2011 ISO C 标准在这方面没有做出任何改变。
int main() 和int main(void) 的区别在于后者明确表示main 不带参数;前者没有指定它需要多少个参数。使用int main(void) 表单。关于int main() 是否合法一直存在争议。
您很可能不写void main(),因为这是编译器实际上不需要诊断的错误(这是未定义的行为,除非实现记录了它)。
底线:main 的正确定义有着悠久而多样的历史,并且有很多变体形式您可能可以使用。但是,除非您正在为嵌入式系统编程,否则除了两种正式有效的形式之一之外,没有任何意义:
int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }