OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 06 Август, 2020 04:54

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




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Узнать размер стека
СообщениеДобавлено: Понедельник, 13 Январь, 2020 16:28 
Аватара пользователя

Зарегистрирован: Понедельник, 13 Январь, 2020 15:49
Сообщения: 6
дана программа вывода чисел Фибоначчи

MODULE Fibonacci;
IMPORT StdLog;
PROCEDURE Do*;
VAR
a, b, c, i, n: INTEGER;
BEGIN
a := 0;
b := 1;
n := 9;
FOR i := 0 TO n DO
c := b;
b := a + b;
a := c;
StdLog.Int( c );
END;
END Do;
END Fibonacci.

все просто-выводит 10 чисел.Если однако убрать строчку n := 9; то программа начнет выводить бесконечное число цифр пока блекбох не зависнет с надписью "NOT RESPONDING".
Ясное дело что отведенный операционной системой стек оказался переполненым и ОС аварийно остановила программу.Вопрос: как узнать/вычислить сколько чисел максимально может выдать программа не зависнув?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Понедельник, 13 Январь, 2020 18:16 

Зарегистрирован: Пятница, 11 Январь, 2019 19:26
Сообщения: 149
Откуда: Russia
А причем здесь стек?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Понедельник, 13 Январь, 2020 19:03 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2808
Блэкбокс никогда не инициализирует переменные базовых типов внутри процедур.
Это важное свойство для скорости выполнения программ, а также для обучения начинающих программистов.
Поэтому ваша обязанность присвоить n какое-то значение.
Обнаружить такие ошибки в коде помогает команда Инфо -> Анализировать модуль

Вложение:
Снимок экрана от 2020-01-13 23-03-02.png
Снимок экрана от 2020-01-13 23-03-02.png [ 45.7 КБ | Просмотров: 1349 ]


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Понедельник, 13 Январь, 2020 19:22 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2808
Теперь, если понять ваш вопрос иначе...

Начнем с того, что Блэкбокс не завис, а продолжает выполнять ваше задание.
Но Windows думает, что он завис, поэтому показывает вам сообщение.
Он так думает, потому что Блэкбокс перестал отвечать на системные сообщения.

Чтобы ББ отвечал на них, и иногда обновлял интерфейс, надо в ваш цикл вставить вызов вот такой процедуры:
Код:
   PROCEDURE ProcessMessages;
      VAR msg: Win.MSG; res: INTEGER;
   BEGIN
      WHILE Win.PeekMessage(msg, 0, 0, 0, Win.PM_REMOVE) # 0 DO
         res := Win.TranslateMessage(msg); res := Win.DispatchMessageA(msg)
   END END ProcessMessages;

Спасибо Штирлицу, что когда-то показал мне такое решение: viewtopic.php?f=31&t=1937&p=39240#p39240

Получится вот такой код:

Код:
MODULE Fibonacci;

IMPORT StdLog, Win := WinApi;

PROCEDURE ProcessMessages;
   VAR msg: Win.MSG; res: INTEGER;
BEGIN
   WHILE Win.PeekMessage(msg, 0, 0, 0, Win.PM_REMOVE) # 0 DO
      res := Win.TranslateMessage(msg); res := Win.DispatchMessageA(msg)
END END ProcessMessages;

PROCEDURE Do*;
VAR
   a, b, c, i, n: INTEGER;
BEGIN
   a := 0;
   b := 1;
   n := 900000;
   FOR i := 0 TO n DO
      c := b;
      b := a + b;
      a := c;
      StdLog.Int( c );
      IF i MOD 10000 = 0 THEN
         ProcessMessages
      END
   END;
END Do;

END Fibonacci.


Однако более правильное решение часто - это разбить вычисления на порции и организовать в очередь рекурсивно устанавливающихся событий.
Этот вопрос обсуждался тут:
viewtopic.php?f=1&t=130


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Понедельник, 13 Январь, 2020 19:42 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1294
Иван Денисов писал(а):
В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти.
Поэтому программа выполняется очень долго.

Каким бы большим оно не было, это 32-битное число, программа не должна выполнятся слишком долго. Здесь дело в том, что слишком много пишется в журнал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Понедельник, 13 Январь, 2020 19:46 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2808
Сочетание двух факторов ;)

Сложность тела цикла + Число повторений цикла

А сложность может быть большой и без вывода в журнал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Четверг, 09 Июль, 2020 09:48 

Зарегистрирован: Вторник, 07 Июль, 2020 15:52
Сообщения: 1
Trurl писал(а):
Иван Денисов писал(а):
В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти.
Поэтому программа выполняется очень долго.

Каким бы большим оно не было, это 32-битное число, программа не должна выполнятся слишком долго. Здесь дело в том, что слишком много пишется в журнал.

А можно по подробней в этом плане?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Узнать размер стека
СообщениеДобавлено: Суббота, 11 Июль, 2020 13:12 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1294
Для любого 32-битного числа (кроме одного) собственно вычисления займут не более нескольких секунд. Но запись в журнал такого количества информации, а затем её отображение - большая нагрузка на систему.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

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


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

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


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

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