|
|
Управление потоком
3.8. Оператор CONTINUE
Оператор continue родственен оператору break, но используется реже; он приводит к началу следующей итерации охватывающего цикла ( for, while, do ). В циклах while и do это означает непосредственный переход к выполнению проверочной части; в цикле for управление передается на шаг реинициализации. (оператор continue применяется только в циклах, но не в переключателях. оператор continue внутри переключателя внутри цикла вызывает выполнение следующей итерации цикла).
В качестве примера приведем фрагмент, который обрабатывает только положительные элементы массива а; отрицательные значения пропускаются.
for (i = 0; i < n; i++) {
if (a[i] < 0) /* skip negative elements */
continue;
... /* do positive elements */
}оператор continue часто используется, когда последующая часть цикла оказывается слишком сложной, так что рассмотрение условия, обратного проверяемому, приводит к слишком глубокому уровню вложенности программы.
Упражнение 3-6
Напишите программу копирования ввода на вывод, с тем исключением, что из каждой группы последовательных одинаковых строк выводится только одна. (Это простой вариант утилиты uniq систем UNIX).
Оператор GOTO и метки
В языке "C" предусмотрен и оператор goto, которым бесконечно злоупотребляют, и метки для ветвления. С формальной точки зрения оператор goto никогда не является необходимым, и на практике почти всегда можно обойтись без него. Мы не использовали goto в этом курсе.
Тем не менее, мы укажем несколько ситуаций, где оператор goto может найти свое место. Наиболее характерным является его использование тогда, когда нужно прервать выполнение в некоторой глубоко вложенной структуре, например, выйти сразу из двух циклов. Здесь нельзя непосредственно использовать оператор break, так как он прерывает только самый внутренний цикл. Поэтому:
for ( ... )
for ( ... ) {
...
if (disaster)
goto error;
}
...
error:
clean up the messЕсли программа обработки ошибок нетривиальна и ошибки могут возникать в нескольких местах, то такая организация оказывается удобной. Метка имеет такую же форму, что и имя переменной, и за ней всегда следует двоеточие. Метка может быть приписана к любому оператору той же функции, в которой находится оператор goto.
В качестве другого примера рассмотрим задачу нахождения первого отрицательного элемента в двумерном массиве. (Многомерные массивы рассматриваются в лекции "лекции 5" ). Вот одна из возможностей:
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
if (v[i][j] < 0)
goto found;
/* didn't find */
...
found:
/* found one at position i, j */
...Программа, использующая оператор goto, всегда может быть написана без него, хотя, возможно, за счет повторения некоторых проверок и введения дополнительных переменных. Например, программа поиска в массиве примет вид:
found = 0;
for (i = 0; i < n && !found; i++)
for (j = 0; j < m && !found; j++)
found = v[i][j] < 0;
if (found)
/* it was at i-1, j-1 */
...
else
/* not found */
...Хотя мы не являемся в этом вопросе догматиками, нам все же кажется, что если и нужно использовать оператор goto, то весьма умеренно.
