Добрый день!
Я начинающий программист на С и у меня возник ряд вопросов при разработке приложений, которые чуть больше, чем тестовые примеры:
1. Реализуете ли вы свой ADT для каждого отдельного модуля с opaque указателем или используете открытую структуру и в программе сами выделяете для нее место и получаете значения отдельных элементов напрямую из структуры?
2. Используете ли вы глобальные переменные? Например, если необходимо использовать одну и ту же переменную в нескольких модулях системы. Если ее передавать в каждый модуль, заметно возрастает сложность интерфейса, а иначе получается взаимозависимость между модулями.
3. Реализуете ли вы в своем системе exception'ы или используете глобальную переменную наподобие errno, или делаете реализацию, наподобие GError в glib, ну или просто возвращаете специальное значение из функции (например, NULL)?
4. Используете ли вы assert'ы или обрабатываете, все исключительные ситуации сами?
5. Реализуете ли вы собственные wrapper'ы для malloc/free?
6. Реализуете ли вы базовые структуры данных сами (списки, деревья и т.п.) или используете готовую библиотеку, например glib?
7. Подскажите хорошую литературу/форумы на английском/русском языке для уровня intermediate++.
Проектирование программных интерфейсов на C
1. Не использую данный подход
2. Нет
3. Возвращаю специальное значение из функции
4. Использую
5. Нет
6. Зависит от задачи
2. Используете ли вы глобальные переменные? Например, если необходимо использовать одну и ту же переменную в нескольких модулях системы. Если ее передавать в каждый модуль, заметно возрастает сложность интерфейса, а иначе получается взаимозависимость между модулями.
да. если это действительно глобальные данные, вроде упомянутой вами errno
(эмпирика - если их >10, то это быдлокод)
3. Реализуете ли вы в своем системе exception'ы или используете глобальную переменную наподобие errno, или делаете реализацию, наподобие GError в glib, ну или просто возвращаете специальное значение из функции (например, NULL)?
это от задачи зависит. шурупы я завинчиваю отвёрткой.
6. Реализуете ли вы базовые структуры данных сами (списки, деревья и т.п.) или используете готовую библиотеку, например glib?
использую и то, и то.
7. Подскажите хорошую литературу/форумы на английском/русском языке для уровня intermediate++.
у нас тут тема есть про это.
1. Не использую данный подход
А как вы реализуете стек, список и т.п.; собственные библиотеки?
5. Нет
Пользуетесь malloc и проверяете на NULL каждый раз? Вообще вопрос больше в другом, пишете ли вы wrapper'ы как для стандартных функций так и для своих собственных, с дополнительными проверками и предопределенными значениями?
у нас тут тема есть про это.
В той теме обсуждают в основном книги по С++. Интересуют форумы по программированию на С
А как вы реализуете стек, список и т.п.; собственные библиотеки?
Джефф Элджер "C++ ++"
эту книжку читали?
[quote=eyenie]А как вы реализуете стек, список и т.п.; собственные библиотеки?
Джефф Элджер "C++ ++"
эту книжку читали?[/quote]
Нет, к сожалению пока еще не читал. Но обсуждаем вроде чистый С, а не С++.
Нет, к сожалению пока еще не читал. Но обсуждаем вроде чистый С, а не С++.
прочитайте. Если у вас возникают такие вопросы, то С без плюсов вам явно недостаточно.
А как вы реализуете стек, список и т.п.; собственные библиотеки?
лично я не знаю, как можно сделать простой и удобный способ вынести из своей либы хоть сколько-нибудь сложную структуру. Проблемы начинаются с обычных массивов - внезапно оказывается, что в С их просто нет - есть указатель на начало, и всё. И если со строками ещё можно как-то выкрутится (ASCIIZ), то всё остальное... Посмотрите на страшненькие реализации той-же qsort :(
В плюсах это выглядит более-менее приемлемо.
А как вы реализуете стек, список и т.п.; собственные библиотеки?
Извиняюсь, за путаницу я говорил об:
Реализуете ли вы свой ADT для каждого отдельного модуля с opaque указателем
Пользуетесь malloc и проверяете на NULL каждый раз? Вообще вопрос больше в другом, пишете ли вы wrapper'ы как для стандартных функций так и для своих собственных, с дополнительными проверками и предопределенными значениями?
Если есть необходимость, то создаю функции вида struct object *new_object(), которая вызывает malloc, и инициализирует поля структуры. Для выделения, к примеру, памяти под массив обычно просто вызываю malloc.
лично я не знаю, как можно сделать простой и удобный способ вынести из своей либы хоть сколько-нибудь сложную структуру.
Никогда не испытывал с этим особых проблем, объявлял структуру в хедере и вуаля =) С массивами все немного сложнее...
Никогда не испытывал с этим особых проблем, объявлял структуру в хедере и вуаля
я не про структуру в смысле struct {};, я про структуру данных. Например стек, или очередь. Или даже простой массив. Слишком сильные зависимости, если в ++ я пишу array[17] в клиентском коде, и у меня всё работает, даже если array это дерево, то в простом Си array это именно указатель, причём нет никакой возможности указать его длину.
[quote=RasenHerz]Никогда не испытывал с этим особых проблем, объявлял структуру в хедере и вуаля
я не про структуру в смысле struct {};, я про структуру данных. Например стек, или очередь. Или даже простой массив. Слишком сильные зависимости, если в ++ я пишу array[17] в клиентском коде, и у меня всё работает, даже если array это дерево, то в простом Си array это именно указатель, причём нет никакой возможности указать его длину.[/quote]
А что мешает реализовать свой ADT, где будет указана и длина массива и все что вам нужно? Реализовать функции для работы с этой ADT, тогда не будет никаких зависимостей.
А что мешает реализовать свой ADT, где будет указана и длина массива и все что вам нужно? Реализовать функции для работы с этой ADT, тогда не будет никаких зависимостей.
мешает то, что в С++ это делается просто и естественно, а как это реализовать красиво в С - я не знаю.