3.6. Цикл DO - WHILE
Как уже отмечалось в главе 1, циклы WHILE и FOR обладают тем приятным свойством, что в них проверка окончания осуществляется в начале, а не в конце цикла. Третий оператор цикла языка “C”, DO-WHILE, проверяет условие окончания в конце, после каждого прохода через тело цикла; тело цикла всегда выполняется по крайней мере один раз. Синтаксис этого оператора имеет вид:
DO оператор WHILE (выражение) Сначала выполняется оператор, затем вычисляется выражение.
Если оно истинно, то оператор выполняется снова и т.д. Если выражение становится ложным, цикл заканчивается.
Как и можно было ожидать, цикл DO-WHILE используется значительно реже, чем WHILE и FOR, составляя примерно пять процентов от всех циклов. Тем не менее, иногда он оказывается полезным, как, например, в следующей функции ITOA, которая преобразует число в символьную строку (обратная функции ATOI). Эта задача оказывается несколько более сложной, чем может показаться сначала. Дело в том, что простые методы выделения цифр генерируют их в неправильном порядке. Мы предпочли получить строку в обратном порядке, а затем обратить ее.
ITOA(N,S) /*CONVERT N TO CHARACTERS IN S */ CHAR S[];
INT N;
{ INT I, SIGN;
IF ((SIGN = N) < 0) /* RECORD SIGN */
N = -N; /* MAKE N POSITIVE */ I = 0;
DO { /* GENERATE DIGITS IN REVERSE ORDER */ S[I++] = N % 10 + '0';/* GET NEXT DIGIT */
} WHILE ((N /=10) > 0); /* DELETE IT */
IF (SIGN < 0)
S[I++] = '-'
S[I] = '';
REVERSE(S);
}
Цикл DO-WHILE здесь необходим, или по крайней мере удобен,
поскольку, каково бы ни было значение N, массив S должен со держать хотя бы один символ. Мы заключили в фигурные скобки
один оператор, составляющий тело DO-WHILе, хотя это и не
обязательно, для того, чтобы торопливый читатель не принял
часть WHILE за начало оператора цикла WHILE.
Упражнение 3-3.
------------- При представлении чисел в двоичном дополнительном коде
наш вариант ITOA не справляется с наибольшим отрицательным
числом, т.е. Со значением N рAвным -2 в степени м-1, где м размер слова. объясните почему. Измените программу так, что бы она правильно печатала это значение на любой машине.
Упражнение 3-4.
------------- Напишите аналогичную функцию ITOB(N,S), которая преобра зует целое без знака N в его двоичное символьное представле ние в S. Запрограммируйте функцию ITOH, которая преобразует
целое в шестнадцатеричное представление.
Упражнение 3-5.
-------------- Напишите вариант Iтоа, который имеет три, а не два аргу мента. Третий аргумент - минимальная ширина поля; преобразо ванное число должно, если это необходимо, дополняться слева
пробелами, так чтобы оно имело достаточную ширину.
3.7. Оператор BREAK Иногда бывает удобным иметь возможность управлять выходом из цикла иначе, чем проверкой условия в начале или в конце. Оператор BRеак позволяет выйти из операторов FOR, WHILE и DO до окончания цикла точно так же, как и из переключателя. Оператор BRеак приводит к немедленному выходу из самого внутреннего охватывающего его цикла (или переключателя).
Следующая программа удаляет хвостовые пробелы и табуляции из конца каждой строки файла ввода. Она использует оператор BRеак для выхода из цикла, когда найден крайний правый отличный от пробела и табуляции символ.
#DEFINE MAXLINE 1000 MAIN() /* REMOVE TRAILING BLANKS AND TABS */
{ INT N;
CHAR LINE[MAXLINE];
WHILE ((N = GETLINE(LINE,MAXLINE)) > 0) { WHILE (--N >= 0) IF (LINE[N] != ' ' && LINE[N] != 'T' && LINE[N] != 'N') BREAK;
LINE[N+1] = '';
PRINTF(“%SN”,LINE);
}
}
Функция GETLINE возвращает длину строки. Внутренний цикл начинается с последнего символа LINE (напомним, что—N уменьшает N до использования его значения) и движется в обратном направлении в поиске первого символа , который отличен от пробела, табуляции или новой строки. Цикл прерывается, когда либо найден такой символ, либо N становится отрицательным (т.е., когда просмотрена вся строка). Советуем вам убедиться, что такое поведение правильно и в том случае, когда строка состоит только из символов пустых промежутков.
В качестве альтернативы к BRеак можно ввести проверку в сам цикл: WHILE ((N = GETLINE(LINE,MAXLINE)) > 0) { WHILE (--N >= 0 && (LINE[N] == ' ' !! LINE[N] == 'T' !! LINE[N] == 'N'))
;
...
}
Это уступает предыдущему варианту, так как проверка становится труднее для понимания. Проверок, которые требуют переплетения &&, !!, ! И круглых скобок, по возможности следует избегать.
3.8. Оператор CONTINUE
Оператор CONTINUE родственен оператору BRеак, но используется реже; он приводит к началу следующей итерации охватывающего цикла (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).
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев