#1 [09.11.09, 19:22] Урок: разбираем списки, часть 1
И так, цель нашего урока - понять зачем нужны списки объектов (LIST'ы, листы). Допустим, нам надо сделать эльф, который будет читать из файла какие-то данные и выводить их удобным образом, например в виде пунктов, или выводить список файлов в папке - примеров можно придумать кучу. Таким образом - листы помагают удобно и быстро распределять объекты в памяти. Это удобство достигается специальными функциями для работы со списками:
Код:
LIST *List_New(void); void List_Free(LIST *lst); void ListElement_AddtoTop(LIST *lst,void *newElement); void * ListElement_Remove(LIST *lst,int index); int ListElement_Prt2NumElement(LIST *lst,void *ptr); int ListElement_Find(LIST *lst,void *element, int (*cmp_proc)(void *,void *)); void * ListElement_GetByIndex(LIST * , int index); void ListElement_Add(LIST *lst,void *newElement); void List_FreeElements(LIST *,int (*cmp_proc)(void * elem_from_list),void (*freefunc)(void * elem_from_list)); void ListElement_Insert(LIST *lst, int i, void *new_item);
Сейчас все функции мы разбирать не будем, а рассмотрим основные моменты.
Для начала необходимо создать список. Он будет находится в переменной list. Перед этим расскажу немного о структуре LIST:
Код:
typedef struct { u16 unk;//неизвестно u16 FirstFree;//кол-во пунктов void **listdata;//массив с данными }LIST;
Теперь приступим!
1. Объявляем list как указатель:
Код:
LIST * list;
2. Создаем свою структуру, содержащую какое-то число и строку, и называем её ITEM:
Код:
typedef struct { int number;// число wchar_t * string;//строка }ITEM;
3. Пишем функцию для создания списка, она не будет возвращать никакого значения, поэтому её тип - void, также она не содержит параметров. Я делаю для этого отдельную функцию только для оптимизации при использовании её в нескольких местах, да и код выглядит красивее. Ещё советую давать понятные имена функциям, например: List_Create, List_Destroy, List_Save и т.д.
Код:
void List_Create() { list=List_New();//выделяем память под список for(int i=0;i<10;i++)//запускаем цикл для добавления 10-ти пунктов { ITEM *item=new ITEM; //создаем новую переменную типа ITEM memset(item,0,sizeof(ITEM));// выделяем для неё память item->number=i;//присваиваем переменной number в структуре ITEM текущего пункта значение i wchar_t buf[1];//создаем так называемый буффер, для хранения временной строчки //тип wchar_t - строка в кодировке Unicode snwprintf(buf, 2, L"%d", i);//функцией записываем в буффер число как строку item->string=new wchar_t[wstrlen(buf)+1];// выделяем память под строку //string в структуре ITEM в размере буффера buf //единицу прибавлять в таком случае обязательно! //иначе символ L'\0' не запишется в строку wstrcpy(item->string, buf); //наконец, копируем в item->string строку buf ListElement_Add(list, item);//добавляем всё это дело в список } }
Вроде бы всё расписал тут, что не понятно - не стесняйтесь спрашивать. Эту функцию очень легко отредактировать под свои
нужды.
4. Теперь пришло время функции уничтожения списка, назовем её List_Destroy, также для удобства напишем простенький макрос:
Код:
#define DELETE(a) if (a) {delete(a);a=0;} //если объект a не равен 0, то очищаем память, занятую им
Код:
void List_Destroy() { if (list)//если список list существует { while (list->FirstFree)//если есть ещё пункты в списке { ITEM* it=(ITEM*)ListElement_Remove(menu->list,0);//удаляем пункт с индексом(номером) 0 //из списка и присваиваем его указатель переменной it. //Можно удалять и последний пункт, но так удобней. DELETE(it->string);// очищаем память, выделенную под строку it->string DELETE(it);//очищаем память, выделенную под сам пункт it } List_Free(list);//удаляем список } }
Если вы не поняли зачем List_Destroy - при создании списка вы выделяли память под список, пункты, строки в пунктах, если это
всё не "убивать" то происходит утечка памяти, тоесть нужно очистить память, занятую этими объектами.
5. Располагаем функции где нам необходимо, например:
- List_Create помещаем в main - List_Destroy в onMyBookClose (в ту функцию, где обрабатывается ивент закрытия книги)
Лучше всего уничтожать лист, когда он уже не используется.
Вот, собственно, на сегодня и всё. Что не так, не понятно и т.д. - отписывайтесь :)
#3 [30.09.10, 21:31] Re: Урок: разбираем списки, часть 1
я бы рекомендовал в функции List_Destroy() удалять последний элемент из списка, так как при его "выемки" из списка сдвига элементов происходить не будет, работать очищение листа будет в разы быстрее, особенно для листов с количеством элементов >>5000
не занимаюсь эльфами и патчами (= Siemens c75 -> SonyEricsson k610i + SonyEricsson w595 + SonyEricsson w580i -> HTC Desire Z
Вы не можете начинать темы. Вы не можете редактировать свои сообщения. Вы не можете создавать опросы. Вы не можете вкладывать файлы в сообщения. Вы не можете отвечать на сообщения. Вы не можете удалять свои сообщения. Вы не можете голосовать.