Author Topic: подпрограммы и передача переменных  (Read 4823 times)

0 Members and 1 Guest are viewing this topic.

lokipall

  • Зашел в гости
  • *
  • Posts: 17
    • View Profile
вопрос не по этой тепе но что бы не плодить темы возможно похожие.
так вот: Возможно ли передать переменную в подпрограмму через другую подпрограмму
подробнее: есть у меня например program1 она в определенный момент вызывает файл program2 и процессе выполнения Программы№2 вызывается program3 которая использует переменную которая задана еще в Программе№1. вот можно такой бред реализовать?все 3 программы в разных файлах
я думал хватит на это такой конструкции:
Code: [Select]
#name "program1"
#include "program2.cms"
DEFINE($x ,0)
DEFINE($y , 0)
print($x,$y)
program2($x,$y)
halt
Code: [Select]
SUB(program2)
#include "program3.cms"
$y=$y+1
print($x,$y)
program3($x,$y)
END_SUB
Code: [Select]
SUB(program3)
$x=$x+1
print($x,$y)
END_SUB
но тест выдал очень интересный результат:
[spoiler]
логи:
14:32:27 01
14:32:27 11
14:32:27 12
14:32:27 22
14:32:27 32
14:32:27 42
14:32:27 52
14:32:27 62
14:32:27 63
14:32:27 73
14:32:27 73
14:32:27 83
14:32:27 93
14:32:27 103
14:32:27 113
14:32:27 123
14:32:27 123
14:32:27 123
14:32:27 123
14:32:27 123

[/spoiler]
я надеялся что он выведет значения 00 потом вызовет программу номер 2 выведет значение 01 далее вызовет 3 программу выведет значения 11 ( или может значения 10 хотел за одно проверить изменения  передадутся или что в DEFINE написал то и будет) и тут должен был найти строку halt в первой программе но получил я то что получил.
а что бы было не скучно он мне выдает :

ошибка при вызове функции POP()
Прерывать выполнение сценария?


а за тем

ошибка при интерпретации строки JMP(POP())
Прерывать выполнение сценария?


собственно это окончательно подорвало мое понимание

кто нибудь подскажите
1)что за бред у меня вышел? откуда рекурсия если end_sub прописывал
2) как надо грамотно передавать переменные через программу из первой в третью
3) эта идея жизнеспособна или так не делают?

PS.подумал почитал исправил объявление имени подпрограммы на вид
Code: [Select]
SUB(program2,$x,$y) ошибки теже, только логов не выдает вообще
начинаю подозревать что так можно передавать только параметры а вот переменные не получается почему то... нужен умный совет

PPS программа с одной подпрограммой вроде работают корректно
Code: [Select]
#name "program1"
#include "program2.cms"
DEFINE($x ,0)
DEFINE($y , 0)
print($x,$y)
program2($x,$y)
halt
Code: [Select]
SUB(program2)
#include "program3.cms"
$y=$y+1
print($x,$y)
program3($x,$y)
END_SUB
« Last Edit: December 22, 2016, 02:17:54 PM by lokipall »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: подпрограммы и передача переменных
« Reply #1 on: December 22, 2016, 02:52:12 PM »
Тело любой подпрограммы должно быть описано в корне скрипта.

#include  фактически вставляет код из файла на своё место.
У тебя подпрограмма program3 описана внутри другой подпрограммы, что неправильно

Code: (clickermann) [Select]
SUB(program2)
   #include "program3.cms"
   ...
END_SUB

что в итоге выглядит как
Code: (clickermann) [Select]
SUB(program2)
   SUB(program3)
   ...
   END_SUB
   ...
END_SUB

Вынеси инклюд за SUB
Code: (clickermann) [Select]
#include "program3.cms"
SUB(program2)
   ...
END_SUB

или совсем собирай всё в главном скрипте
Code: (clickermann) [Select]
#name "program1"
#include "program3.cms"
#include "program2.cms"
...

Надеюсь это пример?
« Last Edit: December 22, 2016, 02:54:15 PM by Vint »


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: подпрограммы и передача переменных
« Reply #2 on: December 22, 2016, 02:57:30 PM »
И просто запомни, если в инклюде есть подпрограммы или потоки, его нельзя пихать ни в какие конструкции.
А лучше никогда этого не делать и будет всё OK.


lokipall

  • Зашел в гости
  • *
  • Posts: 17
    • View Profile
Re: подпрограммы и передача переменных
« Reply #3 on: December 22, 2016, 04:05:39 PM »
И просто запомни, если в инклюде есть подпрограммы или потоки, его нельзя пихать ни в какие конструкции.
А лучше никогда этого не делать и будет всё OK.
кажется понял, сейчас попробую исправить, спасибо. еще вопрос. в качестве пораметра в подпрограмму массив из скажем 10 переменных можно передать?

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: подпрограммы и передача переменных
« Reply #4 on: December 22, 2016, 04:36:14 PM »
Передача массивов не реализована. Только обычные переменные.
Пока так обходись, глобальными переменными.


Луций

  • Активный участник
  • ***
  • Posts: 248
  • чат в телеге: https://t.me/klickermannchat
    • View Profile
    • Пишу скрипты на заказ:
Re: подпрограммы и передача переменных
« Reply #5 on: December 22, 2016, 06:40:11 PM »
ребята вы почти изобрели наследование и полиморфизм, не останавливайтесь

lokipall

  • Зашел в гости
  • *
  • Posts: 17
    • View Profile
Re: подпрограммы и передача переменных
« Reply #6 on: December 23, 2016, 09:45:28 AM »
ребята вы почти изобрели наследование и полиморфизм, не останавливайтесь
чукча не понимать таких сложных слов, чукча по клавишам тык тык, монитор мигать, чукча хорошоо-о-о-о
( а серьезно я объектно ориентированное программирование знать не знаю,и вообще как то долег от составления кодов, так что прошу прощения если ошибки грубые или глупые)
Quote
Передача массивов не реализована. Только обычные переменные.
Пока так обходись, глобальными переменными.
вчера ответ не прочитал попробовал, и пять переменных передалось, это я терминологию перепутал или работает случайно и еще глюки будут:
Code: [Select]
...................
FOR($c=1, $c <$n+1)  //перебераю фото в выбраной ранее папке
    IF_PICTURE_IN ($xt0+$a*$shag,$yt0,$xt0+($a+1)*$shag,$yt1, STRCONCAT("protivnik\protivnik_",$b,"_mehs\",$c,".bmp"), -1, 50)      //ищу фото
WAITMS(100)   
    $p[$a]=$b
    print(" НАШЕЛ на экране на ",$a," позиции фото №",$c," из папки ",$b," ) 
ELSE
print(" на экране на ",$a," позиции фото №",$c," из папки ",$b," ,НЕ найдено")     
END_IF
END_CYC
........................
pvpboi($p)
Code: [Select]
SUB (pvpboi,$p)

FOR($a=0, $a < 5)
print($p[$a])
END_CYC
END_SUB // Точка выхода из подпрограммы

вроде все работает все $p[a] выводит
эт корректно или надо писать как то по другому?


и еще вопрос а двухмерный массив тут можно прописать и как?
ну что бы у переменной $p было два индекса $a и $b в справке не нашел если оно там есть укажите где искать

PS вопрос не по теме а как вы код так красиво в форуме оформляете, в моих сообщениях почему то не так смотриться

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: подпрограммы и передача переменных
« Reply #7 on: December 23, 2016, 10:44:50 AM »
Зачем вставлять массив в вызов? В кликере все переменные и массивы глобальные. Кроме того все переменные участвующие в параметрах подпрограммы по её завершению обнуляются.

Пишем просто
Code: (clickermann) [Select]
SUB (pvpboi)
   FOR($a=0, $a < ARRSIZE($p))
      print($p[$a])
   END_CYC
END_SUB // Точка выхода из подпрограммы


FOR($c=1, $c<$n+1)  //перебераю фото в выбраной ранее папке
   IF_PICTURE_IN ($xt0+$a*$shag,$yt0,$xt0+($a+1)*$shag,$yt1, STRCONCAT("protivnik\protivnik_",$b,"_mehs\",$c,".bmp"), -1, 50)      //ищу фото
      WAITMS(100)
      $p[$a]=$b
      print(" НАШЕЛ на экране на ",$a," позиции фото №",$c," из папки ",$b," )
   ELSE
      print(" на экране на ",$a," позиции фото №",$c," из папки ",$b," ,НЕ найдено")
   END_IF
END_CYC


pvpboi()


HALT

Quote
и еще вопрос а двухмерный массив тут можно прописать и как?
ну что бы у переменной $p было два индекса $a и $b в справке не нашел если оно там есть укажите где искать
Массивы в кликере одномерные.

Quote
PS вопрос не по теме а как вы код так красиво в форуме оформляете, в моих сообщениях почему то не так смотриться
Обрати внимание на шапку форума, там как раз про это написано.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: подпрограммы и передача переменных
« Reply #8 on: December 23, 2016, 12:39:37 PM »
вчера ответ не прочитал попробовал, и пять переменных передалось, это я терминологию перепутал или работает случайно и еще глюки будут:

Все (почти) переменные глобальные.
Если не передавать как параметр, можно использовать основные переменные скрипта.
Code: (clickermann) [Select]
SUB(s1)
    print("$a sub1  ", $a)
    $a = $a + 1
END_SUB

$a = 5
print("$a до    ", $a)
s1()
print("$a после ", $a)
HALT

Code: [Select]
12:00:14 $a до    5
12:00:14 $a sub1  5
12:00:14 $a после 6

В этом случае массивы работают нормально.


Если переменную передавать как аргумент, то внутренняя переменная (параметр) принявшая аргумент - временная и после завершения подпрограммы удаляется.
Code: (clickermann) [Select]
SUB(s2, $b)
    print("$b sub2  ", $b)
    $b = $b + 2
    print("$b sub2  ", $b)
    print(" ")
END_SUB

$a = 5
$b = 100

print("$a до    ", $a)
print("$b до    ", $b)
print(" ")
s2($a)
print("$a после ", $a)
print("$b после ", $b)
HALT

Code: [Select]
12:06:05 $a до    5
12:06:05 $b до    100
12:06:05 
12:06:05 $b sub2  5
12:06:05 $b sub2  7
12:06:05 
12:06:05 $a после 5
12:06:05 $b после 0

Переменная $a передалась как аргумент в подпрограмму. Сама переменная так и осталась.
Параметр $b принял значение 5 переменной $a. Пока мы в подпрограмме, работаем с локальной $b. После выхода $b удалилась.
В этом случае массивы правильно не передаются, от массива остаётся [ 0 ] элемент. Длину показывает "1". Но все элементы пока на месте и к ним можно обращаться по индексу. Но что будет если эта память потребуется ХЗ. Принадлежат ли эти ячейки памяти по прежнему переменной или освободились не знаю. Это как с заданием сразу n-ного элемента...


Если имя параметра подпрограммы совпадает с именем переменной аргумента:
Т.к. имена все глобальные имеем побочный эффект.
Code: (clickermann) [Select]
SUB(s2, $a)
    print("$a sub2  ", $a)
    $a = $a + 2
    print("$a sub2  ", $a)
    print(" ")
END_SUB

$a = 5

print("$a до    ", $a)
print(" ")
s2($a)
print("$a после ", $a)
HALT

Code: [Select]
12:28:34 $a до    5
12:28:34 
12:28:34 $a sub2  5
12:28:34 $a sub2  7
12:28:34 
12:28:34 $a после 0

Параметр ПП $a совпал по имени с передаваемым аргументом $a. Всё как в преведущем примере, но т.к. заданы параметры при выходе переменная удалится (а она глобальная). То глобальная тю-тю.
Если в этом случае переменная массив, войдёт он так же сломанным, но при выходе ещё и уничтожится.
Code: (clickermann) [Select]
SUB(s2, $a)
    print("$a элементов sub2  ", $a)
    FOR($i=0, $i < 3)
       print($a[$i])
    END_CYC
   
    print(" ")
END_SUB

STRSEPARATE("1:2:3", ":", $a)

print("$a элементов до    ", ARRSIZE($a))
print(" ")
s2($a)
print("$a элементов после ", ARRSIZE($a))
HALT

Code: [Select]
112:23:53 $a элементов до    3
12:23:53 
12:23:53 $a элементов sub2  1   <<<--- ЗДЕСЬ ВНИМАНИЕ НА ВЫДАВАЕМЫЙ РАЗМЕР МАССИВА
12:23:53 1
12:23:53 2
12:23:53 3
12:23:53 
12:23:53 $a элементов после 0
« Last Edit: December 23, 2016, 12:42:35 PM by Vint »


lokipall

  • Зашел в гости
  • *
  • Posts: 17
    • View Profile
Re: подпрограммы и передача переменных
« Reply #9 on: December 23, 2016, 03:47:57 PM »
 Vint, спасибо очень доходчиво, для чайников, прям для меня.
Quote
Принадлежат ли эти ячейки памяти по прежнему переменной или освободились не знаю. Это как с заданием сразу n-ного элемента...
а это что за ошибка?
 может я ее тоже совершил уже и надо быстрей исправлять

Quote
Массивы в кликере одномерные.
сейчас стало очень грустно :-[ половина задумки летит в тар-тарары.

может кто сталкивался с задачей типа:
есть поле m на n клеток закрытое надо по одной открывать клеточки, при этом открыть модно только соседние с уже открытой если на уже открытой нет препятствия или врага,препятствия надо обходить по другим клеткам, врага бить, еще и бонусы могут валяться. открыть надо все.двигаться строго по горизонтали или вертикали получается очень нечасто из-за препятствий.

я надеялся через вайл гонять двумерный массив двумя форами, каждый элемент которого соответствует клетке а содержание клетки соответствует значению элемента массива.
 просто поиск по экрану будет затруднителен так как там куча одинаковых элементов, каждый элемент имеет (как я понял) два три варианта оттенков цветов( упрощение графики не очень помогает на показателе 5 только с 50 процентной точностью может найти, показатель 7 и выше превращает все в однотипные пятна) и что бы совсем не скучно было карта больше экрана по вертикале. вот такая вот задачка интересная...

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

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: подпрограммы и передача переменных
« Reply #10 on: December 23, 2016, 04:45:33 PM »
а это что за ошибка?
 может я ее тоже совершил уже и надо быстрей исправлять
Просто не передавай массив в подпрограмму как параметр и всё. Просто используй глобальную переменную.

Quote
Массивы в кликере одномерные.
сейчас стало очень грустно :-[ половина задумки летит в тар-тарары.
Чего там грустного. Высчитывай сам индексы псевдо многомерных массивов.
http://crapware.aidf.org/forum/index.php?topic=321.msg2686#msg2686
http://crapware.aidf.org/forum/index.php?topic=1138.msg5115#msg5115

На форуме куча скриптов написана с подобным использованием массивов.


lokipall

  • Зашел в гости
  • *
  • Posts: 17
    • View Profile
Re: подпрограммы и передача переменных
« Reply #11 on: December 23, 2016, 08:51:49 PM »
Vint спасибо еще раз, просвещаешь темного
Quote
Чего там грустного. Высчитывай сам индексы псевдо многомерных массивов.
http://crapware.aidf.org/forum/index.php?topic=321.msg2686#msg2686
http://crapware.aidf.org/forum/index.php?topic=1138.msg5115#msg5115

На форуме куча скриптов написана с подобным использованием массивов.

почитал... интересно...
с разделением  знаком вроде понял более менее ( скорее менее но попробую разберусь) но возник другой вопрос
Quote
формулу оффсета (смещения)
как записывать и как сравнивать  вроде понял.
а вот как в заполнено массиве искать элемент по значению а потом из его номера получить два параметра,  это его номер надо разделить на количество эллементов в строке взять целую часть а после из номера вычесть целую часть?

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: подпрограммы и передача переменных
« Reply #12 on: December 26, 2016, 10:17:00 AM »
с разделением  знаком вроде понял более менее ( скорее менее но попробую разберусь)
Разделение не нужно.

а вот как в заполнено массиве искать элемент по значению а потом из его номера получить два параметра,  это его номер надо разделить на количество эллементов в строке взять целую часть а после из номера вычесть целую часть?

Ну, да.


Code: (clickermann) [Select]
// 0   1   2   3   4   5   6
// 7   8   9  10  11  12  13
//14  15  16  17  18  19  20

//$arr[№колонки + №строки*длину строки]
//$arr[5 + 1*7] == 12


$R = 7 // количество элементов в ряду

FOR($i=0, $i < 21)
    ARRPUSH($arr, $i)
END_CYC

LOGWRITE($arr[5 + 1*$R])

// ищем по значению
FOR($i=0, $i < ARRSIZE($arr))
    IF($arr[$i] = 12)
        $row = INT($i / $R)
        $column = $i - $row*$R

        $i = ARRSIZE($arr)
    END_IF
END_CYC
LOGWRITE("row = ", $row, ",  column = ", $column)

HALT


lokipall

  • Зашел в гости
  • *
  • Posts: 17
    • View Profile
Re: подпрограммы и передача переменных
« Reply #13 on: December 26, 2016, 04:43:34 PM »
спасибо, очень помогли. тему закрою пожалуй,
тем кто после читать будет: строки и столбцы нумеруются с 0 не тупите как я