C++ 循环问题初学者

C++ 循环问题初学者,c++,for-loop,C++,For Loop,[编辑]哎呀,代码中有个错误,现在对这个问题的所有回答似乎都很奇怪,但基本上for循环过去是,例如(i=0;i首先,您的示例代码从0循环到14。但是如果您从0循环到15,自然我必须是16才能结束循环。发生的事情是它变成16,然后您的循环注意到它超出了界限并中断。如果您希望它在15结束,老实说,最简单的方法就是在循环结束后立即递减。您一定错过了什么 在这个循环中,它甚至不会达到15,你需要说ii在上一次检查中增加为16,这不小于15,因此循环以i为16退出。我建议在循环完成后使用除i之外的其他变量

[编辑]哎呀,代码中有个错误,现在对这个问题的所有回答似乎都很奇怪,但基本上for循环过去是,例如(i=0;i首先,您的示例代码从0循环到14。但是如果您从0循环到15,自然我必须是16才能结束循环。发生的事情是它变成16,然后您的循环注意到它超出了界限并中断。如果您希望它在15结束,老实说,最简单的方法就是在循环结束后立即递减。

您一定错过了什么


在这个循环中,它甚至不会达到15,你需要说ii在上一次检查中增加为16,这不小于15,因此循环以i为16退出。

我建议在循环完成后使用除
i
之外的其他变量。使用for循环而不是while循环的标准是你事先知道确切地说,for循环将执行多少次。如果您已经知道这一点,只需将其他变量设置为循环的结束值,并使用它,而不是赋予
i
双重用途

int j = 15;

for(int i=0; i <= j; i++)
{
    someClass.array[i];
}

// continue on using j, which value hasn't changed
intj=15;

对于(int i=0;iSo)-如果要检查16元素数组,通常会执行以下操作:

for(i=0; i<16; i++)
然后它在第二个语句中执行检查:

i < 16 // True here, since 0 < 16
i++
最后,它做了最后的陈述:

i < 16 // True here, since 0 < 16
i++
然后它按顺序重复第二和第三条语句

在最后一次运行之前,i==14,然后它执行i++,将i设置为15,并执行块。最后,它执行i++,设置:

i==16
此时,条件不再为真:

i < 16 // False, since i==16
i<16//False,因为i==16

此时,您的块不会执行,但i仍然设置为16。

for
循环的
相当于以下
while
循环:

i = 0;
while(i < 16) {
    someClass.array[i];

    i++;
} // while
i=0;
而(i<16){
数组[i];
i++;
}//而

i
需要达到16才能正确脱离循环。

知道以下几点可能有用:

for (before; check; after) { body } 
这与:

before 
while(check) { 
  body 
  after 
} 

如果你用这个术语来思考你的for循环,也许你会很容易找到为什么我在退出时是16。

从技术上讲,有一些方法可以编写循环,这样退出循环时,
i
是15,但你不应该这样做:

int i = 0;
while (1) {
    someclass.someMethod(i);
    if (i < 15) {
        i++;
    } else {
        break;
    }
}
inti=0;
而(1){
someclass.someMethod(i);
如果(i<15){
i++;
}否则{
打破
}
}

是的,它能满足你的要求。但是流程很糟糕。

你不能用内置的循环结构来实现这一点,正如蜥蜴比尔所说的,你可能真的不想重用for循环变量

<>但是,如果你真的想做的话,这里有一个方法来做。诀窍是把循环条件放在循环的中间:

int i = 0;
while (true)
{
    someclass.array[i];
    if (i == 15)
        break;
    ++i;
}

这里要理解的关键问题是,对于“i的什么值导致测试成功?”这个问题,有17种不同的答案。我可以在{0,1,…,15}中,或者i的任何值都不会导致测试成功,在本例中,i==16表示。因此,如果我仅限于16个值,则无法回答这个问题

在某些合法的情况下,您不希望超过最后一个有效值。例如,如果您有256个值,并且由于某种原因,您只有一个字节可以计算。或者,正如我最近遇到的情况,您只希望检查数组的每一个第i个元素,而迭代器的最后一次添加将使您远远超出数组的末尾。在这些情况下,循环展开是必要的

但是,对于此问题,使用标志会更干净:

bool flag = false;
for (int i = 0; i < 15; ++i) 
{
    someClass.someMethod(i);

    if (someClass.Test())
    {
        flag = true;
        break;
    }
}
bool标志=false;
对于(int i=0;i<15;++i)
{
someClass.someMethod(i);
if(someClass.Test())
{
flag=true;
打破
}
}

然后就可以清楚地知道测试是否成功了。

如果循环自然终止,而不是中断,
i
将为16。无法避免这一点。如果您希望i最终为15或更少,那么您的代码是完全可以接受的:

int i;
for (i=0; i<16; i++) {
    someClass.someMethod(i);
    if (someClass.Test())
        break;
}
if (i == 16)
    i = 15;
等等

然而,这假设
i
将被用于某个有意义的东西,作为与该循环相关的post条件。我发现这种情况很少发生,人们倾向于在重复使用之前重新初始化它(例如另一个for循环)

此外,您所做的工作使得很难(甚至不可能)将其作为post条件来确定,您的循环是正常终止的,还是因为
someClass.Test()
i==15
返回了true而提前终止的。这意味着使用i来做进一步的决定充满了危险

我的问题是:为什么您认为您需要将
i
保留为15或更少

我在试着做一个for循环 检查16元素数组,使其循环 从0到15。然后使用 后来变了,不过有时候我== 16,这会导致问题 当然可以

您需要检查for循环没有中断的情况,因为此信息决定您想对i执行的任何操作是否有效

有两种方法可以做到这一点。一种是在bool中跟踪它,例如“foundClass”或“testsuccessed”。将其默认为false,然后在中断时将其设置为true。在“if(foundClass){}”块中的函数后面包含i的所有用法


另一种方法是只做你已经做过的事情。尽管你的回退看起来一点也不正确。如果你将i设置为15,你是在对你的代码撒谎,并告诉它someClass.Test()i==15时成功,但这不是真的。避免将值设置为错误的值,这样以后代码就不会出错。最好在代码中稍后对i的实际使用情况进行边界检查。

您的方法似乎存在一些基本缺陷

  • 您不应该在循环范围之外使用索引变量
  • 您应该使用变量或函数来确定循环的限制
  • 最好使用迭代器而不是数字
    int i;
    for (i=0; i<16; i++) {
        someClass.someMethod(i);
        if (someClass.Test())
            break;
    }
    if (i == 16)
        i = 15;
    
    if (i == 16) i = 15;
    i = (i == 16) ? 15 : i;
    i = MAX (15,i); /* where MAX is defined :-) */
    
    for(int i=0; i<17; i++)
    {    
      if(i<16)
      {
         someClass.someMethod(i); 
         if(someClass.Test())   
         {        
           break;    
         }
      }
      else if(i==16)
      {
         i=15;
      }
    }
    
    for(int i = 0; i < myArray.length; ++i){
           myArray[i].somemethod();
    }
    // lastindex = myArray.length-1;