цикл FOR

Проектирование и разработка идеального средства программирования.

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

цикл FOR

Сообщение Alexander » 13.10.2007 21:42:20

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

И почему бы не использовать такие варианты ? :

Код: Выделить всё
X := 20;
for f := 10 to X do begin
  WriteLn(f);
  if f = 15 then break;
breakfor; // опциональный параметр
  WriteLn('Цикл был прерван. Значение F=', f);
endfor;  // опциональный параметр
  WriteLn('А сюда бы мы попали, если бы break не было. Значение F=', f);
end; {end for}
// сюда попадаем в любом случае, если Х < 10 то F = 10.
WriteLn('Значение F=', f);
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 690
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Сообщение Deepthroat » 13.10.2007 23:43:51

А че так сложно?

Без дополнительных конструкций делаем так:
Код: Выделить всё
  X := 20;

  for f := 10 to X do
  begin
    WriteLn(f);

    if f = 15 then
    begin
      WriteLn('Цикл был прерван. Значение F = ', f);
      break;
    end;
  end;

  if f = X then
  begin
    WriteLn('А сюда бы мы попали, если бы break не было. Значение F = ', f);
  end;

  // сюда попадаем в любом случае, если Х < 10 то F = 10.
  WriteLn('Значение F = ', f);

Break - нехорошо, так что, когда надо, я использую while или изменяю значение X (лучше while, конечно). Ну это Вы и без меня знаете.

А насчет почему, то я думаю, что переменная цикла, по идее, вообще должна быть временной. А ее область видимости должна ограничиваться циклом, как это сделано в других языках.
Аватара пользователя
Deepthroat
постоялец
 
Сообщения: 144
Зарегистрирован: 06.09.2007 00:21:34
Откуда: Outer Heaven

Сообщение alexs » 13.10.2007 23:45:48

конструкция интересная - но логичнее распологать её после самого тела цикла:
Код: Выделить всё
X := 20;
for f := 10 to X do begin
  WriteLn(f);
  if f = 15 then break;
  WriteLn('А сюда бы мы попали, если бы break не было. Значение F=', f);
end
breakfor; // опциональный параметр
  WriteLn('Цикл был прерван. Значение F=', f);
endfor;  // опциональный параметр
{end for}

// сюда попадаем в любом случае, если Х < 10 то F = 10.
WriteLn('Значение F=', f);


хотя я не вижу смысла особого введения такой языковой конструкции (сам операторы break и continue) вобще не использую - уж очень они мне goto напоминают :-)
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение debi12345 » 14.10.2007 01:10:36

Зато был бы смысл в "CONTINUE/BREAK cycle_var" - чтобы явно указывать, для какого из вложенных циклов отрабатывать.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5752
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение Alexander » 14.10.2007 14:07:32

debi12345 писал(а):Зато был бы смысл в "CONTINUE/BREAK cycle_var" - чтобы явно указывать, для какого из вложенных циклов отрабатывать.


Да, это мысль !
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 690
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Сообщение alexs » 14.10.2007 14:18:11

ну уж если совсем тюнинг наводить - то тогда так:
Код: Выделить всё
for i:=1 to 10 do
begin
  ...
breakfor
  ...
end


аналогично строить для циклов while-do и repeat-until

также можно отказаться от открывающего begin в циклах for и while - но это дело вкуса
лично мне они всёж нравятся (а может привычка).
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение Tariel » 14.10.2007 14:46:26

в цикле for переменная вообще не используется , работа идет с регистром CX,
если использовать значение переменной после выхода,
надо в цикле постоянно присваивать значение переменной значения CX
проверка значения+оператор break по идее в цикле for на асме добавляет всего две команды,
begin вообще не должен добавлять ни одной команды,

Вообще, это тот случай когда С лучше паскаля.
на С
for (int i=10;i<20;i++){} //устанавливается значение цикла
на паскале
var i:integer; //создается переменная
for i:=10 to 20 do begin//устанавливается значение i + устанавливается значение цикла
end;
Tariel
незнакомец
 
Сообщения: 3
Зарегистрирован: 04.10.2007 14:23:35

Сообщение bw » 14.10.2007 14:56:18

Мне не нравится идея использования break в циклах, это дурной тон. Так же как continue, exit/return и пр. Точка выхода из подпрограммы должна быть одна. Что касается переменной цикла, то считаю что область её видимости должна ограничиваться самим циклом. Но для этого придется определять её тип непосредственно в конструкции цикла (как мне кажется), для того что бы использование этой переменной трактовалось однозначно и что бы не сбить программиста с толку.
И еще, я бы отказался от текущего в паскале вида цикла в пользу изпользования директивы in как в Python и многих других языках:
Код: Выделить всё
for i in SomeIterator do WriteLn(i);
for i in range(10, 20) do WriteLn(i);
for row in SQLTableRows('users') do WriteLn('[row] ', String(row));

Может и не нужно определять тип переменной цикла, может он должен определяться автоматически :-), во время компиляции?

..bw
Аватара пользователя
bw
постоялец
 
Сообщения: 359
Зарегистрирован: 01.12.2005 11:36:23
Откуда: Усть-Илимск

Сообщение alexs » 14.10.2007 15:05:03

bw писал(а):Может и не нужно определять тип переменной цикла, может он должен определяться автоматически

и встаёт вопрос смешения объявления переменных и кода - в паралельном треде на эту тему обсуждени.

bw писал(а):И еще, я бы отказался от текущего в паскале вида цикла в пользу изпользования директивы in как в Python и многих других языках:Код:

если не ошибаюсь - это в последних дельфях уже есть.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение Bonart » 15.10.2007 08:17:33

bw
bw писал(а):Мне не нравится идея использования break в циклах, это дурной тон. Так же как continue, exit/return и пр. Точка выхода из подпрограммы должна быть одна.

Подобный пуризм приводит к дополнительным многократным проверкам одних и тех же условий и к жуткому коду обработки ошибок.
Переходы "вперед и вверх" являются неотъемлемой частью структурного программирования и нет никакого смысла их ограничивать.
alexs писал(а):и встаёт вопрос смешения объявления переменных и код

А объявлять (т.е. руками приписывать тип) совсем не обязательно :)
bw писал(а):И еще, я бы отказался от текущего в паскале вида цикла в пользу изпользования директивы in как в Python и многих других языках

А смысл именно отказываться, а не дополнять? Цикл for .. in недоста
точно общий.
Alexander писал(а):Почему Вирт против использования значения переменной цикла

после выхода из цикла ? Из за того, что for может завершиться

не начавшись и переменная может быть не определена ?

Для возможности эффективной реализации компилятора - в идеале переменная цикла вне его не должна существовать. Как и сделано в Аде.
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение debi12345 » 15.10.2007 11:11:45

Bonart писал(а):
bw писал(а):Мне не нравится идея использования break в циклах, это дурной тон. Так же как continue, exit/return и пр. Точка выхода из подпрограммы должна быть одна.

Подобный пуризм приводит к дополнительным многократным проверкам одних и тех же условий и к жуткому коду обработки ошибок.

Согласен - выходы/переходы в начало циклов соответствуют человеческой логике. Вы идете по коридору и видите дверь с надписью "выход" - и выходите, если она открыта. Не обязательно идти о конца, бесполезно проверяя остальные двери.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5752
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение bw » 15.10.2007 11:28:31

Это можно рассматривать как двери-порталы. Ты входишь в разные двери, но выходишь всегда из одной и той же, очень скоро твой мозг лопнет, если ты попытаешься вспомнить в какую дверь ты входил что бы выйти :-).

..bw
Аватара пользователя
bw
постоялец
 
Сообщения: 359
Зарегистрирован: 01.12.2005 11:36:23
Откуда: Усть-Илимск

Сообщение Alexander » 15.10.2007 12:39:47

alexs писал(а):ну уж если совсем тюнинг наводить - то тогда так:


Наверное я не правильно обозвал второй вариант, слишком похоже
на просто конец в Обероне. Можно что то вроде completefor.

Код: Выделить всё
X := 20;
for f := 10 to X do begin
  WriteLn(f);
  if f = 15 then break;
breakfor; // опциональный параметр
  WriteLn('Цикл был прерван. Значение F=', f);
completefor;  // опциональный параметр
  WriteLn('А сюда бы мы попали, если бы break не было. Значение F=', f);
end; {end for}
// сюда попадаем в любом случае, если Х < 10 то F = 10.
WriteLn('Значение F=', f);


Bonart писал(а):Для возможности эффективной реализации компилятора - в идеале переменная цикла вне его не должна существовать. Как и сделано в Аде.


Понял, со значением переменной цикла после цикла проясняется.
Может как то явно указывать, если переменная цикла нужна после
цикла, нпример использовать ":=", а когда не нужна просто "=" ?
Ну равна в пределах цикла и всё тут.

alexs писал(а):аналогично строить для циклов while-do и repeat-until


Да, конечно ! А вот дать для всех одинаковое имя или для каждого своё
это вопрос. Для простоты компилятора и обучения лучше одно.
Например что то вроде complete и breaked.
Для читаемости программ - разные.

alexs писал(а):также можно отказаться от открывающего begin в циклах
for и while - но это дело вкуса лично мне они всёж нравятся (а может
привычка).


Да, либо от begin, либо наоборот от концов конструкций. Те от do,
then, ... А begin можно или сократить до 3 букв или использовать
вместо него do.

bw, какая альтернатива этому сейчас ? :

Код: Выделить всё
for f := 1 to 10 do begin
    for  ff := 1 to 10 do begin
        for  fff := 1 to 10 do begin
          if (f = 5) and (ff = 5) and (fff = 5) then goto ex;
        end;
    end;
end;

ex:
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 690
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Сообщение ev » 15.10.2007 13:30:08

с логической точки зрения более правильнее отказаться от от do
т.к. begin и end - это границы блока
без них может выполнятся цикл
Код: Выделить всё
for  fff := 1 to 10 do
if (f = 5) and (ff = 5) and (fff = 5) then goto ex;

так же как и можно опускать begin и end в условиях и т.п.
по аналогии можно рассмотреть наличие и отсутствие { и } в циклах и условиях в си-подобных языках (например, си и пхп)
ev
долгожитель
 
Сообщения: 1763
Зарегистрирован: 27.04.2005 23:19:06
Откуда: Москва

Сообщение bw » 15.10.2007 14:09:39

Alexander писал(а):какая альтернатива этому сейчас ?

Код: Выделить всё
function Loop1: Boolean;
begin
  I := 1;
  while I <= 10 and Loop2(I) do I += 1;
  Result := I > 10;
end;

function Loop2(I): Boolean;
begin
  J := 1;
  while J <= 10 and Loop3(I, J) do J += 1;
  Result := J > 10;
end;

function Loop3(I, J): Boolean;
begin
  K := 1;
  while K <= 10 and Expression(I, J, K) do K += 1;
  Result := K = 11;
end;

fucntion Expression(I, J, K): Boolean;
begin
  Result := I != 5 or J != 5 or K != 5;
end;

begin
  Loop1;
end.


..bw
Аватара пользователя
bw
постоялец
 
Сообщения: 359
Зарегистрирован: 01.12.2005 11:36:23
Откуда: Усть-Илимск

След.

Вернуться в Компилятор / язык программирования

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

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

Рейтинг@Mail.ru