没有返回类型定义的main()函数会发出警告
这是我的计划:
main() { printf("hello world\n"); }
编译时我收到此警告:
function should return a value
将main()
更改为void main()
,警告消失。
为什么会这样?
你应该注意的事情很少:
-
int
是main()
函数的返回类型。 这意味着main()
可以返回的值是一个整数。 -
main( )
被C90编译器所容忍,但不被C99编译器所容忍,这意味着它不再是C99标准的一部分,所以不要这样做。 -
void main()
不是标准forms,有些编译器允许这样做,但没有一个标准曾将它列为选项。 因此,编译器不必接受这种forms,而有些则不然。 再次,坚持使用标准表单,如果将程序从一个编译器移动到另一个编译器,则不会遇到问题。 -
最后一件事,而不是像这样写主要:
int main()
// 这里你沉默地将参数传递给main,这意味着它可能会也可能不会参数
像这样写:
int main(void)// this specifies there are no arguments taken by main
您可能需要查看 C99标准 以获取更多详细信息 。
快速摘要:如果您不想使用命令行参数,则应编写:
int main(void) { /* body of main function */ }
如果你这样做:
int main(int argc, char *argv[]) { /* ... */ }
这些是定义main
function的唯一可移植方式。
你应该有一个return 0;
最后,虽然这不是绝对必要的。 返回0
表示执行成功。 有办法表明执行失败; 我不会在这里讨论。
这背后有一些历史。 有关main
函数定义的规则在C标准的不同版本中有所改变。
在1989年推出C的第一个官方标准之前,最常见的forms是:
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
。此规则仅适用于参数定义。)
给定的编译器可能会也可能不会选择允许其他forms。 例如,一些编译器支持第三个参数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
函数的closing }
相当于执行return 0;
。 添加显式return 0;
仍然是一个坏主意return 0;
,特别是如果您的代码可能使用pre-C99编译器编译。
2011 ISO C标准未对此领域进行任何更改。
int main()
和int main(void)
之间的区别在于后者明确表示main
不带参数; 前者没有指定它需要多少个参数。 使用int main(void)
表单。 关于int main()
是否合法的争论一直存在。
编写void main()
可能会失败,因为编译器实际上并不需要诊断它是一个错误(除非实现记录它,否则它是未定义的行为 )。
底线: main
的正确定义有着悠久而多变的历史,并且有许多变体forms你可以使用它们。 但除非你是为嵌入式系统编程,否则使用除两种官方有效forms之外的任何东西都是没有意义的:
int main(void) { /* ... */ } int main(int argc, char *argv[]) { /* ... */ }
c自动将数据类型int
为没有声明数据类型的函数。 所以就编译器而言,上面是:
int main() { printf("hello world\n"); }
这期望您将使用return
语句在其末尾返回一个整数。 如果您明确地将其指定为void main()
,则告诉编译器该函数没有返回值,因此没有警告。
这不是错误的原因是,如果没有指定, main()
将return 0;
在执行结束时。 但是编译器仍然会发出警告,说明这种情况正在发生。
最佳做法是使用int main()
,然后在程序执行结束时return 0
,如下所示。
int main() { printf("hello world\n"); return 0; }
请参阅: 此问题以获取更多信息。
您收到警告,因为您没有指定main
的返回类型。
你应该总是使用int main
,并返回一个int
数,通常为0
表示成功。
int main() { printf("hello world\n"); return 0; //you can omit this since C99 }
在托管环境中使用void main
(通常我们是,如果不是,以下不一定是真的)会导致未定义的行为,即使它在某些编译器中有效, 也从不使用它。
标准说main
有两种原型,都返回int
:
C11 5.1.2.2.1 程序启动
程序启动时调用的函数名为main。 该实现声明此函数没有原型。 它应该使用返回类型int并且没有参数来定义:
int main(void) { /* ... */ }
或者使用两个参数(这里称为argc和argv,尽管可以使用任何名称,因为它们是声明它们的函数的本地名称):
int main(int argc, char *argv[]) { /* ... */ }
等效的; 10)或其他一些实现定义的方式。
写
return 0 ;
在最后一行。