【问题标题】:How to construct a compound for loop in C++?如何在 C++ 中构造一个复合 for 循环?
【发布时间】:2014-10-31 23:55:24
【问题描述】:

for 循环的计数器部分(第三部分)是否允许另一个 for 循环?在我尝试优雅地编写代码以生成直角三角形时,我写了这个,但它不会编译:

#include <stdio.h>
int main()
{   
    int i, j, N = 5;
    for (i = 1;
         i <= N; 
         (for (j = 1; j <= i; j++, printf("%c", '0'));), i++)
       printf("\n");
    }
    return 0;
}

【问题讨论】:

  • 您的代码存在问题: 1. ijN 的类型是什么? 2、N的值是多少? 3. 第三边在哪里计算?
  • “C/C++”。没有这样的语言。
  • 这个结构对我来说似乎比优雅更令人困惑。
  • @n.m. Metrowerks 曾经销售用于 C/C++ 语言的编译器,在文件内具有编译模式之间的编译指示切换。尽管发布者不太可能正在使用它,甚至没有意识到它。
  • 我认为没有多少人会考虑在另一个 for 循环的控制部分使用 for 循环特别“优雅”。

标签: c++ c++11 for-loop lambda


【解决方案1】:

不允许只有表达式或声明。

编辑:对不起。我以为您在谈论循环的条件部分。在循环的表达式部分,只允许使用表达式。

您可以使用包含此 for 循环的 lambda 表达式。例如

for ( i = 1;
      i <= N;
      []( int i ) { for ( j = 1; j <= i; j++, printf("%c", '0' ) ); }( i ), i++)

这是一个示范性的例子

#include <iostream>

int main() 
{
    int N = 10;

    for ( int i = 1;
          i < N;
          []( int i ) 
          { 
            for ( int j = 1; j < i; j++, ( std::cout <<  '*' ) ); 
          }( i ), i++ )
    {
        std::cout << std::endl;
    }               

    return 0;
}

输出是

*
**
***
****
*****
******
*******
********

或者您可以在外部循环之外定义 lambda 表达式,以使程序更具可读性。例如

#include <iostream>

int main() 
{
    int N = 10;

    auto inner_loop = []( int i ) 
    { 
        for ( int j = 1; j < i; j++, ( std::cout <<  '*' ) ); 
    };


    for ( int i = 1; i < N; inner_loop( i ), i++ )
    {
        std::cout << std::endl;
    }               

    return 0;
}

考虑到在一般情况下,其他帖子中显示的嵌套循环无法用 lambda 表达式替换循环。例如,外部循环可以包含将跳过内部循环的continue 语句。因此,如果您需要在任何情况下独立于 continue 语句执行内部循环,那么这种使用 lambda 表达式的构造将很有帮助。:)

【讨论】:

  • 这是对 lambdas 的创造性使用,但我希望没有人会真正编写这样的代码......
  • 我会马上给你投票,但 Burr 打败了你,我用他的想法作为我的答案。
  • @Vlad 那么他应该只是反转循环。如果存在这样的算法来强制执行此构造,我会感到惊讶。
  • @Mihai Todor 不可能总是反转循环。
【解决方案2】:

没有必要这样做。因为 for 循环可以很容易地替换为 while 循环,所以 for 循环的每个部分都可以放在另一个地方,在那里可以使用复杂的结构。在您的情况下,您只需将循环更改为以下内容:

for (i = 1; i <= N; i++) {
    printf("\n");
    for (j = 1; j <= i; j++) {
        printf("%c", '0');
    }
}

但是,如果你真的需要放置复杂的动作,你可以使用 gcc 扩展(复合语句):

for (i = 1;
     i <= N; 
     ({for (j = 1; j <= i; j++) putchar('0'); }), i++) {
   printf("\n");
}

【讨论】:

  • 我在寻找复杂的动作,是的!我喜欢你的答案,因为它不像其他答案那样使用lambdas
  • 您对我的编辑进行了编辑吗?请检查代码是否正确。最后的换行符没有显示这是显示此内容的ideone
  • for 的第三个块在每个循环之后执行。这就是为什么上次没有调用printf()
【解决方案3】:

for() 循环的计数器部分,允许使用表达式,但不允许使用语句。
C/C++ 中的每一行 for() 都会形成一个新语句(它不是表达式)。

但是,如果需要,您可以嵌套多个 for() 循环。
例如,由于您希望在计数器部分中创建一个新循环,这意味着您需要在主 for() 循环的末尾执行一个循环。

这是方案:

  for (int i = 0; i < i_max; i++) {
      // stuff...


      for (int j = 0; j < j_max; j++) {
            // stuff..
      }  
  }

【讨论】:

    【解决方案4】:

    您不能这样做,因为for 的条件和增量部分只能包含表达式。不过,for 循环是一个迭代语句

    像理智的程序员那样简单地嵌套循环:

    #include <stdio.h>
    int main()
    {   
        int N = 5;
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= i; j++)
                 printf("0");
            printf("\n");
        }
    }
    

    不过,如果你感觉不舒服,你可以使用 lambda:

    #include <stdio.h>
    int main()
    {   
        int N = 5;
        for (
            int i = 1;
            i <= N; 
            [=](){ for (int j = 1; j <= i; j++) printf("0"); }(), printf("\n"), i++
        ) ;
    }
    

    【讨论】:

    • C++11,如果需要的话。但这现在应该是默认设置了。
    • #jrok,C++11 不是我的 g++ 的默认值,无论如何,我什至不知道我必须编译为 C++ ...这就是 gcc 给出错误的原因
    【解决方案5】:

    最短可能的解决方案:

    main(i){for(i=1;i<11;printf("%0*d\n",i++,0));}
    

    输出:

    0
    00
    000
    0000
    00000
    000000
    0000000
    00000000
    000000000
    0000000000
    

    LIVE DEMO

    【讨论】:

    • 很高兴知道。您实际上可以将 \n 移动到 printf 语句中,并使其更小。
    • 这个更短:int N=10; for (int i=1; i&lt;=N; printf("%0*d\n", i++, 0)) ;
    • @pablo1977:现在怎么样?
    • @PiotrS.: 删除未使用的j :)
    • 这是 C89 中的 Code Golfing,这种语言现在应该已经死了(但你可以感谢 Microsoft 让它保持活力,即使 GCC 也默认使用 C89 模式编译)。不过,这样的代码在 Code Golf 之外没有立足之地。
    【解决方案6】:

    优雅伴随着清晰。 当我想创建一个字符串时,我构造了一个名为std::string 的C++ 对象。

    #include <iostream>
    #include <string>
    
    int main()
    {
      char c = '0';
      const int n = 5;
    
      for (int i = 1; i <= n; ++i)
      {
        std::cout << std::string(i, c) << '\n';
      }
    }
    

    因此在这种特殊情况下不需要嵌套的for-loop。 否则,按照其他答案的建议,将for-statement 放在外循环的主体中。

    【讨论】:

      【解决方案7】:

      Michael Burr 致敬以获取使用lambda 的建议。感谢评论员要求我使用putchar()

      #include <stdio.h>
      
      int main() {
        int N;
        scanf("%d", &N);
      
        for (int i = 0; i < N; i++, [i] {
               for (int j = 1; j <= i; j++, putchar('0'))
                 ;
             }(), printf("\n"))
          ;
      
        return 0;
      }
      

      LIVE DEMO

      【讨论】:

        【解决方案8】:

        我认为我们应该避免混淆代码,除非我们因使代码复杂而获得报酬。

        【讨论】:

          猜你喜欢
          • 2018-10-12
          • 2013-09-10
          • 2016-05-03
          • 2020-03-27
          • 2017-09-30
          • 1970-01-01
          • 2016-01-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多