【问题标题】:Is for ({statements;}; condition; {statements;}) legal C?for ({statements;}; condition; {statements;}) 合法吗?
【发布时间】:2011-04-20 14:28:25
【问题描述】:

尽管风格不好,但在 C 语言中,在括号内有一个带大括号的 for 循环是否合法?像这样:

char *a = "a ";
char *b = "b ";

for ( { int aComesFirst = 1;
        char *first = a;
        char *second = b;
      };
      aComesFirst >= 0;
      { aComesFirst--;
        swap(first, second);
      } )
{
  printf("%s%s\n", first, second);
}

如果有可能,我应该在第一个右大括号后加一个分号,还是添加一个空语句?

我确实意识到,将 char* 声明移到 for 循环之外,将 swap 声明移到循环内部的末尾在风格上会更好。但是样式不是这个问题的重点,我只想知道是否可以在括号内放置大括号。

【问题讨论】:

标签: c for-loop curly-braces


【解决方案1】:

我之前回答过这个问题……这可以通过添加本地 struct 类型轻松地在 C 或 C++ 中合法化。不过,这通常是一种糟糕的风格。

char *a = "a ";
char *b = "b ";

for ( struct loopy {
        int aComesFirst;
        char *first;
        char *second;
      } l = { 1, a, b }; /* define, initialize structure object */

      l.aComesFirst >= 0; /* loop condition */

      l.aComesFirst--, /* loop advance */
      swap(l.first, l.second)
    )
{
  printf("%s%s\n", l.first, l.second);
}

【讨论】:

  • struct loopy 啊! +1 喜欢这个标签; -1 啊啊啊啊;结果+0
  • ++ 用于破解循环进入实际工作;我的问题的唯一直接答案。是的,这和喇叭裤一样时尚。
  • 可能有编译器允许您省略loopyl 来声明匿名类型的匿名对象,因此您可以假装它不存在。
  • 只有当 swap() 是一个表达式(例如,一个非 void 函数,或展开返回一个值的宏)时,上述代码才会编译。
  • @JeffLearman for的第三部分可能是void
【解决方案2】:

您是否将gcc 与语句表达式一起使用? http://tigcc.ticalc.org/doc/gnuexts.html#SEC63 也许这将使这种类型的代码工作。除了(int i = { stmts; }; { stmts; bool}; { ... })

【讨论】:

  • ++ 感谢您向我展示语句表达式扩展。
【解决方案3】:

不,这是不合法的。如果它是合法的,那么代码无论如何都不会工作,因为 c 具有块级范围,因此您将无法访问大括号中定义的变量。

【讨论】:

    【解决方案4】:

    标准说 (6.8.5.3/1)

    for (clause-1 ; expr-2 ; expr-3 ) 语句

    我很确定expr-2expr-3 都不能被不是表达式的东西替换(块不是表达式),我也很确定clause-1不能用语句代替。

    【讨论】:

    • +1 用于相关引用并反击谁是反对票的白痴。
    【解决方案5】:

    这是不合法的,但这是:

    for(i = 0, j = 10; i < 10; i++, j--)
    {
      // ..
    }
    

    见:the comma operator

    【讨论】:

    • ++ 用于“逗号运算符”的链接。我不知道逗号是一流且非常有用的运算符。
    【解决方案6】:

    不,这是不合法的,但您可以使用逗号来达到一半:

    for (int a = 1, b = 2; a < 10; ++a, ++b)
    

    你不能声明多个不同类型的变量,你不能在最后一位使用控制结构,但大多数时候已经足够了。

    如果你不知道,这里使用的逗号并不是什么特殊语法只能在for 循环中使用,它是一个通用的operator,可以在任何地方使用来计算左操作数,然后是右操作数,并返回右表达式的结果,即a, b == ba, b, c == c等。

    【讨论】:

    • 谢谢!如果它仍然是最好的,我会在几分钟内接受你的回答。
    • ...坦率地说,等效的while 结构无论如何都会更清晰。如果您决定限制范围,只需在初始化代码-n-while-loop 周围使用一个独立的{} 块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 2011-02-12
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多