Вопрос про цикл for

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Вопрос про цикл for

Сообщение iskander » 25.01.2024 19:24:34

sts писал(а):
Mikhail писал(а):Изменение переменной цикла внутри for всегда было невозможным.

смутно припоминаю что в 90х в борланд (или турбо) паскале я таким регулярно пользовался и это не считалось неправильным

Можно даже особо не напрягать смутную память, а просто скомпилировать в FPC и выполнить:
Код: Выделить всё
program Counter;
{$mode tp}
var
  I: Integer;
begin
  for I := 1 to 20 do begin
    Inc(I, 2);
    WriteLn(I);
  end;
end.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Вопрос про цикл for

Сообщение ZWolol » 25.01.2024 19:52:49

@Mikhail
>Вообще-то я привел цитату из "Language reference guide FreePascal"
А я сразу с этим согласился, только это правила компилятора, а не языка.
Но в любом случае это аргумент, а не домыслы.

А теперь о ISO 7185:1990
Это стандарт языка без привязки к компилятору.
И опять ты не привел цитату, ну хоть дал ссылку.
У нас не все и не всегда соответстует стандартам.

>>After a for-statement is executed, other than being left by a goto-statement, the control-variable shall be unde ned.
Это соответсвует неопределенному значению на выходе, однако допускает выход по go-to.
Про continue и break я не нашел (тяжело искать без знания ангелького).

Apart from the restrictions imposed by these requirements, the for-statement
for v := e1 to e2 do body
shall be equivalent to
begin
temp1 := e1;
temp2 := e2;
if temp1 <= temp2 then
begin
v := temp1;
body;
while v <> temp2 do
begin
v := succ(v);
body
end
end
end

Эквивалент - это только пример, ну а реализация может быть разной.
ZWolol
новенький
 
Сообщения: 21
Зарегистрирован: 06.01.2023 06:49:21

Re: Вопрос про цикл for

Сообщение bormant » 25.01.2024 20:28:09

Зачем бы для поиска в массиве нужен был for do?
Код: Выделить всё
i:=0; while (i<n) and not IsMatch(v[i]) do Inc(i);
if i<n then
  WriteLn('Found at ',i)
else
  WriteLn('Not found');

Вариант с for был выше:
Код: Выделить всё
k:=-1;
for i:=0 to n-1 do if IsMatch(v[i]) then begin
  k:=i; Break;
end;
if k>=0 then
  WriteLn('Found at ',k)
else
  WriteLn('Not found');

Если в массиве ссылки, то можно вполне:
Код: Выделить всё
r:=nil;
for t in v do if IsMatch(t) then begin
  r:=t; Break;
end;
if r<>nil then
  WriteLn('Found')
else
  WriteLn('Not found');
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Вопрос про цикл for

Сообщение Mikhail » 26.01.2024 21:14:10

sts писал(а):
Mikhail писал(а):Изменение переменной цикла внутри for всегда было невозможным.

смутно припоминаю что в 90х в борланд (или турбо) паскале я таким регулярно пользовался и это не считалось неправильным


Да был неправ. В Turbo Pascal действительно переменная цикла доступна для изменения внутри цикла.

Поведение изменилось в Object Pascal (Delphi). Кроме того такое поведение было в ISO Pascal и последующих потомках типа модулы.

Добавлено спустя 15 часов 54 минуты 19 секунд:
ZWolol писал(а):Это стандарт языка без привязки к компилятору.

Стандарт он на то и стандарт, что никакой привязки к компилятору нет. Это компилятор создают с оглядкой на стандарт. В любом случае стандарт существует на Паскаль и на Модула-2. На Turbo Pascal, Object Pascal, FreePascal и пр. никаких стандартов нет. Здесь конкретный компилятор сам себе стандарт, хотя и с условной оглядкой на ISO 7185:1990.

Из того что удалось найти по обсуждаемой теме. Вот выдержки из документации на соответствующие компиляторы.
USCD Pascal
The value of the control variable, after a FOR statement terminates naturally (whether or not the body executes), is undefined. It can vary due to optimization and, if $INITCK is on, can be set to an uninitialized value. However, the value of the control variable after leaving a FOR statement with GOTO or BREAK is defined as the value it had at the time of exit.


No assignments to the control variable are allowed in the repeated statement. This error
is caught by making the control variable READONLY within the FOR statement; it is not caught when a procedure or function invoked by the repeated statement alters the control variable. The control variable cannot be passed as a VAR (or VARS) parameter to a procedure or function.


Turbo Pascal 3
Notice that the component statement of a for statement must not contain assignments to the control variable. If the repetition is to be terminated before the final value is reached, a goto statement must be used, although such constructs are not recommended - it is better programming practice use a while or a repeat statement instead.
Upon completion of a for statement, the control variable equals the final value, unless the loop was not executed at all, in which case no assignment is made to the control variable.


Turbo Pascal 7
After a for statement is executed, the value of the control variable value is
undefined, unless execution of the for statement was interrupted by a goto from the for statement.


ISO Pascal
After a for-statement is executed, other than being left by a goto-statement, the control-variable shall be undefined. Neither a forstatement nor any procedure-and-function-declaration-part of the block that closest-contains a forstatement shall contain a statement threatening the variable denoted by the control-variable of the for-statement.


Object Pascal
statement is a simple or structured statement that does not change the value of counter.

After the for statement terminates, the value of counter is undefined.


Free Pascal
It is not allowed to change (i. e. assign a value to) the value of a loop variable inside the loop.

The value of the loop variable is undefined after a loop has completed or if a loop is not executed at all. However, if the loop was terminated prematurely with an exception or a break or goto statement, the loop variable retains the value it had when the loop was exited.

The compiler does not expliticly forbid jumping with a goto statement into a for loop block, but doing so will result in unpredictable behaviour.
Mikhail
энтузиаст
 
Сообщения: 562
Зарегистрирован: 24.10.2013 16:06:47

Re: Вопрос про цикл for

Сообщение ZWolol » 28.01.2024 07:49:23

@Mikhail
Снимаю шляпу за твою подробную выборку...
Стандарты то же меняются, до него был другой и этот со временем заменится на новый.
По крайней мере там должно быть описание про break и continue.

А теперь заметь, что все выписки относятся не к языку, а компиляторам и связаны они в основном с одной причиной:
использование в цикле вместо самой переменной ее дубля (это особенности компиляторов).

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

А вот тебе еще вариант, который не меняет i, но работает не как пример в стандарте:
var
i: Integer;
SL: TStringList;
begin
SL:= TStringList.Create;
SL.Add('1');
for i := 0 to SL.Count do
begin
WriteLn(IntToStr(i));
if i = 0 then SL.Add('2');
end;

В приведенном аналоге стандарта ISO, цикл будет один, а у меня получается два!!!
По твоему, значит ли это, что Lazarus не соответствует ISO и его надо менять!!! :) :) :)

Я не вижу принципиальной разницы между этими двумя переменными (e1 и e2).
Как было сказано выше, результат может отличаться при использовании в компиляторе ++i или i++
И это не относится к правилам языка.
ZWolol
новенький
 
Сообщения: 21
Зарегистрирован: 06.01.2023 06:49:21

Re: Вопрос про цикл for

Сообщение Снег Север » 28.01.2024 08:52:34

ZWolol писал(а):В приведенном аналоге стандарта ISO, цикл будет один, а у меня получается два!!!

Не понял, каким чудом у вас получается два цикла. И я вижу сразу грубейшую ошибку избегать которой учат даже школьников - верхний предел должен быть не SL.Count, а SL.Count-1.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2997
Зарегистрирован: 27.11.2007 16:14:47

Re: Вопрос про цикл for

Сообщение ZWolol » 28.01.2024 10:45:03

Действительно, поторопился и ошибся...
Значение переменной количества циклов берется только в начале и не меняется в цикле for.
Хотя ее, в отличие от переменной цикла, можно менять, но это ни на что не отражается.
ZWolol
новенький
 
Сообщения: 21
Зарегистрирован: 06.01.2023 06:49:21

Re: Вопрос про цикл for

Сообщение Mikhail » 28.01.2024 17:51:40

Вот более показательный пример. Тело цикла выполнится четыре раза. Изменять переменные a и b можно, это позволяет стандарт. А вот счетчик цикла менять нельзя и его значение не определено после выхода из цикла (если это не досрочный выход).
Код: Выделить всё
program Project1;
var a, b, i: Integer;
begin
a:=0; b:=3;
for i:=a to b do begin
  writeln(i);
  inc(a); dec(b);
end;
readln;
end.
Mikhail
энтузиаст
 
Сообщения: 562
Зарегистрирован: 24.10.2013 16:06:47

Re: Вопрос про цикл for

Сообщение ZWolol » 28.01.2024 18:32:18

Ну и к чему этот пример?
Я задал вопрос и давно получил ответ, а для чего здесь следующие ТРИ страницы?
Что ты хочешь мне доказать?

Если то, что на Паскале везде одинаково, так ты вроде сам согласился, что не всегда.
Если утверждаешь, что на всех языках функция for ведет себя точно так же, то это бред.
На С она так не работает.
Если считаешь, что на Паскале она реализована лучше чем на С, то я с этим не согласен.

Я 10 лет не программировал на С, а на Delphi, больше 20 лет.
Работал на Clipper, это интерпретатор (продолжение dBase III+).
Там все переменные типа вариант и все операции ведутся с переменными, а не с их копиями.
Там таких проблем нет.

Почему переменная должна быть целочисленной? Да все очень просто.
Процессор выполняет машинные коды, у него есть регистры, но нет переменных.
Регистр не может быть дробным.

Потому проще присвоить регистру целое число и приращивать его без вычислений.
Это ограничение компилятора (которое занесли в стандарт языка для обеспечение совместимости).

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

Если будешь еще что-то доказывать, то сначала укажи, что тебе нужно.
ZWolol
новенький
 
Сообщения: 21
Зарегистрирован: 06.01.2023 06:49:21

Re: Вопрос про цикл for

Сообщение RRYTY » 28.01.2024 18:57:22

Вся ветка должна называться "Что такое индусский код."
ZWolol писал(а):а для чего здесь следующие ТРИ страницы?

Чтобы показать, что будет, если каждый, кто назовет себя программистом, еще и начнет программировать. :-D
RRYTY
постоялец
 
Сообщения: 187
Зарегистрирован: 25.12.2021 10:00:32

Пред.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 41

Рейтинг@Mail.ru