【问题标题】:calling main() in main() in c在 c 中调用 main() 中的 main()
【发布时间】:2011-05-13 09:32:01
【问题描述】:

是否可以在c中的main()函数中调用main()

【问题讨论】:

  • 你试过了吗?成功了吗?
  • 没有什么能阻止您在其上下文中调用函数。这叫做递归。
  • @Donnie 仅仅因为某些东西在测试示例中似乎有效并不意味着它总是会或者是正确的。 “试试看它是否有效”在 C 中通常很危险。
  • @nos:我仍然希望看到作者在提出问题之前至少先尝试并分享他/她的经验。我不喜欢人们将其用作交互式 Google 界面。
  • 这是一个合法的问题,例如C++ 标准明确禁止它,而“尝试看看它是否有效”的方法可能会表明如果这个问题是关于 C++ 的“它有效”,但它是不正确的。

标签: c


【解决方案1】:

是的,C 允许你调用你的 main 函数(而 C++ does not

【讨论】:

  • 我很好奇,你为什么不能用 C++ 调用它?
  • @ThiefMaster:全局构造函数的最简单实现(无需操作系统和底层C运行时入口代码的特殊支持)是C++编译器在main开头生成函数调用(@ 987654324@ 是它的通用名称)它调用所有全局构造函数。每次递归调用 main 时都重构全局对象将是一件相当糟糕的事情...... :-)
  • @nos 你能否指出任何 C 标准中专门解决 main() 递归的地方,如果它是专门解决的?
  • 我认为你应该链接this
【解决方案2】:

确实允许从自身调用main(),甚至使用用于任何其他递归代码的相同方法避免堆栈溢出,终止条件例如:

#include <stdio.h>
int main (int argc, char *argv[]) {
    printf ("Running main with argc = %d, last = '%s'\n",
        argc, argv[argc-1]);
    if (argc > 1)
        return main(argc - 1, argv);
    return 0;
}

当以testprog 1 2 3 运行时,输出:

Running main with argc = 4, last = '3'
Running main with argc = 3, last = '2'
Running main with argc = 2, last = '1'
Running main with argc = 1, last = 'testprog'

但是,由于这只是轶事证据,我们应该转向标准。 ISO C11 部分4 Conformance 声明:

1/ 在本国际标准中,“应”被解释为对实现或程序的要求;相反,“shall not”将被解释为禁止。

2/ 如果违反了出现在约束或运行时约束之外的“应”或“不应”要求,则行为未定义。未定义的行为在本国际标准中以“未定义的行为”一词或省略任何明确的行为定义来表示。这三者在重点上没有区别;它们都描述了“未定义的行为”。

3/ 在所有其他方面都正确的程序,对正确的数据进行操作,包含未指定的行为,应是正确的程序,并按照 5.1.2.3 行事。

现在,由于main() 调用自身的标准中的任何地方都没有明确的禁止,因此上面的第 3 条是控制方面。

在两个地方可以看到进一步的支持(我的粗体),首先在5.1.2.2.3 Program termination部分:

1/ 如果main 函数的返回类型是与int 兼容的类型,则initial 调用返回main 函数相当于以main函数返回的值作为参数调用exit函数;

然后在7.21.3 Files部分:

5/ 该文件可能随后被相同或另一个程序执行重新打开,并且其内容被回收或修改(如果它可以在其开始时重新定位)。如果main 函数返回到它的原始 调用者,或者如果exit 函数被调用,所有打开的文件都被关闭(因此所有输出流都被刷新)之前程序终止。

这两个小节都支持在初始/原始调用之外其他调用main()的可能性。

【讨论】:

    【解决方案3】:

    是的,我们可以在 main() 函数中调用 main()。

    函数本身调用函数的过程称为递归。

    嗯,你可以在 main() 函数中调用 main(),但是你应该有一个不调用 main() 函数来终止程序的条件。

    否则,程序将永远返回并无限运行。

    【讨论】:

    • 栈空间用完会导致栈溢出。
    • 除非编译器进行尾调用优化,但无论如何你不能依赖它,所以要避免无休止的递归。
    【解决方案4】:

    是的,你可以

    简单程序:

    int main()
    {
        printf("Anything");
        main();
        return 0;
    }
    

    说明:

    call stackfunction stack 用于多个相关目的,但拥有一个的主要原因是跟踪每个活动子例程在完成执行时应返回控制权的点。

    在调用堆栈上使用过多内存时会出现stack overflow

    这里函数main()被重复调用,其返回地址存储在堆栈中。堆栈内存满后。它显示stack overflow error

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多