- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
SGELISTENTRY *sgeListAdd(SGELIST *l, const char *id, void *data) {
SGELISTENTRY *ret;
sgeNew(ret, SGELISTENTRY);
l->numberOfEntries++;
if (l!=NULL) {
ret->prev=l->last;
} else {
ret->prev=NULL;
}
if (l!=NULL && l->last!=NULL) {
l->last->next=ret;
}
ret->next=NULL;
ret->id=strdup(id);
ret->data=data;
if (l==NULL) return ret;
if (l->first==NULL) l->first=ret;
l->last=ret;
return ret;
}
Кстати, а есть ведь наверняка для сей какой-то способ указать контракт: дескать параметр не может быть NULL, и чтоб потом статический анализ делать и ругаться на такие вещи?
------------
Например для Java в Idea у менять есть аннотация @NotNull.
Ну и для C# тоже
Компиляторы эту строчку так и понимают и радостно выкидывают последующие проверки нахер. Нормальные анализаторы должны на это ругаться (линт и шланг ругаются)
A нa caмoм тo дeлe этo нe пpocтoй cвязнoй cпиcoк, a нeкaя cyщнocть, пycть и кpивo, нo peaлизyющaя интepфeйc accoциaтивнoгo мaccивa нa eгo ocнoвe.
Поиск ноды вобще красота:
P.S. Ну разве что id должно быть const char *, а не char *.
Я бы сделал как const int id, задефайнил где то ид ноды, и далее искал простым сравнением вместо strcmp.
P.S. Небольшие alist'ы не так уж и тормозят.
Тоесть если там лежит три калеки, то он все равно будет занимать 2^16 байт?
А Вы всегда используете ассоциативные массивы c O(N)?
Хоспаде... Нет конечно. Но если мне надо распарсить какой-нибудь конфиг при старте проги, а под рукой только alist или вообще ничего - я не пойду искать/писать хешмапу/дерево только из-за того, что она быстрее.
Если человек пишет на плейн сях, то скорее всего он хочет СКОРОСТИ, разве нет?
Другой вопрос что может быть в этот лист чаще добавляют, чем пишут
Нет.
Вообще какой смысл вручную писать ассоциативный массив?
А плейнсишку сейчас есть смысл юзать только там, где языки более высокого уровня вообще не справятся (ядра, дрова, рантаймы), либо справятся, но медленно или с большим расходом ресурсов.
> вручную писать ассоциативный массив
Изкоробочного то нет. А использование внешних либ под вопросом.
Так вот казалось бы сишка — сверхбыстрый язык, а пострадали от квадратичной питушни.
вот прямо там нету мапы готовой?
>>рантаймы
хм.. а почему не кресты с их std::map?
>>внешних либ
Ну он все равно не будет одно и тоже писать 10 раз, все равно он сделает себе либу и будет с нею линковаца (пусть и статически). Поцчему не взять готовое то?
Только петушилово со свитчами.
Одно дело - как реализовать конкретный контейнер.
И совсем другое - в каких случаях нужно юзать его, а не какой-то другой.
С точки зрения реализации конкретного контейнера - тут всё ок. Мелкие косяки, не более того. Тестирование и ревью их пофиксят.
По этой же причине, например, практические реализации квиксорта использую сортировку вставкой для маленьких массивов.
Реализация ассоциативного списка без наворотов имеет все шансы обогнать хеш-таблицу на списках до 8-16 элементов.
Говно тут скорее всего в отсутствии тестов.
У NULL'а?
Оператор ++ анализирует стек вызвавшей процедуры, отыскивает в нем переменную l и тайком помещает в нее NULL?
Разве что макрос sgeNew его туда положил...
1) l -- указатель на структуру SGELIST
2) Внутри этой структуры храница указатель на какой-то numberOfEntries
3) Что было с инстансом этой структуры до её попадания в функцию мы не знаем
4) Если представить что numberOfEntries это не int, а какой-то объект то где-то наверху могло быть сказано [тут_идет_приведенный_Вами_код
Так что всё верно, но "где-то наверху" ограничивается строчками 2-4 этой функции.
Как вредно писать неподумав:-.
http://sourceforge.net/projects/sge2d/
Тоже производительности добавляет.