LinuxForum.Fans
Тема

Проектирование программных интерфейсов на C

Автор: eyenie 12 сообщений 2366 просмотров
#165616

Добрый день!
Я начинающий программист на С и у меня возник ряд вопросов при разработке приложений, которые чуть больше, чем тестовые примеры:
1. Реализуете ли вы свой ADT для каждого отдельного модуля с opaque указателем или используете открытую структуру и в программе сами выделяете для нее место и получаете значения отдельных элементов напрямую из структуры?
2. Используете ли вы глобальные переменные? Например, если необходимо использовать одну и ту же переменную в нескольких модулях системы. Если ее передавать в каждый модуль, заметно возрастает сложность интерфейса, а иначе получается взаимозависимость между модулями.
3. Реализуете ли вы в своем системе exception'ы или используете глобальную переменную наподобие errno, или делаете реализацию, наподобие GError в glib, ну или просто возвращаете специальное значение из функции (например, NULL)?
4. Используете ли вы assert'ы или обрабатываете, все исключительные ситуации сами?
5. Реализуете ли вы собственные wrapper'ы для malloc/free?
6. Реализуете ли вы базовые структуры данных сами (списки, деревья и т.п.) или используете готовую библиотеку, например glib?
7. Подскажите хорошую литературу/форумы на английском/русском языке для уровня intermediate++.

#166002

1. Не использую данный подход
2. Нет
3. Возвращаю специальное значение из функции
4. Использую
5. Нет
6. Зависит от задачи

#166011
eyenie написал:
2. Используете ли вы глобальные переменные? Например, если необходимо использовать одну и ту же переменную в нескольких модулях системы. Если ее передавать в каждый модуль, заметно возрастает сложность интерфейса, а иначе получается взаимозависимость между модулями.

да. если это действительно глобальные данные, вроде упомянутой вами errno
(эмпирика - если их >10, то это быдлокод)

eyenie написал:
3. Реализуете ли вы в своем системе exception'ы или используете глобальную переменную наподобие errno, или делаете реализацию, наподобие GError в glib, ну или просто возвращаете специальное значение из функции (например, NULL)?

это от задачи зависит. шурупы я завинчиваю отвёрткой.

eyenie написал:
6. Реализуете ли вы базовые структуры данных сами (списки, деревья и т.п.) или используете готовую библиотеку, например glib?

использую и то, и то.

eyenie написал:
7. Подскажите хорошую литературу/форумы на английском/русском языке для уровня intermediate++.

у нас тут тема есть про это.

#166043
RasenHerz написал:
1. Не использую данный подход

А как вы реализуете стек, список и т.п.; собственные библиотеки?

RasenHerz написал:
5. Нет

Пользуетесь malloc и проверяете на NULL каждый раз? Вообще вопрос больше в другом, пишете ли вы wrapper'ы как для стандартных функций так и для своих собственных, с дополнительными проверками и предопределенными значениями?

#166048
drBatty написал:
у нас тут тема есть про это.

В той теме обсуждают в основном книги по С++. Интересуют форумы по программированию на С

#166050
eyenie написал:
А как вы реализуете стек, список и т.п.; собственные библиотеки?

Джефф Элджер "C++ ++"
эту книжку читали?

#166059
drBatty написал:
[quote=eyenie]А как вы реализуете стек, список и т.п.; собственные библиотеки?

Джефф Элджер "C++ ++"
эту книжку читали?[/quote]
Нет, к сожалению пока еще не читал. Но обсуждаем вроде чистый С, а не С++.

#166075
eyenie написал:
Нет, к сожалению пока еще не читал. Но обсуждаем вроде чистый С, а не С++.

прочитайте. Если у вас возникают такие вопросы, то С без плюсов вам явно недостаточно.

eyenie написал:
А как вы реализуете стек, список и т.п.; собственные библиотеки?

лично я не знаю, как можно сделать простой и удобный способ вынести из своей либы хоть сколько-нибудь сложную структуру. Проблемы начинаются с обычных массивов - внезапно оказывается, что в С их просто нет - есть указатель на начало, и всё. И если со строками ещё можно как-то выкрутится (ASCIIZ), то всё остальное... Посмотрите на страшненькие реализации той-же qsort :(
В плюсах это выглядит более-менее приемлемо.

#166094
eyenie написал:

А как вы реализуете стек, список и т.п.; собственные библиотеки?

Извиняюсь, за путаницу я говорил об:

eyenie написал:

Реализуете ли вы свой ADT для каждого отдельного модуля с opaque указателем
eyenie написал:

Пользуетесь malloc и проверяете на NULL каждый раз? Вообще вопрос больше в другом, пишете ли вы wrapper'ы как для стандартных функций так и для своих собственных, с дополнительными проверками и предопределенными значениями?

Если есть необходимость, то создаю функции вида struct object *new_object(), которая вызывает malloc, и инициализирует поля структуры. Для выделения, к примеру, памяти под массив обычно просто вызываю malloc.

drBatty написал:
лично я не знаю, как можно сделать простой и удобный способ вынести из своей либы хоть сколько-нибудь сложную структуру.

Никогда не испытывал с этим особых проблем, объявлял структуру в хедере и вуаля =) С массивами все немного сложнее...

#166097
RasenHerz написал:
Никогда не испытывал с этим особых проблем, объявлял структуру в хедере и вуаля

я не про структуру в смысле struct {};, я про структуру данных. Например стек, или очередь. Или даже простой массив. Слишком сильные зависимости, если в ++ я пишу array[17] в клиентском коде, и у меня всё работает, даже если array это дерево, то в простом Си array это именно указатель, причём нет никакой возможности указать его длину.

#166124
drBatty написал:
[quote=RasenHerz]Никогда не испытывал с этим особых проблем, объявлял структуру в хедере и вуаля

я не про структуру в смысле struct {};, я про структуру данных. Например стек, или очередь. Или даже простой массив. Слишком сильные зависимости, если в ++ я пишу array[17] в клиентском коде, и у меня всё работает, даже если array это дерево, то в простом Си array это именно указатель, причём нет никакой возможности указать его длину.[/quote]

А что мешает реализовать свой ADT, где будет указана и длина массива и все что вам нужно? Реализовать функции для работы с этой ADT, тогда не будет никаких зависимостей.

#166163
eyenie написал:
А что мешает реализовать свой ADT, где будет указана и длина массива и все что вам нужно? Реализовать функции для работы с этой ADT, тогда не будет никаких зависимостей.

мешает то, что в С++ это делается просто и естественно, а как это реализовать красиво в С - я не знаю.

Войдите или зарегистрируйтесь, чтобы ответить.