Другая причина полного пересмотра конструкции for
заключается в том, что ее область действия препятствует доступу к контролируемым переменным после завершения цикла. Значение (я) переменной (ей) переменной (ей) в цикле может быть полезно по ряду причин (например, чтобы отличить успех от неудачи в поиске), которые в противном случае потребовали бы дополнительных переменных для сохранения этой информации после выхода из области. Вот небольшой пример, который ищет квадратный массив с именем a
для значения target
(при условии, что SIZE
не равен нулю, в противном случае поиск не требуется!):
int i = 0;
int j = 0;
while (i < SIZE && a[i][j] != target) { // still in array but not at target
if (SIZE <= ++j) { // fallen off the end of a row
j = 0;
++i;
}
}
В следующем коде можно использовать i < SIZE
, чтобы определить, было ли найдено нужное значение.
Еще одним преимуществом вышеперечисленного является гибкость. Предположим, мы теперь проинформированы о том, что значения в строках a
являются восходящими, поэтому остаток строки не имеет значения, если встречается значение, большее target
. Легко узнать, что именно нужно сделать, и где это сделать. Поскольку эта новая информация позволяет нам отказаться от текущей строки, затрагивается только внутреннее решение, которое становится следующим:
if (target < a[i][j] || SIZE <= ++j) { // can't be in row or fallen off end
...
Я вижу больше новых языков (особенно функционально-ориентированных), отказавшихся от старой конструкции "подсчета" цикла; это, вероятно, хорошо, так как это побуждает нас думать о значении цикла, а не просто считать.