【问题标题】:what is the alternative for "while" / "for" loops“while”/“for”循环的替代方法是什么
【发布时间】:2019-03-24 09:25:37
【问题描述】:

我有一个作业,我应该一次又一次地做一些动作,直到我在控制台中写“停止”,但我不能使用forwhilegotoswitch,@987654325 @, typedef 在我所有的代码中。那么如何更换循环呢?

【问题讨论】:

  • 你可以使用递归
  • 你也可以使用带有可变参数的模板元编程在编译时实现循环。
  • @πάνταῥεῖ 听起来循环的持续时间需要在运行时确定。
  • 您可以使用setjmp/longjmp,因为这些不在您的禁止操作列表中。
  • @JesperJuhl Awwwwwwww!

标签: c++ loops


【解决方案1】:

可以使用递归。此示例重复您输入的内容,直到您键入“stop”作为示例:

#include <iostream>
#include <string>

void do_it()
{
  std::string s;
  std::cin >> s;
  if (s == "stop")
    return;
  std::cout << s << '\n';
  do_it();
}

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

这里可能不是这样,但递归有其缺点。一方面它比简单循环慢,因为在 C++ 等语言中,函数调用相对昂贵。如果重复次数过多,可能会导致堆栈溢出。话虽如此,函数的递归版本有时会更干净,更容易阅读/理解。您可以详细了解递归的优缺点here

【讨论】:

    【解决方案2】:

    正如 Jesper Juhl 在 cmets 中指出的,他们禁止了 goto,但忘记禁止 setjmp/longjmp

    与基于递归的解决方案不同,setjmp/longjmp 在迭代次数过多时不可能导致堆栈溢出。

    #include <csetjmp>
    #include <iostream>
    #include <string>
    
    int main()
    {
        std::string s;
    
        std::jmp_buf jump_buffer;
        setjmp(jump_buffer);
    
        std::cin >> s;
    
        if (s == "stop")
            return 0;
    
        std::cout << s << '\n';
        std::longjmp(jump_buffer, 0);
    }
    

    请注意,longjmp 具有潜在危险,因为它不调用析构函数。因此,应尽可能避免。

    【讨论】:

      【解决方案3】:

      接受挑战 -- 原始标签的 C 版本

      #include <stdio.h>
      #include <string.h>
      int main(int argc, char **argv) {
          if (strcmp(*argv, "stop")) {
              char *in = malloc(99);       // assume it worked
              fgets(in, 99, stdin);        // assume it worked
              *(in+strcspn(in, "\n")) = 0; // remove trailing ENTER
              main(argc + 1, &in);         // memory leak
          } else {
              printf("Stopped after %d entries.\n", argc - 1);
          }
      }
      

      查看在 ideone 运行的代码:https://ideone.com/Slx4g9

      【讨论】:

      • 你不能自己打电话给mainmain 可能不是递归的(至少在 C++ 中不是)
      • @Ayxan:在 C 中允许调用 main()
      • 我认为您至少应该在答案中注明,因为该问题已标记为 C++
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2019-09-13
      • 1970-01-01
      • 2020-01-31
      • 2011-12-05
      • 2018-04-22
      相关资源
      最近更新 更多