Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мова програмування С.docx
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
489.95 Кб
Скачать

3.6 Цикли do-while

Як ми вже обговорили в Розділі 1, цикли while і for перевіряють умову завершення циклу на самому початку. На противагу першим двом, do-while перевіряє умову вкінці, після проходження кожного кроку у корпусі цикла; корпус завжди виконується щонайменше один раз.

Синтаксис do наступний:

do

твердження

while (вираз)

Тож, спочатку буде виконано твердження, і лиш потім оцінено вираз. Якщо умова справджується, твердження виконується ще раз, і так далі... Коли вираз виявиться хибним, цикл буде перервано. За винятком змісту перевірки, do-while еквівалентний repeat-untill у Pascal.

Досвід свідчить, що do-while використовується значно рідше ніж while або for. Тим не менше, час од часу він - корисний, як у наступній функції itoa, яка перетворює число у символьний ланцюжок (функція, протилежна atoi). Ця задача трохи складніша, ніж може видатись з першого погляду, оскільки легкі способи генерації чисел розставляють ці числа в невірному порядку. Ми вирішили відтворити ланцюжок в оберненому порядку, а потім розвернути його.

/* itoa: перетворює n у знаки s */

void itoa(int n, char s[])

{

int i, sign;

if ((sign = n) < 0) /* виявити знак */

n = -n; /* перетворити n на додатнє */

i = 0;

do { /* генерувати цифри в зворотньому порядку */

s[i++] = n % 10 + '0'; /* одержати наступну цифру */

} while ((n /= 10) > 0); /* видалити її */

if (sign < 0)

s[i++] = '-';

s[i] = '\0';

reverse(s);

}

Цей do-while — потрібний, або щонайменше зручний, оскільки принаймні один знак повинен потрапити в масив s, навіть якщо n буде нульовим. Ми використали фігурні дужки навколо єдиного твердження з якого складається корпус do-while (хоча вони не обов'язкові) для того, щоб поспішний читач не сприйняв while-частину за початок циклу while.

Вправа 3-4. У двійковому взаємодоповнюючому представленні чисел, наша версія itoa не справляється з найбільшим від'ємним числом, тобто значенням n що дорівнює -(2величина слова-1). Поясніть чому ні. Поміняйте програму, щоб вона виводила це число правильно, незалежно від машини на якій вона виконується.

Вправа 3-5. Напишіть функцію itob(n,s,b) яка переводить десяткове n у b систему числення і зберігає це у рядку s. Так, наприклад, itob(n,s,16) сформує n як шістнадцяткове число, збережене в ланцюку s.

Вправа 3-6. Напишіть версію itoa, яка братиме три аргументи замість двох. Третім аргументом буде мінімальна ширина поля. Конвертоване число буде доповнюватись пробілами зліва у разі потреби, щоб добитися певної ширини.

3.7 Break і continue

Часом зручно мати можливість вийти з циклу інакше, ніж шляхом тестування умови зверху або внизу. Саме твердження break забезпечує передчасний вихід із for, while або do-циклів, так само як і у випадку зі switch. Вираз break змушує найближчий цикл або switch, у якому він знаходиться, завершитись негайно.

Наступна функція, яку ми назвали trim, вилучає кінцеві пробіли, кроки табуляції та символи нового рядка в ланцюжкові, використовуючи break для виходу з циклу, як тільки знайдено перший знак, що не є ні пробілом, ні знаком табуляції, ні символом нового рядка.

/* trim: видаляє хвостові пробіли, табуляцію і символи *

* нового рядка */

int trim(char s[])

{

int n;

for (n = strlen(s)-1; n >= 0; n--)

if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')

break;

s[n+1] = '\0';

return n;

}

strlen повертає довжину ланцюжка. Цикл for починає з кінця ланцюжка і перевіряє у зворотньому напрямку, шукаючи перший знак, що не являється пробілом, табуляцією або символом нового рядка. Цикл перерветься, коли один з них буде знайдено або, коли n стане від'ємним (тобто, коли весь ланцюжок пройде перевірку). Вам слід перевірити, чи цей цикл веде себе правильно, навіть коли ланцюжок порожній або містить тільки символи пропуску.

Оператор continue — споріднений з break, але не так часто використовується. Він зумовлює початок наступної ітерації оточуючого циклу for, while або do. У випадку while і do, тестова частина виконується негайно; у випадку for, керування передається етапові приросту. Твердження continue вживається тільки з циклами, а не switch-конструкціями. Операторcontinue всередині switch, розміщеному в циклі, спричинить наступну ітерацію циклу.

Як приклад, наступний фрагмент коду обробляє тільки додатні елементи масиву a, пропускаючи від'ємні.

for (i = 0; i < n; i++) {

if (a[i] < 0) /* пропустити від'ємні елементи */

continue;

... /* обробити додатні елементи */

}

Твердження з continue часто використовуються, коли наступна частина циклу занадто складна, тож перевірка протилежної умови та додатковий відступ коду вправо гніздить програму занадто глибоко.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]