没有返回类型定义的main()函数会发出警告

这是我的计划:

main() { printf("hello world\n"); } 

编译时我收到此警告:

 function should return a value 

main()更改为void main() ,警告消失。

为什么会这样?

你应该注意的事情很少:

  1. intmain()函数的返回类型。 这意味着main()可以返回的值是一个整数。
  2. main( )被C90编译器所容忍,但不被C99编译器所容忍,这意味着它不再是C99标准的一部分,所以不要这样做。
  3. void main()不是标准forms,有些编译器允许这样做,但没有一个标准曾将它列为选项。 因此,编译器不必接受这种forms,而有些则不然。 再次,坚持使用标准表单,如果将程序从一个编译器移动到另一个编译器,则不会遇到问题。
  4. 最后一件事,而不是像这样写主要:

    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[]) { /* ... */ } 

这些是定义mainfunction的唯一可移植方式。

你应该有一个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 ; 

在最后一行。