noder_ss
@noder_ss
Линуксоид-энтузиаст и SQL разработчик

В чем смысл do while? Как его можно использовать?

Чуть ли не в каждом языке программирования есть цикл do while. В чем его смысл? Знаю, что он сначала делает действие, а потом уже провереку. Но как можно его применить?
  • Вопрос задан
  • 366 просмотров
Решения вопроса 5
mayton2019
@mayton2019
Bigdata Engineer
do-while удобно применять когда например есть пользовательский ввод и есть реакция на ошибу. Где нужно ввод
повторить. Например

do {
  s = input("Enter your bidthday: ")
} while(!isValidDate(s));

Еще я использовал для простого I/O когда надо что-то по-символьно читать и проверять
что файл не закончился (результат не отрицательный).

В последних версиях Scala (3.x) мусье Одерский внезапно зобанил оператор цикла с постусловием.
Я уж не помню как он это аргументировал.

В качестве альтернативы предлагалось делать такой композитный предикат который делает
сначала действие а потом проверяет.

while ({ <body> ; <cond> }) ()

Еще дальше пошел Дейкстра. Он придумал специальный вид do-while для конечных автоматов.
Такой себе гибрид do-switch-case-while. Где можно как в DSL описать исходящие переходы.
Правда я не помню где он его реализовал.

UPD: Ошибочка. Не Вирт а Дейстра. Путаю их.
Ответ написан
Комментировать
@igor6130
Этот цикл всегда срабатывает один раз. Остальные итерации зависят от условия.
Ответ написан
@evgeniy_lm
Как написано в инструкции. Тело такого цикла обязательно выполняется хотя бы один раз. Часто густо бывают ситуевины когда нужно выполнить некие действия и по их результату решить повторить их или продолжить выполнение проги далее
Ответ написан
Комментировать
@res2001
Developer, ex-admin
Например, функции ввода/вывода в POSIX возвращают EINTR, если во время их работы в приложение пришел сигнал.
Сигнал вы можете перехватить, обработать и можно продолжать дальше. Но функция (например write) вернет EINTR. Если эту ситуацию не обрабатывать отдельно, то это может вызвать, например, завершение приложения (из-за ошибки ввода/вывода), тогда как приложение могло бы дальше работать.
В этом случае удобно вызов функции заключать в do while:
int ret;
do {
  ret = write(...);
} while(ret == EINTR);

Это один из вариантов, когда надо выполнить действие, и по результатам действия будет понятно надо ли еще раз его запустить или уже достаточно.
В этот же цикл можно добавить и другой функционал.
В случае неблокируемых операций ввода/вывода операция может завершится не записав или не прочитав все что нужно или вообще вернуть EAGAIN, если ничего нет. Можно эти проверки добавить в этот же цикл do while вместе с проверкой на EINTR.
Вариантов использования, на самом деле много. Вы это увидите, когда столкнетесь с таким вариантом в своей практике.

Но самый популярный вариант у Си программистов, это использование в макросах:
#define MACRO(x)      do { тут что-то делаем } while(0)

Этот фиктивный цикл служит двум целям:
1. внутри цикла можно объявлять локальные переменные, которые не будут видны вне цикла
2. При использовании макроса можно в конце ставить точку с запятой, не нарываясь на предупреждения компилятора: MACRO(val);. Компилятор в итоге уберет цикл, но все побочные эффекты сохранятся.
В плюсах этот вариант практически не используется, т.к. тут есть шаблоны и т.п. и от макросов в основном отказываются. Но в Си макросы вполне актуальный инструмент.

Но циклы for и while применяются чаще, чем do while.
Ответ написан
Комментировать
New_Horizons
@New_Horizons
Бред:
Просто ещё один примерчик:
Когда нужно из апи получить какие-то данные постранично, но ты не знаешь сколько там вообще их, может быть 0, а может быть миллион. Т.е. тебе в любом случае нужно сделать хотя бы один запрос в апи, чтобы узнать сколько товаров, сколько страниц и т.п. Тут и пригождается do-while. Далем первоначальный запрос, а дальше уже в зависимости от ответа либо продолжаем цикл, пока не получим все страницы, либо выходим из цикла, если данных вообще нет или не более одной страницы.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
saboteur_kiev
@saboteur_kiev Куратор тега Программирование
software engineer
В баш until и while отличаются только тем, что один проверяет на true, второй на false
выбираешь что тебе нужнее
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы