Шаг для цикла For

Действительно, смысл приколупываться к циклу с параметрами for, когда есть более гибкие repeat и while, а то набегут любители дробных параметров-функций и устроят холивар сколько раз должен “правильно” выполняться цикл вида

for i:=0 to 9 step 2.1
// или
for i:=1 to 9 step ((9-i)/2)
, не говоря о скучающих поклонниках рекурсий и **goto**-шниках)

Да, если известно ОТ, ДО и ШАГ, то проще сразу поделить ДО на ШАГ и не выделываться зря.

Для этой цели есть Rаnge с вещественными параметрами, “железно” нарезающий интервал на требуемое количество участков. Никаких холиваров))

Применяем функциональную парадигму, формируем последовательность нужных индексов или значений с помощью генераторов, а затем перебираем иx в foreach.

Просто пишем Range(От, До, Шаг)

5 сообщений перенесены в тему Болталка PascalABC.NET

Зачем выносить ОБЫКНОВЕННЫЙ счетчик в какую то там последовательность (они у вас что комбинации что ли???- это же не комбинаторика, да у вас и алгоритмов таких нет, максимум ваша последовательность может быть randomidze)… я думаю, вы просто не можете реализовать for как в с++, ведь там можно делать не только шаг но и много чего еще, а через последовательность For становится тяжелым по времени выполнения. Так что не нужно свою ограниченность выдавать за вашу мудрость…)))))))))))))) полазил я по вашим исходникам выложенным на GitHub и заметил в них даже Visual Basic, а в некоторых местах имитацию шага через while. Короче, я даже промолчу про коменты в мою сторону про грязный код…)))))))))))))))

Вам все же стоит внимательнее познакомиться с организацией PasacalABC.NET. Хотя бы для того, чтобы не смешить присутствующих своими безапелляционными рассказами о том, как хранится последовательность, занимая память. В PascalABC.NET последовательность не хранится! И памяти она занимает ровно столько, сколько занимает один ее элемент. Это первое.

И второе. Вам уже писали, что если Вы хотите, чтобы Ваши сообщения читали - проявляйте уважение к другим участникам форума и разбивайте свой “поток сознания” на отдельные предложения.

14 сообщений перенесены в тему Болталка PascalABC.NET

О да, “ленивые” расчёты значения только по требованию в этом смысле на пользу. Хотя даже странно, но после Бейсика довольно легко научился пользоваться конструкциями вида for i:=1 to 5 do x[i]:=i*2; {2,4,6,8,10}, удивляясь гибкости DOS с for %f in (1,2,7,8,1,5,am,dd,zz) do echo %f

Ну нет STEP, значит можно перефразировать задачу, а в циклы с пред- и постусловием можно хоть функции от функций загонять, лишь бы желание.

ИМО, проблема скорее надумана, так как не смог придумать ни единого примера обязательно и только через STEP

Я тут зашел на Википедию первого Оберона и там в его синтаксисе цикл FOR вообще отсутствует. А вот во втором Обероне они его восстановили взад, как там пишут в версии Модулы-2, с шагом, ключевое слово, которого, кстати, BY.

1 лайк

Range работает только с целыми числами. А есть такое же, но чтоб для вещественных с вещественным же шагом? Partition не очень удобно, т.к. нужно высчитывать количество равных частей. Можно, конечно, и Range приспособить, делить на десять, сто и т.д. Но вот так чтоб сразу взял и задал любую границу(ы) и любой шаг?

Лично мне не понятно, зачем перекручивать именно цикл с параметрами, да ещё с последующими дебатами неоднозначных моментов вроде

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

Но, в любом случае, итерация с превышением параметра окончания цикла выполняться не должна, иначе будет допустима ситуация с реальным арифметическим переполнением переменной цикла: тихого переполнения – в случае с целочисленной переменной (т.е. может случайно получиться вечный цикл) или возникновения исключения – в случае с вещественной переменной.

1 лайк
  1. Вы всегда можете определить свою функцию, которая будет вычислять число шагов, либо даже готовить нужную последовательность.

  2. Вы можете написать выражение для вычисления количества повторений - что за проблема?

Вот простой пример:

function RealFor(a, b, h: real) :=
    SeqWhile(a, p -> p + h, q -> h > 0 ? q <= b : q >= b);

begin
  foreach var x in RealFor(3.8, 4.72, 0.1) do
    Writeln(x:6:3, x * x:15:6);
  (21 * '-').Println;
  foreach var x in RealFor(3.15, -2.1, -0.237) do
    Writeln(x:6:3, x * x:15:6)
end.

Не в одном языке программирования нет выхода за границу конечного параметра цикла.

1 лайк

Пофиксил :slight_smile: Иначе при шаге 0 ваша последовательность была бы бесконечной:

function RealFor(a, b, h: real) :=
    SeqWhile(a, p -> p + h, q -> h > 0 ? q <= b : (h <> 0 ? q >= b : false));

А при шаге 0 любой стандартный цикл зацикливается))) Я же делал, чтобы моделировало максимально точно. Вдруг там в теле break где-то…

PascalABC.NET не возражает против бесконечных последовательностей, поскольку их элементы все равно не хранятся.

А разве шаг 0 был допустим в языках, где for мог иметь произвольный шаг?

Да. Ведь он мог, к примеру, возвращаться функцией или вводиться с клавиатуры. Компилятор такое не может отследить. Он и сейчас допустим, например, в VB/VBA

Так же, как while true do

Алекс, спасибо за пример, а вот насчёт “ни в одном” лучше уточнять “общепринятом современном” или “из вам известных”, потому что только на моей памяти было несколько диалектов ЯП, которые переполняли FOR. Если не ошибаюсь, были даже с защитой параметра цикла от модифицирования. Кроме того, с дробными значениями следует ожидать проблему округления (± цикл).

А не могли бы Вы привести хотя бы один? Мне казалось, я знаю достаточно именно старых, а не современных языков программирования и их диалектов.

А вот из-за нее цикл с real и изгнали из большинства современных языков. Я не встречал ни одного языка программирования, который умел бы в операторе цикла (или его аналоге) делать округление параметра цикла - разве только у Айверсона в APL.

Почему “даже”? Попробуйте в разных Бейсиках поменять руками параметр цикла for.

И еще. В языке Фортран - “короле точных вычислений” - вещественное значение в цикле с параметром было запрещено. Для пробы его разрешили в версии Fortran-77, но ужаснулись результатам и с версии Fortran-90 запретили снова.

Хм… Как-то раньше никогда не задумывался над ситуацией с шагом 0 в циклах for в других ЯП – в голову не приходило такое попробовать. Для “вечных” циклов с каким-то альтернативным выходом или окончанием (типа break, goto, exit и т.п.) цикл for как-то… неправильно использовать. Теоретически ведь можно было просто запретить в таких языках вход в тело цикла в такой ситуации, а при компиляции с литерным 0 в шаге – как минимум выдавать warning.

Я в курсе, что такое генератор и state machine :slight_smile: