27

几个星期以来,我一直在以自学的方式学习 C 编程,我对这个main()函数有一些疑问。

  1. 所有函数都必须在其函数原型中声明,然后在其定义中声明。为什么我们不必先main()在原型中声明函数?

  2. 为什么我们必须使用int main()而不是void main()

  3. main()return 0 在函数中究竟做了什么?例如,如果我编写一个以 结束main()函数的程序会发生什么return 1;

4

9 回答 9

24
  1. 只有在使用函数之前才需要声明函数。定义本身就是一个声明,因此不需要事先的原型。(如果在没有事先原型的情况下定义函数,一些编译器和其他工具可能会发出警告。这是一个有用的指南,而不是 C 语言的规则。)
  2. 因为C标准是这么说的。操作系统将返回值传递给调用程序(通常是 shell)。一些编译器会接受void main,但这是一个非标准扩展(它通常意味着“总是向操作系统返回零”)。
  3. 按照惯例,非零返回值表示发生了错误。Shell 脚本和其他程序可以使用它来确定您的程序是否成功终止。
于 2013-08-26T14:43:33.797 回答
18

1) 所有函数都必须在其函数原型中声明,然后在其定义中声明。为什么我们不必先在原型中声明 main() 函数?

不对。简单的例子:

void foo(){}  //definition

int main()
{
    foo();
    return 0;
}

仅当调用了一个函数但尚未看到定义时,才需要声明。这永远不会发生,main因为它是程序的启动。


2) 为什么我们必须使用 int main() 而不是 void main()?

因为标准是这样说的。(更准确地说,在托管环境中确实如此,通常是这种情况)

C99 5.1.2.2.1程序启动

程序启动时调用的函数名为main. 实现没有声明这个函数的原型。它应定义为返回类型int且不带参数:

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

或带有两个参数(这里称为argcand argv,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):

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

或同等学历; 或以其他一些实现定义的方式。


3) return 0 在 main() 函数中究竟做了什么?例如,如果我编写了一个以 return 1 结束 main() 函数的程序,会发生什么?

返回值表示程序的结果。通常0表示成功,而其他值表示不同类型的失败。

于 2013-08-26T14:44:47.443 回答
3

您不能自由选择 main 的返回类型,因为您没有编写调用 main 的代码。在您考虑学习 C 之前,调用 main 的代码就已经存在。它是由提供C 运行时启动代码的人编写的,通常会在您不知情的情况下自动链接到您的可执行文件。此代码通常位于名为 crt0.o 的文件中(由 crt0.c 甚至 crt0.s 中的汇编程序创建)。它期望使用指示成功 (0) 或失败 (非零) 的返回值,以及可能的其他信息,例如代码是否因信号而终止,如果是,是哪一个。这些是一些 Unix 历史,我不会在这里重复 :-)

于 2013-08-26T15:03:47.233 回答
1

1) 不一定;定义也可用作声明。其次,无论如何只有几个有效的签名,除非您正在为 IOCCC 编写条目,否则您main通常不会在代码中调用。main

2)简短的回答:因为语言定义是这样说的。更长的答案:这是您的程序向主机环境指示成功或失败的方式。单独的实现可以自由地支持 的附加签名main,但它必须记录这些附加签名。如果您的编译器文档未void main()列为合法签名,则不应使用它。

3) 按照惯例(至少在第一次使用 C 的 *nix 系统上),状态 0 表示成功,非零状态表示......不是成功。究竟什么值对应什么状态取决于实现。

于 2013-08-26T14:45:34.843 回答
0

1)它是假的,你只能创建一个函数的定义。

2)我们可以知道main()函数是否正确终止

3)除了在你的shell中它将被写为1而不是0

于 2013-08-26T14:41:42.197 回答
0

函数不必首先声明为原型。仅当我们需要在定义之前使用函数时才需要这样的声明。

main根据定义具有 int 类型。

从 main 返回的值的含义是约定俗成的。普遍接受的惯例是 0 被认为是成功,而不是 0 某种失败。

于 2013-08-26T14:48:26.357 回答
0

1. C 库通过识别内置关键字“main”隐式调用 main() 函数。所以我们不需要为 main 函数声明原型。

2.这个我不确定,但我认为这取决于使用的编辑器类型。在 Turbo C 中, void main() 将被接受,而在 dev-cpp main() 中应该返回一个值。

3.return 0 简单地以退出状态 0 退出程序,换句话说,返回值决定了主线程的退出状态。

于 2013-08-26T14:51:50.053 回答
0

简单地说,你所有问题的最本质就是传统和一致性。工具链、操作系统等都知道这个称为 main() 的过程必须首先从用户代码空间(程序)中调用...

现在具体来说:1)因为我说的一致性。您不需要声明,因为工具链和操作系统已经知道 main。还有其他一致性函数,如 exit()。

2)当主要时间返回时,操作系统可以从中返回结果。通常非零意味着错误。因此,当您使用脚本或其他程序调用您的程序时,例如 main() 函数,您可以检查它是否成功。

3) 返回非零值表示错误。但实际上,您可以按照自己的意愿解释该值。但正如我所说,操作系统可以有结果。

附加信息: main() 实际上不是启动程序时将调用的第一个函数(您已编写)。但实际上操作系统和工具链在你的主之前促进其他调用,设置环境,进行初始化或其他任何事情。但是,当您编写代码时,您并不直接知道这一点,而且您根本不必处理和考虑这一点。在嵌入式系统中,通常会调用一些非常低级的函数来设置 CPU 主时钟、中断、堆栈等。一些工具链(如 IAR)实际上可以让您在调用 main 之前执行自己的代码。

希望这有帮助:)

于 2013-08-26T15:11:01.987 回答
0

当我们运行 C 程序时,计算机控制权传递给 C 程序的main()函数,C 程序从那里开始执行

于 2019-03-11T16:05:12.550 回答