OberonCore
https://forum.oberoncore.ru/

Входящий поток
https://forum.oberoncore.ru/viewtopic.php?f=35&t=5449
Страница 1 из 1

Автор:  snuk [ Понедельник, 13 Июль, 2015 20:41 ]
Заголовок сообщения:  Входящий поток

Объясните пожалуйста, что не так со мной или входящим потоком?

Код:
(* найти сумму всех положительных чисел из входящего потока*)

MODULE Ex;
   IMPORT  Log := StdLog,  In := i21sysIn,  Math;
   PROCEDURE Pos*;
      VAR  k, sum:INTEGER;
   BEGIN
      In.Open; ASSERT (In.done);
      sum:=0;
      WHILE In.Done DO
         In.Int(k);
         IF k>0 THEN
            INC( sum,k );
         END;
      END;
      Log.Int(sum);
   END Pos;
END Ex.

Сам входящий поток:

-2 2 2 -2 результат 4

-2 2 2 -2 2 результат 8

Изображение

Автор:  Пётр Кушнир [ Понедельник, 13 Июль, 2015 21:03 ]
Заголовок сообщения:  Re: Входящий поток

На самом деле надо проверять done каждый раз после чтения Int и только если done, то прибавлять k. А так у вас последняя k два раза учитывается ошибочно, если она положительная.

Автор:  snuk [ Понедельник, 13 Июль, 2015 21:07 ]
Заголовок сообщения:  Re: Входящий поток

Пётр Кушнир писал(а):
На самом деле надо проверять done каждый раз после чтения Int и только если done, то прибавлять k. А так у вас последняя k два раза учитывается ошибочно, если она положительная.

Спасибо Пётр, поправил, сразу получил верный результат :D

Автор:  Пётр Кушнир [ Понедельник, 13 Июль, 2015 21:12 ]
Заголовок сообщения:  Re: Входящий поток

Вообще, я бы сделал с циклом REPEAT, не знаю, насколько это соответствовало бы эталонному решению, но REPEAT был бы кстати.
С одной стороны ASSERT можно выкинуть, так как WHILE уже охраняет. С другой стороны, ASSERT и WHILE можно заменить на IF In.done THEN REPEAT UNTIL !In.done END, с чтением не в начале цикла, а в конце, но тогда появляется лишняя первая итерация. Но это скорее борьба с нерегулярностью интерфейса модуля In.

Автор:  Пётр Кушнир [ Понедельник, 13 Июль, 2015 21:15 ]
Заголовок сообщения:  Re: Входящий поток

А еще желательно k присвоить 0 вначале, а то если ни одного числа не прочитается, то в k может быть огромный мусор больше нуля.

Автор:  prospero78 [ Пятница, 14 Август, 2015 09:31 ]
Заголовок сообщения:  Re: Входящий поток

Специально сейчас проверил. Все строки создаются как "", целые -- 0, вещественные -- 0.0 Вы недооцениваете мозг Вирта,)

Автор:  Иван Денисов [ Пятница, 14 Август, 2015 10:10 ]
Заголовок сообщения:  Re: Входящий поток

prospero78 писал(а):
Специально сейчас проверил. Все строки создаются как "", целые -- 0, вещественные -- 0.0 Вы недооцениваете мозг Вирта,)

Проверьте получше. Это далеко не всегда так. Что-то такое было по поводу глобальных переменных только, еще указатели всегда инициализируются в NIL. Локальные никак не инициализируются. Нули и пустые строки могут быть, если место под память ББ выделилось случайно пустое.

Автор:  Илья Ермаков [ Пятница, 14 Август, 2015 10:33 ]
Заголовок сообщения:  Re: Входящий поток

Для глобальных переменных инициализация нулями гарантируется.

Для локальных - гарантируется мусор в стеке.

Кроме указателей, которые таки, конечно, зачищаются.
Если посмотреть дизасм преамбул процедур в ББ, видно, как компилятор
старательно затирает указатели во фрейме процедуры, игнорируя всё между ними :)

Инициализация глобальных переменных гарантирована сообщением о языке, так что на неё можно полагаться.

Автор:  prospero78 [ Пятница, 14 Август, 2015 12:57 ]
Заголовок сообщения:  Re: Входящий поток

Я вот как раз глобальные и объявлял.
Странно, почему для локальных такое допущение. Может кто-то запилет обнуление локальных? Это же будет методически верно? xor eax, eax; push eax; сделать не в напряг же будет для INTEGER и SHORTREAL?
З.Ы. А в Go это лучше сделано, получается. Тоже заявлен, как язык системного программирования,)

Автор:  Иван Денисов [ Пятница, 14 Август, 2015 15:02 ]
Заголовок сообщения:  Re: Входящий поток

prospero78 писал(а):
Я вот как раз глобальные и объявлял.
Странно, почему для локальных такое допущение. Может кто-то запилет обнуление локальных? Это же будет методически верно? xor eax, eax; push eax; сделать не в напряг же будет для INTEGER и SHORTREAL?
З.Ы. А в Go это лучше сделано, получается. Тоже заявлен, как язык системного программирования,)

Это активно обсуждалось в Центре, в целом есть за и против, но особой необходимости нет. Вызов процедур должен быть "дешевым", если при вызове процедуры должны происходить инициализации, то она станет жирнее, рекуррентные алгоритмы будут работать медленно.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/