Author Topic: Параметры подпрограммы  (Read 9565 times)

0 Members and 1 Guest are viewing this topic.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Параметры подпрограммы
« on: July 09, 2014, 10:59:53 AM »
Переменная содержащая массив не передаётся в качестве параметра для подпрограммы.
От массива остаётся нулевой элемент.
Code: (clickermann) [Select]
LOGCLEAR

SUB(LOG_ARR, $ARR_LOG)
   LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
   FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
      LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
   END_CYC
   LOGWRITE (" ")
END_SUB

ARRPUSH($arr, 5)
ARRPUSH($arr, 6)
ARRPUSH($arr, 7)
ARRPUSH($arr, 8)
LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
LOGWRITE ("Подпрограмма:")
LOG_ARR($arr)

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


Atas

  • Активный участник
  • ***
  • Posts: 147
    • View Profile
Re: Параметры подпрограммы
« Reply #1 on: July 09, 2014, 01:37:44 PM »
В данном скрипте происходит следующее...

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

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

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Параметры подпрограммы
« Reply #2 on: July 09, 2014, 02:34:14 PM »
Или я чего то не понял, или это развод...
Ты не понял.
В чём состоит развод?

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

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

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

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


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Параметры подпрограммы
« Reply #3 on: July 09, 2014, 03:28:17 PM »
Ну очевидно что в подпрограмме применять массив в качестве параметра нельзя. Это не ошибка. Просто это не реализовано пока что.
Передается только одна строка, нужно указать её

Code: (clickermann) [Select]
LOGCLEAR

SUB(LOG_ARR, $ARR_LOG)
   LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
   FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
      LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
   END_CYC
   LOGWRITE (" ")
END_SUB

ARRPUSH($arr, 5)
ARRPUSH($arr, 6)
ARRPUSH($arr, 7)
ARRPUSH($arr, 8)
LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
LOGWRITE ("Подпрограмма:")
LOG_ARR($arr[2])

HALT

Лог
Code: [Select]
16:30:46 Настоящий размер 4
16:30:46 Подпрограмма:
16:30:46 Размер массива: 1
16:30:46 [0] = 7
16:30:46 
« Last Edit: July 09, 2014, 03:32:37 PM by Oraven »

Atas

  • Активный участник
  • ***
  • Posts: 147
    • View Profile
Re: Параметры подпрограммы
« Reply #4 on: July 09, 2014, 03:59:57 PM »
А почему тогда так работает?
Code: (clickermann) [Select]
LOGCLEAR

ARRPUSH($arr, 5) // Создаем массив из четырех элементов
ARRPUSH($arr, 6)
ARRPUSH($arr, 7)
ARRPUSH($arr, 8)

LOGWRITE ("Размер массива = ", ARRSIZE($arr)) // Проверяем размер массива

//--------------------------------

SUB(LOG_ARR, $arr)

ARRPUSH($arr, 9) // Добавим элементов в массив
ARRPUSH($arr, 10)
ARRPUSH($arr, 11)

LOGWRITE ("Действия с параметром подпрограммы: (вывод в лог значений элементов массива)")
   
   FOR($INARR,$INARR<ARRSIZE($arr))
      LOGWRITE ("[",$INARR,"] = ",$arr[$INARR]) // Выводим в лог значения элементов массива
   END_CYC
   
END_SUB

//--------------------------------

LOG_ARR($arr)

LOGWRITE (STRCONCAT("Новый размер массива = ", ARRSIZE($arr), " (т.к.локальные переменные подпрограммы (параметры) при этом будут уничтожены).")) // Повторно проверяем размер массива

HALT // Полная остановка выполнения скрипта (это я для себя)
« Last Edit: July 09, 2014, 04:05:21 PM by Atas »

aden

  • Оплот сообщества
  • ****
  • Posts: 363
    • View Profile
Re: Параметры подпрограммы
« Reply #5 on: July 09, 2014, 05:00:16 PM »
при вызове саба с ключом(переменной) представляющей массив,  она переиницилизируется в локальную переменную.
Зачем вообще нужно передавать массив в вызов саба, если внутри саба ваш заранее инициилизированый массив и так будет доступен, ведь в кликермане все переменные изначально публичны/глобальны.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Параметры подпрограммы
« Reply #6 on: July 09, 2014, 06:07:00 PM »
Я и не говорю что это ошибка. Но в том виде как оно сейчас не есть хорошо. Я в курсе что тоже самое при выводе массива в лог.
Передавать нужно конечно не здесь. Это пример. Передавал я в саб в инклюде у которого свои имена переменных. Вся идея из-за этого провалилась. Помнить и использовать имена переменных в стандартных удобных инклюдах когда есть передача параметров не есть хорошо.


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Параметры подпрограммы
« Reply #7 on: July 09, 2014, 06:22:05 PM »
Дело тут в том что нельзя просто так скопировать массив

Code: (clickermann) [Select]
ARRPUSH($arr, 5)
ARRPUSH($arr, 6)
ARRPUSH($arr, 7)
ARRPUSH($arr, 8)

$arr2 = $arr // получим не копию а всего лишь одно значение
LOGWRITE ("размер ", ARRSIZE($arr2))

HALT

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

Vint

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


Bitya

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

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

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

Code: (clickermann) [Select]
SUB(ArrSmpl, $LocalString)
   STRSEPARATE($LocalString,"_",$LocalArray) //парсим сроку в УЖЕ локальный массив по заранее заданному разделителю
   FOR($i=0, $i < ARRSIZE($LocalArray))
      LOGWRITE($LocalArray[$i]) //ну и дальше можно работать с элементами массива как нам удобно
   END_CYC
END_SUB


$GlobalArray[0] = 1 //инициализируем переменные
$GlobalArray[1] = 2
$GlobalArray[2] = 3
$GlobalArray[3] = 4
$GlobalArray[4] = 5

$string = ""
FOR($i=0, $i < ARRSIZE($GlobalArray)) //запихиваем элементы массива в строку
   $string = STRCONCAT($string,$GlobalArray[$i],"_") //разделителем в данном случае выступает нижнее подчеркивание
END_CYC
ArrSmpl($string)

HALT

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

Космич

  • Активный участник
  • ***
  • Posts: 265
    • View Profile
Re: Параметры подпрограммы
« Reply #10 on: January 22, 2020, 05:37:57 AM »
Уже давно есть GETVAR/SETVAR
Code: (clickermann) [Select]
SUB(_ARR_OUTPUT, $_arrName, $_strName, $_start, $_stop, $_step)
   $_stop = $_stop*$_step
   WHILE($_start*$_step <= $_stop)
      SETVAR($_strName, STRCONCAT(GETVAR($_strName), GETVAR(STRCONCAT($_arrName, "[", $_start, "]"))))   
      INC($_start, $_step)
   END_CYC
END_SUB

STRSEPARATE("0,1,2,3,4,5,6,7,8,9", ",", $arr)

$output_str = ""

_ARR_OUTPUT("$arr", "$output_str", ARRSIZE($arr)-1, INT(ARRSIZE($arr)/2), -1) // Заполнение строки в обратном порядке половиной массива

PRINT($output_str)
 
HALT
«Иногда ты ваяешь до тех пор, пока до тебя не дойдёт, что именно ты делаешь.»

Vint

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

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


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Параметры подпрограммы
« Reply #12 on: January 23, 2020, 11:22:29 PM »
Это я знаю. Я и предлагал давно сделать копирование массивов простым присваиванием.

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

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

На деле это будет как-то так (не совсем то что требовалось, но работать должно быстро и без лишних заморочек):
Code: (clickermann) [Select]
LOGCLEAR

SUB(LOG_ARR)
   LOGWRITE ("Размер массива: ",ARRSIZE($ARR_LOG))
   FOR($INARR,$INARR<ARRSIZE($ARR_LOG))
      LOGWRITE ("[",$INARR,"] = ",$ARR_LOG[$INARR])
   END_CYC
   LOGWRITE (" ")
END_SUB

ARRPUSH($arr, 5)
ARRPUSH($arr, 6)
ARRPUSH($arr, 7)
ARRPUSH($arr, 8)
LOGWRITE ("Настоящий размер ", ARRSIZE($arr))
LOGWRITE ("Подпрограмма:")

ARRCONCAT ($ARR_LOG, $arr)
LOG_ARR()

halt

Code: (текст) [Select]
23:18:07 Настоящий размер 4
23:18:07 Подпрограмма:
23:18:07 Размер массива: 4
23:18:07 [0] = 5
23:18:07 [1] = 6
23:18:07 [2] = 7
23:18:07 [3] = 8
23:18:07 


Bitya

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

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

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

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