C 未定义返回类型的main()函数发出警告

C 未定义返回类型的main()函数发出警告,c,types,return,main,C,Types,Return,Main,这是我的节目: main() { printf("hello world\n"); } 我在编译时收到以下警告: function should return a value 将干管更改为空干管时,警告消失 为什么会这样?c自动向没有声明数据类型的函数暗示数据类型int。就编译器而言,上述内容是: int main() { printf("hello world\n"); } 这要求您在它的末尾使用return语句返回一个整数。如果显式地将其指定为void main,则

这是我的节目:

main()
{ 
    printf("hello world\n");
}
我在编译时收到以下警告:

function should return a value
将干管更改为空干管时,警告消失


为什么会这样?

c自动向没有声明数据类型的函数暗示数据类型int。就编译器而言,上述内容是:

int main()
{ 
    printf("hello world\n");
}
这要求您在它的末尾使用return语句返回一个整数。如果显式地将其指定为void main,则会告诉编译器该函数没有返回值,因此不会发出警告

这不是错误的原因是,如果未指定,main将返回0;在执行结束时。然而,编译器仍在警告您这种情况正在发生

最佳实践是使用int main,然后在程序执行结束时返回0,如下所示

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

请参阅:了解更多信息。

c自动向没有声明数据类型的函数暗示数据类型int。就编译器而言,上述内容是:

int main()
{ 
    printf("hello world\n");
}
这要求您在它的末尾使用return语句返回一个整数。如果显式地将其指定为void main,则会告诉编译器该函数没有返回值,因此不会发出警告

这不是错误的原因是,如果未指定,main将返回0;在执行结束时。然而,编译器仍在警告您这种情况正在发生

最佳实践是使用int main,然后在程序执行结束时返回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返回类型,且不包含 参数:

或者使用两个参数,这里称为argc和argv,尽管任何名称都可能是 使用,因为它们是声明它们的函数的本地函数:

或同等品;10或以某种其他实现定义的方式


您得到警告是因为您没有指定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返回类型,且不包含 参数:

或者使用两个参数,这里称为argc和argv,尽管任何名称都可能是 使用,因为它们是声明它们的函数的本地函数:

或同等品;10或以某种其他实现定义的方式


您应该注意以下几点:

int是主函数的返回类型。这意味着这种价值观可以 return是一个整数。 C90编译器允许main,但C99编译器不允许main,这意味着它不再是C99标准的一部分,所以不要这样做。 voidmain不是一个标准表单,一些编译器允许这样做,但没有一个标准将其列为选项。因此 编译器不必接受此表单,有些编译器也不必接受。再次,坚持标准形式, 如果你把一个程序从一个编译器移到另一个编译器,你就不会遇到问题。 最后一件事,不要像这样写主文:

int main(void)// this specifies there are no arguments taken by main
int main//在这里,您对向main传递参数保持沉默,这意味着它可能接受也可能不接受参数

这样写:

int main(void)// this specifies there are no arguments taken by main

您可能需要查看以了解更多详细信息。

您应该注意以下几点:

int是主函数的返回类型。这意味着这种价值观可以 return是一个整数。 C90编译器允许main,但C99编译器不允许main,这意味着它不再是C99标准的一部分,所以不要这样做。 voidmain不是一个标准表单,一些编译器允许这样做,但没有一个标准将其列为选项。因此 编译器不必接受此表单,有些编译器也不必接受。再次,坚持标准形式, 如果你把一个程序从一个编译器移到另一个编译器,你就不会遇到问题。 最后一件事,不要像这样写主文:

int main(void)// this specifies there are no arguments taken by main
在 t main//在这里,您对向main传递参数保持沉默,这意味着它可能接受参数,也可能不接受参数

这样写:

int main(void)// this specifies there are no arguments taken by main

您可能需要查看以了解更多详细信息。

快速摘要:如果不想使用命令行参数,您应该编写:

int main(void) {
    /* body of main function */
}
如果您这样做:

int main(int argc, char *argv[]) {
    /* ... */
}
这些是定义主功能的唯一可移植方法

您可能应该有一个返回0;最后,虽然这不是绝对必要的。返回0表示执行成功。有很多方法表明执行失败;我不想在这里谈这个

这背后有一些历史。在C标准的不同版本中,主函数的有效定义规则发生了一些变化

在1989年引入C的第一个官方标准之前,最常见的形式是:

main()
{
    /* ... */
}
或者,如果要使用命令行参数:

main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
    /* ... */
}
int main(void) {
    /* ... */
}
无法定义不返回值的函数。如果未指定返回类型,则默认为int

1989年的ANSI C标准作为1990年的ISO C标准进行了编辑性修改,重新发布了该标准,引入了原型、函数声明和指定参数类型的定义。对于main,有两个同样有效的定义。根据是否需要使用命令行参数,可以使用一个或另一个参数:

main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
    /* ... */
}
int main(void) {
    /* ... */
}

char*argv[]也可以写为char**argv。此规则仅适用于参数定义

给定的编译器可能会也可能不会选择允许其他形式。例如,某些编译器支持第三个参数envp

不知何故,一些作者认为void main或void mainvoid是有效的。它可以对某些特定的编译器有效,但前提是该编译器明确支持它。它不是便携式的。奇怪的是,第一个引入void关键字的标准同时建立了main的返回类型为int的规则

void main是一个有用的指标,表明您正在阅读的书的作者对C语言不是很了解,您应该找到另一本书

独立嵌入式系统的情况则不同。对于这样的系统,程序的入口点完全由实现定义,甚至可能不被称为main。将其定义为void mainvoid可能对此类系统有效


1999年的ISO C标准取消了隐式整数规则。从一开始,利用这条规则可能从来都不是一个好主意。自ISO C 1990起,您可以合法使用:

main(void) { /* ... */ }
因为它相当于:

int main(void) { /* ... */ }
自1999年标准起,int是强制性的

1999年的标准还添加了一个特例规则:到达main函数的closing}相当于执行return 0;。添加显式返回0;,仍然是个不错的主意;,尤其是如果您的代码可能是用C99之前的编译器编译的

2011年ISO C标准在这方面没有做任何更改

int main和int mainvoid的区别在于后者明确表示main不接受参数;前者没有指定需要多少参数。使用int mainvoid表单。关于int-main是否合法,一直存在争论

您可能不需要编写voidmain,因为编译器实际上不需要诊断它的未定义行为,除非实现记录它,否则这是一个错误

一句话:main的正确定义有着悠久而多样的历史,并且有许多变体形式,您可能可以不用使用。但是,除非您是为嵌入式系统编程,否则使用以下两种官方有效形式之一之外的任何形式都没有意义:

int main(void) { /* ... */ }

int main(int argc, char *argv[]) { /* ... */ }

快速总结:如果不想使用命令行参数,则应编写:

int main(void) {
    /* body of main function */
}
如果您这样做:

int main(int argc, char *argv[]) {
    /* ... */
}
这些是定义主功能的唯一可移植方法

您可能应该有一个返回0;最后,虽然这不是绝对必要的。返回0表示执行成功。有很多方法表明执行失败;我不想在这里谈这个

这背后有一些历史。在C标准的不同版本中,主函数的有效定义规则发生了一些变化

在1989年引入C的第一个官方标准之前,最常见的形式是:

main()
{
    /* ... */
}
或者,如果要使用命令行参数:

main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
    /* ... */
}
int main(void) {
    /* ... */
}
无法定义不返回值的函数。如果未指定返回类型,则默认为int

1989年的ANSI C标准作为1990年的ISO C标准进行了编辑性修改,重新发布了该标准,引入了原型、函数声明和指定参数类型的定义。对于main,有两个同样有效的定义。根据是否需要使用命令行参数,可以使用一个或另一个参数:

main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
    /* ... */
}
int main(void) {
    /* ... */
}

char*argv[]也可以写为char**argv。 此规则仅适用于参数定义

给定的编译器可能会也可能不会选择允许其他形式。例如,某些编译器支持第三个参数envp

不知何故,一些作者认为void main或void mainvoid是有效的。它可以对某些特定的编译器有效,但前提是该编译器明确支持它。它不是便携式的。奇怪的是,第一个引入void关键字的标准同时建立了main的返回类型为int的规则

void main是一个有用的指标,表明您正在阅读的书的作者对C语言不是很了解,您应该找到另一本书

独立嵌入式系统的情况则不同。对于这样的系统,程序的入口点完全由实现定义,甚至可能不被称为main。将其定义为void mainvoid可能对此类系统有效


1999年的ISO C标准取消了隐式整数规则。从一开始,利用这条规则可能从来都不是一个好主意。自ISO C 1990起,您可以合法使用:

main(void) { /* ... */ }
因为它相当于:

int main(void) { /* ... */ }
自1999年标准起,int是强制性的

1999年的标准还添加了一个特例规则:到达main函数的closing}相当于执行return 0;。添加显式返回0;,仍然是个不错的主意;,尤其是如果您的代码可能是用C99之前的编译器编译的

2011年ISO C标准在这方面没有做任何更改

int main和int mainvoid的区别在于后者明确表示main不接受参数;前者没有指定需要多少参数。使用int mainvoid表单。关于int-main是否合法,一直存在争论

您可能不需要编写voidmain,因为编译器实际上不需要诊断它的未定义行为,除非实现记录它,否则这是一个错误

一句话:main的正确定义有着悠久而多样的历史,并且有许多变体形式,您可能可以不用使用。但是,除非您是为嵌入式系统编程,否则使用以下两种官方有效形式之一之外的任何形式都没有意义:

int main(void) { /* ... */ }

int main(int argc, char *argv[]) { /* ... */ }

在最后一行。

写入

return 0 ;


在最后一行。

这是你可以通过简单搜索找到的东西。它应该是int mainvoid这是你可以通过简单搜索找到的东西。它应该是int mainvoid否,void main无效,始终使用int main。1999年ISO C标准删除了隐式int规则,使main{}无效。否,void main无效,始终使用int main。1999年ISO C标准删除了隐式int规则,使main{}无效。第4点是错误的。作为定义,int main{…}与int mainvoid{…}相同。它只是一个声明,即int main;不带void的表单未指定参数。@R..:函数定义包含声明。任何现有编译器都可能接受int main,但您仍应使用int mainvoid。我已经进一步讨论过了,第四点是错误的。作为定义,int main{…}与int mainvoid{…}相同。它只是一个声明,即int main;不带void的表单未指定参数。@R..:函数定义包含声明。任何现有编译器都可能接受int main,但您仍应使用int mainvoid。我已经进一步讨论过了。实际上,K&R C的第一版在hello world示例中没有指定main的类型。@Wyatt8740这是因为K&R C第一版的日期早于ANSI/ISO C C89/90。在K&R和C89/90中,有一个隐式int规则,该规则规定忽略返回类型的函数会自动被视为返回int。C99放弃了该规则,因此在K&R和C89/90中不为main指定返回类型是可以的,但现在不是,老实说,除非您所处的环境早于ANSI/ISO C,老实说,您永远不应该使用隐式int规则。看看基思·汤普森的答案。是的,@RastaJedi-我知道它比ANSI早。我想基本上每个人都知道。@Wyatt8740实际上有很多人因为这本书的第二版而混淆了“K&R”这个名字。有趣的是,他们没有在这个例子中使用返回类型,+1。@RastaJedi名称“C89”读作:1989,最初的第一版出版日期可能会给我提供线索。实际上,K&R C的第一版在hello world示例中没有指定main的类型。@Wyatt8740这是因为K&R C第一版早于ANSI/ISO C C89/90。在K&R和C89/90中,有一个隐式int规则,该规则规定忽略返回类型的函数会自动被视为返回int。C99放弃了该规则,因此在K&R和C89/90中不为main指定返回类型是可以的,但现在不是了,老实说,除非您
e在ANSI/ISO C之前的环境中,您绝对不应该使用隐式int规则。看看基思·汤普森的答案。是的,@RastaJedi-我知道它比ANSI早。我想基本上每个人都知道。@Wyatt8740实际上有很多人因为这本书的第二版而混淆了“K&R”这个名字。有趣的是,他们没有在这个例子中使用返回类型,+1。@RastaJedi名字“C89”读作:1989年,最初的第一版出版日期会给我提供线索。一个从所有这些进化中幸存下来的人给出了相当广泛的答案。。。这个更简单的选择是OK:int main{/*…*/}@chqrlie:取决于您如何定义OK。int main不是原型,根据C标准,非原型函数声明和定义已经过时。我认为任何C编译器都会接受int main{/*…*/},我相信标准的作者的意图是它应该是可以接受的,但标准实际上并没有说它是可以接受的。我已经在这里详细讨论了这一点:。一个从所有这些进化中幸存下来的人给出了一个相当广泛的答案。。。这个更简单的选择是OK:int main{/*…*/}@chqrlie:取决于您如何定义OK。int main不是原型,根据C标准,非原型函数声明和定义已经过时。我认为任何C编译器都会接受int main{/*…*/},我相信标准的作者的意图是它应该是可以接受的,但标准实际上并没有说它是可以接受的。我已经在这里详细讨论过:。请在回答中添加更多描述请在回答中添加更多描述