Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Язык С. Мастерство программирования. Принципы, практики и паттерны

Покупка
Новинка
Артикул: 856517.01.99
Доступ онлайн
1 699 ₽
В корзину
В этом практическом руководстве начинающие и опытные программисты на C найдут наставления по принятию проектных решений, включая пошаговое применение паттернов к сквозным примерам. Автор, один из ведущих членов сообщества паттернов проектирования, объясняет, как организовать программу на C, как обрабатывать ошибки и проектировать гибкие интерфейсы. В части I вы научитесь реализовывать проверенные практикой подходы к программированию на языке C; часть II показывает, как паттерны программирования на C применяются к реализации более крупных программ.
Прешерн, К. Язык С. Мастерство программирования. Принципы, практики и паттерны : практическое руководство / К. Прешерн ; пер. с англ. А. А. Слинкина. – Москва : ДМК Пресс, 2023. - 302 с. – ISBN 978-6-01810-340-7. - Текст : электронный. - URL: https://znanium.ru/catalog/product/2205124 (дата обращения: 11.04.2025). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов
Прешерн К.
Язык С  
Мастерство программирования
Принципы, практики и паттерны


Fluent C
Principles, Practices, and Patterns
Christopher Preschern
Beijing • Cambridge • Farnham • Köln • Sebastopol • Tokyo


Прешерн К.
Язык С  
Мастерство программирования
Принципы, практики и паттерны


УДК   004.4
ББК   32.372
П71
П71    Прешерн К.
Язык С. Мастерство программирования. Принципы, практики и паттерны / пер. с англ. А. А. Слинкина – М.: ДМК Пресс, 2023. – 300 с.: ил.
            ISBN 978-6-01810-340-7
В этом практическом руководстве начинающие и опытные программисты на C найдут наставления по принятию проектных решений, включая пошаговое применение паттернов к сквозным примерам.
Автор, один из ведущих членов сообщества паттернов проектирования, 
объясняет, как организовать программу на C, как обрабатывать ошибки 
и проектировать гибкие интерфейсы. В части I вы научитесь реализовывать проверенные практикой подходы к программированию на языке C; 
часть II показывает, как паттерны программирования на C применяются 
к реализации более крупных программ.
Copyright © 2023 Books.kz Limited Liability Partnership. All rights reserved.
Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без 
письменного разрешения владельцев авторских прав.
Материал, изложенный в данной книге, многократно проверен. Но, поскольку 
вероятность технических ошибок все равно существует, издательство не может гарантировать абсолютную точность и правильность приводимых сведений. В связи 
с этим издательство не несет ответственности за возможные ошибки, связанные 
с использованием книги.
ISBN 978-1-49210-973-3 (англ.)         ©  Christopher Preschern, 2023 
ISBN 978-6-01810-340-7 (казах.)          © Оформление, перевод на русский язык, издание, 
	
       Books.kz, 2023


Оглавление
Предисловие....................................................................................................8
ЧАСТЬ I. Паттерны на C...............................................................................25
Глава 1. Обработка ошибок.........................................................................26
Сквозной пример..............................................................................................27
Разбиение функции................................................................................................29
Проверка условий....................................................................................................32
Принцип самурая....................................................................................................35
Переход к обработке ошибки.................................................................................39
Запись об очистке....................................................................................................42
Объектная обработка ошибок................................................................................45
Резюме................................................................................................................48
Для дополнительного чтения...........................................................................49
Что дальше.........................................................................................................50
Глава 2. Возврат информации об ошибке.................................................51
Сквозной пример..............................................................................................52
Возврат кода состояния..........................................................................................54
Возврат существенной информации об ошибке...................................................61
Специальное возвращаемое значение..................................................................67
Протоколирование ошибок....................................................................................70
Резюме................................................................................................................77
Для дополнительного чтения...........................................................................77
Что дальше.........................................................................................................77
Глава 3. Управление памятью.....................................................................78
Хранение данных и проблемы с динамической памятью..............................80
Сквозной пример....................................................................................................83
Сначала стек............................................................................................................83
Вечная память.........................................................................................................86
Последствия.............................................................................................................88
Отложенная очистка...............................................................................................90
Единоличное владение...........................................................................................94
Обертка выделения.................................................................................................97
Проверка указателя...............................................................................................102
Пул памяти............................................................................................................105
Резюме..............................................................................................................111
Для дополнительного чтения.........................................................................111
Что дальше.......................................................................................................112
Глава 4. Возврат данных из C-функций...................................................113
Сквозной пример............................................................................................115
Возвращаемое значение.......................................................................................116


6    Оглавление
Выходные параметры...........................................................................................119
Агрегат...................................................................................................................123
Неизменяемый экземпляр...................................................................................128
Буфер, принадлежащий вызывающей стороне..................................................131
Вызываемая сторона выделяет память...............................................................135
Резюме..............................................................................................................139
Что дальше.......................................................................................................140
Глава 5. Время жизни и владение данными..........................................141
Сквозной пример............................................................................................143
Программный модуль без состояния...................................................................144
Программный модуль с глобальным состоянием...............................................148
Экземпляр, принадлежащий вызывающей стороне..........................................152
Разделяемый экземпляр.......................................................................................158
Резюме..............................................................................................................164
Для дополнительного чтения.........................................................................165
Что дальше.......................................................................................................166
Глава 6. Гибкие API......................................................................................167
Сквозной пример............................................................................................169
Заголовочные файлы............................................................................................169
Описатель..............................................................................................................172
Динамический интерфейс....................................................................................176
Управление функцией..........................................................................................179
Резюме..............................................................................................................183
Для дополнительного чтения.........................................................................183
Что дальше.......................................................................................................184
Глава 7. Гибкие интерфейсы итераторов.................................................185
Сквозной пример............................................................................................187
Доступ по индексу.................................................................................................188
Курсор.....................................................................................................................192
Итератор обратного вызова.................................................................................197
Резюме..............................................................................................................202
Для дополнительного чтения.........................................................................203
Что дальше.......................................................................................................204
Глава 8. Организация файлов в модульных программах....................205
Сквозной пример............................................................................................207
Охрана включения................................................................................................209
Каталоги программных модулей.........................................................................212
Глобальный каталог include..................................................................................217
Автономный компонент.......................................................................................221
Копия API...............................................................................................................226
Резюме..............................................................................................................235
Что дальше.......................................................................................................235
Глава 9. Бегство из ада #ifdef....................................................................236
Сквозной пример............................................................................................238
Избегание вариантов............................................................................................240


Оглавление    7
Изолированные примитивы................................................................................243
Атомарные примитивы........................................................................................246
Уровень абстракции..............................................................................................250
Разделение реализаций вариантов......................................................................255
Резюме..............................................................................................................261
Для дополнительного чтения.........................................................................261
Что дальше.......................................................................................................262
ЧАСТЬ II. Истории о паттернах................................................................263
Глава 10. Реализация протоколирования...............................................264
История о паттернах.......................................................................................264
Организация файлов.............................................................................................265
Центральная функция протоколирования..........................................................266
Фильтрация источника сообщений.....................................................................267
Условное протоколирование................................................................................269
Несколько мест протоколирования.....................................................................270
Протоколирование в файл....................................................................................272
Кросс-платформенная обработка файлов...........................................................273
Использование средства протоколирования......................................................277
Резюме..............................................................................................................277
Глава 11. Построение системы управления пользователями.............279
История о паттернах.......................................................................................279
Организация данных............................................................................................279
Организация файлов.............................................................................................281
Аутентификация: обработка ошибок..................................................................282
Аутентификация: протоколирование ошибок....................................................284
Добавление пользователей: обработка ошибок.................................................285
Итерирование........................................................................................................287
Применение системы управления пользователями...........................................290
Резюме..............................................................................................................291
Глава 12. Заключение.................................................................................293
Чему вы научились..........................................................................................293
Для дополнительного чтения.........................................................................293
Заключительные замечания...........................................................................294
Об авторе.....................................................................................................295
Об иллюстрации на обложке....................................................................295
Предметный указатель..............................................................................296


Предисловие
Вы купили эту книгу, чтобы поднять свои навыки программирования на новый 
уровень. И это правильно, потому что вам, безусловно, пригодятся излагаемые 
в ней практические знания. Если у вас имеется большой опыт программирования на C, то вы в деталях узнаете, как принимаются хорошие проектные решения и какие у них есть плюсы и минусы. Если вы только начинаете знакомиться 
с C, то найдете здесь руководство по принятию решений и на примерах кода 
увидите, как эти решения применяются для построения больших программ.
В книге есть ответы на вопросы о том, как структурировать C-программу, 
как обрабатывать ошибки и как проектировать гибкие интерфейсы. Когда вы 
больше узнаёте о программировании на C, начинают возникать разные вопросы, например:
•	 следует ли возвращать имеющуюся информацию об ошибке?
•	 следует ли использовать для этой цели глобальную переменную errno?
•	 что лучше: немного функций с большим числом параметров или наоборот?
•	 как построить гибкий интерфейс?
•	 как реализовать базовые вещи, например итератор?
Для объектно ориентированных языков на большую часть этих вопросов 
почти исчерпывающий ответ дает книга «банды четырех»: Erich Gamma, Richard 
Helm, Ralph Johnson, John Vlissides «Design Patterns: Elements of Reusable Object-Oriented Software»1. Паттерны проектирования дают программисту проверенные 
опытом рекомендации, как должны взаимодействовать между собой объекты 
и как они связаны отношением владения. Кроме того, они показывают, как 
следует группировать объекты.
Однако на процедурных языках типа C большинство этих паттернов проектирования невозможно реализовать так, как описано «бандой четырех». 
В  С  нет встроенных объектно ориентированных механизмов. Наследование 
или полиморфизм  можно эмулировать, но это не лучшее решение, потому что 
такой код будет непонятен программистам, привыкшим к программированию 
на C, но не владеющим программированием на объектно ориентированных 
языках типа C++ и незнакомым с использованием таких концепций, как наследование и полиморфизм. Такие программисты хотели бы придерживаться 
стиля программирования на C, к которому привыкли. Однако к нему применимы не все объектно ориентированные рекомендации или, по крайней мере, 
конкретная реализация идеи паттерна проектирования не годится для не объектно ориентированного языка.
1	
 Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. «Паттерны объектно ориентированного проектирования». Питер, 2022.


Зачем я написал эту книгу    9
Итак, ситуация выглядит следующим образом: мы хотим писать на C, но не 
можем напрямую использовать большую часть знаний, документированных в 
виде паттернов проектирования. В этой книге показано, как преодолеть разрыв и практически реализовать эти знания на языке программирования C.
Зачем я написал эту книгу
Теперь я хочу рассказать, почему знания, собранные в этой книге, оказались 
столь важными для меня и почему их так трудно отыскать.
В школе я изучал C в качестве первого языка программирования. Как и любой 
начинающий программист на C, я удивлялся, почему нумерация элементов 
массива начинается с 0, и наугад пытался поместить операторы * и & в нужное 
место, чтобы заставить работать магию указателей.
В университете я узнал, как в действительности работают синтаксические 
конструкции C и как они транслируются в аппаратные биты и байты. Вооруженный этими знаниями, я смог писать небольшие программы, которые работали очень хорошо. Но я по-прежнему не понимал, почему более длинный код 
выглядит именно так, а не иначе, и, уж конечно, не мог сам придумать решения 
вроде:
typedef struct INTERNAL_DRIVER_STRUCT* DRIVER_HANDLE;
typedef void (*DriverSend_FP)(char byte);
typedef char (*DriverReceive_FP)();
typedef void (*DriverIOCTL_FP)(int ioctl, void* context);
struct DriverFunctions
{
  DriverSend_FP fpSend;
  DriverReceive_FP fpReceive;
  DriverIOCTL_FP fpIOCTL;
};
DRIVER_HANDLE driverCreate(void* initArg, struct DriverFunctions f);
void driverDestroy(DRIVER_HANDLE h);
void sendByte(DRIVER_HANDLE h, char byte);
char receiveByte(DRIVER_HANDLE h);
void driverIOCTL(DRIVER_HANDLE h, int ioctl, void* context);
При изучении этого кода возникает много вопросов:
•	 зачем нужны указатели на функции в struct?
•	 зачем функциям нужен этот DRIVER_HANDLE?
•	 что такое IOCTL и почему бы не написать вместо этого отдельные функции?
•	 зачем нужны явные функции создания и уничтожения?
Эти вопросы появились, когда я начал писать производственные приложения. 


10    Предисловие
Я то и дело сталкивался с ситуациями, когда понимал, что мне не хватает 
знаний о C; например, как реализовать итератор или как обрабатывать ошибки 
в функциях. Я осознавал, что синтаксис-то я освоил, но понятия не имею, как 
им правильно воспользоваться. Я пытался чего-то добиться, но все получалось 
коряво или не получалось вовсе. Мне были необходимы рекомендации, 
показывающие, как решать конкретные задачи на языке C. Например:
•	 как проще всего захватывать и освобождать ресурсы?
•	 можно ли использовать goto для обработки ошибок?
•	 следует ли сразу проектировать интерфейс гибким или лучше изменять 
его, когда возникнет необходимость?
•	 следует ли использовать макрос assert, или нужно возвращать код 
ошибки?
•	 как реализовать итератор на C?
Для меня оказалось неожиданным открытием, что, хотя у моих опытных 
коллег было много различных ответов на эти вопросы, никто не смог направить меня туда, где такие проектные решения были документированы вместе 
с описанием их плюсов и минусов.
Поэтому я обратился к интернету и снова испытал удивление: оказалось 
очень трудно найти убедительные ответы на эти вопросы, хотя язык C существует уже не один десяток лет. Я обнаружил, что, несмотря на изобилие литературы по основам и синтаксису языка C, нет почти ничего о продвинутом 
программировании и о том, как писать на C красивый код, который выдержит 
испытание производственным приложением.
И вот тут в игру вступает эта книга. Она поможет вам отточить свои навыки программирования на C и перейти от простеньких программок к большим 
системам, в которых ошибки обрабатываются должным образом и которые обладают достаточной гибкостью, чтобы быть готовыми к будущим изменениям 
требований и проекта. В этой книге используется концепция паттернов проектирования, чтобы познакомить вас со всеми шагами принятия решений и 
оценкой их достоинств и недостатков.  Эти паттерны применяются к сквозным 
примерам когда, чтобы показать, как код эволюционирует и почему принимает именно такую, а не иную конечную форму.
Основы паттернов
Рекомендации по проектированию в этой книге приводятся в форме паттернов. Идея представлять знания и передовые практики в виде паттернов исходит от архитектора Кристофера Александра, который высказал ее в книге 
«The Timeless Way of Building» (Oxford University Press, 1979). Он использует 
небольшие проверенные временем фрагменты для решения важнейшей проблемы в своей области: как проектировать и возводить города. Подход на основе паттернов переняли разработчики программного обеспечения, и теперь 
проводятся конференции типа Pattern Languages of Programs (PLoP), имеющие 
целью расширить наши знания о паттернах. В особенности книга «банды четы

Похожие

Доступ онлайн
1 699 ₽
В корзину