[cdev] Задача_6. гр 135

Grigoriy A. Sitkarev sitkarev на komitex.ru
Пн Сен 20 05:57:56 MSK 2010


Лёша,

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: <http://amplab.syktsu.ru/pipermail/cdev/attachments/20100920/923c6082/attachment.h>


Подробная информация о списке рассылки cdev