From rg-400 на list.ru Sat Sep 11 16:52:44 2010 From: rg-400 на list.ru (jam) Date: Sat, 11 Sep 2010 15:52:44 +0400 Subject: [cdev] =?koi8-r?b?+sHEwc7JxSDOwSDTxc3F09TS?= In-Reply-To: <4C07FF1C.10707@komitex.ru> References: <219521273269305@web28.yandex.ru> <4C07FF1C.10707@komitex.ru> Message-ID: <1284205964.1627.6.camel@jam> а можно уже сейчас получить список утилит, чтобы выбрать себе задание? From sitkarev на komitex.ru Sat Sep 11 18:13:55 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Sat, 11 Sep 2010 17:13:55 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDQvdC40LUg0L3QsCDRgdC10LzQtdGB0YLRgA==?= In-Reply-To: <1284205964.1627.6.camel@jam> References: <219521273269305@web28.yandex.ru> <4C07FF1C.10707@komitex.ru> <1284205964.1627.6.camel@jam> Message-ID: <4C8B8093.2010101@komitex.ru> Можно, почему же нет. Просто список корректировался исходя из того какой материал группа усваивала. Я могу повторить задания с прошлого года. Если вы пороетесь в архивах, то найдёте его, он там где-то был. В прошлом году мы делали вот это: ps chat bc date dd df find fuser id kill stty telnet echo Требования по спецификациям OpenGroup. Я бы ещё сюда добавил простой аналог sh, довольно таки интересное задание. На chat(1) у OpenGroup спецификации нет, пользуйтесь man-страницей в Linux/FreeBSD/*nix. -- Г.А. jam пишет: > а можно уже сейчас получить список утилит, чтобы выбрать себе задание? > > > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From pcarina1990 на gmail.com Sat Sep 18 14:24:37 2010 From: pcarina1990 на gmail.com (=?KOI8-R?B?68HSyc7BIPDBzNjbyc7B?=) Date: Fri, 17 Sep 2010 21:24:37 -1200 Subject: [cdev] =?koi8-r?b?KMLF2iDUxc3ZKQ==?= Message-ID: а можно уже сейчас получить список утилит, чтобы выбрать себе задание? ----------- следущая часть ----------- Вложение в формате HTML было извлечено… URL: From rg-400 на list.ru Sat Sep 18 14:52:03 2010 From: rg-400 на list.ru (jam) Date: Sat, 18 Sep 2010 13:52:03 +0400 Subject: [cdev] =?koi8-r?b?KMLF2iDUxc3ZKQ==?= In-Reply-To: References: Message-ID: <1284803523.8616.1.camel@jam> http://wiki.syktsu.ru/pipermail/cdev/2010-September/000220.html тут список утилит В Птн, 17/09/2010 в 21:24 -1200, Карина Пальшина пишет: > а можно уже сейчас получить список утилит, чтобы выбрать себе > задание? > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From ksun_91 на mail.ru Sat Sep 18 17:36:57 2010 From: ksun_91 на mail.ru (=?koi8-r?Q?=EB=D3=C5=CE=C9=D1_=EF=C2=CF=D4=D5=D2=CF=D7=C1?=) Date: Sat, 18 Sep 2010 16:36:57 +0400 Subject: [cdev] =?koi8-r?b?KMLF2iDUxc3ZKQ==?= In-Reply-To: References: Message-ID: Здравствуйте Григорий Александрович, я из 135 группы, а можно получить список задач, которые требуется решить для получения зачета? From sitkarev на komitex.ru Sat Sep 18 19:35:15 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Sat, 18 Sep 2010 18:35:15 +0400 Subject: [cdev] =?utf-8?b?0KPRgtC40LvQuNGC0Ys=?= In-Reply-To: References: Message-ID: <4C94CE23.6000807@komitex.ru> Коллеги, Я вас прошу только пишите пожалуйста тему в новых сообщениях, потому что потом по ним можно ориентироваться в архивах списка. Действительно, список заданий уже отправлялся в список. http://wiki.syktsu.ru/pipermail/cdev/2010-September/000220.html Спецификации OpenGroup на большую часть утилит смотрите по ссылке ниже, в самом конце они там перечислены в алфавитном порядке. http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html Там чего-то может и не быть, например telnet(1) и chat(1). По этим заданиям смотрим реализованные утилиты в ОС Linux/*BSD. -- Г.А. Ксения Оботурова пишет: > Здравствуйте Григорий Александрович, я из 135 группы, а можно получить список задач, которые требуется решить для получения зачета? > > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From rg-400 на list.ru Sat Sep 18 19:42:40 2010 From: rg-400 на list.ru (jam) Date: Sat, 18 Sep 2010 18:42:40 +0400 Subject: [cdev] =?koi8-r?b?KMLF2iDUxc3ZKQ==?= In-Reply-To: References: Message-ID: <1284820960.8616.15.camel@jam> 1) я уже спрашивал насчет заданий для 145 группы (в теме http://wiki.syktsu.ru/pipermail/cdev/2010-September/000219.html), можно туда было поместить вопрос для 135. 2) пишите тему письма и почитайте первую часть http://wiki.syktsu.ru/pipermail/cdev/20100220/000005.html . В Сбт, 18/09/2010 в 16:36 +0400, Ксения Оботурова пишет: > Здравствуйте Григорий Александрович, я из 135 группы, а можно получить список задач, которые требуется решить для получения зачета? > > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From sitkarev на komitex.ru Sat Sep 18 19:49:36 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Sat, 18 Sep 2010 18:49:36 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDQvdC40Y8g0LTQu9GPIDEzNS3QuSDQs9GA0YM=?= =?utf-8?b?0L/Qv9GL?= In-Reply-To: <4C94CE23.6000807@komitex.ru> References: <4C94CE23.6000807@komitex.ru> Message-ID: <4C94D180.1050500@komitex.ru> Я действительно что-то утомился сегодня. Даже отправил почему-то 135-й группе совсем не то что нужно. Сейчас исправим положение. ------------>8------------------------------------------- Легенда следующая. Требуется создать библиотеку для работы с основными структурами данных. Как известно, стандартная библиотека Си не содержит таких функций и её требуется реализовывать или самостоятельно или пользоваться дополнительными библиотеками. Мы ставим задачу сделать такую библиотеку самостоятельно, в разработку которой каждая пара внесёт свою лепту. Т.к. по легенде мы разрабатываем библиотеку для встраиваемой платформы, мы требуем ясности кода, простоты и полноты. Оптимизацию оставляем "на потом", для нас важно на данном этапе получить рабочие алгоритмы. Для создания и манипулирования со структурами потребуются ф-ии динамического выделения памяти malloc(3), free(3), realloc(3). 1. Абстрактный тип "односвязанный список" и функции для работы с ним. Операции со списком "добавить", "добавить в конец", "удалить", "поиск элемента списка", "проход списка", "сортировка списка по заданной ф-ии сравнения", "получить n-й элемент", "получить первый элемент". Элементом списка является указатель на void (т.е. любой тип данных можно поместить в список). 2. Абстрактный тип "двусвязанный список" и функции для работы с ним. Операции со списком аналогично заданию 1 плюс проход списка может выполняться и в обратном порядке. 3. Абстрактный тип "хеш-таблица" и функции для работы с ней. Операции "создать таблицу", "добавить элемент", "удалить элемент", "заменить элемент", "поиск элемента по ключу", "проход по всем элементам", "уничтожить таблицу". + "подрастание" таблицы с переселением элементов в новую при коэффициенте заполнения > 2.0 или < 0.3. + предусмотреть возможное дублированием элементов с одинаковым ключом, предложить варианты решения. В качестве хеш-функции выбрать любую стандартную хеш-функцию (по умолчанию) и дать возможность назначать через API такую функцию самостоятельно при создании таблицы. Элементом таблицы является указатель на void (т.е. любой тип можно поместить в хеш-таблицу). 4. Абстрактный тип "динамический массив указателей". Операции "создать массив", "добавить элемент", "удалить элемент", "взять n-й элемент", "заменить элемент", "поиск элемента по ключу", "сортировка массива", "уничтожить массив", "получить количество элементов в массиве". Подобрать эмпирически метод увеличения/уменьшения размера массива по мере добавления/удаления элементов в/из него. Функцию для сравнения элементов массива можно задать при создании массива. Элементом массива является указатель на void (т.е. любой тип можно поместить в динамический массив). 5. Абстрактный тип "бинарное дерево" (не сбалансированное). Операции "создать дерево", "добавить элемент в дерево", "удалить элемент из дерева", "заменить элемент в дереве", "поиск элемента по ключу", "проход дерева". + поиск ближайшего большего и ближашего меньшего. + предложить варианты балансировки дерева. Функция для сравнения элементов дерева - аналогично 4. Элементом дерева является указатель на void (т.е. любой тип можно поместить в дерево). 6. Абстрактный тип "очередь" (queue). Предлагается использовать простой алгоритм кучи (heap queue). Операции "создать очередь", "добавить элемент в очередь", "удалить элемент из очереди", "вынуть следующий элемент из очереди", "подглядеть следующий элемент очереди", "уничтожить очередь". + предложить варианты усовершенствованных алгоритмов, например MinMax Heap, широко описанные в литературе (искать в сети Интернет). Функция для сравнения элементов очереди - аналогично 4. Элементом очереди является указатель на void (т.е. из любых типов и структур можно создать очередь). 7. Абстрактный тип "словарь" (dictionary), представляющий возможность сортированного (и несортированного) хранения пары ключ->значение. Предлагается использовать простой алгоритм "сортировка при вставке" (insertion sort). Операции "создать словарь", "добавить ключ в словарь", "удалить ключ из словаря", "поиск данных по ключу", "заменить данные ключа", "уничтожить словарь". + предложить варианты усовершенствования алгоритмов или структур данных. Элементом очереди является указатель на void (т.е. из любых типов и структур можно создать словарь). Ключом как правило является строка, память для хранения строки выделяется программистом. 8. Абстрактный тип "n-мерное дерево", представляющий возможность иметь каждому элементу дерева множество (а не два, как в бинарном дереве) потомков. Операции "создать n-мерное дерево", "добавить элемент как потомка слева/справа", "удалить элемент", "обход всех элементов дерева", "обход всех элементов по уровням", "уничтожить дерево". + предложить реализацию сортированного n-мерного дерева (в котором потомки на каждом уровне находятся в сортированном порядке); + предложить усовершенствования алгоритмов и структур данных. Элементом дерева является указатель на void (т.е. из любых типов и структур можно создать n-мерное дерево). 9+. Аллокатор памяти по методу близнецов (buddy memory allocator). Легенда: По какой-то причине нас не устраивает стандартный аллокатор библиотеки Си и мы вынуждены реализовывать свой. В таком случае стандартный malloc(3) и free(3) используется только для начального выделения кусков памяти максимального размера, в предположении что они эффективны именно для этого случая. Суть метода в следующем: Аллокатор выделяет куски памяти размером кратным степеням двойки (т.е. от 2 до 2^x где x целое число). Таким образом, требуется определить лимиты для верхней и нижней границы (u и l). Слотом мы будем называть свободный блок памяти, пригодный для аллокации. Для того чтобы выделить блок размера k аллокатор поступает следующим образом: 1. Искать слот подходящего размера. Это должен быть минимальный блок размера 2^n, такой чтобы он был больше или равным размеру аллоцируемой памяти. Учтите, что общий размер блока будет по всей видимости включать и накладные расходы на хранение его "заголовка" со служебными данными. 1. Если такой слот найден, то он выделяется вызывающей программе. 2. Если такого слота не нашлось, то пытаемся создать подходящий свободный слот. Для этого: 1. Разделяем свободный слот, большего размера чем требуется, на половинки. 2. Если достигнут нижний лимит размера слота, тогда выделяем этот размер вызывающей программе. 3. Переходим на шаг 1 ("Искать свободный слот подходящего размера.."). 4. Повторять весь процесс, пока не найден подходящий слот. Если требуется освободить память аллокатору: 1. Освободить блок памяти. 2. Посмотреть, нет ли свободного соседнего блока слева или справа? 3. Если такой блок есть, то собрать их в один, перейти на шаг 2 и повторить процесс пока не достигнут верхний предел или пока не встретится несвободный блок. Для хранения структур аллокатора можно предложить множество вариантов. Выбрать любой, реализовать его, протестировать, предложить варианты улучшений. Предлагается реализовать простой аллокатор по методу близнецов, при этом параметры l (минимальный размер блока) равен 2^6 (64 байта) а u (максимальный размер блока) равен 2^12 (4096 байт). Максимальный размер таким образом равен размеру страницы на машине x86 и x86-64 и других архитектур, минимальный выбран из соображений баланса "размер/накладные расходы на хранение описания блока". Данный метод описан в книге Д.Кнута (1-й том монографии), а впервые опубликован в 1965 году. API для аллокатора копирует поведение malloc(3) и free(3). + реализовать функцию, копирующую поведение realloc(3). ------------8<------------------------------------------- Grigoriy A. Sitkarev пишет: > > Действительно, список заданий уже отправлялся в список. > > http://wiki.syktsu.ru/pipermail/cdev/2010-September/000220.html From ksun_91 на mail.ru Sun Sep 19 00:14:01 2010 From: ksun_91 на mail.ru (=?koi8-r?Q?=EB=D3=C5=CE=C9=D1_=EF=C2=CF=D4=D5=D2=CF=D7=C1?=) Date: Sat, 18 Sep 2010 23:14:01 +0400 Subject: [cdev] =?koi8-r?b?+sHEwc7J0SDEzNEgMTM1Lcogx9LV0NDZ?= In-Reply-To: <4C94D180.1050500@komitex.ru> References: <4C94D180.1050500@komitex.ru> Message-ID: спасибо Григорий Александрович) From alexeypetrunev на gmail.com Sun Sep 19 19:17:49 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Sun, 19 Sep 2010 18:17:49 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Проверьте пожалуйста. ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: MyQueue.cpp Type: application/octet-stream Size: 6315 bytes Desc: отсутствует URL: From rg-400 на list.ru Sun Sep 19 21:02:12 2010 From: rg-400 на list.ru (jam) Date: Sun, 19 Sep 2010 20:02:12 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= In-Reply-To: References: Message-ID: <1284912132.14278.36.camel@jam> программа падает вроде по тем же причинам, что и раньше. Если ставить INIT_SIZE не меньше, чем хочешь положить элементов, то все работает, иначе проблемы с освобождение памяти. вместо prioq_free(struct prioq* queue) вроде должно быть по заданию prioq_free(struct prioq** queue) а так queue = NULL; теряет всякий смысл, т.к. это локальная переменная функции и в q у тебя будет совсем не NULL; /* void prioq_free (struct prioq** queue) { if (*queue == NULL) { fprintf (stderr, "prioq_free:The queue is free\n"); return; } if ((*queue)->heap == NULL) { free (*queue); fprintf (stderr, "prioq_free:The queue is free\n"); return; } free ((*queue)->heap); free (*queue); *queue = NULL; fprintf (stderr, "prioq_free: The queue is free\n"); } */ int prioq_put(struct prioq *queue, struct prioq_head *hp) должна возвращать целое, а ты возвращаешь NULL З.Ы. : куда пропал queue.h? В Вск, 19/09/2010 в 18:17 +0400, Алексей Петрунёв пишет: > Проверьте пожалуйста. > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From sitkarev на komitex.ru Mon Sep 20 05:57:56 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Mon, 20 Sep 2010 04:57:56 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: References: Message-ID: <4C96B194.1000702@komitex.ru> Лёша, a) Давай начнём с того что ты постараешься привести в порядок стиль. Потому что сейчас там даже не выравнены строки программы по уровню вложенности. Мы приняли за правило выделять уровни вложенности табуляцией, с шириной в 8 пробельных символов. Есть в некоторых местах неаккуратности с расстановками скобок. Если учесть эти правила то объявление вот этой структуры: struct prioq{ struct prioq_head **heap; size_t size; size_t used; prioq_compare_t compare; }; должно превратиться вот в такое: struct prioq { struct prioq_head **heap; size_t size; size_t used; prioq_compare_t compare; }; После имени структуры должен идти пробел. Хоть Си и нечувствителен к проблам мы их используем для того чтобы читалось проще. Глазу так удобнее. Напомню, что хорошее руководство по стилю было включено в документацию к ядру Linux. Мы используем этот стиль как современную версию стиля K&R. http://www.kernel.org/doc/Documentation/CodingStyle b) Тебе нужно подумать и где-то исправить проверки входных аргументов. Внесём некоторую ясность сюда. Зачем мы вообще проверяем аргументы? Нужно ли это делать всегда во всех функциях, и если не во всех, то тогда в каких? Здесь можно руководствоваться таким практическим правилом. Проверку аргументов на их валидность (нулевые указатели, выход за границы массивов и т.д.) следует делать в функциях, которые относятся к public интерфейсу библиотеки, т.е. во всех функциях, которые могут быть напрямую вызваны пользователем. Это значит что, как правило, во внутренних функциях такие проверки делать уже не нужно т.к. мы их уже сделали раньше, в тот момент когда пользовател вызывал public функцию. Как мы делаем эти проверки? Можно сделать конечно напрямую, и писать в начале каждой функции, сразу после аргументов что-то вроде: if ((queue == NULL) || (hp == NULL)){ fprintf(stderr. "NULL args\n"); return; } Это конечно в функции, которая возвращает void. На стандартный вывод ошибок мы должны какое-то сообщение напечатать, чтобы программист во время отладки смог обнаружить где он ошибся. И в этом как раз и есть первая задача этой проверки - найти ошибки программиста и сообщить ему об этом. Потому что если программа написана верно, такие условия никогда не должны выполняться. Если проверка не прошла, мы должны выйти из функции, потому что дальше её код предполагает что эти параметры валидны. На практике удобно сделать макросы, которые потом в начале функции будут генерировать код проверки аргументов. У меня они обычно определены в заголовке macros.h и я его включаю во все файлы. Этот файл я вложил в сообщение. Если я компилирую файлы с флагом -DDEBUG то макросы будут генерировать код проверки аргументов. gcc -DDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -Wall -O0 -o test test.c Если же я уберу DEBUG то макросы ничего не генерируют, и это уже когда production код выпускается, то проверок там не будет. Это зависит конечно от условий где работать будет программа, лучше всего проверки оставить, если такая возможность есть. с) Теперь по ошибкам. Я её разу увидел, когда просмотрел код. Обрати внимание на функцию prioq_get() а потом загляни в псевдокод, который я тебе отправлял и внимательно сравни, что они там делают. Думаю что ты сразу найдёшь где ты там ошибся и почему код не работает. Есть ещё замечания, но о них после того как заработает всё. -- Г.А. Алексей Петрунёв пишет: > Проверьте пожалуйста. > > > ------------------------------------------------------------------------ > > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: macros.h Type: text/x-chdr Size: 831 bytes Desc: отсутствует URL: From sitkarev на komitex.ru Mon Sep 20 08:21:31 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Mon, 20 Sep 2010 07:21:31 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: <4C96B194.1000702@komitex.ru> References: <4C96B194.1000702@komitex.ru> Message-ID: <4C96D33B.6000505@komitex.ru> Как-то незаконченно получилось. Я продолжу. Так как мы уже макросы написали, мы потом в public функциях проверки будем делать так: struct prioq_head * prioq_get(struct prioq *queue) { struct prioq_head *head; struct user_data *ptr; unsigned int used; return_val_if_fail(queue != NULL, NULL); ... Это в том случае если функция что-то возвращает. Если же ничего не возвращает, то используется макрос return_if_fail. void prioq_free(struct prioq **queue) { return_if_fail(queue != NULL); return_if_fail(*queue != NULL); ... Для проверки состояний, которые однозначно ошибочны внутри функций, служит макрос assert(3). Но мы написали вместо него свой. Он посылает процессу сигнал SIGABRT через abort(3), таким образом если программа была запущена под управлением отладчика, она остановится в том месте проверка assert-ом не прошла. Есть ещё один нюанс, который видимо пока не совсем ясен. Например, в функции prioq_get() у тебя идёт проверка аргументов таким образом: if (queue == NULL || queue->used == 0) { fprintf(stderr, "prioq_get: Can't extract " "head from queue\n"); return NULL; } С проверкой указателя queue всё понятно, и это правильно, надо его проверить, потому что программист-пользователь нашей библиотеки мог допустить ошибку и передать туда NULL или же передал туда указатель, который был обнулён уже (например prioq_free()), потому что пять же ошибся в программе и использует очередь, которой уже не существует. Но, что касается следующей проверки, счётчика элементов в очереди, здесь формально ошибки нет, но есть ошибка функциональная. Дело в том что состояние, при котором в очереди нет элементов, не является ошибкой. Если кто-то попытался извлечь из пустой очереди элемент, то ошибки нет, просто мы возвращаем NULL, пользователь проверяет всегда возвращённое значение, и если элемента не было, то ничего с ним не делает. У тебя же получается что состояние (queue->used == 0) обнаруживается как ошибка программиста, потому что на стандартный вывод ошибок ты печатаешь сообщение о том что невозможно извлечь элемент из очереди. Правильный вариант был бы такой: if (queue == NULL) { fprintf(stderr, "prioq_get: Can't extract " "head from queue\n"); return NULL; } if (queue->used == 0) return NULL; Ну или с использованием макроса: return_val_if_fail(queue != NULL, NULL); if (queue->used == 0) return NULL; Конечно же нельзя делать проверку на (queue->used == 0) до того, как мы проверим сам указатель queue. Потому что queue может быть NULL а мы его в проверке станем разыменовывать ``(->used'', т.е. ходить по смещению от адреса queue (от нуля) к полю used, что непременно приведёт к ошибке сегментации и ядро доставит процессу сигнал SIGSEGV. Можешь проверить что будет в таком случае. struct prioq *q; q = ((struct prioq *)(NULL))->used; А NULL это константа, определённая где-то в заголовках примерно так: #define NULL ((void *)(0)) Между прочим, аналогичным способом можно и вычислять смещение любого поля в структуре, в байтах. Если я возьму адрес 0 и разыменую его как указатель на структуру, а потом возьму его адрес... То как раз получится смещение. unsigned long offset; offset = &((struct prioq *)(NULL))->used; В offset мы получим смещение в байтах адреса где хранится поле used относительно начального адреса структуры prioq. В Си и системном программировании часто случается что нам нужно имея указатель на поле структуры получить указатель на её начало. Тогда удобно написать такой макрос: #define CONTAINER_OF(ptr, type, field) \ ((type *)((unsigned long)(ptr) - (unsigned long)(&((type *)(0))->field))) Тогда, например, имея указатель (адрес) любого поля внутри структуры мы бы могли получить указатель на объемлющую структуру. Я вложил файл containter.c там это продемонстрировано на простом примере. Таким образом можно организовывать некое подобие наследования. Из практических соображений удобно писать функции для работы с абстрактными типами данных, не привязанных к какой-то объемлющей структуре пользователя. Думаю что пример в containter.c всё проясняет. -- Г.А. > Тебе нужно подумать и где-то исправить проверки входных аргументов. > Внесём некоторую ясность сюда. Зачем мы вообще проверяем аргументы? > Нужно ли это делать всегда во всех функциях, и если не во всех, то тогда > в каких? > > Здесь можно руководствоваться таким практическим правилом. Проверку > аргументов на их валидность (нулевые указатели, выход за границы > массивов и т.д.) следует делать в функциях, которые относятся к public > интерфейсу библиотеки, т.е. во всех функциях, которые могут быть > напрямую вызваны пользователем. Это значит что, как правило, во > внутренних функциях такие проверки делать уже не нужно т.к. мы их уже > сделали раньше, в тот момент когда пользовател вызывал public функцию. > > Как мы делаем эти проверки? ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: container.c Type: text/x-csrc Size: 1205 bytes Desc: отсутствует URL: From rg-400 на list.ru Mon Sep 20 17:07:12 2010 From: rg-400 на list.ru (jam) Date: Mon, 20 Sep 2010 16:07:12 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= In-Reply-To: <1284912132.14278.36.camel@jam> References: <1284912132.14278.36.camel@jam> Message-ID: <1284984432.1549.9.camel@jam> а лучше так. /* void prioq_free (struct prioq** queue) { if (*queue == NULL) { fprintf (stderr, "%s:The queue is free\n", __func__); return; } if ((*queue)->heap != NULL) { free ((*queue)->heap); } free (*queue); *queue = NULL; fprintf (stderr, "%s:The queue is free\n", __func__); } */ From sitkarev на komitex.ru Mon Sep 20 17:20:24 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Mon, 20 Sep 2010 16:20:24 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: <1284984432.1549.9.camel@jam> References: <1284912132.14278.36.camel@jam> <1284984432.1549.9.camel@jam> Message-ID: <4C975188.8000008@komitex.ru> Не совсем "лучше". По смыслу получается что если очередь освободили то это ошибка? Проверку на NULL queue->heap пожалуй не стоит делать, т.к. там всегда память выделяется в prioq_new(). Это будет смущать тех, кто код будет читать, как будто-бы в каких-то случаях там может оказаться нулевой указатель. Пробелы всё же надо ставить. Есть ещё один нюанс. В Си `*' в объявлениях относится к имени идентификатора. Лучше их там и оставлять. int** a, b, c; По смыслу у вас указателем на указатель является только `a', переменные `b' и `c' это целые. Однако такое оформление заставляет нас считать их тоже указателями, хотя это не так. int **a, b, c; Так было бы корректнее. Посему в объявлениях типов лучше звёздочки прицеплять к имени идентификатора. Это принятая практика, хотя дело ваше, просто имейте в виду что чтение объявлений усложняется. -- Г.А. jam пишет: > а лучше так. > /* > void > prioq_free (struct prioq** queue) > { > if (*queue == NULL) { > fprintf (stderr, "%s:The queue is free\n", __func__); > return; > } > if ((*queue)->heap != NULL) { > free ((*queue)->heap); > } > free (*queue); > *queue = NULL; > fprintf (stderr, "%s:The queue is free\n", __func__); > } > */ From rg-400 на list.ru Tue Sep 21 17:08:04 2010 From: rg-400 на list.ru (jam) Date: Tue, 21 Sep 2010 16:08:04 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= In-Reply-To: References: Message-ID: <1285070884.1867.58.camel@jam> вроде еще одна ошибка кочует из исходника в исходник memset(queue->heap + OLD_SIZE(queue), 0, NEW_SIZE(queue) - OLD_SIZE(queue)); memset(queue->heap + queue->size, 0, NEW_SIZE(queue) - OLD_SIZE(queue)); From sitkarev на komitex.ru Tue Sep 21 19:23:29 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Tue, 21 Sep 2010 18:23:29 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: <1285070884.1867.58.camel@jam> References: <1285070884.1867.58.camel@jam> Message-ID: <4C98BFE1.1070109@komitex.ru> Не вроде а ошибка. Мне кажется что мы её где-то уже писали. Там надо было или привести queue->heap к (void *) или же сделать как ваш вариант. memset((void *)queue->heap + OLD_SIZE(queue), 0, NEW_SIZE(queue) - OLD_SIZE(queue)); Надо всегда быть внимательным с адресной арифметикой. Кстати, это я мог легко насоветовать, и забыть потом. -- Г.А. jam пишет: > вроде еще одна ошибка кочует из исходника в исходник > > memset(queue->heap + OLD_SIZE(queue), 0, NEW_SIZE(queue) - > OLD_SIZE(queue)); > > memset(queue->heap + queue->size, 0, NEW_SIZE(queue) - OLD_SIZE(queue)); > From sitkarev на komitex.ru Tue Sep 21 19:31:48 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Tue, 21 Sep 2010 18:31:48 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: <1285070884.1867.58.camel@jam> References: <1285070884.1867.58.camel@jam> Message-ID: <4C98C1D4.8060804@komitex.ru> Наверное стоит дать пояснение почему это ошибка. Когда мы работаем с адресной арифметикой, т.е. прибавляем, вычитаем и т.д. с указателями, то все операции с ними идут по кратности размера типа, на который ссылается указатель. Для примера, если это указатель на int то при прибавлении или вычитании N к адресу прибавляется или вычитается N*sizeof(int) а не N. Функция memset(3) она в первом аргументе ждёт адрес, в последнем количество в байтах. Размер мы вычислили правильно, а вот со смещением получается ошибка, потому что queue->heap он указывает на struct prioq_head, а наше смещение там посчитано в байтах а не в элементах struct prioq_head. Значит мы убежим слишком далеко указателем и затрём память там где не надо. Поэтому или изменить смещение на количество элементов, они у нас в queue->size, или же привести тип queue->heap к (void *), тогда все арифметические операции с таким указателем будут по кратности байта. -- Г.А. jam пишет: > вроде еще одна ошибка кочует из исходника в исходник > > memset(queue->heap + OLD_SIZE(queue), 0, NEW_SIZE(queue) - > OLD_SIZE(queue)); > > memset(queue->heap + queue->size, 0, NEW_SIZE(queue) - OLD_SIZE(queue)); From alexeypetrunev на gmail.com Thu Sep 23 19:21:22 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Thu, 23 Sep 2010 18:21:22 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: В prioq_put исправил строчку "i = queue->used++" на "i = queue->used". Ошибку с memset тоже исправил и prioq_get убрал(закоментил) queue->heap[used] = NULL. Хотя queue->heap[used] не должен участвовать в сортировке и нам уже он не нужен, поэтому можем присвоить ему NULL. Неожиданно возник вопрос: В функции prioq_heapify условие "largest == queue->used" когда-нибудь выполняется? queue->used всегда больше последнего индекса в массиве, т.к. он с нуля начинается. ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: MyQueue.cpp Type: application/octet-stream Size: 6977 bytes Desc: отсутствует URL: From rg-400 на list.ru Thu Sep 23 19:57:03 2010 From: rg-400 на list.ru (jam) Date: Thu, 23 Sep 2010 18:57:03 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= In-Reply-To: References: Message-ID: <1285253823.3326.17.camel@jam> i = queue->used++ - а это разве была ошибка? i присваивается значение queue->used, а уже потом на единицу увеличивается queue->used. From alexeypetrunev на gmail.com Thu Sep 23 20:26:49 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Thu, 23 Sep 2010 19:26:49 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Нверно не увидел queue->used++ дальше по тексту и поставил i:=queue->used++ потому и не работало. From alexeypetrunev на gmail.com Thu Sep 23 20:29:56 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Thu, 23 Sep 2010 19:29:56 +0400 Subject: [cdev] =?koi8-r?b?98/Q0s/T?= Message-ID: У меня проблемы с рассылкой. Ответ от jam еще не пришел на почту, я его посмотрел в архиве рассылки. Почему так несвоевременно доходят сообщения? From sitkarev на komitex.ru Thu Sep 23 20:49:05 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Thu, 23 Sep 2010 19:49:05 +0400 Subject: [cdev] =?utf-8?b?0JLQvtC/0YDQvtGB?= In-Reply-To: References: Message-ID: <4C9B76F1.9020006@komitex.ru> Скорее всего потому что они в спаме лежат. Мы хостимся на сервере СГУ, и никак не можем их заставить сделать запись в обратной зоне DNS. Позже отвечу на остальные вопросы. -- Г.А. Алексей Петрунёв пишет: > У меня проблемы с рассылкой. Ответ от jam еще не пришел на почту, я > его посмотрел в архиве рассылки. Почему так несвоевременно доходят > сообщения? > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From alexeypetrunev на gmail.com Thu Sep 23 20:52:31 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Thu, 23 Sep 2010 19:52:31 +0400 Subject: [cdev] =?koi8-r?b?98/Q0s/T?= Message-ID: У меня в спаме ничего нет. From sitkarev на komitex.ru Thu Sep 23 20:56:50 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Thu, 23 Sep 2010 19:56:50 +0400 Subject: [cdev] =?utf-8?b?0JLQvtC/0YDQvtGB?= In-Reply-To: References: Message-ID: <4C9B78C2.5040400@komitex.ru> Лёша, Дело в том что в списке порядка 40 человек, может быть что-то и не проходит сразу. Попрошу Мишу, он посмотрит логи почему именно до тебя ничего не дошло. Я получаю все письма примерно через 5-10 секунд после отправления. Может быть gmail куда-то их засовывает, не могу сказать. -- Г.А. Алексей Петрунёв пишет: > У меня в спаме ничего нет. > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From ilyin_mikhail на inbox.ru Thu Sep 23 20:58:29 2010 From: ilyin_mikhail на inbox.ru (Mikhail Ilyin) Date: Thu, 23 Sep 2010 19:58:29 +0400 Subject: [cdev] =?koi8-r?b?98/Q0s/T?= In-Reply-To: References: Message-ID: Здравствуйте, Алексей, дело в том, что список рассылки используется ни как средство динамичного общения, основная его задача сохранение последовательности сообщений, а так же архивирование. Движок список рассылки конечно сохранит полученное письмо в базе раньше, чем вы получите его на почту, и только затем он перешлет Ваше письмо всем остальным, подписанным на рассылку. Так же стоит помнить, что требуется немного времени для обработки письма Вашим почтовым сервером. Если есть необходимость динамичного общение есть предложение создать irc канала, где можно обсудить текущие проблемы в реальном времени, и не ждать рассылку. Thu, 23 Sep 2010 19:29:56 +0400 письмо от Алексей Петрунёв : > У меня проблемы с рассылкой. Ответ от jam еще не пришел на почту, я > его посмотрел в архиве рассылки. Почему так несвоевременно доходят > сообщения? > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From sitkarev на komitex.ru Thu Sep 23 21:02:17 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Thu, 23 Sep 2010 20:02:17 +0400 Subject: [cdev] =?utf-8?b?0JLQvtC/0YDQvtGB?= In-Reply-To: References: Message-ID: <4C9B7A09.506@komitex.ru> Т.е. всё-таки сообщения видимо к Лёше приходят. А то что они в архиве появятся раньше - скорее всего так и должно быть. Список это действительно не замена irc. Насколько это "своевременно" - пять минут задержки для доставки почты это вполне своевременно. На счёт irc, я думаю пока нет такой необходимости, но в обозримом будущем можно подумать на счёт своего канала и irc сервера. -- Г.А. Mikhail Ilyin пишет: > Здравствуйте, Алексей, дело в том, что список рассылки используется ни как > средство динамичного общения, основная его задача сохранение последовательности > сообщений, а так же архивирование. Движок список рассылки конечно сохранит > полученное письмо в базе раньше, чем вы получите его на почту, и только затем он > перешлет Ваше письмо всем остальным, подписанным на рассылку. Так же стоит помнить, > что требуется немного времени для обработки письма Вашим почтовым сервером. > Если есть необходимость динамичного общение есть предложение создать irc канала, > где можно обсудить текущие проблемы в реальном времени, и не ждать рассылку. > > > Thu, 23 Sep 2010 19:29:56 +0400 письмо от Алексей Петрунёв : >> У меня проблемы с рассылкой. Ответ от jam еще не пришел на почту, я >> его посмотрел в архиве рассылки. Почему так несвоевременно доходят >> сообщения? From rg-400 на list.ru Sat Sep 25 18:09:36 2010 From: rg-400 на list.ru (jam) Date: Sat, 25 Sep 2010 17:09:36 +0400 Subject: [cdev] =?koi8-r?b?dGVsbmV0ICjTz9TS1cTOyd7F09TXzyk=?= Message-ID: <1285420176.4089.4.camel@jam> Кто хочет писать telnet? Предлагаю сотрудничество. From sitkarev на komitex.ru Sun Sep 26 01:55:04 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Sun, 26 Sep 2010 00:55:04 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: References: Message-ID: <4C9E61A8.7040408@komitex.ru> Лёш, посмотри как должны эти функции работать. Я вложил файл, чтобы не включать код в тело письма. Тебе нужно добавить проверку во все public функции, как мы договаривались, и немного переделать prioq_add потому что у меня там ф-я prioq_resize() а у тебя её скорее всего нет. Расскажи что у тебя не получилось с macros.h, я не могу понять. Ты его включил в файл? Он локально должен включаться, ты его положи в тот же каталог где и исходные файлы и впиши после всех заголовков: #include "macros.h" Там поправлена ошибка в prioq_heapify() а также переделан prioq_remove(). В prioq_heapify() теперь проверяется случай перед поиском наибольшего из потомков, не выходим ли мы за границу массива кучи при попытке обратиться к правому потомку. В prioq_remove() алгоритм приведён в порядок, сначала мы должны самый последний элемент, помещённый на место удалённого, двигать наверх, пока его родитель не станет больше или не будет достигнут корень кучи, потом мы его двигаем вниз, пока его потомки не станут меньше чем он сам. Таким образом поддерживается нужные свойства бинарной кучи в том числе и после изъятия любого элемента из неё. В этой функции идёт проверка на краевой случай, когда изъят последний элемент, тогда ничего двигать не надо. Надо это всё ещё раз проверить, но важнее чтобы ты понял как это всё программируется и потом работает. Попробуй также написать пример с использованием концепции в container.c, через макрос CONTAINER_OF(), поищи в архиве рассылки, там было всё расписано. В любую структуру можно включить struct prioq_head и потом работать с ней как с элементом очереди. -- Г.А. Алексей Петрунёв пишет: > В prioq_put исправил строчку "i = queue->used++" на "i = > queue->used". Ошибку с memset тоже исправил и prioq_get > убрал(закоментил) queue->heap[used] = NULL. Хотя queue->heap[used] не > должен участвовать в сортировке и нам уже он не нужен, поэтому можем > присвоить ему NULL. Неожиданно возник вопрос: В функции prioq_heapify > условие "largest == queue->used" когда-нибудь выполняется? queue->used > всегда больше последнего индекса в массиве, т.к. он с нуля начинается. ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: prioq.c Type: text/x-csrc Size: 1709 bytes Desc: отсутствует URL: From sitkarev на komitex.ru Sun Sep 26 01:56:27 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Sun, 26 Sep 2010 00:56:27 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: <4C9E61A8.7040408@komitex.ru> References: <4C9E61A8.7040408@komitex.ru> Message-ID: <4C9E61FB.50800@komitex.ru> Grigoriy A. Sitkarev пишет: > Тебе нужно добавить проверку во все public функции, как мы > договаривались, и немного переделать prioq_add потому что у меня там ф-я > prioq_resize() а у тебя её скорее всего нет. Имелось в виду prioq_put() конечно, не prioq_add(). -- Г.А. From alexeypetrunev на gmail.com Sun Sep 26 02:44:53 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Sun, 26 Sep 2010 01:44:53 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Я забыл написать #include "macros.h". From sitkarev на komitex.ru Mon Sep 27 22:28:30 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Mon, 27 Sep 2010 21:28:30 +0400 Subject: [cdev] =?utf-8?b?dGVsbmV0ICjRgdC+0YLRgNGD0LTQvdC40YfQtdGB0YLQstC+?= =?utf-8?q?=29?= In-Reply-To: <1285420176.4089.4.camel@jam> References: <1285420176.4089.4.camel@jam> Message-ID: <4CA0D43E.4060907@komitex.ru> Егор, ты не жди никого. Начинай писать сам. За основу можешь взять программу клиента TCP, который мы писали на занятиях. Внимательно изучи RFC854 и попробуй сделать минимально рабочий NVT (network virtual terminal) пока без опций. Для этого тебе нужно посимвольно обрабатывать входной буфер, то что ты будешь читать из сокета, обрабатывать NUL, LF, CR (потом можно доделать BEL, BS, HT, VT, FF). Тебе также нужно обнаруживать символ IAC (255) и пока просто игнорировать команды. Нужно сделать обработку CR LF и CR NULL, как требует RFC, в обе стороны. Это такой минимум. На любые запросы DO XXX и WILL XXX пока достаточно отвечать соответственно WON'T XXX и DON'T XXX. -- Г.А. jam пишет: > Кто хочет писать telnet? Предлагаю сотрудничество. > > > _______________________________________________ > cdev mailing list > cdev на wiki.syktsu.ru > http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev From alexeypetrunev на gmail.com Mon Sep 27 23:57:38 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Mon, 27 Sep 2010 22:57:38 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Я добавил условие в prioq_heapify, чтобы элемент не двигался если он больше своих потомков. ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: MyQueue.cpp Type: application/octet-stream Size: 5962 bytes Desc: отсутствует URL: From sitkarev на komitex.ru Tue Sep 28 00:40:30 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Mon, 27 Sep 2010 23:40:30 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: References: Message-ID: <4CA0F32E.10007@komitex.ru> Лёша, Большая просьба, поставь в редакторе TAB в 8 символов и посмотри что у тебя происходит, всё вкривь и вкось, где-то пляшет, где-то убежало. Где-то табуляция, где-то пробелы. Поправь пожалуйста, а то читать же невозможно, честное слово. Теперь замечания: 1. В prioq_remove() есть условие: if (q->used > 0 && idx != q->used) внутри этого блока выполняется код если: а) очередь не пуста, после удаления элемента; б) если удалённый элемент не был последним элементом в куче (индексом). Потому что если это так, то ничего с кучей делать не надо. У тебя почему-то часть кода, включая prioq_heapify(), вне этого блока находится. По смыслу, они должны быть внутри этого блока. 2. У нас это будет часть библиотеки. Все не-public функции должны получить модификатор static, чтобы они не засоряли пространство имён при связывании. Так, например, prioq_heapify() должна стать static void. 3. Не понятно, почему спустились определения макросов RIGHT_CHILD и LEFT_CHILD вниз. По смыслу они должны быть в начале файла, чтобы пользователь видел о чём речь пойдёт дальше, потому что основная структура, с которой идут манипуляции, это двоичная куча. 4. В prioq_remove() проверки в return_if_fail() указателя hp идут после того как он уже был разыменован, выше по коду. Там мы получаем индекс в hp->index. Надо быть немножко внимательнее, и не забывать что проверки у нас идут сразу же после определений локальных переменных и конечно же до попыток разыменования указателей, которые мы проверяем, и т.д. 5. Пример с использованием CONTAINER_OF() и твой проверочный код, и вообще всё, что не относится к API очереди, нужно вынести в отдельный файл исходный. У нас же prioq.c это часть библиотеки должно быть или отдельный объектный файл, так ведь? 6. Пример с CONTAINER_OF() не совсем верно использован, хотя и работает. Работает, потому что в структуре user_data поле prioq_head идёт первым и указатель на user_data аналогичен указатель на prioq_head. Но смысл CONTAINER_OF() был в том что мы можем поместить prioq_head в любом месте объемлющей структуры а затем по указатель на prioq_head получить саму структуру. Поэтому с примером ещё раз разберись, подумай, если не получится или что-то не понятно будет, я напишу подробнее. -- Г.А. Алексей Петрунёв пишет: > Я добавил условие в prioq_heapify, чтобы элемент не двигался если он > больше своих потомков. From alexeypetrunev на gmail.com Wed Sep 29 01:21:50 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Wed, 29 Sep 2010 00:21:50 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Поправил. P.S. Я не знаю как сделать TAB в 8 символов. ----------- следущая часть ----------- Вложение в формате HTML было извлечено… URL: ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: example.cpp Type: application/octet-stream Size: 746 bytes Desc: отсутствует URL: ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: MyQueue.cpp Type: application/octet-stream Size: 5391 bytes Desc: отсутствует URL: From alexeypetrunev на gmail.com Wed Sep 29 01:31:22 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Wed, 29 Sep 2010 00:31:22 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Я сейчас посмотрел архив с моим сообщением, там опять все "уехало". Я здесь не причем. ----------- следущая часть ----------- Вложение в формате HTML было извлечено… URL: From sitkarev на komitex.ru Wed Sep 29 02:25:00 2010 From: sitkarev на komitex.ru (Grigoriy A. Sitkarev) Date: Wed, 29 Sep 2010 01:25:00 +0400 Subject: [cdev] =?utf-8?b?0JfQsNC00LDRh9CwXzYuINCz0YAgMTM1?= In-Reply-To: References: Message-ID: <4CA25D2C.1030208@komitex.ru> Лёша, Тебе надо настроить почтовый клиент чтобы он посылал plain-text для начала. HTML от тебя сейчас приходит. Там ничего не уезжает потому что в архиве файлы, которые ты присылал. По поводу пробелов и табуляции. Табуляция это символ такой, один байт, из набора ASCII, его код 0x09. Текстовый редактор этот символ отображает как несколько пробелов, сколько там будет пробелов - это зависит от настроек редактора. Обычно этот параметр устанавливается где-то в настройках. Мы приняли соглашение что ширина табуляции у нас должна быть 8 символов. В твоих файлах в некоторых местах вместо табуляции используются 4-е пробела. Поэтому если например я поставлю себе ширину табуляции как мы договорились в 8 символов, то всё будет уезжать. Я думаю что тебе надо уже поставить нормальную ОС и выбрать хорошую среду разработки. 1. В prioq_get() надо проверять после извлечения элемента что там что-то осталось, и только после этого перемещать элемент из конца массива в начало и делать prioq_heapify(). Это я думаю очевидно. 2. Весь код, не относящийся к prioq надо убрать и перенести в example. Там не должно быть никаких ссылок на user_data и т.д. У нас же библиотека, так? 3. В примере вообще нет вызова prioq_*(). Не понятно тогда зачем он вообще нужен? Ты можешь линковать код примера с объектным файлом где реализована очередь, или же сделать из последнего библиотеку и линковать с библиотекой. Задавай вопросы, потому что здесь надо понять что тебе не ясно. Нам уже надо закончить с этим кодом и двинуться дальше. -- Г.А. Алексей Петрунёв пишет: > Я сейчас посмотрел архив с моим сообщением, там опять все "уехало". Я здесь > не причем. From alexeypetrunev на gmail.com Wed Sep 29 02:53:55 2010 From: alexeypetrunev на gmail.com (=?KOI8-R?B?4czFy9PFyiDwxdTS1c6j1w==?=) Date: Wed, 29 Sep 2010 01:53:55 +0400 Subject: [cdev] =?koi8-r?b?+sHEwd7BXzYuIMfSIDEzNQ==?= Message-ID: Давайте пример с CONTAINER_OF() останется на мой совести. Просто надоело уже отправлять, я понял как он работает. В prioq_get я условие добавил. Я бы хотел уже закончить. ----------- следущая часть ----------- Вложение в формате HTML было извлечено… URL: ----------- следущая часть ----------- A non-text attachment was scrubbed... Name: MyQueue.cpp Type: application/octet-stream Size: 5337 bytes Desc: отсутствует URL: