对于 ({语句;}; 条件; {语句;}) 这种写法在 C 语言中是否合法?

5

尽管风格不佳,但是在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);
}

如果可以实现类似的功能,我是否应该在第一个闭括号后加上分号,还是会添加一个空语句?
我确实意识到,在for循环之外将char*声明移动到内部循环的末尾并将swap放到内部循环的末尾在风格上更佳。但风格不是这个问题的重点,我只想知道是否可以在括号内放置大括号。

我理解那个可怕的东西实际上可以编译吗? - amara
不,它并不是。那只是我正在寻找的答案形式的示例。 - AlcubierreDrive
相关:https://dev59.com/FHA75IYBdhLWcg3wVniI - Mechanical snail
6个回答

9

我之前已经回答过这个问题了……在C或C++中,通过添加本地struct类型,可以轻松实现合法性。但这通常是不好的编程风格。

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);
}

1
结构体循环。啊!+1 喜欢这个标签;-1 糟糕透了;结果 +0。 - pmg
++来破解循环并使其正常工作;这是我问题的唯一直接答案。是的,这就像喇叭裤一样时髦。 - AlcubierreDrive
可能有编译器可以让你省略 loopyl 来声明一个匿名类型的匿名对象,这样你就可以假装它不存在。 - Potatoswatter
如果swap()是一个表达式(例如,非void函数或宏展开返回值),则上述代码才能编译。 - Jeff Learman
1
@JeffLearman for 的第三部分可以是 void - Potatoswatter
@Potatoswatter 我并不反对这一点;我反对使用 void 表达式与逗号运算符,这在过去是非法的。显然现在已经合法了,或者至少 gcc 支持它。 - Jeff Learman

7
不,这并不合法,但您可以使用逗号来实现一半的效果:
for (int a = 1, b = 2; a < 10; ++a, ++b)

你不能声明多个不同类型的变量,也不能在最后一位使用控制结构,但大多数情况下这已经足够了。
如果你不知道,那里使用的逗号并不是一些特殊的语法,只能在for循环中使用,它是一个通用的操作符,可以在任何地方使用,评估左操作数,然后是右操作数,并返回右表达式的结果,即a, b == ba, b, c == c等。

谢谢!如果您的答案仍然是最好的,我会在几分钟内接受它。 - AlcubierreDrive
...而且,坦白地说,等价的 while 结构会更清晰。如果你决定要获得有限的作用域,只需在初始化代码和 while 循环周围使用一个独立的 {} 块即可。 - dmckee --- ex-moderator kitten

3
不,这是不合法的。即使它是合法的,代码也无法正常工作,因为C具有块级作用域,所以您将无法访问括号中定义的任何变量。

2

这个是合法的,但那个不合法:

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

请参阅:逗号操作符


++用于“逗号运算符”的链接。我不知道逗号是一个一等的、如此有用的运算符。 - AlcubierreDrive

1

感谢您向我展示了语句表达式扩展。 - AlcubierreDrive

0

标准规定(6.8.5.3/1)

for ( clause-1 ; expr-2 ; expr-3 ) statement

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


+1 给相关引用,并反驳那些莫名其妙的踩票者。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接