Новичок для проблемы петли - PullRequest
0 голосов
/ 29 апреля 2009

[РЕДАКТИРОВАТЬ] К сожалению, в коде произошла ошибка, и теперь все ответы на вопрос кажутся странными, но в основном это был цикл for (i = 0; i <15; i ++). Я также отредактировал, чтобы сделать вопрос более понятным. [/ EDIT] </p>

Я пытаюсь создать цикл for, который проверяет массив из 16 элементов, поэтому он циклично переходит от 0 до 15. Затем я использую переменную i позже, однако иногда 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;
}

Ответы [ 15 ]

6 голосов
/ 29 апреля 2009

Я предлагаю использовать другую переменную, отличную от 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
3 голосов
/ 29 апреля 2009

Кажется, в вашем подходе есть некоторые фундаментальные недостатки.

  1. Вы не должны использовать индексную переменную вне области цикла.
  2. Вы должны использовать переменную или функцию для определения предела цикла.
  3. Было бы лучше использовать итераторы вместо числовых индексов.
  4. Универсальные алгоритмы могут устранить необходимость в циклах.

Только мои 0,02 доллара.

3 голосов
/ 29 апреля 2009

Может быть, полезно знать, что:

for (before; check; after) { body } 

это то же самое, что и

before 
while(check) { 
  body 
  after 
} 

Если вы подумали над циклом for в этом термине, возможно, вы легко поймете, почему у меня на выходе 16.

3 голосов
/ 29 апреля 2009

i увеличивается при последней проверке до 16, что не менее 15, поэтому цикл завершается с i, равным 16.

3 голосов
/ 29 апреля 2009

Хорошо, для начала, ваш пример кода будет иметь циклы от 0 до 14. Но если вы делаете цикл от 0 до 15, естественно, я должен быть 16 , прежде чем цикл может закончиться. То, что происходит, становится 16, ТОГДА ваша петля замечает, что она выходит за пределы и выходит из строя. Если вы хотите, чтобы он заканчивался в 15, честно говоря, самое простое, что нужно сделать, это просто уменьшить значение сразу после окончания цикла.

1 голос
/ 29 апреля 2009

Итак - если вы проверяете массив из 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.

0 голосов
/ 16 ноября 2010

если вы говорите, что у вас есть массив с 16 элементами, вам не нужно это определять, используйте массив для получения этой информации (НЕ ДУБЛИРУЙТЕ ИНФОРМАЦИЮ)

впоследствии, если вы хотите получить последний индекс снова, используйте массив для получения этой информации.

for(int i = 0; i < myArray.length; ++i){
       myArray[i].somemethod();
}
// lastindex = myArray.length-1;
0 голосов
/ 01 мая 2009
for(int i=0; i<17; i++)
{    
  if(i<16)
  {
     someClass.someMethod(i); 
     if(someClass.Test())   
     {        
       break;    
     }
  }
  else if(i==16)
  {
     i=15;
  }
}
0 голосов
/ 29 апреля 2009

Я пытаюсь сделать цикл проверяет массив из 16 элементов, поэтому он зацикливается от 0 до 15. Затем я использую переменная позже, однако иногда я == 16, что вызывает проблемы, будучи вне границ.

Вам нужно проверить случай, когда ваш цикл for не прерывался, потому что эта информация определяет, действительно ли то, что вы хотели сделать с i, действительно.

Есть несколько способов сделать это. Одним из них является отслеживание этого в bool, таком как «foundClass» или «testSucceeded». По умолчанию это значение false, а затем установите его на true во время перерыва. Заключите любое использование i позже в функцию в блоках "if (foundClass) {}".

Другое - просто делать то, что ты сделал. Хотя ваш запасной вариант выглядит совсем не так. Если вы устанавливаете i в 15, вы врете своему коду и говорите ему, что someClass.Test () успешно для i == 15, что не соответствует действительности. Избегайте установки значения на что-то неправильное, просто чтобы ваш код не ошибался позже. Гораздо лучше поместить проверки границ вокруг фактического использования i позже в коде.

0 голосов
/ 29 апреля 2009

Если ваш цикл заканчивается естественным путем, а не с перерывом, i будет равным 16. Нет способа избежать этого. Ваш код является вполне приемлемым, если вы хотите, чтобы я в конечном итоге был 15 или менее:

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

Все, что изменится i с 16 на 15 после тела цикла, будет:

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

и т. Д.

Однако это предполагает, что i будет использоваться для чего-то значимого в качестве постусловия по отношению к этому циклу. Я нахожу, что это редко случается, люди склонны повторно инициализировать его перед повторным использованием (например, другое для цикла).

Кроме того, то, что вы делаете, делает очень трудным (даже невозможным) определение в качестве постусловия, завершается ли ваш цикл нормально или преждевременно завершен, потому что someClass.Test() вернул true для i == 15. Это означает, что использование i для принятия дальнейшего решения чревато опасностью.

Мой вопрос: Почему Как вы думаете, вам нужно оставить i как 15 или меньше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...