PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Разное поведение хэш-карты в структуре


Разное поведение хэш-карты в структуре

Сообщений 1 страница 11 из 11

1

Интересную особенность обнаружил. В коде ниже, в первом случае, при проверке через If путь структуры создаётся автоматически, во втором случае, при присвоении, такой путь не создаётся. В обоих случаях обращение идёт к Map1("Map1(2)")\MapIn("MapIn"), но поведение разное. Знать бы с чем это связано?

Код:
Structure pMapIn
  *Pointer
EndStructure

Structure pMap
  Map MapIn.pMapIn()
EndStructure

Define NewMap Map1.pMap()

Define NewMap Map2.pMap()

; Вариант 1 - "путь" хэш-карт создаётся автоматически при проверке
If Not Map1("Map1")\MapIn("MapIn")\Pointer
  Map1()\MapIn()\Pointer = 1 ; нет ошибки, "путь" был создан 
EndIf

Debug Map1()\MapIn()\Pointer


; Вариант 2 - здесь "путь" хэш-карт не создаётся
Define *Pointer = Map2("Map2")\MapIn("MapIn")\Pointer
If Not *Pointer
  Map2()\MapIn()\Pointer = 2 ; ошибка
EndIf

Debug Map2()\MapIn()\Pointer

Отредактировано Webarion (11.07.2022 17:24:00)

0

2

PB 6.0, ошибки нет как с асм так и с си.

0

3

А что так можно " Map2("Map2")\MapIn("MapIn")\Pointer",указывать индекс массива структур не числом а в виде строки?

Отредактировано Sergeihik (11.07.2022 20:39:09)

0

4

Sergeihik написал(а):

А что так можно " Map2("Map2")\MapIn("MapIn")\Pointer",указывать индекс массива структур не числом а в виде строки?

Это не массив, а Хэш-карта со структурой. Хэш-карта Map2 содержит структуру, внутри которой есть ещё одна хэш-карта MapIn со структурой содержащей указатель.

С вложенными структурами хэш-карт, так можно, например:

Код:
Structure pMapInternal
  Text$
  Map MyMap.pMapInternal() ; указываем на свою структуру, как на внутреннюю (Можно, вечного зацикливания не будет)
EndStructure

Define NewMap MyMap.pMapInternal()

MyMap("Key1")\Text$ = "111"
MyMap()\MyMap("Key1")\Text$ = "222"
MyMap()\MyMap()\MyMap("Key1")\Text$ = "333"

Debug MyMap("Key1")\Text$
Debug MyMap("Key1")\MyMap("Key1")\Text$
Debug MyMap("Key1")\MyMap("Key1")\MyMap("Key1")\Text$

Отредактировано Webarion (11.07.2022 21:24:08)

0

5

Webarion написал(а):

If Not *Pointer

Может из за того что во втором случае идёт возвращение адреса на ячейку а не самого значения и нужно так?

Код:
 Вариант 2 - здесь "путь" хэш-карт не создаётся
Define *Pointer = Map2("Map2")\MapIn("MapIn")\Pointer
If Not peeki(*Pointer)
  Map2()\MapIn()\Pointer = 2 ; ошибка
EndIf

Debug Map2()\MapIn()\Pointer

0

6

Sergeihik написал(а):

Может из за того что во втором случае идёт возвращение адреса на ячейку а не самого значения и нужно так?

Нет, там возвращается именно значение указателя, в Define *Pointer возвращается 0. И ваша конструкция If Not peeki(*Pointer) также создаёт ошибку: "Указанный адрес является нулевым"
По смыслу, и тот и другой вариант должны делать одно и то же. Но, так как сказал Пётр, в PB 6.0, ошибки нет, и это действительно так, а ошибка есть на нижних версиях. То смею предположить, что либо это был баг, либо в шестой версии, смысл такого обращения стал равнозначным, это логично.

0

7

Webarion написал(а):

В коде ниже, в первом случае, при проверке через If путь структуры создаётся автоматически, во втором случае, при присвоении, такой путь не создаётся.

В первом случае

Код:
; If Not Map1("Map1")\MapIn("MapIn")\Pointer
  MOV    eax,_S1
  PUSH   eax
  PUSH   dword [m_Map1]
  CALL  _PB_CreateMapElement@8
  MOV    ebp,eax
  PUSH   ebp
  MOV    eax,_S2
  POP    ebp
  PUSH   eax
  PUSH   dword [ebp+0]
  CALL  _PB_CreateMapElement@8
  MOV    ebp,eax
  CMP    dword [ebp],0
  JE     No0
  XOR    eax,eax
  JMP    Ok0

Во втором

Код:
; Define *Pointer = Map2("Map2")\MapIn("MapIn")\Pointer
  MOV    eax,_S3
  PUSH   eax
  PUSH   dword [m_Map2]
  CALL  _PB_GetMapElement@8
  MOV    ebp,eax
  PUSH   ebp
  MOV    eax,_S2
  POP    ebp
  PUSH   eax
  PUSH   dword [ebp+0]
  CALL  _PB_GetMapElement@8
  MOV    ebp,eax
  MOV    eax,dword [ebp]
  MOV    dword [p_Pointer],eax

То есть в первом случае проверяется наличие элемента с заданным именем (если нет, он создается), а во втором чтение данных из поля Pointer. Если данных нет, возвращается 0, но элемент не добавляется в массив.

0

8

Пётр написал(а):

В первом случае...

Пётр, спасибо! Да, здесь видно, что идёт обращение к разным процедурам _PB_CreateMapElement@8 <> _PB_GetMapElement@8
В первом случае создание, во втором чтение, тут сами названия говорят) Да и результат говорит сам за себя. Но смысл мне не понятен, для чего было сделано именно так. А из какой версии PB, эти листинги? Как-то раньше я смотрел ASM листинги PB программы, а сейчас вот просто не могу найти как. Подскажите? Вроде в IDE можно было просмотреть.

0

9

Webarion написал(а):

Подскажите?

из справки

-c, --commented, /COMMENTED: создаёт откомментированный файл вывода '.asm' при создании исполняемого файла. Этот файл можно впоследствии передать ассемблеру, после того как будут сделаны нужные изменения. Эта опция только для опытных программистов.

+1

10

https://www.purebasic.fr/english/viewtopic.php?t=30864

+1

11

В общем, всё понятно. В листингах PB 6.0 картина совсем другая, в обоих вариантах, идёт обращение к одной Get процедуре. И уже в этой процедуре автоматически создаются пути хэш-карт. Хотя в прошлых версиях Get процедура не создавала, а только читала. Ребят, всем спасибо за участие в этом небольшом исследовании, и за ссылки.
https://forumupload.ru/uploads/0009/ae/28/644/t106083.jpg

Отредактировано Webarion (13.07.2022 20:28:19)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Разное поведение хэш-карты в структуре