Важная информация
Показано с 1 по 8 из 8

Тема: Строковый REDIM PRESERVE в пространствах имён

  1. #1 Строковый REDIM PRESERVE в пространствах имён 
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,846
    Сказал(а) спасибо
    1,815
    Поблагодарили 945 раз(а) в 807 сообщениях
    Записей в блоге
    1



    Некоторое время назад на форуме у Стаса выложил простейшее решение вопроса с динамическим
    строковым массивом в пространстве имён.

    Задублирую и сюда [ StringArrays.bas ]:

    FreeBasic Code:
    1.  
    2. '$LANG: "FB"
    3.  
    4. '
    5. '  Пример использования реинициализируемых динамических строковых
    6. '  массивов в пространствах имён.
    7. '
    8. '  Функции:
    9. '
    10. '    _DIM     ( имя массива, нижняя граница, верхняя граница )
    11. '    _REDIM   ( имя массива, нижняя граница, верхняя граница )
    12. '    _REDIM_PRESERVE  ( имя массива, нижняя граница, верхняя граница )
    13. '    _KILLDIM ( имя массива )
    14. '
    15. '
    16. '
    17. '  >Quiet Snow< 2018
    18. '
    19. '
    20.  
    21. NAMESPACE __
    22. #DEFINE DEBUG     '  Можно закомментировать это и отключить отладочн. режим
    23.  
    24. TYPE StringDIM    '  Кастомный тип "строковый массив"
    25.     LoIndex AS INTEGER
    26.     HiIndex AS INTEGER
    27.     PtrToStr AS STRING PTR
    28. END TYPE
    29.  
    30.  
    31.   '  Аналог функции DIM, т.е. резервирования массива
    32.  
    33.   SUB _DIM (BYREF NameDIM AS StringDIM, Lo AS INTEGER, Hi AS INTEGER)
    34.   DIM LengthDIM AS INTEGER
    35.  
    36.   '  Если массив ещё не выделен - выделяем.
    37.   IF NameDIM.PtrToStr = FALSE THEN
    38.     '  Проверяем верность границ
    39.     IF Lo < Hi THEN
    40.       NameDIM.LoIndex = Lo:  NameDIM.HiIndex = Hi
    41.     ELSE
    42.       NameDIM.LoIndex = Hi:  NameDIM.HiIndex = Lo
    43.     END IF
    44.     '  Считаем длину массива
    45.     LengthDIM = (NameDIM.HiIndex - NameDIM.LoIndex) + 1
    46.     NameDIM.PtrToStr = NEW STRING[LengthDIM]
    47.   END IF
    48.  
    49.   END SUB
    50.  
    51.  
    52.   '  Освобождаем память
    53.  
    54.   SUB _KILLDIM (BYREF NameDIM AS StringDIM)
    55.     DELETE[] NameDIM.PtrToStr
    56.     NameDIM.PtrToStr = 0
    57.     NameDIM.LoIndex = 0
    58.     NameDIM.HiIndex = 0
    59.   END SUB
    60.  
    61.  
    62.   '  Аналог функции REDIM, т.е. пересоздания массива без сохранения значений
    63.  
    64.   SUB _REDIM (BYREF NameDIM AS StringDIM, NewLo AS INTEGER, NewHi AS INTEGER)
    65.  
    66.     '  Если массив выделен - убираем и создаём новый.
    67.     IF NameDIM.PtrToStr <> FALSE THEN
    68.  
    69.       _KILLDIM NameDIM             '  Удаляем старый
    70.       _DIM NameDIM, NewLo, NewHi   '  И создаём новый
    71.  
    72.     END IF
    73.  
    74.   END SUB
    75.  
    76.  
    77.   '  Аналог функции REDIM PRESERVE пересоздания массива c сохр. значений
    78.   '  Работа немного отличается от функции REDIM PRESERVE
    79.   '  Сохраняет значения согласно значениям индексов
    80.   '  С учётом перекрытий множеств старых и новых значений
    81.   '  Позволяет "расширять" массив как назад так и вперёд
    82.  
    83.   SUB _REDIM_PRESERVE (BYREF NameDIM AS StringDIM, NewLo AS INTEGER, NewHi AS INTEGER)
    84.   DIM AS INTEGER  NLo, NHi
    85.   DIM AS INTEGER  SvLo, SvHi, SvLen
    86.   DIM MvInd AS INTEGER
    87.   DIM BaseIndex1 AS INTEGER, BaseIndex2 AS INTEGER
    88.   DIM NewLengthDIM AS INTEGER
    89.   DIM NewPtrToStr AS STRING PTR
    90.  
    91.   '  Если массив выделен - убираем и создаём новый.
    92.   IF NameDIM.PtrToStr <> FALSE THEN
    93.  
    94.     '  Проверяем верность границ
    95.     IF NewLo < NewHi THEN
    96.       NLo = NewLo:  NHi = NewHi
    97.     ELSE
    98.       NLo = NewHi:  NHi = NewLo
    99.     END IF
    100.  
    101.  
    102.     '  Найдём пересечение индексов
    103.     IF NLo > NameDIM.HiIndex OR NHi < NameDIM.LoIndex THEN  '  Не пересекается
    104.  
    105.       '  Сохранять данные не требуется
    106.       #IFDEF DEBUG  
    107.         COLOR 10: PRINT "Variant 1: No save data": COLOR 7     '   >>> DEBUG <<<  !!!
    108.       #ENDIF
    109.       
    110.       _KILLDIM NameDIM             '  Удаляем старый
    111.       _DIM NameDIM, NewLo, NewHi   '  И создаём новый
    112.  
    113.     ELSE                                                    '  Пересекается
    114.       #IFDEF DEBUG
    115.         COLOR 10: PRINT "Variant 2: Save data": COLOR 7        '   >>> DEBUG <<<  !!!
    116.       #ENDIF
    117.  
    118.       NewLengthDIM = (NHi - NLo) + 1
    119.       NewPtrToStr = NEW STRING[NewLengthDIM]   '  Заводим новый массив
    120.  
    121.       '  Нужно понять где границы копирования
    122.       '  Присвоим сначала значения старого массива
    123.       SvLo = NameDIM.LoIndex: SvHi = NameDIM.HiIndex
    124.       
    125.       '  И ограничим их значениями нового массива
    126.       IF SvLo < NLo THEN SvLo = NLo
    127.       IF SvHi > NHi THEN SvHi = NHi
    128.  
    129.       '  Вычислим базовые индексы(для копирования)
    130.       '  В массивах созданных через NEW - индексы с ноля
    131.       BaseIndex1 = SvLo - NameDIM.LoIndex   '  Старый массив(откуда)
    132.       BaseIndex2 = SvLo - NLo               '  Новый массив(куда)
    133.  
    134.       '  Посчитаем длину
    135.       SvLen = SvHi - SvLo
    136.       '  Копируем
    137.       FOR MvInd = 0 TO SvLen
    138.          NewPtrToStr[MvInd + BaseIndex2] = NameDIM.PtrToStr[MvInd + BaseIndex1]
    139.       NEXT
    140.  
    141.       DELETE[] NameDIM.PtrToStr       '  Удаляем старый
    142.  
    143.       '  Переносим свежесозданный указатель в старый уже нерабочий
    144.       NameDIM.PtrToStr = NewPtrToStr
    145.       NameDIM.LoIndex = NLo           '  И внесём новые размерности
    146.       NameDIM.HiIndex = NHi
    147.  
    148.     END IF
    149.  
    150.   END IF
    151.  
    152.   END SUB
    153.  
    154.  
    155.   '  Пишем значение в массив
    156.  
    157.   SUB _SETV (BYREF NameDIM AS StringDIM, Index AS INTEGER, BYREF Value AS STRING)
    158.   DIM NIndex AS INTEGER = Index
    159.  
    160.     IF Index >= NameDIM.LoIndex AND Index <= NameDIM.HiIndex THEN
    161.       NIndex -= NameDIM.LoIndex
    162.       NameDIM.PtrToStr[NIndex] = Value
    163.     END IF
    164.  
    165.   END SUB
    166.  
    167.  
    168.   '  Читаем значение из массива
    169.  
    170.   FUNCTION _GETV (BYREF NameDIM AS StringDIM, Index AS INTEGER) AS STRING
    171.   DIM NIndex AS INTEGER = Index
    172.  
    173.     IF Index >= NameDIM.LoIndex AND Index <= NameDIM.HiIndex THEN
    174.       NIndex -= NameDIM.LoIndex
    175.       
    176.       #IFDEF DEBUG                                 '   >>> DEBUG <<<  !!!
    177.         COLOR 12: PRINT NIndex; ", "; : COLOR 7    '   >>> DEBUG <<<  !!!
    178.       #ENDIF                                       '   >>> DEBUG <<<  !!!
    179.  
    180.       RETURN NameDIM.PtrToStr[NIndex]
    181.     END IF
    182.   
    183.   END FUNCTION
    184.  
    185.  
    186.  
    187.  
    188.   '
    189.   '  Функции для тестирования работы самопального массива
    190.   '  Присвоить тестовые значения
    191.   '
    192.  
    193.   SUB _TSTValues (BYREF NameDIM AS StringDIM)
    194.   DIM i AS INTEGER, i2 AS INTEGER
    195.   DIM RandSlov AS STRING
    196.      FOR i = NameDIM.LoIndex TO NameDIM.HiIndex
    197.  
    198.            RandSlov = ""
    199.            FOR i2 = 1 TO (i - NameDIM.LoIndex) + 1
    200.               RandSlov = RandSlov + CHR(65 + (i - NameDIM.LoIndex))
    201.            NEXT
    202.  
    203.            _SETV NameDIM, i, RandSlov
    204.  
    205.      NEXT
    206.   END SUB
    207.  
    208.  
    209.   '  Распечатать массив
    210.  
    211.   SUB _DIMOutput (BYREF NameDIM AS StringDIM)
    212.   DIM i AS INTEGER
    213.  
    214.      FOR i = NameDIM.LoIndex TO NameDIM.HiIndex
    215.  
    216.          #IFDEF DEBUG
    217.            WRITE i, _GETV(NameDIM, i)
    218.          #ELSE
    219.            PRINT i; ", "; _GETV(NameDIM, i)
    220.          #ENDIF
    221.  
    222.      NEXT:  PRINT
    223.   END SUB
    224.  
    225. END NAMESPACE
    226.  
    227.  
    228.  
    229.  
    230. '
    231. '  Тестовое пространство имён
    232. '
    233.  
    234. NAMESPACE MySpace
    235.  
    236.   USING __    '  Подключим простр. имён, отвеч. за работу с массивами строк
    237.  
    238.    '  Строковый массив для долговременного использования
    239.   DIM MyArray AS StringDIM
    240.  
    241.  
    242.    '  Тестовая процедура
    243.   SUB MyProc ()
    244.  
    245.      _DIM MyArray, -5, 3               '  Заведём массив = DIM
    246.      _TSTValues MyArray                '  Заполним тестовыми значениями
    247.      _DIMOutput MyArray                '  Выведем на консоль
    248.  
    249.      _REDIM_PRESERVE MyArray, -10, -3  '  Реиниц. массив ~ REDIM PRESERVE
    250.      '_REDIM MyStrArray, -5, 5            '  Реиниц. массив = REDIM
    251.      _DIMOutput MyArray                '  Выведем на консоль
    252.      _KILLDIM MyArray                  '  Уничтожим массив, освободив память
    253.  
    254.   END SUB
    255.  
    256. END NAMESPACE
    257.  
    258.  
    259.   '   Тестируем
    260.  
    261.   MySpace.MyProc
    262.  
    263.   SLEEP
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  2. Пользователь сказал cпасибо:

    Free Admin (23.07.2018)

  3. #2  
    Разбирающийся
    Регистрация
    01.04.2015
    Сообщений
    59
    Сказал(а) спасибо
    3
    Поблагодарили 35 раз(а) в 27 сообщениях
    Разве в FB нет строкового динамического массива?
    Ответить с цитированием  
     

  4. #3  
    Начинающий Аватар для Эрик Замабувараев-Ёмолкуу
    Регистрация
    12.03.2018
    Сообщений
    31
    Сказал(а) спасибо
    0
    Поблагодарили 18 раз(а) в 13 сообщениях
    В чём суть? Почему не устроил Dim Vector(25) As String?
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на FreeBASIC!
    Ответить с цитированием  
     

  5. #4  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,846
    Сказал(а) спасибо
    1,815
    Поблагодарили 945 раз(а) в 807 сообщениях
    Записей в блоге
    1
    Цитата Сообщение от locm Посмотреть сообщение
    Разве в FB нет строкового динамического массива?
    Есть. К сожалению просто так обернуть его в namespace - нельзя, массивы там сугубо STATIC, а код внутри namespace
    можно писать только внутри подпрограмм. Мне вообще не нравится как сделан оператор Namespace. По идее(по асмовой
    логике), просто должны создаваться множества имён, грубо говоря прога просто должна быть раздроблена на допустим
    две части(как будто это две разные проги), если два пространства имён. Тут же ребята походу использовали идеологию
    c++ и не стали ничего дописывать. Я честно пытался понять почему они так сделали, мол вдруг какие ограничения или
    "непростые" концептуальные причины. Увы никаких препятствий - не увидел, просто реализовали именно так, значит им
    так нравится.

    Цитата Сообщение от Эрик Замабувараев-Ёмолкуу Посмотреть сообщение
    В чём суть? Почему не устроил Dim Vector(25) As String?
    Потому что не работает. Я всегда за самый простейший подход по многим причинам, но тут не вышло.
    И я не такой любитель паскалевских NEW\DELETE как может показаться, просто надо было решать вопрос,
    желательно максимально просто(хотя в бошке мелькала идея полной имплементации типа STRING, но мозг
    и эту идею берегу для другого проекта, потому что долго и сложно).
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  6. Пользователь сказал cпасибо:

    Free Admin (25.07.2018)

  7. #5  
    Разбирающийся
    Регистрация
    01.04.2015
    Сообщений
    59
    Сказал(а) спасибо
    3
    Поблагодарили 35 раз(а) в 27 сообщениях
    Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
    массивы там сугубо STATIC, а код внутри namespace можно писать только внутри подпрограмм.
    Какое-то искусственное ограничение. В PB в пространстве имен допустимо все, а не только функции.
    Ответить с цитированием  
     

  8. Пользователь сказал cпасибо:

    >Quiet Snow< (25.07.2018)

  9. #6  
    Начинающий Аватар для Эрик Замабувараев-Ёмолкуу
    Регистрация
    12.03.2018
    Сообщений
    31
    Сказал(а) спасибо
    0
    Поблагодарили 18 раз(а) в 13 сообщениях
    Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
    К сожалению просто так обернуть его в namespace - нельзя
    У меня почему‐то можно
    FreeBasic Code:
    1.  
    2. Namespace Tester
    3. Dim Vector() As String
    4. End Namespace
    5.  
    6. Const MaxVectorLength As Integer = 10
    7.  
    8. ReDim Tester.Vector(MaxVectorLength - 1)
    9.  
    10. For i As Integer = 0 To MaxVectorLength - 1
    11. Tester.Vector(i) = Str(i)
    12. Next
    13.  
    14. For i As Integer = 0 To MaxVectorLength - 1
    15. Print Tester.Vector(i)
    16. Next
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на FreeBASIC!
    Ответить с цитированием  
     

  10. 2 пользователя(ей) сказали cпасибо:

    >Quiet Snow< (25.07.2018), Free Admin (25.07.2018)

  11. #7  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,846
    Сказал(а) спасибо
    1,815
    Поблагодарили 945 раз(а) в 807 сообщениях
    Записей в блоге
    1
    Цитата Сообщение от Эрик Замабувараев-Ёмолкуу Посмотреть сообщение
    У меня почему‐то можно
    В прошлом сообщении размерность была указана - так оно не работает, а метод с пустыми скобками
    впервые вообще вижу, нигде он в справке не указан, что крайне странно.
    Получается изобретал велосипед, ну да ладно)))

    Цитата Сообщение от locm Посмотреть сообщение
    Какое-то искусственное ограничение. В PB в пространстве имен допустимо все, а не только функции.
    Ну как бы да, так и живём. Приходится оборачивать в процедуры, хоть это и не сложно, но хлопот доставляет.
    Последний раз редактировалось >Quiet Snow<; 25.07.2018 в 20:48.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  12. #8  
    Начинающий Аватар для Эрик Замабувараев-Ёмолкуу
    Регистрация
    12.03.2018
    Сообщений
    31
    Сказал(а) спасибо
    0
    Поблагодарили 18 раз(а) в 13 сообщениях
    Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
    а метод с пустыми скобками
    впервые вообще вижу
    Вот ссылка на документацию про динамические массивы https://www.freebasic.net/wiki/wikka...PgVarLenArrays
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на FreeBASIC!
    Ответить с цитированием  
     

  13. 2 пользователя(ей) сказали cпасибо:

    >Quiet Snow< (25.07.2018), Free Admin (26.07.2018)

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •