Автор Тема: Параметры подпрограммы  (Прочитано 5083 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3383
  • Лечу куда хочу. cman 4.13.014x32, W10, W7
    • Просмотр профиля
Параметры подпрограммы
« : Июль 09, 2014, 10:59:53 am »
Переменная содержащая массив не передаётся в качестве параметра для подпрограммы.
От массива остаётся нулевой элемент.
Код: Clickermann
  1. LOGCLEAR
  2.  
  3. SUB(LOG_ARR, $ARR_LOG)
  4.   LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
  5.   FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
  6.      LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
  7.   END_CYC
  8.   LOGWRITE (" ")
  9. END_SUB
  10.  
  11. ARRPUSH($arr, 5)
  12. ARRPUSH($arr, 6)
  13. ARRPUSH($arr, 7)
  14. ARRPUSH($arr, 8)
  15. LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
  16. LOGWRITE ("Подпрограмма:")
  17. LOG_ARR($arr)

Лог:
11:59:33 Настоящий размер 4
11:59:33 Подпрограмма:
11:59:33 Размер массива: 1
11:59:33 [0] = 5
11:59:33 


Atas

  • Активный участник
  • ***
  • Сообщений: 136
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #1 : Июль 09, 2014, 01:37:44 pm »
В данном скрипте происходит следующее...

1 часть - Здесь наращивается до бесконечности массив $arr, и выводится размер этого массива в лог.
Код: Clickermann
  1. ARRPUSH($arr, 5)
  2. ARRPUSH($arr, 6)
  3. ARRPUSH($arr, 7)
  4. ARRPUSH($arr, 8)
  5. LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
  6. LOGWRITE ("Подпрограмма:")
  7. LOG_ARR($arr)

2 часть - Здесь вызывается описанная ранее подпрограмма LOG_ARR($arr) с параметром, отличным от параметра в описании подпрограммы. Происходит всего лишь запись в лог - "Размер массива: 1".
Код: Clickermann
  1. LOG_ARR($arr)

3 часть - А подпрограмма SUB(LOG_ARR, $ARR_LOG) с параметром, хоть и описана, но больше нигде в скрипте не используется с этим параметром, переменная  $ARR_LOG всегда будет иметь значение 0. А в лог выводится "Размер массива: ",ARRSIZE($ARR_LOG), всегда равный единице.
Код: Clickermann
  1. SUB(LOG_ARR, $ARR_LOG)
  2.  LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
  3.  FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
  4.     LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
  5.  END_CYC
  6.  LOGWRITE (" ")
  7. END_SUB
Или я чего то не понял, или это развод...

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3383
  • Лечу куда хочу. cman 4.13.014x32, W10, W7
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #2 : Июль 09, 2014, 02:34:14 pm »
Или я чего то не понял, или это развод...
Ты не понял.
В чём состоит развод?

В данном скрипте происходит следующее...
1 часть - Здесь наращивается до бесконечности массив $arr, и выводится размер этого массива в лог.
Почему до бесконечности? Это пример для демонстрации набросан на коленке. И т.к. предназначается не новичкам то не указан HALT и прочая лабуда.

2 часть - Здесь вызывается описанная ранее подпрограмма LOG_ARR($arr) с параметром, отличным от параметра в описании подпрограммы...".
Как может быть параметр отличный. У нас параметры позиционные, а не именованные. Там при передаче вообще могло стоять число без всякого имени.  ???
Мы передаём в подпрограмму ЗНАЧЕНИЕ параметра, а не его имя. В подпрограмме, в заголовке, значение присваивается переменной.

...переменная  $ARR_LOG всегда будет иметь значение 0...

3. тоже неправильно, т.к. неправильно второе.
Переменная $ARR_LOG не имеет значение 0 она имеет значение
[0]-го элемента массива, в данном примере 5
« Последнее редактирование: Июль 09, 2014, 02:40:11 pm от Vint »


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3655
  • Котэ
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #3 : Июль 09, 2014, 03:28:17 pm »
Ну очевидно что в подпрограмме применять массив в качестве параметра нельзя. Это не ошибка. Просто это не реализовано пока что.
Передается только одна строка, нужно указать её

Код: Clickermann
  1. LOGCLEAR
  2.  
  3. SUB(LOG_ARR, $ARR_LOG)
  4.   LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
  5.   FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
  6.      LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
  7.   END_CYC
  8.   LOGWRITE (" ")
  9. END_SUB
  10.  
  11. ARRPUSH($arr, 5)
  12. ARRPUSH($arr, 6)
  13. ARRPUSH($arr, 7)
  14. ARRPUSH($arr, 8)
  15. LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
  16. LOGWRITE ("Подпрограмма:")
  17. LOG_ARR($arr[2])
  18.  
  19. HALT

Лог
16:30:46 Настоящий размер 4
16:30:46 Подпрограмма:
16:30:46 Размер массива: 1
16:30:46 [0] = 7
16:30:46 
« Последнее редактирование: Июль 09, 2014, 03:32:37 pm от Oraven »

Atas

  • Активный участник
  • ***
  • Сообщений: 136
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #4 : Июль 09, 2014, 03:59:57 pm »
А почему тогда так работает?
Код: Clickermann
  1. LOGCLEAR
  2.  
  3. ARRPUSH($arr, 5) // Создаем массив из четырех элементов
  4. ARRPUSH($arr, 6)
  5. ARRPUSH($arr, 7)
  6. ARRPUSH($arr, 8)
  7.  
  8. LOGWRITE ("Размер массива = ", ARRSIZE($arr)) // Проверяем размер массива
  9.  
  10. //--------------------------------
  11.  
  12. SUB(LOG_ARR, $arr)
  13.  
  14. ARRPUSH($arr, 9) // Добавим элементов в массив
  15. ARRPUSH($arr, 10)
  16. ARRPUSH($arr, 11)
  17.  
  18. LOGWRITE ("Действия с параметром подпрограммы: (вывод в лог значений элементов массива)")
  19.  
  20.   FOR($INARR,$INARR<ARRSIZE($arr))
  21.      LOGWRITE ("[",$INARR,"] = ",$arr[$INARR]) // Выводим в лог значения элементов массива
  22.   END_CYC
  23.  
  24. END_SUB
  25.  
  26. //--------------------------------
  27.  
  28. LOG_ARR($arr)
  29.  
  30. LOGWRITE (STRCONCAT("Новый размер массива = ", ARRSIZE($arr), " (т.к.локальные переменные подпрограммы (параметры) при этом будут уничтожены).")) // Повторно проверяем размер массива
  31.  
  32. HALT // Полная остановка выполнения скрипта (это я для себя)
« Последнее редактирование: Июль 09, 2014, 04:05:21 pm от Atas »

aden

  • Оплот сообщества
  • ****
  • Сообщений: 363
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #5 : Июль 09, 2014, 05:00:16 pm »
при вызове саба с ключом(переменной) представляющей массив,  она переиницилизируется в локальную переменную.
Зачем вообще нужно передавать массив в вызов саба, если внутри саба ваш заранее инициилизированый массив и так будет доступен, ведь в кликермане все переменные изначально публичны/глобальны.
vk.com/clickermannclubskype: aden16rus
Скрипты для троецарствие | darkorbit | драконы вечности | timezero
[spoiler=начинающие программисты]

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3383
  • Лечу куда хочу. cman 4.13.014x32, W10, W7
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #6 : Июль 09, 2014, 06:07:00 pm »
Я и не говорю что это ошибка. Но в том виде как оно сейчас не есть хорошо. Я в курсе что тоже самое при выводе массива в лог.
Передавать нужно конечно не здесь. Это пример. Передавал я в саб в инклюде у которого свои имена переменных. Вся идея из-за этого провалилась. Помнить и использовать имена переменных в стандартных удобных инклюдах когда есть передача параметров не есть хорошо.


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3655
  • Котэ
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #7 : Июль 09, 2014, 06:22:05 pm »
Дело тут в том что нельзя просто так скопировать массив

Код: Clickermann
  1. ARRPUSH($arr, 5)
  2. ARRPUSH($arr, 6)
  3. ARRPUSH($arr, 7)
  4. ARRPUSH($arr, 8)
  5.  
  6. $arr2 = $arr // получим не копию а всего лишь одно значение
  7. LOGWRITE ("размер ", ARRSIZE($arr2))
  8.  
  9. HALT

Тоже самое происходит и при передаче параметра

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3383
  • Лечу куда хочу. cman 4.13.014x32, W10, W7
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #8 : Июль 10, 2014, 07:33:49 am »
Это я знаю. Я и предлагал давно сделать копирование массивов простым присваиванием. Ответили, что скопировать в цикле не проблема.
Оно то не проблема, но ведь потянуло ещё несколько неприятностей.
Вот и рекомендую чтобы имя массива отдельно тоже означало/ссылалось на сам массив не только как аргументы функций.
Сейчас имя без индекса используется только внутри своих+поисковых функциях.


Bitya

  • Зашел в гости
  • *
  • Сообщений: 7
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #9 : Январь 21, 2020, 07:02:24 pm »
Не знаю на сколько актуально, и заранее извиняюсь за археологию, но даже при одной мысли о массовом использовании нечто подобного, сразу хочется ударить себя молотком по пальцам ;D
Зачем вообще нужно передавать массив в вызов саба, если внутри саба ваш заранее инициилизированый массив и так будет доступен, ведь в кликермане все переменные изначально публичны/глобальны.
Всё же не кошерно везду и всюду работать с глобальными переменными.

По этому в голову пришел примерно следующий костыль:
1) Перед передачей массива в процедуру преобразовывать его в строку(с разделителями, которые точно не будут попадатся в виде элементов массива)
2) Передавать в процедуру уже строку
3) В процедуре эту строку парсить по разделителям в массив и уже дальше с ним работать

В коде это должно выглядеть примерно так

Код: Clickermann
  1. SUB(ArrSmpl, $LocalString)
  2.   STRSEPARATE($LocalString,"_",$LocalArray) //парсим сроку в УЖЕ локальный массив по заранее заданному разделителю
  3.   FOR($i=0, $i < ARRSIZE($LocalArray))
  4.      LOGWRITE($LocalArray[$i]) //ну и дальше можно работать с элементами массива как нам удобно
  5.   END_CYC
  6. END_SUB
  7.  
  8.  
  9. $GlobalArray[0] = 1 //инициализируем переменные
  10. $GlobalArray[1] = 2
  11. $GlobalArray[2] = 3
  12. $GlobalArray[3] = 4
  13. $GlobalArray[4] = 5
  14.  
  15. $string = ""
  16. FOR($i=0, $i < ARRSIZE($GlobalArray)) //запихиваем элементы массива в строку
  17.   $string = STRCONCAT($string,$GlobalArray[$i],"_") //разделителем в данном случае выступает нижнее подчеркивание
  18. END_CYC
  19. ArrSmpl($string)
  20.  
  21. HALT

По идее, аналогичным способом можно и возвращать массивы из процедур. Надеюсь кому-то будет полезным.

Космич

  • Активный участник
  • ***
  • Сообщений: 236
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #10 : Январь 22, 2020, 05:37:57 am »
Уже давно есть GETVAR/SETVAR
Код: Clickermann
  1. SUB(_ARR_OUTPUT, $_arrName, $_strName, $_start, $_stop, $_step)
  2.   $_stop = $_stop*$_step
  3.   WHILE($_start*$_step <= $_stop)
  4.      SETVAR($_strName, STRCONCAT(GETVAR($_strName), GETVAR(STRCONCAT($_arrName, "[", $_start, "]"))))    
  5.      INC($_start, $_step)
  6.   END_CYC
  7. END_SUB
  8.  
  9. STRSEPARATE("0,1,2,3,4,5,6,7,8,9", ",", $arr)
  10.  
  11. $output_str = ""
  12.  
  13. _ARR_OUTPUT("$arr", "$output_str", ARRSIZE($arr)-1, INT(ARRSIZE($arr)/2), -1) // Заполнение строки в обратном порядке половиной массива
  14.  
  15. PRINT($output_str)
  16.  
  17. HALT
«Иногда ты ваяешь до тех пор, пока до тебя не дойдёт, что именно ты делаешь.»

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3383
  • Лечу куда хочу. cman 4.13.014x32, W10, W7
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #11 : Январь 23, 2020, 10:43:37 pm »
Уже давно есть GETVAR/SETVAR
Прикольное решение. Но всё равно это как-то ненормально. Действие же простое, зачем такие костыли. Ни в одном языке подобного не видел. Не говоря уж проотерю скорости на этих циклах преобразования.

Пока возьмём на заметку, но просим сделать нормальную передачу массивов (и присваивание заодно).
« Последнее редактирование: Январь 23, 2020, 10:45:19 pm от Vint »


dramster

  • Герой форума
  • *****
  • Сообщений: 1031
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #12 : Январь 23, 2020, 11:22:29 pm »
Это я знаю. Я и предлагал давно сделать копирование массивов простым присваиванием.

Пока возьмём на заметку, но просим сделать нормальную передачу массивов (и присваивание заодно).

Так уже все есть  - ARRCONCAT

На деле это будет как-то так (не совсем то что требовалось, но работать должно быстро и без лишних заморочек):
Код: Clickermann
  1. LOGCLEAR
  2.  
  3. SUB(LOG_ARR)
  4.   LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
  5.   FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
  6.      LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
  7.   END_CYC
  8.   LOGWRITE (" ")
  9. END_SUB
  10.  
  11. ARRPUSH($arr, 5)
  12. ARRPUSH($arr, 6)
  13. ARRPUSH($arr, 7)
  14. ARRPUSH($arr, 8)
  15. LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
  16. LOGWRITE ("Подпрограмма:")
  17.  
  18. ARRCONCAT ($ARR_LOG, $arr)
  19. LOG_ARR()
  20.  
  21. halt

Код: Text
  1. 23:18:07 Настоящий размер 4
  2. 23:18:07 Подпрограмма:
  3. 23:18:07 Размер массива: 4
  4. 23:18:07 [0] = 5
  5. 23:18:07 [1] = 6
  6. 23:18:07 [2] = 7
  7. 23:18:07 [3] = 8
  8. 23:18:07  
  9.  


Bitya

  • Зашел в гости
  • *
  • Сообщений: 7
    • Просмотр профиля
Re: Параметры подпрограммы
« Ответ #13 : Январь 30, 2020, 05:04:57 pm »
Уже давно есть GETVAR/SETVAR
Да, тоже решение. Но как по мне - обращатся к элементам массива через array[index] всё же поудобней чем через конструкции GETVAR/SETVAR.
В прочем, описанный ранее мною способ подходит только для передачи данных "в". Для возвращения значений, вообще любых и массивов в частности, "из" процедуры без GETVAR/SETVAR не обойтись.

Так уже все есть  - ARRCONCAT

На деле это будет как-то так (не совсем то что требовалось, но работать должно быстро и без лишних заморочек):
В данном примере всёравно процедура обращается к глобальной переменной. Суть темы же в том, чтобы передавать массив в процедуру параметром.

p.s. А что за функция ARRCONCAT такая? В версии 4.13 об ней не слова нету в справке.