Forum.iFiction.Ru

iFiction.Ru · ifHub · FAQ · IFWiki · QSP · URQ · INSTEAD · AXMA

форум об interactive fiction, текстовых приключенческих играх и всём таком...

Вы не зашли.

0    0    #1
05.09.2011 21:28

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Особенности работы с массивами в QSP

Поиск пустых значений в несуществующем массиве:

Код:

*NL arrpos('probe659', 0)
*NL arrpos('$probe659', '')

вернёт позицию 0, т. е. первую позицию массива, хотя, по-хорошему, хотелось бы получать -1, то есть "не найдено".

Неактивен

0    0    #2
06.09.2011 17:49

Nex
Участник (+120, -130)
Зарегистрирован: 11.06.2007
Сообщений: 2053

---

Re: Особенности работы с массивами в QSP

Неинициализированные переменные и ячейки массивов, числовые и текстовые, имеют значения по умолчанию '' и 0 соответственно.
Если 0 не найден в массиве, то он будет найден сразу за последним элементом массива(в нулевой позиции, если массив пуст), то бишь в первой же неинициализированной ячейке.

При этом стоит учесть то обстоятельство, что массивы неразрывны и "пробелов" между элементами нет: массив располагает свои элементы в ячейках от 0 до N - 1, где N - количество всех существующих элементов массива.

по-хорошему, хотелось бы получать -1, то есть "не найдено"

Оба поведения корректны в своем контексте. Вопрос же заключается в том, какое предпочтительнее для авторов.

Существующий вариант выгоднее тем авторам(A), для которых нет различий между "присвоенным"(инициализированным) значением 0 и "пустым"(неинициализированным), использующим массивы в заранее определенном диапазоне индексов.

Вариант с поиском исключительно инициализированных значений удобнее тем авторам(B), у которых "полезными" считаются значения инициализированные, а "бесполезными" - неинициализированные, при этом длина массива варьируется.

Минус первого варианта для авторов A и B - им придется делать проверку на выход за границы массива при поиске нулевых значений.
Минус второго варианта для авторов A - для работы с массивами им придется инициализировать их нулями. Это противоречит правилу QSP, перенятому из Бэйсика: неинициализированный массив считается заполненным нулями. Придется вводить явное различие между инициализированным значением и неинициализированным(сейчас оно тоже есть, но неявное). С другой стороны, в Бэйсике массивы заранее объявленной длины, поэтому там контекст немного другой.

Отредактировано Nex (06.09.2011 22:56)

Неактивен

0    0    #3
06.09.2011 20:38

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Проблем с тем, что содержимое массива внутри интервала автоматически заполняется (или считается заполненным) нулями, нет. Однако ситуация, когда результат поиска возвращает результат, лежащий по сути вне пределов массива (который задал автор), довольно необычна.

Вдогонку к первому примеру код

Код:

probe[0]=10
probe[1]=20
probe[2]=30
*NL ARRSIZE('probe')
*NL ARRPOS('probe', 0)

вернёт размер массива, равный трём элементам, а позицию нуля — в четвёртом элементе.

Неактивен

0    0    #4
06.09.2011 22:19

Nex
Участник (+120, -130)
Зарегистрирован: 11.06.2007
Сообщений: 2053

---

Re: Особенности работы с массивами в QSP

Как раз в QSP-то, в отличие Бэйсика, размер массива и не задается!
Я писал об этом в предыдущем сообщении.

Массив считается теоретически бесконечным. Автор при использовании просто пользуется любыми ячейками массива на свое усмотрение.

Кстати, я был неправ насчет "пробелов" - они-таки инициализируются нулевыми значениями, начиная с нулевого индекса. Т.е. такой эксперимент:

Код:

probe[1]=20
probe[3]=30
ARRSIZE('probe')

выведет "4"!

Таким образом, весь интервал индексов, между последним инициализированным и нулевым(включительно), будет всегда заполнен как минимум "настоящими" нулями. Эта техника оказалась хитрее, чем я предполагал.

Но нулями он заполняется при присваивании. А как же удаление отдельных элементов через KILLVAR? Но KILLVAR тоже не оставляет пробелов! Как только из массива 1, 2, 3 мы удаляем 2, то получаем массив 1, 3 - два элемента на позициях 0 и 1 соответственно. "Хвост" массива сдвигается влево на 1, сохраняя массив неразрывным.

Раз целостность массивов сохраняется, то, пожалуй, стоит пересмотреть свои выводы.

Неактивен

0    0    #5
06.09.2011 22:40

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Nex написал:

Как раз в QSP-то, в отличие Бэйсика, размер массива и не задается!
Я писал об этом в предыдущем сообщении.
Массив считается теоретически бесконечным. Автор при использовании просто пользуется любыми ячейками массива на свое усмотрение.

Ну так я говорю не про указание максимальной размерности массива, а про то, каким этот массив представляет себе автор.

Даже если он учитывает нюансы автоматического заполнения интервалов в массиве, то после выполнения такой конструкции:

Код:

probe[3]=30

то есть ручного заполнения четвёртого элемента массива (и первых трёх — в автоматическом режиме), он ожидает, что размер массива будет равен 4. Если же он потом заполнит первые три элемента ненулевыми значениями, размер будет всё также равен 4. Но если он после этого поищет в массиве (ВСЕ элементы которого он же заполнил ненулевыми значениями) значение "0" — QSP вернёт ему позицию несуществующего с точки зрения автора пятого элемента.

Неактивен

0    0    #6
06.09.2011 23:12

Nex
Участник (+120, -130)
Зарегистрирован: 11.06.2007
Сообщений: 2053

---

Re: Особенности работы с массивами в QSP

Пересмотрел выводы, отредактировал первое сообщение. Оба варианта имеют свои недостатки.

Хорошим решением, теоретически, был бы ввод необязательного параметра, определяющего предполагаемый размер массива. Если указан - ищем значение в указанных пределах по первому способу, если не указан - в существующих элементах массива по второму. Беда в том, что авторам такие тонкости будет очень трудно объяснить.

Неактивен

0    0    #7
06.09.2011 23:23

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Nex написал:

Хорошим решением, теоретически, был бы ввод необязательного параметра, определяющего предполагаемый размер массива. Если указан - ищем значение в указанных пределах по первому способу, если не указан - в существующих элементах массива по второму. Беда в том, что авторам такие тонкости будет очень трудно объяснить.

Зачем так усложнять для автора? Не проще всё же в реализации самой функции (на уровне платформы) ввести проверку на размер массива? Например, если найденная позиция больше размера массива — значит, ничего не нашли.

Ведь если автор укажет, что

Код:

probe[4]=0
*NL ARRPOS('probe', 0)

то функция отрабатывает вполне корректно и возвращает "4".

Неактивен

0    0    #8
07.09.2011 00:37

Nex
Участник (+120, -130)
Зарегистрирован: 11.06.2007
Сообщений: 2053

---

Re: Особенности работы с массивами в QSP

Затем, что благодаря отсутствию явного задания длины массива, есть два способа их использования, я об этом писал выше.
Если автор использует массив самым простым способом - задав некую переменную(L), определяющую размер массива, то при заполнении произвольных ячеек внутри выбранного автором диапазона, размер полученного массива запросто может не совпасть с L. И вот тут-то, при поиске нулевых значений, в предложенном тобою варианте мы будем искать не по всей длине L, а лишь по отрезку заполненных элементов. Из-за этого придется явно инициализировать массив, о том, чем это плохо, я тоже писал. Перечитай.

Неактивен

0    0    #9
07.09.2011 09:44

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Nex написал:

Затем, что благодаря отсутствию явного задания длины массива, есть два способа их использования, я об этом писал выше.
Если автор использует массив самым простым способом - задав некую переменную(L), определяющую размер массива, то при заполнении произвольных ячеек внутри выбранного автором диапазона, размер полученного массива запросто может не совпасть с L. И вот тут-то, при поиске нулевых значений, в предложенном тобою варианте мы будем искать не по всей длине L, а лишь по отрезку заполненных элементов. Из-за этого придется явно инициализировать массив, о том, чем это плохо, я тоже писал. Перечитай.

Перечитал. В своём описании порядка работы с массивами в QSP ты как-то всё усложнил, смешав как есть и как могло бы быть.

С точки зрения автора всё организовано просто (я не буду говорить про строковые индексы — они не влияют на суть):

  1. Размер массива в QSP определяется максимальным индексом, значение которому было явно присвоено.
  2. При присвоении любого значения элементу массива с числовым индексом, превышающим размер массива, массив увеличивается на соответствующее число элементов. При этом элементы, создаваемые автоматически, заполняются пустыми значениями и становятся "полноправными" элементами массива.
  3. Считывание значения массива с любым индексом, даже выходящим за пределы текущего размера, никак не влияет на размер. При обращении к "несуществующему" элементу возвращается пустое значение.
  4. Как правило, авторы организуют работу так, чтобы манипулировать значениями внутри диапазона, однако пункт 3 обеспечивает нормальное функционирование, даже если авторы выходят за пределы диапазона при считывании значения: и значение (пустое) возвращается, и массив остаётся нетронутым.

Однако, несмотря на "свободную расширяемость" массива, в каждый конкретный момент времени он (массив) имеет вполне определённый фактический размер (который можно получить функцией ARRSIZE), и этот размер автору либо уже известен, либо он его может получить. Так вот, возвращать функцией поиска значение индекса массива, который лежит вне этого диапазона, — на мой взгляд некорректно.

Отсюда и предложение — на уровне платформы ограничить верхний предел обработки массива функцией ARRPOS его фактическим размером, то есть тем значением, которое можно получить функцией ARRSIZE.

Неактивен

0    0    #10
08.09.2011 12:18

WladySpb
Участник (+2)
Зарегистрирован: 21.12.2008
Сообщений: 33

Re: Особенности работы с массивами в QSP

Но нулями он заполняется при присваивании. А как же удаление отдельных элементов через KILLVAR? Но KILLVAR тоже не оставляет пробелов! Как только из массива 1, 2, 3 мы удаляем 2, то получаем массив 1, 3 - два элемента на позициях 0 и 1 соответственно. "Хвост" массива сдвигается влево на 1, сохраняя массив неразрывным.

Вот этот нюанс на самом деле напрягает. Грубо говоря, задавая конкретное значение элементу массива, я рассчитываю что оно таким и останется.
Например, я пишу:

Код:

probe[4]=10

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

PS Кстати, а если используется строковая индексация? Происходит смещение по индексам, или индекс сохраняется за элементом массива вне зависимости от того, где он находится?

Отредактировано WladySpb (08.09.2011 12:30)

Неактивен

0    0    #11
08.09.2011 12:25

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

WladySpb написал:

задавая конкретное значение элементу массива, я рассчитываю что оно таким и останется.
Например, я пишу:

Код:

probe[4]=10

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

Если ты рассчитываешь на неизменность порядка элементов массива, то не нужно удалять элементы — достаточно их просто очищать, вот и всё…

Неактивен

0    0    #12
08.09.2011 12:34

WladySpb
Участник (+2)
Зарегистрирован: 21.12.2008
Сообщений: 33

Re: Особенности работы с массивами в QSP

Ну, я обычно очищаю весь массив целиком, пока необходимости не было делать это поэлементно. Просто представил себе ситуацию.

Неактивен

0    0    #13
08.09.2011 14:56

Nex
Участник (+120, -130)
Зарегистрирован: 11.06.2007
Сообщений: 2053

---

Re: Особенности работы с массивами в QSP

Строковая индексация:

Код:

A["a"]="aaa"
A["b"]="bbb"
A["c"]="ccc"

Имеем:
A[0]="aaa", A["a"]="aaa"
A[1]="bbb", A["b"]="bbb"
A[2]="ccc", A["c"]="ccc"

Далее,

Код:

KILLVAR "A", 1

Имеем:
A[0]="aaa", A["a"]="aaa"
A[1]="ccc", A["c"]="ccc"

Т.о., числовые индексы поменялись, но это для нас неважно, т.к. мы пользуемся строковыми.

Что интересно, KILLVAR не поддерживает строковые индексы. Недоработка. Приходится явно указывать соответствующий числовой индекс.

Неактивен

0    0    #14
08.09.2011 15:24

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Nex написал:

Что интересно, KILLVAR не поддерживает строковые индексы. Недоработка. Приходится явно указывать соответствующий числовой индекс.

На эту "недоработку" я давно уже пытался обратить внимание.

Пока же для реализации удаления элемента по строковому ключу я пользуюсь такой функцией:

Код:

#УдалитьИзМассиваПоКлючу
    ! Параметры
        ! 1. 0 - Имя массива (тип: строка)
        ! 2. 1 - Строковый ключ удаляемого элемента (тип: строка)
    !----------
    dynamic "$<<$ARGS[0]>>[$ARGS[0]] = '!@#$%^del^%$#@!'", $ARGS[1]
    killvar $ARGS[0], arrpos('$' + $ARGS[0], '!@#$%^del^%$#@!')
    !----------
    --- УдалитьИзМассиваПоКлючу

Суть работы функции:

  1. По искомому строковому индексу присваиваем элементу какое-нибудь уникальное строковое значение, которое точно не встречается в массиве.
  2. Ищем индекс элемента массива по этому уникальному строковому значению.
  3. Удаляем элемент массива по найденному индексу.

Неактивен

0    0    #15
08.09.2011 15:26

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Переименовал тему "Поиск нуля в несуществующем массиве" в "Особенности работы с массивами в QSP".

Неактивен

0    0    #16
08.09.2011 15:45

Nex
Участник (+120, -130)
Зарегистрирован: 11.06.2007
Сообщений: 2053

---

Re: Особенности работы с массивами в QSP

Повторяю, есть два способа работы с массивами. Один из них опирается на "реальный размер массива", всегда известный через ARRSIZE, другой - на заданный автором диапазон.
Твое решение подходит только для тех, кто работает по первому способу.

На эту "недоработку" я давно уже пытался обратить внимание.

А кто помешал? Взял бы и обратил внимание, мое или Байта. На форумах ты об этом не писал.

Отредактировано Nex (08.09.2011 15:50)

Неактивен

0    0    #17
08.09.2011 15:59

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Re: Особенности работы с массивами в QSP

Nex написал:

Повторяю, есть два способа работы с массивами. Один из них опирается на "реальный размер массива", всегда известный через ARRSIZE, другой - на заданный автором диапазон.
Твое решение подходит только для тех, кто работает по первому способу.

А можно привести код с примером работы по второму варианту (где автор задаёт диапазон), чтобы понимать, чем же это отличается от "реального размера массива"?

Неактивен

Powered by PunBB
© copyright 2001–2024 iFiction.Ru