在C++中为什么我不能像这样编写for()循环:for(int i = 1,double i2 = 0;

Jon*_*han 21 c++ loops

或者,"在for循环中声明多个变量是禁止的"?

我的原始代码是

 for( int i = 1, int i2 = 1; 
      i2 < mid;
      i++, i2 = i * i ) {
Run Code Online (Sandbox Code Playgroud)

我想循环通过第一个这么多的正方形,并且想要数字和它的正方形,并且停止条件取决于正方形.这段代码似乎是意图的最干净的表达,但它无效.我可以想到十几种解决这个问题的方法,所以我不是在寻找最好的选择,而是为了更深入地理解为什么这是无效的.一点语言律师,如果你愿意的话.

我已经足够记住你必须在函数开始时声明所有变量,所以我很感激

for( int i = 0; ....
Run Code Online (Sandbox Code Playgroud)

句法.阅读它看起来好像你只能在for()语句的第一部分中有一个类型声明.所以你可以做到

for( int i=0, j=0; ...
Run Code Online (Sandbox Code Playgroud)

甚至略有巴洛克风格

for( int i=0, *j=&i; ...
Run Code Online (Sandbox Code Playgroud)

但不是我明智的

for( int i=0, double x=0.0; ...
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么?这是for()的限制吗?或者对逗号列表的限制,比如"逗号列表的第一个元素可以声明一个类型,但不能声明另一个?"下面使用逗号来区分C++的不同语法元素吗?

(一个)

for( int i=0, j=0; ...
Run Code Online (Sandbox Code Playgroud)

(B)

int i = 0, j = 0;
Run Code Online (Sandbox Code Playgroud)

(C)

 int z;
 z = 1, 3, 4;
Run Code Online (Sandbox Code Playgroud)

那里有专家吗?

================================================== ==

根据我得到的好反应,我想我可以提出这个问题:

在for语句中

for( X; Y; Z;) {..... }
Run Code Online (Sandbox Code Playgroud)

什么是X,Y和Z?

我的问题是关于C++,但我没有很好的C++参考.在我的C参考文献中(Harbison and Steele 4th ed,1995),它们都是三个表达式,我的gcc需要C99模式才能用于(int i = 0;

在Stroustrup,第6.3节中,for语句的语法给出为

for(for-init-statement; condition; expression)语句

所以C++有一个特殊的语法语句,专用于for()的第一个子句,我们可以假设它们有一个超出表达式的特殊规则.这听起来有效吗?

Kir*_*sky 20

如果你需要在for循环中使用不同类型的几个变量,那么你可以使用如下结构:

for( struct {int i; long i2;} x = {1, 1}; x.i2 < mid; x.i++, x.i2 = x.i * x.i )
{
  cout << x.i2 << endl;
}
Run Code Online (Sandbox Code Playgroud)

所以这不是限制,只需使用一些不同的语法.

  • 这很酷,很高兴有我的工具包,但我认为在这种情况下它隐藏的不仅仅是有用的.我宁愿维护在for()循环之外声明i和i2的代码.谢谢. (4认同)

bta*_*bta 16

int i = 1, double i2 = 0;不是有效的声明语句,因此不能在for语句中使用它.如果声明不能独立于外for,那么它就不能在for声明中使用.

编辑: 关于您关于逗号运算符的问题,选项'A'和'B'是相同的并且都是有效的.选项'C'也有效,但可能不会达到预期效果. z将被分配1,并且语句34没有实际执行任何操作(您的编译器可能会警告您"无效的语句"并将其优化掉).

更新: 要解决编辑中的问题,以下是C++规范(Sec 6.5)定义的方法for:

for ( for-init-statement condition(opt) ; expression(opt) ) statement
Run Code Online (Sandbox Code Playgroud)

它进一步定义for-init-statementexpression-statementsimple-declaration.这两个conditionexpression是可选的.

for-init-statement可以是任何东西,是一个有效expression-statement(如i = 0;)或simple-declaration(例如int i = 0;).根据规范,该声明int i = 1, double i2 = 0;无效simple-declaration,因此无效for.作为参考,a simple-declaration(在第7节中)被定义为:

attribute-specifier(opt) decl-specifier-seq(opt) init-declarator-list(opt) ;
Run Code Online (Sandbox Code Playgroud)

哪里decl-specifier-seq会像数据类型以及关键字staticexterninit-declarator-list将是一个逗号分隔的声明符及其可选的初始化列表.尝试将多个数据类型放在同一个数据类型中simple-declaration实际上decl-specifier-seq是编译器期望的位置init-declarator-list.看到这个元素不合适会导致编译器将该行视为格式错误.

该规范还指出该for循环相当于:

{
    for-init-statement
    while ( condition ) {
        statement
        expression ;
    }
}
Run Code Online (Sandbox Code Playgroud)

condition如果省略,则默认为"true".考虑这种"扩展"形式可能有助于确定给定语法是否可以与for循环一起使用.

  • 附录:它不是有效的逗号声明,因为逗号声明中的类型必须(每个C语言定义)相同.同样的理由为什么逗号语句`int a = 0,int b = 0;`等同于`int a = 0,b = 5;` - 在最左边继承的所有变量的类型都是从最左边继承的if缺席(或必须是相同的,如果存在). (4认同)
  • 没有"逗号声明"这样的东西.逗号运算符用于生成"逗号表达式",表达式(所有类型)都是语句的一部分.但这不是表达式,逗号不是逗号运算符. (4认同)

Jam*_*ran 13

这实际上是声明声明的限制:

int i=0, j=0, *k=&i;     // legal
int i=0, double x=0.0;   // illegel
Run Code Online (Sandbox Code Playgroud)

所以,基本上,你最后一个问题的答案是:(A)和(B)是一样的.(C)不同.

正如bta指出:

 z = 1,3,4;
Run Code Online (Sandbox Code Playgroud)

是相同的

 z = 1;
Run Code Online (Sandbox Code Playgroud)

但是,这是因为=优先级高于,.如果它写成:

 z = (1,3,4);
Run Code Online (Sandbox Code Playgroud)

然后那将是相同的:

 z = 4;
Run Code Online (Sandbox Code Playgroud)