Здравствуйте, гость ( Вход | Регистрация )

Свернуть

Новости

Форум Лучшее из галереи Уроки и статьи
07.12.2015 Выставочный зал: кошарик - персональная выставка
31.08.2015 Интересные ссылки для рисовальщиков
21.01.2015 Выставочный зал 2: Игрушки Олеси Гавриленко

27.12.2014 Выставочный зал: кошарик - персональная выставка
17.11.2014 Дуэль "Рыбки" - победитель Лисичка
05.11.2014 Конкурс иллюстраций "Снежная королева", до 31 января
30.10.2014 Дуэль "Рыбки" до 16 ноября
14.07.2014 Мастер-класс Мини-мишка в технике фелтинга
26.05.2013 Ау! Мы ищем таланты! – приглашаем модераторов!
«Тревожные мысли»
tn_gallery_8756_506_58673.jpg

© ovena
06.01.2016 Виртуальный Музей: Русский живописец Василий Дмитриевич Поленов
28.12.2015 Виртуальный Музей: Нидерландский живописец Квентин Массейс
16.12.2015 Виртуальный Музей: Итальянский живописец Франче́ско Айец
17.11.2015 Виртуальный Музей: Луи Анкетен (Louis Anquetin)
11.11.2015 Виртуальный Музей: Русский живописец Алексей Иванович Корзухин
Файловый архив
06.09.2013 Прочее: Файлы к уроку "Чайная церемония"
05.09.2013 Журнал Art Tower: ArtTower Magazine #8
16.05.2013 Adobe Photoshop: Кисти: Reid Southen brush
16.05.2013 Adobe Photoshop: Кисти: Goro Fujita brush
16.05.2013 Adobe Photoshop: Кисти: Кисти для рисования в Photoshop
Блоги Новости в цифровом мире и мире дизайна
02.12.2014 Дама с каменьями: Вести с крыши 2
08.11.2014 Timenews: Вассерман: прежняя модель мировой экономики исчерпала себя
06.11.2014 Дама с каменьями: Приятные вести с крыши))) от Гаргула)
02.11.2014 Spell: Книги Дж. Кэмерон
22.10.2014 Vjaz: от ФУ до МА
25.11.2015 Комментарий от Foxx в Costa Rica Adventure Divers, Логотип для компании и рисунок на майку (maria_mer)
18.11.2015 Комментарий от maria_mer в Spellforce - майка, для фанов игры (maria_mer)
18.11.2015 Комментарий от maria_mer в Белая книга. Целитель - любительский прект (maria_mer)
09.04.2015 Комментарий от Romana в Книги Дж. Кэмерон (Spell)
08.04.2015 Комментарий от Romana в Я решил вернуться... (Элбирет)
16.03.2015 ФОТОФОРУМ-2015
01.01.2015 ARQUTE.com и ArtTalk.ru закрываются
19.01.2017 Конкурс дизайна логотипов
26.12.2016 ру/Ководство: О творческом развитии
14.10.2016 ру/Ководство: Разнообразие

 
Добавить ответ в эту темуОткрыть тему
> Основоположения программирования - часть IV.3, Массив: скопировать, уничтожить. Объекты и ключи
V
Des
сообщение 6.01.2009 - 13:27
Сообщение #1


тритониус
****

Звезда писателя I степениЗа вклад в развитие ArtTower.ru
Группа: Почетные граждане
Сообщений: 728
Регистрация: 9.12.2007
Из: Москва \ Питер
Пользователь №: 6553
дышу под водой
Галерея Блог


Симпатии:  68  


Предыдущая часть: Основоположения программирования - часть IV.2
Начало: Основоположения программирования - часть I

Исходники к уроку: lesson_arrays02.rar

5.1 Массивы как ссылочный Тип Данных

Мы уже говорили о том, что массивы (Array) относятся к ссылочному Типу Данных. Однако именно в случае с массивами это чаще всего может привести к ошибке, которую потом можно долго-долго, чертыхаясь, искать в исходном коде...
Попробуем скопировать массив "напрямую":

var arr1:Array = new Array("one","two","three");
var arr2:Array = arr1;


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

arr2[1] = "ooops!";

Понятно, что в элементе с индексом 1 массива arr2 теперь хранится строка "ooops!". И, скорее всего, вы ожидаете, что в массиве arr1 значение arr1[1] осталось неизменным. Однако, к удивлению...



Значение arr1[1] тоже изменилось! В чем же тут дело - ведь мы его, кажется, "не трогали"?
А дело вот в чем: массивы - ссылочный Тип Данных. Т.е. в переменных arr1 и arr2 хранятся не сами массивы, а ссылки на них.
Подробнее: когда мы создаем (объявляем) переменную Простого Типа Данных (Number, Boolean,...) - для нее при объявлении тут же создается область памяти, где будет храниться ее значение. Когда мы копируем значение одной переменной из другой (присваивая, т.о., ей значение другой переменной) - это значение действительно копируется, т.е., условно говоря, для хранения значений двух переменных Простого Типа всегда выделяется две различных области памяти1
Для Ссылочного же (Комплексного, Составного) Типа Данных память под хранение значения выделяется только оператором new ТипДанных()2 при инициализации. Присвоение же значения переменной напрямую, как в нашем примере, для Ссылочного Типа Данных вызывает не копирование из одной области памяти в другую, а только - присвоение переменной ссылки ("указателя"3) на уже существующую область памяти.
Именно поэтому, изменяя "значение" второй переменной, мы тем самым на самом деле изменяем значения в той же области памяти - ведь наши переменные arr1 и arr2 "указывают" (ссылаются) на одну и ту же область памяти!
И это справедливо для всех Ссылочных Типов Данных, (т.е. - классов), не только для Array, и в первую очередь - для Object, TextField и MovieClip.
В случае с MovieClip это, например, означает, что, объявив новую переменную Типа MovieClip и присвоив ей значение другой переменной того же Типа, мы тем самым никакой ролик не скопировали, а получили только еще одну ссылку на тот же ролик.

5.2 Как скопировать массив?

Из сказанного следует, что просто так скопировать массив нельзя - получим только ссылку на тот же массив. А как быть, если скопировать все же нужно? - а очень просто: создать новый массив оператором new и последовательно перекопировать в него все значения всех элементов исходного массива.

var arr1:Array = new Array("one","two","three");
var arr2:Array = new Array();
for (var ii:Number = 0;ii<arr1.length;ii++){
arr2[ii] = arr1[ii];
}



Вот теперь все в порядке.
При этом нужно особенно осмотрительно обращаться с двумерными массивами: их придется и инициализировать, и копировать поэлементно.
С Комплексными Типами Данных связаны другие важные в программировании понятия - передача аргумента функции (методу) по ссылке и по значению, но об этих интересных вещах ;) мы поговорим, когда подробнее будем говорить о функциях и о методах классов.

5.3 Как "очистить" массив, или интересная особенность Action Script

Иногда нужно просто удалить все элементы из массива - очистить его. Самый простой способ сделать это - "завести новый" с помощью оператора new:
var arr:Array = new Array(1,2,3); // массив из трех элементов
// <...>
arr = new Array(); // массив очищен

Однако это не совсем правильный способ... груб он. И что творится с распределением памяти - один Адоб знает...
Правильнее будет уничтожить массив оператором delete (уничтожает ранее объявленную переменную) и объявить его заново:

var arr:Array = new Array(1,2,3);
// <...>
delete arr; // уничтожаем переменную...
var arr:Array = new Array(); // и заново ее объявляем и инициализируем

Тут тоже есть тонкость, связанная со ссылочностью Типа Данных Array (и со Ссылочными Типами вообще): оператор delete уничтожает именно переменную, т.е. в случае, когда переменная Ссылочного Типа - только ссылку на значение, а не само значение, и только когда уничтожены все ссылки на объект - и само значение.
Т.е., если у нас есть такой код:

var arr1:Array = new Array(1,2,3);
var arr2:Array = arr1;
delete arr1;


- то в arr2 будет по-прежнему "храниться" массив с тремя элементами! Да, вот так все запутано - но именно так и логично, и удобно... когда привыкнете smile.gif



И, однако, есть в Action Script преинтересная особенность, абсолютно уникальная для этого языка, и вызывающая обычно снисходительную усмешку пополам с удивлением у "матерых кодеров" других языков: свойство .length у массивов можно... изменять. Не только считывать, а и присваивать ему значение4 - что абсолютно немыслимо в других языках.
При этом если значение, которое мы присваиваем этому свойству, больше текущего - добавятся undefined элементы, если меньше - массив "обрежется". И, т.о., с "очисткой" все становится очень просто:

var arr1:Array = new Array(1,2,3);
var arr2:Array = arr1;

// <...>
arr.length = 0;



- да и все.

6. Ассоциативные массивы. Массивы и Объекты.

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

var assocArr:Array = new Array();

assocArr["key1"] = 1;
assocArr["key2"] = "some string";
assocArr["one more key"] = "2nd string";


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

var person:Array = new Array();
person["firstname"] = "Василий";
person["lastname"] = "Пупкин";
person["mail"] = "vasyapupkin2009@mail.ru";
person["phone"] = "";
person["age"] = 35;


Однако получить доступ к элементам через индекс - "по номерам" - уже не получится. И чтобы, например, вывести все значения, хранящиеся в таком массиве, нам придется использовать новую (еще не упомянутую в наших уроках) конструкцию for...in:

for (var key in person) {
tf.text += key + " => " + person[key] + "\n";
}

- только так программа "пробежит" по всем ключам ассоциативного массива и добавит сам ключ, строку-"стрелочку", значение, полученное по ключу и перенос строки для каждого ключа.

Если посмотреть в справку Flash, то можно прочитать, что оператор цикла for...in предназначен для пробегания по свойствам объекта (т.е. - переменной Типа Object), а не по "ключам ассоциативного массива". И все же - все правильно, и используется он тут "по закону". Дело в том, что ассоциативный массив в Flash - это и есть переменная Типа Object, и разницы между тем, объявлять ли его как new Array() или как new Object() нет.
Но ведь к свойствам объекта обращаются иначе - через ".", в виде person.firstname = ..., person.age = ...? - все правильно. Можно ведь и так - и это только разные формы записи. person["mail"] абсолютно эквивалентно person.mail
Ну разве что... разве что в виде person[key] мы можем использовать переменную в качестве ключа smile.gif И даже - вычислять эту переменную: например, person["ma"+"il"]
А вот использовать длину (размер) массива и методы, специфические именно для массивов - уже не получится.



Конечно, в ассоциативный массив можно "упаковать" далеко не только "адресную книжку". Можно, например, объявить массив "геометрия" и "положить" туда основные фигуры:

/*
предположим, что у нас имеются ролики в библиотеке, в которых лежат соответствующие символы-MovieClip, с присвоенными им именами для линкования
*/

var geomNames = new Array("circle","sphere","square","cube");
var geom:Array = new Array();
for (var ii:Number = 0;ii<geomNames.length;ii++) {
geom[geomNames[ii]] = _root.attachMovie(geomNames[ii],geomNames[ii]+"_mc",_root.getNextHighestDepth()); // разобрались? Если нет - см. предыдущий урок.
geom[geomNames[ii]]._visible = false; // пока спрячем - сделаем невидимым.
}


...и потом обращаться к ним как geom["circle"] или geom.circle

geom.circle._visible = true;
geom.circle._x = 50;
geom.circle._y = 50;


Или, например, сделать таблицу стандартных имен RGB-цветов:

var RGBColors:Array = new Array();
RGBColors["black"] = 0x000000;
RGBColors["white"] = 0xFFFFFF;
RGBColors["red"] = 0xFF0000;

// ...

Это уже ближе к художественным задачам, не правда ли? smile.gif

Продолжение следует


_________
1 За то, как именно распределяет память флэш-плагин или флэш-проигрыватель на пару с операционной системой - не поручусь smile.gif - все-таки современное программирование приложений очень абстрагировано от "железа". Но "модель поведения" составного (ссылочного, комплексного) Типа Данных по сравнению с Простыми Типами - верна.
2 Для массивов, как уже говорилось в предыдущей части, существует короткая форма записи var i:Array = [value1,value2,...]; - но это только форма записи того же самого оператора new.
3 В других языках программирования, в частности, в C\C++, между указателем и ссылкой существует огромная разница. Однако для Action Script это не актуально, и я позволил себе использовать слово "указатель" как наиболее понятное, а ссылка - как наиболее строгое название одного и того же. На всякий случай заключив слово "указатель" в кавычки smile.gif
4 Если свойство можно только считать (получить его значение), но нельзя изменить (присвоить ему значение), то говорят, что это свойство - read-only (только для чтения). Во всех известных мне языках программирования, кроме AS (в которых вообще есть понятие "размер массива", конечно) - размер массива read-only.

-------------------------------------------
Автором урока является Des.
Запрещается копирование и публикация урока на других сайтах без письменного согласия автора и размещения ссылок.


The tutorial is written by Des.
No part of this tutorial can be copied/pasted on any other website without the author's express written permission.


Сообщение отредактировал Des - 6.01.2009 - 13:31


--------------------
"Высшая мудрость - умение разговаривать с людьми" ((с) Ямамото Цунэтомо (Дзётё), "Хагакурэ")
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения

Быстрый ответДобавить ответ в эту темуОткрыть тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия форума Сейчас: 23.10.2017 - 01:46