2

这是我的程序:

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

编译时收到此警告:

function should return a value

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

为什么呢?

4

5 回答 5

11

有几件事情你应该注意:

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

    int main()//这里你对向 main 传递参数保持沉默,这意味着它可能会或可能不会接受参数

像这样写:

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

您可能想查看 C99 标准 以了解更多详细信息

于 2013-08-10T04:43:09.900 回答
7

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

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()合法一直存在争议。

您可能会摆脱 write void main(),因为编译器实际上不需要诊断这是一个错误(除非实现记录它,否则它是未定义的行为)。

底线: 的正确定义main具有悠久而多样的历史,并且有很多变体形式您可能可以使用。但是,除非您正在为嵌入式系统编程,否则使用除了两种正式有效的形式之一之外的任何东西都没有任何意义:

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

int main(int argc, char *argv[]) { /* ... */ }
于 2013-08-10T18:57:36.007 回答
1

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;
}

请参阅:此问题以获取更多信息。

于 2013-08-10T04:17:51.953 回答
1

您收到警告是因为您没有指定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) 或以其他一些实现定义的方式。

于 2013-08-10T04:40:48.620 回答
1

return 0 ;

在最后一行。

于 2018-10-01T19:22:45.833 回答