【问题标题】:Why there is always main function in C?为什么C语言中总是有main函数?
【发布时间】:2021-05-06 06:26:46
【问题描述】:

使用 C 编写代码时,代码必须包含 main 函数。我一直有一个关于这个的问题。在 Python 或 JavaScript 的情况下,不需要 main 函数。但是,在 C 的情况下,我为什么要包含 main 函数?

这会提高性能吗?

还是只是为了区分主要部分和其他部分?

如果您能解释原因,我将不胜感激。

【问题讨论】:

  • C 程序是通过编译多个源文件并将生成的机器代码链接在一起而构建的。如果 C 允许在全局范围内运行任意语句(这基本上是 JavaScript 和 Python 所做的),你将如何控制来自多个模块的语句的运行顺序?
  • main 函数的一个用途是作为程序其余部分的入口点(例如,如果您看到任何程序集,您会注意到有一个名为 @ 的全局入口点987654322@ 或 main 所有代码开始的地方。高级语言中的 main 函数通常是那个入口点)。更多信息:en.wikipedia.org/wiki/Entry_point
  • @mediocrevegetable1 Linux 中编译的二进制程序可能同时具有_startmain。在调用main 之前还有很多工作要做,比如一些glibc 初始化的东西等等。
  • 嗯,有趣。我想我今天什至学到了一些东西。
  • main() 指定为入口点意味着所有C 或C++ 程序员都知道寻找main() 函数来查找大多数程序开始执行的位置。在解释型语言中,通常不需要像 main() 这样的函数,因为指定了其他启动程序的方式(例如,在提供给解释器的第一个脚本中具有某些特征的第一个函数)。与具有单一设计入口点的 C 或 C++ 相比,这些方法既有优点也有缺点(尽管 main() 可以有不同的签名)。

标签: c++ c architecture


【解决方案1】:

有两个主要原因,而且它们有点相关。

首先,对于任何给定的可执行文件,知道从哪里开始执行很重要。在像 Python 这样的语言中,有一个执行的脚本,虽然它可以包含其他代码,但可以理解为有一个“主”脚本。

在像 C 这样的语言中,情况并非如此,其中许多文件被编译并链接在一起成为最终的可执行文件。这些文件的编译和链接顺序在很大程度上是无关紧要的,一般来说,它们都被平等对待。因此,为入口点保留了一个名为 main 的“特殊”函数。

在 C 和扩展的 C++ 中,您必须在函数内部做很多事情,而这在代码的主体中是不允许的。在其他语言中,这种区别并不适用。在 C 语言中,您至少需要一个函数来做任何有用的事情,该函数将被称为 main

这种区别并不特别是像 Python 这样的脚本语言与像 C 这样的编译语言。Swift 是编译的,但允许在不需要 main() 函数的情况下进行类似脚本的编码。这完全是语言设计的功能,并且在考虑到约束的情况下才有意义。

这也仅适用于可执行文件。对于图书馆来说,没有一个入口点,而是有多少功能就有多少。您导出的任何函数都可以按任意顺序任意调用,至少在库定义的 API 允许的范围内。

您甚至可以将可执行文件视为具有一个有效功能的“库”:main()

【讨论】:

    【解决方案2】:

    main 函数在程序启动时调用,在所有具有静态存储持续时间的对象都被初始化之后。它是在宿主环境(即操作系统)中执行的程序的指定入口点。任何独立程序(引导加载程序、操作系统内核等)的入口点的名称和类型都是由实现定义的。

    main() 函数是程序开始执行时执行的第一个函数,但它不是第一个执行的函数。第一个函数是 _start(),它通常由 C 运行时库提供,在编译程序时自动链接。细节高度依赖于操作系统和编译器工具链,所以我会假装我没有提到它。

    您可以编写没有 main 函数的 C 库,并从具有 main 的其他 C 程序调用这些函数。

    【讨论】:

      【解决方案3】:

      编译 C/C++ 程序时,编译器生成的实际代码以设置内存、配置标准输入和输出的前导码开始,然后调用 main() 函数。如果你试图编译一个没有 main() 函数的程序,链接器实际上会抱怨它的缺失,因为它在运行时环境中被引用。因此 main() 函数对于运行时执行程序至关重要。

      【讨论】:

      • 这个答案有点重言式。 “这是必要的,因为它是必要的。”
      • 有点重言式,是的,但我读这个答案更多的是说,“启动代码和你的程序之间必须有一些接口,并且这个接口被选为 main() 函数。因此,如果您不提供 main(),则启动代码将期待 main(),因此链接器会抱怨它不存在“
      • 通常,编译器不会生成这个“序言”。运行时启动代码链接在里面。
      【解决方案4】:

      编译器开始编译使用 main() 函数在 c 中提供的主要代码时需要表单。

      【讨论】:

      • 编译器不使用main()开始编译代码。
      猜你喜欢
      • 1970-01-01
      • 2010-09-28
      • 2017-07-31
      • 1970-01-01
      • 2011-09-24
      • 2012-08-16
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      相关资源
      最近更新 更多