Анимация
JavaScript
|
Главная Библионтека 0x210 0x100 0x77
АССОЦИАТИВНЫЕ МАССИВЫ ОБ АССОЦИАТИВНЫХ МАССИВАХ Ассоциативные массивы это маленькое чудо IDA. Большинству программистам возможно ранее никогда не приходилось сталкиваться ни с чем подобным. К сожалению, о них очень мало (ну совсем ничего) не сказано в контекстной помощи, поэтому будет не лишим остановиться на них и рассмотреть подробнее. Один из распространенных языков, поддерживающим такие конструкции можно назвать Perl, который ввиду свой кросс - платформенности стал очень популярен среди разработчиков Internet - приложений. Но многие тысячи поклонников Си и Pascal могли и вовсе не слышать о нем, а уж тем более изыскивать время для досконального изучения. Когда-то авторитет программиста зависел от числа освоенных им языков. Сегодня же ситуация переменилась - разработчики предпочитают сосредоточиваться не только на одном языке, но даже компиляторы, зачастую совершенно не интересуясь, что происходит у «соседей». К сожалению, ставшие популярными языки многие конструкции реализуют далеко не лучшим образом, если вообще реализуют это. Так случилось и с ассоциативными массивами. Чем они отличаются от своих собратьев? И какие возможности предоставляют при этом? Уникальность ассоциативных массивов в том, что они индексируются строковыми значениями. Причем строковыми в буквальном смысле этого слова, - никакого хеширования или иного преобразования в численный вид не проводится. Это позволят значительно упрощать многие алгоритмы, раньше выглядевшие громоздкими, - например, пусть нам требуется составить таблицу, перечисляющую имена сотрудников и получаемую ими зарплату. Традиционно потребовалось бы создавать три массива, а потом обвязывать все это кодом, гарантирующим согласованность и непротиворечивость данных. Насколько же проще решается задача с использованием ассоциативных массивов Кроме этого можно придумать массу других примеров. АРХИТЕКТУРА АССОЦИАТИВНЫХ МАССИВОВ Ассоциативные массивы представляют собой всего лишь подкласс обычных разряженных массивов, которые уже были подробно рассмотрены выше. Ассоциативные массивы создаются вызовом функции CraeteArray, точно так же как и обычные разряженные. Кроме того, любой массив по сути одновременно является и разряженным и ассоциативным. Точнее, масивов на самом деле все же несколько, но идентификатор (ID) у всех может быть один. Поэтому к ассоциативным массивам применимы описанные выше функции RenameArray и DeleteArray. Новым является набор менее чем из десятка функций работающий со строковыми индексами. Вообще же в терминологии ассоциативных массивов индексы называются ключами. Каждый ключ предстваляет собой строковое значение без явных ограничений (во всяком случае в контекстой помощи IDA на этот счет ничего не сказано) и может содержать один элемент типа «строка» или «длинное целое» Обратите внимание, тогда как каждый индекс разряженного массива может одновременно содержать элементы двух типов, то каждый ключ ассоциативного массива ссылается лишь на одно значение того или иного типа. В остальном же операции с элементами ассоциативных массивов ничем не отличаются от уже описанных выше. Собственно всеми манипуляциями заведут всего три функции. Элемент можно присвоить, прочитать, и, наконец, удалить. На этом предоставляемые IDA возможности заканчиваются. Более интересны операции, выполняемые над ключами. Поскольку теперь они представляют собой строковые значения, то может быть не совсем понятно с первого взгляда, как можно выполнить даже такую тривиальную операцию, как перечислить все элементы массива. На самом деле для этого существуют традиционные функции GetNext и GetPrev. Очевидно, что они перечисляют ключи (то есть индексы) массива один за другим, но вот в каком порядке? Вообще-то это не документировано, и поэтому стоит проектировать код скрипта так, чтобы его работоспособность не зависела от подобного рода деталей. Но как нетрудно убедиться, все текущие версии IDA упорядочивают список индексов в алфавитном порядке, не зависимо от очередности создания элементов. Необходимо заметить, что некоторые языки упорядочивают индексы ассоциативных массивов именно в порядке их создания, и никем не гарантируется, что так не будет и в следующих версиях IDA (хотя, это конечно, очень маловероятно). Однако, ваш скрипт не должен завистеть от этих деталей. success SetHashLong(long id,char idx,long value); Функция присваивает значение элементу ассоциативного массива. Ассоциативные массивы выгодно отличаются от остальных тем, что могут индексироваться строковыми значениями! В остальном же с ними могут использоваться те же подходы, что и для разряженных массивов. Однако, в отличие от разреженных массивов один и тот же индекс не может содержать числовое и строковое значение одновременно. Пример использования: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0x66); SetHashLong(a,"CheputiIo",0x77); SetHashLong(a,"AIushta",0x67); DeleteArray(a);
success SetHashString(long id,char idx,char value); Функция присваивает значение элементу ассоциативного массива. Ассоциативные массивы выгодно отличаются от остальных тем, что могут индексироваться строковыми значениями! В остальном же с ними могут использоваться те же подходы, что и для разряженных массивов. Однако, в отличие от разреженных массивов один и тот же индекс не может содержать числовое и строковое значение одновременно. Пример использования: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov","Patron"); SetHashLong(a,"CheputiIo","Mouse"); SetHashLong(a,"AIushta","Metro Station"); DeleteArray(a);
long GetHashLong(long id,char idx); Функция возвращает значение элемента ассоциативного массива типа «длинное целое» Как уже говорилось выше один и тот же элемент не может содержать значения «строка» и «длинное целое» одновременно. Поэтому возникает возможность присвоить значение одного типа, а попытаться прочитать другого. Эта операция завершиться корректно и типы будут автоматически преобразованы. При этом функция GetHaskLong всегда возвращает четыре первые байта, сколько бы строка ни занимала на самом деле. Если она была короче, - то остаток будет представлять собой мусор и содержать непредсказуемые значения. Например: auto a; DeleteArray(GetArrayId("MyArray")); 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 [ 121 ] 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |