[编辑]哎呀代码中有一个错误,现在对问题的所有回答看起来很古怪,但基本上是for循环,对于(i = 0; i <!> lt; 15; i ++ )。我还编辑了以使问题更清楚。[/ EDIT]

我正在尝试创建一个for循环,它检查一个16个元素的数组,所以它从0到15循环。然后我再使用i变量,但有时我= = 16,这会导致问题超出界限

我有一个解决方案,但它看起来并不优雅,这让我觉得我错过了一些东西。我尝试过while循环,但是我永远不能从0到15获得任何循环,并且永远不会以大于15的值结束。

有没有办法让循环去检查数组的所有16个元素,而在循环结束时从不大于15?

int i;

for(i=0; i<16; i++)
{
    someClass.someMethod(i);

    if(someClass.Test())
    {
        break;
    }
}



if (i == 16)
{
    i = 15;
}
有帮助吗?

解决方案

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

int j = 15;

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

// continue on using j, which value hasn't changed

其他提示

对于初学者来说,你的示例代码从0到14循环。但是如果你从0循环到15,那么在循环结束之前我自然必须是16 。它会变成16,然后你的循环会注意到它已经超出范围并且爆发了。如果你希望它在15结束,老实说,最简单的事情就是在循环结束后减少。

i在最后一次检查时递增为16,这不小于15,所以循环退出时i为16。

知道这一点可能很有用:

for (before; check; after) { body } 

它与:

相同
before 
while(check) { 
  body 
  after 
} 

如果你在那个词中想到你的for循环,也许你会很容易地发现为什么我在出口处是16岁。

您的方法似乎存在一些根本性缺陷。

  1. 您不应该在循环范围之外使用索引变量。
  2. 您应该使用变量或函数来确定循环的限制。
  3. 最好使用迭代器而不是数字索引。
  4. 通用算法可以消除对循环的需求。
  5. 只需我0.02美元。

所以 - 如果你正在检查16个元素数组,通常你会这样做:

for(i=0; i<16; i++)

如何工作,是从第一个三个语句开始:

i=0

然后它会在第二个声明中进行检查:

i < 16 // True here, since 0 < 16

这发生在你的循环之前。然后它使用该集运行循环块:

someClass.array[i]; //0

最后,它做了最后的陈述:

i++

然后它按顺序重复第二和第三个陈述。

在上次运行之前,i == 14,然后它执行i ++,将i设置为15,然后执行该块。最后,它确实是i ++,设置:

i==16

此时,条件不再成立:

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

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

你一定错过了什么。

在这个循环中,它甚至不会达到15,你需要说我<!> lt; = 15,一旦i = 14,它就会运行一次并保释。

for循环等效于以下while循环:

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

    i++;
} // while

i需要达到16才能正确退出循环。

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

int i = 0;
while (1) {
    someclass.someMethod(i);
    if (i < 15) {
        i++;
    } else {
        break;
    }
}

是的,它符合您的要求。但是流程太可怕了。

你无法通过内置的循环结构实现这一点,正如Bill The Lizard所说,你可能并不真的想重用for循环变量。

但是,如果你真的想,这是一种方法。诀窍是将循环条件放在循环的中间:

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

这里要理解的关键问题是问题有17个不同的答案<!>“i; i的值是什么导致测试成功?<!>”。我可以在{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;
    }
}

然后很清楚测试是否成功。

如果你的循环终止,而不是休息,i 为16。没有办法避免这种情况。如果您想要的最终结果为15或更少,那么您的代码是完全可以接受的:

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

在循环体之后将someClass.Test()从16改为15的任何东西:

if (i == 16) i = 15;
i = (i == 16) ? 15 : i;
i = MAX (15,i); /* where MAX is defined :-) */

等等。

然而,假设i == 15将用于有意义的事情作为关于该循环的后置条件。我发现这种情况很少发生,人们倾向于在重新使用之前重新初始化它(比如另一个循环)。

此外,你正在做的事情很难(甚至不可能)找出一个后置条件,你的循环正常终止或是否过早终止,因为<=>为<=>返回true。这意味着使用我做出进一步的决定充满了危险。

我的问题是:为什么你认为你需要将<=>留在15或更少?

  

我正在尝试制作一个for循环   检查一个16元素数组,因此它循环   从0到15.然后我用i   变量稍后,但有时我==   16,通过外出导致问题   边界。

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

有几种方法可以做到这一点。一种是在bool中跟踪它,例如<!> quot; foundClass <!> quot;或<!> quot; testSucceeded <!> quot;。将其默认为false,然后在休息时将其设置为true。稍后在函数<!>中使用i; if(foundClass){} <!> quot;块。

另一个是做你做过的事。虽然你的后备看起来并不正确。如果你将i设置为15,你就会对你的代码撒谎并告诉它someClass.Test()成功为i == 15,这不是真的。避免将值设置为错误的值,以便稍后您的代码不会出错。最好在代码中稍后对i的实际使用情况进行边界检查。

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

如果你说你有一个包含16个元素的数组,你不必定义它,使用数组来获取那些信息(不要重复信息)

之后,如果你想再次获取最后一个索引,请使用数组来获取该信息。

for(int i = 0; i < myArray.length; ++i){
       myArray[i].somemethod();
}
// lastindex = myArray.length-1;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top