OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 29 Апрель, 2024 11:13

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 81 ]  На страницу Пред.  1, 2, 3, 4, 5  След.
Автор Сообщение
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 16:26 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
А.П. писал(а):
Грубо: FOR - для статики, он нагляднее, с ним новичку труднее ошибиться, WHILE/REPEAT - для любой динамики и тонкой оптимизации.

Вот где пригождается REPEAT - вообще не представляю. По инерции вошедшее средство "додейкстровских" времён ("донаучного" составления циклов), которое Николай Вальтерович решил не убирать.

Цитата:
"Каторжная интеллектуальная тренировка" ((С) Ершов А.П.) на сотне-другой задач с циклами такие понимание и навык обеспечат!

Нет, Анатолий Иванович, давайте, может, эту фразу не трогать? )) Нам в методиках до неё ещё расти и расти. Т.к. окончание этой фразы у Ершова что-то типа "... с доказательствами, в стиле лучших курсов матанализа".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 17:23 

Зарегистрирован: Пятница, 02 Декабрь, 2005 14:35
Сообщения: 210
Откуда: Россия, Томск
Илья Ермаков писал(а):
Вот где пригождается REPEAT - вообще не представляю.
Недавно на одной задаче, связанной с чтением строки символов неопределенной (но заведомо не пустой!) длины, готовил решение на турбопаскале для нашего турнира. Так для "отсечки" конца строки от последнего символа и простоты условия показалось разумно применить как раз
repeat read(c); <обработка> until eoln;
С while так просто не получилось.

Цитата:
давайте, может, эту фразу не трогать? )) Нам в методиках до неё ещё расти и расти. Т.к. окончание этой фразы у Ершова что-то типа "... с доказательствами, в стиле лучших курсов матанализа".

А почему бы не поставить целью одолевать хотя бы первую половину фразы во имя того, чтобы не призывали вообще отменить азы программирования для всех "как ненужное многим в жизни"? :D Ну не удалось воплотить в жизнь, увы, идею "Программирование - вторая грамотность". Так давайте хотя бы не отпугивать с порога массу хороших людей еще и требованиями "доказательства, в стиле лучших...". Смогут дальше расти - будут доказывать. Тут на форуме есть живой пример, кто не поладил в свое время с матанализом, но программист он весьма мною уважаемый. Если захочет - сам обозначится :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 17:38 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Да, я сам вижу на практике, что нужны как минимум два варианта базового курса: для одних групп (будущие программисты) - математичный (этот в этом году удалось построить); для других (будущие инженеры, технари...) - некий другой (в этом году он мне не удался). На самом деле, нужен ещё курс для гуманитариев (тут Фёдор Васильевич получше скажет...).

Но тех, кто метит в программисты, надо сразу "строить по науке". Иного способа нет отсечь ту "пену", которая сейчас дискредитирует название профессии, и которая всем нам доставляет уйму головной боли. Нужно задирать планку. Тогда можно будет чётко говорить: "уважаемый, Вы - не программист, Вы максимум - любитель. А вот - программист."


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 17:42 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
А.П. писал(а):
Недавно на одной задаче, связанной с чтением строки символов неопределенной (но заведомо не пустой!) длины, готовил решение на турбопаскале для нашего турнира. Так для "отсечки" конца строки от последнего символа и простоты условия показалось разумно применить как раз
repeat read(c); <обработка> until eoln;
С while так просто не получилось.

Анатолий Иванович, но это же базовая схема "полный проход":
взять_первый_элемент;
WHILE ~конец_последовательности DO
обработка;
взять_следующий_элемент
END

Из того, что в данном частном случае взятие первого и следующего элементов выглядят одинаково, ещё не следует что "кажущийся повтор" нужно пытаться укоротить. Пусть так и будет, очевидно, шаблонно и ясно:
Read(c);
WHILE ~eot DO
обработка;
Read(c)
END


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 19:10 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Илья Ермаков писал(а):
Из того, что в данном частном случае взятие первого и следующего элементов выглядят одинаково, ещё не следует что "кажущийся повтор" нужно пытаться укоротить. Пусть так и будет, очевидно, шаблонно и ясно:
Read(c);
WHILE ~eot DO
обработка;
Read(c)
END

Может я что-то упускаю из виду, но по-моему правильно так:
Код:
Read(c);
обработка;
WHILE ~eot DO
  Read(c);
  обработка
END

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


Последний раз редактировалось Comdiv Понедельник, 13 Апрель, 2009 19:18, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 19:18 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Comdiv писал(а):
Может я что-то упускаю из виду, но по-моему правильно так:
Код:
Read(c);
обработка;
WHILE ~eot DO
  Read(c);
  обработка
END
Это не может быть правильно, потому что после Read должна быть проверка.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 19:50 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
А перед Read -установка(инициализация). тогда всё намного логичнее:
Код:
Инициализация; WHILE проверка DO действия; Read(); END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 20:11 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Info21 писал(а):
Это не может быть правильно, потому что после Read должна быть проверка.

Что ж, значит я неверно понял смысл "eot". Но если говорить о Турбо Паскале, то функция "eoln" отвечает, есть ли что считывать, а не проверяет, правильно ли прочитался символ при последнем запросе. Поэтому в варианте Ильи Ермакова с функцией "eoln" последний символ строки обрабатываться не будет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 22:04 

Зарегистрирован: Понедельник, 19 Март, 2007 09:40
Сообщения: 142
Откуда: USA, Israel, Belarus
Как то читал статью о "структурных переходах" (не помню ни автора ни точного названия).
В которой утверждалось, что переходы вперед и во внешний контекст являются "структурными".
Т.е., break, continue, throw-catch и даже обычный goto удовлетворяющий этим условиям можно считать структурными переходами.

К сожалению не помню пытались ли авторы доказать применимость формальных методов для доказательства корректности алгоритмов с такими "структурными переходами".
Практически, наблюдая такой "структурный" код на практике, склоняюсь к тому, что -- нет.
ИМХО, единственный способ выбивания такой дури -- это строгое структурное программирование, например как в Oberon-07.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 22:35 

Зарегистрирован: Понедельник, 19 Март, 2007 09:40
Сообщения: 142
Откуда: USA, Israel, Belarus
Имею одно наблюдение.
Использование break (и др.) обосновывается тем, что тело цикла становится короче.
Обычно, приводится пример поиска for-if-break.
И действительно, в таких вырожденных случаях, циклы выходят более короткими, чем их WHILE-аналоги.
Так почему же в результате на практике наблюдаем тела циклов в десятки-сотни строчек, напичканные break и continue?
Настолько ли сложна проблема, что без break никак?

Моя гипотеза: нет.
Т.е. наоборот, break играет дурную шутку.
Заменяя паттерн поиска:
Код:
WHILE ~found DO
   search
END;

IF found THEN
   process
END;
через for-if-break или for-if-return, получаем:
Код:
for (...)
{
    search;
    if (found)
    {
        process;
        break;
     }
}
В WHILE-цикле, блоки поиска (search) и обработки (process) разделены.
В for-цикле, поиск и обработка "слипаются", увеличивая тело цикла.
Практически, не возможно используя break вытащить обработку из тела for-цикла.

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

Конечно можно обвинять "тупого соседа", но специально акцентирую внимание на процессe развития таких циклов, от маленького и простого, до полотен в несколько страниц.
Этот процесс неизбежен, хотели как лучше (сократить пару строчек в простейшем цикле), получаем в дальнейшем кошмар.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Понедельник, 13 Апрель, 2009 22:47 

Зарегистрирован: Понедельник, 19 Март, 2007 09:40
Сообщения: 142
Откуда: USA, Israel, Belarus
Теперь пару слов о FOR-циклах в Oberon.
На мой взгляд, главная проблема решена -- нет break/EXIT для FOR.
Вторая проблема -- "RETURN из середины процедуры" должна быть как то решена методически.
Т.е. преподавание построить так, что бы начинающему ученику даже в голову не могла прийти такая идея как RETURN из циклов.
Иными словами преподавать Oberon-07.
LOOP-EXIT должны тоже выпасть из образовательного процесса.
Если после всего этого у учеников все еще будут проблемы с применением FOR/WHILE, то вполне возможно, что WHILE должен идти первым.
Т.е. отработать вначале поиск (например, по массиву), и только потом, как некая оптимизация частных случаев, можно представить пробег "по всем".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 06:04 

Зарегистрирован: Пятница, 02 Декабрь, 2005 14:35
Сообщения: 210
Откуда: Россия, Томск
Илья Ермаков писал(а):
Анатолий Иванович, но это же базовая схема "полный проход":
взять_первый_элемент;
WHILE ~конец_последовательности DO
обработка;
взять_следующий_элемент
END

А вот и нюанс, на которые я намекал, говоря о тонкой оптимизации:
eoln=true мы получим ОДНОВРЕМЕННО с чтением последнего символа строки, который в Вашем варианте алгоритма будет потерян!!
Вот прогнал Ваш вариант в среде Борланд Паскаль (от среды турбопаскаль в этом месте отличий вроде бы нет):
Код:
var c:char;
begin
read(c);
while not eoln do
begin write(c); read(c) end
end.
Последний прочитанный символ строки не допускается к обработке, поскольку в while вход уже закрыт!
Мой вариант с repeat этот нюанс учитывает.
В Вашем варианте этот дефект можно разглядеть, если хорошие очки надеть! :)
В КП/ББ иная картина: вариант с REPEAT "не катит", а с WHILE всё четко:
Код:
In.Char(c);
WHILE In.Done DO
   StdLog.Char(c);
   In.Char(c);
END;

Но тут разработчики ББ были более точны.
Так что, коллеги, в очередной раз убеждаемся, что в нашем деле за каждой "запятой" надо внимательно следить :)
Правда, показать полезность REPEAT в КП не получилось :mrgreen:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 07:13 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
"Тонкая оптимизация" такого рода в учебной программе (и в большинстве профессиональных) -- наказуемая ошибка.

Корректный вариант должен содержать обработку конца цикла.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 07:18 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
А.П. писал(а):
А вот и нюанс, на которые я намекал, говоря о тонкой оптимизации:
eoln=true мы получим ОДНОВРЕМЕННО с чтением последнего символа строки, который в Вашем варианте алгоритма будет потерян!!

А Ваш вариант с repeat правильно отработает при попытке чтения пустого файла?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 11:38 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
А.П. писал(а):
Код:
var c:char;
begin
read(c);
while not eoln do
begin write(c); read(c) end
end.
Последний прочитанный символ строки не допускается к обработке, поскольку в while вход уже закрыт!
Мой вариант с repeat этот нюанс учитывает.

Чем Вам не нравится следующий вариант?
Код:
var c:char;
begin
  while not eoln do begin
    read(c);
    write(c)
  end
end.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 12:14 

Зарегистрирован: Пятница, 02 Декабрь, 2005 14:35
Сообщения: 210
Откуда: Россия, Томск
Geniepro писал(а):
А Ваш вариант с repeat правильно отработает при попытке чтения пустого файла?

Неправильно. Но я заранее оговорился, что предполагаем файл не пустой!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 12:20 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
А может не делать таких предположений? Лучше - грамотную обёртку для чтения текстов в турбике, чтобы было типа In.Done.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 12:41 

Зарегистрирован: Пятница, 02 Декабрь, 2005 14:35
Сообщения: 210
Откуда: Россия, Томск
Comdiv писал(а):
Чем Вам не нравится следующий вариант?
Код:
var c:char;
begin
  while not eoln do begin
    read(c);
    write(c)
  end
end.


Тем, что я не знаю, каково значение eoln ДО первого чтения.

В Справке в BP7 дан пример:
begin writeln(eoln) end.
Программа ждет нажатия клавиш! Если нажимаешь только Enter, получаешь TRUE. Если жмешь символьные клавиши в любом количестве и только потом Enter - получаешь FALSE. Как говорится, "спасибо"! :( Вам ясно, что будет с первым входом в цикл? Мне - нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 13:05 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
А.П. писал(а):
Если нажимаешь только Enter, получаешь TRUE. Если жмешь символьные клавиши в любом количестве и только потом Enter - получаешь FALSE. Как говорится, "спасибо"!
Вроде как всё очевидно - сразу нажали Enter и первый символ строки имеет код 10, что означает конеw строки, eoln(End of line то есть). а если написали символов - то первый символ строки уже не 10 - вот вам eoln и даёт FALSE. возможно каретка сразу установлена в первый символ.
Цитата:
28 Eoln
Declaration
Function Eoln [(F : Text)] : Boolean;

Description
Eoln returns True if the file pointer has reached the end of a line, which is demarcated by a line-feed character (ASCII value 10), or if the end of the file is reached. In all other cases Eof returns False. If no file F is specified, standard input is assumed. It can only be used on files of type Text.
Errors
None.

Example
Program Example19;

{ Program to demonstrate the Eoln function. }

begin
{ This program waits for keyboard input. }
{ It will print True when an empty line is put in,
and false when you type a non-empty line.
It will only stop when you press enter.}
While not Eoln do
Writeln (eoln);
end.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Долой цикл FOR (?)
СообщениеДобавлено: Вторник, 14 Апрель, 2009 15:36 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
А.П. писал(а):
Пётр Кушнир писал(а):
Вроде как всё очевидно - сразу нажали Enter

"Ты не умничай, ты пальцем покажи" :)
Из Вашего ответа не стало ясней, будет ли работать вариант while без предварительного считывания символа.

Я не могу найти где задача. :)
придумаю сам: прочитать многострочный файл посимвольно(и построчно) и вывести на экран сохраняя структуру переносов строки:
Код:
uses crt;

var f : text; ch : char;
begin
        assign(f, 'c:\file.txt');
        reset(f);
        while not eof(f) do begin
                while not eoln(f) do begin
                        read(f, ch);
                        write(ch);
                end;
                read(f, ch); writeln;
        end;
        readkey;
end.

работает. не знаю, поможет или нет.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 81 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Часовой пояс: UTC + 3 часа


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB