Author Topic: Код работает, но вот почему?  (Read 1146 times)

0 Members and 1 Guest are viewing this topic.

Пытливый

  • Освоившийся
  • **
  • Posts: 21
    • View Profile
Код работает, но вот почему?
« on: October 08, 2017, 11:12:35 PM »
Странная ситуация, не пойму почему код работает правильно. :)
В общем не получилось с рекурсией, я попробовал сделать это иным способом:
Code: [Select]
ArrPush($AActionName, "Город")
ArrPush($AActionName, "Таверна")
ArrPush($AActionName, 100)
ArrPush($AActionName, 100)
ArrPush($AActionName, "Таверна")
ArrPush($AActionName, "Окорок")
ArrPush($AActionName, 10)
ArrPush($AActionName, 10)

sub(Activate, $ActionName)
EnterToSubActivate:
   print($ActionName)
   $ActionIndex = 0
   $ActionRecognized = 1
   while (($ActionRecognized = 1) & ($ActionIndex < ArrSize($AActionName)/4))
      if ($AActionName[$ActionIndex*4+1] = $ActionName)
         $ActionRecognized = 0
         
         ArrPush($ActivateVar, $ActionName)
         ArrPush($ActivateVar, $ActionIndex)
         ArrPush($ActivateVar, $ActionRecognized)
         $ActionName = $AActionName[$ActionIndex*4]
         Goto(EnterToSubActivate)
ExitFromSubActivate:         
         $ActionRecognized = ArrPop($ActivateVar)
         $ActionIndex = ArrPop($ActivateVar)
         $ActionName = ArrPop($ActivateVar)
         
         Move($AActionName[$ActionIndex*4+2], $AActionName[$ActionIndex*4+3])
         LClick(-1, -1)
      else
         Inc($ActionIndex)
      end_if
   end_cyc
   Goto(ExitFromSubActivate)
end_sub

print("Start")
Activate("Окорок")
print("Finish")
Я не пойму, почему код у меня завершается? 
Инструкция Goto(ExitFromSubActivate) должна в вечный цикл загонять код, но нет, все завершается вполне пристойно. ???
По ошибке внутренней что-ли?

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Код работает, но вот почему?
« Reply #1 on: October 09, 2017, 08:32:23 AM »
Потому... что выпрыгивать и впрыгивать в цикл по GOTO плохая идея.
Ты зашёл в известную тему, но благодаря удачливости зашёл с другого конца. Обычно происходит наоборот  :) ;D
http://crapware.aidf.org/forum/index.php?topic=3429.msg23483#msg23483

Что у тебя? Да всё то же самое. После того как ты вышел из цикла while и добрался до GOTO (стр. 35) на вершине стека как раз оказывается адрес возврата из подпрограммы. Если бы не GOTO end_sub снял бы этот адрес с вершины и вернулся бы куда положено.
Но через Goto ты продлил ему агонию направив внутрь цикла минуя начало. Выполнились строки 25-30 и выполнение дошло до end_cyc. Который должен снять с вершины стека адрес начала цикла и перейти туда (ведь работают окончания почти одинаково), но на вершине стека нет никакого адреса начала цикла, там только упомянутый выше возврат из подпрограммы. Вот туда нас судьба и выбрасывает.

Даже если для тебя сейчас это хорошо и "так и нужно", лучше перепиши по нормальному и так не делай никогда.
Пока скрипт как этот из 40 строк найти причину такого поведения не сложно. Когда скрипт будет в 3000 строк и такие выкрутасы будут в нём повсеместно... ну ты понял. Ты не сможешь быть ни в чём уверен, не зная куда тебя телепортирует в очередном месте.


Пытливый

  • Освоившийся
  • **
  • Posts: 21
    • View Profile
Re: Код работает, но вот почему?
« Reply #2 on: October 09, 2017, 07:30:30 PM »
Что так делать "стремно" я понимаю, но вот как сделать иначе не могу сообразить, уж очень сильно я в рекурсию "врос". То что код сработал как хотелось бы, а не как ожидаемо - не мой стиль, поэтому я и задал вопрос. :) Как курьез его можно использовать, но ни в коем случае как готовое решение.