为什么变量声明作为for循环的条件运行良好?

时间:2016-10-12 07:25:33

标签: c++ for-loop language-lawyer declaration

int i = 5等声明的返回值/类型是什么?

为什么不编译此代码:

#include <iostream>

void foo(void) {
    std::cout << "Hello";
}

int main()
{
    int i = 0;
    for(foo(); (int i = 5)==5 ; ++i)std::cout << i; 
}

虽然这样做

#include <iostream>

void foo(void) {
    std::cout << "Hello";
}

int main()
{
    int i = 0;
    for(foo(); int i = 5; ++i)std::cout << i; 
}

4 个答案:

答案 0 :(得分:25)

for循环要求条件是表达式或声明:

  

条件 - 要么

     
      
  • 一个上下文可转换为bool的表达式。在每次迭代之前计算此表达式,如果它产生false,   循环退出。
  •   
  • 使用brace-or-equals初始值设定项声明单个变量。在每次迭代之前评估初始化程序,并且   如果声明的变量的值转换为false,则循环为   退出。
  •   

第一个代码不起作用,因为(int i = 5)==5根本不是有效的expression。 (它也不是声明。)operator==的操作数也应该是一个表达式,但int i = 5是一个声明,而不是表达式。

第二个代码有效,因为int i = 5匹配 condition 的第二个有效案例;使用等于初始值设定项的单个变量的声明。 i的值将转换为bool以进行判断;总是5,然后导致无限循环。

答案 1 :(得分:2)

此代码符合以下条件:

for (foo(); int i = 5 == 5; ++i)

检查是否5 == 5并将i设置为此布尔结果(即1) - &gt;无限循环

for(foo(); int i = 5; ++i)

这只是在设置为5后检查i的值,因此......转换为bool时,它总是true - &gt;无限循环

答案 2 :(得分:0)

C编程语言中for循环的语法如下:

for ( init; condition; increment ) {
   statement(s);
}
  

首先执行init步骤,并且只执行一次。你可以使用init来   声明并初始化任何循环控制变量。

     

接下来,评估条件。如果是真的,循环体   被执行。如果为false,则循环体不执行   控制流跳转到'for'之后的下一个语句   循环。

     

执行'for'循环后,控制流会跳转   备份到增量语句。这个陈述允许你   更新任何循环控制变量。

考虑您的第一个计划声明:

 for(foo(); (int i = 5)==5 ; ++i)std::cout << i;

以上陈述将给您以下错误(使用GCC编译):

    error: expected primary-expression before ‘int’
        for(foo(); (int i = 5) == 5; ++i)std::cout << i; 

    error: expected ‘)’ before ‘int’

C中的主要表达可以是以下任何一种:

a name (of a variable or a function)
a typename
an operator
a keyword like if or while
the list goes on and on ...

此错误是由于语句(int i = 5) == 5不是有效表达式而编译器试图以其他方式解释。但是,第二个程序可以用int i = 5声明作为condition检入for循环的有效条件,因为此声明的值为initializer 5在你的第二个程序中。但是,第二个程序将是一个无限循环,并将继续打印5到终端。但是,如果初始化程序的值是0,那么条件在第一次检查时会变为false并且{{ 1}}循环体不会被执行一次。

答案 3 :(得分:-3)

虽然根据for循环的语法,初始化语句应首先出现,然后检查然后更新,因为你的检查语句是第二个例子中的初始化,我被初始化为5作为一部分检查和for循环继续。

在初始化中使用foo()调用对于for循环没有任何影响,因为返回类型为void,如果你用0代替foo(),你将得到相同的输出 < / p>

现在让我们考虑第一个例子,你的检查语句是一个初始化,就像第二个例子一样,如果你没有那些括号,它会起作用。 由于声明没有返回任何值,(int i = 5)不会返回任何值,因此无法与&#34;中的5进行比较。 == 5&#34;。

但是,如果您尝试&#34; for(foo(); int i = 5 == 5; ++ i)...&#34; ,则检查语句会编译与 int i =(5 == 5)相同。由于5 == 5为真,它返回值1,然后将其初始化为i的值。因此输出是11111 ......

TL; DR:由于声明不返回任何值,(int i = 5)不会返回任何值,因此无法与5 in&#34; == 5&#34;如第一个例子中那样

问题解决了。