LINUX.ORG.RU

Односвязные списки в Си

 ,


2

7

Всем привет) Давеча на меня наехал препод по программированию, мол: «почему ты никогда не используешь код который даю я, а все время пишешь свое. Лучше меня ты не напишешь.» В аудитории я промолчал.

Давал он код библиотеки для работы с односвязными списками. Я его полистал и понял что это говно.

Вот оно -> https://github.com/maksspace/unn/tree/master/prepod

Моя критика:

  1. Большинство функции не нужны ибо поля структур открыты
  2. Бессмысленное зануление указателя и проверка на ноль почти в каждой функции
  3. Поле данных в нодах списка, это не void*, а просто структура, по этому придется каждый раз исправлять библиотеку чтобы работать в другими типами данных
  4. Нет возможности использовать кастомный аллокатор памяти

Вот мой вариант: https://github.com/maksspace/slistlib

Дайте критику по обоим вариантам)

Посмотри на реализацию в ядре и проникся. Все эти void* – говно.

staseg ★★★★★ ()

твой код такое же говно.

anonymous ()
Ответ на: комментарий от staseg

Посмотри на реализацию в ядре

2 чая сему регистранту

anonymous ()

«почему ты никогда не используешь код который даю я, а все время пишешь свое. Лучше меня ты не напишешь.»

Слоллировал. Теперь вместо того чтобы заниматься делом будешь воевать со своим преподом в качестве ненужного кода?

loz ★★★★★ ()

Односвязные списки не нужны.

mix_mix ★★★★★ ()

2 говна по цене одного :(

если уж односвязить список то по заветам крохоборно

https://en.wikipedia.org/wiki/XOR_linked_list

http://stackoverflow.com/questions/21528422/storing-a-doubly-linked-list-usin...

http://www.geeksforgeeks.org/xor-linked-list-a-memory-efficient-doubly-linked...

ps. а вообще от автора A Retargetable C Compiler: Design and Implementation есть отличный мануал C Interfaces and Implementations: Techniques for Creating Reusable Software

вот эта вот C Interfaces and Implementations (гугляни) даж входит в список через http://stackoverflow.com/tags/c/info

http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-lis...

ззы. преподу есть теперь шанс квалу качнуть

qulinxao ★★☆ ()
Ответ на: комментарий от Bad_ptr

Назови преимущества этого КО-подхода, пожалуйста. Я вижу два минуса: дополнительные операции с памятью (можно избавиться в продвинутом варианте) и касты в вызывающем коде.

staseg ★★★★★ ()

Работать надо, а не меряться красотой кода. «Заводы стоя́т» (c)

pacify ★★★★★ ()

Очередной раунд обсуждения навесов для велосипедов объявляется открытым!

i-rinat ★★★★★ ()

почему ты никогда не используешь код который даю я, а все время пишешь свое. Лучше меня ты не напишешь.

Лучше препода ты всё равно не напишешь, потому что решать, что лучше, а что хуже, будет он. Ты в заведомо проигрышном положении. Даже если мы тут все единогласно признаем твой код шедевром, для него ничего не изменится.

i-rinat ★★★★★ ()

Дайте критику по обоим вариантам)

по ссылкам не ходил, но использовать готовые библиотеки (если нет задачи приготовить собственно библиотеку) - правильный подход, иначе NIH, велосипеды, безблагодатность

Если в реальных условиях окажется, что готовая библиотека говно^Wне подходит, тогда уже будешь велосипедить, не раньше.

lazyklimm ★★★★★ ()
Ответ на: комментарий от loz

вместо того чтобы заниматься делом будешь воевать со своим преподом

Будет. И препод его завалит, ТСа отчислят и заберут в армию. И это будет хорошим уроком.

Смысл обучения в вузе - не получить навык написания кода - этому учат в ПТУ, а «научиться учиться». т.е. уважать начальство/авторитетов, в данном случае преподов и делать как велено, не больше не меньше, а не умничать. И не выделяться из коллектива. Выскочек не любят не только преподаватели, но и одногруппники.

pawnhearts ★★★★★ ()
Ответ на: комментарий от Norgat

Какая хорошая либа, хорошо хоть патч Бармина не накладывает

false ★★★★★ ()

Покажи преподу sys/queue.h и отправь его лесом.

beastie ★★★★★ ()
Ответ на: комментарий от pawnhearts

т.е. уважать начальство/авторитетов, в данном случае преподов и делать как велено,

Вот так и появляются соплежуи и жополизы.

И не выделяться из коллектива. Выскочек не любят не только преподаватели, но и одногруппники.

Если бы не было выскочек, то охотились бы мы на мамонтов с палкой-копалкой.

andreyu ★★★★★ ()

По первому впечатлению говнецо-то у обоих. Но у препода фееричнее. У него же не C, а C++ (неужто в варианте от Borland?). Так что он уже здесь обосрался неслабо: если он учит вас C, то нефиг использовать new/delete. Если учит C++, то зачем NULL и где, мать его, шаблоны? ;)

Ну и отдельно доставляет вот это:

#define DL DESCRIPTOR_LIST

PS. А вообще даже не знаешь, плакать от такого кода у преподавателей или смеяться.

eao197 ★★★★★ ()

Давал он код библиотеки для работы с односвязными списками.

Зачем? Если вы изучаете связные списки(единственное, зачем они нужны на практике), то вы должны писать сами. Если вы изучаете что-то другое, то пользоваться нужно стандартными библиотеками(в коде препода C++).

anonymous ()
Ответ на: комментарий от false

Там до этого _dl = new ..., так что эта строка всё равно не имеет эффектов.

i-rinat ★★★★★ ()
Ответ на: комментарий от pawnhearts

Выскочек не любят не только преподаватели, но и одногруппники.

Я начал выделяться, итог: освобождение от экзамена и последующих курсов с отлично. Lol.

Oxdeadbeef ★★★ ()

Бессмысленное зануление указателя

где?

и проверка на ноль почти в каждой функции

что с ней не так?

anonymous ()
Ответ на: комментарий от i-rinat

имеет. садись, 2. что будет, если память внезапно НЕ выделится?

впрочем, преподу тоже 2: new — это не С, а плюсы.

Norgat к вам вопрос: а что ещё делать в случае исчерпания свободной памяти? ИМХО, завершение работы программы — вполне норм решение, ещё бы лог на это дело повесить и норм.

anonymous ()
Ответ на: комментарий от anonymous

что будет, если память внезапно НЕ выделится?

бросит исключение. По умолчанию new бросает исключение, хотя можно попросить и NULL возвращать.

i-rinat ★★★★★ ()

не, я надеялся, что у препода там хотя бы дефайн какой-нибудь. но честно: «using namespace std;» нет слов.

сообщите преподу, что он — дебил. если уж использовать С++, то писать шаблоны, а не структурки. если не использовать плюсы, то никаких «new» и «using namespace std;

anonymous ()

Лучше меня ты не напишешь

Эксперт ведь.

Ну в целом и ты и он пытались писать «красиво» - за это вас можно похвалить. Но не фортануло-да.

anonymous ()
Ответ на: комментарий от i-rinat

бросит исключение.

неправильно: выполнит оператор new(). а уж как внутри он будет работать - дело оператора.

anonymous ()
Ответ на: комментарий от i-rinat

потому что решать, что лучше, а что хуже, будет он.

Но его можно обоссать. В чём проблема? Естественно он как и ты будет считать, что он «лучше», но жопой будет чуять, что он ничто.

Хотя да, тебе такое поведение знакомо.

Ты в заведомо проигрышном положении.

Нет. Скилл пацана-то и заключается в том, чтобы мочь показать где дерьмо, а где нет. Чтобы потом балаболки кукарекали «это не говно - просто мне так удобнее», ну да - удобнее, но это не ответ, а согласии с тем, что говно.

anonymous ()
Ответ на: комментарий от anonymous

имел в виду, что оператор new продолжит выполняться и его поведение зависит только от него самого

anonymous ()
Ответ на: комментарий от anonymous

имел в виду, что оператор new продолжит выполняться и его поведение зависит только от него самого

Ну, если наплевать на стандарт, то да, только от него самого.

eao197 ★★★★★ ()
Ответ на: комментарий от anonymous

О, царь пришёл.

Но его можно обоссать. В чём проблема?

Это мелкое хулиганство. Суток на 15 могут закрыть.

Скилл пацана

Заключается в классификации видов экскрементов?

i-rinat ★★★★★ ()
Ответ на: комментарий от anonymous

неправильно: выполнит оператор new(). а уж как внутри он будет работать - дело оператора.

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

i-rinat ★★★★★ ()
Ответ на: комментарий от anonymous

а что ещё делать в случае исчерпания свободной памяти? ИМХО, завершение работы программы — вполне норм решение, ещё бы лог на это дело повесить и норм.

Подразумевается, что это либа. Если либа не может что-то сделать, то она должна проинформировать приложение об ошибке, а приложение уже пусть решает, что делать.

Если мы обсуждаем C, то либа должна вернуть NULL и установить флаг ошибки. Приложение получает от либы невалидный указатель и смотрит на причины. Как пример см. GetLastError в Windows и errno в Linux.

Если NULL считается валидным возвращаемым значением, то функция возвращает int и делаем проверку на -1 в вызывающем коде.

А вот лог и прочее - забота вызывающего кода, а не забота либы.

Norgat ★★★★★ ()
Ответ на: комментарий от i-rinat

Перегрузки оператора new там быть не должно.

Вроде как для перегрузки глобальных new/delete достаточно просто определение новых версий в одной из единиц трансляции (тыц):

a user-provided non-member function with the same signature defined anywhere in the program, in any source file, replaces the implicit version. Its declaration does not need to be visible.

eao197 ★★★★★ ()
slist* slist_new()
{
    slist* l = SLIST_MALLOC(sizeof(slist));
    if(l != NULL) {
        l->head = NULL;
        l->tail = NULL;
        l->free_data = NULL;
        l->size = 0;
    }
    return l;
}

malloc returns a void pointer (void *), which indicates that it is a pointer to a region of unknown data type

у вас ошибка молча проглатывается

if(l != NULL)

if(l) читабельнее

в общем, у препода хуже соответствие стандарту и стиль, у вас — баги на пустом месте, стиль получше, но тоже не очень

anonymous ()
Ответ на: комментарий от Norgat

Всё так, но есть один нюанс: в случае исчерпания свободной памяти, вызывающий код может сделать чуть больше, чем ничего. Поэтому, «мягкое» завершение работы — лучшее решение для некритичных процессов в такой ситуации.

anonymous ()
Ответ на: комментарий от anonymous

у вас ошибка молча проглатывается

Обосновать можете? А то что-то не видно проглатывания ошибки ни на первый взгляд, ни на второй.

eao197 ★★★★★ ()
//============================== Файл LIBLIST.CPP ==============================
//                 Библиотека функций работы с односвязным списком
//   Согласование кодировок для вывода символов кириллицы

Дальше не читал.

anonymous ()

Большинство функции не нужны ибо поля структур открыты

Потом структура меняется и вместо изменения функции-оберток, ты мечешься по всему коду и выискиваешь обращение к полям.

Молодец! Ты проиграл.

anonymous ()

А то, что связные списки используют только опущенцы, твой препод тебе рассказать забыл?

anonymous ()
Ответ на: комментарий от lazyklimm

да, была задача написать библиотеку для работы со списками

maksspaces ()
Ответ на: комментарий от i-rinat

Это мелкое хулиганство. Суток на 15 могут закрыть.

Я же любя.

Заключается в классификации видов экскрементов?

Да нет - моя сишка это не его сишка, а пацанская сишка. Т.е. я могу всё так, как это будет максимально идеально и красиво, а пацан нет. Поэтому я победитель по умолчанию.

В целом я бы даже списки не делал, ибо пацан не смог доказать их нужность. Хотя да, наверное меня так же забанили бы в недовузе, как и тут.

Но зато я победитель по-жизни, не?

anonymous ()
Ответ на: комментарий от maksspaces

А вам ваш эксперт объяснял зачем в списке:

slist_index(), slist_append(), slist_prepend(), slist_delhead(), slist_deltail() - что это за даунство?

slist* slist_prepend(slist* l, void* data)//как это работает?
{
    snode* n = slist_node_new();//вот  новая нода
    if(n != NULL)
    {
        if(l->size == 0) {
            l->head = n;
            l->tail = n;
        }
        else {
            snode* temp_head_ptr = l->head;
            l->head = n;//ты взял поставил на место head новую ноду, но та нода, что указывала на твой head указывает всё равно на хеад, а не на твою ноду.
            n->next = temp_head_ptr;
        }
            
        n->data = data;
        l->size++;
    }
    return l;
}

Это односвязный список - в нём операции производятся только над парами. Т.е. вставить ты можешь только за текущей в пару cur межу cur->next.

Какая ещё нахрен структурка, какая ещё нахрен структурка с tail - это для даунов что-ли?

create_node();//
//Далее все твои вставки работают только для елемента, либо пары.
insert(node, data);//вствить после текущей. На её место вставить нельзя.
remove(a);//то же самое - удалить текущую нельзя, только следующую.

Может сделать.
remove2(a, b)//удалить между.

Всё, больше никакого дерьма быть не должно. Обходить список не вставляя - никому не надо, если ты это делаешь - выйди в окно. Доступ по индексу - так же в окно. Спаси мир от дебила. Если тебе надо удалять с концов - выкинь себя в форточку так же.

Проблема в том, что в недовузопойке, да и нигде вообще адепты до сих пор не понимают нахрена собственна нужен список. Крякнутые пытаются запилить какое-то api, чтобы он мимикрировал под массив. Нахрен тогда тебе список, ало?

Особенно односвязный.

А ну и да, операция по индексу возвращает дату, а не пару - гениально решение.

anonymous ()

tailgunner

О, прибежала обосаннная мною уже сотню раз балаболка обозлённая на меня. А так да - я очень беспомощен. У всего ложа жопа порвалась в попытках нагнуть меня, правда безрезультатно. Такое бывает. Может я беспомощен против вызова модератора и бана? Ну да.

Я тебя люблю-обожаю <3, хочу с тобою дружить, а ты на меня лаешь - как мне быть? У меня же жопу разрывает от неразделённой любви. Фу таким быть - давай дружить ^_^.

А ну и да, я настолько беспомощен, что удалил свой коммент быстрее, чем я на него смог ответить.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.