Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 3 из 3
  1. #1
    Аватар для oukibt
    Пользователь

    Статус
    Оффлайн
    Регистрация
    27.02.2020
    Сообщений
    26
    Репутация:
    3 ±

    Доступ к двухмерному массиву

    Как правильно получить в плагине доступ к двухмерному массиву?

    Пример:

    1. enum Info
    2. {
    3. Data1[10],
    4. Data2,
    5. };
    6.  
    7. native function(Array[][Info], size = sizeof array);
    8.  
    9. main()
    10. {
    11. new Array[][Info] = {
    12.  
    13. { "228", 228 },
    14. { "100", 100 },
    15. { "1337", 1337 }
    16. };
    17.  
    18. function(Array);
    19. }

  2. #2
    Аватар для oukibt
    Пользователь

    Статус
    Оффлайн
    Регистрация
    27.02.2020
    Сообщений
    26
    Репутация:
    3 ±
    С проблемой разобрался, но всё равно не понятно, как оно работает.

    (Код на павн в посте сверху учитывается)

    1. cell AMX_NATIVE_CALL Function(AMX *amx, cell *params)
    2. {
    3. cell* addr;
    4. amx_GetAddr(amx, params[1], &addr);
    5.  
    6. int i, len;
    7. char string[10];
    8.  
    9. // params[2] == размеру массива, в данном случае 3
    10. // 10 - это размер массива (первого элемента) в энуменаторе
    11. // 1 - размер второго элемента
    12.  
    13. for (i = params[2]; i < params[2] * (10 + 1) + params[2];)
    14. {
    15. amx_StrLen(&addr[i], &len);
    16. amx_GetString(string, &addr[i], NULL, len + 1);
    17.  
    18. i += 10;
    19.  
    20. something = addr[i]; // addr[i] - это второй элемент энуменатора
    21.  
    22. i++;
    23. }
    24.  
    25. return 1;
    26. }


    Каждую итерацию цикла, в string записывается первый, а в something второй элемент
    И, как раз таки, не понятно, почему i начинается со значения params[2]
    Последний раз редактировалось oukibt; 30.06.2021 в 17:01.

  3. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Суть в том, что в многомерных массивах данные располагаются не совсем обычным образом.
    В двухмерных массивах перед содержимым массива указываются смещения до содержимого каждой строки второго измерения.
    Например, если у нас есть такой массив:
    1. new a[2][3] = {
    2. { 0xA, 0xB, 0xC },
    3. { 0xD, 0xE, 0xF }
    4. };

    то в файл *.amx попадёт следующее:
    1. 8 10 ; смещения (8 и 16 в десятичной системе)
    2. a b c ; строка 0
    3. d e f ; строка 1

    Т.е. если требуется получить значение элемента a[1][2], то следует:
    • Взять адрес массива.
    • Прибавить номер строки 2-го измерения, умноженный на размер ячейки (в примере выше нужен элемент из 1-й строки; размер ячейки равен четырём; 1 * 4 = 4).
    • Прочесть значение из получившегося адреса (в примере выше это будет 10), это значение и будет смещением данных 2-й строки. Прибавить прочитанное значение к уже имеющемуся адресу.
    • Прибавить номер ячейки в 2-м измерении, умноженный на размер ячейки (в примере - 2 * 4 = 8).
    • Снова прочесть значение по получившемуся адресу. Это и будет значение из a[1][2].

    Сделана эта галиматья со смещениями потому, что в Pawn строки последнего измерения могут заполняться не до конца.
    Например, если сделать так:
    1. new a[2][] = {
    2. { 0xA, },
    3. { 0xD, 0xE, 0xF }
    4. };

    то в *.amx попадёт:
    1. 8 8 a d e f

    На крупных массивах это может здорово сэкономить память. Собственно, Pawn и разрабатывался с расчётом на микроконтроллеры, у которых обычно очень ограниченный объём памяти.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. Пользователь сказал cпасибо:
    oukibt (02.07.2021)
 

 

Информация о теме

Пользователи, просматривающие эту тему

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

Ваши права

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