В. Г. АБАШИН - abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4...

520
В. Г. АБАШИН СИНЕРГИЯ СИ Москва 2019

Upload: others

Post on 10-Sep-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

В. Г. АБАШИН

СИНЕРГИЯ СИ

Москва 2019

Page 2: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

УДК ____.__:___.__(___._)ББК __.___._-___._

____

Абашин В.Г.А13 Синергия Си: Учеб. пособие. - М: XXXXXXX

Издательство, 2019. - 520 с.: ил.ISBN _-___-_____-_.

Первые две главы содержат общие знания,необходимые для освоения языка программирования Си.Главы третья, четвертая и пятая содержат описаниеязыка Си. В них приводятся ссылки на разделы стандартаязыка Си, содержащие исчерпывающие описанияконструкций языка Си. Шестая глава посвященанаиболее часто используемым технологиямпрограммирования в среде GNU/Линукс. В седьмой главезатронуты вопросы алгоритмизации. Восьмая главасостоит из списка этапов разработки программы наязыке Си с учетом технологий программирования.

Для желающих освоить программирование на языке Си.УДК ___._.__:___.__(___._)ББК __.___._-___._

ISBN _-___-_____-_. © В.Г Абашин, 2019

Page 3: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

Посвящаю своему сыну Абашину Андрею Валерьевичу

Выражаю благодарность моим учителям:- Сорокиной Галине Александровне,- Брагиной Людмиле Николаевне,- Лобановой Валентине Андреевне,- Пилипенко Ольге Васильевне,- и всем кто смог меня научить чему-то, независимо от обстоятельств.

Page 4: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

4

Синергия Си

Введение 8

1. Базовые понятия и навыки 191.1. Информация и данные 191.2. Кодирование информации 281.3. Процессы 331.4. Базовые алгоритмы для программиста на языке

Си и способы их применения42

1.5. Базовое программное обеспечение, операционные системы

52

1.6. Файловые системы 621.7. Конфигурационная информация 721.8. Стек протоколов TCP/IP 76

2. Администрирование ЭВМ, компьютерных сетей 872.1. Установка и обновление ОС и ПО 872.2. Программное обеспечение 952.3. Эмулятор терминала 1032.4. Текстовый редактор vim 1172.5. Диагностические утилиты 1282.6. Диагностические сетевые утилиты. Сетевые

службы141

2.7. Информационная безопасность 154

3. Язык программирования Си 1583.1. Концепция языка. Первая программа 1583.2. Типы данных. Операторы ввода/вывода 1733.3. Выражения. Арифметические операции.

Математические функции187

3.4. Операторы выбора 1983.5. Операторы цикла 206

Page 5: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

5

3.6. Функции 2103.7. Область видимости 2193.8. Операции прерывания и безусловного перехода 2313.9. Стиль программирования 238

4. Язык программирования Си. Составные типы данных

245

4.1. Составные типы данных: массивы 2464.1.1. Объявление и инициализация массивов 2464.1.2. Обращение к элеметам массива 2504.1.3. Упорядочивание массивов 2624.2. Составные типы данных: структуры и

объединения275

4.2.1. Объединения 2754.2.2. Структуры 2804.2.3. Расположение элементов структур в ОЗУ ЭВМ 2844.3. Составные типы данных: строки 2954.3.1. Объявление и инициализация строк 2954.3.2. Функции для работы со строками 3014.3.3. Пример: инверсия символов 3134.4. Составные типы данных: многомерные массивы 3154.4.1. Инициализация многомерных массивов 3154.4.2. Операции с многомерными массивами 3324.5. Составные типы данных: битовые поля 3384.6. Составные типы данных: перечисления 343

5. Язык программирования Си. Вспомогательные средства и приемы работы

348

5.1. Переменные. Указатели. Объявления 3485.2. Преобразования типов данных 3545.3. Логические, битовые операции, операции

сдвига, операции сравнения363

5.4. Квалифицирующие типы и спецификаторы функций

372

Page 6: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

6

5.5. Директивы предпроцессора 3785.6. Отличия между стандартами языка Си разных

лет386

5.7. Переменные окружения. Потоки ввода вывода. Передача параметров

389

6. Технологии программирования. Средства автоматизации разработки

397

6.1. Жизненный цикл ПО. Методологии разработки ПО

397

6.2. Концепция системы контроля версий git 4046.3. Этапы создания исполняемого файла. Типы

исполняемых файлов. Профилирование программы

423

6.4. Автоматизация проверки исходных текстов и создания исполняемых файлов

433

6.5. Автоматическая генерация документации 4426.6. Приемы отладки программ 4466.6.1. Отладка без специальных программ 4486.6.2. Отладка с использованием gdb 4576.6.3. Поиск утечек памяти valgrind 4656.7. Си и ассемблер. Технологии

дезасемблирования469

6.8. Использование библиотек 4796.8.1. Библиотечные функции 4796.8.2. Статические библиотеки 4826.8.3. Динамические библиотеки 485

7. Экспресс — алгоритмизация 4947.1. Блок-схемы и UML 4947.2. Реализация односвязных и многосвязных

списков496

7.3. Приемы оценки вычислительной сложности алгоритмов

502

Page 7: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

7

8. Новый взгляд на программу «Привет, мир!» 507

Заключение 514

Литература 515

Page 8: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

8

Введение

Тест на то, какой Вы программист.Что Вы видите?

i = 0;

Варианты ответов:а) код;б) выражение с ошибкой;в) так уже не делают;г) все равно на это книгой не мотивируешь.Список с оценкой квалификации и еще один

шуточный тест где-то во введении.Зачем становиться программистом?Заработная плата программиста обычно больше, чем

у других специалистов. Это элита любой компании.Отличный старт для управленцев и менеджеров. Этовозможность посмотреть мир, имея высокий личныйдоход, видеть перспективные технологии до их появленияв серийном производстве, а значить жить немного вбудущем.

Основная цель среды «информационщиков» - делатьмир лучше. Возможно, что такой подход немногоидеализирован, это скорее то, к чему стремятся всепрограммисты. Все равно, любое свое значимое решениеследует оценивать в соответствии с этой миссией.Получившие широкое распространение компьютерныезлоумышленники обычно имеют посредственнуюквалификацию или не имеют специального образованиявообще. Это факт, это статистика правохранительныхорганов.

Само по себе программирование похоже наплавание. В том смысле, что чтобы научиться плавать —

Page 9: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

9

необходимо плавать. По учебнику плавать не научишься.Учебник должен лежать рядом с клавиатурой, с помощьюкоторой проверяется все, что написано в учебнике.Программирование — это плавание для ума.

С другой стороны, программирование похоже наигру. Каждый день или даже каждый час необходимоставить себе задачу, решать головоломки и получатьнебольшую порцию серотонина в награду за её успешноерешение. Программирование позволяет развивать свойинтеллект, изучать полезные в обычной жизни приемымышления. В то же время программирование требуетусидчивости.

Кроме желания заниматься программированием, дляуспешного освоения этой профессии необходимообладать рядом качеств. Наиболее яркойпрофессиональной деформацией среди программистовявляется тип мышления. Каждый современныйпрограммист обычно обладает несколькими типамимышления. Самый важный — алгоритмический типмышления. Как показывает практика на егоформирование уходит не менее полугода. Время егоразвития зависит от исходных условий. Человек,обладающий математической подготовкой, обычно ужеимеет алгоритмическое мышление и требуется толькотренировка в переложении алгоритмов на языкпрограммирования или отображение алгоритмов спомощью блок-схем. Охарактеризовать данный тип однимпредложением можно так: все — последовательностьдействий.

Другой популярный тип мышления – объектный. Онреализуется объектно-ориентированными языками. Егоразвитие обычно происходит после формированияалгоритмического мышления и занимает немногоменьше времени. Вполне достаточно месяца, чтобы

Page 10: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

10

разобраться с этой концепцией. Самым близкимобъектно-ориентированным языком к Си является С++,однако это полностью другой язык. Объектно-ориентированное мышление можно реализовывать и спомощью языка Си, но такой подход может потребоватьизлишних или «некрасивых» конструкций в коде,которые будут признаны Си — программистами плохимипрактиками программирования. Охарактеризуем этоттип мышления так: все — объект, объектывзаимодействуют между собой.

Еще один популярный тип мышления —многопоточный. Сейчас его не выделяют какотдельный тип мышления, считая скорее рядомограничений, зависимых от современных технологий,например CUDA. Данный тип мышления являетсянадстройкой как для алгоритмического, так и дляобъектного типа мышления. Обучение ему обычнопроисходит на месячных курсах повышенияквалификации для программистов с опытом или в рамкахдисциплины в среднем или высшем учебном заведении.Охарактеризуем этот тип мышления так: вычисления –это потоки, потоки текут с разной скоростью, нодолжны закончится вместе.

Главным ошибочным типом мышления является –предоптимизация. Он встречается как у начинающихпрограммистов со стажем 1-3 года, так и упродолжающих, со стажем 3-6 лет. В этом случаепрограммист пытается улучшить программу до того, какона написана полностью. Этот тип мышления — главныйвраг программистов. Любая оптимизация заключается вобъединении ресурсов или алгоритмов. Получаетсясвоего рода свернутая, упакованная структурапрограммы, которая, в случае изменения, часто требуетполного перепроектирования части программы. Если

Page 11: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

11

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

Для каждого программиста характерен свой способнаписания исходных кодов программ. Такой способназывается стилем программирования. В данномслучае подразумевается, что язык программированияпозволяет написать одно и то же действие разнымиспособами, кроме того, можно по разному поставитьскобки, сделать для наглядности переносы на новуюстроку или разрядить код пробельными символами,называть по определенным правилам пользовательскиепеременные и функции. Обычно в компаниях имеетсянекоторый набор примеров кода, которые используютсядля образца. Нарушать корпоративный стиль нельзя. Этоне является обязательным навыком, поэтомупрограммисты, получившие образование в постсоветскойшколе, часто используют ничего не значащие названияпеременных из одной буквы и прочие приемы,понижающие читаемость исходных кодов программы.

Любая сложная технология есть плод трудамножества людей разных профессий. Технология можетрождаться столетиями, а может за один год. Насегодняшний день нет такого человека, который одинвладел бы всеми технологиями производствавычислительных машин. Не существует даже такогогосударства, которое одно могло бы произвести самоепередовое устройство, без приобретения материалов,технологий или составных элементов в других странах.Каждый элемент информационных систем был в своевремя новшеством, которое сделало использованиевычислительных средств немного проще. Все это было быневозможно без формирования среды межчеловеческогообщения с позитивным настроем, желанием бескорыстнопомогать друг другу в развитии технологий. Такой подход

Page 12: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

12

реализован в различных форумах, конференциях,сообществах, группах, в которых происходит обсуждениеразвития технологий, обучение молодых специалистов.Базовым законом таких сообществ является желаниебескорыстно помогать другим и возможность, в случаенеобходимости, получить помощь самому.

В сфере информационных технологий при общениипринято ссылаться на первоисточник знания отехнологии. К ним относятся стандарты и спецификации,принятые в разных странах и организациях: ГОСТ, RFC,IEEE, документы SIG по направлениям. Причина в том,что информационные технологии развиваются попринципам инженерного дела. К программистам наязыке Си это относится даже больше, чем, например, кпрограммистам на PHP или других высокоуровневыхприкладных языках.

Информационные системы — первая областьдеятельности человека, в которой удалось создатьтехнологию, используемую большей частью населенияпланеты, без принуждения одного человека другим. Приэтом продукт получился более высокого качества, чемпри использовании обычных иерархическо-подчиненныхструктур управления коммерческих организаций. Вданном случае имеется ввиду операционная системаЛинукс, над разработкой которой работают сотни тысячлюдей, не имея единого центра управления. Этот фактеще требует осознания обществом, но несомненно онокажет значительное влияние на развитие всейчеловеческой цивилизации.

Ответьте себе на следующие вопросы. Вам хотелосьбы научиться пользоваться инструментом, которыйявляется ключом ко всем современным информационнымтехнологиям? Какой язык программирования являетсясамым универсальным? На каком языке можно писать

Page 13: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

13

программы для микроконтроллеров по цене 135 рублей,программировать Интернет-вещи, создаватьискусственный интеллект? Какой язык является однимиз самых компактных и простых?

Всем этим условиям удовлетворяет языкпрограммирования Си. Этому языку программирования46 лет. Программисты на этом языке руководствуютсяпринципом: чем проще — тем лучше. Наиболеепродвинутые используют специальные правила даже дляобоснования применения вполне тривиальныхконструкций, советуют избегать longjump указателей нафункции, malloc, арифметики указателей, обычныхструктур.

Следует учитывать, что когда работодательформулирует вакансию программиста на языке Си, он неищет человека, который умеет программировать на СИ.Работодатель ищет человека, который умеет решатьзадачи, стоящие перед компанией. Обычно этопрограммирование микроконтроллеров,высокоскоростные вычисления, большие данные,робототехника. Соискатель должен не просто знать какзаписываются операторы, а иметь несколько видовмышления, алгоритмическое и объектно-ориентированное, знать технологию программирования,иметь теоретическую подготовку в предметной области,быть активным участником сообщества разработчиков изнать, как устроены технологии, эксплуатируемые натекущий момент в разных компаниях.

Только после овладения рядом навыков происходитпрорыв возможностей разработчика, у него появляетсявозможность создавать краткие, эффективные решения.Этот потенциал приводит к синергетическому эффекту,являющемуся симбиозом техники и культуры, синергииСи.

Page 14: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

14

В качестве информации для разработкипрофессиональные программисты используюттехнологические стандарты или документацию,поставляемую компанией разработчиком. Все остальныеисточники считаются уделом начинающих. Фактически,полностью читать все стандарты на все используемыетехнологии не приходится. Обычно достаточноограничиться рядом разделов, описывающихнеобходимые функциональные возможности.

Сами стандарты обычно тяжело читаются иописывают то, как написать ту или иную конструкцию, ноучиться программированию по ним чрезвычайно сложно.В стандарте часто используются упреждающие ссылкина материал, который будет изложен позже, материалможет излагаться по частям, в соответствии с разделом.Текущей версией стандарта языка программирования Сиявляется версия от 2018 года. Документ, являющийсястандартом языка Си, стоит дорого, однако бесплатнодоступен черновик предыдущей версии стандарта сномером документа ISO/IEC9899:2017. Он содержитнеточности, которые не мешают использовать его дляработы. Для его поиска необходимо произнести номердокумента любому программному ассистенту в своеммобильном устройстве.

Стандарт языка программирования появился какразвитие книги Брайна Кернигана и Дениса Ритчи «Языкпрограммирования Си», называемой в средеразработчиков K&R. Сама книга раскрывает красотуязыка и его парадигму, однако не уделяет вниманиясовременным технологиям создания программ. Их тогдапросто не существовало.

Современные учебники по программированию наязыке Си, используемые в учебных заведениях, большесосредоточены на развитие компетенций, требуемых в

Page 15: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

15

соответствии с учебным планом. Они эффективнообучают решать задачи в рамках курса и редко выходятза его рамки.

Не стоит игнорировать еще один эффективныйисточник знаний по программированию — форумы ипрочие способы общения в сети Интернет. Единственныйсовет — при использовании Интернета соблюдатьправила общения, характерные для конкретной группы.Очень рекомендуется не использовать сленг. Он оченьбыстро меняется и следует моде. Наиболееквалифицированные ответы пишутся грамотным языкомносителя, например, на русском или английском. Крометого, в сети отвечают тем, кто описывает конкретнуюпроблему. Например, на вопрос «я хочу и не понимаюкак, напсать программу для работы с папками», ответаскорее всего не последует. Появятся только отписки ипросьбы уточнить. Правильно заданный вопрос должензвучать примерно так: «функции из каких заголовочныхфайлов используются для отображения спискакаталогов». Таким образом производится уточнениезадачи, а также демонстрируется, что работа уже начатаи ведется, требуется немного подсказать, чтобыпрограмма была дописана. Для разработчика на языкепрограммирования Си двумя основными интернетресурсами являются cplusplus.com и stackoverflow.com.

Если Вам интересно программирование и Выдочитали до этой страницы, представим задачи, которыеставились перед этой книгой. Она должна:

1. Заставить обратить внимание на стандарт языкапрограммирования, получить сведения об его структуреи научить работать с ним.

2. Научить читать исходный текст программы в слух,а также вспомнить о том, что программы можно писатьбез компилятора. Такой подход единственно возможный,

Page 16: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

16

когда сборка проекта занимает около суток.3. Сразу учиться программировать правильно.

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

4. Обратить внимание начинающих программистовна умение писать код программ на бумаге безкомпьютера, что значительно снижает количествологических ошибок в программе, но повышаетколичество синтаксических ошибок, от которыхизбавляются, используя компилятор.

Для работы с этой книгой желательно иметь подрукой черновик стандарта языка программирования 2017года и K&R. «Синергия Си» несет некоторуюнелогичность повествования. Описание переменныхпроизведено в одном разделе, способ их задания вразных системах счисления в другом, указатели дляработы с ними в третьем. Также встречается ихповторное описание в случае необходимости.

Другие нарушения, умышленно допущенные в книге«Синергия Си»:

- автор не придерживается одного стиляпрограммирования, чтобы читатель не привыкал;

- один и тот же алгоритм может быть реализован поразному в разных примерах;

- наличие повторяющихся объяснений одинаковыхучастков исходного текста, которые позволяют читатьпримеры без перечитывания предыдущих глав;

- в нескольких случаях дается не только текстпрограммы, но и пояснения, как его улучшить.

- избыточно подробные объяснения для простыхвыражений текста программы.

- не рассматриваются технологии совместнойразработки, за исключением git.

Page 17: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

17

Избыточное описание связано с тем, что неизвестно,в каком месте у программиста может возникнуттрудность. Кроме того, к книгам иногда обращаютсяпосле появления ошибок, не поддающихся быстройотладке. В этом случае чтение подробного описанияпомогает посмотреть на проблему с другой стороны,сдвинуться с места и решить проблему.

Первые две главы содержат информацию, котораямгновенно всплывает в памяти у автора книги, когда онначинает программировать. Если читатель не являетсястудентом специализированного высшего учебногозаведения, обычно эти темы остаются не изучены.

Книга адресована в первую очередь тем, кто хочетначать изучение языка программирования Си. Крометого, она будет полезна тем, кто хочет сменитьиспользуемую при разработке программ операционнуюсистему на Линукс.

Желательно иметь опыт работы с компьютером нениже продвинутого пользователя. Однако если этогоуровня нет, не стоит отчаиваться. Разве это может статьпреградой для достижения Вами Вашей цели?

Кстати, результаты тестирования проведенного вначале введения:

а) начинающий;б) программист;в) хороший программист;г) эксперт.В конце еще один шуточный тест. Как определить

стаж программиста:- 1-5 года – пишет как получится, недооценивает

сроки разработки, легко заводит разработку в тупик;- 5-10 лет – делает все правильно, … в теории;- 10-15 лет – не смешивает этапы проектирования и

разработки, отталкивается от задачи и ресурсов, сроки

Page 18: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

18

разработки близки к реальным;- 15+ - решает вашу проблему.Вы без всяких тестов можете понять, что стали

хорошим программистом, когда Вам станет понятно, чтоэта книга про людей, которые живут технологиями,тратят свое время на их развитие.

Нужна ли именно эта книга? Посмотрите главу 8.Если все, что там написано, Вам известно, эта книга Вамскорее всего не пригодится.

Page 19: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

19

1. Базовые понятия и навыки1.1. Информация и данные

Первой задачей, подтолкнувшей развитиевычислительных машин, была задача управления соскоростями реакции значительно выше доступной длячеловека. Известно, что комфортной пофизиологическим соображениям, скорость реакцииравна примерно 0,2 секунды. Это целых 200 млс.Минимальная, в смысле наилучшая, скорость реакцииможет ровняться 30 млс и даже быстрее, но работая стакой скоростью, высока вероятность ошибки, и чемдольше длится работа в таком режиме, тем большеошибок совершает человек.

Во времена зарождения ракетной техники, которая,как и любая другая технология, сначала служилаисключительно военным целям, не существовало точныхкарт в континентальном масштабе. Расчет размераматерика по картам того времени приводит к появлениюошибки в десятки километров. Корректировка ошибкитребовала оперативного управление ракетой впромежутки времени, на порядки меньшие доступныхреакции человека.

Исследуя проблемы управления, ученые пришли квыводу, что они едины для всех сущностей нашего мира,включая искусственные, биологические и социальныесистемы. Первым заметным трудом в этой области сталакнига Норберта Винера «Кибернетика или управление исвязь в животном и машине», выпущенная в 1948 году.Суть управления можно описать как использованиемалой силы для управления большой силой. Насегодняшний момент известно всего четыре видауправления, которые изучает наука «Теорияуправления».

Page 20: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

20

В основе управления лежит базовая сущность нашегомира – информация. Информация не определяемоепонятие, также как понятие «точка» в математике. Вотличие от вещества и энергии мы не можемвоспринимать информацию органами чувствнепосредственно. Единственным органом,взаимодействующим с ней, является мозг человека.Опираясь на это базовое понятие, мы можем строитьпроизводные понятия, используемые в нашейдеятельности.

Все, что мы воспринимаем в окружающем мире, мывоспринимаем через отличие одной сущности от другой.Например, когда мы говорим «ключ от двери», мыобозначаем только применение предмета относительнодверного замка, но не раскрываем сути этого предмета.Любое другое обозначение ключа от двери также будетотносительным, относительно другой сущности илидействия. Например, ключ металлический, т.е.подразумевает наличие предметов из других материалов,но не говорит о сути дверного ключа. Отличия любойсущности от другой называются свойствами. Основнымотличием информации от других базовых сущностейэтого мира является её неистощимость и подразумеваетдругие методы получения, создания и преобразования.При этом информация является ресурсом, которыйотносится к любой сущности нашего мира. Наиболеекорректно описывать свойства информации черездействия, производимые с информацией. Наиболее частовстречающимися из них являются:

Запоминаемость – возможность хранитьинформацию, используя как среду, так и процессы этойсреды. Похожий процесс существует у материи иэнергии. Например, можно положить в карман ключиили сохранить энергию в энергоемком материал батареи.

Page 21: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

21

Передаваемость – возможность передачиинформации через каналы связи, в том числе спомехами. При этом информация может быть сохраненакак в источнике, так и в получателе, а пространственныеотношения между частями системы, передающимимежду собой информацию, не являются существеннымограничением. Это свойство было подробно изученоКлодом Шенноном, результат работы закреплен в видетеорем. Сравнивая с материей и энергией, приведемпример водопровода и передачи энергии в электрическойсети. Однако это сравнение не совсем корректно, так какпередача материи и энергии зависимо отпространственной распределенности.

Воспроизводимость информации подразумеваетвозможность создавать копии информации, не изменяяеё источник. Получается, информация являетсянеиссякаемым источником и остается равной самой себепри любом количестве копирований. Аналогов свойствавоспроизводимости информации для материи и энергиине существует.

Преобразуемость – информация может изменятьформу своего существования, однако есть ограничение,связанное с тем, что при преобразовании информациименяется её форма представления, но возрастать она неможет. Для материи примером этого свойства служитрастворение кристаллов в воде и восстановление их впроцессе выпаривания. Энергия можетпреобразовываться, например, из механической втепловую или электрическую и обратно.

В процессе преобразования информация можетуменьшаться и частным случаем преобразованияявляется стираемость информации. В этом случае еёколичество уменьшается и становится равным 0. Насегодняшнем этапе развития человечеству известен

Page 22: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

22

способ преобразования энергии в материю и обратночерез ядерные реакции, однако в естественной среде онинам недоступны.

Таким образом, информация обладает свойствами,аналогичными свойствам энергии и материи,совпадающими с ними с ограничениями и отличными отних.

Информация окружает нас всегда и везде. Насегодняшний день мы научились использовать тольконаиболее важную часть информации, котораязаписывается и обрабатывается. Информация, полезнаядля решения наших задач, называется данными.

Данные – это зарегистрированные сигналы, которыеявляются представлением информации в заранееопределенном, в смысловом понимании, виде ипригодном для дальнейшего использования. Данныеупаковываются в сообщения.

Сообщение - это заранее определенная форма ипредставление передаваемой информации. Например,текст на бумаге имеет определенную форму в видебумаги и представление в виде букв.

Сообщение подразумевает наличие «источника»,«получателя» и «канала связи». Смысловые значения«источника» и «получателя» не требуют расшифровки,под «каналом связи» понимается любая среда, спомощью которой сообщение передается от источникаполучателю.

Основными составляющими «канала связи»являются: «носитель информации», «сигнал» и«параметр сигнала».

Под «носителем информации» подразумеваетсянекоторая материя.

«Сигнал» - это сообщение, но не в общем виде, апередаваемое с помощью носителя информации. Обычно

Page 23: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

23

под сигналом подразумевают изменяющийся во временифизический процесс. Например, изменение напряженияв течение секунды.

«Параметр сигнала» - это характеристика,используемая для предоставления сообщения. Например,изменения напряжения от 0,2 до 1,4 В.

Распространенным заблуждением, связанным снеточным переводом иностранной литературы, сталоиспользование понятия «форма представленияинформации», применительно к понятиям текстовая,графическая, мультимедийная информация. Обычно вэтом случае подразумевают формат представленияфайла, например, mp3 для звукового файла или txt длятекстового файла.

На вопрос формы представления информацииубедительного ответа пока нет, но в соответствии стеорией информации существует всего две формыпредставления сигналов информации: дискретная ианалоговая (непрерывная). Большинство окружающихнас бытовых вычислительных устройств обрабатываютинформацию в дискретном виде. Наиболее часто этодвоичная информация, но она является частнымслучаем дискретной информации.

Дискретным сигнал считается в том случае, если егопараметр принимает последовательное во времениконечное число значений. Сообщения, передаваемые спомощью дискретного сигнала, называютсядискретными, а информация – дискретной информацией.

Если источник вырабатывает непрерывноесообщение с заранее неизвестным количествомсостояний, то это соответственно непрерывноесообщение, а информация – непрерывная информация.Рассмотрим пример: человек с помощью речи передаетинформацию другому человеку. Речь является

Page 24: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

24

моделированной звуковой волной, в которой параметромсигнала является давление, создаваемое в ухе человека.Такие абстрактные примеры очень важны, так каксовременный уровень информационных технологий давношагнул за рамки компьютерных вычислений и позволяетвзаимодействовать с окружающей средой.

В окружающем нас мире мы чаще встречаемся снепрерывной информацией, однако компьютеры обычнообрабатывают дискретную информацию. В связи с этимвостребовано преобразование сигналов от аналоговой вдискретную форму и обратно. Процесс преобразованияинформации из аналоговой формы в дискретнуюназывается дискретизацией. Следует учесть, чтообычно дискретизация выполняется с потерей частиинформации.

Сообщение «на улице пошел дождь» содержитразное количество информации для человека,собирающегося на улицу, и человека, пришедшего домойи не планирующего выходить из дома. В связи с этимвозникает вопрос о количестве информации всообщениях и возможности количественного измеренияинформации.

Существует два подхода к измерению количестваинформации. Первый, называемый вероятностным,разработан Клодом Шенноном. Он состоит в измеренииколичества информации относительно её отклонения отполной энтропии. Под энтропией, в этом случае,понимается неопределенность. Переформулируем. Объеминформации — это степень отклонения от состоянияполного хаоса. На формирование данного подходаосновное влияние оказали теории физических процессов,в первую очередь законы термодинамики.Вероятностный подход используется чаще при созданииинформационных систем, взаимодействующих с

Page 25: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

25

аналоговой информацией, иногда для выполненияпреобразования информации со смысловымсодержанием, например, поиске зависимости в большомобъеме данных. Основным ограничением вероятностногоподхода является игнорирование смысла и ценностисообщений. Исходя из ограничений вероятностногоподхода, для его использования со смысловойинформацией требуется применение дополнительныхупрощений в расчетах в каждом конкретном случае.

С математической точки зрения вероятностныйподход описывается формулой Хартли и формулойШеннона. Формула Хартли описывает объеминформации для дискретных сообщений с известнымоснованием алфавита, когда события происходятравновероятностно. Формула Шенона позволяетвычислять объем информации для событий с разнойстепенью вероятности.

Из формулы Хартли следует, что один бит — эторезультат события с двумя исходами, например,результатом может быть только да или нет, причем и даи нет выпадают одинаковое количество раз.

Второй подход называется объемным, используетпонятие бит и обусловлен необходимостью экономиифизических ресурсов. С ним мы встречаемся каждыйдень, например, когда оцениваем размер видеозаписи изапрашиваем размер доступной памяти своих устройств.Во всех устройствах размер памяти указывается в смыслеобъемного подхода и подразумевает, что в каждойячейке памяти может оказаться значение 0 или 1 содинаковой вероятностью. На сегодняшний деньразвитие технологий позволяет записывать в одну ячейкупамяти более 1 бита, однако это не изменяет смыслаобъемного подхода. Если ячейка позволяет записыватьболее 1 бита, она воспринимается как некоторое

Page 26: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

26

устройство, осуществляющее групповую запись и чтениебит. Однако производители вычислительных устройствотдают предпочтение двоичным устройствам по причинеих простоты и дешевизны производства.

Как следует из описания подходов к измерениюинформации, ограничивающим является объемныйподход. Нельзя записать больше информации, чем можетхранить физическая среда. Однако, следуявероятностному подходу, не вся информация, записаннаяв память вычислительного устройства, полезна.

Вычислительные устройства обрабатывают данные вцифровом виде и умеют выполнять только логические иматематические операции. Начинают появлятьсяустройства, производящие матричные и параллельныевычисления (нейропроцессоры, оптоэлектроника ипрочие), однако их базовые функции остаются прежними.

Принятый способ записи чисел и сопоставление имреальных значений называется системой счисления,которые делятся на позиционные и непозиционные.Пример позиционной системы счисления — арабскиецифры, непозиционной — римские. Как известно,значение числа в римской системе записи цифр невлияет на её значение, в арабской влияет. В зависимостиот позиции цифра может означать количество единиц,десятков и т.д.

Число знаков в позиционной системе счисленияназывается основание системы счисления. Ввычислительной технике наиболее часто встречаютсяследующие системы счисления: двоичная, восьмеричная,десятеричная, шестнадцатеричная.

Преобразование числа из одной системы счисления вдругую выполняется по соответствующим формулам илис помощью специальных приемов, подробно описанных всоответствующих источниках.

Page 27: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

27

Изложенной выше информации достаточно дляпояснения основ кодирования информации ввычислительных машинах.

Сообщения передаются с помощью букв, которыеявляются элементом некоторого конечного множестваотличных друг от друга знаков. Множество знаков сопределенным порядком называются алфавитом.

Page 28: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

28

1.2. Кодирование информации

Впервые человечеству кодирование информациипотребовалось при разработке систем передачиинформации. Проблемы, возникающие при передачеинформации, известны со времен, когда для сообщения онападении использовались сигнальные костры. Хворост идрова могли намокнуть, костер мог быть разведендругими людьми, заставу, ответственную за разведениекостра, могли разгромить. Все эти факты условно можносчитать помехами, возникающими в каналах связи.

Одним из пионеров, исследовавших проблемупередачи информации в каналах связи с научной точкизрения, был Клод Шеннон, который описал основныепроблемы, возникающие при передаче информации, исформулировал теоремы, позволяющие их решить. Косновным проблемам передачи информации, искажаемойпомехами, относятся: установления факта искаженияинформации, выяснение места искажения информации,исправление ошибки с некоторой долей достоверности.

В естественном языке, для защиты от помех, людииспользуют избыточность передаваемой информации.Избыточность является основным средством борьбы спомехами и присутствует в подавляющем большинстветехнических систем. Наиболее простым примеромизбыточности является многократная передача одной итой же информации, до тех пор, пока она не будетпринята приемником информации без искажения. Стехнической точки зрения, избыточность приводит кперерасходу ресурсов, в первую очередь, временизатрачиваемого на передачу информации и объемахранимой и передаваемой информации.

В дальнейшем будет показано построениеоптимальных информационных систем, не содержащих

Page 29: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

29

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

Вывод оптимального объема избыточностиосновывается на двух теоремах Шенона, упрощенносмысл которых сводится к следующему:

- Первая теорема дает математический аппарат дляоценки минимально допустимого количества двоичныхсимволов, представляющих другой алфавит. Например,если алфавит содержит 5 символов, то будетиспользоваться минимум 4 двоичных символа,позволяющих кодировать 8 символов. Соответственно 8-5=3, 3 символа двоичной кодировки никогда не будутиспользоваться.

- Вторая теорема декларирует возможность всегданайти такую систему, которая при наличии помехпередаст информацию с заданной степеньюдостоверности. Также она накладывает следующиеограничения: производительность канала всегда должнабыть выше производительности источника сообщений,так как кроме информации необходимо передаватьизбыточные данные.

Считается, что в канале связи сообщение можетпреобразоваться из символов одного алфавита в символыдругого алфавита. Кодом называется правило такогопреобразования, изменяющее вид сообщения. Набытовом уровне понятие кода часто путается с понятиемшифрование, которое относится в другой области знанияи связана с сокрытием информации, а не изменением еговида. Применение кода к некоторому сообщениюназывается кодированием. Обычно под кодированием

Page 30: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

30

подразумевают преобразование информации междуисточником информации и каналом с помехами, адекодированием — преобразование между каналом спомехами и приемником информации. В свою очередь,кодировщик и декодировщик — это устройства,выполняющие кодирование и декодирование.

Наиболее часто встречающаяся задача, связанная скодированием, это преобразование текста в различныхформатах. Сегодня популярны кодировки ASCII – дляаппаратного обеспечения и UTF-8 в сети Интернет. Длярусского алфавита в ASCII выделяют кодировкирасширенной части таблицы KOI8-R, WIN-1251.Общепринятые таблицы символов описаны всоответствующих стандартах, для UTF-8 это RFC 3629 иISO/IEC 10646, для KOI8-R это RFC 1489. Такжесуществует ряд ГОСТ (государственных отраслевыхстандартов), описывающих различные кодировки.

При изучении любой технологии особое вниманиеследует уделить поиску технологических стандартов наизучаемую технологию, таких как ГОСТ, RFC, ISO. Вмире высококвалифицированных программистов иинженеров знание о существовании стандартовсчитается обязательным. Обычно так проверяетсяквалификация собеседника. Если вопрос звучит какпросьба о помощи в поиске стандарта на конкретнуютехнологию или уточнение по какому-либо пункту этогостандарта, практически всегда общение будет строитьсяв позитивном, конструктивном ключе. Такой подходзамечен как на конференциях и выставках, так и нафорумах в сети интернет.

Для представления информации в вычислительныхмашинах используется двоичное представление, так какего проще реализовать с технической точки зрения. Насегодняшний день на логическом уровне принято

Page 31: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

31

считать, что минимальным участком памяти, к которомувозможен доступ, имеет длину 8 бит. Такой участокпамяти обычно называется ячейкой памяти. Нааппаратном уровне размер минимального участкапамяти, к которому можно обратится, обычно равенразрядности платформы. Сейчас популярные платформыимеют разрядность 8, 16, 32, 64, 128 и 256 бит. Реальнуюфизическую разрядность называют машинным словом,именно столько информации передается ввычислительном устройстве за один такт. Дляперсональных компьютеров основная разрядность 64бита. Каждый байт памяти имеет свой номер, которыйназывается адресом.

Для разных операций числа записываются в разныхвидах. Например, существует два вида записи чисел взависимости от направления расположения ячеек сразрядами, несущими большее значение: Big ending иLittle ending. В первом случае сначала производитсячтение байт с меньшими разрядами, во втором сначалачитаются большие разряды. В платформах x86, x86-64корпорации Intel(TM) используется Little endingархитектура. Для записи отрицательных значенийиспользуется крайний левый бит, являющийся флагомотрицательного числа.

Для выполнения сложения удобно использоватьпрямой код, т.е. обычную запись числа. Вычитаниеможно также выполнить как сложение, но для этогонеобходимо инвертировать каждый бит одного из чисел,что будет равносильно умножению числа на -1,выполнить сдвиг на недостающее количество бит ивыставить флаг отрицательного числа. Такоеинвертированное число называют дополнительнымкодом.

Некоторые операции удобнее выполнять в

Page 32: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

32

упакованном десятичном формате. В этом случаенеобходимо каждое десятичное число представить спомощью 4 бит. Таким образом, в один байт помещаетсядва десятичных числа вместо 256 значений, чтоувеличивает объем памяти требуемой для хранениязначения, но увеличивает скорость выполнениявычислений и позволяет обойти ограничения намаксимальное целое значение, ограниченноеразрядностью архитектуры.

Действительные числа представляются какзначения с плавающей точкой. Для этогоиспользуется стандартный вид Mx10P, где M — этомантисса числа, а P – его степень (порядок). Ввычислительной машине мантисса хранится внормализованном виде в диапазоне значений0.0<мантисса<2.0.

В памяти вычислительной машины значение сплавающей запятой хранится в виде двух значений, азначит вычисления с такими данными происходятмедленнее. В одном значении хранится знак и значениемантиссы, в другом знак и значение степени. Причемзначение степени хранится как смещенное число,ставящее в соответствие минимальному значению 0, чтопозволяет упрощать операции сравнения двух чисел ивычисления с ними.

Page 33: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

33

1.3. Процессы

Компьютеры реализуют две основные сущности:данные и их преобразования, выполняемые процессами.Такой подход стал возможен после того, как в серединеXX-го века было предложено хранить данные ипрограмму в одной быстродействующей памяти. Врезультате программы получили возможностьсамостоятельно изменять себя в процессе обработкиданных.

Базовые операции преобразования данных — этологические и математические преобразования.Логические операции являются частью теорииматематической логики, основоположником которой сталнемецкий математик Готфрид Вильгельм Лейбниц. Онпытался построить универсальный язык, с помощьюкоторого можно решать споры между людьми путемвычислений. На фундаменте, заложенным Лейбницем,ирландский математик Джордж Буль построил системувычислений, оперирующих не числами, авысказываниями. Под высказыванием понимается любоеутверждение, которое может быть или истинно(соответствует действительности) и равное 1, или ложно(не соответствует действительности) и равное 0. Истиначасто выбирается равное 1, т. к. это соответствует«возмущению» системы, повышенному напряжению вканале и т. д., что удобнее при технической реализации.Например, если система работает, более естественнобудет восприниматься повышение напряжения в каналесвязи, а когда система вышла из строя, напряжениескорее всего будет отсутствовать.

Существует всего три основных логическихоперации, с помощью которых можно реализовать любоелогическое преобразование: НЕ, И, ИЛИ. Операция НЕ

Page 34: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

34

(отрицание, дополнение, инверсия) называется унарной,т.к. принимает всего один аргумент и инвертируетзначение, т.е. да изменяется на нет. Операция И(конъюнкция, логическое умножение) называетсябинарной, т.к. принимает два аргумента и возвращает 1только в том случае, если оба входных значений равны 1.Операция ИЛИ (дизъюнкция, логическое сложение)также называется бинарной, т.к. принимает двааргумента и возвращает 1 в случае, если хотя бы одинаргумент равен 1. Для логических функций независимоот их сложности возможно построение таблицистинности.

В аппаратном обеспечении по технологическимпричинам часто используются дополнительные функции:исключающее ИЛИ (штрих Шеффера) и элемент И-НЕ(стрелка Пирса). Каждый из этих двух элементовпозволяет реализовать все базовые логические функции,а значит для реализации вычислений фактическидостаточно использовать один из этих элементов, что иприводит к экономии.

Вторая важная составляющая вычислительныхустройств – возможность выполнять арифметическиевычисления и прочие математические преобразования.Первыми математическими преобразованиями сталиарифметические операции сложения, вычитания,умножения и деления, выполняемые с арабскимицифрами в позиционной системе счисления. Они былиразработаны арабским ученым Мухаммедом аль-Хорезми,имя которого в последствии стало нарицательным и далоимя понятию алгоритма. Преимуществом этих операцийбыла возможность производить операции надмногозначными числами «в уме», что быстрее, чем прииспользовании популярных тогда табличек длявычислений, применяемых египтянами. Это стало

Page 35: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

35

конкурентным преимуществом в торговых делах, чтоможно наблюдать и сейчас на любом восточном базаре,когда продавец пытается непрерывно делать все более«выгодные» предложения, не давая потенциальномупокупателю просчитать свою реальную выгоду.

Важность математической составляющейпрограммного обеспечения подтверждается тем, чтосреди специалистов наивысшего уровня принятоназывать программы математическим обеспечением. Увсех разделов математики есть один общий секрет, онисложны для понимания, но если человек в нихразобрался один раз, он сможет его понимать ииспользовать всю свою жизнь. В связи с этим нельзяигнорировать математическую составляющуюпрограммирования, при слабых знаниях базовыхразделов математики нужно набраться терпения иразобраться с плохо усвоенными темами раз и навсегда.

Кроме известных всем со школьной скамьиалгоритмов выполнения арифметических операций, приразработке программ приходится на постоянной основеразрабатывать собственные алгоритмы. Алгоритмыизучаются «Теорией алгоритмов» и являются одним изфундаментальных понятий науки «Информатики».

Главным элементом понятия алгоритм являетсяпонятие «исполнитель алгоритма». Это абстрактноепонятие, которое может быть физическим объектом,процессом или командой языка программирования.Главным свойством для него является наличие«системы команд исполнителя», т.е. полного наборадействий, которые исполнитель алгоритма умеетвыполнять. Исполнитель алгоритма не должензадумываться при исполнении алгоритма, должен строгоисполнять его инструкции и получить результат,предусмотренный алгоритмом. Требование к

Page 36: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

36

«формальному» выполнению алгоритма переноситпроцесс размышления о возможной последовательностидействий с исполнителя на разработчика алгоритма.Таким образом, алгоритм является формализованнымрешением задачи.

Рассмотрим свойства алгоритмов.1. Алгоритм должен разбивать процесс выполнения

некоторого действия на последовательность отдельныхшагов. Это свойство алгоритма называетсядискретностью.

2. Алгоритм должен быть ориентирован наконкретного исполнителя алгоритма, которомусоответствует определенная система командисполнителя, поэтому при записи алгоритма допустимоиспользовать только команды системы командисполнителя. Это свойство называется понятностью.

3. Алгоритм не должен содержать команд,воспринимаемых неоднозначно. Каждая команда приисполнении в разное время разными исполнителямидолжна давать одинаковый результат. Это свойствоалгоритма называется определенностью.

4. При исполнении алгоритм должен прекратиться законечное число шагов и должно быть полученоконкретное решение. Вывод о том, что решения несуществует, тоже результат. Это свойство называетсярезультативностью.

5. Алгоритмы должны обеспечивать решение не одной задачи, а целого класса задач. Это свойство называется массовостью.

6. Алгоритмы обладают эффективностью. Этосвойство описано в пункте 7.3 данной книги.

При разработке алгоритма необходимо прилагатьусилия к выполнению свойств 1-4. Если класс задачопределить как различные наборы входных значений, то

Page 37: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

37

свойству массовости все алгоритмы будут удовлетворятьавтоматически.

Алгоритмы могут быть представлены в текстовом,формульном, табличном, графическом виде или на языкепрограммирования. Интересной особенностью являетсяфакт отказа признания алгоритмов в текстовом виде впроцессе обучения. Это делается для повышениямотивации учащихся в изучении графическогопредставления алгоритмов. В практической деятельноститекстовое описание алгоритмов, один из способовнаписания исходных текстов программ и является однимиз двух самых часто используемых наравне сграфическим представлением.

Наиболее популярный способ графическогопредставления алгоритмов называется блок-схемой иописан в ГОСТ 19.701-90. Блок-схема – этоориентированный граф, в котором используютсяспециализированные вершины графа для обозначениядействий алгоритма и определяется порядок ихисполнения. В соответствии с теорией графов всевершины обозначаются точкой, в блок-схемах типнаиболее часто используемых действий обозначаетсяразличными геометрическими фигурами. Другимотличием блок-схем от графов является ограниченноеколичество способов отображения ребер графа, которыев блок-схеме называются управляющими линиями. Такдостигаются такие преимущества как наглядность иявное отображение управления. Непосредственноспособы отображения блок-схем лучше всего изучать посоответствующему регламентирующему документу ГОСТ19.701-90. Часто, при подготовке документов длявнутреннего использования среди ограниченного кругалиц, используются упрощения при рисовании блок-схем.Могут не соблюдаться размеры или пропорции блоков,

Page 38: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

38

вводятся собственные блоки, некорректноотрисовываются управляющие линии. В таком случаеуказывается, что блок-схема выполнена в общем виде.

Подведем итог, перечислив все возможныепреобразования, выполняемые процессами:

- логические преобразования;- математические преобразования.На их основе производится построение алгоритмов,

выполняющих все преобразования данных ввычислительной технике.

Современные микропроцессоры, т.е. микросхемы,производящие вычисления в вычислительной технике,ассоциируют понятие процесса с каждойпользовательской или системной программой.Программа является процессом. Понятия «программа» и«процесс» могут использоваться как синонимы, однакопод процессом чаще понимают набор данных иинструкций для микропроцессора в период исполненияна микропроцессоре. Под программой понимаетсянабор данных и инструкций для создания и исполнения впроцессе. При этом процесс может находится вследующих состояниях:

- Создание, подготовка необходимых устройств иресурсов для управления процессом и его запуска вмикросхеме.

- Исполнение, выполнение команд в микросхеме.- Ожидание, отсутствие одного из ресурсов, кроме

микропроцессорного времени. Например, данных изфайла.

- Готовность, все ресурсы подготовлены, но невыделено микропроцессорное время.

- Завершение, освобождение всех ресурсоввычислительной машины и, соответственно,прекращение существования процесса.

Page 39: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

39

Взаимодействие этих состояний процесса приведенов [6].

Реализация различных состояний процесса возможнатолько в рамках концепции прерываний. Онаподразумевает возможность приостановки исполненияпроцесса для переключения на более приоритетный иописывает процедуру такого переключения. Причинамипрерываний могут быть:

- одно из устройств выполнило действие, требующееобработки на микропроцессоре;

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

- активным процессом выполнена операция, неимеющая смысла, например, деление на ноль; операцияперевела микропроцессор в состояние, негарантирующее правильность выполняемых вычислений,например, арифметическое переполнение;

- возникла необходимость синхронизации междупроцессами, использующими одни данные. Обычно такие

Создание

Исполнение

Завершение

Ожидание

Готовность

Page 40: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

40

процессы называют параллельными.Опишем действия, выполняемые при прерывании:- получается запрос на прерывание;- запоминается состояние прерванного процесса;- передается управление прерывающей программе;- обрабатывается прерывание;- восстанавливается состояние прерванного

процесса.Псевдопараллельное исполнение процессов

реализуется приемом, называемым режимомразделения времени. Его суть заключается впараллельном исполнении нескольких процессов наодном аппаратном микропроцессоре. При запускекаждого процесса определяется степень его важности и,в соответствии с этим, определяется его приоритет. Приисполнении каждому процессу выделяется некотороевремя для его выполнения в соответствии с приоритетом.В связи с тем, что интервалы времени, на которыевыделяется микропроцессор, очень малы, намногоменьше времени, требуемого для вывода звука,изображения или воспроизведения управляющеговоздействия на исполнительный механизм техническойсистемы, например, электродвигатель, создаетсявпечатление одновременного исполнения несколькихпроцессов.

При параллельном выполнении процессыизолированы друг от друга, однако они могутосуществлять взаимодействия между собой. Набормежпроцессорных взаимодействий, доступных процессу,определяется операционной системой. Операционныесистемы будут рассмотрены в следующих разделах. Всегосуществует три основных задачи взаимодействиямежду процессами:

- передача данных;

Page 41: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

41

- совместное использование одной копии данных;- извещение другого процесса или нескольких

процессов о некотором событии.В соответствии со стандартом на операционных

систем POSIX, задачи взаимодействия между процессамиреализуются следующими средствами:

- сигналы;- каналы;- именованные каналы;- сообщения очереди сообщений;- семафоры;- сокеты;- разделяемая память.Внутри процессов существуют более мелкие единицы

выполнения – потоки. Они обмениваются информациейвнутри процесса без ограничений, но длявзаимодействия с другими процессами используютобычные механизмы взаимодействия между процессами.Одно из главных преимуществ потоков — этовозможность параллельного исполнения программы навычислительных машинах с несколькимимикропроцессами или на многоядерныхмикропроцессорах.

Page 42: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

42

1.4. Базовые алгоритмы для программиста на языке Си и способы их применения

В каждой области применения языковпрограммирования можно выделить ряд типовых задач, скоторыми приходится сталкиваться наиболее часто. Дляязыка Си, который часто используется для разработкиаппаратнозависимых или наиболеевычислительноэффективных проектов, к таким можноотнести задачи кодирования и шифрования. Если задачикодирования естественно связаны с разработкойдрайверов, преобразованием данных между различнымиаппаратными протоколами, то шифрование изначальносчиталось специфическим направлением разработки.

Как указано выше, под кодированием понимаетсяпреобразование данных, основанное на правиле, коде.Примером может служить преобразование текста изкодировки UTF-8 в любую другую кодировку. Такоепреобразование не должно менять объем передаваемойинформации, изменению подвергается только способ еёпредставления. Под шифрованием понимается именносокрытие информации в сообщении, канале связи, либодругим образом. Более подробно шифрование будетрассмотрено ниже.

Наиболее простым видом кодирования являетсяконтрольная цифра. Правило его применениязаключается в дописывании в конце числа цифры 1, еслисумма единиц в двоичном представлении числа нечетно,или 0, если сумма единиц четная. Например, в концечисла, представленного в двоичном виде 1000101,необходимо дописать 1, чтобы количество единиц стало4, т.е. четным. Получается 10001011. В числе 1001011необходимо дописать 0, т.к. число единиц уже четно.Получается 10010110. Алгоритм применения

Page 43: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

43

контрольной цифры — наиболее быстрый способпроверки ошибок в передаваемых данных. Контрольнаяцифра обычно применяется при разработке аппаратныхпротоколов обмена данными и служит для нахождениянечетного количества сбойных бит. Она позволяетопределить наличие сбоя в одном, трех, пяти и так далеебит.

Применение обобщения алгоритма контрольнойцифры к десятичным и другим числам называетсяконтрольной суммой.

Контрольная сумма — это значение, рассчитанное поопределенному правилу и используемое для проверкиправильности переданного числа. Правило примененияконтрольных сумм основывается на сравнении числа,полученного путем вычислений, проводимых спереданными значениями, включая число контрольнойсуммы и некоторой константы. В этом случаеконтрольная сумма дополняет результат вычислений доконстантного значения.

Приведем простейший пример контрольной суммы.Пусть сумма цифр числа должна всегда быть равна 100.Тогда контрольной суммой для числа 263567, будет равно100-(2+6+3+5+6+7)=71. Способ передачи контрольнойсуммы обычно сложнее передачи контрольного числа, азначит его применение возможно не во всех аппаратныхреализациях.

Контрольные суммы применяются в сетевыхпротоколах, файловых системах, архиваторах и т.д.Наиболее популярными являются CRC8, CRC16 (CRC –циклический избыточный код) и CRC32. Хотя CRC чащеотносят к алгоритмам хеширования. Контрольные суммымогут применяться независимо от самих данных.Основным требованием для контрольных сумм являетсяотличие между наиболее близкими значениями, т.е. чем

Page 44: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

44

меньше разница двух чисел, тем больше должныотличаться их контрольные суммы. Таким образом,контрольные суммы позволяют находить ошибки,состоящие из подряд идущих неверных значений.

Хеширование, хеш-функция, хеш-код, функциясвертки – это наиболее общее название преобразованийвходного массива данных произвольной длины ввыходную битовую строку фиксированной длины.Выходная строка обычно называется хешем.Хеширование применяется для сравнения массивовданных. Например, выполняется получение хеша файла.Через некоторое время хеширование повторяется иполученный хеш сравнивается с более ранним. Такимобразом можно узнать, изменилось ли содержимое файлаза прошедшее время. Примеры алгоритмов хеширования:MD5, MD6. В РФ принят алгоритм хеширования«Стрибог», закрепленный в ГОСТ Р 34.11-2012 (RFC6986).

Необходимо понимать очевидную вещь: хеш обычносодержит намного меньше цифр, чем исходный массив,поэтому одному хешу соответствует множество массивовтакой же длины. Такая ситуация называется коллизией.Причем чем длиннее массив, тем больше массивов такойже длины имеют такой же хеш. Однако не следуетзабывать, что чем длиннее массив, тем больше общееколичество таких массивов. В результате, приувеличении длины массива вероятность совпаденияхешей все равно остается примерно одинаковой.Правило, применимое для контрольных сумм, котороеговорит о максимальном различии хешей ближайшихмассивов данных, распространяется на все хеш-функции.

Хеширование применяется для проверкисоответствия некоторого сообщения другому сообщению.Одно из применений хеш-функций — поиск ошибок в

Page 45: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

45

передаваемых данных. Другим способом примененияявляется ускорение поиска данных. Хеш содержитфиксированное количество символов, например, в MD5это 32 символа. Посчитав хеш от 100 страниц текста,можно сравнить 100 страниц с другим текстом, такжепосчитав хеш от второго текста. Для двух текстовпреимущество в производительности будет неочевидно.Однако, если текстов десятки, достаточно будетсравнивать 32 символьные числа, что на порядки ускоритвремя поиска.

Наиболее сложные алгоритмы преобразованияданных изучаются наукой – криптография. Эта наукаведет свою историю несколько тысяч лет и изучаетматематические методы обеспеченияконфиденциальности и аутентичности информации. Подконфиденциальностью понимается невозможностьпрочтения информации посторонним, а подаутентичностью — целостность и подлинность авторства,невозможности отказа от авторства. Криптография незанимается изучением защиты от обрыва связи, влияниясоциальных угроз информации.

Базовыми понятиями в этой области являются:- открытый (исходный) текст;- шифрованный (закрытый) текст;- криптосистема (шифр);- ключ;- принцип Керкгоффса;- расшифрование;- дешифрование (“взлом”);- криптоанализ;- криптоаналитик;- криптографическая атака;- абонент криптографической системы;- взлом;

Page 46: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

46

- имитозащита;- имитовставка;- цифровая электронная подпись.С целью выработки навыка самостоятельного поиска

информации их объяснение приведено не будет.Значение этих терминов легко найти в сети Интернет.

За время существования криптографиипредпринимались попытки создания принципиально невскрываемых шифров, например, шифр Вернама,который заключается в двоичном сложении исходноготекста с однократно используемой случайнойпоследовательностью. Однако построение универсальнойсистемы, решающей все проблемы, связанные со скрытойпередачей информации, еще не увенчались успехом.

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

Тайнопись. Посторонним лицам неизвестеналгоритм шифрования и доступен только отправителю иполучателю. Данный способ противоречит принципуКеркгоффса и на сегодняшний день используется редко.

Симметрическое шифрование / шифрование сзакрытым ключом. Используется общеизвестныйалгоритм шифрования. Ключ, одинаковый дляшифрования и расшифрования, известен толькоотправителю и получателю. Ключ выбирается до началаобмена шифрованной информацией и сохраняется дозавершения обмена.

Ассиметрическое шифрование / шифрование соткрытым ключом. Используется общеизвестныйалгоритм шифрования, ключ для шифрования(открытый ключ) предоставляется в открытом доступе.Ключ для расшифрования (закрытый ключ) известентолько получателю. Сеанс обмена шифрованнойинформацией инициируется получателем путем

Page 47: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

47

генерации ключа шифрования, разбиения его наоткрытую и закрытую часть и опубликования своегооткрытого ключа. Зашифрованная с помощью открытогоключа информация может быть прочитана толькополучателем, т.к. только он обладает закрытым ключом.

Система шифрования может реализовываться толькопрограммными средствами или с помощью программно-аппаратного комплекса.

Комплекс средств вокруг способа симметричногошифрования может включать вспомогательные функциидля управления ключами, реализацию самого алгоритмашифрования, другие сервисные функции. К достоинствамсимметричного шифрования относится скоростьшифрования, простота реализации, меньшая длинаключей и изученность. Недостатки – сложность обменаключами между абонентами и сложность управленияключами при большом количестве абонентов. Данныйспособ шифрования невозможно использовать дляподтверждения авторства, т.к. ключ известен всемабонентам.

Преимущество ассиметрического шифрованиясостоит в отсутствии необходимости передачисекретного ключа. Недостатками является потребность взначительно больших вычислительных ресурсах, чем присимметрическом шифровании, а также необходимостиобеспечения отличия между источниками шифрованнойинформации, для чего часто используются сертификаты.Не менее серьезным недостатком являетсяневозможность скрыть источник и получателясообщения.

С одной стороны шифрование — это в первуюочередь сложная математика, с другой — технология,которой мы пользуемся каждый день в сети интернет.Приводить примеры математических преобразований для

Page 48: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

48

шифрования/расшифрования не имеет смысла безглубокой математической подготовки, поэтомусосредоточимся на технологиях, которые их используют.

Любая технология шифрования может статьуязвимой при её неправильном использовании. Каксказано выше, криптография не изучает проблемыпсихологических особенностей пользователей,применяющих криптографические технологии имежчеловеческие деструктивные отношения, такие какобман, предательство, шантаж. Чаще всего именно этифакторы приводят к снижению эффективностиприменения шифрования. Также существуюттехнологические факторы, понижающие эффективностьшифрования. Например, виртуальная файловая системашифрования информации encfs надежно шифруетданные, однако подвержена атаки наблюдения зафайловой системой. Другими словами, еслизлоумышленник имеет доступ к зашифрованным данным,он, наблюдая за изменениями в файлах, можетзначительно упростить взлом зашифрованнойинформации. Человеческий фактор чаще всего приводитк следующим факторам ухудшения надежностишифрования:

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

- неверная настройка системы шифрования. Выборалгоритмов шифрования, не соответствующих степениважности информации. Неумение правильно настроитьсистему шифрования. Недостаточная квалификациясотрудников.

- Недостаточная благонадежность сотрудников.Неумение хранить секреты, намеренное вредительство,

Page 49: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

49

предательство.Приведеное выше описание призвано подчеркнуть

важность и сложность поднятой проблемы, однако еёизучение требует высокой квалификации.

Администраторы компьютерных сетей иразработчики чаще всего используют технологию,содержащую шифрование под названием SSH(защищенная оболочка). Технология основана наодноименном сетевом протоколе SSH-2 (RFC 4251),позволяющем передавать файлы и управлятьоперационной системой вычислительной машины.Протокол шифрует весь передаваемый трафик, создаваябезопасный канал почти для любого другого сетевогопротокола. Позволяет передавать звуковые ивидеоданные в масштабе реального времени, выполнятьсжатие передаваемых данных для запуска «удаленныхрабочих столов».

В некоторых странах (Франция, Россия, Ирак иПакистан) до сих пор требуется специальное разрешениев соответствующих структурах для использованияопределенных методов шифрования, включая SSH.Однако, по-факту, в РФ это требование не выполняется.

Технология SSH построена по архитектуре клиент-сервер. Для подключения к другой вычислительноймашине необходимо установить программу-клиент SSH,соответственно, на вычислительной машине, к которойпроизводится подключение, должна быть установленапрограмма-сервер SSH. На одной и той жевычислительной машине могут быть одновременноустановлены и программа-клиент и программа-сервер.

Непосредственно после установки SSH-серверанеобходимо выполнить ряд действий для повышениянадежности зашифрованного канала, а если SSH-сервериспользуется в общедоступной сети, включая интернет,

Page 50: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

50

необходимо выполнить скрытие наличия SSH-сервера уэтого компьютера.

Основные алгоритмы шифрования, о которыхнеобходимо знать, являются DES, Triple DES, AES,ГОСТ 28147-89. В этом списке Triple DES и ГОСТ 28147-89 содержат в себе по несколько алгоритмовшифрования. DES считается устаревшим, однако на егопримере проще понять механизм шифрования.

Последним классом алгоритмов, о которых будетупомянуто в этом разделе — сжатие данных. В разноевремя популярность имели разные алгоритмы сжатия.Они обычно сложны для понимания и их разработкойзанимаются математики. Каждый из алгоритмов даетмаксимальное значение коэффициента сжатия данныхопределенных форматов, которые были популярны впериод создания алгоритма. Во времена наибольшейраспространенности файлов с текстом, чащеиспользовался алгоритм сжатия RAR (Архив Рошаля).Разработанный Филом Кацем алгоритм ZIP (RFC 1951)лучше сжимает данные графических файлов и наборыфайлов с разнотипным содержимым. Алгоритмбазируется на алгоритме Хаффмана и LZ77 и позволяетего свободно использовать, что стало причиной егопопулярности в сети интернет. Следующим алгоритмом,получившим широкое распространение в компьютерныхсетях, стал 7Z (архиватор 7-zip), основанный на LZMA.Его активно применяют как в сетевых устройствах, так идля сжатия мультимедийной информации.

Основной принцип сжатия называется механизмкодирования совпадений, заключается в поискеповторений и обозначение их более короткойпоследовательностью, которая не встречается в файле. Врезультате экономия равна разнице между размеромповторяющейся последовательности в файле и

Page 51: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

51

последовательности, используемой для её замены,умноженной на количество повторений. Таким образомлучше всего сжимаются файлы, состоящие измногократно повторяющихся длинныхпоследовательностей. Другое следствие из этого правилазаключается в том, что зашифрованные файлы несжимаются, т. к. практически не содержатповторяющихся последовательностей.

Другой базовый принцип для алгоритмов сжатия —принцип скользящего окна. Смысл этого принципазаключается в наличии некоторого окна (буфера), вкотором содержится информация из участков потокаданных, встреченных ранее, и благодаря этому возможноповышать степень сжатия.

Следует учитывать, что современные графические имультимедийные форматы уже содержат в себеалгоритмы сжатия данных, поэтому на текущий моментпользователи персональных вычислительных устройствстали намного реже использовать программы сжатияданных с помощью архиваторов. За них это делаютбольшинство популярных программ.

Page 52: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

52

1.5. Базовое программное обеспечение, операционные системы

Программное обеспечение является частью почтилюбого аппаратного устройства внутри вычислительногоустройства. Программное обеспечение этого классаимеет сленговое название — прошивка устройства. Онииспользуются в накопителях информации, сетевыхкартах, устройствах позиционирования (мышь,контроллер сенсорного экрана). Центральныймикропроцессор содержит в себе настолько сложноепрограммное обеспечение, что его уже относят к классуоперационных систем.

Управляет работой всех устройств программно-аппаратное обеспечение UEFI — интерфейсрасширяемой прошивки. Это класс программ, часть изкоторых содержат в себе специальные программыуправления устройствами – драйвера. Программноеобеспечение этого класса не поддается управлению иобслуживанию в домашних условиях, поэтому ошибка внем делает устройство неработоспособным.

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

Говоря о программном обеспечении этого уровня,необходимо вспомнить технологию Plug and Play. До еёпоявления устройства внутри вычислительной машинымогли сломаться из-за их неправильного подключения.Технология Plug and Play содержит три основныхкомпонента: операционную систему, поддерживающуюPlug and Play, Plug and Play BIOS/UEFI и Plug and Play -

Page 53: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

53

устройства с соответствующими драйверами. Поэтомуполное решение проблемы Plug and Play требуетподдержки как на программном, так и на аппаратномуровнях. Сегодня название этой технологии сталоименем нарицательным и используется, когда говорят оналичие в устройстве элементов самодиагностики,которые в совокупности с технологией подключенияспособны предотвратить поломку устройства принеправильном подключении.

Далее UEFI запускает программу начальнойзагрузки операционной системы (загрузчикоперационной системы), который способенпредоставлять выбор загружаемой ОС. Наиболеепопулярным является загрузчик ОС WindowsTM, которыйпригоден только для загрузки операционной системысемейства WindowsTM. Мультизагрузчик grub позволяетзагружать большое количество типов и версийоперационной системы.

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

Распределение полномочий между программами ипользователями позволяет решать следующие задачи:

- решать разные задачи на одной вычислительной

Page 54: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

54

машине;- позволять задачам сохранять результат или

обмениваться результатами своей работы с другимизадачами;

- разделять полномочия между программами,ресурсами и пользователями;

- имитировать режим разделения времени,реализовывать виртуализацию или другую технологию;

- предоставлять пользователю возможностьуправлять процессами и программами.

Под упомянутым ранее термином ресурсподразумевается обобщение, которое может быть иаппаратным устройством и функциональным блоком.Кроме того часто используется понятие виртуальныйресурс, являющийся моделью физического ресурса,реализуемой за счет другого физического ресурса.Например, образ оптического диска (CD, DVD, BlueRay)может быть файлом на носителе информации, но ОСбудет его отображать как физическое устройство. Болеепопулярным примером является виртуальнаяоперативная память, которая реализуется файлом наносителе информации, и позволяет частично записыватьинформацию оперативной памяти в файл. Таким образомобъем «дорогого ресурса» увеличивается за счет болеедешевого носителя информации.

Функции ОС описаны в стандарте POSIXISO/IEC/IEEE 9945:2009 (рекомендуется читать как«позикс»). В нем содержится определение около 1000системных вызовов и несколько сотен команд оболочки иутилит ОС, но отсутствуют способы их реализации.Кроме графических интерфейсов, ОС может включатьнабор средств разработки. Стандартизация ОС упрощаетвзаимозаменяемость разных ОС, упрощает переносприкладного программного обеспечения между

Page 55: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

55

различными ОС, включая полную совместимость науровне исходных кодов. Самым заметным результатомсуществования стандарта ОС стало эффективноеразворачивание Интернета в 90-х годах.

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

Считается, что создание языка Си и системы UNIX —две самые важные вехи в развитии компьютернойиндустрии. Си — первый мультиплатформенный язык, аUNIX, так как написана на нем, — перваямультиплатформенная ОС [7].

Язык Си развивался параллельно с операционнойсистемой Unix, поэтому язык Си исключительно ценен спрактической точки зрения. С одной стороны онсодержит в себе инструменты для работы со всемиэлементами ОС, с другой не привязан ни к одной ОС. Всевзаимодействия с ОС вынесены в подключаемые модули.В связи с этим для переноса исходного текста программыв другую ОС требуется только пересборка подключаемыхмодулей.

Важность ОС Unix в том, что в процессе её развитиябыли опробованы многие технологии жизненного циклапрограммного обеспечения, был заложен фундамент дляпервого стандарта для ОС POSIX, который до сих порявляется основным стандартом для всех разработчиковОС. Впоследствии Unix дала жизнь проекту, из которогопоявилось ядро ОС Линукс. С помощью краткогоисторического обзора предпримем попытку показатьвзаимосвязь развития операционных систем, языка Си иинформационных систем как единого процесса.

Первая версия ОС была задумана и реализованаКеном Томпсоном при участии Денниса Ричи и Брайана

Page 56: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

56

Кернигана в 1969 году. Отметим, что Деннис Ричи иБрайан Керниган — авторы языка Си.

Уже тогда ОС имела следующие черты:- простая метафорика, состоящая всего из двух

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

принцип «одна программа — одна функция», а такжесредство связывания разных программ, названноеоболочкой;

- использовался принцип минимизация ядра ОС иколичества системных вызовов;

- была независимой от аппаратной архитектуры;- имела файловую систему и унификацию форматов

записи и чтения файлов;- обеспечивалась возможность использования

системы двумя пользователями;- имела командный интерпретатор.В 1971 году был выпущен первый комплект

документации, после которого родилась традицияобъявлять о выходе новой версии после выхода новойверсии документации. Таким образом был нарушен одиниз основных принципов инженерной работы, требующейсначала разработки документации, а уже затем созданиесамого продукта.

В 1972 году в ОС появились программные каналы(pipes).

В 1973 году ОС была переписана на языке Си и ужеимела 25 установок.

В 1974 году была опубликована историческая статья"UNIX Timesharing Operating System" в журналеCommunications of the ACM. Эта статья и сейчас свободнодоступна в сети интернет. Значительная её часть досегодняшнего дня актуальна как концептуально, так и науровне реализации. Компания Bell Labs объявила о

Page 57: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

57

возможности бесплатного получения исходных текстовUnix для образовательных целей. Такой подход сталпрообразом для движения open source, основанного налицензии GNU.

В 1975 году Си уже имел легкопереносимыйкомпилятор, таким образом впервые была решенапроблема переносимости программ на уровне исходныхкодов.

В 1976 году была создана библиотека стандартноговвода/вывода (stdio), используемая до сих пор. В этом жегоду появился «дистрибутив» UNIX под названиемBerkeley Software Distribution (BSD), в котором впервыебыл реализован стек транспортных протоколов TCP/IP(Transport Control Protocol/Internet Protocol). Эта работафинансировалась министерством безопасности США.

В 1977 году происходила смена 16-ти разряднойархитектуры на 32-х разрядную. В связи с этим в язык Сибыли введены новые типы данных: union, short integer,long integer и unsigned integer.

В 1978 году была организована группа поддержки(UNIX Support Group — USG), которая по-сути являетсяпрообразом всех форм поддержки пользователей всехпрограмм и групп разработки стандартов в областиинформационных технологий. В этом году MicrosoftCorporation совместно с Santa Cruz Operation (SCO)произвели вариант UNIX под названием XENIX.

В 1983 году была выпущена версия UNIX, к которойпроизводитель обещал поддержку для всехпоследующих версий. Данный подход показал своюнежизнеспособность. Все новшества в этом году былисвязаны с активным внедрением хеш-таблиц, т.е. таблицдля быстрого доступа к данным и хешированием данных.Появились семафоры, очереди сообщений и разделяемаяпамять.

Page 58: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

58

В этом же году был выпущен один из первыхкомпьютеров с графическим пользовательскиминтерфейсом Lisa от компании Apple, который не сталпопулярным из-за высокой стоимости и плохойнадежности аппаратного обеспечения. Это событие сталоповодом для применения методов социальной инженериив конкуренции информационных систем. В средепользователей DOS TM компании MicrosoftTMраспространялись насмешливые прозвища графическогоинтерфейса пока велась работа над ликвидациейтехнологического отставания.

В 1984 году была выпущена версия названная UNIXSystem V Release 2. В нем появились новые механизмыработы с памятью, возможность блокировок файлов изаписей. На тот момент было выполнено более 100000установок ОС UNIX.

В 1987 году была выпущена версия UNIX System VRelease 3. В ней появились межпроцессныевзаимодействия, разделения удаляемых файлов (RemoteFile Sharing - RFS), разделяемые библиотеки. Былопроизведено 750000 установок и более 4,5 млн.пользователей.

В эти годы ходили слухи о внедрении в исходныекоды ОС DOS и Windows умышленной ошибки, непозволявшей работать электронным таблицам пакетовLotus продолжительное время без ошибок. На тот моментзаконодательства регулирующего область разработкипрограммного обеспечения не было, и такие слухи, всовокупности с непредсказуемыми зависаниями ОС прииспользовании пакетов Lotus, казались вполнеправдоподобными.

Начиная с 1990 года популярность продуктовкомпании WindowsTM отодвинули ОС UNIX ипроизводные от ней ОС на второй план до появления

Page 59: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

59

проекта ОС Линукс в 1994 году. Линус Тордвальдспородил массовое движение за открытый исходный кодпрограмм. Это движение позволило огромномуколичеству, участников проекта, точное количествокоторых не знает никто, создавать подавляющеебольшинство новшеств именно в этом проекте и толькозатем они переносятся в другие ОС. После переноса ОСЛинукс на мобильные устройства в виде ОС Андроид иiOS, UNIX подобные системы вернули себе лидерство поколичеству установок.

Язык Си являлся центром развития информационныхтехнологий на протяжении длительного времени и еговозможности развивались, исходя из реальныхпотребностей разработчиков на основе экспериментовпри создании ОС.

ОС Линукс является ядром операционной системы,на основе которого создают наборы программ,именуемые дистрибутивами ОС Линукс. Каждыйдистрибутив имеет свою философию развития инаправлен на определенную группу пользователей.

В этой книге будет использоваться дистрибутивАльтЛинукс. Адреса проекта в сети Интернетhttp://www.altlinux.ru. Кроме бесплатности, он обладаетрядом преимуществ. Не требователен к ресурсам иможет эксплуатироваться на моральноустаревших ПЭВМ.Его можно развернуть за 40 минут или установить за чассо всеми приложениями. Обновление редко занимаетбольше 5 минут, при этом обновляются сразу всеприложения. После однократной установки упользователей этой ОС обычно не возникаетнеобходимости её переустанавливать. Команда проектаустойчиво развивается на протяжении многих лет имаксимально приближена к российским реалиям. Онавыпускает стабильные версии ОС, но есть возможность

Page 60: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

60

получать наиболее свежие обновления, которые могутсодержать ошибки. В этом случае приходится в ручномрежиме возвращаться к более ранним версиям.Дистрибутив имеет собственный форум, расположенныйпо адресу http://forum.altlinux.org, на котором можнополучить помощь в оперативном режиме.

К недостаткам ОС Линукс можно отнести отсутствиедрайверов на наиболее дорогие аппаратныекомплектующие, выпущенные менее года назад. Однакоэто может быть и плюсом, не требуется тратить многоденег на самое свежее аппаратное обеспечение.Оптимальным является выбор аппаратного обеспечения,выпущенного 2-3 года назад. К этому времени цена нанекоторые комплектующие может снизиться до двух иболее раз, а их производительность позволит незаниматься обновлением аппаратной составляющей допяти лет. Решением проблемы совместимостиаппаратного и программного обеспечения являетсяпоиск информации о поддержки выбираемогоаппаратного обеспечения текущей версией ОС допокупки аппаратного обеспечения.

Часто возникает противоречие, связанное сосложностями при использовании новейшегооборудования и дистрибутивов на базе ОС Линукс.Обычно наиболее производительные конфигурациииспользуются для узкопрофильных задач. Такиеустройства потребляют большое количество энергии инабирать на них исходные тексты программэкономически не эффективно. Другой отговоркой отпокупки 2-3 летнего аппаратного обеспечение являетсяневозможность запуска компьютерных игр со сложнымиэффектами. Для них уже много лет успешноиспользуются компьютерные приставки,производительность которых не ниже «игровых

Page 61: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

61

конфигураций» ПЭВМ, но стоимость часа игры наприставке, состоящей из стоимости приставки, игры,потребляемой электроэнергии, ниже, чем постояннаяэксплуатация «игровой ПЭВМ». Главным преимуществомигровой приставки является отсутствие графическихэффектов «подвисания изображения», «несвоевременнаяпрорисовка», «малая дальность прорисовки» и прочие.

Page 62: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

62

1.6. Файловая система

Основное понятие файловой системы – файл.Наиболее общее определение файла следующее: файл –именованная последовательность байт. Таким образом,под файлом может пониматься модель любогоустройства, например клавиатуры или мыши, байты наносителе информации, сетевое соединение или дажемикропроцессор. Файл является упаковкой как длябазовой сущности — информация, базовой сущностипроцесс, а также для устройств.

В случае файла с информацией, информация обычнохраниться в устройстве по частым в произвольномпорядке, что позволяет экономить физическоепространство накопителя, но приводит к фрагментациифайлов. В случае процесса, файл процесса являетсявиртуальным и не записывается на носитель

Файл

Файл-данные Файл-процесс Файл-устройство

Содержит:атрибутыпроцесса,

используемыересурсы ОС

Содержит:данные с

устройства илиатрибуты

устройства

Содержит:информацию

илиданные

Носительинформации

Оперативная память

Page 63: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

63

информации. Файл устройство обычно является областьюоперативной памяти, через которое производится обменинформацией с устройством. Файлы устройства и файлыпроцессов существуют только в ОС и содержатконфигурационную информацию, информацию о текущемсостоянии процесса/устройства, списки ресурсов,предоставленные ОС данному процессу или устройству.

Для управления файлами используется файловаясистема. Файловая система (ФС) - состоит из драйверови программ и используется для управления файлами.Благодаря файловой системе работа с файламипроизводится с помощью унифицированных действий ине требует знания особенностей реализации конкретногоустройства. ФС обрабатывает ошибки, возникающие впроцессе работы с файлами. Вторым после понятия файл,наиболее важным понятием файловой системы являетсякаталог (папка). Каталог — файл специального формата,содержащий записи о других файлах и каталогах и ихатрибутах.

Используя каталоги, файловая система реализуетиерархическую структуру расположения файлов икаталогов. Именно в каталогах хранятся названия

/

Каталог Файл

Файл Каталог

Файл

Page 64: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

64

файлов и вложенных каталогов, общий размер файлов.Каталог, из которого начинается ветвление файловойсистемы, называется корневой каталог и обозначается«/». В операционных системах семейства WindowsTM дляпросмотра файловой системы используется программа«Проводник», в которой корневой каталог скрыт и вместонего отображается программа «Мой компьютер» или«Компьютер».

Для отображения расположения объекта файловойсистемы используется понятие путь к файлу иликаталогу.

Пути бывают двух типов.1. Относительный путь, содержит перечисление

каталогов от текущего каталога до искомого файла,например: groff/man.local .

2. Полный путь, содержит перечисление всехкаталогов до искомого файла, например:/etc/groff/man.local . Полный путь всегда начинается ссимвола «/».

Базовый принцип работы с файлами описываетсятак: открыл – чтение/запись – закрыл. Это оченьнапоминает алгоритм наших действий с кастрюлями накухне. Мы открываем крышку одной кастрюли (открыл)смотрим в её содержимое или черпаем оттуда суп(читаем) и закрываем крышку (закрыл). Также и сзаписью, сначала нужно открыть крышку чистойкастрюли, затем налить туда молоко, затем закрыть.

Во время одного сеанса работы с файлом возможно

Открыл

Чтение

Запись

Закрыл

Page 65: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

65

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

Для работы нескольких пользователей на однойвычислительной машине необходимо иметь возможностьразграничивать их права. Исторически сложиласьсистема, в которой все права разделяют на три группы:владелец (user); группа владельца (group); остальные(other). Удобство такой системы заключается ввозможности работать с файлами индивидуально,обмениваться информацией внутри группы илипредоставить общий доступ к файлу.

Для разграничения доступа различных программ ОСреализуют три вида доступа к программе: чтение (read),запись (write), исполнение (execute). Причем праваразграничения доступа процессов можно задавать длякаждой группы пользователей. Подчеркнутые буквыанглийского написания прав используются какобщепринятый способ указания прав. Отсутствие праваотображается символом «-». Права доступа записываютсяв следующем порядке: права владельца, права группывладельца, права всех остальных. Приведем примеры:

rwxrwxrwx — владелец имеет доступ на чтение,запись, исполнение этого файла; группа владельца имеетдоступ на чтение, запись, исполнение файла; всеостальные имеют права на чтение, запись и исполнениефайла;

rwxr-x--x — владелец имеет только право на чтение,запись и исполнение файла, группа владельца имеетправо на чтение и исполнение файла, остальные имеют

Page 66: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

66

право только на исполнение файла.Такой способ задания прав удобен, если владелец

файла создает текстовый файл, являющийся скриптом.Скрипты имеют возможность исполняться какпрограммы. Группа владельца может просматриватьисходный код скрипта и исполнять его, оказывая такимобразом помощь владельцу файла. Все остальные могуттолько исполнять файл, не зная исходный кодпрограммы.

Для файла можно задать любую другую комбинациюправ, включая комбинацию, при которой у всехотсутствует любой доступ к файлу. Чтобы понять какисправить такую ситуацию, необходимо вспомнить, чтовсе атрибуты файлов хранятся в каталоге. Удалив всеправа к файлу, пользователь теряет к нему доступ, ноесли сохраняются права к каталогу, в которой оннаходится, значит эти права можно вернуть. После этогоможно получить доступ к файлу во вновь заданныхрежимах.

Реальная система управления файлами немногосложнее. В современные ОС используются такназываемые липкие биты, которые позволяют запускатьпрограммы от имени других пользователей, болеедетальную информацию о них можно узнать с помощьюпоисковых систем сети интернет. Кроме того,пользователь root (администратор/системныйпользователь) имеет доступ на чтение и запись ко всемобъектам файловой системы независимо от выставленныхправ, однако не имеет прав на исполнение программ,если они не заданы явно. Права к файлу иногда задаютсяс помощью трех цифр, что менее удобно дляначинающих. Способ задания прав доступа не влияет нарезультат.

Дополним список объектов ФС:

Page 67: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

67

- жесткая ссылка. Это запись внутри каталога,которая указывает на другую запись. Она можетиспользоваться только в пределах одного устройства;

- символьная или мягкая ссылка. Это файл надиске, указывающий на другой файл или несколькофайлов в другом каталоге, которые могут находиться надругом устройстве;

- канал (FIFO, PIPE) — файл, расположенный воперативной памяти, используемый для обменаинформацией между процессами;

- сокет. Это файл, расположенный в памяти ииспользуемый для обмена информацией междупроцессами. Обычно сокеты используются длямежсетевых взаимодействий по протоколам TCP/IP,однако сокеты являются стандартным способ обменаинформацией между любыми процессами.

Файловая система отображается для пользователякак единая иерархическая структура, однако каждая изних умеет работать только с одним типом объектов:файлами с данными; файлами процессами или файламиустройствами. Существуют ФС следующих типов:

- devfs. Предоставляет доступ к устройствамкомпьютера;

- proc. Позволяет получить доступ к атрибутамисполняемых в данный момент процессам, а также кпараметрам ОС;

- ext2, ext3, ext4. Наиболее популярная файловаясистема для управления файлами с информацией;

- ReiserFS. Журнализируемая ФС, ориентированнаяна хранение множества файлов малого размера,например html-страниц. В ней фрагментация файлов вносителе почти всегда находится на пренебрежимомалом уровне. Может рассматриваться какспециализированная ФС для управления файлами с

Page 68: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

68

информацией;- VFS. Виртуальная ФС. Выполняет функцию

прослойки между любой ФС, включая FAT32, NTFS, Ext2и ядром ОС;

- NFS. Сетевая ФС. Позволяет реализовыватьразделение одной ФС между несколькими компьютерами.В этом случае, каталог ФС может оказаться носителеминформации на другой вычислительной машине.

Для добавления одной ФС в другую используютсяоперации монтирования и размонтирования. Длямонтирования ФС достаточно вызвать функцию mount иуказать её каталог, в которую будет произведеномонтирование и путь к монтируемому каталогу или путьк монтируемому устройству. В случае монтирования вкаталог уже содержащий объекты, имеющиеся объектыбудут скрыты, но не удалены. После размонтированияпредыдущее содержание каталога станет вновьдоступным. Более подробно вопрос монтирования будетрассмотрен в главе, посвященной администрированиюОС.

Приведем структуру файловой системыдистрибутива АльтЛинукс с описанием их содержимого.Список каталогов корневого каталога «/» можетменяться от версии к версии, однако имена большинствакаталогов будут совпадать.

bin — содержит наиболее важные системныеприкладные программы, которые доступны в любыхрежимах работы ОС.

boot — содержит образы ядер ОС Линукс разныхверсий и веток, загрузчик, утилиту для тестированияоперативной памяти memtest, которая запускается беззагрузки ОС, прочую информацию, необходимую длязагрузки. Для доступа в этот каталог необходимообладать правами администратора (root).

Page 69: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

69

dev — предоставляет доступ к устройствамвычислительной машины. Доступ на чтения содержимогоэтого каталога есть у всех пользователей. Для работы сустройствами требуется обладать правамиадминистратора.

etc — содержит файлы конфигурации ОС, драйверов,служб и прикладных программ. Доступ на чтениепредоставляется всем пользователям. Изменятьинформацию в этом каталоге может только пользовательс правами администратора.

home — содержит каталоги, имена которыхсоответствуют системным именам пользователей,например для пользователя valerii должен существоватькаталог /home/valerii . Доступ к содержимому каталогапользователя имеет сам пользователь и администратор.

lib — содержит библиотеки, необходимые для работысистемы, чаще связанные с аппаратным обеспечением.

lib64 — содержит архитектурнозависимыесистемные библиотеки для архитектуры x86-64, т. е. длявычислительных машин, оснащенныхмикропроцессорами, имеющими 64-х разрядныерегистры и команды для логических и арифметическихопераций.

lost+found — этот каталог используется ФС дляисправления ошибок в самой себе. Каталог с такимназванием может встречаться в других каталогах.

media — в этот каталог монтируются(присоединяются или добавляются) переносныеустройства, такие как оптические дисковые носители,носители информации на основе флеш-памяти и прочее.В случае их успешного монтирования в этом каталогепоявляется каталог соответствующий определенномуустройству.

mnt — каталог для монтирования дополнительных

Page 70: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

70

накопителей информации, постоянно присутствующих вОС.

opt — каталог для хранения настроек, которыеотносятся к конфигурированию системы. Вдистрибутивах АльтЛинукс обычно пустой.

proc — каталог, соответствующий ФС,предоставляющей доступ к исполняемым в данныймомент процессам.

root — каталог системного администратора. Оннаходится в главном каталоге, т. к. в случаевосстановления системы может не быть возможности длязагрузки вспомогательных ФС или монтированиядополнительных устройств.

run — может содержать разную информацию,необходимую для функционирования ОС и процессов,например сокеты принадлежащий процессу.

sbin — системные утилиты, нужные для организацииработы пользователя или используемые пользователем.

selinux — каталог в АльтЛинукс используется дляспециального программного обеспечения, часто пуст.

srv — чаще используется для работы прикладныхслужб.

sys — необходим для работы ОС.tmp — содержит временные файлы. Его содержимое

очищается после перезагрузки ОС.usr — дублирует основные каталоги корневой ФС.

Используется для хранения пользовательских программ,библиотек, настроек, игр, подключаемых файловкомпилятора и прочей информации процессовпользователей. Такое дублирование необходимо с цельюзащиты ОС от неправильных действий пользователей.

var — используется для хранения различнойинформации, начиная от сокетов и уникальныхидентификаторов процессов, заканчивая каталогами для

Page 71: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

71

автомонтирования съемных накопителей.Предположительно автомонтирование производится вэтот каталог, чтобы исключить совпадение имен приручном монтировании устройств в каталогах media илиmnt. Основное назначение информации этого каталога,хранение журналов исполнения различных сервисов ипроцессов. Здесь сохраняется информация о событиях,произошедших в ОС, переменные данные ОС.Рекомендуется размещать этот каталог на отдельномлогическом или физическом накопителе, т. к.информация в каталоге обновляется очень часто и этоможет вызвать повышенный износ дорогого накопителяили фрагментации ФС. При использовании накопителейна основе жестких дисков это вызовет замедлениеработы и быстрый его износ. Самое важное что нужнознать об этом каталоге, — его переполнение приводит костанову всей системы.

В завершении краткого обзора базовых концепций ипонятий ФС отметим, что основной перспективнойконцепций ФС является переход на безфайловое или неиерархическое хранение информации. В этом случае длядоступа к информации пользователь должен знать толькоатрибуты информации, например, примерное времясоздания или изменения, тип искомой информации,объем информации. Переход на такой типвзаимодействия был анонсирован примерно в начале2000-х годов и до сих пор не существует ни однойреализации, способной достойно заменить обычнуюиерархическую структуру информации.

Другим направлением развития ФС является еёинтеграция с системами контроля версий. Подобныесистемы позволяют отслеживать изменение состоянияфайлов и их структуры в процессе работы и позволяетвозвращать ФС в состояние на любой момент времени.

Page 72: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

72

1.7. Конфигурационная информация

Операционная система содержит в себе множествотаблиц. Примером могут служить таблицы дескрипторовоткрытых файлов или сокетов, страничная организацияоперативной памяти. Эти таблицы на прямую доступнытолько разработчикам ОС. Другой важной составляющейОС является конфигурационная информация. Основнойспособ хранения конфигурационной информациииспользование конфигурационных файлов, содержимоекоторых в текстовом виде описывает настройкипрограммного обеспечения. Этот подход имеет дваспособа применения. В одном случае конфигурационныефайлы хранятся в специальном каталоге /etc .Преимущество такого подхода в том, что место поискаконфигурационного файла определено заранее. Другойвариант заключается в хранении конфигурационногофайла вместе с исполняемым файлом.

Оба этих варианта имеют ряд недостатков и чтобы ихпреодолеть, компания MicrosoftTM разработалатехнологию специальной базы данных, называемойреестр WindowsTM. В этом случае все настройкихранятся в одной базе данных, а ОС предоставляет наборфункций для добавления, изменения и удалениянастроек. Для использования технологии реестранеобходимо знание приоритетов настроек, описанных вего разных частях. По-факту реестр WindowsTM являетсяодним из самых уязвимых мест ОС, т. к. технологияреестра замыкает на себе все процессы, включаядрайверы устройств и их взаимодействия в ОСнезависимо от их прав доступа. В результате элементыреестра ОС WindowsTM все равно хранятся в разныхфайлах, а сама компания MicrosoftTM со временемзадумалась об обходе ограничений собственной

Page 73: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

73

технологии, что было отражено в платформе .NET.Формат исполняемого файла в этой технологии позволяетхранить конфигурационную информациюнепосредственно в исполняемом файле. Такой подходтоже противоречит основам разграничения доступа, т. к.исполняемые файлы обычно не должны иметь право назапись в самого себя, чтобы уменьшить возможныйущерб в случае возникновения ошибок при выполнении воперативной памяти или заражении вирусом.

Большая часть конфигурационной информации в ОСАльтЛинукс храниться в каталоге /etc, расположенном вкорневом каталоге. В нем находится как системнаяконфигурация ОС, так и настройки пользовательскихпрограмм. Общепринятой практикой сталоиспользование в названии конфигурационного файлаимени исполняемого файла программы, названияпрограммы или сокращения, связанного с программой.

Для примера приведем программу acpi. Еёназначение заключается в отображении информации изфайловой системы /proc о состоянии заряда батареи,температуры, передаваемой датчиками в случае ихналичия, прочей информации. Конфигурационнаяинформации утилиты расположена в каталоге /etc/acpi.Этот каталог содержит вложенный каталог events. В нейимеется только один конфигурационный файл power,который является текстовым файлом в кодировке ASCII.Полный путь к нему /etc/acpi/events/power. Он имеетследующие права доступа: -rw-r--r-- . Его владельцемявляется пользователь root. Файл принадлежит группеroot . Содержимое этого файла — две строки

event=button/poweraction=/sbin/poweroffОни предписывают исполнять программу

/sbin/poweroff при нажатии кнопки power.

Page 74: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

74

Процессы, запускаемые при загрузке ОС Линукс,имеют различные приоритеты запуска. Дляконфигурирования и запуска таких процессов можноиспользовать каталог /etc/init.d/ , который являетсясимвольной ссылкой на каталог /etc/rc.d/init.d/ . Однако вОС есть и другие уровни приоритетов запуска. Онирасполагаются в каталоге /etc/rc.d . Файлы в каждой изшести каталогов, задающих приоритет загрузки rc0.d —rc6.d, начинаются с символов K05. Число 05соответствует желаемому порядковому номеру длязапуска процесса в своей группе, задаваемой названиемкаталога, однако ОС не всегда может четко следоватьэтим предписаниям.

В каталоге /etc/ конфигурационные файлы могут бытьв двоичном формате, например /etc/localtime . В немзаписана временная зона и правила перехода налетнее/зимнее время.

Приведем другие примеры конфигурационнойинформации ОС.

- /etc/default/ — в этом каталоге хранятся файлы,используемые при создании новой учетной записипользователя в системе.

- /etc/passwd — в этом файле хранятся паролипользователей.

- /etc/group — в этом файле хранятся паролипользователей.

- /etc/local/ - настройки текстового режима системы.- /etc/kde/ — настройки графической системы KDE и

её приложений.- /etc/ppp/ - настройки демона (сервиса) pppd,

реализующего PPP-интерфейс. Этот интерфейсиспользуется для обеспечения работы модемов.

- /etc/NetworkManager — настройки менеджерасетевых подключений.

Page 75: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

75

- /etc/samba/ - настройки демона, обеспечивающегоработу в сети, содержащей компьютеры на базе Windows.

- /etc/sysconfig/ - каталог, содержащий файлысистемной конфигурации.

- /etc/X11/ - настройки графической оболочки X11.- /etc/hosts — содержит сопоставление IP адресов —

символьным именам.- /etc/motd/ — сообщение, выдаваемое системой после

входа пользователя в систему.- /etc/fstab — содержит список точек монтирования

ФС, в том числе подключенные аппаратные накопителиинформации.

В отличие от настроек ОС, конфигурационные файлыпользователей могут находиться в его домашнемкаталоге, например /home/ivanov/ . Обычно названия этихкаталогов или файлов начинаются с символа точка,который предписывает не отображать такие объекты дляпользователя без явного указания показывать скрытыеобъекты. Также конфигурационная информацияпользователя может находится в каталоге /usr/etc/ .

В домашнем каталоге пользователя находитсяфайл .dmrc, в котором указывается основной язык длясессии пользователя, например так:

[Desktop]Language=ru_RU.utf8Session=defaultВ каталоге .config располагается каталог autostart, в

котором размещаются скрипты и объекты-иконкирабочего стола, выполняемые при входе пользователя всеанс ОС.

Если нужный конфигурационный файл не удаетсянайти в ФС, значит программа не установлена. Одним изспособов поиска файлов конфигурации являетсяизучение установочного скрипта в дистрибутиве.

Page 76: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

76

1.8. Сетевые технологии. Стек протоколов TCP/IP

Одной из главных причин популярностивычислительной техники стало массовоераспространение вычислительных сетей. Появление сетиИнтернет позволило кардинально снизить стоимостьбытового общения на любые расстояния. Основные идеиобмена информацией с помощью вычислительных машинотражены в модели ВОС (OSI). OSI - open systemsinterconnection basic reference model. Базовая ЭталоннаяМодель Взаимодействия Открытых Систем (ЭМВОС) илисокращенно ВОС. Модель описана в ряде стандартов:

1. ГОСТ Р ИСО/МЭК 7498-1-99. — «ВОС. Базоваяэталонная модель. Часть 1. Базовая модель».

2. ГОСТ Р ИСО 7498-2-99. — «ВОС. Базоваяэталонная модель. Часть 2. Архитектура защитыинформации».

3. ГОСТ Р ИСО 7498-3-97. — «ВОС. Базоваяэталонная модель. Часть 3. Присвоение имён иадресация».

4. ГОСТ Р ИСО/МЭК 7498-4-99. — «ВОС. Базоваяэталонная модель. Часть 4. Основы административногоуправления».

Прикладной HTTP, SMTP, SNMP, FTP, Telnet, NFS, RTCP

Представительный XML, XDR, SMB

Сеансовый TLS, SSH, RPC, NetBIOS

Транспортный TCP, UDP, BGP

Сетевой IP, ICMP, IGMP, X.25

Канальный Ethernet, PPP, ISDN, ISDL

Физическийэлектричество, радио, лазер (физическая среда и принципы кодирования информации)

Page 77: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

77

Полная модель ВОС называется традиционноймоделью и содержит 7 уровней. Каждый протокол описанв RFC или другом документе.

В практической деятельности не всегдазадействуются все 7 уровней стандартной модели ВОС.Например, при нажатии на ссылку в браузере можетбыть отправлен запрос по HTTP протоколу. В этом случаевычислительная машина отправителя запроса используетследующую схему формирования и передачи запроса:

Прикладной — HTTP.Транспортный — TCP.Сетевой — IP.Канальный — Ethernet.Физический — электричество.Всего использовано 5 уровней вместо 7. Сервер

получит сообщение и для его разбора задействуетследующие уровни:

Физический — электричество.Канальный — Ethernet.Сетевой — IP.Транспортный — TCP.Прикладной — HTTP.Таким образом на сервере также будут использованы

протоколы 5 уровней.Стеком TCP/IP называют набор протоколов разных

уровней модели ВОС. Его главной особенностью являетсянезависимость от физической среды передачиинформации. С помощью него реализуются все уровнимодели ВОС. Сам он занимает 4 уровня: прикладной,транспортный, межсетевой, уровень доступа к сети(физический, канальный и частично сетевой). Досегодняшнего момента существуют разногласия на какиеуровни делить стек протоколов. Например, предлагаетсяввести восьмой уровень «Internetworking» — между

Page 78: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

78

транспортным и сетевым уровнями, т. к. существуютпротоколы, которые нельзя отнести к одному из уровней.

Способ подключения вычислительных машин ккомпьютерной сети и архитектуру связей,сформированных между вычислительными машинами,называют топологией вычислительной сети. Насегодняшний день наиболее популярной являетсятопология звезда, при которой к центральному серверуили маршрутизатору подключаются остальныевычислительные устройства. Топология сетейопределяется канальным уровнем.

В стеке TCP/IP верхние 3 уровня модели ВОС(прикладной, представительный и сеансовый)объединены в прикладной, а функции по определениютипа данных переданы программе пользователя.

В результате упрощенную модель ВОС для стекаTCP/IP можно ограничить уровнями:

- физический — описывает среду передачиинформации, принципы передачи информации в этойсреде, физические характеристики этой среды;

- канальный — описывает, как выполняетсякодирование и передача пакетов с информацией виспользуемой среде;

- сетевой — используется для передачи пакетов изодной подсети в другую, получения служебнойинформации, управления широковещательными ипрочими пакетами;

- транспортный — используется для решенияпроблемы негарантированной доставки пакетовинформации, гарантируют правильнуюпоследовательность получения пакетов, определяютисточник и получателя пакета;

- прикладной — используется большинством сетевыхприложений (браузеры, почтовые сервисы, передача

Page 79: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

79

файлов и т.д.);Существует набор стандартных сетевых протоколов,

которые определяются Агентством по выделению имен иуникальных параметров протоколов (IANA). Основноеотличие стандартных протоколов в максимальноширокой поддержке вычислительными устройствами иприсутствием зарезервированного номера порта,который закреплен только за этим протоколом. Сетевойпорт — это участок оперативной памяти, в которыйкопируются данные из памяти сетевого устройства.

В основе стека протоколов TCP/IP лежит протокол IP(Internet Protocol — межсетевой протокол). Он необеспечивает надежную доставку, т. е. пакеты могутприйти не в том порядке, в котором были отправлены,прийти поврежденными или не прийти вообще. Всовременных сетях используется IPv4 (RFC 791) илиболее новый IPv6 (RFC 2460).

Основное понятие протокола IP — это IP пакет. IPпакет (IP датаграмма) — форматированный блокинформации, передаваемый по вычислительной сети.Общепринятым способом описания структуры IP пакетаявляется графическое представление датаграммы,которое представлено на изображении ниже.Представление датаграмм для всех протоколов нижнихуровней включено в соответствующие им стандарты.

0 1 2 30 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7Версия IHL Тип обслуживания Длина пакетаИдентификатор Флаги Смещение фрагментаЧисло переходов (TTL) Протокол Контрольная сумма заголовка

IP-адрес отправителя (32 бита)IP-адрес получателя (32 бита)

Параметры (до 320 бит) Данные (до 65535 байт минус заголовок)

Page 80: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

80

Пояснения для всех полей даны в RFC 791.Интерпретация поля «Протокол» дана в RFC 1700,упоминание о котором многократно встречается впротоколах IP и 4-й и 6-й версий. Научится читатьдатаграммы очень просто. Приведенное графическоеизображение подразумевает, что 1 и 2 строки содержатномера байт и битов, 3-я содержание первых 4-х байт.Путаница может возникнуть уже на этом этапе, т. к.первый байт имеет индекс 0. Четвертая строка содержит5,6,7 и 8 байт IP пакета с номерами 4,5,6 и 7соответственно. Для экономии ширины изображения,четвертая и последующие строки изображаются подтретьей и без нумерации бит и байт, в которых онирасполагаются. Получается, что адрес получателясодержится в 17,18,19 и 20 байте IP пакета. Высотастроки не указывает на количество байт в поле и зависитот размера текстового описания поля.

Датаграмма IP пакета версии 6 IPv6 имеетсовершенно другой вид. Её заголовок занимает большееколичество байт.

Версия (4 бита)

Класс трафика (8 бит)

Метка потока (20 бит)

Длина полезной нагрузки (16 бит) След. заголовок (8 бит) Число переходовIP-адрес отправителя (128 бит)IP-адрес получателя (128 бит)Данные

В протоколе IPv6 учтена возможность определенияприоритета пакета с помощью поля «Класс трафика». Егоприменение позволит ускорять передачу данных,актуальность которых быстро обесценивается современем.

IP адреса распределены по области применения. ВRFC 1918, а также в стандартах, указанных в его 9-мразделе, определены диапазоны адресов, которые могут

Page 81: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

81

использоваться только в локальных сетях.- 10.0.0.0 — 10.255.255.255 класс A;- 172.16.0.0 — 172.31.255.255 класс B;- 192.168.0.0 — 192.168.255.255 класс C;- сеть 2001:0DB8::/32 в IPv6 — зарезервировано дляпримеров и документации.Вычислительные машины объединяются в подсети

общими начальными битами адреса. Количество такихбит называется маской подсети. Классы IP адресовопределяют, сколько октетов адреса может изменяться.Класс A позволяет присваивать адресам\вычислительным машинам, изменяя три октета, начинаясправа. Класс B позволяет изменять два октета, начинаясправа. Класс C только один октет, начиная справа. Наданный момент классы не имеют повсеместногораспространения в глобальных сетях, но могутприменяться в отдельных локальных сетях.

Также существует специальный локальный адрес127.0.0.1 . В случае отправки пакетов ему, онизакольцовываются и передаются в порт этой жевычислительной машины. Данные, переданные адресу127.0.0.1, не достигают сетевого устройства,соответственно он доступен даже при отсутствии илинеисправности сетевого устройства. Благодаря этомувозможна организация взаимодействия процессов врамках одной ЭВМ даже при отсутствии сетевогоутсройства.

Все современные технологии работают сиспользованием IP адресов. Не имея своего корректногоIP адреса невозможно получить ответ на запрос,отправленный в вычислительную сеть по протоколу IPили более высокого уровня. Аппаратное обеспечениевыполняет обмен информацией с помощью протоколовболее низкого уровня и использует аппаратные адреса

Page 82: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

82

(MAC адреса). Существуют технологии перехватасетевого трафика, но о них речь пойдет в разделе,посвященном администрированию вычислительной сети.При подключении к точке доступа в вычислительнуюсеть, первой процедурой является автоматическоеполучение IP адреса по технологии DHCP илииспользование IP адреса, указанного заранее в ОС. ЕслиIP адрес указывается вручную и ЭВМ с таким адресомуже присутствует в сети, передача данных производитсяне будет, а также будет нарушена стабильная работаЭВМ с таким же адресом.

При построении глобальной сети Интернет,магистральных каналов, соединяющих материки ирегионы, высокоскоростных оптоволоконных каналов,используются IP адреса, выделяемые организациейICANN. Организация имеет свои представительства вовсех крупных промышленно развитых регионах. ВЕвропейском союзе представительство называется RIPENCC. Без функционирования этих организаций созданиеглобальной вычислительной сети было бы невозможно,кроме того деятельность в сети Интернет регулируетсямеждународным правом и множеством локальныхправовых баз. Считать Интернет безконтрольной зонойполной свободы не верно. Таким Интернет не был ниодного дня с момента своего создания.

Подключение ЭВМ с одинаковыми локальными IPадресами возможно. Для этого используются прокси-сервера или NAT. Прокси-сервер — это технология,предоставляющая для любой подключенной ЭВМ доступв вычислительную сеть от имени прокси-сервера.Технология NAT предоставляет доступ ЭВМ с IPадресами своей локальной сети, в глобальную сеть.Принцип работы технологии NAT заключается взакреплении портов за отдельными локальными ЭВМ.

Page 83: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

83

Для внешних ЭВМ подключения по NAT выглядят какобычные ЭВМ, с подключениями через один IP адрес.

На одном уровне с протоколом IP в модели ВОСнаходится протокол ICMP RFC 792 с дополнениями RFC950 (Internet Control Message Protocol — межсетевойпротокол управляющих сообщений). Как следует изназвания протокол используется для решения сервисныхзадач: поиска ошибок, проверки доступности удаленнойЭВМ с помощью эхо-запросов. Несмотря на то, что этотпротокол вынесен в отдельный документ, он являетсяобязательным при реализации стека TCP/IP. Датаграммыпротокола ICMP фактически помещаются какпользовательские данные в датаграммы протокола IP,однако данные, пересылаемые в нем, поддерживаютработу протокола IP и их обработка включена валгоритмы протокола IP. У каждой версии протокола IPесть соответствующая версия протокола ICMP этой жеверсии, IPv4 — ICMPv4, IPv6 — ICMPv6.

Приведем пример датаграммы протокола ICMPv4.

Бит 0 — 7 8 — 15 16 — 310 Тип Код Контрольная сумма

32 Содержание сообщения(зависит от значений полей Код и Тип)

Версия используемого протокола не указывается, таккак соответствует версии протокола IP, которая, в своюочередь, указывается в первых четырех битах заголовкаIP пакета.

Два основных протокола стека протоколов TCP/IP —TCP (RFC 793) и UDP (RFC 768). Протокол UDP служитдля негарантированной доставки данных.Негарантированная доставка означает, что данные могутне придти к адресату, могут придти не полностью или внеправильном порядке. Он используется при передачепотоковой мультимедийной информации и в других

Page 84: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

84

случаях, когда актуальность информации снижаетсякаждую долю секунды. Протокол TCP наоборот служитдля гарантированной доставки, т. е. в каком виде данныебыли отправлены в сеть, в таком они будут полученыадресатом. Необходимо обратить особое внимание!Порты протоколов TCP и UDP с одинаковыми номерами— это разные участки оперативной памяти. ПротоколUDP работает быстрее и в локальных вычислительныхсетях потери данных почти не происходит, однако, еслинеобходимо гарантировано доставить некоторуюинформацию, нужно использовать более медленныйпротокол TCP. Существует золотое правило выборамежду протоколами TCP и UDP, если хотя бы разпотребовалось подтвердить получение данных,необходимо использовать протокол TCP. Реализациялюбой надстройки над UDP с целью подтвержденияполучения данных всегда будет заведомо проигрышноерешение. Проблемы могут возникнуть как на этаперазработки, так и на этапе поддержки или при выпускеновой версии через несколько лет эксплуатациипрограммного обеспечения.

Максимальная длина UDP пакета составляет 65527октетов (байт). Для взаимодействия сетевых приложенийиспользуются 16-ти битные порты со значениями от 0 до65535. Порт с номером 0 считается портом источника ииспользуется, если программа не требует ответныхдействий. Порты с 1 по 1023 системные. Их назначениене может быть изменено, доступ к ним возможен толькос привилегиями администратора системы. Порты с 1024по 49151 — относятся к зарегистрированным портам,которые используются специальным программнымобеспечением. Порты с 49152 по 65535 — используютсядля пользовательских приложений. Для отправки данныхпо UDP не требуется становления соединения. UDP

Page 85: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

85

используется во множестве протоколов, наиболеепопулярными из которых являются: DNS, RTP, RTCP,SNTP, NTP.

Протокол TCP предоставляет поток данных, спредварительным установлением соединения. В случаепотери данных TCP самостоятельно производит ихповторный запрос, отбрасывает повторные данные,исправляет множество других коллизий. Еслипроисходит разрыв соединения на длительное время,соединение сбрасывается и выдается сообщение обошибке. Протокол TCP используется множествомпротоколов: HTTP, FTP, RTCP, NFS, Torrent и другими.

Адрес отправителя и получателя содержится взаголовке IP датаграммы. В заголовке TCP датаграммы,как и в заголовке UDP датаграммы, содержится портотправления и порт назначения.

В отличие от рассмотренных ранее протоколов, вкоторых данные передаются в двоичном виде, впротоколе HTTP (HyperText Transfer Protocol —«протокол передачи гипертекста») данные передаются втекстовом виде и имеют значительную избыточность.Другим отличием протокола HTTP является егобазирование на архитектуре «клиент — сервер». При егоиспользовании взаимодействие может бытьосуществлено только по запросу «клиента». «Сервер»обрабатывает запрос, формирует ответ и соединениеразрывается. Адрес ресурса задается с помощью URL взапросе клиента. Наиболее популярны следующиеверсии этого протокола: HTTP 1.0 (RFC 1945), HTTP 1.1(RFC 2616), HTTP 2.0 (RFC 7231).

В сетевых технологиях активно используютсяотносительные понятия локальный и глобальный.Локальной может являться вычислительная сетьорганизации, но она является глобальной для

Page 86: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

86

вычислительной сети одного отдела. Также локальнойможет быть вычислительная сеть страны, по отношениюк Интернет. Однако вычислительная сеть страныодновременно является глобальной для сети одногорегиона.

Перечислим классы архитектур серверов, наиболеепопулярные в сети Интернет. По способу организациипамяти они делятся на однопоточные и многопоточные.В случае однопоточного сервера производитсяпоследовательная обработка запросов, поступающих насервер. Остальные запросы ставятся в очередь наобработку или теряются. Многопоточный серверсоздает для каждого входящего соединения отдельныйпоток, который выполняет его обработку, формируетответ, возвращает ответ клиенту и завершает своюработу. Другое деление архитектур связано снаправлением передачи данных. Асинхронный серверможет обмениваться данными с клиентом в один моментвремени только в одном направлении, т. е. только отсервера к клиенту, или от клиента к серверу.Синхронный сервер может осуществлятьдвунаправленную передачу данных в любой моментвремени.

Для глубокого изучение межсетевых взаимодействийи стека протоколов TCP/IP требуется не менее годаежедневной работы. В институте Беркли авторский курсв этой области обеспечен материалом, изложенным втрех томах. Этот раздел необходим для обозначенияосновных технологий и протоколов, которые будутиспользоваться далее и не являются учебным пособием.

Отдельно следует рассматривать семейство сетевыхпротоколов, в которые изначально включены средствазащиты передаваемых данных, например, протоколыIPsec, HTTPS, HFTP.

Page 87: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

87

2. Администрирование ЭВМ, вычислительных сетей2.1. Установка и обновление ОС и ПО

В этом разделе описаны основные этапы подготовкипрограммного обеспечения к разработке программногообеспечения. Главу правильнее было бы назвать«Обслуживание ЭВМ и компьютерных сетей», потому чтов ней будут рассмотрены всего несколько задачадминистрирования.

В разделе нет подробных пошаговых инструкций,которые имеются в различных формах в сети Интернет.Каждый человек имеет свои предпочтения признакомстве с новыми знаниями, поэтому здесьпоясняются исключительно вопросы, которые сложносформулировать и еще сложнее найти на них правильныеответы. Также в этом разделе не затрагиваются вопросывыбора аппаратного обеспечения, считая, что передпокупкой пользователь догадался найти информацию осовместимости выбранного аппаратного обеспечения сдругими компонентами и о его поддержке современнымиоперационными системами.

До работы с ЭВМ необходимо пройти этапподготовки. Первым этапом подготовки являетсяопределение набора задач, для решения которыхготовиться ЭВМ. ПЭВМ на базе ядра ОС Линукс можетрешать все задачи, за исключением эффективногоиспользования программного обеспечения,разработанного специально для ОС WindowsTM. Послеопределения задач, необходимо заняться сбороминформации об удобстве их решения в разныхдистрибутивах.

Для первоначального сбора информации достаточноуметь пользоваться поисковыми машинами в сети

Page 88: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

88

Интернет. На сегодняшний день текстовые материалылучше использовать для аналитического сравнения ОС,программ, способов реализации функций. Видеоматериаллучше использовать для подготовки к некоторомудействию, например, установке ОС.

После определения ряда дистрибутивов, которыепозволяют решать все поставленные задачи, выборконечного можно производить, руководствуясь самымглавным критерием: простота эксплуатации иобслуживания, наличие необходимого программногообеспечения. На практике у начинающих пользователей,выбор часто производится по причине наиболеекрасивого изображения на рабочем столе, что тожеочень важно.

Существует еще одна не формализуемая причинавыбора дистрибутива: «так сложилось исторически».Обычно под этим подразумевают наличие значительногоопыта его применения. В текущей ситуации такоеобоснование является подтверждением того, что надэтим дистрибутивом работает живое сообществоразработчиков и пользователей, также имеетсябесплатная оперативная поддержка в виде форума поадресу http://www.forum.altlinux.org.

Для получения дистрибутива следует выбиратьисключительно доверенные источники. Чаще всего этосайт в сети Интернет разработчика дистрибутива. Вслучае возникновения необходимости использовать файл-образ ОС из не доверенного источника, например, изсети, работающей по протоколу torrent, необходимоподтвердить его подлинность с помощью контрольнойсуммы с сайта разработчика. Как это сделать будетописано в следующих разделах.

Разработчики АльтЛинукс предоставляют двеконцепции распространения дистрибутивов. На сайте

Page 89: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

89

разработчиков по адресу http://www.altlinux.ru имеютсяссылки на актуальный дистрибутив АльтЛинукс. Этополноценный дистрибутив с репозиторием программ длянего содержащим порядка сотни тысяч бесплатныхпрограмм.

Для высококвалифицированных пользователей,администраторов и разработчиков предоставляетсядистрибутив в виде стартовых наборов. На сайтеразработчиков по специальному адресуhttps://www.altlinux.org/Starterkits имеется информация оних. Стартовые наборы для скачивания доступны поадресу http://nightly.altlinux.org/ . Данные наборысодержат в себе минимальное количество пакетовпрограмм.

Далее для описания будет использоватьсядистрибутив AltLinux. На сайте разработчиковприсутствуют образы двух форматов: ISO и IMG.

Для того чтобы выполнить установку ОС на ЭВМ,необходимо сделать загрузочный CD/DVD диск илизагрузочный флеш-накопитель. Для создания CD/DVDиспользуется файл-образ формата ISO, для созданиязагрузочного флеш-накопителя — файл-образ форматаIMG. Эти форматы называются файл-образами, потомучто кроме файлов, необходимых для загрузки ОС, онисодержат информацию о их расположении нанакопителе, на котором они использовались в качествеОС.

Для записи файлов-образов в ОС WindowsTMиспользуются специальные программы. В ОС,основанных на ядре Линукс достаточно выполнитьследующие действия:

1. скачать файл-образ из сети Интернет, например, сименем cdrom.img ;

2. переместить его в папку /mnt/img/ ;

Page 90: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

90

3. определить путь к устройству, записывающему CD,например /dev/sr0 ;

4. выполнить команду: dd if=/mnt/img/cdrom.imgof=/dev/sr0 .

При наличии у пользователя опыта работы свиртуальными машинами возможна установка ОС Линуксв качестве виртуальной машины, независимо отиспользуемой системы виртуализации virtualbox,wmware, kvm (qemu). Также как и с другими ОС, прииспользовании Линукс на виртуальной машинепроисходит падение производительности центральногопроцессора, также существенно снижаетсяпроизводительность видеокарты. Некоторые аппаратныеи программные мультимедия технологии, драйвераразработчика видеокарты могут быть недоступнывообще. К преимуществам использования виртуальныхмашин следует отнести меньший риск для базовой ОС,возможность эмуляции отсутствующего аппаратногообеспечения, например, 8 сетевых карт, вместоимеющейся одной.

ЭВМ и ПО, как любое техническое решение или егочасть, требует обслуживания. Одна из главных задачобслуживания ПО — его обновление. В ОС WindowsTMиспользуется общая стратегия, говорящая о том, что всеобновления должны быть установлены как можнобыстрее. Принимать решение о нужности того или иногообновления рекомендуется только опытнымпользователям. Большие обновления происходятпримерно один раз в месяц, так называемые сервисныепакеты могут выходить примерно один раз в год. Приэтом речь идет только об обновлениях самой ОС, но не остороннем ПО. В каждом дистрибутиве ОС Линукссуществует своя стратегия обновления. РазработчикиАльтЛинукс рекомендуют выполнять обновление по

Page 91: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

91

необходимости. Финальные сертифицированныедистрибутивы выпускаются компанией раз в год илинесколько лет. Это считается достаточным. Исключениесуществует для исправлений обнаруженных критическихуязвимостей безопасности и критических ошибок,приводящих к зависанию программ. При этом имеетсяввиду все программное обеспечение вместе с ОС.

В сообществе АльтЛинукс обновления появляютсязначительно чаще, практически ежедневно. Онииспользуются для тестирования и не обязательны дляустановки. Даже в сообществе рекомендуется выполнятьобновления не чаще, чем раз в квартал или понеобходимости.

Перед обновлением в АльЛинукс, необходимозапустить программу Synaptic и проверить настройкирепозиториев (Главное меню → Параметры →Репозитории). Репозиторий – каталог на сервере,имеющий специальную структуру, в котором хранитсяпрограммное обеспечение и ядро операционной системыв виде исходных файлов или пакетов для конкретнойаппаратной платформы ЭВМ. Наиболее популярнымиплатформами на текущий момент являются (x86, x86-64).При первом запуске необходимо удостовериться, что внастройках репозитория выбран хотя бы одинрепозиторий, адрес которого начинается с названияпротокола http, ftp или rsync, т.е. напротив строкивыставлен символ «V» в элементе множественноговыделения.

ПО хранится на сервере в виде пакетов формата rpmили deb. Пакеты являются архивированными каталогамис файлами. Принципиальным отличием этих форматовявляется концепция. Пакеты формата rpm обычносодержат только устанавливаемое ПО и списокзависимостей от других пакетов, т.е. список программ и

Page 92: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

92

их версий, без которых эта программа работать не может.Пакеты формата deb обычно содержат все необходимыедля установки и запуска программы. Наиболее яркопреимущество концепции deb пакетов проявлялось впериод высокой стоимости доступа к сети Интернет и вплохо развитых системах хранилищ rpm пакетов.Основной недостаток deb пакетов — в возможностизахламления накопителя с ОС различными версиямиодной программы при частой установке и удалениипрограмм. Сейчас эти концепции одинаково популярны.В АльтЛинукс разработчиками используются rpm пакеты,однако возможно использование и deb пакетов, но этотребует углубленных знаний по администрированию ОСЛинукс.

Пакетами в формате rpm управляет программа apt. Спомощью неё проверяются требуемые зависимости,выполняется обновление списков доступных программ,устанавливаются и удаляются программы. Synapticявляется графическим интерфейсом для apt, поэтому всеизменения, выполняемые в Synaptic, можно сделатьпутем внесения изменений в конфигурационные файлыapt. Следует помнить, что apt базируется на собственномхранилище данных и не является системой управлениябазами данных. В связи с этим одновременно может бытьзапущен только один экземпляр программы apt.Пользователи с небольшим опытом работы могутпопробовать параллельно запустить apt и Synaptic, чтовызовет блокировку программы, запущенной второй, т.к.они обе обращаются к одному хранилищу данных.

Программа apt конфигурируется с помощью каталогаapt в каталоге /etc/ . В этом каталоге содержится файлsources.list, в котором указывается путь к файлу,содержащему адреса репозиториев. В текущей версии ОСпути находятся в файлах каталога

Page 93: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

93

/etc/apt/sources.list.d/*.list . Такая путаница возникла впроцессе развития программы apt и необходимостиразделить все имеющиеся пути к репозиториям,например, по имени компании, предоставляющей к нимдоступ.

Компания — разработчик дистрибутива АльтЛинуксделает снимки репозиториев по датам и размещает их вотдельных каталогах. Такой подход позволяетреализовывать следующий прием. В случае, еслипоследнее обновление привело к отказу ОС, требуетсянаиболее новая версия одной из программ, необходимо вкачестве репозитория указать такой снимок. Например:rpmhttp://ftp.altlinux.org/pub/distributions/archive/p8/date/2016/09/15 x86_64 classicrpmhttp://ftp.altlinux.org/pub/distributions/archive/p8/date/2016/09/15 noarch classic .

Снимок можно отличить от обычного репозитория поналичию в нем даты, когда он был создан.

В заключении остановлюсь на проблемеразграничения доступа, которую можно решить на этапеустановки ОС. Первоначально под пользователем ОСподразумевался человек. Сейчас такое соответствие необязательно и практически никогда не соблюдается.Пользователь и соответствующая группа можетсоздаваться под отдельное устройство или программу. Всвязи с этим, если задачи, которые планируется решатьна ЭВМ, можно сгруппировать и эти группы непересекаются, то под каждую из этих групп желательносоздать отдельного пользователя. Решаемые задачи необязательно должны быть уникальными, они могутповторяться.

Например:

Page 94: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

94

- пользователь для игр;- пользователь для работы в офисных приложениях

прослушивания музыки и работы в сети Интернет;- отдельный пользователь для прослушивания

музыки и Интернет-серфинга;- пользователь для тестирования новых программ и

обновлений.Такое деление позволяет, в случае некорректной

работы одной из программ, удалить пользователя совсеми файлами, принадлежащими ему одной командой:userdel -r username . Настройки и файлы остальныхпользователей не пострадают.

Другой обширной темой, изучение которойжелательно проводить до установки Линукс, правильнаяразметка носителя информации, на которыйустанавливается ОС, слишком обширна длярассмотрения в контексте данного раздела. Такжерекомендуется рассмотреть вопросы созданиявиртуальных файловых систем, но этот вопрос неотносится к первостепенным.

Page 95: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

95

2.2. Программное обеспечение

Ранее было сказано о том, что при выборе ОСнеобходимо определить свои потребности, сделав списокзадач, которые планируется решать с помощью данноговычислительного устройства. Под решением задачиимелось в виду наличие ПО, имеющего соответствующиефункции. В этом разделе будет перечислено бесплатноепрограммное обеспечение, которое автор использует напостоянной основе. В скобках после названия программперечислены аналоги, которые используются в случаеневозможности установки рекомендуемой программы.

Cледует отметить, рабочая среда, в том числерабочий стол, формируется платформой xfce4.Перечислим другие пользовательские программы:

- firefox, opera, chromium – программы-браузеры дляпросмотра документов в формате html;

- wget – программа для загрузки файлов из сети вавтономном режиме, т.е. без вмешательствапользователя.

- libreoffice – полноценный оффисный пакет,поддерживающий как форматы файлов свободногораспространения, так и закрытые форматы;

- qmmp – аналог популярного прогрывателя winampдля POSIX систем;- qmmp-out-pulseaudio – плагин программы qmmp.После его установки его необходимо выбрать всвойствах qmmp. Плагин работает в подсистемойвывода аудио pulseaudio, которая установлена навычислительной машине автора по умолчанию;- sane – программа для использования устройствасканирования изображений с листа бумаги;- xsane – графическая оболочка для программы sane;- cuneiform – программа для распознования текста в

Page 96: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

96

отсканированных файлах и файлах графическогоформата;

- okular (FoxIt Reader, CoolReader) – просмотрщикфайлов в нескольких десятках форматов. В основномиспользуется для просмотре файлов в формате pdf;

- fbreader – программа просмотра фалов форматаэлектронных книг fb2;

- ristretto – простая программа из окружения xfce4для просмотра графических файлов;

- kopete – программа для обмена сообщениями ифайлами с поддержкой множества протоколов, включаяXMPP и ICQ;

- VLC, kaffeine – проигрыватели мультимедийныхфайлов. Наличие двух программ связано сдублированием на случай неудачного обновления одногоиз них;

- XVidCap — позволяет производить запись видеодействий, производимых на рабочем столе;

- K3b — программа с графическим интерфейсом.Выполняет создание образов форматов ISO и их записьна оптические носители информации;

- genisoimage — программа с терминальныминтерфейсом, выполняющая создание образов файлов икаталогов в различных форматах;

- wodim — программа с терминальным интерфейсом,позволяющая производить запись оптических носителей(CD/DVD);

- wine — альтернативная реализация технологииWinAPI компании MicrosoftTM. Позволяет запускатьпростые приложения, реализованные с использованиемэтой технологии;

- synaptic — в AltLinux установлен по умолчанию. Вдругих дистрибутивах также может устанавливаться какменеджер пакетов формата rpm, т. е. для установки

Page 97: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

97

других программ;- lyx – программа для работы с научным форматом

подготовки документов TEX;- wxmaxima – графическая оболочка для программы

maxima, умеющего выполнять аналитическиематематические преобразования;

- blender — наиболее функциональный свободныйредактор трехмерной графики, позволяющий создаватьмультипликацию, видео и игры;

- inkscape — редактор векторной графики в форматеSVG;

- gimp — наиболее функциональный свободныйредактор растровой графики;

- ImageMagick-tools — пакет программ, позволяющийвыполнять пакетную обработку изображений, а такжередактировать изображения с помощью командэмулятора терминала;

- audacity – наиболее функциональный свободныйредактор аудио;

- kdenlive – один из наиболее функциональныхсвободных редакторов видео;

- avconv – набор инструментов для обработки видео спомощью команд в эмуляторе терминала;

- galculator – калькулятор, имеющий три режимаработы (простой, инженерный, бумажный – формулы длявычислений набираются текстом);

- mc – менеджер файлов со встроенным текстовымредактором, возможностью подключения по ftp имножеством других функций;

- medit – графический текстовый редактор, удобныйдля редактирования текстовых файлов в различнойкодировке;

- xscreensaver – заставки рабочего стола. Длянастройки в эмуляторе терминала необходимо выполнить

Page 98: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

98

команду xscreensaver-demo;- rss-glx – заставки рабочего стола с использованием

opengl.

Следующий список содержит вспомогательныепользовательские программы, установка которыхтакже крайне желательна:

- java-1.8.0 openjdk. Пакет, в первую очередь,необходим для электронных таблиц и прочих программпакета LibreOffice;

- rsync – программа для синхронизации файлов икаталогов;

- md5sum – программа для создания хеш-образов постандарту md5;

- espeak – программа воспроизводит текст мужскимголосом. Возможно написание текста на разных языках;

- gpg – криптопакет, программа для шифрованияпочтовых сообщений;

- enca – программа для преобразования текстовыхфайлов в различные кодировки;

- unrar, zip, p7zip – программы-архиваторы;- bluez-utils – пакет программ для работы с

радиоприемником, использующим протоколы семействаbluetooth;

- wireless-tools – пакет программ для работы срадиоприемником, использующим протоколы семестваWIFI;

- gostcrypt – инструмент для шифрования постандарту ГОСТ 28147-89;

- acpi — программа отображает информацию изфайловой системы /proc о заряде батареи или с датчиковтемпературы;

- foomatic, hplib, cups – программы, необходимые дляиспользования принтеров различных моделей.

Page 99: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

99

Список далее содержит программное обеспечение,необходимое для обслуживания вычислительноймашины:

- gparted – программа с графическим интерфейсомдля разметки носителей информации;

- fdisk – программа для разметки носителейинформации с терминальным интерфейсом;

- lsblk – программа выводит список разделов наносителях информации, точки монтирования, раздел скоторого произведена загрузка ОС;

- hddtemp – программа отображает температурунакопителей, если они снабжены технологией S.M.A.R.T.;

- smartctl – отображает информацию S.M.A.R.T.;- testdisk – программа восстановления информации

на носителях информации, удаленной из файловойсистемы, но до физической перезаписи ячеек памятиносителя информации;

- gsmartcontrol, smartmontools – пакеты, содержащиепрограммы smartctl, smartd;

- lm_sensors – пакет ПО, предоставляющий доступ кинформации датчиков вычислительной машины. Послеустановки может требовать выполнения команды sensors-detect. Для отображения информации датчиковиспользуется програма sensors;

- aticonfig/nvidia-setting – набор драйверов и утилитыдля конфигурирования видеокарт производителейATI/NVIDIA;

- encfs – пакет для создания шифрованных каталогов;- cryptsetup – программа для создания шифрованных

разделов;- htop – наглядный и функциональный аналог

стандартной программы для отображения процессов изагрузки центрального процессора и оперативной

Page 100: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

100

памяти;- tcpdump – перехват и сбор данных по сетевым

протоколам;- flashrom – программа для создания образов и

перезаписи микросхем вычислительного устройства;- dmidecode – программа отображения информации

BIOS.

Следующий список содержит программы,используемые для разработки программногообеспечения:

- dosbox – эмулятор ОС DOS TM (MicrosoftTM);- libtool – набор инструментов для создания,

установки и удаления библиотек;- git – система контроля версий;- curl – программа для отправки запросов по

протоколу HTPP/HTTPS и получения ответов;- sqlite3 – библиотека, встраиваемая в

разрабатываемое ПО с целью реализации функций БД, наоснове языка структурированных запросов SQL;

- geany – среда для работы с исходными кодамипрограмм, с функциями автоматизации разработки ПО;

- valgrind – программа для поиска утечекоперативной памяти в период исполнения разработаннойпрограммы. Под утечкой подразумевается наличиеошибок, связанных с успешным выделением блоковоперативной памяти и не освобождением их послеиспользования;

- meld – графический редактор, позволяющийсравнивать текстовые файлы и каталоги с текстовымифайлами. Показывает посимвольные отличия междуфайлами.

- gcc – компилятор языка программирования С;- gcc-c++ - компилятор языка программирования С+

Page 101: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

101

+;- gdb – отладчик программного обеспечения,

дополненного отладочной информацией на этапекомпиляции;

- make – программа создания скриптов длякомпиляции сложных проектов;

- automake – программа конфигурирования скриптовкомпиляции сложных проектов;

- doxygen – программа автоматического созданиядокументации из исходного кода программы. Длялучшего качества документирования требует созданияспециальных комментариев в коде программы;

- doxygen-wizard – программа-помощник doxygen;- libusb-dev – набор для разработки библиотеки,

взаимодействующей с устройствами по USB протоколу;- libreadline-devel – набор для разработки библиотеки

обработки текста в эмуляторе терминала;- libudev-devel – набор для разработки библиотек,

получающих информацию об устройствах;- mariadb (mysql) – СУБД для малых и средних

проектов реляционных БД;- mingw – набор библиотек для компиляции для

платформы WIN32;- swi-prolog – свободная реализация языка Prolog.

Далее приведен список программ, используемых всфере информационной безопасности:

- kismet – программное обеспечение для определениянадежности радиосоединений WIFI. Позволяетвыполнять поиск, перехват и вмешательство вфункционирование соединений WIFI;

- wireshark – сетевой анализатор различныхпротоколов с графическим интерфейсом;

- tshark – сетевой анализатор с терминальным

Page 102: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

102

интерфейсом;- nmap – сканер сетевых портов;- snort – автоматический анализатор и блокировщик

сетевых пакетов;- p0f – программа позволяет деанонимизировать

версию ОС, на которой было сформировано сообщение;- whois – программа для работы с протоколом WHOIS

(RFC 3912). Позволяет определять владельцев сетевыхресурсов, их сетевые адреса;

- tor – сеть с «луковичным» шифрованиемсоединений. Позволяет оставаться анонимным в сетиИнтернет при квалифицированном использовании. Еёприменение может быть запрещено на территориинекоторых стран;

- traceroute – программа, определяющаяпромежуточные узлы вычислительной сети и их сетевыеадреса между источником и получателем информации;

- netstat – программа, отображающая все сетевыесоединения, как локальные, так и связывающие сдругими узлами вычислительной сети;

- netcat – программа отправки и получениясообщений по TCP и UDP протоколам.

Приведенное деление программ очень условно. Всеэто программное обеспечение можно на законныхоснованиях БЕСПЛАТНО устанавливать на своихвычислительных машинах без каких-либо ограничений. Вслучае установки платных аналогов, стоимостьпрограммного обеспечения для автора было бы в 40 иболее раз больше стоимости самой вычислительноймашины.

Page 103: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

103

2.3. Эмулятор терминала

При запуске вычислительной машины производитсяпроверка работоспособности её основных компонентов.Далее загружается загрузчик операционной системы,например GNU Grub, и отображается его графическийинтерфейс. С его помощью возможен выбор ОС, еслиустановлено несколько ОС на одну ЭВМ, или выборрежима имеющейся ОС. Один из режимов загрузки-single, не выполняет загрузку графического интерфейсаи производит загрузку одного суперпользователя root. Вэтом режиме загрузка производится в компьютерныйтерминал.

Базовым для понятия компьютерный терминалявляется текстовый пользовательский интерфейс(ТПИ). Этот интерфейс является разновидностьюинтерфейса пользователя и предоставляет возможностьотображения информации и ввода/вывода информации спомощью буквенных, цифровых символов и символовпсевдографики. ТПИ содержит в себе подкласс,называемый интерфейсом командной строки.

Интерфейс командной строки – текстовыйинтерфейс, имитирующий на экране прокручивающуюсябесконечную ленту бумаги, на которую пользовательможет выводить текст вводимых им команд и следом заними получать результаты их работы.

Интерфейс командной строки всегда используется впрограммном обеспечении содержащим сотни и тысячикоманд. Такое количество команд просто невозможноразместить в графическом интерфейсе.

Другая проблема, решаемая интерфейсом команднойстроки, это возможность управлением вычислительнымимашинами с низкопроизводительным микропроцессором,каналом связи или при отсутствии

Page 104: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

104

низкоквалифицированых пользователей. Такимтребованиям удовлетворяют: датчики, встраиваемыеустройства, мобильные устройства, составныекомпоненты персональных вычислительных машин,системы промышленной автоматизации,высокопроизводительные сервера без аппаратногоинтерфейса VGA. Отметим, что серверное оборудование сVGA интерфейсом массово поставляется только в однустрану мира – РФ.

Интерфейс командной строки следует изкомпонентной архитектуры. С помощью дополняющегоего пакетного интерфейса, смысл которого ввозможности создания текстовых файлов сперечислением команд, которые можно исполнить так,как будто их набрал пользователь, он позволяетвыполнять автоматизацию действий.

Кроме того, интерфейс командной строки болееинформативный, из-за отсутствия постоянногоотображения элементов самого интерфейса. Работу в немпроще обсуждать в сообществе, обмениваясь текстовымисообщениями с использованием сети Интернет.

Основные недостатки интерфейсов данного вида –высокие требования к квалификации пользователя иотсутствие возможности управлять вычислительноймашиной путем незначительных изменений положениясвоего тела.

Компьютерный терминал – устройство или наборустройств, используемые для взаимодействия оператораили пользователя с вычислительной системой локальноили удаленно. К одной вычислительной машине можетбыть подключено множество терминалов. Например, призакрузке ОС АльтЛинукс, по умолчанию запускаетсясразу 4 интерфейса коммандной строки, переключениемежду которыми возможно с помощью комбинации

Page 105: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

105

клавиш CTRL+ALT+F1, CTRL+ALT+F2. Для возврата вграфический режим необходимо вернуться в интерфейскоммандной строки 1 или 7 в зависимости от настроекОС. Не путать переключение между интерфейсамикомандной строки и переключениями междуграфическими рабочими столами выполняемое спомощью комбинаций CTRL+F1, CTRL+2 и т.д.

Компьютерный терминал может реализовыватьлюбые интерфейсы, однако первые компьютерныетерминалы могли содержать только интерфейскомандной строки. Из-за этого на сегодняшний деньукоренилось восприятие приведенных выше понятий каксинонимом, что не верно.

Программа, эмулирующая компьютерный терминалвнутри другой архитектуры или другого интерфейса,называется эмулятором терминала (ЭТ).

Использование командного интерпретатора вэмуляторе терминала позволяет выполнятьавтоматизацию действий при вводе любых команд.Наиболее популярным являются версии GNU Bourne-Again SHell, bash и sh, которые немного отличаютсясинтаксисом написания выражений.

Наиболее часто используемыми в практическойдеятельности являются эмулятор терминала икомандный интерпретатор, остальные понятияприведены для понимания разницы между ними.

После загрузки ОС AltLinux с любой графическойплатформой и аутентификации пользователяотображается «Рабочий стол» пользователя. Вызватьтерминал пользователя можно различными способами,например, с помощью пункта Эмулятор терминала вГлавном меню. Также можно выполнить щелчок правойкнопкой мыши на любом свободном участке рабочегостола.

Page 106: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

106

Далее необходимо выбрать пункт меню «OpenTerminal Here» или «Эмулятор терминала».Откроется следующее окно.

Page 107: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

107

Зеленый прямоугольник информирует о том, чтофокус ввода передан эмулятору терминала. При вводесимвола, символ будет отображаться на месте этогопрямоугольника. Если фокус ввода передан в другоеокно, прямоугольник станет черным, окаймленнымзеленой рамкой. В каждой строке ввода командыотображается имя пользователя, отделенное символомамперсанд @. Далее следует сетевое имявычислительной машины, пробел и имя текущегокаталога. Для отображения имени домашнего каталогапользователя используется символ тильда ~.

Введите команду ls /etc и нажмите клавишу Enter.Символы ls — это имя программы, расположенной вкаталоге /bin, которая отображает содержимоекаталогов. Её имя является сокращением от английскогоlist – список. Далее следует пробел и полный путь к папкеetc, которая находится в корневом каталоге. Точку вконце команды ставить нельзя.

Каталог ls содержит множество объектов, поэтомупосле выполнения команды отобразится конец спискаобъектов каталога etc. Для перемещения вверх поотображенному списку используются комбинацииклавиш Shift+PageUp, для перемещения внизShift+PageDown.

В любой момент начните вводить команду exit .Отображение в эмуляторе терминала будет прокрученовниз к области ввода команды. В дальнейшем ввод ипросмотр отображения вывода в эмуляторе терминаластоит осуществлять таким образом.

В эмуляторе терминала есть две программы info иman. Это два формата справочной информации о другихпрограммах. Более популярной является система man,более удобной для пользователя info. Чтобы получитьсправочную информацию о команде ls, необходимо

Page 108: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

108

выполнить командуman lsРассмотрим наиболее часто используемые команды:- pwd – вывод полного пути к текущему каталогу,- ls – вывод списка объектов текущего каталога,- cd – сменить текущий каталог,- echo – отображение строк текста,- mkdir – создание нового каталога,- rmdir – удаление каталога,- touch – изменение метки файла, создание файла

без содержимого в случае его отсутствия,- rm – удаление файла,- cat – отображение содержимого файла,- chmod – смена режима доступа к существующему

объекту ФС,- chown – смена владельца указанного объекта.Приведем решение следующей задачи: необходимо в

домашнем каталоге создать каталог с именем 123, в немфайл z.txt, в который записать текст «Hello» и наследующую строку символы «C!».

1. После запуска программы в эмулятора терминалав открывшемся окне вводится команда

pwd

Эмулятор терминала выведет что-то типа

/home/valerii

2. Вводится команда создания каталога

mkdir 123

Page 109: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

109

т.к. программа выполнена успешно, никакихсообщений выведено не будет. Если произошла ошибка,будет выведено соответствующее ситуации сообщение обошибке.

3. Проверка создания каталога

ls

Вывод программы ls:

123 Desktop Documents Downloads Public

4. Переход в созданный каталог

cd 123

Не должно быть выведено никаких сообщений.

5. Проверка установки текущим правильногокаталога

pwd

Вывод

/home/valerii/123

6. Создание файла

touch z.txt

Сообщений быть не должно.

Page 110: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

110

7. Отображение имени созданного файла

ls

Вывод команды

z.txt

8. Запись в файл z.txt слова Hello

echo Hello > z.txt

Вывода после выполнения команды быть не должно.

9. Отобразим содержимое файла z.txt

cat z.txt

Вывод

Hello

10. Дописать вторую строку с символами C!

echo "C!" >> z.txt

11. Отобразить содержимое файла z.txt

cat z.txt

Вывод

HelloC!

Page 111: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

111

Задание выполнено.

Удалим созданные файл и каталог.1. Удалим файл

rm z.txt

Будет выведено предупреждение

rm: удалить обычный файл 'z.txt'?

Необходимо подтвердить удаление нажатиемклавиши «y».

2. Выйти из каталога 123 на уровень выше.

cd ..

Вывода не будет.3. Удалить пустой каталог 123

rmdir 123

Вывода не будет, т.к. каталог пуст.4. Подтвердить правильность удаления каталога

ls

Вывод

Desktop Documents Downloads Public

Один из парадоксов для начинающего пользователяэмулятора терминала заключается в том, что простые

Page 112: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

112

команды выполнять в эмуляторе терминала дольше, чемв графическом интерфейсе. Однако с повышением уровнявладения этой технологией такие операции станетвыполнять также просто.

Далее приведен пример, как можно выполнитьпоставленную ранее задачу в одну команду:

mkdir 123 && touch 123/z.txt && echo Hello >123/z.txt && echo "C!" >> 123/z.txt

В этом решении использована операция &&, котораясоответствует логическому И. При этом действуетправило: если первое (левое) выражение ложно, второе(правое) никогда не будет выполнено.

Проверить содержимое полученного файла можнокомандой:

cat 123/z.txt

Вывод

HelloC!

Удалить созданные объекты можно командой:

rm -rf 123

Решение задачи можно записать еще короче.

mkdir 123 && touch 123/z.txt && printf 'Hello\nC!\n'>> 123/z.txt

Существуют еще более лаконичные способы решения

Page 113: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

113

этой задачи, но на начальных этапах освоения приемовработы в эмуляторе терминала лучшим являетсяпонятное решение, а не короткое.

В эмуляторе терминала доступны развитые средстваобработки текстовых данных. Например, программа grepпозволяет отфильтровывать строки в соответствии спереданным запросом. Программа sed умеет выполнятьфильтрацию текста и выполнять изменения в нем. Приэтом её синтаксис настолько объемен, что его изучениеможет стать отдельной задачей. Программа joinпозволяет объединять строки из нескольких файлов,являясь по-сути прообразом запроса к табличной базеданных. Программа printf выполняет формирование ипечать (отображение) данных. Программ awk так иназывается «язык обработки и поиска шаблонов».

Несмотря на обширные возможности, применениеэтих программ очень просто на практике и может бытьиспользовано в программах. Например, для замены всехвхождений слова ‘пример’ на ‘привет’ в файле input.txt исохранение результата в файле output.txt, необходимовыполнить команду

sed ‘s/пример/привет/’ input.txt > output.txt

Рассмотрим ряд задач, имеющих практическоезначение. Наиболее часто для архивирования и созданиярезервных копий используются форматы tar, zip, 7z. Ониупоминались в пункте 1.4. Приведем пример созданиясжатого файла из содержимого текущего каталога спомощью программы tar.

tar -cvvf archive.tar ./

Извлечь содержимое из файла archive.tar можно с

Page 114: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

114

помощью команды

tar -xvvf foo.tar

Для формата zip используется следующая командадля создания архива

zip -r archive.zip ./

для извлечения содержимого

unzip archive.zip

Для формата 7-Zip приведен пример архивированиятекущего каталога с заданием пароля для шифрованияинформации.

7z a -pПАРОЛЬ archive.7z

Для извлечения сжатой и зашифрованнойинформации используется команда

7z x archive.7z

Приведем пример использования ЭТ совместно свизуальной оболочкой Midnight Commander дляизменения путей к репозиториям в системе apt, окоторой упоминалось в пункте 2.1.

Выполните в ЭТ команду

mc

Запуск программы приведет к отображению двухпанелей с содержимым текущих каталогов.

Page 115: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

115

Программа имеет интуитивно понятный интерфейс иподдержку манипулятора «мышь». Для перемещения покаталогам используется «мышь» или клавишиклавиатуры стрелка вверх, стрелка вниз, Tab, Enter.

После перехода в каталог /etc/apt/sources.list.dнеобходимо выбрать файл alt.list и нажать на клавиатуреклавишу F4 или щелкнуть левой кнопкой мыши понадписи «Правка».

Page 116: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

116

Работа в окне запущенного текстового редакторамало чем отличается от программы Блокнот в ОСWindowsTM. Для добавления дополнительногорепозитория необходимо удалить символ «#» в началестроки. Для комментирования, наоборот, нужно добавитьэтот символ в начало строки. После внесения измененийв файл, для их сохранения необходимо нажать клавишуF2 или щелкнуть мышью по надписи “Сох~ть” внизуэкрана. Для выхода из текстового редактораиспользуется F10 или щелчок левой кнопки мыши понадписи «Выход».

Page 117: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

117

2.4. Текстовый редактор VIM

Для создания текстовых файлов с исходным текстомпрограмм необходим текстовый редактор. Вдистрибутиве АльтЛинукс возможно использованиеразличных текстовых редакторов и интегрированныхсред программирования. Среди интегрированных средпрограммирования стоит выделить KDevelop иQTCreator. Менее требовательной к ресурсам являетсясреда разработки Geany. В случае невозможностииспользования средств разработки необходимовоспользоваться обычным текстовым редактором. Прииспользовании платформ (QT, Gnome, XFCE) сграфическим интерфейсом доступны medit, leafpad. ВMidnight Commander встроен собственный текстовыйредактор, работа с которым была продемонстрирована впункте 2.3.

Особенно следует выделить два текстовых редактораemacs и vim. Emasc является продуктом основателядвижения GNU и уже давно приобрел статус культовогопродукта. Это очень сложная в освоении программа,требующая много времени на настройку и установкуплагинов. Vim является наследником программы vi,которая поставляется со всеми версиями POSIX систем,начиная с 1976 года. Несмотря на прошедшее время ивысокого уровня интеграции ПО, при разработке на Cпостоянно случаются ситуации, самым простым выходомиз которых является использование редактора vi или vim.

Для пользователя, имеющего опыт работы только стекстовыми редакторами в графических средах, первоевремя работать с vi или vim сложно. Это связано с тем,что такая работа требует запоминания текущегосостояния программы в каждый момент времени. Вграфическом режиме для этого используются

Page 118: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

118

подсвеченные кнопки, подсказки, выделение цветом изапоминать состояние программы не требуется.Программы имеют два режима ввода: командный итекстовый. В командном режиме нажатие клавиш наклавиатуре приводит к изменению состояния программыи исполнению команд, соответствующих нажатымклавишам. В текстовом режиме производится вставкасимволов. Редакторы имеют большое количество«горячих клавиш», которые выполняют действия, редкодоступные в графических текстовых редакторах:удаление строки, переход на начало или конец абзаца идр. Для переключения между режимами используетсяклавиша Esc. Со времен использования vim навычислительных машинах, оснащенных системнымдинамиком, существует шутка о том, что vim работает вдвух режимах: в одном пищит, в другом портит текст.

Редакторы vi и vim имеют одинаковые комбинации«горячих клавиш» и логику работы, но vim болеефункционален и имеет ряд нужных возможностей,отсутствующих в vi. Целесообразно сначала проверятьналичие в системе именно vim и только в случае егоотсутствия использовать vi. Далее будет рассматриватьсяредактор vim без дополнительных плагинов. Послезапуска командой vim выводится сообщение и текстовыйредактор переводится в режим ввода команд.

vim

командный текстовый

Esc

Page 119: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

119

Для завершения работы с программой безсохранения сделанных изменений необходимо выполнитьследующие действия:

1. ввести символ «:»2. ввести символы «q!»3. нажать EnterПосле этих действий работа с редактором будет

завершена.Программа умеет редактировать также и двоичные

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

Page 120: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

120

Запуск программы с открытием двоичного файлаграфического изображения в формате JPEG

vim -b 0010.jpeg

После запуска программа переведена в режим вводатекста. Необходимо нажать клавишу a. Удалив несколькосимволов, необходимо закончить работу без сохранениявнесенных изменений с помощью действий, описанныхвыше.

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

В командах vim часто используются специальныесимволы, поэтому последовательности команд будутзаключены в скобки, т. е. нажатие клавиши q будетобозначаться как (q).

Программа vim использует терминологию, несколькоотличную от общепринятой. Приведем главные понятия:

- буфер – временное хранилище текста, копияотображаемого или редактируемого файла. Каждыйредактируемый файл связан с единственным буфером, нокаждый буфер может отображаться в неограниченномколичестве окон;

- окно – область экрана для просмотра иотображения одного буфера;

- вкладки (сленг. табы) – механизм группировки ипереключения между группами окон;

- регистр по умолчанию – наименованноехранилище текста для множественных вставок,наподобие «буфера обмена» в офисных пакетах;

- именованный регистр – именованное хранилищетекста для множественных вставок. Также напоминает

Page 121: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

121

один из режимов работы «буфера обмена» в офисныхпакетах;

- аббревиатуры – сокращения, которые при набореотдельных слов путем замены разворачиваются всоответствующий текст;

- изменение – включает в себя вставку текста изрегистра, аналог команды «вставка» в графическомтекстовом редакторе.

Для получения исчерпывающей справочнойинформации необходимо после запуска программыввести команду (:help). Для получения справки поконкретной команде (:help W).

При открытии файлов с исходными текстамипрограммы возможно изменение режима отображениятекста редактором, путем добавления номера строки вфайле. Для этого используются команды:

- (:set number) — отображать номер строки;- (:set nonumber) — перестать отображать номер

строки.Для того чтобы номер строки отображался всегда,

необходимо в домашнем каталоге пользователя в файле~/.vimrc добавить строку

set numberВ случае отсутствия файла ~/.vimrc его необходимо

создать.При открытии файла с текстом возможно как

открытие на определенной строке с помощью командыvim +5 filenameгде 5 — номер строки, на которую необходимо

переместиться, filename — имя открываемого файла.При открытии файла присутствует возможность

перехода на искомую строку с использованиемтекстового шаблона

Page 122: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

122

vim +/main filename

где main — название искомой функции, filename —имя файла.

Редактор vim имеет множество командперемещения, часть из которых не встречается воконных редакторах. Для перемещения используетсякомандный режим. Перемещение на один символпроизводится расположенными по порядку клавишами←h ↓j ↑k →l. Кнопки — стрелочки позволяютперемещаться в окне. Присутствует поддержкаманипулятора «мышь».

Кроме перемещения на один символ возможныследующие варианты перемещения:

- на конец текущего слова вправо (w) или влево (b);- на следующее слово вправо (W) или влево (B);- в конец следующего слова (E);- на начало (^) или конец строки ($);- на начало текущего предложения ()) или его конец

(();- на начало текущего абзаца ({) или его конец (});- на первую строку на экране (H) или на последнюю

(L);- переместится в конец текущего отображения

буфера (G);- на первое вхождение произвольного символа (fv –

переход на первый символ v в строке);- повторить последнюю команду поиска в пределах

текущей строки (;).Почти все команды перемещения могут быть

повторены произвольное количество раз. Например, 5jпереведет курсор на 5 строк вверх, а 3} — на три абзацавниз. Этот способ повторения выполнения командыдоступен для большинства команд других типов.

Page 123: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

123

Рассмотрение команд изменения текста начнетсяс команды (u) – отмена последнего действия. Наборкоманд редактирования наиболее удобен для написанияисходного кода программы или для редактированияконфигурационного файла и также содержит команды,не встречающиеся в графических текстовых редакторах.Далее приведены команды редактирования текста:

- если vim запущен в ЭТ, вставка из буфера обменаОС (ctrl+chift+v);

- редактирование одного текущего символа (r);- вставить символы с позиции курсора, заменив

текущий символ под курсором (i);- добавить текст, начиная с позиции курсора (a);- заменить текст с начала строки (I);- вставить строку до текущей и приступить к её

редактированию (O);- вставить строку после текущей и приступить к её

редактированию (o);- удалить текущий символ (d);- удалить текущее слово (daw);- удалить текущую строку (dd). Команда, удаляющая

10 строк 10dd;- удалить символы, начиная от курсора до конца

строки (D);- (*) - выделить текущее слово;- (/y клавиша Enter) – подсветит все вхождения

символа y в текущем окне. Перемещаться междувыделенными символами можно с помощью клавиш N иn;

- (y) – копирование в регистр по умолчаниювыделенного текста;

- (yy) или (Y) - копирование всей строки в регистр поумолчанию;

- (v) – режим «визуального выделения». До нажатия

Page 124: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

124

клавиши необходимо установить курсор в началокопирования, затем нажать клавишу v, далее,перемещаясь по тексту, выделить необходимый фрагменттекста и нажать клавишу (y);

- (/шаблон) — поиск последовательности символовшаблон;

- (p) – вставка текста из регистра по умолчанию;- (%s/шаблон/замена) – заменяет все вхождения

слова шаблон на слово замена.Несмотря на то, что программа vim не имеет

графического интерфейса, она способна отображатьодновременно буферы нескольких файлов. Команда vim-o filename1 filename2 откроет два файла, разделенныхпо горизонтали. Команда vim -O filename1 filename2откроет эти же файлы, разделенные по вертикали.

- (:tabs) – просмотр всех открытых буферов;- (:n) – переход на предыдущую вкладку;- (:N) – переход на следующую вкладку;Кроме буферов, vim оперирует понятием вкладки.

Команда vim -p10 откроет 10 пустых вкладок.Максимальное количество открываемых вкладок поумолчанию 10, однако может настраиваться с помощьюфайла конфигурации. Открытие нескольких файлов вовкладки выполняется командой vim -p filename0filename1 filename2. Для переключения междувкладками используются команды:

- (:tabs) – просмотр всех открытых вкладок;- (:tabn) – переход на предыдущую вкладку;- (:tabp) – переход на следующую вкладку;- (:tabfirst) – переход на первую вкладку;- (:tablast) – переход на конечную вкладку;- (:tabm 2) – переход на третью вкладку, потому что

нумерация вкладок начинается с 0.Программа vim способна выполнять сравнение

Page 125: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

125

файлов и выделять отличия цветом. При этом возможноодновременное сравнение двух и более файлов.Например, для сравнения трех файлов необходимовыполнить команду vim -d filename1 filename2filename3. После этого они будут открыты с разделениемпо горизонтали и подсветкой отличий друг от друга.

Запуск vim с ключом -x, например так, vim -xfilename приведет к запросу пароля и егоподтверждения, после чего при сохранении будетвыполнено шифрование файла.

Для ежедневного использования возможноиспользование графического режима редактора vim (vim-g). Этот режим требует указания специального ключа наэтапе компиляции и сборки программы vim.

Поддержка плагинов позволяет vim полноценнозаменять среду разработки программного обеспечения.Перечислим некоторые плагины, облегчающиеразработку исходных кодов программ:

- vundle – устанавливает плагины с github.com ;- neocomplcache – автоподсказки и автозавершение

кода;- nerd tree – навигация по файлам и каталогам,

позволяет открыть просмотрщик файлов командойNERDTree;

- nerd commenter – упрощает добавлениякомментариев в исходный код программы;

- ctrlp – выполняет поиск файла по названию. Дляисполнения необходимо нажать комбинацию клавишctrl+p и набрать имя файла;

- vim airline – повышение наглядности с помощьюстроки статуса программы vim;

- taglist – позволяет просматривать структурупрограммных файлов, список функций и прочуюинформацию;

Page 126: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

126

- supertab – автодополнение слов нажатием клавишиtab;

- project – позволяет организовывать файлы в проекты.

Использование редактора Vim в качестве основногоинструмента поднимает престиж программиста средиразработчиков, дает гибкий инструмент для созданияпрограмм с минимальным потреблением ресурсов.

Редактор vim можно использовать дляформатирования текстовых файлов как стороннююпрограмму.

Пример изменения кодировки в текстовом файле.Открыть файл filename в программе vim.

vim filename

Изменить кодировку для отображения имеющегосясодержимого файла.

:e ++enc=cp1251

Изменить кодировку текста открытого файла.

:set fileencoding=utf-8

Задать формат последовательности перехода нановую строку (доступные значения dos, unix, mac).

:set fileformat=unix

Сохранение файла в новой кодировке.

:wq

Page 127: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

127

Текстовый редактор vim являетсяполнофункциональным редактором с большим наборомфункций. Команды vim имеют как полные, так исокращенные формы записи. Обычно изучениевозможностей vim происходит в процессе работы с ним.

Page 128: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

128

2.5. Диагностические утилиты

Команды, доступные в ЭТ, позволяют винтерактивном режиме получать информацию обаппаратном обеспечении вычислительной машины, атакже о версиях и настройках ОС и программ. Если послеввода команды получен ответ об отсутствии такойпрограммы, необходимо выполнить её установку Дляпрограммы blkid команда установки имеет вид

apt-get install blkid

Для получения информации о микропроцессорах,установленных в системе, используется команда ЭТ

cat /proc/cpuinfo

Команда выводит 26 параметров каждогомикропроцессора. Для просмотра определенногопараметра необходимо скомбинировать представленнуюкоманду с командой grep. Для получения информации омодели микропроцессора можно использовать команду

cat /proc/cpuinfo | grep ‘model name’

Выполнение указанной команды на вычислительноймашине, на которой производился набор текста данногопункта книги, привело к следующему выводу:

model name : Intel(R) Celeron(R) 2955U @ 1.40GHzmodel name : Intel(R) Celeron(R) 2955U @ 1.40GHz

Таким образом, вычислительная машина оснащенадвумя физическими ядрами модели Intel(R) Celeron(R)

Page 129: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

129

2955U @ 1.40GHz. В приведенном выше примере, потоквывода команды cat, которая выводит содержимоепсевдофайла cpuinfo файловой системы proc, с помощьюсимвола | передается в поток ввода команды grep,которая выводит строки, содержащие строку ‘modelname’, а остальные отбрасывает.

Для получения информации об известных серьезныхуязвимостях аппаратного уровня микропроцессоранеобходимо выполнить команду

cat /proc/cpuinfo | grep 'bugs'

bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass

bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass

Приведенный вывод команды показывает на то, чтомикропроцессоры обладают серьезными уязвимостями нааппаратном уровне и негодны для хранения информации,составляющей государственную тайну или другиекритические данные, но вполне подходят для наборатекста, участия в сообществах разработчиков имножества других задач.

Для получения информации о материнской платеиспользуется команда

dmidecode --type baseboard

Для выполнения этой команды необходимо обладатьпривилегиями суперпользователя, т.е. выполнитькоманду su – и ввести пароль администратора root.Также возможно использование команды sudo, однаковозможность её использования зависит от настройки

Page 130: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

130

конкретного текущего пользователя. После выполнениякоманды получения информации о материнской платевозможно ознакомление с информацией о производителе,модели, версии и её серийным номером. Также доступнаинформация о наличии интегрированных платдополнения, таких как сетевая плата или видеокарта.Комбинируя команду с утилитой grep, можно получитьинформацию по одному требуемому параметру.

Команда

dmidecode --type baseboard | grep Manufacturer

отображает информацию о производителематеринской платы

Manufacturer: Packard Bell

а команда

dmidecode --type baseboard | grep -e 'Product Name' -e'Serial Number'

выводит информацию только о модели материнскойплаты и её серийный номер

Product Name: EG50_HWSerial Number: NBNAZ12040031713033111

В приведенном примере команда grep принимаетсразу два шаблона для фильтрации и выводит на экранстроки как с символами «Product Name», так и ссимволами «Serial Number».

Для получения информации об установленныхпланках ОЗУ в слоты материнской платы необходимо

Page 131: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

131

выполнить команду

dmidecode --type 17 | more

Поток вывода команды dmidecode передается напоток ввода команды more, которая выводит информациювысотой в один экран ЭТ и ждет нажатия клавишипробел для продолжения вывода или q для завершениявывода.

Следует обратить внимание! Команда dmidecode невсегда выводит корректную информацию об аппаратномобеспечении ОЗУ.

Для определения типа микросхем ОЗУ используетсякоманда

dmidecode --type 17 | grep "Type:"

вывод

Type: DDR3Type: DDR3

Для определения количества свободных слотов дляпланок памяти ОЗУ используется команда

dmidecode --type 17 | grep "No Module Installed" | wc -l

В приведенной команде в дополнение кперенаправлению потока вывода dmidecode в поток вводаgrep, поток вывода grep перенаправляется в поток вводаwc. Программа wc может выполнять подсчет количествастрок, слов и символов в файлах и данных, полученныхчерез поток ввода.

Не весь объем памяти ОЗУ может быть доступен по

Page 132: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

132

причине выхода из строя аппаратного обеспечения илиневерной настройки ОС. Информация об объемефактически доступной ОЗУ получается с помощьюкоманды

cat /proc/meminfo | grep -e MemTotal -e MemFree

её вывод

MemTotal: 10109896 kBMemFree: 8194740 kB

Особенность приведенной команды в отсутствиикавычек в параметрах команды grep. Они отсутствуют,так как передаваемые шаблоны для поиска не имеютпробелов или других разделительных символов.

Информация о распределении прерываний несчитается критически важной для пользователявычислительной машины, но в некоторых случаяхнеправильное распределение прерываний приводит внекоторых режимах к замедлению работывычислительной машины. Для получения информации опрерываниях используется команда.

cat /proc/interrupts

Немного подробнее о концепции прерыванийнаписано в пункте 1.3.

Информация об установленных платах расширенийдоступна с помощью команды lspci. Она выводитинформацию об установленных видеокартах, сетевыхплатах, USB, ISA, SATA контроллерах и прочее.Например, для получения информации обинтегрированной видеокарте необходимо выполнить

Page 133: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

133

команду

lspci | grep VGA

пример вывода которой приведен ниже

00:02.0 VGA compatible controller: Intel CorporationHaswell-ULT Integrated Graphics Controller (rev 0b)

Информация об устройствах, использующихинтерфейс USB, доступна с помощью команды

lsusb

которая выводит общую информацию об устройствах,например

Bus 001 Device 002: ID 8087:8000 Intel Corp.

Добавление ключа к команде следующим образомlsusb -t выводит информацию об устройствах в видедревовидного списка.

Для получения подробной информации используетсякоманда

usb-devices

Далее рассмотрено получение информации обустановленных накопителях информации, в том числежестких дисках. Узнать, какие накопители подключены вОС, можно с помощью команды

lsblk

Page 134: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

134

она предоставляет информацию в наглядном виде спомощью символов псевдографики

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 223,6G 0 disk ├─sda1 8:1 0 49,2G 0 part /└─sda2 8:2 0 174,4G 0 part /homesdb 8:16 0 119,2G 0 disk └─sdb1 8:17 0 119,1G 0 part

В соответствии с выводом программы lsblkвычислительная машина оснащена двумя накопителями,способными сохранять 223,6 Гб и 119,2 Гб. Такжеуказаны точки монтирования. Для раздела sda1 точкоймонтирования является корневой каталог /, а для разделаsda2 точка монтирования /home . При каждой установкеОС или в процессе её эксплуатации ОС точкимонтирования и набор разделов может меняться. Болееподробную информацию о разделах выведет командаblkid .

Информацию о доступных разделах на носителяхинформации также можно получить с помощью команды

fdisk -l

в конце вывода команды будут примерно такиестроки

Устр-во начало Конец Секторы РазмерТип

/dev/sda1 2048 103151615 103149568 49,2GФайл.система Linux

Для получения информации по технологии S.M.A.R.T.

Page 135: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

135

используется программа smartctl . Для получениякраткой справки по работе с программой используетсяключ -h .

Узнать модель накопителя можно с помощьюкоманды

smartctl -i /dev/sda

Указанная команда отобразит модель устройства,серийный номер, версию прошивки устройства и прочуюинформацию.

Для получения всей информации об устройствеиспользуется команда

smartctl --all /dev/sda

В случае отсутствия поддержки технологииS.M.A.R.T. выведенные значения будут не корректными.

Важной задачей с точки зрения обслуживаниявычислительной машины является проверкатемпературы основных компонентов. Для определениятемпературы, сообщаемой сенсором центральногопроцессора, используется команда

acpi -t

Также можно использовать команду

sensors

пример вывода

coretemp-isa-0000Adapter: ISA adapter

Page 136: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

136

Package id 0: +46.0°C (high = +100.0°C, crit =+100.0°C)

Core 0: +42.0°C (high = +100.0°C, crit =+100.0°C)

Core 1: +40.0°C (high = +100.0°C, crit =+100.0°C)

Для определения температуры накопителейинформации используется команда hddtemp, применитьеё можно, например, так hddtemp /dev/sda . Программавыдаст шуточный комментарий и отобразит полученноезначение

/dev/sda: SSD Smartbuy 240GB #�: 30°Cили °F

или так

/dev/sdb: OCZ-AGILITY4 #�: нетдатчика

В процессе загрузки и работы вычислительногоустройства ОС ведет протоколирование основныхдействий с аппаратным обеспечением на уровне ядра.Доступ к этим записям можно получить с помощьюкоманды dmesg. Например, чтобы получить записи осетевом интерфейсе eth0, необходимо выполнитькоманду

dmesg | grep eth0

которая выведет следующие сообщения

[ 4.324760] tg3 0000:01:00.0 eth0: Tigon3

Page 137: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

137

[partno(BCM57786) rev 57766001] (PCI Express) MACaddress 20:1a:06:76:04:a2

[ 4.324764] tg3 0000:01:00.0 eth0: attached PHY is57765 (10/100/1000Base-T Ethernet) (WireSpeed[1],EEE[1])

[ 4.324766] tg3 0000:01:00.0 eth0: RXcsums[1]LinkChgREG[0] MIirq[0] ASF[0] TSOcap[1]

[ 4.324768] tg3 0000:01:00.0 eth0:dma_rwctrl[00000001] dma_mask[64-bit]

[ 5.349252] IPv6: ADDRCONF(NETDEV_UP): eth0:link is not ready

[ 5.520883] IPv6: ADDRCONF(NETDEV_UP): eth0:link is not ready

Для целей аппаратной автоматизации илиподключения датчиков одним из популярныхинтерфейсов остается последовательная шина (Serial) иинтерфейс UART. Для работы с устройствами,подключаемыми с помощью неё, основнымиинструментами являются setserial , stty и minicom.После установки вызов программы minicom выполняетсяследующим образом minicom -s . Более подробнуюинформацию необходимо искать в литературе,посвященной этим интерфейсам.

Для определения доступных разрешений экранаиспользуется команда xrandr . Кроме разрешенийэкрана она выводит состояние интерфейсов,поддерживаемых микропроцессором видеокарты.Следует учесть, что не все выводы могут присутствоватьфизически, т.к. производители могут сокращать ихколичество с целью уменьшения стоимости конечногоизделия, отсутствия необходимого физическогопространства или по другим причинам.

Кроме вывода конфигурационной информации xrandr

Page 138: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

138

также может поворачивать изображение вправо иливлево, например xrandr -o left или вернуть его внормальное положение xrandr -o normal .

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

xset led 3 – включает подсветку клавиатуры.xset -led 3 – выключает подсветку клавиатуры.В заключении раздела приведем несколько приемов

работы, которые значительно проще реализовать спомощью ЭТ.

С целью сохранения важной информации желательнопериодически выполнять затирание всей поверхностиносителя информации. Для некоторых типов устройствзаполнение нулями не является гарантией от стиранияинформации. Жесткие диски могут сохранять остаткиинформации на своих дисках до 7 и более цикловперезаписи, однако для бытовых целей достаточно иоднократной перезаписи носителя информации.Используя программу dd, перезапись поверхностиносителя информации sda можно осуществить выполнивследующую команду

dd if=/dev/urandom of=/dev/sda

Приведенная команда предписывает утилите ddполучать информацию от псевдоустройства /dev/urandom,являющегося программным генератором случайныхчисел, и записывать случайные значения в устройство/dev/sda до исчерпания свободного пространстваустройства /dev/sda. После перезаписи устройства такимобразом, его необходимо заново подготовить к работе сОС, выполнив разбивку на логические разделы. Для этогоиспользуются программы fdisk, cfdisk или программа с

Page 139: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

139

графическим интерфейсом gparted.Пользователи, начинающие знакомиться с ОС

Линукс, часто параллельно используют несколько ОС.Если для выбора загрузки ОС используется загрузчикgrub и по какой-то причине загрузка в ОС, отличная отЛинукс, не производится, достаточно выполнить командуupdate-grub в ЭТ с привилегиями суперпользователя.Команда обновит список доступных для загрузки ОС и ихконфигурации.

Для настройки аппаратного счетчика временииспользуется программа hwclock. Время, используемое вОС, можно посмотреть и изменить с помощью программыdate. Для отображения календаря на текущий месяциспользуется команда cal, а чтобы посмотреть календарьза 2000 год, необходимо использовать команду cal -y2000.

Для задания временной зоны и аппаратного временинеобходимо обладать правами root.

Примеры приемов работы с hwclock:- hwclock –set ln /…./Moscow /etc/localtime –

задание временной зоны;- hwclock -r узнать аппаратное время;- hwclock --systohc –utc — синхронизация

аппаратного времени с utc;- hwclock --systohc — синхронизировать аппаратное

время с системным;- hwclock --hctosys — синхронизировать системное

время с аппаратным.Хранение информации на оптических дисках сегодня

используется достаточно редко. Однако привозникновении такой потребности все операции можнопровести с помощью программ genisoimage и wodim.

Для просмотра списка устройств выполняющихзапись оптических дисков и информации об их

Page 140: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

140

совместимости со стандартами MMC, используетсякоманда

wodim -prcap

Просмотр списка устройств на шинах SCSI и IDE, ихмодели и точек монтирования используется команда

wodim --devices

Для открытия или закрытия лотка оптического дискаиспользуются команды:

- открытие лотка

eject

- закрытие лотка

eject -t

Полезная информация о настройке ОС доступна при вызове команды

ulimit -a

Page 141: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

141

2.6. Диагностические сетевые утилиты. Сетевые службы

По сравнению с 1976 годом, когда появилась перваяреализация стека TCP/IP, простота настройки сетевыхсоединений значительно повысилась. Обычноконфигурирование установленных сетевых картпроизводится в процессе установки ОС. Для полученияпервоначальной информации о конфигурации сетевыхустройств и подключений используется конфигураторсетевых соединений программа ifconfig.

Выполнение команды ifconfig -a в ЭТ приведет котображению основной информации об имеющихсяинтерфейсах. Для перечисления доступных интерфейсовиспользуется команда ifconfig -a | grep Link . Выводэтой команды представлен ниже:

eth0 Link encap:Ethernet HWaddr 24:8С:80:26:19:С0

lo Link encap:Local Loopbackwlan0 Link encap:Ethernet HWaddr

12:20:A3:F3:A1:09

В соответствии с выводом программы,вычислительная машина имеет три сетевых интерфейса.eth0 – интерфейс, связанный с сетевой картой,передающей данные по 8P8C, т.е. по витой паре. Приналичии двух таких сетевых карт, второй интерфейс имелбы обозначение eth1 и т.д. Следующий интерфейс lo. Егообозначение является сокращением от loopback, т.е.кольцо. Он имеет связь только с одним сетевым адресом127.0.0.1 и служит для обмена информацией междупроцессами внутри одной вычислительной машины, а

Page 142: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

142

также для отладки сетевых приложений на этапе ихнаписания. Данный интерфейс не имеет аппаратнойреализации и реализован с помощью центральногомикропроцессора и ОЗУ, поэтому скорость его работысопоставима с работой с каналами и другими приемамимежпроцессовых взаимодействий. Обозначение wlan0соответствует сетевому соединению по одному избеспроводных интерфейсов (WIFI).

Для получения подробной информации осоединениях WIFI, используется программа iwconfig .

wlan0 IEEE 802.11 ESSID:off/any Mode:Managed Access Point: Not-Associated

Tx-Power=off Retry short limit:7 RTS thr:off Fragment thr:off Encryption key:off Power Management:off

Пакет для работы с wifi в ЭТ называется wireless-tools. В него входят такие программы как iwlist дляполучения информации о соединении и iwspy для сборастатистики по конкретному узлу, использующемубеспроводную сеть.

Отдельным классом сетевых интерфейсов являетсяBluethoot. Он занимает промежуточное место междуаппаратными интерфейсами наподобие стекаинтерфейсов USB и беспроводными интерфейсами WIFI.Его соединения не отображаются совместно суниверсальными сетевыми интерфейсами, т.к. основноеего назначение обмен информацией с устройствами,находящимися в непосредственной близости.Конфигуратором bluethoot устройств является программаhciconfig , которую необходимо устанавливатьдополнительно.

Page 143: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

143

Для взаимодействия между конечнойвычислительной машиной и устройством маршрутизацииили сервером используются уникальные физическиеадреса сетевых устройств, MAC – адреса (Hwaddr – вприведенном выше выводе). Однако на сегодняшниймомент часть производителей позволяет произвольноменять MAC – адрес в соответствии с потребностямипользователя. При изменении MAC — адреса необходимоотслеживать его уникальность в пределах подсети допервого маршрутизатора.

Для обмена информацией в разных подсетяхиспользуется сетевой адрес или IP. Его уникальностьможет обеспечиваться специальными технологиями,например NAT. Технология NAT подменяет IP адресавычислительных машин, маршрутизацию которых онаобеспечивает, на связку из собственного IP адреса иномера порта. Получая данные из сети на определенныйномер порта, устройство с NAT, используя свои таблицысоответствий, пересылает данные адресату с внутреннимIP адресом.

При подключении к вычислительной сетиавтоматическое получение IP адреса и других настроекобеспечивает технология DHCP. Принцип работы этойтехнологии заключается в том, что при включениивычислительного устройства в сеть, устройствопроизводит широковещательную рассылку сообщенияспециального формата. В ответ на это сообщение DHCP –сервер высылает конфигурационную информацию,содержащую сетевой адрес, маску сети.

В случае необходимости получения доступа кподсетям с несколькими масками сети с помощью одногоинтерфейса используется следующая команда

ifconfig eth0:0 192.168.12.89 up

Page 144: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

144

Команда предписывает к интерфейсу eth0 добавитьпсевдоним eth0:0, который использует сетевой адрес192.168.12.89, соответствующий сетевой маске255.255.255.0 и подсети 192.168.12.0. При этомосновной сетевой адрес, сетевая маска и подсеть можетбыть любым другим.

Защиту от нежелательных подключенийобеспечивают программы фильтрации сетевых пакетов,часто называемые файерволы. Наиболее популярнойпрограммой является iptable. Он имеет сложный языкнастройки. Неправильно составленные правила iptableмогут сильно замедлить работу сетевых интерфейсов илизаблокировать работу системных программ,обеспечивающих базовую функциональность. Приведемпример открытия порта 80, который по умолчаниюиспользуется для передачи данных по протоколу http.Для этого необходимо выполнить ряд действий.

1. Выполнить команду добавления нового правила фильтрации

iptables -I INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT

2. Сохранить внесенные изменения

service iptables save

3. Перезагрузить iptables

/etc/init.d/iptables restart

Для просмотра открытых портов используется команда

Page 145: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

145

iptables --line-numbers -n -L

Для получения статистики сетевых подключенийиспользуется программа netstat. Программа привыполнении отправляет в поток вывода от десятка досотен строк, поэтому её вывод здесь представлен небудет. Список всех открытых портов TCP можно получитьс помощью команды netstat -at . Для просмотраоткрытых портов по протоколу UDP netstat -au . Списоктолько прослушиваемых TCP портов netstat -lt . Списоквсех открытых портов netstat -s . Для отображениясписка открытых портов с указанием процессов, которыеих используют netstat -p .

Для получение информации о сетевых соединенияхтакже может использоваться еще одна программа ss. Дляотображения списка процессов с открытымисоединениями с помощью этой программы используетсякоманда ss -p . Команда отображения списка сокетов дляпрослушивания ss -l .

Программа отображения списка открытых файловlsof также отображает список сетевых соединений. Дляотображения всех сетевых соединений используетсякоманда lsof -i , а для отображения списка процессов,работающих с портом 80, используется команда lsof -i :80 .

В некоторых случаях возникает необходимостьиспользовать одно подключение для обменаинформацией с устройствами, находящимися в разныхподсетях и имеющих несовместимую маску подсети.

В больших компьютерных сетях часто используютсяпрокси-сервера, работа которых напоминает действияDHCP-серверов. Кроме того, прокси-сервера могутвыполнять фильтрацию сетевых соединений, отбрасывая

Page 146: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

146

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

export http_proxy='http://192.168.12.1:3128'

Команда создает переменную окружения http_proxy,которая содержит сетевой адрес и порт прокси-сервера.Для указания имени пользователя и пароля используетсяследующая конструкция команды

exporthttp_proxy='http://USERNAME:PASSWORD@PROXY_IP:PROXY_PORT/'

гдеUSERNAME – имя пользователя среди учетных

записей пользователей прокси-сервера.PASSWORD – пароль пользователя,

соответствующий имени пользователя.PROXY_IP – сетевой адрес прокси-сервера.PROXY_PORT – порт прокси-сервера, который

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

Созданная таким образом переменная окружениябудет существовать только в ЭТ, в котором выполненакоманда. При повторном открытии терминала,необходимо повторно выполнить команду. Командуможно дополнить вызовом ЭТ, поместить в текстовыйфайл, изменить расширение файла на sh и дополнить егоправа правом на исполнение. Существуют и другиеспособы задания переменных окружения по умолчанию.

Для проверки доступности любого другого сетевого

Page 147: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

147

устройства существует утилита для выполнения эхо-запросов ping. Эхо-запросы описаны ранее в пункте 1.8.Необходимо учесть, утилиты, подобные ping, существуютдля большинства протоколов, однако их название можетнемного отличаться. Приведем вывод команды ping127.0.0.1 -c 2 . Ключ -с 2 указывает программе онеобходимости отправить 2 запроса.

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.045

ms64 bytes from 127.0.0.1: icmp_req=2 ttl=64 time=0.049

ms

--- 127.0.0.1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time

1052msrtt min/avg/max/mdev = 0.045/0.047/0.049/0.002 ms

После информации о результатах каждого запросавыводится общая статистика о выполненных эхо-запросах.

Программа ping отправляет запросы с небольшиминтервалом, однако, если добавить ключ -f , интервалбудет равен 0, что может идентифицироваться сетевымиустройствами как флуд-атака. В результате источникможет быть заблокирован или ограничен в привилегиях.Ключ -f доступен только для пользователей спривилегиями администратора вычислительной машины.

Для получения информации о промежуточных узлахвычислительной сети используется утилита traceroute,которая формирует сообщения ICMP протокола с типом11 и постоянно увеличивающимся числом переходов TTL.В соответствии с протоколом IP, в случае отбрасывания

Page 148: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

148

пакета из-за обнуления поля TTL, промежуточный узелдолжен отправить обратный пакет с сообщением обуничтожении пакета. Таким образом, отправивсообщение с TTL=1, источник узнает сетевой адресследующего за ним в сетевом узле. Сообщение с TTL=2приводит к получению сетевого адреса второгопромежуточного узла и т.д. Следует учитывать, что нанекоторых узлах службы протокола ICMP могут бытьотключены. Также замечено, сетевой трафик,попадающий в РФ, лишается большей части служебнойинформации. Это легко проверить, выполнив запросы стерритории РФ и такие же запросы с территории странНАТО.

Для сбора пересылаемой и получаемой информациииспользуется программа tcpdump. Работа с нейпроизводится с привелегиями администраторавычислительной машины. Для просмотра интерфейсов,доступных для сбора информации, используется командаtcpdump -D . Далее приведен вывод этой команды.

1.eth02.any (Pseudo-device that captures on all interfaces)3.lo

Для сбора всех пересылаемых пакетов черезинтерфейс eth0 используется команда tcpdump -i eth0 .Если необходимо собрать максимальное количествоинформации, используется команда tcpdump -v -i eth0 .Данные, переданные через сетевые интерфейсы ипредставленные в текстовом виде, генерируютзначительные объемы информации, которыепроскакивают по экрану бесконечным потоком. Одно изрешений этой проблемы — запись потока в файл дляпоследующего анализа tcpdump -i eth0 -w file.txt .

Page 149: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

149

Просмотр собранной информации удобно производить спомощью этой же утилиты, выполнив команду tcpdump-r file.txt .

Для непосредственного наблюдения сетевойактивности необходимо выполнять предварительнуюфильтрацию поступающей информации. Далееприведены примеры фильтрации:

- tcpdump -i eth0 ip dst 127.0.0.1 - просмотрпакетов от одного ip;

- tcpdump -i eth0 ip src 127.0.0.1 - просмотротправляемых пакетов;

- tcpdump -vv -i eth0 port 514 - дампированиепорта;

- tcpdump -vvv -i eth0 udp - дампированиеинформации, передаваемой по протоколу UDP;

- tcpdump -i eth0 net 192.168.1.1 - дампированиепакетов подсети;

- tcpdump -i eth0 less 50 - дампирование пакетовинтерфейса размером менее 50 бит;

- tcpdump -i eth0 greater 100 – дампированиепакетов больше 100 бит;

- tcpdump -A -i eth0 - просмотр содержимогопакетов;

- tcpdump host name – просмотр отправляемых иполучаемых пакетов между источником и узлом name;

- tcpdump ip host name2 and not name – просмотрвсех пакетов между узлом name2 и всеми другимиузлами за исключением узла name;

- tcpdump udp and not src net localnet –отслеживать UDP-пакеты, приходящие от узлов ссетевыми адресами, не соответствующими локальноймаски сети.

Более гибким и наглядным инструментом сбораинформации о сетевой активности является программа

Page 150: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

150

Wireshark или её аналог без графического интерфейсаtshark.

Приведем несколько команд программы tshark:- tshark -D – выводит список доступных интерфесов;- нажатие на клавиатуре Ctrl + C – прекращение

выполнения команды;- tshark -i 2 -w test.pcap – получение пакетов

сетевого интерфейса 2 и их запись в файл test.pcap;- tshark -i 3 icmp – получение пакетов ICMP

протокола сетевого интерфейса 3;- tshark -r test.pcap -V | more - просмотр ранее

записанного файла test.pcap в постраничном режиме.Одним из приемов отправки сообщений в сеть

является их отправка из ЭТ. Однако эта возможностьдоступна, начиная с версии 4.4. При этом даннаявозможность должна быть указана при сборкеисполняемых файлов. Текущей версией, поставляемойвместе с дистрибутивом, является 3.2.57. Приведемпримеры команд.

Отправка текстового запроса на основе выводакоманды echo с использованием протокола tcp, используяпсевдоустройства

echo "GET / HTTP/1.0" > /dev/tcp/192.168.3.20/80

Отправка текстового запроса на основе выводакоманды printf

printf "GET / HTTP/1.0" > /dev/tcp/192.168.3.20/80

Для отправки двоичных данных необходимоиспользовать файл с данными, так набор двоичныхданных с помощью клавиатуры не предусмотрен.

Отправка 160 байт в двоичном виде по tcp порт 7654

Page 151: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

151

с использованием утилиты dd для передачи данных для отправки

dd if=binary.dat bs=160 count=1 > /dev/tcp/192.168.3.20/7654

Другим приемом, не зависящим от версии bash,является использование программы netcat (nc –сокращенная форма записи вызова программы).

Отправка текстового запроса на основе выводакоманды echo с использованием программы netcat

echo -e "GET / HTTP/1.0\n\n" | nc 192.168.3.20 80

Утилита netcat также может выступать в качествепрограммы, получающей данные из вычислительнойсети.

Для получения информации по протоколу UDP напорт 5555 используется команда

nc -lu 5555

Для отправки данных на порт, открытый предыдущейкомандой, используется команда

echo “Hello” | nc -u 127.0.0.1 5555

Приведенная команда передаст информацию из окнаЭТ с командой отправки информации, в другое окно ЭТ скомандой открытия и прослушивания порта.

Программа netcat так же умеет письма по протоколуSMTP и сканировать порты.

Распространенной задачей является определениепроцесса, занимающего или слушающего определенный

Page 152: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

152

сетевой порт. Для этих целей можно использоватьразличные приемы, однако чаще применяется программаnetstat. Знание трех способ вызова программы netstatобычно достаточно для определения причинынедоступности порта:

- netstat -anpu — отображение загруженныхсервисов с открытыми портами;

- netstat -tlnp — отображение процессов соткрытыми портами;

- netstat -a — отображение всех открытых портов безподробностей.

Для определения установленных соединенийдостаточно выполнить команду arp, которая позволяетвыполнять манипуляции с кешем протокола arp.Отображение аппаратных адресов выполняетсякомандой.

arp -a mac

Для получения информации о версии ОС ЭВМ,подключающийся к вашему устройству, можноиспользовать пассивный сканер p0f, который требуетзапуска с правами администратора. После запускапрограммы, она начинает отслеживать форматпринимаемых IP пакетов и пытается таким образомопределить версию ОС отправителя. Этот сканер невсегда может определить версию ОС, однако против негобессильны практически все анонимайзеры, т. к. они неизменяют структуру пересылаемого IP пакета.

Перечислим программы, ознакомление с которымиявляется необходимым минимумом для работы в сети:

- write – отправляет сообщение или файл указанномуадресату;

- rsync – синхронизация локальных и удаленных

Page 153: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

153

каталогов;- wget – скачивание файлов и статических сайтов,

независимо от разрывов соединения с возможностьюдокачивания через некоторое время;

- openssh – программа удаленного доступа спомощью ЭТ по зашифрованному каналу;

- nmap – получение списка открытых портов;- whois – получение информации о владельце ресурса

по протоколу whois;- nikto – сканер уязвимостей серверов, работающих с

использование протокола http; - snort – автоматический анализатор / блокировщик

сетевых пакетов;- awstats – в режиме реального времени анализ

статистики вэб-серверов.

Page 154: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

154

2.7 Информационная безопасность

Настали времена, когда государственные службыбезопасности всех стран перестали скрывать своепристальное внимание к вычислительным сетям. Чемчаще и интенсивнее человек использует глобальныеинформационные сети, тем выше риск нанесения емуущерба в том или ином виде, т.е. меньше егобезопасность. Таким образом, кажется ответ очевиден:не используя вычислительные сети человек неподвергается опасности. Это не так! Данные о человекеесть в вычислительных сетях независимо от того,использует ли он её сознательно или нет, а значиткаждый человек подвергается опасности. На текущиймомент, в среднем, ущерб, наносимый человеку прииспользовании вычислительной сети меньше, чем пользаот преимуществ, получаемых им от их использования.

Сфера информационной безопасности являетсяпрофессиональной областью деятельности, связанной среальным риском для здоровья и жизни. Дляминимизации рисков и угроз безопасности при работе ввычислительных сетях необходимо знать ряд концепцийи понимать базовые принципы работы в них.

1. Стать высококвалифицированным специалистом вобласти информационной безопасности, читая книги исидя за компьютером, невозможно!

2. Чем дольше человек присутствует ввычислительной сети, тем сложнее оставатьсяанонимным, независимо от уровня квалификациичеловека. Чем выше квалификация, тем дольше и лучшесохраняется частичная анонимность.

3. Значительную часть угроз несут сознательныедействия некоторых участников обмена информацией вкомпьютерных сетях, т.е. правонарушения и

Page 155: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

155

преступления. Структура преступности в сфереинформационных технологий полностью повторяетлюбую другую преступность. Причины преступностиизучает наука криминология. Если социум не подверженинформационному и культурному давлению, количестволюдей, сознательно преступающих закон, не превышает3%, даже во время войн и голода. На сегодняшний деньдавление на социум осуществляется с использованиемглобальных вычислительных сетей.

4. Невозможно продолжительное время заниматьсясомнительной или противозаконной деятельностью всети Интернет, не попав в поле зрения служббезопасности.

5. Бытовые устройства, подключенные квычислительной сети, опасны, т.к. изначальнопроектируются для сбора информации на самойзащищенной территории человека – в его доме!

6. Проблема использования нелицензионногопрограммного обеспечения и информационного контентав масштабах страны напрямую связано исключительно собщим достатком, а не с культурными различиями илиполитическим строем.

7. Потеря контроля над своими персональнымиданными является угрозой безопасности для каждогочеловека. Подразумевается свободная передачаперсональных данных между государственнымиструктурами, корпорациями, частным бизнесом,конкретными персоналиями.

8. Частный случай предыдущего пункта,лицензионные соглашения о передачи обезличенныхданных третьим лицам. Причина опасностииспользования соглашения о передаче данных третьимлицам в том, что с увеличением объема информации онаперестает быть обезличенной и снова становится

Page 156: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

156

персональной. Именно поэтому оставаться анонимным всети продолжительное время невозможно в принципе.

Основу информационной безопасностисоставляет ряд правил, базирующихся на общих правилахбезопасности, которые в первую очередь опираются наздравый смысл.

1. Стоимость защищаемой информации всегдадолжна быть меньше стоимости получения доступа к ней.

2. Принцип «Неуловимый Джо». Встречаются дваковбоя. Мимо проходит третий. Первый говорит второму:«Это неуловимый Джо прошел.» Второй спрашивает:«Такой крутой? Поймать никто не может?». Первыйотвечает: «Нет. Ненужен никому».

3. Бесплатный сыр бывает только в мышеловке.4. Не бывает облачных технологий, бывают чужие

сервера. (Пословица системного администратора однойкомпании). Эта пословица относиться как к бесплатным,так и платным почтовым серверам, социальным сетям,файловым хранилищам и всем другим Интернет-сервисам. Облачные сервисы дешевле, потому что онименее безопасны.

5. Если какую-то информацию можно не публиковатьв вычислительной сети, её нужно НЕ публиковать.

6. Если какую-либо информацию следуетопубликовать, подумайте как к ней отнесется каждыйчлен Вашей семьи сегодня, через 15 лет, через 30 лет.Как к этой публикации отнесутся Ваши дети и другиеродственники.

7. Собака лает, караван идет. Если по какой-топричине Вам приписывается информация, к которой Выне хотите иметь никакого отношения, выводите общениепо этим вопросам в правовое поле. Все другие вариантыдля ценителей Сунь-цзы.

8. Следовать правилам безопасности необходимо

Page 157: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

157

постоянно.Не следует забывать, что лучшими массовыми

бесплатными школами в области безопасности являютсяДОСААФ РФ и ВС РФ.

Page 158: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

158

3. Язык программирования Си3.1. Концепция языка. Первая программа

Язык программирования Си позволяет описыватьалгоритмы в текстовом виде, с целью преобразованияполученных текстовых файлов, написанных на языке Си,в набор инструкций понятных микропроцессору, вформате исполняемого файла целевой операционнойсистемы. Язык Си стандартизирован. Актуальным насегодняшний день является стандарт языка, описанный вдокументе ISO/IEC 9899:2018. Сокращенное названиестандарта C18. Мое личное мнение заключается в том,что прочитать стандарт и изредка перечитыватьнеобходимо, но знание стандарта наизусть не являетсяобязательным. Для этого есть ряд причин:

1. Стандарт разрабатывается по частямконсорциумом, а программист — это один человек.

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

3. Срок жизни конкретной версии стандарта языкане более 10 лет, т. е. стандарт однозначно придетсяпереучивать.

4. Компиляторы постепенно реализуют возможностистандарта от версии к версии. Таким образом, текст,написанный для одной версии компилятора, можетнекорректно обрабатываться компилятором другойверсии, причем таких расхождений со стандартом могутбыть десятки. Со временем они накапливаются в тексте итекст быстрее и проще написать заново, чем разобратьсяво всех доработках.

5. Некоторые разработчики компиляторовумышленно включают элементы, не соответствующиестандарту языка, делая исходный текст программ

Page 159: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

159

зависимым от своей версии компилятора.Язык Си — это инструмент, позволяющий ускорить

написание программ и повысить их переносимостьмежду аппаратными платформами, по сравнению сассемблером. Такой эффект достигается за счетабстрагирования от задач, связанных снепосредственным управлением элементами и блокамимикропроцессора. Си относится к высокоуровневымязыкам программирования, но остается достаточнонизкоуровневым, чтобы с его помощью реализовыватьвысокоэффективные программы.

В среде специалистов, не использующих Си какосновной инструмент разработки, распространяетсямнение о сложности языка и высокой цене ошибки. Напрактике язык Си можно использовать какалгоритмический язык, так и инструмент разработкидрайверов и других программных компонент,взаимодействующих с аппаратным обеспечениемнапрямую или через процесс — посредник. В пункте 1.5более подробно рассказывается о причинах связи языкаСи и операционных систем.

Язык Си может использоваться для разработкипрограмм для микроконтроллеров. Существует простоежизненное правило, чем меньше рюкзак, тем проще егоперенести, главное, чтобы его содержимого хватило длярешения всех насущных задач. Так и впрограммировании, чем меньше языкпрограммирования, тем проще его перенести на другуюплатформу. В связи с этим ядро языка Си, т.е. наборключевых слов очень мал. Под ключевыми словамипонимаются символьные конструкции, значение которыхзарезервировано стандартом языка. Зарезервированныеслова не могут использоваться никаким другимспособом, кроме как описанным в стандарте.

Page 160: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

160

Перечислим ключевых слова языка Си:auto, extern, short, while, break, float, signed, _Alignas,

case, for, sizeof, _Alignof, char, goto, static, _Atomic, const,if, struct, _Bool, continue, inline, switch, _Complex, default,int, typedef, _Generic, do, long, union, _Imaginary, double,register, unsigned, _Noreturn, else, restrict, void,_Static_assert, enum, return, volatile, _Thread_local

Компактность языка достигнута с помощьювключения в него только тех ключевых слов, которыесоответствуют набору команд микропроцессора. Всеостальные возможности вынесены в отдельныебиблиотеки. Любой другой подход не позволил быиспользовать этот язык на микропроцессорах сограниченным набором команд. Писать программы на Симожно даже для микропроцессоров, не имеющихсобственных средств ввода/вывода, благодаря переносувсех функций стандартного ввода вывода в библиотекустандартного ввода/вывода (stdio - standart inputoutput), описываемую заголовочным файлов stdio.h.

Другими словами, язык Си очень ограничен вовстроенных возможностях и не умеет даже получать ивыводить информацию. Однако такая компактностьпозволяет изучать и использовать требуемые библиотекипо необходимости, что значительно ускоряет разработкупрограмм.

Сложными темами при изучении языка Си являются:область видимости переменных, приведение типов,приоритет операторов, адресная арифметика, битовыеоперации, плохо спроектированные библиотеки. Такжебольшие трудности создает отсутствие знаний впредметной области, часто это микроэлектроника,электроника, схемотехника, операционные системы. Заисключением области видимости переменных, всеостальные сложные темы можно изучать по мере

Page 161: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

161

необходимости. Кроме того, существуют приемы,позволяющие существенно упростить работу с областямивидимости переменных.

Любая запускаемая в ОС программа дополняетфункции ОС и управляется ОС. Все современные ОСсоответствуют стандарту операционных систем POSIX втой или иной степени. В соответствии с этим стандартомпри запуске программы на исполнение, ОС создает трипотока: поток ввода, поток вывода и поток ошибок. Втерминологии языка Си поток ввода называется stdin,поток вывода stdout, поток ошибок stderr. Дляпрограммы, запускаемой в ЭТ, данные, получаемые склавиатуры помещаются в поток ввода, данные,помещаемые в поток вывода, отображаются на экране,данные, помещаемые в поток ошибок, такжеотображаются на экране. Потоки можно перенаправлятьи ассоциировать с различными устройствами и файлами.Обычно перенаправление потоков не требуется напервых этапах изучения языка программирования.

Программа на языке Си может состоять из одногофайла, имя которого имеет расширение *.c . Звездочкойобозначается набор любых символов произвольнойдлинны. Расширение позволяет интегрированным средамразработки определять используемый языкпрограммирования для выполнения подсветки ключевыхслов, переменных и констант разных типов. Разработкаязыка велась в то время, когда объем доступной памятиОЗУ не позволял загрузить команды программы в ОЗУполностью. Было предложено выполнять делениеисходного текста на два файла, один с расширением .c ивторой с расширением *.h. Расширение *.h отанглийского head — т. е. файл заголовок илизаголовочный файл. Таким образом существовалавозможность писать программы, размер которых

Page 162: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

162

превышал размер ОЗУ. Со временем, размер ОЗУувеличился на порядки, но от использованиязаголовочных файлов все равно не отказались, т. к. онипредоставляют значительные удобства дляструктурирования исходного текста программы с цельюуменьшения времени повторной компиляции иприменения концепции модульного программирования.Под модульным программированием подразумеваетсясовместная работа нескольких программистов над однимпроектом.

Сложность программы связана с объемом исходноготекста программы и растет экспоненциально, т. е.программа 100 строк предположительно будет более чемв два раза сложнее, чем программа из 50 строк. При этомнаиболее часто используют следующее деление:

- программы до 10000 строк считаются малыми;- программы от 10000 до 100000 строк относятся к

средним программам;- программы свыше 100000 строк являются

большими.При создании средних, больших и сверхбольших

программ, как правило, используется несколько файлов срасширением *.с и несколько файлов *.h. Соответствиемежду файлами программы и заголовочными файлами невсегда однозначное. Могут использоваться заголовочныефайлы, не имеющие соответствующего файла программы,также наличие заголовочного файла для файлапрограммы не является обязательным. Сведения оструктуре исходных текстов на языке Си содержатся встандарте языка программирования в разделе 5.1Концептуальная модель стандарта языка.

Создание исполняемого файла из исходных текстовна языке Си происходит в три этапа:

1. Обработка исходных текстов предпроцессором.

Page 163: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

163

2. Компиляция исходных текстов в объектный файл.3. Сборка объектных файлов в исполняемый файл

целевой операционной системы.Рассмотрим этапы создания исполняемого файла на

примере простейшего исполняемого файла. Обычнопервая программа на новом языке программированиявыводит всего одну фразу «Hello world!», обыгрываяпервую публичную демонстрацию работы телефонапередачей слова «Hello». В данном случае программабудет выводить текст «var =» и далее значениепеременной var, хранимое в ОЗУ. Программа состоит иззаголовочного файла main.h и файла программы main.c.

Заголовочный файл main.h

Файл содержит три строки. Первая строка являетсядирективой предпроцессора. Директивы предпроцессораописаны в разделе 6.10 стандарта языкапрограммирования. Предпроцессор обрабатывает первуюстроку следующим образом: он удаляет её из файлаmain.h и заменяет содержимым файла stdio.h. Файлstdio.h является заголовочным файлом стандартнойбиблиотеки ввода-вывода, заключен в скобки из символов«<» и «>». Значит файл поставляется вместе скомпилятором, расположен в каталоге /usr/include исодержит макросы, константы и прототипы функций,необходимые для использования функций стандартнойбиблиотеки ввода/вывода, включая функции для работы сфайлами. Вторая строка объявляет переменную типа charс идентификатором var. Идентификатор — это имя

Page 164: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

164

переменной, константы или элемента сложного типа.Третья строка не содержит символов. В конце файлалучше оставлять пустую строку, не содержащуюсимволов. Такое требование предъявлялось совсемстарыми версиями компиляторов, но для совместимости,на всякий случай, лучше их ставить. Также они могутпомочь при работе с файлами с исходными текстамипрограммы, обработанными предпроцессором.

Файл программы main.c

Файл main.c содержит 8 строк. Первая строкасодержит директиву предпроцессора. Предпроцессорзаменяет эту строку на содержимое файла main.h, однакофайл должен находится в том же каталоге, что и файлmain.c, т. к. в директиве его имя заключено в двойныекавычки.

Вторая строка не содержит символов ипредназначена для визуального отделения блокаобъявлений от текста программы, обрабатываемогокомпилятором. Её наличие не обязательно.

В третьей строке определена главная функцияпрограммы main, с которой начинается исполнение всехпрограмм на языке Си. Функция не принимает никакихаргументов, т. к. не содержит символов между скобкамии после завершения своего исполнения возвращаетзначение типа целое число (int — от integer, т. е. целое

Page 165: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

165

число). Тело, т. е. содержимое функции main, ограниченофигурными скобками «{» и в 7-й строке «}». Последняя8-я строка также не содержит символов какпредписывает раздел 5.1 Концептуальной моделистандарта языка Си. И хотя компиляторы обычно незамечают отсутствие в конце пустой строки, лучше еёоставлять.

В четвертой строке записано выражение, котороепеременной с идентификатором var присваиваетсячисленное значение, равное 0.

В пятой строке используется функция printfстандартной библиотеки ввода-вывода. В первомаргументе функции задается шаблон вывода вместе сформатом вывода переменной и служебнаяпоследовательность символов \n, обозначающая переходна новую строку, во втором идентификатор самойпеременной.

В шестой строке записано ключевое слово return,позволяющее передать в вызывающую программу кодвозврата. Для данной программы вызывающейпрограммой будет ЭТ.

Более подробное описание будет приводиться помере разбора элементов языка.

Для создания исполняемого файла необходимоиспользовать ЭТ, описанный в пункте 2.3. Для этогонеобходимо выполнить щелчок правой кнопки мыши нарабочем столе или в любом свободном месте файловогоменеджера и выбрать команду «Open terminal here»,«Terminal» или «Терминал». Название команды будетменяться в зависимости от используемой платформы длярабочего стола.

В ЭТ необходимо выполнить команды:

cd ~

Page 166: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

166

Сделать текущим домашний каталог пользователя.

mkdir source_code

Создать в домашнем каталоге пользователя каталогsource_code.

cd source_code

Сделать текущим каталог source_code.

echo "#include <stdio.h>" > main.h

Вывести фразу "#include <stdio.h>" в поток выводапрограммы echo, который перенаправлен в файл main.h.Если файл main.h существует, его содержимое удаляется.

echo "char var;" >> main.h

Вывести фразу "char var;" в поток вывода программыecho, перенаправленный в файл main.h. Причемсодержимое файла будет дополнено переданной фразой.

printf "\n" >> main.h

Вывести символ конца строки в поток выводапрограммы printf, перенаправленный в файл main.h.Причем содержимое файла будет дополнено.

Для проверки содержимого полученного файла используется команда

cat main.h

Page 167: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

167

ЭТ с текущим каталогом source_code будетнеобходим для получения исполняемого файла наследующем этапе.

Для набора второго файла можно использоватьредактор vim, описанный в пункте 2.4. Также можноиспользовать редакторы gedit, medit, leafpad, nano идругие. Для создания иллюстраций с исходным текстомпрограммы использовалась среда разработки Geany.

После подготовки файлов с исходными текстами,необходимо преобразовать их с помощью компилятора вфайл с исполняемыми командами. Для этогопредлагается использовать компилятор gcc.

В ЭТ с текущим каталогом source_code необходимовыполнить команду

gcc main.c

Если компилятор не установлен, в ЭТ будет выведено

bash: gcc: команда не найдена

Для проверки наличия установленного компиляторавыполняется команда

whereis gcc

При правильно установленном компиляторе будетвыведено

gcc: /usr/bin/gcc /usr/lib/gcc /usr/lib64/gcc /usr/libexec/gcc /usr/share/man/man1/gcc.1.xz

При его отсутствии

Page 168: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

168

gcc:

Для установки gcc необходимо повысить правадоступа до уровня администратора ЭВМ с помощьюкоманды

su -

затем необходимо ввести пароль администраторасистемы.

Получив права администратора системы, необходимовыполнить следующие команды:

apt-get update

обновить список версий, доступных для установкипакетов, включая список версий доступных ядер ОС.

update-kernel

обновить ядро операционной системы, т. е. Линукс.Если производится обновление ядра Линукс, длязагрузки с новым ядром требуется перезагрузка ЭВМ.

apt-get dist-upgrade

установить новые версии уже установленных пакетоввзамен старых.

Каждая команда работает в диалоговом режиме итребует ответов на ряд вопросов. Чаще всего программызапрашивают подтверждение на выполнение некоторогодействия.

apt-get install gcc

Page 169: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

169

установить пакет gcc.Примерный вывод такой команды

Вывод программы apt-get сообщает о том, чтокомпилятор gcc5 версии 5.3.1 уже установлен.

В случае, если бы он был не установлен, для егоустановки потребовалась бы команда

apt-get install gcc5

После установки компилятора вернемся к созданиюисполняемого файла. В ЭТ с текущим каталогомsource_code необходимо выполнить команду

gcc main.c

Программа gcc выполнит все этапы преобразованияисходных текстов в исполняемый файл. Подробнее её

Page 170: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

170

работа будет рассмотрена в пункте 5.2 этой книги.Представим упрощенную схему преобразованияисходных текстов программы в исполняемый файл.

В результате будет получен исполняемый файл сименем a.out. Это имя является для программы gccименем создаваемого исполняемого файла поумолчанию.

Если выполнить команду ls для каталога source_code,будет выведено имя исполняемого файла, созданного gcc.

Для запуска полученного файла используется команда

main.c

Предпроцессор

Компилятор

Линковщик(сборка)

main.h main.c

stdio.h

main.h

main.o

stdio.o

./a.out

Page 171: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

171

./a.out

Вывод в ЭТ

var = 0

В случае, если в исходном тексте содержитсяошибка, компилятор предпринимает попытки её найти ивыводит соответствующее сообщение. Например, если вфайле main.c в строке 5 удалить символ «p», получится

rintf("var = %d\n", var);

Далее необходимо сохранить изменения в файл.Выполнив команду gcc main.c, будет получен

следующий вывод

Каждая строка вывода программы gcc начинается сназвания файла с исходным текстом, в которомобнаружена ошибка. Первое двоеточие отделяет номерстроки с ошибкой, второе двоеточие отделяет номерсимвола, в котором обнаружена ошибка.

Page 172: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

172

После удаления одного символа в названии функциибиблиотеки базового ввода/вывода printf и выполненияповторной компиляции, компилятор посчитал, чтоиспользуется математическая функция rintf и вывел 2предупреждения, 2 замечания и 2 ошибки. Однако вданном случае он смог точно указать место началапроблемы. Это символ 5 строки 5 файла main.c.

Приведенный пример демонстрирует главноеправило чтения вывода сообщений компилятора. Ихнеобходимо читать сверху вниз и по порядку. Не следуетзабегать вперед, пока не исправлены ошибки выше.Часто исправление одной ошибки приводит кисправлению нескольких последующих.

Page 173: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

173

3.2. Типы данных. Операторы ввода/вывода

Основные принципы построения ОС описаны впункте 1.5. Одним из них является принцип простойметафорики, состоящей всего из двух понятий:вычислительный процесс и файл. Под файлами в первуюочередь понимается способ хранения данных. В языке Сидля хранения данных используются переменные иконстанты, описанные одним из типов данных, которыемогут храниться только в ОЗУ. Обработка данных врегистрах контроллера или микропроцессора скрытаконструкциями языка Си. Данные, хранимые наносителях информации, устройствах или ввычислительной сети, доступны с помощью функцийвнешних библиотек.

Назначение типов данных — это помощь внахождении ошибок компилятором в исходном текстепрограммы. Соответственно на этапе выполненияисполняемых команд типов данных не существует, т.к.микропроцессор умеет выполнять операции только сданными, размер которых равен размеру машинногослова микропроцессора или кратен ему.

Каждое значение или набор значений в языке Сиявляется некоторой последовательностью ячеек ОЗУ,которые логически связаны между собой. Имеется ввидутот факт, что теоретически один элемент массива можетфизически располагаться на одной физической планкеОЗУ, а следующий на другой. Однако ОС предоставляетнекоторую абстракцию, в рамках которой обе планкипамяти являются единым адресным пространством свозрастающим адресом для каждой последующейячейки.

Все данные в языке Си делятся на несколькокатегорий.

Page 174: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

174

1. Переменная, константа или указатель. Константаотличается от переменной тем, что её значение задаетсяодин раз и не может быть изменено до завершениявыполнения программы. Значение переменной можетменяться неограниченное количество раз. Указательможет содержать адрес как переменной или константылюбого типа, так и адрес элемента составного типа, окоторых будет рассказано далее.

2. Значение может быть знаковым или беззнаковым.Первый бит знаковой переменной или константыиспользуется для определения знака числа,положительное оно или отрицательное. Беззнаковаяпеременная может вместить большее положительноезначение.

Каждая переменная, константа или указательописывается идентификатором (именем переменной),имеет свой адрес, соответствующий адресу первойячейки памяти, начиная с которой располагаются еёзначения, и занимает некоторое количество ячеек ОЗУ.Тип данных, в свою очередь, определяет допустимыйдиапазон значений для соответствующей переменнойили константы и допустимые для неё операции.

В языке Си существует набор типов, называемыхсложными или составными типами данных. Основное ихотличие — в использовании одного идентификатора длянескольких элементов, каждый из которых по-сутиявляется отдельной переменной или константой.Подробнее составные типы будут рассмотрены вследующих разделах.

Стандарт языка Си в пункте 6.2.5. Типы, содержитописание допустимых типов данных. Спецификаторытипов, т.е. идентификаторы, которыми задаются ихназвания, описаны в пункте 6.7.2. Спецификаторы типов.Можно выделить несколько категорий типов данных:

Page 175: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

175

1. Архитектурнозависимые целые типы данных,размер которых может меняться в зависимости отаппаратной платформы. К ним относятся: char, short int,int, long int, long long int.

2. Целочисленные типы с минимальнодопустимойили фиксированной разрядностью. Например:int_least8_t, uint_least8_t, int_least16_t, uint_least16_t,int_least32_t, uint_least32_t, int_least64_t,uint_least64_t; это типы с минимально допустимымразмером объема памяти для значения типа. intN_t, гдеN = 8, 16, 32, 64, фиксированный объем памяти для этоготипа.

3. Числа с плавающей запятой: float, double, longdoube.

4. Комплексные и мнимые числа: float _Complex,double _Complex, long doube _Complex, _Imaginary.

5. Указатели, размер которых зависит от типапеременной или константы, на который они указывают.

6. Составные типы: массивы, структуры,объединения, битовые маски.

7. Типы, предлагаемые разработчикамикомпиляторов языка Си.

Существуют также рекомендуемые типы данных. Воизбежания возникновения путаницы, рекомендуетсяиспользовать только те типы данных, однозначноеописание которых приведено в стандарте языкапрограммирования. На практике, все потребностипрограммиста при разработке программы удовлетворяетне более 10 типов, остальные нужны только для чтенияисходных текстов, написанных другими программистами.

Для обработки текстовых значений в языкеиспользуются массивы типов char или wchar длямультибайтовых кодировок. Массивы будут рассмотреныв следующих разделах. Специальные типы для работы с

Page 176: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

176

текстом рассматриваются при работе над новымстандартом.

Максимальные и минимальные значения допустимыедля переменных и констант разных типов и описаны вразделе 5.2.4.2. Пределы значений стандарта языка.Стандарт предписывает поставлять вместе скомпилятором файл limits.h, в котором также приведеныдопустимые диапазоны для разных типов. Прииспользовании компилятора gcc этот файл можно найтив каталоге /usr/include/ .

При изучении типов данных необходимо такжеобратить внимание на заголовочные файлы stdint.h,float.h, stdbool.h. Следует помнить, что разработчикикомпилятора gcc могут менять расположение этихзаголовочных файлов или отказаться от них, переместивих содержимое в другие заголовочные файлы.

Для использования каждой константы, переменнойили указателя необходимо обязательно выполнить егообъявление, т. е. задание идентификатора. Такжекрайне рекомендуется выполнять инициализациюпеременных, т. е. задание начального значение. Правилаинициализации, немного отличные от других операцийдля составных типов данных, и будут рассмотрены всоответствующих разделах.

На рисунке 1 приведен исходный текст программы,демонстрирующей объявления переменных, константы иуказателей разных типов. Реализация главной функцииmain начинается со строки 3. Тело функции открываетсяоткрывающей фигурной скобкой «{».

В строке 4 объявлена константа типа char сидентификатором ch1, которая инициализирована кодомсимвола «a».

В строке 5 объявлена переменная типа short int сидентификатором shr. При объявлении типа short int,

Page 177: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

177

достаточно использовать ключевое слово short.Переменная инициализирована значением 15 вдесятичном виде.

В строке 6 объявлена переменная типа int сидентификатором dig, которая инициализированазначением 4.

В строке 7 объявлена переменная ch2, типабеззнаковый char и инициализирована числом 1.

Рисунок 1 — Исходный текст программы

В строках 8-9 записана функция форматированноговывода printf стандартной библиотеки ввода/вывода. Вшаблоне вывода указана строка, в которую подставленыспецификаторы типов для выводимых аргументов.Выводимыми аргументами являются идентификаторыпеременных.

В строке 10 объявлена переменная сидентификатором fl типа с плавающей запятой float,инициированная значением 3.0. При задании констант сплавающей запятой, необходимо указывать дробнуючасть через точку, даже если она равна 0.

Page 178: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

178

В строке 11 объявлен указатель на переменную типаfloat с идентификатором fl_p, который инициированрезультатом выполнения операции взятия адресапеременной fl. Операция взятия адреса обозначается спомощью унарного оператора &.

В строке 12 объявлен указатель на переменную типас плавающей запятой удвоенного размера (тип double) сидентификатором dbl, которая инициирована значениемNULL. NULL — означает указатель в никуда,определяется с помощью заголовочного файла,поставляемого с компилятором и обычно равен 0, однакозаменять его 0 не рекомендуется.

В строке 13-14 записан вызов функцииформатированного ввода/вывода, который выводитпервую переменную в формате две цифры до запятой иодна цифра после запятой. Вместо второй переменнойвыводится её адрес. Третья переменная выводится какпеременная с плавающей запятой. Четвертаяпеременная выводит значение адреса. Кроме того, кпеременной fl_p в четвертом аргументе примененаоперация разыменования, которая обозначаетсязвездочкой «*».

В строке 15 записано ключевое слово, задающеезначение, возвращаемое в ЭТ при завершении работыпрограммы.

В строке 16 записан один символ, закрывающий телофункции main.

На рисунке 2 представлены команда компиляцииисходного текста программы, его исполнения и выводпрограммы в стандартный поток вывода. Все командывыполняются после задания текущим каталогасодержащего файл main.c!

Page 179: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

179

Рисунок 2 — Вывод программы в ЭТ

Функция форматированного вывода строк 8-9сформировала первую строку вывода, в которой в текстшаблона вывода, вместо спецификаторов типоввставлены значения инициированных переменных.

Функция, записанная в строках 13-14, сформировалавторую строку вывода. Переменная fl выведена сшаблоном одна цифра две цифры до запятой и однапосле. Переменная fl_p является указателем и вывелаадрес, по которому располагается переменная fl.Разыменование переменной fl_p с помощью операции *привело к выводу значения переменной fl. Однако т. к.формат не указан, после запятой было выведенозначение символов по умолчанию, а именно 6 нулей.Переменная dbl инициирована значением NULL, котороеобозначено функцией printf как «(nul)».

Более подробная информация о типах содержится всоответствующих разделах стандарта языкапрограммирования.

Рассмотрим основные операторы ввода/вывода. Дляих использования необходимо подключать заголовочныйфайл stdio.h. Наиболее простыми и быстрыми функциямиявляются gets и puts, потому что их использование нетребует преобразования аргументов в другой формат. Всоответствии со стандартом языка Си, каждая функциядолжна быть реализована до своего первого вызова илииметь прототип, который по тексту встречается раньшееё вызова. Подробно правила написания функций будут

Page 180: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

180

рассмотрены в соответствующем пункте.Прототип функции gets описан в стандарте

следующим образом

char *gets(char *s);

Функция gets читает символы из стандартногопотока ввода stdin и размещает считанные данные вмассив s, указатель на который передан в качествеаргумента функции, пока не встретит символ концафайла или символ конца строки. Завершающий символотбрасывается, а вместо него записывается null, обычносоответствующее значению 0.

Если функция завершилась успешно, она возвращаетуказатель на массив, переданный её в качествеаргумента. Подробнее о массивах будет рассказано впоследующих пунктах. Если функция завершиласьнеудачей, возвращается значение null.

Полное описание функции содержится в пункте7.19.7.7 стандарта.

В пункте 7.19.7.10 содержится описание функцииputs. Данная функция имеет прототип

int puts(const char *s);

и выводит символы, содержащиеся по адресу s, встандартный поток вывода stdout и возвращаетколичество выведенных символов. Тип, передаваемый вфункцию puts, соответствует константному значения, азначит изменение массива символов внутри функцииputs невозможно.

В разделе 7.19.6 описаны функцииформатированного ввода/вывода. Функцияформатированного вывода fprintf описана в пункте

Page 181: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

181

7.19.6.1 и имеет прототип

int fprintf(FILE * restrict stream, const char * restrictformat, ...);

Функция принимает следующие аргументы:- restrict stream — указатель на структуру типа FILE,

которая может быть как stdin, stdout, stderr, так иуказателем на файл на накопителе или на файл-устройство;

- restrict format — шаблон вывода, являющийсястрокой со вставленными спецификаторами типов,вместо которых будут подставлены значенияпеременных;

- … — означает возможность использовать любоеколичество аргументов, которые будут подставленывместо спецификаторов типов выводимых переменных.

Допустимые спецификаторы типов описаны в том жепункте стандарта, что и сама функция.

Часто используется сокращенная форма записиоператора fprintf. Она отличается отсутствиемвозможности указания потока вывода и всегдаиспользует стандартный поток вывода stdout. Функцияназывается printf, описана в пункте 7.19.6.3 и имеетпрототип

int printf(const char * restrict format, ...);

Функция форматированного ввода fscanf является«обратной» fprintf, в том смысле, что её использованиесхоже с применением fprintf, только используется дляполучения данных из стандартного потока ввода.Функция fscanf описана в пункте 7.19.6.2. и имеетпрототип

Page 182: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

182

int fscanf(FILE * restrict stream, const char * restrictformat, ...);

Функция также как и fprintf использует шаблонввода, в котором указываются спецификаторы типов.Сокращенная форма записи имеет прототип

int scanf(const char * restrict format, ...);

и описана в пункте 7.19.6.4.

Рисунок 3 — Исходный текст программы примераработы операторов ввода/вывода

Приведем пример использования рассмотренныхфункций ввода / вывода с помощью исходного текста,набранного в файл inout.c. Назначение первой, второй и

Page 183: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

183

третьей строки подробно описано в предыдущем пункте.В строке 4 производится инициализация переменной сидентификатором buffer, которая является массивом из100 элементов. Подробно массивы будут рассмотрены вследующих разделах.

В строке 5 объявляется знаковая переменная целоготипа с идентификатором dig и инициализируетсязначением 0.

Строки 6, 10, 14, 18 оставлены пустыми длянаглядности. Пустая строка 21 добавлена длясовместимости со старыми версиями компиляторов.

Строка 7 состоит из вызова функции puts. Скобкамиограничен аргумент, передаваемый в функцию. В этойстроке в функцию передается константное значение«Введите слово», которому не присвоен идентификатор.Вызов функции заканчивается точкой с запятой, т. к.стандарт языка Си требует завершать этим символомкаждое выражение.

Строка 8 содержит вызов функции gets, которыйпринимает аргументом указатель на массив сидентификатором buffer. При вызове этого оператора,выполнение программы будет приостановлено и будетотображаться приглашение для ввода словапользователем в виде прямоугольника, который будетзаменен введенным символом. Для завершения вводанеобходимо нажать клавишу Enter. После этогоисполнение программы продолжится.

Строка 9 содержит вызов функции puts, но в этот разв неё передается указатель на первый элемент массиваbuffer, т. к. цифра 0 в квадратных скобках обозначает непорядковый номер элемента, а на сколько элементовнужно сместиться в памяти процесса от начала массива.

Строка 11 отличается от строки 7 только константой,передаваемой в функцию puts.

Page 184: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

184

Строка 12 содержит вызов функции fscanf. В негопередается три аргумента. Первый аргумент stdin — этостандартный поток ввода, ассоциированный склавиатурой. Второй аргумент — это шаблон ввода,содержащий только один формат переменной целоготипа. Третий аргумент состоит из унарной, т. е.содержащей только один операнд, операции взятияадреса и идентификатора знаковой переменной целоготипа. Таким образом, третьим аргументом будетконстанта типа адрес знаковой переменной целого типа.В результате вызова этой функции данные будут читатьсяиз стандартного потока ввода до нажатия клавиши Enter,затем они будут преобразованы в целое число и записаныв область ОЗУ, адресуемую идентификатором dig.

Строка 13 содержит вызов функции fprintf, первыйаргумент которой stdout соответствует стандартномупотоку вывода. Второй аргумент соответствует шаблонувывода. Символы данного шаблона вывода будутвыведены на экран, за исключением последовательности%d, которая будет заменена на значение переменной сидентификатором dig, и последовательности \n , котораяозначает переход на новую строку.

Строка 15 идентична строке 11.Строка 16 содержит вызов оператора scanf,

аргументы которого отличаются от вызова в строке 12только отсутствием указания потока ввода.

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

Строка 19 содержит ключевое слово return, которое передает значение 0 в вызывающую программу, т.е. ЭТ.

Для создания программы необходимо запустить ЭТ,сделать каталог с исходным текстом программы текущими выполнить команду, указанную на рисунке 4. Команда

Page 185: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

185

состоит из двух, объединенных логическим оператором И(&&). Первая часть команды gcc inout.c -o inoutпредписывает выполнить создание исполняемого файлапрограммы из исходного текста на языке Си,расположенного в файле inout.c, а исполняемый файлназвать inout без расширения. Вторая часть команды./inout предписывает запустить полученный исполняемыйфайл на исполнение.

Рисунок 4 — Создание и исполнение программыпримера использования функций форматированного

ввода/вывода

При создании исполняемого файла из исходноготекста программы были получены следующиесообщения:

inout.c: В функции «main»:

В файле inout.c в функции с идентификатором main.

Page 186: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

186

inout.c:8:5: предупреждение: неявная декларация функции «gets» [-Wimplicit-function-declaration]

gets(buffer); ^

В файле inout.c в строке 8 символе 5 предупреждениеоб использовании неявной декларации функции gets,появление которой в данном случае, связано снеобходимостью преобразования входного аргумента ктипу указатель на тип char.

/tmp/.private/valerii/cczPEvD3.o: In function `main':inout.c:(.text+0x52): warning: the `gets' function is

dangerous and should not be used.

Данное сообщение предупреждает, чтоиспользование функции gets опасно и от неё будетпроизведен отказ в следующих стандартах языкапрограммирования.

Последующий вывод, начиная с фразы «Введитеслово», сгенерирован программой inout, созданной израссмотренного исходного текста программы. Изпримера следует, что использование операторов fscanf иfprintf с указанием стандартных потоков ввода и выводасоответственно ничем не отличается от использованияоператоров printf и scanf.

Page 187: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

187

3.3. Выражения. Арифметические и логические операции. Математические функции

Выражение — это последовательность операторов,операндов, других объявленных объектов или вызововфункций, которые допустимы в рамках языкапрограммирования. Обычно выражения отделяются другот друга с помощью точки с запятой, при условии что ононе расположено внутри скобок, квадратных скобок, неявляется аргументом функции. Полное определениепонятия выражения дано в пункте 6.5 стандарта языкаСи.

Примерами выражения являются:

i = j + 2;printf("%d", k);j - t && t + j

Бинарные арифметические выражениязаписываются следующим образом: сначалазаписывается идентификатор, по которому будетприсвоено значение, полученное в результатевычисления выражения, далее ставится знак присвоения= , после знака присвоения записывается вычисляемаячасть выражения. Под бинарными арифметическимивыражениями подразумеваются те, в которых операциявыполняется над двумя значениями, например 3+5.Действия, выполняемые над одним значением, напримеротрицание единицы, обозначаемое восклицательнымзнаком !1, которое будет равно 0, называется унарнойоперацией.

Примеры арифметических операций:

x = y + 2;

Page 188: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

188

x = y — 2;x = y * 2;x = y / 2;

Для выполнения арифметической операции с однойпеременной возможно использование короткой записивыражения, например:

int x = 2;x += 2;

полностью соответствует записи

x = x + 2;

в первом и во втором случае x будет равно 4.Другой пример:

int x = 8;x /= 2;

Переменная x будет равна 4.Особенностью языка Си является отбрасывание

дробной части, если результат деления присваиваетсяцелочисленной переменной. Для получения остатка отделения используется специальный оператор. Например:

int x = 9;int y = x / 2;

В результате вычисления выражения, переменная yбудет инициализирована целочисленным значением 4.Остаток от деления будет отброшен.

Для получения остатка от деления используется

Page 189: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

189

оператор %. Например:

int x = 9;int y = x % 2;

Переменная y будет равна 1. Более подробно этотвопрос будет рассмотрен в пункте, посвященномпреобразованию типов данных.

Арифметические действия можно записывать в видевыражений с использованием скобок, например:

int y = (x — 3) / (x — 2);

при этом приоритет выполнения операция будетсоответствовать правилам арифметики.

В языке Си в качестве знака присвоенияиспользуется символ, обозначающий равенство вматематике. Это вызывает путаницу на начальных этапахизучения языка. Математическое равенство в языке Сиобозначается как логическая операция сравнения иобозначается двумя символами == . Предлагаетсяследующий способ запомнить отличия. Считать, что знакприсвоения эквивалентен действию положить яблоко вкорзинку, т. е. поместить некоторое значение в ячейкипамяти. Знак сравнения содержит два символа и поэтомупредлагается ассоциировать его с весами, на которыекладут два яблока и выполняют сравнение, какое из нихбольше.

Операции сравнения, проверка на равенство,проверка на неравенство и другие операции сравненияприведены в пункте 6.5.9 стандарта Си.

Для рассмотрения логических, побитовых операций иопераций сдвига обратимся к исходному текступрограммы, представленному на рисунке 1.

Page 190: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

190

Рисунок 1 — Выполнение логических, побитовыхопераций и операций сдвига

Строки 1-4, 16-18 подробно описаны в пункте 3.1.Строка 5 объявляет переменную целого типа с

идентификатором j и инициализирует её константой 3.Строка 6 объявляет переменную целого типа с

идентификатором t и инициализирует её константой 1.Строки 7-14 состоят из выражений, содержащих один

вызов оператора printf, и отличаются толькопередаваемыми в него аргументами. В строке 7 первыйаргумент является шаблоном вывода "%d=%d+%d\n".Спецификаторы типа %d будут заменены следующимобразом: первый спецификатор будет замен результатомвычисления выражения j+t. В конце выражения неставиться точка с запятой, т. к. выражение являетсяаргументом оператора printf. Второй будет заменензначением переменной с идентификатором j. Третийзаменен значением переменной с идентификатором t.

Page 191: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

191

Замечание. Обычно результат вычисления выражениязаписывается в ячейки, соответствующие некоторойпеременной. Эти действия соответствуют двум действияммикропроцессора: выполнить сложение и поместитьрезультат в регистр микропроцессора eax, поместитьрезультат в переменную с указанным идентификатором вОЗУ, т. к. все переменные, по определению, расположеныв ОЗУ. В строке 7 результат выражения j+t вычисляется вмикропроцессоре и сохраняется в регистремикропроцессора, например, в eax. Далеемикропроцессор размещает другие аргументы в своихдругих регистрах и переходит к выполнению операторовфункции printf. Таким образом создается текстпрограммы, которая будет выполняться быстрее. Дляболее глубокого понимая таких механизмов необходимызнания в области микропроцессорной техники ипрограммировании на ассемблере.

В строке 8 операция сложения заменена бинарнойоперацией побитового И (&). В результате выполненияэтой операции будут выполнены операции И междусоответствующими разрядами переменных j и t, и еслиоба разряда будут равны 1, в соответствующий разрядрегистра eax будет помещена единица. Послевыполнения операций со всеми разрядами получитсяединое многоразрядное значение, которое будетвыведено на экране оператором printf.

В строке 9 выполняется бинарная операциялогическое И (&&). Результатом выполнения этойоперации является 1, если оба операнда не равны 0, впротивном случае результат будет равен 0.

В строке 10 выполняется бинарная операция —побитовое ИЛИ (|). Эта операция выполняется так же,как и операция побитового И в строке 8, за темисключением, что для получения значения 1 в

Page 192: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

192

результирующем разряде необходимо, чтобы хотя быодин из двух соответствующих разрядов входныхоперандов был равен 1. В ином случае, значениерезультирующего разряда будет равно 0.

В строке 11 выполняется бинарная операция —логическое ИЛИ (||). Результатом этой операции будетединица, если хотя бы один из операндов будет отличенот нуля. В противном случае он будет равен 0.

В строке 12 выполняется унарная операцияпобитового отрицания (~). В результате выполнения этойоперации каждый бит операнда будет изменен напротивоположный. При использовании знакового типацелого числа, первый бит обозначает знак числа. Егоизменение приведет к интерпретации числа какотрицательного, т. е. записанного в дополнительномвиде, см. пункт 1.2.

В строке 13 выполняется унарная операциялогического отрицания (!). Эта операция возвращает 0,если его операнд отличен от 0 или 1, если его операндравен 0.

В строке 14 выполняется бинарная операция сдвигавлево (<<). Арифметически сдвиг влево на 1соответствует умножению на 2. Данная операциязаключается в том, что каждый бит числа будетперезаписан на одну позицию левее, а в освободившийсяразряд будет помещен 0.

В строке 15 выполняется бинарная операция сдвигавправо (>>). Арифметически сдвиг вправо на 1соответствует делению на 2. Данная операциязаключается в том, что каждый бит числа будетперезаписан на одну позицию правее, а восвободившийся разряд будет помещен 0. Крайнийправый бит будет потерян.

Приоритет арифметических, логических и побитовых

Page 193: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

193

операций сведен в таблицу в разделе 2.12 Книги «Языкпрограммирования Си» Брайана Кернигана и ДеннисаРитчи.

В стандарте языка программированияпредусмотрены альтернативные названия логическихопераций, описанные в разделе 7.9 Альтернативныеобозначения, которые объявлены в файле iso646.h.

Считается, что операции сдвига позволяют ускоритьисполнение программы, однако это справедливо только,если операции сдвига составляют большую частьвычислительной сложности исполняемого файла.

Рисунок 2 — Результат исполнения исходного текстапредставленного на рисунке 1

Для запуска описанного исходного текста программыиспользуется команда ЭТ, содержащая логическое Ипричем вторая часть — запуск полученногоисполняемого файла, производится только в случаеуспешного завершения команды создания исполняемогофайла скриптом gcc.

Операции сравнения будут подробно рассмотрены впункте, посвященном условным переходам.

Для выполнения математических операций,

Page 194: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

194

отличных от арифметических, необходимо выполнятьподключение модуля math. Для этого исходный текстпрограммы должен содержать строку

#include <math.h>

При компиляции исходных текстов, содержащихматематические функции модуля math, необходимоуказывать ключ -lm, например так:

gcc 02.c -o 02 -lm

Все библиотеки кроме стандартных (stdio.h, stdlib.h),которые подключены по умолчанию, требуют длякомпоновки указания специального ключа.

Математические функции модуля math описаны впункте 7.12 Математика стандарта языка Си. Наиболеечасто используемыми являются функции возведения встепень, извлечения корня и тригонометрическиефункции.

Пример использования математических функцийпредставлен на рисунке 3.

Поясним значение некоторых строк текстапрограммы, представленной на рисунке 3.

В строке 2 указана директива предпроцессора.Предпроцессор обрабатывает эту строку, заменяя её насодержимое файла math.h, расположенного в каталогеinclude, поставляемой вместе с компилятором.Добавление этой строки позволяет использоватьматематические функции, прототипы которых описаны вфайле math.h.

Page 195: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

195

Рисунок 3 — Исходный текст программыиспользующей математические функции

В строке 6 объявляется и инициализируетсяпеременная с идентификатором xd, типа double. Типdouble обозначает переменные и константы, хранящиезначение в виде мантисы и степени удвоенной точности,т. е. значение с плавающей запятой удвоенной точности.После знака присвоения указана константа с дробнойчастью. Необходимо запомнить, при инициализации

Page 196: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

196

переменных и констант с плавающей запятой всегданеобходимо указывать дробную часть, даже если онаравна 0. Под объявлением понимается, что будетвыделена память в ОЗУ для хранения переменной, а подинициализацией понимается присвоение начальногозначения переменной.

Строка 7 также объявляет и инициализируетпеременную с плавающей запятой.

Рисунок 4 — Результат исполнения исходного текста,представленного на рисунке 3

В строке 10 производится вызов оператора printf.Первый аргумент этого оператора является шаблономвывода. Он будет выведен на экран за исключениемпоследовательностей %e, которые являютсяспецификаторами типа double оператора printf. Первыйспецификатор типа будет заменен результатом вызоваматематической функции acos, второй — значениемпеременной с идентификатором xd. Арккосинусвычисляется от одного значения, т. е. координаты по оси

Page 197: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

197

x, поэтому в функцию acos также передается однозначение с идентификатором xd. В конце шаблона выводаиспользуется последовательность символов «/n»,обозначающая переход на новую строку.

В строке 13 используется функция вычисленияаргтангенса y/x, поэтому в функцию atan2 передается двааргумента с идентификаторами xd, yd.

Для создания программы из исходного текстапрограммы и её запуска в файле 02.c используетсякоманда, представленная в первой строке на рисунке 4.Команда состоит из двух частей. Первая часть вызываеткомпилятор gcc и передает в него в качестве аргументовимя файла с исходным текстом программы и ключом -lm.Программа gcc передает ключ -lm компоновщику ld,который включает в создаваемый исполняемый файлобъектный файл библиотеки math.

Следует обратить внимание на то, что аргументыприведенных математических функций, т. е.передаваемые им значения, должны не противоречитьматематическим правилам.

Page 198: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

198

3.4. Операторы выбора

Наиболее популярный оператор условного переходаif описан в стандарте языка Си в пункте 6.8.4.1 и имеет 2формы записи.

Полная форма:

if ( выражение ) { операторы }else { операторы };

Сокращенная форма записи:

if ( выражение ) { операторы };

Если после ключевого слова if и скобки используетсяодин оператор, фигурные скобки можно не использовать.

if ( выражение ) оператор;

Также не использовать фигурные скобки можнотолько в одной части полного оператора if.

if ( выражение ) оператор;else { операторы };

Есть простое правило, которое позволяет незапутаться с необходимостью выставления фигурныхскобок. Их нужно ставить всегда. С появлением нужногоопыта этот вопрос отпадает сам собой.

Следует иметь в виду, что результатом выраженияявляется логическое значение, соответствующее одномуиз двух значений — истина или ложь. Приведем примерызадач, которые можно решить с использованием этихключевых слов.

Page 199: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

199

Условие задачи:Если значение переменной с идентификатором left

равно 1, необходимо вызвать функцию поворота налево.Решение:if ( left == 1 ) move_left();

Условие задачи:Если значение переменной с идентификатором left

равно 2, вызвать функцию поворота налево и вызватьфункцию остановки.

Решение:if ( left == 1 ) {

move_left();stop ();

};

Условие задачи:Если значение переменной с идентификатором right

равно 1, вызвать функцию поворота направо, иначеповернуть налево и остановиться.

Решение:if ( right == 1 ) move_right();else {

move_left();stop ();

};

Условие задачи:Если значение переменной с идентификатором right

равно 1 и значение переменной left равно 0, вызватьфункцию поворота направо.

Решение:

Page 200: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

200

if ( right == 1 && left == 0 ) move_right();else {

move_left();stop ();

};Пояснение:В данном примере выражение в скобках после

ключевого слова if содержит две операции сравнения,объединенные операцией логического И. Приоритетлогической операции И меньше, чем у операциисравнения, поэтому сначала будет произведеносравнение переменной с идентификатором right сконстантой 1. Второй шаг будет выполнен только тогда,если результатом первого сравнения будет 1, т.е. истина.Вторым шагом станет сравнение переменной сидентификатором left с константой 0. Третий шаг —выполнение логической операции И над первымрезультатом, равным 1 и результатом второй операции.Логическая И возвращает 1 в случае, если оба значенияравны 1, во всех других случаях она вернет 0 и будутвыполнены операторы в фигурных скобках послеключевого слова else.

Для упрощения понимания выражения следуетиспользовать скобки, руководствуясь правиламиарифметики. Предыдущее решение можно записать так:

if ( (right == 1) && (left == 0) )

Добавление скобок упрощает восприятие условия.Если условие содержит более 3 операций, скорее всегоего разбиение на несколько операторов if ускоритвыполнение программы. Для этого необходимо вынести впервый оператор условие, которое будет встречаться

Page 201: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

201

реже.

if ( right == 1 )if ( left == 0 ) move_right();

else {move_left();stop ();

};

Предположим, что в программе значение right чащеравно 0. В таком случае проверка left равно 0 будетпроизводиться только, если right равно 1. В данномслучае это не дает прироста скорости исполнения, т.к.второе выражение и так не будет выполнено, если первоеравно ложь. Причина отсутствия ускорения программы втом, что в выражении всего 3 операции.

Существует форма операции выбора безиспользования ключевого слова if. Его форма:

условие ? оператор : оператор;

Представленная форма оператора выбора обычноиспользуется в качестве аргумента при вызове некоторойфункции.

Например:

int var = 0;printf ("&s", var?"да":"нет");

Программа, созданная из этого исходного текстапрограммы, всегда будет выводить

нет

Page 202: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

202

Первая строка объявляет и инициализируетпеременную целого типа с идентификатором var. Втораястрока — это вызов оператора форматированного выводаprintf, первым аргументом которого являетсяспецификатор строкого типа, второй аргумент содержитконструкцию, возвращающую одну из двух текстовыхконстант "да" или "нет". Переменная var до символа ?интерпретируется как результат логического выражения.Значение var, отличное от 0, считается логическойистиной, 0 – логическая ложь.

Для выбора одного из нескольких значенийиспользуется оператор switch. Он описан в пункте 6.8.4.2стандарта языка программирования. Его форма записи:

switch ( выражение ){

объявленияcase константа : операторы;default: операторы;

}

Результатом «выражения», в отличие от оператора if,является значение целого типа. Это делает возможнымвыбор одного из нескольких значений. В блоке«объявления» возможно объявление и инициализацияпеременных и функций.

Условие задачи:Если переменная с идентификатором value равна 2,

умножить её на значение переменной value_offset. Еслиvalue равна 3, прибавить к ней значение value_offset. Вовсех других случаях вычесть из value значениеvalue_offset.

Решение:

Page 203: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

203

int value;...switch (value){

int value_offset = 4;case 2: value *= value_offset; break;case 3: value += value_offset; break;default: value -= value_offset;

}Пояснение:Троеточие означает, что часть текста программы

пропущена. В области объявления оператора switchобъявлена одна переменная целого типа value_offset иинициализирована значение 4.

При выполнении оператора switch производитсявыбор метки case, соответствующей значениюпеременной с идентификатором value. Далеевыполняются операторы, следующие за этой меткой,пока не будет встречен оператор прерывания break; .После этого управление передается за фигурную скобку,завершающую оператор switch. В случае отсутствияметки case, соответствующей текущему значениювыражения, управление передается за оператор switch. Всвязи с этим настоятельно рекомендуется использованиенеобязательной метки default. Считается, что в случае еёотсутствия, программа передает управление за операторвыбора, не выполнив выбора. Такая ситуация частовозникает по причине ошибки значения, переданного ввыражение, или ошибки в алгоритме программы.

В примере используется сокращенная форма записиарифметических операций. Выражение

value *= value_offset;

Page 204: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

204

соответствует

value = value * value_offset;

Также интерпретируются остальные операции.Сокращенная форма записи арифметическоговыражения позволяет реализовать эту операцию заменьшее количество ассемблерных операций.

Условие задачи:Реализовать реостат с разным сопротивлением на

разных участках катушки. Считается, что каждый витокимеет разное значение сопротивления. Всего имеется 5витков.

Решение:int rheostat_turns;int resistance;...switch ( rheostat_turns ){

case 1: resistance += 2;case 2: resistance += 3;case 3: resistance += 1;case 4: resistance += 4;case 5: resistance += 2; break;default: resistance = 0;

}Пояснение:Так как в операторе switch в действиях по всем

меткам case, кроме case 5, отсутствуют операторыпрерывания break, все действия будут выполнены попорядку. Например, при переходе на метку case 2 будутвыполнены строки:

Page 205: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

205

case 2: resistance += 3;case 3: resistance += 1;case 4: resistance += 4;case 5: resistance += 2; break;

Будет получено значение resistance = 12.Если будет указано неверное количество витков

реостата, будет выполнен переход на метку default ипеременной с идентификатором resistance будетприсвоено значение 0. Чтобы проверить, было липередано недопустимое значение в качестве выраженияоператора switch, необходимо проверить на равенство 0переменную resistance таким образом

if ( resistance == 0 ) было передано неверное количество витков;

Page 206: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

206

3.5. Операторы цикла

Реализация алгоритмов часто требует многократногоповторения одних и тех же действий. В языках высокогоуровня, к которым относится Си, для этого используютсяциклы. В стандарте языка Си они именуютсяитераторами и описаны в разделе 6.8.5 Описаниеитераторов. Циклов всего три: цикл с предусловием(6.8.5.1. while), цикл с постусловием (6.8.5.2. do), цикл сзаданным количеством повторений (6.8.5.3. for). Всециклы содержат в себе выражение, являющеесяусловием выхода из цикла, и тело цикла. В случае, еслитело цикла содержит в себе более одного выражения,необходимо его заключать в кавычки.

Цикл с предусловием имеет следующее описание:

while ( выражение ) тело цикла;

Для всех циклов используются единые правилаобрамления тела цикла фигурными кавычками.Представим два случая, когда тело цикла является однимвыражением или несколькими.

while ( выражение ) выражение1;

или

while ( выражение ) {выражение 1;…выражение n;

}

Условие задачи:

Page 207: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

207

Вычерпать весь суп из кастрюли.Решение:while ( уровень супа в кастрюле > 0 ) {

зачерпнуть суп;вылить половник в тарелку;

}

Цикл с постусловием имеет следующее описание

do тело цикла while ( выражение );

Условие задачи:Известно, что дверь закрыта. Открыть дверь

вставленным в замок ключом.Решение:do {

повернуть ключ в замке;толкнуть дверь;

}while ( дверь закрыта );

Цикл с заданным количеством итераций имеет следующее описание:

for ( выражение 1 ; выражение 2 ; выражение 3 ) тело цикла;

Выражение 1 используется для задания начальногозначения счетчика цикла. Выражение 2 являетсяусловием выхода из цикла, т.е. пока результат этоговыражения не равен 0, тело цикла будет выполняться.Выражение 3 производит увеличение счетчика циклапосле каждого выполнения тела цикла.

Page 208: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

208

Условие задачи:Подпрыгнуть три раза.Решение:char count = 0;for ( ; count < 3; count++ ) подпрыгнуть;Пояснения:Переменная count является счетчиком цикла. Её

объявление и инициализация производится до цикла. Таккак в цикле инициализация не требуется, первоевыражение содержит пустое выражение, состояние изодного символа, точка с запятой. Второе выражениесодержит условие, что счетчик цикла должен бытьстрого меньше 3. Третье выражение выполняетинкремент счетчика цикла. Далее выполненоразвертывание цикла в последовательность действий.Текст описан псевдоязыком с использованиемлингвистически недопустимого текста для упрощения,также используются символы /* */ которыми отделяетсякомментарий от текста программы. При компиляциикомментарии компилятором не обрабатываются.

char count = 0; /* Объявление и инициализациясчетчика цикла

; выражение 1*/count < 3; /* выражение 2, count равен 0*/подпрыгнуть; /* тело цикла*/count++ /* выражение 3, count равен 0*/count < 3; /* выражение 2, count равен 1, т. е.

он увеличенв результате предыдущей операции*/

подпрыгнуть; /* тело цикла*/count++ /* выражение 3, count равен 1*/count < 3; /* выражение 2, count равен 2, т. е.

он увеличенв результате предыдущей операции*/

Page 209: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

209

подпрыгнуть; /* тело цикла*/count++ /* выражение 3, count равен 2*/count < 3; /* выражение 2, count равен 3, т. е.

он увеличенв результате предыдущей операции*/

После того как счетчик цикла стал равен 3, т. е.условию выхода из цикла, выполнение циклапрекращается.

Приведем примеры записи бесконечных циклов. Оничасто используются при ожидании событий отаппаратного обеспечения.

Используя цикл с предусловием

while (1) тело цикла;

Используя цикл с постусловием

do тело цикла while (1);

Используя цикл с заданным количеством итераций

for ( ; 1; ) тело цикла;

Как показано выше, циклы взаимозаменяемы. Выборнужного цикла обычно не вызывает затруднений.

Page 210: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

210

3.6. Функции

При написании небольших учебных программисходный текст обычно размещается в одной функцииmain. В соответствии с пунктом 5.1.2.2.1 стандарта языкапрограммирования, выполнение любой программыначинается с первого выражения функции main. Также вэтом пункте описаны способы интерпретации аргументовфункции main и их значений, передаваемых в программуиз ОС. Начиная с пункта 3.1. было показано, что дажесамые простые программы не обходятся без вызовабиблиотечных функций, поставляемых вместе скомпилятором. Сама по себе функция — этосинтаксически допустимая возможность выделениянабора инструкций в отдельную синтаксическуюединицу.

К основным причинам использования функцийотносят:

- выделение повторяющегося исходного текста свозможностью обращения к нему из любого местаисходного текста программы;

- выделение специфических частей исходного текста,например, обмен данными с некоторым аппаратнымустройством;

- создание с помощью функций логических модулейили библиотек для создания исходного текста,соответствующего разработанному алгоритму;

- повышение читаемости исходного текстапрограммы.

Каждая функция имеет входные и выходныезначения, типы которых указываются вместе сидентификатором функции. Входные значения такженазываются аргументами функции. Сначала указываетсятип выходного, результирующего значения, затем

Page 211: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

211

указывается идентификатор функции, далее в скобкахперечисляются типы и идентификаторы аргументов,передаваемых в функцию.

Например:

char first_function (float first_argument, intsecond_argument);

Выходное значение у функции может быть толькоодно. Это ограничение связано с аппаратнойархитектурой большинства современныхмикропроцессоров, т. к. выходное значение помещается врегистр микропроцессора общего назначения eax,который в логической структуре регистров один. Следуетотметить, что в современных микропроцессорахфизически может присутствовать сотня регистров eax,однако они недоступны для управления из прикладнойпрограммы. Их распределением занимаетсямикропрограмма, зашитая в микропроцессор. Вприведенном примере выходное значение имеет типchar. Для возврата значения из функции используетсяоператор return.

Входные значения функции перед её запускомпомещаются в стек, поэтому в функцию можно передатьмножество аргументов, общий размер которых непревышает размер стека. Входные значения отделяютсядруг от друга запятой, называемой операциейследования. В приведенном примере входные аргументы— это переменная с идентификатором first_argumentтипа float и переменная с идентификатором типаsecond_argument типа int.

Идентификатором функции является first_function.Функция может быть реализована двумя способами:1. Объявление и тело функции находится до её

Page 212: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

212

первого использования.Пример:

...char first_function (float first_argument, int

second_argument){

char value;…return value;

}

...

int main (){

float float_value;int int_value;...char result = first_function (float_value, int_value);…return 0;

}

Из примера видно, названия переменных не должнысовпадать с названиями аргументов, передаваемых вфункции.

2. Тело функции находится после функции, в которойпроисходит её вызов. В этом случае необходимовыполнить объявление функции до её вызова.Объявление функции состоит из строки, содержащей типвозвращаемого значения, идентификатора функции,списка входных аргументов, заключенных в скобки, и

Page 213: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

213

точки с запятой.Например:

...char first_function (float first_argument, int

second_argument);...

int main (){

float float_value;int int_value;...char result = first_function (float_value, int_value);...

}

char first_function (float first_argument, intsecond_argument)

{char value;…return value;

}

В случае, если выполнено объявление функции, нореализации функции нет, компиляция исходного текстапрограммы возможна, при этом ошибка не будет выдана.Такой прием позволяет проектировать структурубиблиотеки или программы, непосредственно написанисходный текст программы, а реализацию отдельныхфункций разделить между несколькими программистами.

Page 214: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

214

Отсутствие тела функции приведет к ошибке на этапекомпоновки. Схема преобразования исходного текстапрограммы в исполняемый файл описана в пункте 3.1.

Функция может не иметь входных аргументов,например:

int main ();

Рисунок 1 — Демонстрация синтаксиса описанияфункций

При объявлении функций может использоватьсяспецификатор inline, описанный в разделе 6.7.4. языкапрограммирования. В этом случае вместо вызова

Page 215: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

215

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

Пример объявления, реализации и использованияфункций приведен на рисунке 1.

Первая и вторая строка исходного текста программыявляются директивами предпроцессора и заменяются насодержимое указанных файлов.

В строке 4 описывается функция с идентификаторомprint_pi. Функция не принимает никаких значений,потому что не указаны аргументы между открывающей изакрывающей скобкой. Функция ничего не возвращает,поэтому указывается пустой тип void, означающий«ничего». Если функция не возвращает никакихзначений, обязательно перед её идентификатором писатьvoid, в соответствии со стандартом, если передидентификатором функции нет никакого типа, поумолчанию подставляется тип int и компилятор будеттребовать указать тип возвращаемого значения.

Реализация функции print_pi состоит из конструкцийв 5, 6 и 7 строках. Открывающая фигурная скобка в 5строке обозначает начало тела функции. Закрывающаяфигурная скобка в строке 7 обозначает завершение телафункции. Единственным выражением функции являетсявызов функции printf стандартной библиотекиввода/вывода. В первом аргументе оператора printfуказывается о необходимости вывести значение сплавающей запятой, при этом целая часть должнасостоять из одного символа, а дробная из двадцати. Вкачестве значения используется константа M_PI,объявленная с помощью оператора предпроцессора#define в файле math.h.

Page 216: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

216

В строке 9 представлено объявление функции pi.Функция не принимает никаких значений, т. к. в скобкахотсутствуют аргументы, и возвращает значение типаfloat. Тело функции не указано за её объявлением изначит для создания исполняемого файла тело функциинеобходимо реализовать в другом месте. В связи сиспользованием спецификатора inline, прииспользовании этой функции её вызов будет замененинструкциями, из которых она состоит.

В строке 11 объявляется и реализуется третья посчету функция программы, main. Функция не принимаетникаких значений и возвращает значение целого типаint. Это главная функция и с неё начинается исполнениепрограммы. Тело функции main ограниченооткрывающей фигурной скобкой в строке 12 изакрывающей фигурной скобкой в строке 19.

В строке 13 вызывается функция printf модулястандартного ввода/вывода. Несмотря на то, что в данномвызове не производится формированного вывода,необходимость использования printf обусловлена тем, чтотребуется произвести вывод без перехода на следующуюстроку. В свою очередь, оператор puts автоматическидополняет вывод переходом на следующую строку.

В строке 14 выполняется вызов функции print_pi,реализация которой выполнена в строках 4-7.

В строке 15 вызывается функция printf. В данномслучае printf мог быть заменен на вызов puts(";"); .

В строке 16 объявляется переменная плавающеготипа float с идентификатором pi_value, котораяинициализируется результатом выполнения функции pi().

В строке 17 производится вызов функции printf,выполняющей форматированный вывод переменнойpi_value в соответствии с шаблоном вывода, переданнымпервым аргументом "pi = %f;\n" .

Page 217: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

217

В строке 18 вызывается оператор return, которыйпомещает в регистр общего назначения eax результатвыполнения функции, в данном случае 0, и завершает еёработу. В связи с тем, что это главная функцияпрограммы, происходит завершение работы программы,а код возврата передается вызывающей программе, т. е.ЭТ.

В строках 21-24 реализована функция pi. В строке 21содержится её объявление. Оно необходимо дляоднозначной идентификации реализуемой функции. Телофункции ограничено фигурными скобками,открывающими в 22 строке и закрывающими в 24 строке.Тело функции состоит из вызова оператора return,который возвращает в точку вызова значение константыM_PI, объявленной в файле math.h с помощью директивыпредпроцессора #define. Так как при объявлении этойфункции в строке 9 использован спецификатор inline прикомпиляции исходного текста програмы вместо floatpi_value = pi(); будет использоваться выражение floatpi_value = M_PI;

В строке 25 оставлена пустая строка.На рисунке 2 представлен результат выполнения

программы.

Рисунок 2 — Результат выполнения программы,соответствующей исходному тексту программы нарисунке 1

Так как из математической библиотеки mathиспользуется только константа, а функции не

Page 218: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

218

используются, при компиляции не обязательно указыватьключ -lm для компоновщика. Предпроцессор заменитстроку 2 на содержимое файла math.h, в котором иобъявлена константа M_PI. После этого возможна сборкаисполняемого файла, т. к. вся необходимая информациядля этого будет доступна для компилятора икомпоновщика.

В случае возврата значения 1 командой сборкиисполняемого файла произойдет запуск собранногофайла a.out, находящегося в текущем каталоге.

Вывод первой строки реализован по частямфункциями строк 13, 14 и 15. Вывод второй строки, сокругленным значением дробной части, производитсяфункцией в строке 17.

Похожие возможности предоставляет механизм,реализованный в ОС под названием разделяемыебиблиотеки. Он будет рассмотрен в следующих разделах.

Page 219: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

219

3.6. Область видимости

Все переменные хранятся в ОЗУ. Для храненияпеременных программ ОС использует два отдельныхучастка памяти: область стека и область кучи. Стек –участок ОЗУ размером от нескольких килобайт донескольких мегабайт, выделяемый ОС для программы сцелью кратковременного хранения некоторых значений.Куча – все ячейки ОЗУ, не используемые другимипрограммами, включая ОС, и прошивками аппаратногообеспечения. Память на стеке выделяется один раз присоздании процесса и ОС не вмешивается в процесс еёиспользования. Размер доступной памяти в области кучипостоянно меняется в зависимости от режимов работызапущенных процессов. ОС контролирует распределениеэтой памяти, но не вмешивается в то, как выделеннаяпамять используется программой для своих нужд,поэтому память в области кучи также называютдинамической памятью.

В примерах, приводимых ранее, все переменныеобъявляются и инициализируются на стеке. Например:

int i;

Для создания переменной в области кучииспользуется одна из специальных функций. Память,выделенную в области кучи, необходимо очищать отпредыдущих значений и освобождать до завершениявыполнения программы. Более подробно работа спамятью в области кучи будет рассмотрена всоответствующем разделе.

Программа gcc может выполнятьдезасамблерирование исходного текста программы наязыках программирования в ассемблерный текст

Page 220: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

220

нескольких нотаций. Для этого используется ключ -S,например:

gcc 1.c -S -masm=intel

В результате дезасемблирования программы,содержащей выражения на языке Си, которые объявляютдве переменные и инициализируют их некоторымизначениями

int i = 0;int j = 2;

был получен текст программы на языке ассемблер всинтаксисе masm

mov DWORD PTR [rbp-12], 0mov DWORD PTR [rbp-8], 2

Обычно одной строчке на языке Си соответствуетмножество команд на языке ассемблер, однако вприведенном примере соответствие однозначное. Невдаваясь в подробное описание работы со стеком спомощью ассемблерных инструкций отметим, дляхранения данных на стеке идентификаторы переменныхне используются. Переменная хранится как смещение отмаксимального значения в регистре микропроцессораrbp. Экскурс в ассемблерные инструкции сделан, чтобыаргументировано показать, что идентификаторпеременной нужен только для удобства при работе сисходными текстами программ. Следствием из этоговывода является возможность использовать один и тотже идентификатор для нескольких переменных. Этотприем настоятельно не рекомендуется и категорически

Page 221: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

221

запрещен для начинающих программистов!Наиболее часто один и тот же идентификатор

переменных используется для счетчиков циклов,указателей на временные ресурсы. Этот подход оправдантолько в том случае, если программа пишется на основехорошо написанного технического задания,редактирование которого не предполагается. Впротивном случае могут возникать сложные для поиска иисправления ошибки.

Пример использования одного идентификатора дляразличных переменных

int i;if ( условие ) {

int i;...

}

Рисунок 1 — Исходный текст программы,демонстрирующей область видимости переменных

Page 222: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

222

После прохождения открывающей фигурной скобки,появляется возможность использовать такой жеидентификатор переменной, однако значение,объявленное до открывающей фигурной скобки,становиться недоступным.

Если текст программы на рисунке 1 непонятен,необходимо перечитать построчные описания исходныхтекстов программ пунктов 3.1-3.5. Далее будут даныпояснения, касающиеся только области видимости.

Объявленная и инициализированная переменнаяцелого типа с идентификатором i после выполнениявыражения в строке 4 будет равна 0. Оператор printf впятой строке выведет значение 0. В седьмой строкеобъявлена и инициализирована переменная сидентификатором i, однако эта переменная расположенав ячейках памяти, отличных от переменной, объявленнойв строке 4, т.к. между этими переменными присутствуетоткрывающая фигурная скобка.

Открывающая фигурная скобка условно можетсчитаться операцией со стеком. В языке Си переменнаяможет быть объявлена в любом месте, однакофактически операции создания переменных на стекепроизводятся или в начале программы или группируютсяв месте, примерно соответствующем открывающейфигурной скобке. Соответственно, уничтожаются они вконце программы или в области закрывающей фигурнойскобки. Здесь под уничтожением подразумеваетсяизменение указателя области стека, который отделяетиспользуемую память стека от неиспользуемой.Гарантированного затирая ячеек памяти не происходит,а зависит от аппаратного обеспечения, версии ОС,используемой версии компилятора, библиотек,используемых для создания исполняемого файла.

Page 223: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

223

Рисунок 2 — Создание исполняемого файла на основеисходного текста программы рисунка 1, его исполнение

На рисунке 2 представлено содержимое потокавывода программы, полученной из исходного текстарисунка 1. В пункте 3.3 подробно разобрана команда, спомощью которой получается исполняемый файл.

Первая выведенная цифра 0 выведена функциейprintf строки 5. Цифра 1 выведена функцией строки 8.Цифра 2 выведена функцией строки 11. В четвертойстроке вывода выведена цифра 1, соответствующая 13строке исходного текста программы. Последняя строкавывода содержит 0 и соответствует 15 строке исходноготекста программы.

Для управления областью видимости используютсяключевые слова static, extern. Данные спецификаторымогут использоваться как для переменных и констант,так и для функций. В пункте 6.9.1 стандарта языкапрограммирования описано внешнее определение дляфункций, которое используется реже, чем внешниепеременные или константы.

Рассмотрим пример исходного текста программы,суммирующей минимальные значения или любоезначение, если входные аргументы равны. Для учебныхцелей он написан в несколько запуанной манере,

Page 224: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

224

свидетельствующей о плохом структурировании решенияпоставленной задачи. Признаками плохой структуры вданном случае является вызов функции из одного файла,реализованную в другом файле, которая, в свою очередь,вызывает функцию, расположенную в первом файле, сисходным текстом главной функции.

Рисунок 3 — Текст программы файла 03_1.c

В строке 1 используется директива предпроцессора,которая будет заменена предпроцессором на содержимоефайла stdio.h, расположенного в каталоге includeпоставляемого вместе с компилятором. На это указываютскобки в виде знаков < и > .

В строке 2 директива предпроцессора указывает нанеобходимость включения в текст программысодержимого заголовочного файла 03_2.h, который будетописан далее. Файл 03_2.h должен быть расположен втом же каталоге, что и файл 03_1.c. На это указываютскобки в виде двойных кавычек.

Page 225: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

225

В строке 4 объявление и реализация функции сидентификатором min, принимающая два аргументацелочисленного типа с идентификаторами a и b ивозвращающая целочисленное значение. Функциявыполняет поиск минимального значения из двухпереданных. Тело функции ограничено фигурнымискобками. Открывающая скобка стоит в строке 5,закрывающая скобка в строке 7.

В строке 6 находится единственная строка функцииmin, являющаяся вызовом оператора return, которому вкачестве аргумента передается оператор выбора,состоящий из символа « ? » и символа « : ». Операторвыбора выполняет выражение a < b. Если условиеверное, т. е. a — наибольшее значение, значит оно будетвозвращено оператору return, во всех других случаяхоператору return будет передано значение b. Операторreturn завершит выполнение функции min и вернетзначение в точку вызова.

В строке 9 объявление главной функции программы.Тело функции ограничено фигурными скобками. Функцияначинается в строке 10 и завершается в строке 18.

В строке 11 объявлена целочисленная переменнаятипа int с идентификатором а, инициализированнаязначением 3.

В строке 12 объявлена целочисленная переменнаятипа int с идентификатором b, инициализированнаязначением 4.

В строке 13 объявлена целочисленная переменнаятипа int с идентификатором variable,инициализированная значением 0.

В строке 14 вызывается функция calc, объявлениекоторой выполнено в файле 03_2.h. В функцию в качествеаргументов передаются значения переменных a и b, арезультат выполнения функции присваивается

Page 226: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

226

переменной с идентификатором variable.В строке 15 вызывается функция стандартной

библиотеки ввода/вывода printf. Первым аргументом внеё передается шаблон вывода, содержащий триспецификатора типа %d, которые будут замененызначениями, переданными 2, 3, 4 аргументами.

Строка 16 соответствует вызову строки 14 и 15,однако запись сделана в сокращенном виде в однустроку. Первым аргументом в функцию printf передаетсяшаблон вывода, идентичный шаблону вывода строки 15.Второй аргумент состоит из вызова функции calобъявленной в заголовочном файле 03_2.h. В своюочередь, в функцию calc передаются аргументы,значения переменных a и b. Аргументы 3 и 4 функцииprintf соответствуют аргументам в строке 15.

В строке 17 вызывается оператор return, в которыйпередается значение 1. Оператор завершит выполнениефункции main. Функция main является главной функциейпрограммы, значит программа будет завершена, азначение 1 будет возвращено в вызвавшую её программу,а именно в ЭТ.

Строка 19 соответствует пустой строке в конце файла.

В этом файле функция min объявлена и реализована,однако нигде не использована. А функция calc наоборот,использована, но нигде не объявлена.

Рисунок 4 — Текст заголовочного файла 03_2.h

Page 227: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

227

Файл 03_2.h является заголовочным файлом. Встроке 1 использована директива предпроцессора,которая будет заменена содержимым файла stdio.h,расположенного в каталоге include поставляемого вместес компилятором.

В строке 3 объявляется функция с идентификаторомcalc, которая принимает два целочисленных аргументатипа int с идентификаторами a и b, и возвращаетцелочисленное значение. Однако тело функции в этомфайле также отсутствует.

В строке 4 с помощью спецификатора externобъявляется внешняя функция с идентификатором min,которая была объявлена в файле 03_1.c, где ипредставлено её описание и реализация.

Заголовочный файл и файл с исходным текстомпрограммы отрабатываются как единое целое, в случае,если их имена до расширения имени файла, т. е. допоследней точки, совпадают.

Рисунок 5 — Текст программы файла 03_2.c

В файле 03_2.с в первой строке указана директивапредпроцессора, которая будет заменена содержимымфайла 03_2.h . Благодаря этому в файле 03_2.c доступнафункция min, а функция calc становится доступна приподключении в файле заголовочного файла 03_2.h так,

Page 228: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

228

как это сделано в 03_1.c.В строке 3 объявление функции calc, совпадающее с

объявлением этой функции в файле 03_2.h. Далее следуеттело функции calc, которое ограничено открывающейфигурной скобкой в строке 4 и закрывающей фигурнойскобкой в строке 8.

В строке 5 объявлена целочисленная переменная сидентификатором result и спецификатором static, котораяинициализирована значением 0. Использованиеспецификатора static позволяет создать переменную,ячейки памяти которой не будут освобождаться каждыйраз после её завершения.

В строке 6 использована сокращенная форма записи+= , которая означает прибавление некоторого значенияк переменной слева от этой операции. Справа от этогознака вызывается функция min, которая реализована вфайле 03_1.c . В функцию min передаются аргументы a иb, значения которых получено функцией calc извызывающей её функции.

В строке 7 вызывается оператор return,возвращающий вычисленное значение result в точкувызова функции min.

Следует отметить, в файле 03_2.c не используютсяэлементы стандартной библиотеки ввода/вывода, однаков заголовочном файле 03_2.h указана директиваподключения этой библиотеки. Такое объявлениеназывается рудиментным. Обычно такое встречается втексте программы, если текст изначально был плохоструктурирован или переписывался. При решениипрактических задач практически всегда остаетсярудиментный текст.

Команда получения исполняемого файла, его запуски результат исполнения представлен на рисунке 6. Длякомпиляции программы, состоящей их нескольких

Page 229: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

229

файлов, необходимо указывать их все в определенномпорядке. Сначала указываются файлы с конечнымифункциями, затем те, которые их используют, и в концефайл с функцией main. В остальном строка соответствуеттем, которые использовались в предыдущих примерах.

Рисунок 6 — Создание исполняемого файла из 03_1.c,03_2.h, 03_2.c и результат его исполнения

Первая строка вывода сформирована вызовомфункции printf в строке 15 файла 03_1.c , котораяпроизошла после первого вызова функции calc. Такимобразом, результатом первого вызова функции calc саргументами a=3 и b=4 является 3. Проверка. Меньшимиз a и b является a=3. Начальным значением result вфайле 03_2.c является 0. 3+0=3.

Вторая строка вывода сформирована строкой 16файла 03_1.c , которая выводит значение после второговызова функции calc. Второй вызов функции calcпроизведен с теми же аргументами что и первый, однакополучен результат 6. Это связано с сохранениемпредыдущего результата работы функции calc впеременной result, которая объявлена соспецификатором static и доступна только внутри функцииcalc. Проверка. Меньшим из a и b является a=3. Текущимзначением result в файле 03_2.c является 3. 3+3=6.

Изменение результирующего значения неочевидно итребует поиска функции, которая приводит к такимрезультатам и просмотру исходного текста этой функции.Избежать подобных проблем позволяет предварительное

Page 230: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

230

проектирование программы и подробноекомментирование назначения реализуемых функций.

Page 231: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

231

3.8. Операции прерывания и безусловного перехода

В пункте 6.8.6 стандарта языка программированияописаны операторы безусловного перехода. К нимотносятся: goto, continue, break, return. Приведемпример исходного текста программы, демонстрирующейиспользование операторов безусловного перехода.

Рисунок 1 — Исходный текст программы,демонстрирующей операторы безусловного перехода

В строке 1 используется директива предпроцессора,предписывающая предпроцессору заменить её насодержимое файла stdio.h, находящегося в каталогеinclude, поставляемом вместе с компилятором.

Строка 2 является отступом для визуальногоразграничения команды предпроцессора от команд для

Page 232: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

232

компилятора.Строка 3 — это начало главной функции main, с

которой начинается выполнение всех программ. Функцияне принимает никаких аргументов, т. к. в скобках ничегоне написано, и возвращает значение типа int ввызывающую её программу. Тело функции mainограничено открывающей фигурной скобкой в строке 3 изакрывающей фигурной скобки в строке 21.

Строка 4 содержит объявление трех переменныхцелочисленного типа int с идентификаторами i, summ,max_value. Идентификаторы разъедены символомзапятая, которая называется операцией следования.Операция следования также используется приперечислении аргументов функции.

В строке 5 производится множественное присвоение.Такие строки читаются справа налево. В данном случаезначение 0 будет присвоено переменной сидентификатором max_value, затем значение max_valueбудет присвоено переменной summ. Далее значениепеременной summ будет присвоено значениюпеременной i. Компилятор при обработкемножественного присваивания значение справапомещается в переменные непосредственно из регистрамикропроцессора, что позволяет сэкономить какминимум одну ассемблерную инструкцию.

В строке 6 вызывается функция считывания изстандартного потока ввода scanf. Её первым аргументомявляется шаблон ввода, соответствующийцелочисленному значению. Второй аргумент состоит изидентификатора переменной max_value и унарнойоперации взятия адреса &. В результате выполнениявыражения во втором аргументе функции scanf, в этуфункцию будет передан указатель на переменнуюmax_value, по которому scanf запишет значение,

Page 233: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

233

считанное из стандартного потока ввода, предварительноотформатировав его в соответствии с шаблонов ввода изпервого аргумента.

В строке 7 написан цикл for, цикл с заданнымколичеством итераций. Первое выражение циклапропущено. В начале обучения программированию такделать не нужно. Легче лишний раз сбросить счетчикцикла с помощью первого выражения, чем потратитьзначительное время на поиск ошибки. Второе выражениеуказывает на то, что цикл будет выполняться, покасчетчик цикла — переменная с идентификатором iменьше переменной max_value. Третье выражениеустанавливает скорость изменения счетчика цикла спомощью операции инкремента i++, которыйсоответствует увеличение на единицы. Отличиеинкремента в том, что он выполняется как однаинструкция микропроцессора, а увеличение значенияпеременной на единицу как три инструкции. Тело циклаfor ограничено открывающей фигурной скобкой в строке7 и закрывающей фигурной скобкой в строке 10.

В строке 8 используется оператор условногоперехода if. Для его исполнения сначала вычисляетсявыражение, состоящея из бинарной операции полученияостатка от деления i на 2. Если остаток от деления неравен 0, выполняется выражение после оператора if. Таккак отсутствует фигурная скобка, будет выполненотолько одно выражение, следующее за оператором if().Этим выражением является оператор безусловногоперехода continue, который прерывает выполнениетекущей итерации цикла, т. е. осуществляет действие,идентичное переходу на закрывающую скобку текущейитерации цикла. После этого выполняется третьевыражение i++ оператора for в строке 7, затем второевыражение в строке 7 как проверка условия завершения

Page 234: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

234

цикла. В случае, если i < max_value, происходит переходв тело цикла в строку 8 и т.д.

В строке 9 используется сокращенная записьарифметического выражения, полная версия котороговыглядит так: summ = summ + i; , т. е. производитсяувеличение значения переменной summ на величину i.

В строке 11 вызывается оператор форматированноговывода printf. Первый аргумент состоит из шаблонацелочисленного вывода и служебной последовательности\n, соответствующей переходу на новую строку. Врезультате выполнения этой строки в стандартный потоквывода будет выведено значение переменной summ ивыполнен переход на новую строку.

В строке 13 описан оператор с заданнымколичеством итераций for. В отличие от предыдущегоиспользования в строке 7, в этом случае с помощьюпервого выражения i = 0 задается начальное значениесчетчика цикла. Второе и третье выражениесоответствует циклу for строки 7.

В строке 14 использован оператор условногоперехода if как и в строке 8. Выражением послеоператора условного перехода является операторбезусловного перехода goto, который предписываетначать выполнять выражения после метки lab в строке16. Если остаток от деления i на 2 равен 0, goto не будетвыполнено и будет выполнена строка 15.

Строка 15 соответствует строке 9.В строке 17 оператор условного перехода if

предписывает выполнить оператор break в случае, еслизначение переменной summ больше 1000. Операторbreak прерывает выполнение цикла или операторамножественного выбора switch.

В строке 19 вызывается оператор printf,соответствующий вызову в строке 11.

Page 235: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

235

В строке 20 использован оператор return,возвращающий значение 0 в вызывающую функцию, т. к.оператор использован в функции main, возврат значенияпроизойдет в вызывающую программу, ЭТ.

Рисунок 2 — Создание исполняемого файла на основеисходного текста программы рисунка 1, его исполнение

На рисунке 2 представлен результат двухкратноговызова программы, полученной из исходного текстапрограммы на рисунке 1. Первая команда вызываетпрограмму, выполняющую создание исполняемого файлаиз исходного текста программы и передает ей в качествеаргументов имя файла с исходным текстом, ключ -o,указывающий имя создаваемого исполняемого файла, вданном случае 01. Далее использована логическаяоперации И, второй аргумент которой является вызовомсозданного исполняемого файла из текущего каталога.

После запуска программы её исполнениеостановится в строке 6, пока не будет введено значение ине нажата клавиша Enter. Если ввести значение 11, тобудет выполнен расчет сумм всех четных чисел до 11,т. е. 0+2+4+6+8+10 = 30. За суммирование отвечаеттекст программы 7-10 строк.

Вторая строка в терминале будет выведенаоператором printf строки 11. Далее будет выполнен

Page 236: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

236

второй цикл, в котором оператор continue замененоператором goto и меткой lab: , а также добавленоусловие прерывания цикла for в строке 17,предписывающее прекратить выполнять цикл, если приисполнении строки 17 значение переменной summ будетболее 1000.

Третья строка вывода сформирована операторомprintf в строке 19.

Таким образом при первом запуске программыпосчитана сумма всех четных чисел до введенного числа11, которая равна 30. Второй цикл также посчитал суммувсех четных чисел до 11, которая равна 30, прибавляяпостоянно значения к переменной summ. Таким образомпрограмма рассчитала удвоенную сумму всех четныхчисел до 11.

Второй запуск не требовал повторного созданияисполняемого файла, т. к. изменения в него невносились. При повторном запуске программы входнымзначением стало 100. Сумма всех четных чисел до 100равна 0+2+4+...+98 = 2450. Удвоить рассчитаннуюсумму не получилось, т. к. она больше 1000, а значитоператор break прекратил выполнение второго цикла привыполнении первой итерации цикла.

Следует обратить внимание на тот факт, чтооперация получения остатка от деления от 0, в отличиеот деления на 0, не вызывает арифметическогоисключения и программа продолжает работать.

В стандарте языка программирования такжеописаны и другие операторы прерывания выполненияпрограммы. Например, abort() (пункт 7.22.4.1) и exit()(пункт 7.22.4.4) библиотеки stdlib, поставляемой вместе скомпилятором. А также ряд функций, схожих с ними подействию: _Exit() (пункт 7.22.4.5), quick_exit() (пункт7.22.4.7).

Page 237: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

237

Функции семейства at_exit (void (*func) (void));(пункт 7.22.4.2) позволяют задать функцию, котораябудет вызываться перед нормальным завершениемпрограммы. Её можно использовать для освобождениявсей выделенной в процессе работы программы памятиили освобождения других ресурсов, т.е. для сборкимусора. Под мусором здесь подразумеваетсяиспользованные ресурсы, которые больше не нужны длявыполнения инструкций программы.

В разделе 7.22.4 Коммуникация с окружением, естьописание других функций, схожих с приведеннымиранее.

Page 238: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

238

3.9. Стиль программирования

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

В данном разделе под стилем программированияподразумевается исключительно правило оформленияисходного текста программы. На сегодняшний деньнаиболее популярными являются две нотации: UNIXнотация и венгерская нотация. Первая из нихподдерживалась сообществом UNIX на протяжениидесятилетий. Вторая поддержана MicrosoftTM иразработчиками, программирующими на языке С++.Следует отметить, язык С++ не является надмножествомязыка Си. На сегодняшний день, в целях недопущенияошибок лучше считать, что С++ также похож на Си, каки PHP.

К базовым правилам стиля программированияследует отнести следующее:

- исходный текст программы пишется длякомпилятора, а оформляется для человека;

- безобразно, зато единообразно;- чем более насыщенный текст программы, тем

проще сравнивать объем и сложность, однако сложнеечитать и изменять.

Чтобы сформировать собственный стильпрограммирования, необходимо взять за основу стиль,предложенный авторами языка. Он исчерпывающепредставлен в книге «Язык программирования Си»

Page 239: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

239

Брайена Кернигана и Денниса Ритчи. В кругахразработчиков он называется K&R. Только в этом случаеможно предпринять попытку понять, какие проблемарешает Си, в чем его красота и почему миллионы строктекста написаны именно на нем.

Одним из требований при написании исходноготекста программы является соблюдение принятого вданной группе разработчиков стиля программирования.Часто он изложен в соответствующем руководстве илирекомендуется некоторый набор исходных текстов дляобразца. Использование в группе разработчиков одногостиля позволяет упростить чтение исходного текстапрограмм, когда структура файла схватывается налету итребует внимательного прочтения всего текста.

Приведем рекомендуемый набор правил дляоформления исходного текста программ.

1. Длина строки не должна превышать 100 строк.

2. Для задания идентификаторов типов, констант,переменных, указателей, функций должныиспользоваться разные правила. В идентификаторахстоит избегать аббревиатур, двояко понимаемыхсокращений и слишком коротких названий.

Например:

#typedef int digit; // Переопределение типа. Все типы

// пишутся строчными буквами.

#typedef MAX_BUFF_SIZE 164 // Идентификаторы констант

// пишутся заглавными буквами

Page 240: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

240

int *ptr_counter; // Указатели выделяются с помощью

// последовательности символов «_ptr».

struct telnomber { char country_code; // Определение переменной в

UNIX нотации. // Разделителем слов в

идентификаторе // является символ «_». digit nomber;};void set_telnomber (struct telnomber * tel_nom); //

Название функции // содержит слово действие set, // разделителем слов является

«_».

3. При объявлении экземпляров объектовиспользовать похожие идентификаторы.

Например:

void set_telnomber (struct telnomber * tel_nom); // Название аргумента

// tel_nom, созвучно своему типуstruct telnomber

// и функции set_telnomber().

4. Каждая переменная объявляется в отдельной строке.

Например: char country_code; int nomber;

Page 241: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

241

5. Всегда использовать отступы в места, где посинтаксису языка используются или подразумеваютсяфигурные скобки. По всему тексту программыиспользуются отступы одинаковой кратности, т. е. всеотступы кратны 4 пробелам. Количество пробелом можновыбирать самостоятельно. Отступы в 2 пробела плохоразличимы при исходных текстах более 100 строк ииспользовании шрифтов, отображающих пробелы ужеостальных символов. Отступы, кратные более 6 пробеламиспользовать слишком расточительно, из-за ограниченийна ширину строки. Текстовый редактор среды Geanyотводит на строку 72 символа, проводя перед 73-мсимволом непечатаемую вертикальную серую черту. Длямаксимальной переносимости используются пробелы.Горизонтальная табуляция может по разномуотображаться в каждом экземпляре редактора, такимобразом исходный текст с табуляцией будет удобночитать только в том редакторе на той ЭВМ, в котором оннаписан. Однако идеологически, горизонтальнаятабуляция является более правильным решением, таккак она является специальным символом, специальноизобретенным для этой цели.

If (a < d) assert (a);else { if (a == d) { assert ("стороны многоугольника равны"); } else { assert (d); }}

Page 242: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

242

6. Пробелы необходимо использовать не только длясоблюдения синтаксических правил, но и для улучшениячитаемости исходного текста программы. В некоторыхслучаях они избавляют от синтаксических ошибок ( j+++i ). В правиле 1 комментарии написаны свыравниванием пробелами для повышения читаемости.Рекомендуется использовать пробел между типом исимволами «*» или «&», но не использовать между этимиоперациями и идентификаторами переменных (int *digit;digit = &value).

Пример неправильного форматирования:

If(a<d)assert(a);else{if(a==d){assert ("стороны многоугольника равны");}else{assert(d);}}

Пример:

#define MAX_TEMP 94 // Максимальная температура

#define MIN_TEMP 11 // Минимальная температура

#define START_TEMP 34 // Начальная температура

#define STOP_TEMP 80 // Конечная температура

7. Использовать фигурные скобки, когда телофункции пустое или отсутствуют выражения.

Например:

void send_dev_null (char value) {};if (mass > 0) {}else assert(mass);

Page 243: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

243

8. Использовать круглые скобки для группировкивыражений по смыслу и для упрощения пониманияпоследовательности операций, даже если этого нетребует приоритет операций.

Например:

if (((a > 0) && (b > 0)) || (c < 10)) ...

9. Всегда пишите оператор switch, используяодинаковый шаблон форматирования.

Например:

switch (value) { case 1: function_1 (); break; case 2: case 3: function_2 (); break; default: function_1 ();}

10. Объем текста функции не более одного экрана (неболее 50 строк). Если в функции более 50 строк, обычноозначает, что это решение задачи плохоструктурировано.

11. В случае переноса аргументов вызываемойфункции или разрыва строки необходимо делатьзначительный отступ пробелами. Такие фрагментытекста программы становятся зрительными «якорями»,за которые цепляется взгляд и значительно упрощает

Page 244: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

244

ориентирование в тексте программы.Например:

int result = function_1 (arg_1, arg_2, arg_3, arg_4);

12. Все объявления функций и глобальных объектовнеобходимо производить в заголовочных файлах.Локальные переменные необходимо объявлятьнепосредственно перед её первым использованием.

13. Комментарии не следует писать в конце строкитак, чтобы они были не видны.

14. В начале файла нужен многострочныйкомментарий, описывающий что делает текст программыэтого файла, его лицензионные ограничения. Еслинеобходимо, указывается способ использования в составепрограммного комплекса или особенности компиляции.

15. Для визуального разделения блоков исходноготекста желательно использовать пустые строки.

Для повышения переносимости текста программнеобходимо также использовать правила MISRA C,которые не являются обязательными к исполнению, носледованием им позволяет решить ряд проблем.

Page 245: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

245

4. Язык программирования Си. Составные типыданных

Человеческий мозг, по разным оценкам, можетоперировать одновременно 5 – 8 значениями. С другойстороны, большинство задач для своего решения требуетзначительно большее количество значений. Одним изспособов преодоления этого противоречия являетсяиспользование наборов данных, объединяемых поразному признаку.

Однотипные данные, в соответствии с определениемтипов, часто обрабатываются одинаковымипоследовательностями команд. Для такой обработкииспользуются составные типы — массивы, иимитируемые с помощью адресной арифметикимногомерные массивы.

Отдельно выделяется обработка текста. Обработкатекста является одним из важнейших направлений дляпрограммирования. Текст состоит из однотипныхзначений, поэтому для его обработки такжеиспользуются массивы.

Значения разных типов могут описывать один объект,одно событие или явление. В таком случае часто ихобработка производится в одной функции или одноммодуле. В этом случае используются структуры.

В некоторых случаях значение одного типанеобходимо интерпретировать как значение другоготипа. Для разной интерпретации одной и той же областиОЗУ, а также для экономии ОЗУ используется типобъединение.

Для повышения читаемости исходного текстапрограммы некоторые константы можно заменить насокращения или аббревиатуры. Для этого используетсятип перечисления.

Page 246: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

246

В языке программирования существует тип битовыеполя, который используя ряд операций позволяетизменять значения отдельного бита, что позволяетэкономить память ОЗУ, однако требует большемикропроцессорных операций.

4.1. Составные типы данных: массивы4.1.1. Объявление и инициализация массивов

Массив – набор объектов одного типа,расположенных в ОЗУ последовательно друг за другомбез промежутков.

Формат объявления массивов приведен в пункте6.7.6.2 стандарта языка программирования. Приведемобъявление одномерного массива из 5 элементов,каждый из которых имеет тип целого числа int.

int array[5];

В начале выражения, объявляющего массив,указывается тип элементов массива (int), далее следуетидентификатор переменной (array). Затем в квадратныхскобках указывается количество элементов массива – 5.

Объявленный массив состоит из пяти элементов. Дляобращения к каждому элементу необходимоиспользовать идентификатор массива и индекс,указывающий на смещение от начала массива. Такимобразом, после объявления массива будут доступныследующие элементы:

array[0] , array[1] , array[2] , array[3] , array[4]

Еще раз обратим внимание, при инициализации

Page 247: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

247

массива указывается количество элементов массива. Приобращении к элементам массива используется смещениеот начала массива. Подробно ознакомится с такимподходом можно на примере абстракции «машинаПоста».

Инициализация значений массива константнымизначениями описана в пункте 6.7.9. стандарта языкапрограммирования. Следует учесть, в этом разделеописаны все возможные случаи для разных составныхтипов, поэтому как не парадоксально, без знания языкапрограммирования сложно понять, что там написано. Вданном разделе приведено максимально простоеописание. Для задания начального значения каждомуэлементу массива используются различные приемы,однако они доступны только в момент объявлениямассива.

int array[5] = {1, 2, 3, 4, 5};

Выполненная таким образом инициализацияприведет к заданию следующих значений.

array[0] = 1, array[1] = 2, array[2] = 3, array[3] = 4, array[4] = 5.

Если при инициализации задается каждое значение,размер массива можно не указывать. Компилятор сампосчитает количество элементов массива.

int array[] = {1, 2, 3, 4, 5};

В приведенном примере массив с идентификаторомarray будет состоять из 5 символов.

С помощью фигурных скобок может производится

Page 248: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

248

инициализация нескольких элементов массива. В этомслучае, остальным значениям будет присвоено значение0. Однако не стоит забывать указывать правильноеколичество элементов массива.

int array[5] = {1, 2};

Приведенная инициализация приведет к заданиюследующих значений:

array[0] = 1, array[1] = 2, array[2] = 0, array[3] = 0, array[4] = 0.

Обнуление значений массива при инициализацииявляется следствием предыдущего примера:

int array[5] = {0};

Данная инициализация задает значение элемента синдексом 0 равное 0, а все последующие значения такжеравны 0. В результате все элементы массива будут равны0.

array[0] = 0, array[1] = 0, array[2] = 0, array[3] = 0, array[4] = 0.

Для задания значений элементам массиваиспользуется цикл.

int array[10] = {0};int count = 0;for ( ; count < 10; count++)

array[count] = count;

Page 249: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

249

Начиная со стандарта ISO/IEC 9899:1999 в языке Сипоявилась возможность объявлять массивы, количествоэлементов в которых задается в режиме исполнения, т. е.в момент работы программы.

int array[n];

Для корректной работы приведенного примеранеобходимо чтобы значение n было задано до строки,инициализирующей массив с её использованием.

Приведенные выше примеры создают массив настеке. Область стека ограничена и не позволяетиспользовать все пространство ОЗУ. Для массивов сколичеством элементов более 50 рекомендуетсяиспользовать память в области кучи. При использованииболее 500 элементов, настоятельно рекомендуетсяиспользовать память в области кучи, т. е. динамическивыделяемой памяти.

Выделение и освобождение памяти в области кучисчитаются медленными операциями, поэтому нерекомендуется использовать динамическую память дляпеременных, состоящих из одного значения. Прииспользовании массива операция выделенияприменяется один раз и делает доступными множествопеременных, поэтому использование медленнойоперации допустимо.

Выделение памяти для размещения массива будетпредставлено в следующем разделе.

Page 250: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

250

4.1.2. Обращение к элементам массива

При работе с массивами возможно получениедоступа к его элементам как последовательно, так ивыборочно к произвольному элементу. При этомпоследовательный доступ является многократнымвыборочным доступом с последовательноувеличивающимся счетчикам смещения.

Основными операциями при работе с массивамиявляются: инициализация значений и изменениепроизвольного элемента массива.

Рассмотрим исходный текст программы,инициализирующий элементы массива, изменяющий дваэлемента массива и выводящий результат в стандартныйпоток вывода после каждого набора операций смассивом. Исходный текст программы состоит из трехфайлов: 01.c — текст программы, array_output.h —заголовочный файл функции вывода в стандартный потоквывода, array_output.c — текст программы функциивывода в стандартный поток вывода.

Рисунок 1 — Исходный текст файла заголовка array_output.h

Первая строка на рисунке 1 является директивойпредпроцессора. При её обработке она заменяется насодержимое файла stdio.h, расположенного в каталогеinclude поставляемого вместе с компилятором.

Третья строка объявляет функцию с

Page 251: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

251

идентификатором array_output, принимающую указательна объект типа int с идентификатором array ипеременную целочисленного типа int с идентификаторомarray_size. Функция не возвращает никаких значений. Изназваний аргументов функции следует, что первыйаргумент является указателем на массив, а второйсообщает, сколько элементов содержится в массиве.Более подробное объяснение того почему указатель напеременную целочисленного типа может бытьинтерпретирован как указатель на массив, будет вследующих разделах.

Перейдем к исходному тексту программы на рисунке2.

Строка 1. В ней использована директивапредпроцессора, которая на первом этапе компиляциибудет замена на содержимое заголовочного файлаarray_output.h, представленного на рисунке 1. Имя файлауказано в двойных кавычках, поэтому заголовочный файлдолжен быть расположен в том же каталоге, что и файлarray_output.c. С помощью этой строки подключаетсястандартная библиотека ввода-вывода, котораянеобходима для использования функций puts и printf.

В строке 3 указан идентификатор функции,принимаемые аргументы и возвращаемое значение сцелью определения однозначного соответствияреализуемой функции объявленному ранее прототипу.

Строка 4 содержит один символ открывающуюфигурную скобку с которого начинается тело функцииarray_output.

В строке 5 объявляется целочисленная переменная сидентификатором count, которая инициализируетсязначением 0. Всегда, независимо от стажапрограммирования, необходимо инициализировать всеобъявляемые переменные.

Page 252: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

252

Рисунок 2 — Исходный текст функции выводамассива на экран array_output.с

В строке 6 объявлен цикл for, счетчиком циклакоторого является переменная с идентификатором count.Начальным значением счетчика является 0. Несмотря нато, что счетчик цикла был инициирован строкой выше,всегда, за очень редким исключением, необходимоинициировать счетчик цикла заново. Причина в том, чтов процессе редактирования исходного текста программыв течение длительного периода времени, текстпрограммы может измениться произвольным образом инет гарантии, что между строкой инициализации ициклом не появится еще несколько циклов.

Условие завершения выполнения цикла count <array_count. Шаг приращения инкремент, т. е. плюс 1.Тело цикла for ограничено открывающей фигурнойскобкой в строке 6 и закрывающей фигурной скобкой встроке 9.

Тело цикла for состоит из двух выражений, поэтомуиспользование фигурных скобок в данном случаеобязательно.

В строке 7 написан оператор форматированного

Page 253: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

253

вывода printf. Его первый аргумент, являющийсяшаблоном вывода, будет выведен при вызове этогооператора, а спецификаторы типов %d будут замененызначением переменной count и значением элементамассива array со смещением count.

В строке 8 используется условие выбора. Выражениеоператора if сравнивает значение count, изменяемое прикаждой новой итерации цикла, со значением array_size,уменьшенное на 1. Далее следует функцияформатированного вывода, содержащая только текстовыйшаблон из двух символов: запятой и пробела. Текст встроке 8 выведет символы запятая и пробел четыре раза,для элементов array[0], array[1], array[2], array[3].Назначение этой строки в правильном оформлениивывода программы. Функция printf стандартнойбиблиотеки ввода-вывода использована по той причине,что функция не форматированного вывода puts вставляетпосле выводимых символов переход на новую строку,который в данном случае не требуется.

В строке 10 вызывается функция неформатированного вывода puts, выводящая точку.

В строке 11 закрывающая фигурная скобказавершает тело функции array_output.

Перейдем к рассмотрению исходного текстапрограммы в файле 01.с, представленного на рисунке 3.

В строке 1 используется директива предпроцессорадля включения в текст программы содержимогозаголовочного файла стандартной библиотеки ввода-вывода. В тексте программы файла 01.c не используютсяфункции ввода-вывода, строка 1 осталась там из-за того,что в начале написания примера планировалосьразместить весь текст программы в одном файле, однакоего размер оказался слишком велик и функции выводабыли перенесены в отдельный файл, а директива

Page 254: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

254

осталась. Данная ошибка никак не скажется наэффективности программы, т. к. любая библиотекавключается в исполняемый файл только один раз,независимо от количества её подключений.

Рисунок 3 — Исходный текст программы,демонстрирующей основные операции с массивами

Однако лишние объявления необходимо избегать прииспользовании специальных библиотек, потому чтоможет сложится ситуация, когда её функции нигде в

Page 255: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

255

программе не используются, но от компилятора икомпоновщика требуется добавление её кода висполняемый файл. Невозможно гарантировать, чтокомпоновщик правильно обработает эту ситуацию и невключит ненужную библиотеку.

Строка 2 содержит директиву предпроцессора,которая будет заменена содержимым файла stdlib.h изкаталога include, поставляемого вместе с компилятором.Использования функций стандартной библиотеки нетребует использования дополнительных ключей длякомпоновщика. В файле 01.c применяются функцииmalloc и обратная ей free.

В строке 3 содержится директива предпроцессора,которая будет заменена на содержимое файла memory.h.В этой библиотеке объявлена функция memset, котораязакомментирована в тексте программы. Такая заготовкапозволит продемонстрировать второй приеминициализации значений массива. Файл memory.hрасположен в каталоге include и поставляется вместе скомпилятором. Использование библиотеки memory нетребует указания специальных ключей длякомпоновщика.

В строке 4 используется директива предпроцессора,предписывающая заменить эту строку содержимымфайла array_output.h. Этот файл должен бытьрасположен в том же каталоге что и файл 01.c. На этоуказывают двойные кавычки, в которые заключено имяфайла. Подключаемый заголовочный файл содержитвсего одну функцию array_output, которая и используетсяв программе.

Строка 6 объявляет константу с идентификаторомARRAY_SIZE и значением 5. Данная константасоответствует количеству элементов в массиве.Объявление константы с помощью директивы

Page 256: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

256

предпроцессора позволяет изменять размер массива иодновременно вносить все необходимые изменения дляобработки массива нового размера, заменив цифру 5 встроке 6 на любое другое значение до 1000. В случаепревышения 1000 повышается возможность разрушенияпрограммы в связи с переполнением стека.

В строке 8 содержится начало реализации функцииmain. Функция не принимает никаких значений, этовидно из отсутствия символов между скобками ивозвращает значение типа int. Возвращаемое значениебудет передано в вызывающую программу, которойявляется ЭТ. В этой же строке содержится открывающаяфигурная скобка, с которой начинается тело функцииmain. Закрывающая скобка содержится в строке 31.

В строке 9 объявляется и инициализируетсяпеременная с идентификатором array. Переменная имееттип указателя на целочисленный тип и инициируетсязначением NULL. NULL — означает указатель в никуда.Объявленный в этой строке указатель будет указывать наначало массива и все операции с элементами массивабудут доступны только с помощью этого указателя. Еслизначение адреса, хранимое в переменной указателябудет изменено, будет потеряна возможность работы сэлементами массива.

В строке 10 с помощью функции malloc выделяетсяпамять в области кучи размером, равным размерупеременной типа int умноженного на 5, т. е. под 5переменных типа int. В случае успешного выделенияпамяти адрес начала выделенного участка памяти вобласти кучи присваивается значению указателя array.После выполнения этой строки, программа получитпамять для массива из общей свободной памяти ОЗУвычислительной машины.

Строка 11 содержит объявление переменной типа int

Page 257: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

257

с идентификатором count, инициализированнуюзначением 0.

Строки 13, 16, 23 начинаются с символов // иявляются комментариями. Все символы отпоследовательности // до символа конца строкипропускаются компилятором при обработке исходноготекста программы.

В строках 14, 21, 27 вызывается функцияarray_output, реализованная в файле array_output.c. Еёаргументами является указатель на начало массива arrayи количество элементов массива, переданное константойARRAY_SIZE. После выполнения этой функции встандартный поток вывода будут распечатаны значенияэлементов массива по указателю array.

Строка 17 содержит цикл с заданным количествомитераций, цикл for. Первое выражение обнуляетзначение счетчика цикла count. Второе выражениеявляется сравнением счетчика цикла count с условиемпрекращения выполнения цикла константойARRAY_SIZE. Пока счетчик цикла меньше константы,будут выполнены операторы тела цикла. Третьевыражение определяет шаг приращения счетчика цикла,который равен инкременту, т. е. увеличению на единицу.Тело этого цикла не ограничено фигурными скобками,поэтому телом может являться только одно выражение.

В строке 18 написано тело цикла for строки 17. Оносостоит из присвоения константного значения 1элементу массива по указателю array cо смещениемcount.

Строка 19 закомментирована. Она содержит вызовфункции memset, в которую передается три аргумента:указатель на массив array, приведенный к типу указателяна void, т. е. указателю на переменную неизвестноготипа. Внутри функции memset будет изменяться память

Page 258: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

258

по этому указателю. Вторым аргументом являетсяконстантное значение 0, которым будет заполнятьсяпамять. Третий аргумент состоит из вызова оператораsizeof, возвращающий размер массива array.

Строки 17 и 18 изменят все значения массива на 1.Если закомментировать строки 17, 18 иразкомментировать строку 19, всем элементам массивабудет задано значение 0. После изменения набора строкнеобходимо заново откомпилировать программу и послеэтого запустить.

В строке 24 производится изменение значениямассива с индексом 2. Это будет третье значениемассива, т. к. 2 — это смещение. После смещения на 2элемента происходит доступ к третьему элементу.Элементу присваивается удвоенное значение счетчикацикла for, записанного в строках 17,18.

В строке 25 производится присвоение последнемуэлементу массива array со смещением 4 значенияконстанты ARRAY_SIZE = 5.

В строке 29 выполняется освобождение памяти вобласти кучи, выделенной для массива по указателюarray с помощью функции free.

В строке 30 оператор return возвращает значение 0 ввызывающую её программу, т. е. ЭТ. Под возвратомзначения подразумевается помещение в регистр eaxзначения 0 и завершение работы программы.

Для создания исполняемого файла и его запускаиспользовалась комбинация команд из вызовакомпилятора gcc и запуска самой программы ./01(Рисунок 4).

Исходный текст программы написан в трех файлах.Из них текст программы содержат два файла, поэтомудля компилятора необходимо указать два файла стекстом программы array_output.c и 01.c. Сначало

Page 259: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

259

указываются файлы с текстом функций, в конце файл сфункцией main. Ключ -o позволяет задать имяисполняемого файла 01. Ключ -Wall предписываеткомпилятору все предупреждения считать ошибками.Таким образом уменьшается возможность допускаошибки по невнимательности.

Рисунок 4 — Компиляция и исполнение программы,демонстрирующей основные операции с массивами

Ключ -pedantic предписывает выполнить проверкуправильности исходного текста программы максимальнострого, исключая всевозможные способы «додумывания»за программиста.

После запуска программы выведено три строки иработа программы была завершена. Все строки выводасформированы вызовами функции array_output.

Первая строка сформирована вызовом в строке 14файла 01.c. Вывод показал что все элементы массиваимеют значение 0. В соответствии со стандартом языкапрограммирования функция malloc не должна обнулятьпамять. Фактически этого и не происходит. При созданиимассивов больших размеров, часть элементов массивовсразу после выделения памяти в области кучи будутиметь значения отличные, от нуля.

Вторая строка вывода сформирована вызововфункции в строке 21 файла 01.c. После проведенияинициализации значений массива константнымзначением 1 в строках 17,18, все элементы будут равны

Page 260: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

260

1.Третья строка сформирована вызовом в строке 27

файла 1.c. Вывод третьей строки будет отличаться отвторой измененными значениями элементов массива синдексом 2 (изменен в строке 24) и с индексом 4(изменен в строке 25). В третьей строке значение синдексом 2 равно 10, а значение с индексом 4 равно 5.

Данный пример продемонстрировал неудобствосовпадения названий файлов и функций. Несмотря наотсутствие жесткого требования к различиям, кправилам формирования имен файлам и функциям,лучше иметь фиксированное правило, которое позволитлегко отличать, где используется название файла, а гдефункции или переменной.

Используемая в строке 19 функция memset можетбыть заменена другими функциями, например calloc —выделяющую и одновременно обнуляющую выделеннуюпамять. Обнулить уже выделенную память можно спомощью функции bzero, а изменить размер ужевыделенной памяти с помощью функции realloc.

Подробное описание текста программы содержиттакже обсуждение различных ситуаций, которые могутпроизойти при изменении подхода к написанию текстапрограммы или использовании другого приема.

В заключении раздела в качестве заметки следуетотметить распространенный прием определенияколичества аргументов массива, используя операциюsizeof. Для этого используется выражение

int elements_count = sizeof array / sizeof array[0];

С помощью этого приема можно узнать количествоэлементов массива, зная только то, что он создан вобласти кучи и тип элемента массива. Работоспособность

Page 261: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

261

этого приема следует проверять на целевой платформе.Не следует забывать, для работы соспециализированными микропроцессорами компиляторязыка Си может не полностью поддерживать стандартязыка программирования. Также может отличатьсяреализация стандартных библиотек.

Page 262: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

262

Page 263: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

263

4.1.3. Сортировка массива

Упорядочивание массива — это первый классалгоритмов, который рассматривается при изучениимассивов. Операции упорядочивания часто являютсяодним из начальных этапом обработки массивов данных.Исключение составляют задачи, в которых важнапоследовательность расположения значений в массиве. Втаких случаях порядковый номер элемента массиваявляется дополнительной размерностью и послеувеличения размерности массива мерностью,содержащую порядковые номера исходного массива, кнему также становятся применимы алгоритмыупорядочивания.

Существует множество алгоритмов упорядочивания,каждый из которых наиболее эффективен в своейобласти. Под эффективность понимается минимизациявремени выполнения или объема используемой памяти.Под областью применения, в свою очередь, понимаютсявиды функциональных зависимостей и прочиехарактеристики исходных наборов данных. Вопросыалгоритмизации, эффективности алгоритмовисследуются теорией алгоритмов. Одним из главныхпроизведений в этой области для программистовявляется четырехтомник Дональда Кнута.

Считается, хороший специалист знает не только какприменить некоторый алгоритм, но так же знает егоограничения, т. е. где его применять не эффективно илиневозможно.

Рассмотрим два алгоритма сортировки qsort ипузырьковый метод. Алгоритм qsort состоит из двухчастей: первая часть алгоритма ищет среднее значениесреди значений элементов массива, вторая выполняетперестановку значений элементов массива таким

Page 264: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

264

образом, чтобы значения большие или меньшие среднегооказывались по одну сторону от среднего. Далеепроизводится разбиение двух полученных половинмассива и выполняется перестановка элементов вкаждой половине. Операция повторяется до полногоупорядочивания всех значений массива. Вычислительнаясложность этого алгоритма увеличиваетсянезначительно при росте объема значений массива.

Второй алгоритм упорядочивания обычно знаком сошкольной скамьи — пузырьковый метод. Его смыслзаключается в сравнении двух ближайших значений и ихперестановка в случае, если результат сравнения неудовлетворяет условию сортировки. Далее производитсясмещение на один элемент и сравнение повторяется.Вычислительная сложность этого алгоритма растетбыстро, потому что в такой постановке алгоритма массивтребуется обойти n2 раз.

Сравнивая эффективность алгоритма qsort ипузырькового метода, нельзя однозначно сказать, какойиз них будет эффективнее. Для примера будет выбранодин из критических случаев, в которых алгоритм qsortне может демонстрировать своих преимуществ.Использован массив с малым количеством элементов,при этом значения элементов распределены неравномерно, и имеется значение, отличающееся отостальных на два порядка.

Пример исходного текста программы представлен на рисунке 1.

Исходный текст программы содержит функциюarray_output, которая объявлена в файле array_output.h(пункт 4.1.2 Рисунок 1) и реализована в файлеarray_output.c (пункт 4.1.2 Рисунок 2).

Далее будет приведено построчное описание толькотех строк исходного текста программы, для которых

Page 265: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

265

ранее не давалось подробного описания.

Рисунок 1 — Исходный текст программыупорядочивания массива различными методами

В строке 4 дано описание функции cmp, котораяпринимает два аргумента, имеющих тип указателя наконстантное значение пустого типа void. Таким образом

Page 266: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

266

в функцию cmp передается два указателя на пустой тип.Тип void используется в случае, когда определитьзаранее тип значения не представляется возможным.Функция возвращает значение целого типа int.Спецификатор static предписывает заменить вызовфункции cmp операторами, составляющими телофункции cmp. Тело функции состоит из операторов встроках 5, 6 и 7. В строке 8 закрывающая фигурнаяскобка завершает тело функции cmp.

В строке 5 объявлена переменная сидентификатором a, являющаяся указателем назначение, имеющее тип константы целого типа. В этойже строке производится инициализация переменной сидентификатором, a значением первого аргумента,переданного в функцию cmp и приведенного к типууказатель на целочисленный тип int.

В строке 6 объявлена переменная b, являющаясяуказателем на константное значение целочисленноготипа int, которое инициализировано значением второгоаргумента функции cmp, приведенного к типу указательна целочисленный тип int. Строки 5 и 6 отличаютсятолько идентификаторами переменных, однако описаниестрок дано немного по разному, чтобы показать разныеспособы словесного описания текста программы.

Строка 7 состоит из вызова одного оператора return,который возвращает результат выражения, описанного впункте 6.5.15 в стандарте языка программирования.Выражение производит сравнение двух значений,расположенных по адресу a и b. Для получения значенийиспользуется операция разыменования адреса,обозначаемая символом звездочка. В случае, еслизначение по адресу a меньше значения по адресу b,оператор return возвратит значение по адресу a, вслучае, если значения по адресам a и b равны или

Page 267: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

267

значение по адресу b меньше значения по адресу a,функция cmp вернет в точку своего вызова значение поадресу b.

В строке 13 объявляется массив с идентификаторомarray, каждый элемент которого имеет целочисленныйтип int. При этом количество элементов массива неуказывается, т. к. в квадратных скобках нет числа. В этойже строке массив инициируется значениями в фигурныхскобках, перечисленных через запятую. Таким образом,после строки 13 будет доступен массив целочисленныхзначений, созданных на стеке и инициированныхзначениями 2, 1, 2, 1, 125.

В связи с тем, что количество элементов массивавычисляется компилятором, необходимо дополнительносоздавать переменную или константу, содержащуюколичество элементов массива. Так как массив создан настеке, количество его элементов меняться не может,поэтому более правильно было бы использовать дляопределения количества элементов массива константу.Объявление массива без указания количества элементовудобно использовать только при работе со строками,которые будут рассмотрены в следующих разделах.

В строке 14 объявляется переменная array_size иинициализируется значением, равным количествуэлементов массива array.

В строке 15 и 34 вызывается функция вывода наэкран значений элементов массива array_output, вкоторую в качестве аргументов передается указатель намассив array и количество элементов в нем.

Строки 17-28 реализуют алгоритм упорядочиванияметодом пузырька. Такое название он получил благодаряхарактеру изменений значений. В таблице 1представлены значения элементов массива после каждойитерации внутреннего цикла for со счетчиком цикла j.

Page 268: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

268

Максимальное значение 125 как бы «ныряет» воснование массива и затем всплывает, попутнорасставляя в правильном порядке остальные значенияэлементов массива.

Таблица 1 — Изменение значений элементов массиваarray при пузырьковой сортировки

count j array[0] array[1] array[2] array[3] array[4]

0 0 2 1 2 1 125

0 1 2 1 2 1 125

0 2 2 1 2 1 125

0 3 2 1 2 1 125

0 4 125 1 2 1 2

1 0 1 125 2 1 2

1 1 1 125 2 1 2

1 2 1 125 2 1 2

1 3 1 125 2 1 2

1 4 1 125 2 1 2

2 0 1 125 2 1 2

2 1 1 2 125 1 2

2 2 1 2 125 1 2

2 3 1 2 125 1 2

2 4 1 2 125 1 2

3 0 1 2 125 1 2

3 1 1 1 125 2 2

3 2 1 1 2 125 2

3 3 1 1 2 125 2

3 4 1 1 2 125 2

4 0 1 1 2 125 2

4 1 1 1 2 125 2

4 2 1 1 2 125 2

4 3 1 1 2 2 125

4 4 1 1 2 2 125

Page 269: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

269

В таблице 1 первый и второй столбец соответствуеттекущим значениям счетчиков циклов, как буд-то ихвывод произведен оператором вывода между строками 26и 27. Последующие столбцы содержат значенияэлементов массива после выполнения итерациивнутреннего цикла. В таблице наглядно представлено,что в процессе сортировки происходит множествоитераций, при которых значения не меняются. Алгоритмкак бы «промахивается», выбирая элементы,расположение которых не будет изменено. Чтобыуменьшить количество таких «ошибочных» сравнений,полное правило пузырьковой сортировки включает в себяограничение, гласящее, что сортировка прекращается,когда все элементы расставлены в соответствующемпорядке.

Подробное построчное описание алгоритмазатрудняет понимание принципа его работы, поэтомуопишем принцип работы строк 17-28. Внешний цикл forсо счетчиком цикла переменной count изменяет индексэлемента массива, со значением которого будутсравниваться все остальные элементы. Переборсравниваемых элементов обеспечивает внутренний циклfor со счетчиком цикла j. Итерация внутреннего циклавыполняет перестановку элементов в случае, еслиэлемент массива с индексом count меньше элементамассива с индексом j. Для перестановки требуетсявспомогательная переменная temp, в которую временноперемещается одно из значений, во избежание егозатирания. Аналогией для перестановки могут являтьсядве корзины яблок. В одной корзине красные яблоки, вдругой зеленые. Для того чтобы поменять яблоки вкорзинах, необходима третья корзина, в которую навремя нужно пересыпать яблоки, например, красные.

Page 270: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

270

Затем из второй корзины в первую пересыпают зеленыеяблоки, а из вспомогательной корзины во вторуюпересыпают красные яблоки. В приведенном примеретакой вспомогательной корзиной является переменнаяtemp.

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

Строка 31 содержит вызов функции qsort,реализация которой содержится в стандартнойбиблиотеке (stdlib). Текущая версия компиляторапозволяет не проводить явного объявления стандартнойбиблиотеки, т. к. она подключается по умолчанию.Функция qsort описана в пункте 7.22.5.2 стандарта языкапрограммирования Си следующим образом

qsort(void *base, size_t nmemb, size_t sizint (*compar)(const void *, const void *)

Последний аргумент функции qsort — это указательна функцию. Указанному прототипу соответствуетфункция программы cmp, указатель на которуюпередается в строке 31.

Для получения исполняемого файла из текстапрограммы на рисунке 1, необходимо выполнитькоманду, приведенную на рисунке 2. Для успешнойкомпиляции необходимо сначала указать файл с текстомфункции array_output, а затем файл с исходным текстомпрограммы 01.c. В процессе компиляции будет выданопредупреждение о неявной декларации функции qsort,т. к. она определена в файле stdlib.h, однако отсутствуетдиректива include, предписывающая использоватьзаголовочный файл стандартной библиотеки.Предупреждение позволяет закончить создание

Page 271: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

271

исполняемого файла.

Рисунок 2 — Создание исполняемого файла

Для запуска программы необходимо выполнитькоманду запуска программы с именем по умолчанию.

./a.out

В результате запуска программы будет полученвывод, соответствующий выводу на рисунке 3.

Рисунок 3 — Результаты отображения стандартногопотока вывода программы

Первая строка вывода сформирована функциейarray_output, вызываемой в 15 строке. В этой строкезначения в массиве располагаются так же, как и приинициализации массива в строке 13.

Вторая строка сформирована вызовом функцииarray_output, вызываемой в строке 34. До этого вызовамассив сортируется в порядке возрастания пузырьковымметодом и сортируется в порядке убывания функциейqsort.

Скорость выполнения кода описываемых реализацийалгоритмов на современном микропроцессоре настолько

Page 272: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

272

велика, что для сравнения скорости их выполнениякаждый из них был выполнен по 100 000 000 раз подряд.Для этого в исходный текст программы был добавлен ещеодин цикл с заданным количеством итераций. Прикаждом запуске один из методов сортировки былзакомментирован. Время исполнения засекалосьстандартной программой time с помощью вызова.

time ./a.out

Кроме того, был реализован полноценныйпузырьковый алгоритм сортировки, завершающий работув случае, если за полный проход внешнего цикла неосуществлялось ни одной перестановки значений.

Также были проведены замеры времени исполненияв разных направлениях, от большего к меньшему инаоборот. Такое исследование не выявило значительныхотличий в продолжительности работы программы.

Напоследок для всех трех алгоритмов был измененнабор входных данных. На вход им был подан ужеотсортированный массив. Численные результаты этихэкспериментов представлены в таблице 2.

Таблица 2 — Сравнение производительностиалгоритмов на разных наборах данных

qsort Упрощенныйпузырьковый

метод

Пузырьковыйметод

Начальный набор 15,11 13,86 13,81

Отсортированныйнабор

15,11 13,85 0,65

Подведем итоги этого небольшого исследованияреализаций алгоритмов. Как известно из теории

Page 273: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

273

алгоритмизации, алгоритм qsort эффективнеепузырькового метода сортировки при обработке массивовзначительного размера (более 1000 элементов). Скоростьего выполнения замедляется медленно при увеличенииколичества элементов массива. Алгоритм qsort имеетодинаковую скорость работы для различных направленийсортировки, время его работы слабо зависимо отисходных данных.

Упрощенный пузырьковый метод может работатьнесколько быстрее, при очень малом количествеэлементов в массиве, например менее 10. Он такжеслабозависим от характеристик входных данных. Однакоанализируя реализацию его алгоритма хорошо видно,время его исполнения будет значительно увеличиватьсяпри увеличении количества входных значений.

Полноценный пузырьковый метод имеет одноисключительное преимущество, чем меньше работы посортировке необходимо произвести в массиве, тембыстрее алгоритм обрабатывает массив. А если входноймассив почти или полностью отсортирован, время егоисполнения в десятки раз меньше, чем у упрощенногопузырькового алгоритма.

Приведенное в этом пункте описание сравненияалгоритмов сортировки может являться примеромобсуждения сложных вопросов со старшими товарищами,лидером группы или ведущим разработчиком. Обычно врезультате его не даются готовые решения проблем,стоящих перед программистом, а предлагаются способыпоиска решения, содержащие устные рекомендации ипримеры. В связи с этим, умение писать исходный текстпрограммы со слов товарищей, является обязательнымнавыком даже для начинающего программиста.

Этим примером автор хочет обратить внимание нато, что наличие вычислительной машины не избавляет от

Page 274: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

274

необходимости думать, размышлять. Также, крайнежелательно, для каждой задачи разрабатыватьперсональное математическое решение, что может еёускорить в десятки раз.

Page 275: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

275

4.2. Составные типы данных: структуры и объединения

4.2.1. Объединения

Объединения используются в двух случаях.1. Требуется сэкономить память ОЗУ за счет

размещения нескольких переменных в одних ячейкахпамяти. Эти переменные не должны использоватьсяодновременно. А после каждой смены роли экземпляраобъединения необходимо задавать актуальное значениееще раз.

2. Требуется интерпретировать один участок ОЗУ поразному или изменить порядок следования байт.

Объединения описаны в стандарте языкапрограммирования в разделе 6.7.2.1 Спецификаторыструктур и объединений. Элементами объединения могутбыть значения любых, в том числе составных, типовданных. Однако использование объединений в некоторыхслучаях могут привести к неопределенным результатам,поэтому необходимо ознакомится с указанным разделомстандарта.

Размер объединения в ОЗУ равен размеру самогобольшого типа данных, включенных в него.

union utr { unsigned int value; char bytes[2];};

Объединение utr может интерпретироваться какпеременная беззнакового целого типа сидентификатором value или как массив сидентификатором bytes с двумя элементами, каждый изкоторых имеет тип char. Для хранения переменной типа

Page 276: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

276

unsigned int на ПЭВМ с использованной версией ОС икомпилятора необходимо 4 байта. Для переменной bytesтребуется 2 байта. Размер объединения определяется помаксимальному значению, поэтому размер будет равен 4байтам. Проверить размер объединения можно спомощью оператора sizeof.

printf("%ld\n\n", sizeof (union utr));

В примере вызывается функция форматированноговывода printf, в шаблоне вывода которой указанапеременная типа long int и специальнаяпоследовательность символов перехода на новую строку.Вторым аргументом вызывается оператор sizeof. Вкачестве аргумента для оператора sizeof передается типобъединения utr.

На рисунке 1 приведен исходный текст программыопределения аппаратной архитектуры ПЭВМ big endingили little ending. Имеется в виду способ расположенияданных. Big ending условно означает, что разряд,отвечающий за тысячи и сотни в числе находятся вячейках ОЗУ с большими значениями адресов, посравнению с разрядом, отвечающим за десятки иединицы. Соответственно, условно, в архитектуре bigending при чтении в направлении роста адресов, т. е.СПРАВА НАЛЕВО, сначала расположены единицы, потомдесятки. В архитектуре little ending наоборот, сначаларасположены десятки, затем единицы.

При обработке файла 01.c первая строка будетзаменена содержимым файла stdio.h . В программеиспользуется функция форматированного выводастандартной библиотеки ввода/вывода.

Вторая строка будет заменена содержимым файлаstring.h . В программе используется функция bzero из

Page 277: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

277

библиотеки string, которая обнуляет память.

Рисунок 1 — Исходный текст программыопределения аппаратной архитектуры ПЭВМ big endingили little ending

Строки 4-7 содержат объявление объединения utr2.Данное объединение может использоваться какцелочисленная переменная типа int с идентификаторомvalue, или как массив из четырех элементов типа char сидентификатором bytes.

Строки 9-14 содержат объявление и реализациюфункции big_end, которая не принимает аргументы ивозвращает значение типа int. В строке 10 объявляетсяпеременная с идентификатором variable типа union str2.После выполнения этой строки переменная variable будет

Page 278: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

278

содержать мусорное значение. В строке 11 объединениеvariable используется как переменная типа int, которомуприсваивается значение 1. Таким образом изменяютсявсе байты объединения variable. Значение 1 состоит изодного бита, равного 1, остальные биты должны бытьустановлены в 0. Для установления архитектуры bigending необходимо определить, в каком байте находитсябит, равный 1.

В строке 12 объединение интерпретируется какмассив байтов bytes. Байт с нулевым смещением отначала массива затирается значением 0. Таким образом,если единица в числе находилась раньше значенийдесятков и сотен, т. е. используется архитектура bigending, единица не будет затерта нулем. Если сначаланаходятся сотни, в конце единицы, число изменится иvalue будет равно 0.

В строке 13 оператор return завершает выполнениефункции big_end и возвращает инвертированноезначение variable.value , т. е. если variable.value = 1,функция возвращает 0 и наоборот.

Строка 17 соответствует строке 10.Строка 18 выведет размер переменной variable типа

union utr2.Строка 19 выведет размер типа union utr2, который

должен быть равен предыдущему выводу.В строке 20 используется функция bzero библиотеки

string, обнуляющая память по переданному в неёуказателю размером, равным второму аргументуфункции. Вызов данной функции демонстрируетвозможность работы с объединениями с помощьюоператоров работы с памятью, однако использовать такиефункции для обработки массивов объединений с высокойстепенью вероятности приведет к ошибкам в программе.

В строке 21 вызывается функция printf. В её первом

Page 279: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

279

аргументе, шаблоне вывода, указан спецификатор типастрока %s, который будет рассмотрен в следующихразделах. Вторым аргументом является вызовконструкции, которая в качестве выражения используетрезультат вызова функции big_end. Если результатработы функции big_end равен 1, то будет выведенапервая строка со словом «да», если равен 0, со словом«нет».

Для создания исполняемого файла и его запускаиспользовалась комбинированная команда, приведеннаяна рисунке 2.

Рисунок 2 — Создание исполняемого файла и его исполнение

Первая строка вывода сформирована 18 строкойисходного текста программы. Вторая строка и пустаятретья сформированы 19 строкой исходного текста.Слово «нет» и четвертая пустая строка выведена 21строкой исходного текста программы.

Page 280: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

280

4.2.2. Структуры

Структуры используются для объединения значенийразных типов в один тип. Таким образом повышаетсячитаемость исходных текстов программы и появляетсявозможность выполнять часть действий с помощьюфункций для работы с памятью. Основное отличие отмассивов заключается в том, что элементы структурырасполагаются не всегда последовательно друг задругом. Часто, для повышения скорости выполненияпрограммы, при создании экземпляров структуркомпилятор добавляет смещение после переменной.Такое расположение в ОЗУ позволяет ускорить работупрограммы, но может привести к перерасходу ОЗУ ивызывать ошибки при использовании функций по работес памятью.

Структуры описаны в стандарте языкапрограммирования в разделе 6.7.2.1 Спецификаторыструктур и объединений. Способы их инициализации вразделе 6.7.9.

Далее по тексту дано пояснения только по строкам,имеющим отношение к работе со структурами.

В строках 4-7 объявлен тип именованная структура сидентификатором str2, состоящая из двух элементов.Переменная value имеет тип int, переменная bytesявляется массивом из 4 элементов, каждый из которыхимеет тип char.

В строках 9-13 объявлен тип именованная структураstr1, которая включает в себя переменную dbl типаdouble, переменную ch типа char и переменную elem_str2являющуюся структурой типа str2.

В строках 16-17 показан синтаксис инициализацииэлементов структур. Следует обратить внимание на дваприема. Во-первых, инициализацию можно проводить не

Page 281: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

281

по порядку следования элементов при объявленииструктуры. Во-вторых, во время инициализацииструктуры можно задавать значения для вложенныхструктур и массивов.

Рисунок 1 — Исходный текст программы,демонстрирующей выполнение операций со структурамии её элементами

В строках 18-20 написаны строки, которые приведутк выводу размеров структур в байтах.

В строке 22 использована функция

Page 282: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

282

форматированного вывода printf, одним из аргументовкоторой является макрокомманда offsetof, возвращающаясмещение в байтах до элемента от начала структуры.Таким образом в строке 22 будет выведено смещение доэлемента ch структуры struct str1.

В строке 23 будет выведено смещение от началаструктуры struct str1 до последнего элемента в структуреstr1.elem_str2.bytes[3].

В строке 25 приведен пример задания значенияэлемента структуры. Значение 10 задается последнемуэлементу массиву bytes, который является вложенным вструктуру типа struct str2, которая, в свою очередь,является элементом структуры типа struct str 1.

В строках 26-27 показан прием обращения кэлементам структур в функции форматированного выводаprintf.

Рисунок 2 — Создание исполняемого файла и его исполнение

Создание исполняемого файла и его запусквыполнены одной командой (Рисунок 2).

Первая строка вывода сформирована выполнением18 строки исходного текста программы. Цифра 8 — эторазмер в байтах struct str2. Структура данного типасодержит те же элементы, что и объединение в пункте

Page 283: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

283

4.2.1, однако объединение занимает в ОЗУ 4 байта, аструктура 8 байт.

Вторая и третья строки вывода сформированы 19 и20 строками текста программы. Значение 24соответствует размеру структуры типа struct str1. Встроке 19 структура передается с помощьюидентификатора переменной, а в строке 20 как типструктуры.

Четвертая пустая строка сформирована второйслужебной последовательностью перехода на новуюстроку первого аргумента оператора printf в строке 20.

Значение 8 строки 5 сформировано строкой 22 текстапрограммы и означает, что элемент ch структуры structstr1 смещен на 8 байт от начала структуры.

Значение 19 строки 6 сформировано строкой 23текста программы. Получается, последний элементструктуры struct str1 расположен в 19 байте, однакоразмер структуры равен 24 байтам. Объяснение такогорасхождения произведено в следующем разделе книги.

Седьмая строка не содержит символов.Восьмая строка вывода содержит значение элемента

str1.elem_str2.bytes[3] .Девятая строка содержит значение элемента

str1.elem_str2.value .Строки вывода 8 и 9 подтверждают, что значение,

хранимое в структуре, не перезаписывает другиеэлементы структуры.

При использовании структур необходимоотслеживать смещения элементов от начала структуры, сцелью определения фактического выравниванияэлементов структур на данной ЭВМ, конкретной ОС иверсии компилятора. В остальном работа с элементамиструктур производится так же, как и с элементамимассивов.

Page 284: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

284

4.2.3 Расположение элементов структур в ОЗУ ЭВМ

Как было показано в предыдущем разделе, размерпамяти, требуемой для размещения структуры, редкосовпадает с тем, который получается суммированиемразмеров памяти её элементов. Причиной этого являютсяправила работы микропроцессоров с выравниваниемданных. Использование выравнивания микропроцессоромпозволяет выполнять операции с данными однойинструкцией микропроцессора, а обработка данных безвыравнивания требует двух или более инструкций.

Проблема выравнивания объектов возникает прииспользовании функций, оперирующих участкамипамяти, адресной арифметики или при обработке данныхот аппаратных устройств. Использование операций спамятью или приемов применения адресной арифметикипри неправильно вычисленном размере структурыпревращают данные в мусор, а наибольшие потерипамяти ОЗУ возникают при использовании массивовструктур. В этом случае, потери могут достигатьполовины всей потребляемой программой памяти. Такжевозможно разрушение памяти программы из-за выхода запределы области данных, получения мусорногоуказателя из полей структуры и по другим причинам.

Само по себе правило выравнивания одно. Объекткаждого типа должен начинаться с адреса, кратногоразмеру своего типа. Например:

- char имеет размер один байт, поэтому можетначинаться с байта с любым номером;

- если short занимает 2 байта, то он долженначинаться с байтов с номером, кратным двум;

- если int или float занимают по 4 байта, значитдолжны начинаться с адреса, кратного 4;

Page 285: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

285

- если указатель на int занимает 8 байт, то долженначинаться с адреса, кратного 8 и т.д..

Язык программирования Си не предписываеткомпилятору контролировать расположение в памятиэлементов структур. Подобное правило отсутствует сцелью сохранения максимальной совместимости саппаратным обеспечением различных архитектур.

Неиспользуемые байты появляются в тех структурах,в которых сначала расположены данные большегоразмера, а затем данные меньшего размера. Например,вначале char , затем double. Другой причиной являетсяиспользование компилятором байт после структуры, длявыравнивания начала следующей структуры.

Решение проблемы выравнивания заключается врасположении в начале структуры наиболее объемныхданных и далее по уменьшению их размера, например:int , int затем char. Такой подход к решению проблемывыравнивания не всегда применим, т. к. он понижаетчитаемость исходного текста программы.

При обработке данных аппаратных интерфейсовчасто используется директива #pragma pack,отключающая выравнивание для структуры. Такойпример будет рассмотрен в данном разделе.Использование этой директивы гарантирует отсутствиевыравнивания структур, однако может замедлять работупрограммы. Для микропроцессоров архитектуры x86 иx86-64 замедление скорости выполнения программыобычно незначительно или отсутствует вовсе.

Первая и вторая строки содержат директивыпредпроцессора и имена заголовочных файлов,содержащих объявления функций форматированноговвода вывода и задания значения для участка ОЗУ.

В строках 4-6 содержится объявление типаименованной структуры str1. Её элементы расположены

Page 286: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

286

с нарушением правила выравнивания элементовструктуры. Элементы структуры набраны в текстовомфайле в одну строку с нарушением правил оформленияструктур, в соответствии с которым каждое выражениедолжно быть набрано в отдельной строке. В данномслучае это оправдывается тем, что правильноеоформление заголовочного файла увеличило быколичество строк почти в два раза.

Рисунок 1 — Исходный текст заголовочного файла собъявлениями структур и объединений

В строках 8-10 объявлен тип структуры str1_small, в

Page 287: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

287

которой элементы расположены обратно правилувыравнивания, т. е. по возрастанию размера.

В строках 12-16 приведено объявление str1_opt,заключенное в директивы препроцессора, отключающиевыравнивание. Следует обратить особое внимание наналичие закрывающей директивы, включающей правилавыравнивания после завершения объявления типаданных str1_opt.

В строках 18-20 объявлен тип объединения un1, вкоторый включена структура struct1 типа str1 и массивиз 24 элементов типа char. Соответственно структура str1и массив bytes будут использовать одну и ту же областьпамяти ОЗУ.

В строках 22-24 объявлен тип объединения un1_small,отличающийся от объединения un1 использованиемструктуры типа str1_small .

В строках 26-28 объявлен тип объединения un1_opt,отличающийся от un1 использованием структуры типаstr1_opt.

Значение размера массива bytes в 24 элементаполучен предварительно по размеру структуры, котораяиспользует память максимально неэффективно изописанных.

Далее приведено построчное описание текстапрограммы файла 01.c, представленной на рисунке 2.

Строка 1 обрабатывается предпроцессором, которыйзаменяет её на содержимое файла 01.h, находящегося вэтом же каталоге.

Строка 2 предписывает предпроцессору выполнитьзамену набора символов ARRAY_SIZE на константу 24 повсему тексту файла 01.c.

Строки 4-8 содержат объявление и реализациюфункции print_array. Функция принимает один аргументтипа указатель на символьный тип char. Функция не

Page 288: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

288

возвращает никаких значений, на что указываетключевое слово void перед названием функции.

Строка 5 содержит объявление переменной сидентификатором count и инициализацию еёконстантным значением 0.

Строка 6 включает в себя цикл while с условиемвыполнения тела этого цикла, которое состоит из вызоваоператора printf и операции инкремента переменнойcount. Тело цикла while состоит из двух выражений и несодержит обрамляющих фигурных скобок, т. к. ониобъединены операцией следования, обозначающейсязапятой. Выражения можно объединять операциейследования только в том случае, если при их исполнениине требуется изменять состояния стека программы.Имеется ввиду, что значения в стеке могут изменяться,но операции, объединяемые запятой, не должнысоздавать новых переменных на стеке или удалять их.

Следует обратить внимание, в строке 6 всеоператоры цикла написаны в одну строку, что можнорассматривать как нарушение стиля программирования.В данном случае это сделано с целью уменьшенияразмера изображения с исходным текстом.

В строке 7 содержится оператор puts, которыйвыводит пустую строку. Таким образом создаетсявизуальный отступ между отображениями значенийэлементов массива. Этот оператор улучшает читаемостьинформации, выводимой в окне ЭТ, и не несет смысловойнагрузки с точки зрения алгоритма функции.

В строке 10 определен используемый прототипфункции main. В данном случае она не принимает и невозвращает никаких значений.

Строки 11-13 содержат операторы форматированноговывода printf, вторым аргументом которых являетсяоперация sizeof, возвращающая размер структур типов:

Page 289: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

289

struct str1, struct str1_small и struct str1_opt.

Рисунок 2 — Исходный текст программы,демонстрирующей размещение элементов структур вОЗУ

В строках 14-16 объявлены объединения union un1var1, union un1_small var1_small и union un1_opt var1_opt.

Page 290: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

290

С их помощью будет выведено содержимое ячеек ОЗУ, вкоторых находятся структуры, указанные ранее.

В строках 17-19 применена функция memset.Каждому байту объединений будет задано значение 255,которое в двоичном виде записывается как 11111111,значит все биты объединений будут равны 1.

В строке 20 объединение var1 трактуется какструктура типа struct1. Элементу dbl1 типа doubleструктуры struct1 присваивается константное значение1.0. При задании константного значения для переменныхтипов с плавающей запятой необходимо не забыватьуказывать значение дробной части числа.

Присвоение строки 20 заменит биты с единицамиобъединения var1 на соответствующие константе 1 типаdouble. В строках 21-31 задаются значения всемэлементам объединений, интерпретируемым какструктуры.

В строках 32-34 производится вызов функцииprint_array. В функцию передаются указатели наобъединения, как массивы, а не структуры. Такимобразом, при каждом вызове print_array будут выведенызначения всех байт, занимаемых структурой, переданнойпо указателю.

Строка 35 содержит вызов оператора return,завершающего выполнения функции main, а значит ивсей программы.

В строке 36 закрывающая фигурная скобкаограничивает функцию main.

На рисунке 3 представлен результат выполнениятекста программы, представленной на рисунке 2.

Для создания исполняемого файла примененакомбинация вызова программы gcc с передачей вкачестве параметра имени файла 01.c операции && ивызова созданного исполняемого файла с именем по-

Page 291: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

291

умолчанию a.out, расположенном в текущем каталоге.

Рисунок 3 — Создание исполняемого файла и его исполнение

Значение 24 соответствует размеру структуры structstr1 в байтах. При расположении элементов структуры всоответствии с правилом выравнивания, эти же данныебудут занимать в ОЗУ 16 байт, как структура типаstr1_small. Это подтверждает вывод второй строки в ЭТ.Упаковка структуры в памяти позволяет сохранить этиже значения, используя 15 байт, что демонстрируетсявыводом третьей строки.

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

Чтобы понять вывод программы в строках 4-6,следует обратить внимание на следующие факты:

- в файле 01.c в строке 6 в первом аргументе функцииprintf указан спецификатор типа %d, т. е. планируетсявывод значений целого типа int;

- в функцию print_array передается указатель намассив, каждый элемент которого имеет тип char(знаковый символ);

- если все биты значения типа char равны 1, этосоответствует значению -1 в дополнительном коде (см.пункт 1.2);

- значение -1 типа char, переданное в оператор

Page 292: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

292

форматированного вывода, в котором для этого значенияуказан спецификатор целого числа, будет выведен какцелое число, т. е. будет равно -1;

- в используемом процессоре архитектуры x86-64применяется архитектура Big ending, а значит сначалахранятся байты с меньшими номерами, затем сбольшими, т. е. в порядке, обратном записи человеком набумаге. Например, единица записывается так: 1 0 0 0 0 00 0.

При использовании структуры типа struct str1,которая соответствует четвертой строке вывода в ЭТ, впамяти сохранилось четыре значения -1, а значит четыребайта используются для выравнивания внутри структуры.Значения -1 в конце строки соответствуютнеиспользованным байтам.

При использовании структуры типа struct str1_small,которая соответствует пятой строке вывода в ЭТ, впамяти сохранилось всего одно значение -1, а значиттолько один байта используется для выравниваниявнутри структуры. Кроме того, сама структура «короче» впамяти на 24-16=8 байт. Значения -1 в конце строкисоответствуют неиспользованным байтам. Такимобразом, применение правила выравнивания позволилосэкономить 8 байт.

При использовании структуры типа struct str1_opt,которая соответствует шестой строке вывода в ЭТ,значения -1 в памяти не сохранилось. Байты длявыравнивания внутри структуры не использовались.Упакованная структура имеет самый маленький размер впамяти, 15 байт. Значения -1 в конце строкисоответствуют неиспользованным байтам.

Для работы с выравниванием используется двамакроса: alignas, предписывающий выполнитьвыравнивание в соответствии с переданным в него

Page 293: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

293

значением и alignof, отображающий смещение элементаот начала структуры.

Значение возвращаемое макросом alignof длябазовых типов совпадает с размером этого типа, т. е.вызовом оператора sizeof.

Например:

alignof(struct str1);

будет равен 8.

alignof(struct str1_small);

будет равен 8.

alignof(struct str1_opt);

будет равен 1.

Макрос alignas предписывает выровнять попереданному значению, т. е. разместить с адреса,кратного переданному значению, но не предписывает,где именно разместить эти данные. В связи с этимвыравненные переменные не обязательно будутрасполагаться друг за другом и могут находиться вразных участках памяти.

Пример:

alignas(8) struct str1 variable;

Расположить структуру variable с адреса, кратного 8.

Знания только стандарта программирования непозволяют писать правильные исходные тексты

Page 294: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

294

программ. В стандарте специально не выполненажесткая регламентация расположения в памятиструктур. Это сделано для поддержки максимальновозможного количества аппаратных и программныхплатформ.

Написание правильно работающих текстов связаноне со стандартом, а с его реализацией на разныхплатформах. Настоятельно рекомендуется проверятьработу приемом выравнивания на конкретнойаппаратной и программной архитектуре во избежанияполучения скрытых ошибок в исполняемом файле.

Для эффективного использования приемоввыравнивания данных сложных типов требуются знания вобласти аппаратного обеспечения. Другим подходомявляется экспериментальная проверка размеровструктур, адресов расположения всех элементов в них.Также рекомендуется выносить все аппаратнозависимыеобъявления в отдельный файл.

Page 295: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

295

4.3. Составные типы данных: строки4.3.1. Объявление и инициализация строк

Для обработки текстовых данных используютсяодномерные массивы. Отличие от обычных массивовсостоит в наличие нулевого символа в конце строк. Оннеобходим по причине отсутствия информации о длинестроки. Алгоритмы всех стандартных функций дляобработки строк работают корректно только при наличиив конце строки нулевого символа. Ответственность заналичие конечного нулевого символа лежит напрограммисте, хотя стандартные функции облегчают егоработу, т. к. дописывают нулевой символ при выполнениисвоих алгоритмов.

Одной из главных проблем при работе со строкамиявляется правильная конвертация текста из однойкодировки в другую. Кодировки накладываютограничения не только на операции со строками. Ихтакже необходимо учитывать при задании константныхзначений в исходном тексте программы.

Изначально использовалась однобайтовая кодировкатекстовых символов ASCII. В тот период появиласьбиблиотека для работы со строками, функции которойописаны в файле string.h. Кодировка ASCII состоит издвух частей: базовой и расширенной части. Базовая частьвключает в себя управляющие команды, символыанглийского алфавита и цифры. Расширенная частьвключает символы национальных алфавитов и символыпсевдографики и может меняться в зависимости откодировки.

Наиболее популярными кодировками для латиницыстали koi8-r (в POSIX системах), CP866 (сейчасиспользуется в основном в ОС DOS и ЭТ ОС семействаWindowsTM) и windows-1251 (в графическом интерфейсе

Page 296: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

296

ОС семейства WindowsTM и сайтах оптимизированныхпод браузеры фирмы MicrosoftTM). Соответственно,константы, заданные для кодировки koi8-r, будут иметьдругое значение в кодировках CP866 и windows-1251.

Следующим этапом стало появление кодировки спеременным количеством байт на символ. Наибольшуюпопулярность в сети Интернет приобрела кодировка utf-8, т. к. она позволяет передавать управляющие командысетевых протоколов также эффективно, как и с помощьюASCII, а также использовать до четырех байт дляпередачи текстовых и прочих символов.

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

Такое обилие кодировок иногда приводит к мысли осоздании собственного внутреннего представлениятекстовых данных с написанием функцийпреобразования во внутренний формат и из него.Следует учитывать, внутренний формат не сможетхранить все символы кодировок utf-8 и utf-16, если егоразрядность менее двух байт. Однако основнойпроблемой для «собственного» формата текстовыхданных станет использование систем управления базамиданных СУБД, которые используют стандартныекодировки. Также может не быть возможностиприменения библиотечных функций для работы состроками.

Описание задания текстовых констант приведено вразделе 6.4.5 стандарта языка программирования Си.Для хранения текста в разных кодировках используютсяразличных типы данных:

- для хранения символов ASCII используется тип char(префикс не используется);

- для хранения символов utf-8 используется тип int

Page 297: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

297

(префикс u8);- для хранения символов из нескольких байт (wide

string literals) используются следующие типы:- тип wchar_t (префикс L);- тип char16_t или char32_t (префикс u или U).

Для преобразования текста из текстасоответствующего текущей локальной настройки(многобайтовой строки) в формат строки широкихсимволов:

- wchar_t используется функция mbstowcs;- char16_t используется функция mbrtoc16;- char32_t используется функция mbrtoc32.Использование того или иного формата строк

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

Следует обратить особое внимание на тип wchar_t.Он использует различное количество байт для храненияодного символа в ОС WindowsTM (равен 16 бит) и POSIX(соответствует int).

Приведем примеры инициализации строк ASCII, вкоторых каждый символ занимает один байт.

char ch[] = {'h', 'e', 'l', 'l', 'o', '\0'};

соответствует

char ch[] = {'h', 'e', 'l', 'l', 'o', 0};

соответствует

char ch[] = "hello";

Page 298: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

298

соответствует

char ch[6] = "hello";

компилятор сам рассчитывает количество символов встроке с учетом завершающего нулевого символа.

char ch[] = "";

указанная строка создает массив из одного элемента,являющегося нулевым символом.

Другим типом данных описываются символы текста.Отличием при инициализации символов текста являетсясинтаксис и возможность инициализации только одногозначения.

char ch = 'h';

Данная строка инициализирует переменную изодного символа. Нулевой символ не может быть добавленпо определению, т. к. эта переменная не являетсямассивом.

Символы подлежат сравнению между собой спомощью оператора условного перехода if, т. к. ониявляются целочисленными значениями типа char. В своюочередь, для сравнения строк необходимо использоватьспециальные функции, т. к. необходимо выполнитьсравнение двух последовательностей.

Некоторым парадоксом для начинающегопрограммиста кажется необходимость «угадывать»,какое количество символов может потребоваться хранитьв этой переменной за все время выполнения программы.

Page 299: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

299

Такой поход пошел с тех времен, когда текст состоял иззаранее определенных наборов символов и переносилсяиз проектной документации в исходный текстпрограммы. Обычно поле вывода имеет фиксированнуюширину и не позволяет выводить бесконечный текст.Отчасти эта проблема решается использованиемдинамически выделяемой памяти в области кучи.

Многобайтовые константные значения допустимозадавать с помощью числовых кодов, например так

L'\1234'

В этом случае строка обязательно должна иметьсоответствующий её комментарий, в котором приводитсяпояснение значения константы. В среде программистовконстанты, значения которых не объяснены, называются«магическими» значениями. В том смысле, что все ихвидят, но не кто не знает, как они работают.

В соответствии со стандартом языкапрограммирования, если один из символов указываетсякак широкий символ, все остальные символы этойконстантной строки считаются широкими символами.

Например:

"a" "b" L"c"

эквивалентно

L"abc"

Смешение же символов разного количества байтприведет к «неопределенному поведению».

В разделе 6.4.3 стандарта языка программированияуказана возможность задания значений широких

Page 300: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

300

символов с помощью следующей комбинации символов

"\x12"

или

ch = \u0192

В разделе 7.30 стандарта языка программированиявыполнена классификация типов широких символов ифункции отображения между разными типами.

В разделе 7.30.1 определены типы wint_t, wctrans_t,wctype_t, а также макроопределение WEOF,используемое для определения конца файла,содержащего многобайтовые строки. Значение LC_TYPEпозволяет определить текущие локальные настройки.

В следующем разделе этой книги будут рассмотреныфункции отображения данных между разными типами.

Page 301: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

301

4.3.2 Функции для работы со строками

Освоение функций для работы со строками удобнеепроводить с использованием однобайтовых ASCII строк.Минимальный набор для обработки строк состоит изпяти функций: strlen, strcpy, strcat, ctrcmp и strstr. Ониопределены в заголовочном файле string.h, которыйнеобходимо подключать директивой include. Библиотека,соответствующая этому заголовочному файлу,подключается компоновщиком по умолчанию, поэтомунет необходимости указывать ключи для использованияэтих функций.

Также необходимо использовать функцииконвертирования текстовых строк в цифры, даты, прочиеформаты и обратно. За преобразование текста в целоечисло отвечают функции atoi, atol и atoll, описанные взаголовочном файле stdlib.h. Для преобразования текстав число с плавающей запятой используются функцииatof, atol. Передаваемый в эти функции текст должензавершаться нулевым символом.

Для преобразования символов внутри строкибольшего размера используются функции strtod, strtof,strtold. Они используют два аргумента, на начало и конецфрагмента строки, который необходимо перевести вчисло. В этом случае фрагмент строки не должензаканчиваться нулевым символом. Данные функциитакже описаны в заголовочном файле stdlib.h.

Для преобразования цифр и чисел в текстиспользуется функция sprintf, которая преобразуетцифры в текст в соответствии с переданным в нейшаблоном вывода и спецификаторам вывода. Длякорректной работы функции необходимо передаватьуказатель на массив, в который будут выведеныпреобразованные числа. Функция asprintf не только

Page 302: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

302

выполняет преобразование по примеру sprintf, но икорректно выделяет память под сформированную строку.

Используя функции fprintf, fscanf, описанные взаголовочном файле stdio.h, есть возможность выполнятьпреобразование текста в числа и наоборот налету приполучении или записи данных в поток. Этот приемпозволяет выполнить преобразование без использованияпромежуточных буферов, объединив операции чтения изаписи в поток с преобразованием данных в нужныйформат.

Таким образом, функции для работы со строкамиприсутствуют в библиотеках, описанных в заголовочныхфайлах string.h, stdlib.h, memory.h (который являетсяссылкой на string.h), stdio.h. Кроме того функции дляработы со строками есть в заголовочном файле math.h.

Рассмотрим минимальный набор функции,позволяющий выполнять любые операции соднобайтовыми строками, реализуемыми с помощью типаchar * (указатель на тип char).

Функция strcpy копирует константное значение вдругую строку, «стирая» предыдущее значение.

char str1[10] = {'h', 'e', 'l', 'l', 'o', 0};const char str2[] = {'A', 'n', 'n', 0};printf("%d\n", strlen(str1));strcpy (&str1[0], str2);printf("%s\n", str1);

Выполнение первой строки приведет к объявлениюмассива из 10 символов с идентификатором str1, каждыйэлемент которого имеет тип char. Также в этой строкепроисходит инициализация массива str1. Первые 5элементов массива будут заполнены символами hello.Последний инициализируемый элемент массива равен 0.

Page 303: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

303

В соответствии со стандартом языка программирования,все элементы массива, значения которых не указаны приинициализации, становятся равными 0. Соответственноэлементы с 5-го по 10-й, имеющие индексы с 4-го по 9-йбудут равны. Нумерация символов строк начинается с 0,т. к. указывает на смещение от начала строки (массива),а не на порядковый номер.

Вторая строка исходного текста объявляет строку сидентификатором str2, которая является массивомконстант из 4 символов. Последний символ равен 0.Значения символов этой строки изменяться не могут.

В третьей строке производится вызов функции strlen,которая возвращает количество символов в строке допервого нулевого символа. Для str1 длина строки равнапяти символам.

В четвертой строке производится вызов функцииstrcpy, в которую передаются два массива с помощьюаргументов str1 и str2. При этом, первый аргументпередается как указатель на элемент массива str1 синдексом 0, полученный с помощью унарной операциивзятия адреса &. Второй аргумент передается с помощьюидентификатора строка. В соответствии со стандартомпрограммирования, идентификатор массиваинтерпретируется как индекс его первого элемента,имеющего индекс 0. В результате первый и второй способпередачи массива по указателю является разнозначным.

После выполнения строки 4 в массиве str1 будутсодержаться следующие значения:

'A', 'n', 'n', 0, 'o', 0, 0, 0, 0, 0

Первые три символа str1 будут заменены символамимассива str2. После того как символы для переноса вмассиве источника str2 закончатся, функция strcpy

Page 304: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

304

допишет в 4-й символ str1 значение 0. Однако значенияэлементов str1 с пятого по десятый не изменяться. Таккак функции для работы с текстом обрабатывают массивдо первого символа 0, буква «о» в пятом элементемассива не будет учитываться при последующейобработке.

Пятая строка содержит вызов оператора printf,который выводит содержимое массива str1, содержащегосимволы Ann.

Для демонстрации работы функции strcat, дополнимприведенные ранее строки исходного текста программывызовом функции strcat.

strcat (str1, " ");

Приведенный вызов содержит имя функции и двааргумента, первый из которой передается с помощьюидентификатора str1, второй как константное значение,состоящее из символа пробела. Компилятор формируетиз указанной константы массив из двух символов,символа пробела, 0 и передает указатель на этот массив вфункцию strcat. Функция strcat находит первый элемент,,равный 0 в массиве str1, начиная с символа 0переписывает значения в массиве str1, по завершениюсимволов переданных вторым аргументом, записываетпосле них значение 0. Таким образом, в массиве str1будут следующие символы и значения:

'A', 'n', 'n', ' ', 0, 0, 0, 0, 0, 0

Для сравнения строк используется оператор strcmp.Дополним исходный текст следующей строкой:

int result = strcmp (str1, str2);

Page 305: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

305

В результате выполнения данной строки, переменнаяс идентификатором result станет равной 32, что равнокоду пробела, т. к. массив str1 отличается на одинсимвол пробела, добавленного функцией strcat к str1.Функция strcmp сравнивает посимвольно значения двухмассивов и возвращает сумму разностей элементов ссоответствующими индексами. Более привычнымявляется использование следующего приема сиспользованием strcmp:

if (strcmp (str1, str2) == 0) {…строки равны...

}else {

… строки не равны...

}

Дополним исходный текст вызовом функции поискаподстроки.

char * substring = strstr (str1, "nn");printf("%s %p %p\n", substring, &str1[1], substring);

Вызов этих строк приведет к получению следующеговывода:

nn 0x7ffed4dfbd81 0x7ffed4dfbd81

Функция strstr, так же как и strcmp, не изменяет

Page 306: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

306

значения в ячейках памяти передаваемых ей аргументов,а возвращает адрес первого вхождения второгоаргумента в первый.

Очевидно, последовательность nn входит в str1,начиная со второго элемента, т. е. элемента с индексом1, поэтому было сделано предположение, чторезультатом работы функции strstr станет адресэлемента массива str1 с индексом 1. В строке,содержащей вызов printf, указаны спецификаторы типов%s — соответствующий строковым данным и %p —соответствующий адресам переменных в ОЗУ. Следуетобратить внимание, переменная substring указана воператоре printf дважды, однако выведены разныезначения. Это связано с тем, что первый раз переменнаяsubstring была выведена как строка, а второй раз выведенеё адрес. Также оператор printf вывел значение адресаэлемента массива, полученного выражением &str1[1]; ,т. е. адрес элемента массива str1 с индексом 1.

В заголовочном файле определены и другие функциидля работы со строками, содержащими однобайтовыесимволы. Далее приведены их прототипы и назначение.

Функции, аналогичные strcpy и strcat, однакопозволяющие ограничивать максимально допустимое дляпереноса в другую строку количество символов спомощью аргумента n.

char *strncpy(char * restrict s1, const char * restrict s2,size_t n);

char *strncat(char * restrict s1, const char * restrict s2, size_t n);

Функция, аналогичная strcmp, однако позволяетограничивать максимально допустимое количество

Page 307: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

307

сравниваемых символов с помощью аргумента n.

int strncmp(const char *s1, const char *s2, size_t n);

Функция, аналогичная strcmp, однако учитывающаярегиональные настройки.

int strcoll(const char *s1, const char *s2);

Функция преобразует текст с учетом региональныхнастроек так, чтобы применение strcmp давалорезультат, аналогичный вызову strcoll.

size_t strxfrm(char * restrict s1, const char * restrict s2,size_t n);

Кроме этих функций в разделе 7.24.5 стандартаязыка программирования представлены различныефункции поиска в тексте.

void *memchr(const void *s, int c, size_t n);

Рассматривает строку как массив, состоящий изunsigned char элементов. Осуществляет поиск в первых nбайтах по указателю s. Возвращает указатель на первоевхождение символа c в массиве s.

char *strchr(const char *s, int c);

Рассматривает строку как массив, состоящий из charэлементов. Возвращает указатель на местонахождениепервого символа c в массиве s.

char *strrchr(const char *s, int c);

Page 308: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

308

Возвращает указатель на местоположениепоследнего символа c в строке s.

size_t strspn(const char *s1, const char *s2);

Вычисляет длину начального сегмента строки s1, состоящего только из символов s2.

size_t strcspn(const char *s1, const char *s2);

Вычисляет длину начального сегмента строки s1, не содержащего ни одного символа из s2.

char *strpbrk(const char *s1, const char *s2);

Возвращает указатель на первое появление любого из s2 символов в s1.

char *strtok(char * restrict s1, const char * restrict s2);

Разделяет строку на последовательность непустыхподстрок. При первом вызове указывается строка s1. В s2указывается набор символов, которые являютсяразделителями. Для продолжения поиска в последующиевызовы вместо s1 указывается NULL. При последующихвызовах также можно указывать другие разделительныесимволы. Если найден разделитель, возвращается строкаот начала места поиска до разделителя, которыйзаменяется 0. Если встречается несколько разделителей,все они считаются одним разделителем. При достиженииконца обрабатываемой строки, функция возвращаетNULL.

Пример:

Page 309: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

309

char s1[10] = "AA1BB12CC11DD";char s2[3] = "123";Функция strtok будет возвращать следующие

значенияAABBCCDD

Также в стандарте в файле string.h описаны рядфункций, позволяющих оперировать строками какучастками памяти:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

Копирует из s2 в s1 n байт информации. s2 и s1 недолжны перекрываться.

void *memmove(void *s1, const void *s2, size_t n);

Копирует из s2 в s1 n байт информации. Если адресаисточника и получателя перекрываются, в функциииспользуется вспомогательный буфер.

int memcmp(const void *s1, const void *s2, size_t n);

Сравнивает первые n байт в s1 и s2. Возвращет 0,если значения равны. Если массивы не равны,возвращает разницу первых байт сравниваемых массивов.

Для преобразования из однобайтовогопредставления в широкую строку, используютсяфункции, определенные в файле stdlib.h. (7.22.7.3)

Page 310: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

310

int wctomb(char *s, wchar_t wc);

Преобразует многобайтовую строку s в строку широких символов pwcs. В pwcs будет записано не более n символов. (7.22.7.1)

int mblen(const char *s, size_t n);

Вычисляет количество байт в следующеммногобайтовом символе. Функция использует не более nсимволов строки s. (7.22.7.2)

int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n);

Преобразует широкий символ в многобайтовуюпоследовательность, которая записывается в началестроки s. (7.22.8.1)

size_t mbstowcs(wchar_t * restrict pwcs, const char * restrict s, size_t n);

Преобразовывает мультибайтовуюпоследовательность s в широкий символ pwc. Функциярассматривает не более n символов строки s. (7.22.8.2)

size_t wcstombs(char * restrict s, const wchar_t * restrict pwcs, size_t n);

Преобразует широкосимвольную строку вмногобайтовую строку. Записывает в s не более n байт.

Почти все функции, применяемые к однобайтовым

Page 311: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

311

строкам, имеют реализации для широких строк. Ониобъявлены в заголовочном файле wctype.h.

int iswalnum(wint_t wc); - является ли символ числомили буквой.

int iswalpha(wint_t wc); - является ли символ буквой.int iswblank(wint_t wc); - стандартный символ или

региональный.int iswcntrl(wint_t wc); - другие control символы.int iswdigit(wint_t wc); - соответствует ли числу.int iswgraph(wint_t wc); - печатаемый символ и не

пробел iswprint = true, iswspace = false.int iswpunct(wint_t wc); - является ли символом

пунктуации.int iswspace(wint_t wc); - iswalnum, iswgraph, или

iswpunct возвращает истина.int iswupper(wint_t wc); - является ли символ

заглавным.int iswxdigit(wint_t wc); - проверяет, является ли

символ шестнадцатиричной цифрой.int iswctype(wint_t wc, wctype_t desc); - проверяет,

имеет ли символ wc свойство desc.wctype_t wctype(const char *property); - возвращает

свойство широкого символа по имени.wint_t towlower(wint_t wc); - преобразование символа

к нижнему регистру.wint_t towupper(wint_t wc); - преобразование символа

к верхнему регистру.wint_t towctrans(wint_t wc, wctrans_t desc); -

транслитерация символа в соответствии с описателемdesc.

wctrans_t wctrans(const char *property); -преобразование одного широкого символа в другой.

В заголовочном файле stddef.h, описанном в разделе

Page 312: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

312

7.19 стандарта языка программирования, определенытипы ptrdiff_t, wchar_t, size_t, макросы NULL, offsetof().Также в этом файле определены диапазоны для типовwchar_t (WCHAR_MIN и WCHAR_MAX) и wint_t(WINT_MIN и WINT_MAX).

В разделе 6.4.3 стандарта языка программированияуказаны способы задания символов по стандарту ISO/IEC10646 в формате \Unnnnnnnn или \unnnn .

В разделе 7.22.8 стандарта языка программированияописаны функции преобразования мультибайтовых строкв широкие строки и обратно. Примеры применения этихфункций

size_t wcstombs(char * restrict s, const wchar_t * restrict pwcs, size_t n);

и

size_t mbstowcs(wchar_t * restrict pwcs, const char * restrict s, size_t n);

доступны на англоязычном сайте cplusplus.com,который содержит примеры почти ко всем языковымконструкциям и функциям.

Для функции mbstowcs() также доступен пример всправочной системе man. Для его отображениянеобходимо выполнить команду man mbstowcs . Дляотображения примера с пояснениями на русском языкенеобходимо установить пакет man-pages-ru и man-pages-ru-extra с помощью Synaptic или apt-get.

Page 313: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

313

4.3.3 Пример: инверсия символов

Для обработки строк необязательно использоватьготовые библиотечные функции. Приведем примерфункции, выполняющей зеркальное отражениеоднобайтовой строки.

Функция принимает один аргумент сидентификатором word, имеющий тип указатель на char.Функция ничего не возвращает, а результат еёвыполнения доступен в точке вызова по указателю на типchar, переданному в функцию.

В строке 2 объявляются две переменные сидентификаторами i и j, имеющие целочисленный тип int.

В строке 3 объявляются две переменные temp иcount_lim целочисленного типа char. Переменнаяcount_lim инициализируется результатом выполнениявыражения, возвращающего целую часть от делениядлины слова word на два, т.е. 5/2=2; 7/3=2. В разделе,посвященном преобразованию типов данных будетописано, почему при делении целого числа на целое,остаток от деления отбрасывается. С помощью такойинициализации решается проблема, связанная сналичием в числе четного и нечетного количествасимволов. При нечетном количестве символов, среднийсимвол не переставляется.

В строке 5 описан оператор цикла с заданным

Page 314: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

314

количеством итераций. В первом выражении задаютсяначальные значения двух переменных i и j сиспользованием операции следования, обозначаемойзапятой. Второе выражение определяет условиезавершения цикла i < count_limit. В третьем выражениивыполняется инкремент счетчика цикла и декрементпеременной j. Переменная i увеличивается на единицупри каждом выполнении тела цикла, как бы перемещаясьпо первой половине массива. Переменная jперемещается в конец строки и её значение уменьшаетсяна единицу при каждом выполнении тела цикла. Такимобразом, она как бы скользит с конца строки на еёсередину. При достижении обеими переменнымисередины строки, цикл завершается.

Тело цикла состоит из одного выражения, поэтому неиспользуются фигурные скобки, ограничивающие телоцикла. Однако тело цикла содержит три присвоения,записанные с использованием операции следования.Использование такого приема допустимо только вслучае, если среди операций, следующих друг за другом,отсутствуют объявления переменных. Операции состеком среди операций следования недопустимы.

Page 315: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

315

4.4 Составные типы данных: многомерные массивы

4.4.1 Инициализация многомерных массивов

В основе множества современных математическихмоделей лежат матричные вычисления. К ним относятсятеория распознавания, искусственные нейронные сети,большие данные и другие задачи. В Си для таких задаччасто используются многомерные массивы. Объявлениемногомерных массивов рассматривается в разделе 6.7.6.2стандарта языка программирования.

Приведем пример инициализации многомерногомассива

int m[2][2];

Данное определение можно интерпретировать так,будет создан двухмерный массив, соответствующийматрице 2x2. Выполнение этой строки приводит квыделению памяти на стеке для двухмерного массива.Каждая мерность этого массива состоит из двухэлементов целочисленного типа int. Значения в ячейкахне определены, поэтому в них будут находитьсямусорные значения.

Инициализация многомерных массивов рассмотренав разделе 6.7.9 стандарта языка программирования.Следуя правилам инициализации многомерных массивов,перепишем приведенное ранее объявление

int m[2][2] = {{11, 22}, {33, 44}};

Допускается инициализация без выделенияразмерностей фигурными скобками.

Page 316: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

316

int m[2][2] = {11, 22, 33, 44};

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

int m[0][0] = 11;int m[0][1] = 22;int m[1][0] = 33;int m[1][1] = 44;

Для определения их расположения в ОЗУ,необходимо вывести адреса ячеек памяти, с которых ониначинаются. На используемой автором ПЭВМ былиполучены следующие значения

int m[0][0] = 0x7ffbbb9a1d70;int m[0][1] = 0x7ffbbb9a1d74;int m[1][0] = 0x7ffbbb9a1d78;int m[1][1] = 0x7ffbbb9a1d7c;

Разность между адресами элементов массива равна4, т.е. как раз размеру типа int для данной архитектурымикропроцессора. При этом размерности в ОЗУ следуютстрого друг за другом без промежутков, сначаларасположена размерность с индексом 0, затем синдексом 1.

Следствием такого расположения элементовмногомерных массивов является возможностьприменения адресной арифметики для доступа кэлементам многомерного массива.

Например, выражение

*(&m[0][0]+2)

Page 317: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

317

позволит выполнить следующие действия:1. выполнена унарная операция взятия адреса

элемента массива m с индексами 0, 0;2. от полученного адреса начального элемента

массива m будет выполнено смещение на два элементаразмером, соответствующему размеру указателя всторону увеличения индексов массива. В связи с тем, чтов строке массива всего два элемента, указатель будетсодержать адрес первого элемента (с индексом 0)элемента следующей строки матрицы;

3. звездочка за скобками означает операциюразыменования, т.е. обращения к значению,содержащемуся по указанному адресу.

Получить адрес элемента можно с помощью следующего выражения

&m[0][0]+2

Ограничения на размерность массива в стандартеязыка программирования Си найдено не было.Экспериментально установлено, что компилятор gccпозволяет создавать массивы размерностью более 10,однако в практической работе такие размерностивстречаются редко. Рассмотрим несколько наиболеепопулярных направлений разработки, требующих работыс многомерными пространствами. К ним относятсяискусственный нейронные сети состоящие из множестваслоев. Например, для распознавания нарисованныхсимволов может использоваться шесть и более слоев.Однако решение этой задачи построено так, чтофактически используются двухмерные или одномерныемассивы, описывающие каждый слой отдельно. Другимпримером являются задачи управления. Как известно, в

Page 318: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

318

природе существует всего четыре вида управления,которые изучает теория управления. Само управлениечасто сводится к выбору одного из доступныхвоздействий, в соответствии со сложившейся ситуацией,что также легко реализуемо с помощью одномерногомассива. Наибольшая объективно обоснованнаяразмерность массива равна трем. Трехмерные массивыприменяются для обработки координат трехмерногопространства.

Также следует учитывать, при увеличенииразмерности массива значительно увеличивается объемиспользуемой памяти ОЗУ. Двухмерный массив из двухэлементов в каждой размерности занимает 16 байт, адесятимерный, в котором каждая размерность равнадвум 2096 байт. Создание таких объектов в области стекаможет привести к выходу за пределы стека иуничтожению программы.

Приведем пример объявления трехмерного массива

char m_3[4][3][2];

Для многомерных массивов допустима частичнаяинициализация многомерных массивов

char m_3[4][3][2] = {{{ 0 }}, {{ 1, 2 }}, {{ 3 }, { 4, 5 }}};

При частичной инициализации действует правило, всоответствии с которым возможно опускание крайнихсправа значений, однако недопустим пропуск значениймежду двумя инициализируемыми значениями. Все неинициализированные значения становятся равны 0.

Для задания значений элементам многомерногомассива используются вложенные циклы. Для каждой

Page 319: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

319

размерности необходим свой цикл, поэтому чем большеразмерность массива, тем больше вложенных циклов.

int array[10][5][3] = {0};int i = 0;int j = 0;for ( ; i < 10; i++)

for (j = 0 ; j < 5; j++) {int k = 0;for ( ; k < 3; k++)

array[i][j][k] = i+j+k;}

Следует отметить, что решение задачи вывода всехэлементов массива отличается только одной строкой.Вместо присвоения array[i][j][k] = i+j+k; необходимоиспользовать оператор вывода значения printf("%d\n",array[i][j][k]); .

Из составных типов можно формировать болеесложные составные типы, например, массив структурили структуру, содержащую массивы.

Структура, содержащая массив.

struct st {int m[10];int k[10];

}

Массив из 5 структур.

struct st [5];

Степень вложенности составных типов стандартомязыка программирования не ограничена.

Page 320: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

320

Количество элементов многомерного массива,создаваемого на стеке, ограничено размером стека,который может составлять от нескольких килобайт донескольких мегабайт. В ОС Линукс для архитектуры x86-64 размер стека по умолчанию составляет 8192 Кб.Размер ОЗУ измеряется гигабайтами и чтобы получить кней доступ необходимо использовать выделяемуюпамять.

Есть три способа выделения динамической памятидля двухмерного массива.

1. Выделить память для одномерного массивовуказателей. Затем выделять под каждый одномерныймассив память, а его первый адрес заносить в первыйэлемент базовой размерности, создавая массивуказателей на массивы. Преимуществом этого подходаявляется отсутствие необходимости иметь неразрывныйсвободный участок памяти, способный вместить вседанные. Недостаток состоит в том, что подмассивы будутрасположены в памяти не последовательно друг задругом, а в произвольных местах, а значит нельзя будетприменять адресную арифметику для работы сэлементами массива. Также реализовать такой подходсложнее, чем второй. Его имеет смысл использовать,если требуется захватить как можно больше памяти дляхранения данных.

2. Рассчитать размер требуемой памяти и выделитьеё одним вызовом функции выделения памяти.Адресация к элементам в этом случае производится поуказателю с помощью адресной арифметики.

3. Является комбинацией первого и второго. В этомслучае создается одномерный массив указателей иследующим этапом выделяется память, достаточная дляразмещения всех элементов многомерного массива.После этого требуется расставить указатели в массиве

Page 321: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

321

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

Подход, связанный с выделением памяти длямногомерного массива непрерывным участком,используется чаще всего при условии, что планируетсяиспользовать не более 5-10% свободной памяти ОЗУ.

Следует учитывать, операция инициализациямассива недоступна для массивов, использующих памятьиз области динамически распределяемой памяти. Также,несмотря на наличие механизмов сбора мусора всовременных ОС, после использования многомерногомассива, необходимо освободить выделенную под негопамять.

Первый способ

Рассмотрим более подробно первый способ. Для егодемонстрации потребуются следующие определения:

#include <stdio.h>#include <stdlib.h>#include <string.h>

#define ELEMENT_QUANTITY 10#define ARRAY_SIZE

sizeof(int*)*ELEMENT_QUANTITY#define DIMENSION_SIZE

sizeof(int)*ELEMENT_QUANTITY

Далее приведен список функций, используемых висходном тексте с указанием заголовочных файлов, вкоторых они описаны.

printf() — stdio.hmalloc() — stdlib.h

Page 322: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

322

free() — stdlib.hbzero() — string.hС помощью директив препроцессора определяются

три значения. Первое, ELEMENT_QUANTITY, указываетна количество элементов в мерности массива. Второе,ARRAY_SIZE, содержит размер в байтах массивауказателей на массив. Его размер может отличаться отразмера массивов размерностей в случае, если на даннойархитектуре размер типа указатель на тип и типуказатель на указатель занимают разный размер в ОЗУ.Третье значение, DIMENSION_SIZE, указываетколичество байт занимаемой в памяти размерностьюмассива array.

Сначала производится объявление переменной сидентификатором array, имеющую тип указателя науказатель на целочисленный тип int. Выделяется памятьдля массива, который будет содержать указатели надругие массивы. В этой же строке производитсяинициализация переменной array результатомвыполнения функции malloc, которая в качествеаргумента принимает размер массива. Запись (int **)обозначает приведение типа результата выполненияфункции malloc из типа (void *), который она возвращаетпосле своего завершения, к типу (int **). Более подробноо приведении типов будет рассказано в следующихразделах.

int ** array = (int **)malloc(ARRAY_SIZE);

Создание второй размерности производится спомощью цикла, приведенного далее

int count = 0; for ( ; count < ELEMENT_QUANTITY; count++)

Page 323: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

323

array[count] = (int *)malloc(DIMENSION_SIZE);

Сначала производится объявление переменной countцелочисленного типа int, которая инициализируетсязначением 0. Далее следует цикл с заданнымколичеством итераций, начальное условие которогопропущено, т. к. инициализация счетчика цикла countпроизведено строкой ранее. Второе выражениепредписывает выполнять тело цикла, пока значениесчетчика цикла count меньше количества элементовмассива ELEMENT_QUANTITY. Третье выражениеявляется инкрементом счетчика цикла count.

Тело цикла состоит из одного выражения, поэтомуфигурные скобки, ограничивающие тело цикла, опущены.Телом цикла является вызов оператора выделенияпамяти в области динамически распределяемой памятиmalloc, аргументом которой является размер второйразмерности массива array. Функция malloc производитрезервирование ячеек памяти ОЗУ, но не изменяет ихзначений. В этом случае результат выполнения функцииmalloc приводится к типу (int *) указатель нацелочисленный тип, который соответствует одной строкемассива.

Далее необходимо обнулить значения полученногодвухмерного массива. Для этого также необходимоиспользовать цикл с заданным количеством итераций.

for (count = 0 ; count < ELEMENT_QUANTITY; count++)

bzero(array[count], DIMENSION_SIZE);

В отличие от предыдущего цикла, его первоевыражение задает начальное значение счетчика цикла,равное 0. Телом цикла является вызов функции bzero,

Page 324: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

324

которая обнуляет участок ОЗУ, начиная с указателяпереданного ему первым аргументом, размером в байтах,равному второму аргументу.

После создания и обнуления массива обращаться кего элементам можно как элементам многомерногомассива, созданного на стеке.

array[1][2] = 12; printf("array[1][2] = %d\n", array[1][2]);

После завершения работы с массивом необходимоосвободить выделенную под него память. Для этоготакже используется цикл с заданным количествомитераций.

for (count = 0 ; count < ELEMENT_QUANTITY; count++)

free(array[count]); free(array);

Телом цикла является вызов функции free(),аргументом которой является указатель на строкумассива. Следует обратить внимание, после удалениястрок, необходимо удалить сам массив указателей. Дляэтого в завершении еще раз вызывается функция free() саргументом array.

Второй способ

Реализация второго способа требует использованияследующих функций:

printf() — stdio.hcalloc() — stdlib.hfree() — stdlib.h

Page 325: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

325

При реализации этого способа используется функцияcalloc(), которая не только резервирует память в ОЗУ, нои обнуляет её. В связи с этим использование специальнойфункции для заполнения ячеек ОЗУ нулями не требуется.

В примере используется значениеELEMENT_QUANTITY, определенно директивойпредпроцессора и равной 10. Соответственно будетсоздан массив размером 10x10 элементов.

#define ELEMENT_QUANTITY 10

Для получения доступа к элементам массиваиспользуется переменная array, которая имеет типуказателя на целочисленное значение типа int. Значениятакого типа используются как указатели на первыйэлемент одномерного массива.

int * array = calloc(ELEMENT_QUANTITY*ELEMENT_QUANTITY,

sizeof(int));

Для обращения к элементам таких массивовиспользуется адресная арифметика. Для повышениячитаемости исходного текста используютсявспомогательные переменные column_size, row_size,column, row и array_ptr. Их назначение:

column_size — количество элементов в столбце;row_size — количество элементов в строке;column — текущий номер столбца;row — текущий номер строки;array_ptr — указатель на элемент массива.В приведенном далее исходном тексте в первой

строке объявляется четыре переменных целочисленноготипа int. Следующая строка задает значение

Page 326: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

326

ELEMENT_QUANTITY для column_size и row_size, причемприсвоение производится справа налево. Таким жеобразом задается значение 1 для column и row.

Для обращения к элементу массива объявляетсяпеременная array_ptr, которая инициализируетсярезультатом выполнения суммирования адреса array,указывающего на первый элемент массива, ирезультатом выражения column*row_size+row.Выражение указывает на порядковый номер элементатак, как будто все последующие строки расположены впамяти последовательно за первой с индексом 0. Поправилам языка Си, если к адресу массива прибавляетсячисло, то адрес увеличивается на размер элементамассива, умноженный на прибавляемое число. Такимобразом производится переход на соответствующийэлемент массива. В результате array_ptr будет указыватьна элемент с индексами [1][1].

int column_size, row_size, column, row; column_size = row_size = ELEMENT_QUANTITY; column = row = 1; int * array_ptr = array+(column*row_size+row); *array_ptr = 1; printf("array[1][1] = %d\n",

array[column*row_size+row]);

Для обращения к элементу массива выполняетсяоперация разыменования, обозначаемая символомзвездочка, и присваивается значение 1.

Для подтверждения правильности задания значениядля нужного элемента массива используется функцияprintf(), выводящая значение соответствующегоэлемента. Второй аргумент функции printf() такжеиспользует правила адресной арифметики, однако её

Page 327: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

327

синтаксис отличается. Данное обращение больше похожена указание индекса элемента в одномерном массиве.

Освобождение памяти производится с помощьюоднократного вызова функции free().

free (array);

Третий способ

Для реализации третьего способа необходимы те жефункции и определения как для второго способа. Приэтом требуется выделение памяти для двух массивов,массива указателей array и массива значений array_ptr.Массивы отличаются не только количеством элементов,но и типом элементов. Количество элементов массивауказателей равно количеству столбцов в матрице, аколичество элементов в массиве значений равнопроизведению количества элементов в столбце наколичество элементов в строке.

int ** array = calloc(ELEMENT_QUANTITY, sizeof(int*));

int * array_value = calloc(ELEMENT_QUANTITY*ELEMENT_QUANTITY,

sizeof(int));

Для данного способа характерен дополнительныйэтап подготовки массивов, связанный с получениемадресов начала строк массива значений. Послевыполнения приведенного ниже цикла значениямиэлементов массива array станут адреса элементовмассива array_value.

int count = 0;

Page 328: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

328

for ( ; count < ELEMENT_QUANTITY; count++) array[count] =

&array_value[count*ELEMENT_QUANTITY];

После этого обращаться к элементу массива можнокак к элементу многомерного массива.

array[2][2] = 18; printf("array[2][2] = %d\n", array[2][2]);

Для освобождения выделенной под массивы памятинеобходимо два вызова функции free(). Если функции freeвызываются по-очереди, порядок их вызова не так важен.Однако правильнее сначала удалить массив указателей,затем массив значений, что позволит исключитьобращение по адресу освобожденной памяти.

free (array); free (array_value);

Рассмотренные способы выделения памяти длядвухмерных массивов применимы к массивам любоймерности, однако с добавлением каждой мерности,повышается сложность алгоритмов и понижаетсячитаемость исходных текстов программы.

Приведем пример обработки трехмерного массива спомощью первого способа. В данном примере длявыделения памяти ОЗУ будет использоваться фукцияcalloc, поэтому обнуление выделенной памяти непотребуется.

printf() — stdio.hcalloc() — stdlib.hfree() — stdlib.hКоличество элементов в каждой размерности

Page 329: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

329

определяется с помощью директив предпроцессора.

#define DIMENTION1 3#define DIMENTION2 4#define DIMENTION3 5

Для выделения памяти потребуется несколькопредварительных действий. Сначала необходимообъявить переменную array, которая будет являтьсяуказателем на массив. Формально её типом являетсяуказатель, на указатель, на указатель на целочисленныйтип int. В ОЗУ она хранится как указатель на тип int. Досоздания массива объявляются и инициализируютсязначением 0 счетчики цикла для каждой размерности i, j,h.

int ***array; int i, j, h; i = j = h = 0;

Создание массива отличается от созданиядвухмерного массива дополнительным циклом for,который создает еще одну размерность со значениямитипа указателей, хранящихся во вспомогательныхмассивах. Указание в скобках операций явногоприведения типа перед вызовами функции calloc()призваны подчеркнуть, какие именно типы используютсядля хранения указателей. Внешний цикл for добавляет вкаждый элемент массива array адрес начальной ячейкимассива размером DIMENTION2. Вновь создаваемыммассивам не присваивается отдельное имя, поэтому кним можно будет обращаться только через адрес вячейке массива array. Внутренний цикл for добавляет вкаждую ячейку всех массивов, создаваемых внешним

Page 330: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

330

циклом for адреса начальных ячеек массивов, которыебудут содержать обрабатываемые данные.

array = (int ***)calloc(DIMENTION1, sizeof(int**)); for ( ; i < DIMENTION1; i++) { array[i] = (int **)calloc(DIMENTION2, sizeof(int*)); for (j = 0; j < DIMENTION2; j++) array[i][j] = (int *)calloc(DIMENTION3,

sizeof(int)); }

Вспомогательными являются массив array(обращение к элементам array[x]) и все массивы, кэлементам которых обращение производится с помощьюконструкций array[x][y], где x от 0 до значения константыDIMENTION1, а y от 0 до DIMENTION2. Сами значенияхранятся в массивах, к которым обращение производитсяс помощью конструкций вида array[x][y][z], где xизменяется от 0 до DIMENTION1, y от 0 до DIMENTION2,а z от 0 до DIMENTION3.

int count = 0; for (i = 0; i < DIMENTION1; i++) { for (j = 0; j < DIMENTION2; j++) { for (h = 0 ; h < DIMENTION3; h++) { array[i][j][h] = count++; printf("array[%d][%d][%d] = %d ", i, j, h,

array[i][j][h]); } puts(""); } puts(""); }

Page 331: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

331

Для освобождения памяти, выделенной длятрехмерного массива, необходимо выполнить следующиеоперации. Внутренний цикл for удаляет все массивы сданными, обращение к которым производится с помощьюоперации array[x][y][z]. Внешний цикл for освобождаетпамять, выделенную под вспомогательные массивы суказателями, к которым обращение производится спомощью операций array[x][y]. Последний вызов функцииfree() освобождает память, выделенную подвспомогательный массив с указателями array.

for (i = 0; i < DIMENTION1; i++) { for (j = 0; j < DIMENTION2; j++) free(array[i][j]); free(array[i]); } free(array);

Все три способа выделения памяти под многомерныемассивы позволяют создавать массивы любойразмерности. При увеличении размерности массивапроисходит возрастание сложности алгоритмоввыделения и освобождения памяти для хранения егозначений.

Приведенные примеры демонстрируют некотороенеудобство при работе с многомерными массивами,память для которых выделяется в области динамическойпамяти. При практическом программировании редковстречаются задачи, требующие использования массивовразмерностью более 3, а использование массивоввысокой размерности часто является показателемалгоритмических ошибок и ошибок при проектировании.

Page 332: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

332

4.4.2 Операции с многомерными массивами

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

При решении задачи сжатии данных до меньшихразмерностей, т. е. задач понижения размерности илисвертки, неиспользованная память ОЗУ остаетсявыделенной до завершения расчета. Кроме того такиезадачи обычно решаются отдельно от основной задачи ииспользуют сразу несколько массивов разнойразмерности.

Как уже было показано в предыдущем пункте,увеличение размерности массива приводит к увеличениюсложности алгоритмов, описывающих операции с ним, атакже увеличению используемой памяти. Особоевнимание следует уделить рекурсивным функциям,которые многократно вызывают сами себя. В случае ихиспользования не рекомендуется использовать памятьдля многомерного массива в области стека.

Основные и наиболее часто встречающиеся операциис многомерными массивами:

1) выделение и освобождение выделенной памятипод массив;

2) обнуление массива;3) доступ к произвольному элементу массива;4) последовательный доступ ко всем элементам

массива;5) вывод значений массива в устройство вывода.В предыдущем разделе предложено три способа

выделения памяти для многомерных массивов. Для

Page 333: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

333

первого способа обращение к элементам возможнотолько с помощью квадратных скобок. Второй способдопускает использование только адресной арифметики.Третий дает возможность использовать как квадратныескобки, так и адресную арифметику.

Операции пунктов 1, 2 и 3 рассмотрены в предыдущем разделе.

Последовательный доступ к каждому элементумассива осуществляется с помощью вложенных циклов,количество которых равно количеству мерностеймассива. Пример последовательного доступа ко всемэлементам массива предыдущего раздела используеттрехмерный массив. В этом примере операция доступа кэлементам массива дополнена функцией выводазначения элемента массива в стандартный поток выводаprintf(), а значит реализует вывод значений всехэлементов массива.

Рассмотрим случай, при котором требуетсяинициализировать массив значением, отличным от 0.Такая необходимость возникает, когда требуетсяотслеживать, использован элемент массива или нет. Дляэтого при разработке алгоритма выбирается«неиспользуемое» значение, которое и означает, чтоячейка не используется. Проще всего выбратьнеиспользуемым значением недопустимое с точкизрения предметной области решаемой задачи. Например,столкновение физических тел подразумевает наличиекак минимум двух физических объектов, поэтомунеиспользуемым значением может быть как 0, так и 1. Вслучае, когда такие недопустимые значения отсутствуют,«неиспользуемым» выбирается 0, минимальное илимаксимальное значение, допустимое для данного типаданных языка программирования.

Пример побайтового задания значения 255 всем

Page 334: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

334

ячейкам памяти с помощью функции memset() приведенв пункте 4.2.3. Инициировать ячейки памяти такжеможно значениями типа wchar_t с помощью функцииwmemset().

Кроме задания «неиспользуемого» значения,возможно объявление составного типа struct длявыставления флагов неиспользуемых элементов.

struct value {int data;bool enabled;

}

Стоит обратить внимание на тип bool, дляприменения которого необходимо использоватьдирективу препроцессора #include "stdbool.h" (7.18стандарта языка программирования). Данный типреализован с помощью директив препроцессора,которыми переопределяется тип _Bool и позволяетиспользовать значение true и false в тексте программы. Всвязи с этим, тип bool также, как и тип _Bool , занимает впамяти 1 байт, а не бит. Современные архитектурымикропроцессоров не позволяют адресовать один бит,что можно проверить с помощью выражения

printf("sizeof(_Bool) = %ld\n", sizeof(bool));

Допустимо объявление многомерного массива,состоящего из структур типа value.

struct value array[10][2];

Работа с массивом структур выполняется также, каки с обычным массивом, за исключением необходимости

Page 335: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

335

уточнять, к какому именно элементу структурыпроизводится обращение. Например:

array[count1][count2].enabled ? array[count1][count2].data : 0;

В указанном примере в случае, когда элементструктуры enabled равен 1, возвращается значениеэлемента структуры data, в противном случаевозвращается значение 0. Данный пример нагляднодемонстрирует потерю читаемости текста программыпри увеличении размерности массива.

Кроме типа указатель на указатель, int ** array, вкотором количество звездочек указывает на размерностьмассива, существует еще один способ объявленияуказателей на массив. Например,

int (*[4])[3];

объявляет массив из 4-х указателей на массивы,содержащие по 3 элемента.

Стандарт языка программирования допускаетиспользование сечений многомерных массивов.Ограничение состоит в невозможности использованияпромежуточных размерностей для передачи сечения.Например, для int array[5][4] :

- array[2] — допустимо, указывает на подмассив из 4элементов, который следует третьим от началадвухмерного массива, т. е. соответствует третьей строке;

- array[][3] — недопустимо, нельзя опускатьразмерность после указанной, т. е. нельзя передатьуказатель на столбец двухмерного массива.

Сечения массивов используются в основном вмногопоточном программировании, для понижения

Page 336: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

336

размерности данных обычно используется отдельныймассив необходимой размерности.

Начинающие программисты часто задаютсявопросом, возможно ли написание универсальнойфункции, осуществляющей ввод или вывод значенийлюбой размерности. Да, при передаче размерностеймассивов отдельными аргументами это возможно, но впрактическом программировании лучше иметьотдельные функции для вывода значений массивовразличной размерности. Кроме того, функции поиска,обхода всех значений также лучше писать в каждомслучае отдельно, т. к. не существует единогооптимального алгоритма работы с многомернымимассивами для всех вариантов расположения ихэлементов в ОЗУ. При использовании объемовинформации, сопоставимых с физически доступным ОЗУ,требуется разработка специальных алгоритмов длявыделения и освобождения памяти ОЗУ.

При передачи многомерных массивов в функциюмогут использоваться следующие приемы:

- функция принимает указатель на массив, зная егоразмерность

int print_array_5_3_5 (int *** array);

- функция принимает указатель на первый элементтрехмерного массива, что определяется типомаргумента, передаваемого в функцию. В идентификаторефункции указаны длины этих размерностей.Соответственно функция сможет печатать толькомассивы типа

int array[5][3][5];

Page 337: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

337

- функция принимает указатель на массив собъявленными мерностями

print_array(int array[5][10]);

приведенная функция также ожидает толькомногомерные массивы указанной мерности;

- функция принимает указатель и длины всехразмерностей в качестве аргументов;

int print_array (int *** array, int dimention1, intdimention2, int dimention3);

такая функция должна уметь печатать значения всехтрехмерных массивов, независимо от длин егоразмерностей.

Раздел содержит пояснения практически безприведения исходных текстов программы по несколькимпричинам. Исходный текст обработки многомерныхмассивов громоздкий и занимал бы слишком многостраниц. Он частично приведен в предыдущих пунктах.Информация по этой теме имеется на общедоступныхсетевых ресурсах, и обычно не вызывает затруднений.Кроме того, умение писать исходный текст программы поустному описанию является обязательным навыком длястудентов старших курсов.

Page 338: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

338

4.5 Составные типы данных: битовые поля

Битовые поля являются вспомогательным средством,реализующим доступ к определенному биту, используяпобитовые операции с битовыми масками, ноиспользующие синтаксис, применяемый к составнымтипам данных. В практических задачах, единственнойобластью в которой они используются регулярно —разложение байт, полученных с помощью аппаратныхинтерфейсов, на битовые флаги.

В стандарте языка программирования отсутствуетспециальный раздел, посвященный этому средству.Основные синтаксические конструкции для работы сэтим средством полностью совпадают с применениемструктур, объединений и перечислений.

Битовые поля желательно использовать только вмодулях, производящих аппаратнозависимую обработкуданных. Расположение бит битового поля зависит отархитектуры процессора, а вопрос выравнивания битовыхполей в структурах может зависеть от множествафакторов. Также применительно к битовым полям неимеют смысла операции получения адреса, т. к.минимально адресуемым адресным пространством нааппаратном уровне является байт.

На рисунке 1 приведен исходный текст программы,демонстрирующей основные приемы работы с битовымиполями. В приведенном примере битовые поляобъявлены в структуре bitfield, которая объявлена встроках 4-11. Структура содержит 4 однобитовых поля встроках 6-9 и одно четырехбитовое в строке 10, которыесовместно формируют один байт.

В строках 12-15 содержится объявление объединенияbfvalue, состоящее из поля бит bitfield и переменной сидентификатором value типа unsigned char.

Page 339: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

339

В строке 17 объявляется переменная типа unionbfvalue с идентификатором bfv.

В строке 18 переменная bfv инициализируетсязначением 0, с использованием поля объединения value.

В строке 20 выводиться значение value объединенияbfv сразу после инициализации объединения.

В строке 21 элементу битового поля b1присваивается значение 1.

В строках 22, 24 выводится значение поля b1 и значение value.

В строке 23 однобитовое значение b1 увеличивается на 2.

В строке 26 элементу битового поля b5 размером 4бита присваивается значение 1.

В строках 27, 29 выводится значение поля b5 и значение value.

В строке 28 элементу битового поля b5 размером 4бита присваивается значение 15.

Строка 30 содержит оператор return, которыйвозвращает значение 0 в точку вызова, т. к. операторнаходится в функции main, его использование приводит кзавершению программы и освобождению всех ресурсоввыделенных её ОС.

Результат выполнения исполняемого файла,полученного из приведенного текста программы,представлен на рисунке 2.

В результаты выполнения строки 20 исходноготекста программы на экран выведено значение элементаvalue = 0.

Вторая и третья строка вывода получена в результатевыполнения строки 22 исходного текста программы.Значение поля b1 стало равно 1 и значение value такжеизменилось на 1. Это связано с архитектуроймикропроцессора x86-64, которая располагает данные по

Page 340: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

340

правилу big ending.

Рисунок 1 — Исходный текст программы,демонстрирующей базовые операции с битовыми полями

Четвертая и пятая строка вывода сформирована 24строкой исходного текста программы. Следует обратитьвнимание на то, что в 23 строке исходного текстаоднобитовое значение было увеличено на 2. В случаеобычного сложения 1+2=3, а как известно для записичисла 3 необходимо минимум два бита. Однако, в данном

Page 341: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

341

случае, операция увеличения на 2 воспринимается некак сложение, а как двухкратная инверсия поля b1.Соответственно, если бы значение увеличивалось на 3, тоb1 было бы рано 0.

Шестая и седьмая строка вывода получены 27строкой исходного текста. Полю b5 присваиваетсязначение 1. В свою очередь, value становиться равно 17,т. к. 2^5=16 плюс значение b1 равно 1. В результатеполучается 17.

Две последние строки вывода сформированы строкой29 исходного текста программы. После присвоения полюb5 значения 15, все биты переменной value кроме 2,3 и 4стали равны 1, что соответствует значению 241.

Рисунок 2 — Вывод ЭТ с результатами работы программы

Рассмотрим другой пример объявления типаструктуры с использованием поля бит.

#pragma pack(push,1)struct bf2 {

int b1 : 1;int b2 : 1;: 3;int k;

Page 342: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

342

};#pragma pop()

При её объявлении использовались следующиеприемы. С помощью директивы #pragma выполненаупаковка структуры, т. е. данные должны следовать другза другом, без пропусков байт в ОЗУ. Третье битовое полене имеет имени, а значит обратиться к этим битам спомощью этой структуры не получится. Переменная kтипа int будет расположена в байтах, следующих запределами байт, использованных для битовых полей. Всвязи с тем, что количество байт, занимаемых типом intна разных архитектурах может быть разным,использовать такую структуру как универсальноерешение нельзя даже в упакованном виде.

В вопросах, касающихся выравнивания структур,включающих в себя битовые поля, следуетруководствоваться правилами общими для всех другихслучаев выравнивания структур, описанных в пункте4.2.3.

Page 343: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

343

4.6. Составные типы данных: перечисления

Перечисления — это языковая конструкция,реализующая подмену целочисленных констант типа intна комбинацию символов в исходных текстах программ.Как и битовые маски, перечисления предназначены дляповышения читаемости исходного текста программ. Ониописаны в разделе 6.7.2.2 стандарта языкапрограммирования Си. В указанном разделе стандартаязыка программирования приведен озорной пример сиспользованием наименований алкогольной продукции,однако в этом разделе книги будут использована другаяпредметная область.

Рассмотрим пример с использованием перечислений.

Рисунок 1 — Исходный текст программы,демонстрирующей приемы работы с перечислениями

Page 344: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

344

В приведенном примере опишем работу строк,касающихся непосредственно работы с перечислениями.

Строка 4. Объявляется перечисление enum rgb сэлементами red, green, blue.

Строки 5-6. Вызывается функция форматированноговывода printf, которая, в соответствии с шаблоном выводаотобразит размер перечисления enum rgb, константныезначения, соответствующие red, green, blue.

В строке 7 объявляется перечисление color.Перечисление содержит элементы Red, Orange, Yellow,Green, Blue, причем элементу Orange присвоеноконстантное значение 10, а элементу Green значение 5.

В строке 8 объявляется значение c, которое вдальнейшем нельзя использовать как переменную,например конструкций c = Red, не будет иметь длякомпилятора смысла. Идентификатор c допустимоиспользовать вместо конструкции enum color, например воператоре sizeof.

Строки 9-10 содержат вызов функции printf, котораявыводит размер по идентификатору c и константныезначения для всех элементов enum color. Следуетобратить внимание: строка 9 располагается на двухстроках, так как в редакторе Geany, используемом дляработы с исходным текстом программы, включен режимпереноса строк.

В строке 11 объявляется переменная сидентификатором color_example типа int, котораяинициализируется значением элемента Orange.

Строка 12 содержит printf, выводящий в стандартныйпоток вывода значение переменной orange_color.

В строке 13 выполняется сравнение двух значений,объявленных в разных перечислениях. В случае, если этизначения равны, выполняется вызов функции printf встроке 14, содержащей в своем шаблоне вывода

Page 345: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

345

сообщение о равенстве значений и отображающейзначения элементов red и Red.

В строке 15 с помощью оператора условногоперехода if выполняется сравнение значений разныхобъединений green и Green и в случае их неравенствавыполняется вызов функции printf в строке 16. В строке17 записаны второй и третий аргумент функции printfпредыдущей строки.

Вывод программы, полученной из исходного текста,представленного на рисунке 1, показан на рисунке 2.

Рисунок 2 — Результат выполнения программы

Строки вывода 1, 2, 3, 4 сформированы строками 5, 6исходного текста программы. Размер перечисления enumrgb определен равным 4, что соответствует размеру типаint, как и указано в пункте 2 раздела 6.7.2.2 стандартаязыка программирования Си. Данные строкидемонстрируют, если константные значения элементамперечисления не задаются, то они нумеруются начиная с0, каждый следующий элемент на 1 большепредыдущего.

Строки вывода 5, 6, 7, 8, 9, 10 сформированы

Page 346: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

346

строками 9 и 10 исходного текста программы. Онидемонстрируют, что в случае задания константныхзначений элементам перечисления, последующие неинициированные значения имеют значение на единицубольше предыдущего. Таким образом, первое значениеRed равно 0, т. к. оно не инициировалось. ЗначениеOrange инициировано в строке 7 исходного текстапрограммы и равно 10. Следующее значение Yellow неинициировано. Его значение задано как на единицубольшее Orange, т. е. 11. Следующее значение Greenинициировано и равно 5. Значение Blue неинициализировано и следует за Green = 5, поэтому равно6.

Третья снизу строка вывода отображает значениеcolor_example, которое в строке 11 исходного текстапрограммы инициируется значением Orange. Как видноиз предыдущего вывода, Orange равно 10.

Вторая снизу строка вывода сформирована строкой14 исходного текста программы. Вывод сообщает, чтозначения элементов red и Red из разных перечисленийравны. Они не были инициированы и с них начинаютсяоба перечисления, поэтому они равны 0.

Последняя строка вывода сообщает о том, чтозначения элементов green и Green разных перечисленийне равны green =1, а Green равно 5.

С помощью последних двух строк выводапродемонстрирована причина ошибок, возникающих прииспользовании нескольких объединений для одних и техже типов или сущностей в одном модуле или программе.Таким ошибкам подвержены программы, разные частикоторых написаны разными разработчиками, аобъединением их в один продукт проводится третьимразработчиком.

Вместо перечисления enum color возможно

Page 347: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

347

использование нескольких директив предпроцессора#define, например так:

#define red 1#define orange 2#define yellow 3#define green 4#define blue 5

После этого становятся допустимы выражения типа:

int color = red;

В идеальном случае в одной программе не должнобыть нескольких перечислений, описывающих одни и теже понятия. Необходимо заранее определиться, будетперечисление использоваться для замены константныхчисловых значений их обозначениями или такженеобходимо задавать и интерпретировать каким-либообразом сами константные значения. Второй случайусложняет читаемость исходных текстов программ,однако позволяет разработать правила примененияопераций с элементами перечисления.

Page 348: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

348

5. Язык программирования Си.Вспомогательные средства и приемы работы

5.1. Переменные. Указатели. Объявления

В практическом программировании изцелочисленных типов выбираются те, что соответствуютмашинному слову на целевой машине. Обычно именнотакие типы обрабатываются быстрее, а типы меньшегоразмера эмулируются за счет типов, соответствующихминимальной разрядности микропроцессора. Прииспользовании составных типов ситуация меняется инеобходимо использовать принцип выбора типа данных,занимающего минимальный размер в ОЗУ.

При выборе типа с плавающей запятой обычноделают выбор в пользу типа double, т. к. он используетсяв большем количестве прототипов библиотечныйфункций, а значит будет проще писать программы. Типfloat предпочитают не использовать, т. к. он неподдерживается на некоторых специализированныхплатформах несмотря на его наличие в стандарте языкапрограммирования.

Инициализация переменных с плавающей запятойтребует задания значения как целой, так и дробнойчасти

double dbl = 0.0;

Кроме того, при использовании типов с плавающейзапятой нельзя выполнять непосредственное сравнениена равенство

double dbl1 = 0.0;double dbl2 = 0.0;...

Page 349: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

349

if (dbl1 == dbl2) // Условие практически никогда не будет выполнено

Обычно для сравнения переменных с плавающейзапятой, их предварительно округляют с требуемойточностью. Пример округления до 100-й доли

double dbl1 = 12345.123456;double dbl2 = 12345.128456;int temp = (int)((double)dbl1*(double)100.0);double dbl1_temp = (double) temp/100;temp = (int)((double)dbl2*(double)100.0);double dbl2_temp = (double) temp/100;if (dbl1_temp == dbl2_temp)

puts("Значения равны");

Приведенный пример фрагмента исходного текстапрограммы выведет ответ «Значения равны», несмотряна различия в тысячных долях значений переменныхdbl1 и dbl2. Пояснение его работы приведено в разделе5.2 этой книги.

Для значений типов с плавающей запятойприменимы операции < и >, как и для целочисленныхтипов.

Отдельным классом типов данных являютсяуказатели. Проводя аналогию, их можно сравнить сномерами мобильных телефонов. Знать номер мобильноготелефона, не значит знать то, что знает его владелец,однако используя этот номер, можно связаться свладельцем и узнать требуемые данные.

Указатели позволяют передавать данные, неперемещая их между устройствами и ячейками памяти.Вместо данных передается указатель на эти данные итаким образом получается выигрыш в

Page 350: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

350

производительности и затрачиваемых ресурсах.Соответственно, чем больше данных требуется передать,тем больше выигрыш при передаче указателя.

Не все типы данных хранятся в ОЗУ какпоследовательность байт, не требующая специальнойинтерпретации, поэтому размеры указателей на разныетипы могут различаться. Кроме того размеры типовуказателей могут измениться при переходе на другуюплатформу.

Для определения размера ОЗУ в байтах,необходимого для хранения указателя на тип, можноиспользовать выражение

printf("sizeof char* = %ld bytes\n", sizeof (char *));

Все типы данных, включая составные типы и типыфункций, могут использоваться для составлениясложного описателя типа данных.

При инициализации сложных описателей типовдействуют правила приоритета. Квадратные и круглыескобки интерпретируются раньше звездочки, но имеютравный приоритет между собой и раскрываются слеванаправо. Спецификатор типа является последнимэлементом подвергающимся интерпретации.

Для интерпретации сложных описаний используется правило «изнутри наружу», состоящее из четырех шагов.

1. Интерпретация начинается с идентификатора вцентре, затем необходимо посмотреть направо, есть литам квадратные или круглые скобки.

2. Если на предыдущем этапе обнаружены скобки,необходимо интепретировать эту часть описателя ипроверить слева наличие символа звездочка.

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

Page 351: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

351

применяются внутри круглых скобок, затем выйти за нихи начать с правила 1, считая идентификатором результатинтерпретации в скобках.

4. Интерпретировать спецификатор типа.

Примеры:

float ( * funct_ptr) (char value1, char value2); 4 2 1 3

Объявляется функция funct_ptr (1) как указатель (2)на функцию, принимающую два аргумента типа char (3),возвращающую значение типа float.

char * ( * ( * func_ptr ) () ) [5]; 7 6 4 2 1 3 5

Объявляется функция func_ptr (1) как указатель (2)на функцию (3), возвращающую указатель (4) на массив(5) из пяти элементов, которые являются указателями (6)на значения типа char.

int * ( * array_func_ptr [5]) (); 6 5 3 1 2 4

Объявляется переменная array_func_ptr (1), какмассив из пяти (2) указателей (3) на функции (4),возвращающие указатели (5) на значения типа int (6).

Описатели такого уровня вложенности часто говорято попытке использовать объектно-ориентированныйподход в функциональном программировании или привозникновении других проблем проектирования.Объективные причины использования сложных типов

Page 352: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

352

функций — это создание и работа с динамическиподключаемыми библиотеками, а также объявлениепрототипов функций.

Для повышения читаемости исходного текстапрограмм, использующих сложные описатели, возможноприменение объявления типов. Этот прием описан встандарте языка программирования Си в разделе 6.7.8Объявление типов. Объявление пользовательских типовпроизводится как с помощью тегов, так и с помощьюключевого слова typedef.

Примеры:

Объявляется тип указатель на функцию сидентификатором activation. Её входными аргументамиявляются два массива неопределенной длины a и b.Функция возвращает значение типа int.

int (* function)( int a[], int b[]);

С помощью ключевого слова typedef возможноопределение типа функции, указанной ранее

typedef int (* activation)( int a[], int b[]);

Именем нового типа данных является activation.После этого возможно объявление указателя на функциюс идентификатором accumulator.

activation accumulator;

Представленное объявление функции не содержит всебе символа звездочка, который указывает на то, чтообъявляется указатель. В случае, когда объявление

Page 353: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

353

находится в другом файле и поиск его объявлениязатруднителен, читаемость исходного текстазначительно понижается.

При работе с библиотеками необходимо создаватьуказатели для вызываемых функций. Создание указателяна функцию синтаксически мало отличается от созданияуказателя для переменной. Например, для функции

int func ();

указатель получается следующим образом

int (*func_ptr)() = &func;

После этого с указателем на функцию можноработать как с указателем на переменную.

В стандарте языка программирования Си в разделе7.19 «Дополнительные объявления» приведеныобъявления, которые часто встречаются в практическойработе. Описания этих объявлений находятся в файлеstddef.h.

К ним относятся следующие типы:- ptrdiff_t - используется знаковый целый тип для

хранения результата вычитания между двумя адресами;- size_t - используется беззнаковый тип для хранения

результата выполнения операции sizeof;- max_align_t — используется как тип базовых

объявлений, описанных в пункте 6.2.8 стандарта языкапрограммирования Си.

В файле stddef.h также приведены допустимыедиапазоны для этих типов, например

PTRDIFF_MIN -65535PTRDIFF_MAX +65535

Page 354: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

354

5.2. Преобразование типов данных

В языке программирования Си присутствует какявное преобразование типов данных, так и не явное. Приявном преобразовании указывается тип, к которомувыполняется приведение значения. Неявноепреобразование осуществляется по определеннымправилам, оговоренным в стандарте. В процессеразработки рекомендуется не использовать неявноеприведение типов. Во время компиляции, компиляторвыдает предупреждение на многие виды неявногопреобразования типов.

К основным правилам и ограничениям неявногопреобразования данных разных типов можно отнести:

- во время вывода значения типа char в поток выводаон будет интерпретирован как символ, а не как число;

- при присвоении значения типа, занимающего в ОЗУбольше ячеек памяти, типу, занимающему меньше ячеекпамяти, возможна потеря данных;

- при присвоении значения типа с плавающейзапятой, целочисленному типу, дробная частьотбрасывается;

- при присвоении значения беззнакового типазнаковому возможна инверсия знака числа.

Неучтенное изменение значения при приведениитипов не считается ошибкой с точки зрения языкапрограммирования Си. Ответственность за нихполностью ложится на плечи программиста.

Приведем пример исходного текста программы(Рисунок 1), который демонстрирует отображениеучастка ОЗУ одного целочисленного типа, с помощьюдругих типов данных.

В строке 4 объявляется объединение, включающее всебя переменные типов char, int и unsigned int, причем в

Page 355: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

355

одних и тех же ячейках ОЗУ. Для объединения будетвыделен размер памяти, равный наибольшему типу, т. е.int или unsigned int. Эти типы занимают одинаковыйобъем ОЗУ. Объединение не использует тег, поэтомуиспользовать его можно будет только один раз. Приобъявлении объединения создается его экземпляр сидентификатором diff_type.

Рисунок 1 — Исходный текст программы с целыми типами данных.

В строке 6 с помощью элемента объединенияdiff_type оно интерпретируется как тип char и емуприсваивается значение, равное ASCII символу 'A'.

В строках 7, 11, 14, 17 вызывается функцияформатированного вывода printf, которая выводит одну иту же память объединения diff_type как значения разноготипа. Следует обратить внимание, в строке 17 последний

Page 356: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

356

элемент шаблона вывода заменен на %u, что указываетна необходимость вывести значение usi как значениебеззнакового типа.

В строках 9, 10, 13, 16 выполняется присвоениеdiff_type различных значений, интерпретируемых поправилам разных типов.

Рисунок 2 — Отображение потока вывода программы

На рисунке 2 представлено отображение потокавывода описанной ранее программы.

Первая строка вывода сформирована строкой 7исходного текста программы. До этого выводаобъединение было интерпретировано как тип char иприсвоено значение 65. Первый символ А соответствуетвыводу diff_type.ch как типа char. Для получения кодасимвола в шаблоне вывода необходимо указать выводтипа %d. Таким образом получено значение 65,соответствующее символу A английского алфавита.Вывод diff_type.si и diff_type.usi дает произвольныезначения, т. к. при инициализации объединения типомchar не была задействована вся память объединения.Произвольное значение является результатом выводамусора из не инициализированной части объединения.При выводе значения как знакового и беззанаковогополучен одинаковый вывод, т. к. указан один и тот жешаблон вывода %d.

Вторая строка вывода сформирована после того, каквсе биты объединения сначала были обнулены, а ужезатем было присвоено значение 65 как типу char. В этом

Page 357: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

357

случае, при любой интерпретации, значение равно 65,т. е. коду символа А.

Третья строка вывода сформирована послеприсвоения dif_type значения -65 типа unsigned int. Код-65 был интерпретирован как непечатаемый символ иотображен символ псевдографики. Значения всехостальных типов выведены верно.

Последняя строка вывода сформирована послеприсвоения памяти объединения значения -65000000.Данное значение не может вместится в один байт типаchar. В результате -65000000 было интерпретировано каксимвол псевдографики и значение -64 типа char.Значение выведено правильно при использовании типаint и неверно при использовании типа unsigned int.Следует обратить внимание, присвоение было приведеноименно как тип unsigned int (строка 16 исходного текстапрограммы). Компилятор сделал исполняемый файл,который проверил допустимый объем ОЗУ для хранениязначения и просто поместил в них переданные емубайты, без учета типа данных.

При использовании типов данных с плавающейзапятой, «эффекты» неверной интерпретации типовданных будут другими. Рассмотрим пример исходноготекста программы на рисунке 3.

В строке 4 объявлено объединение сидентификатором diff_type, которое может бытьинтерпретировано как тип int, float или double.

В строках 7, 10, 13 использована функцияформатированного вывода, выводящая памятьобъединения как разные типы данных.

В строках 6 и 9 производится присвоение значенияэкземпляру объединения deff_type разного типа.

В строке 12 объединение интерпретируется какцелое число и ему присваивается значение этого же

Page 358: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

358

объединения как типа double. При этом выполняетсянеявное приведение присваиваемого значения кцелочисленному типу.

Рисунок 3 — Исходный текст программы с данными сплавающей запятой

Отображение потока вывода программы, полученнойиз этого исходного текста программы, представлено нарисунке 4.

Рисунок 4 — Отображение потока вывода программы

Первая строка вывода сформирована 7 строкойисходного текста программы. Объединению при этомприсвоено значение 100.0 типа float. При этом

Page 359: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

359

правильное значение сохраняется только в случае, еслиобъединение интерпретируется как тип float. Первое ивторое значение отлично от правильного.

Рисунок 5 — Исходный текст программы с явным приведением типов

Вторая строка вывода сформирована 10 строкойисходного текста программы. В этот раз присвоенозначение 100.0 как тип double. Правильно отобразить его

Page 360: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

360

получилось только как тип double.Последняя строка вывода сформирована 13 строкой

исходного текста программы. Объединению былприсвоен результат неявного приведения значения типаdouble к типу int.

Неявное преобразование может приводить кнеожиданным результатам. При последнем выводезначения типа int и типа double совпали, однако эторезультат работы в состоянии «неопределенногоповедения», описанного в стандарте языкапрограммирования. Не стоит использовать такие способыпрограммирования в надежном приложении. Это можетпривести, например, к делению на ноль и вызватьаварийное завершение работы программы.

Рассмотрим пример исходного текста программы сявным преобразованием типов, используемого дляокругления дробных чисел до сотых долей числа. Данныйтекст программы приведен в предыдущем разделе. Здесьон дополнен отладочными вызовами функции printf встроках 7, 8, 12, 16, 20, 24 для отображения вычисляемыхзначений после каждой операции. Вызов функции printfспециально сдвинут влево для упрощения визуальноговосприятия. В местах выполнения явного преобразованиятипов данных, желаемый тип данных указан в скобках.На рисунке 6 показаны данные потока выводапрограммы, исходный текст которой представлен нарисунке 5.

Рисунок 6 — Отображение потока вывода программы

Page 361: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

361

Первая и вторая строка вывода сформированы 7 и 8строками исходного текста программы. На нихотображаются значения переменных, отличающихся втысячных долях.

Третья строка вывода содержит округленноезначение без дробной части. Этот вывод полученвызовом функции в 12 строке исходного текстапрограммы. Выполнение отбрасывания дробной частипоказано в 10 строке. Для этого достаточно перед знакомприсвоения явно указать требуемый тип (int) .

Четвертая и шестая строки вывода сформированы 16и 24 строками исходного текста программы. Они выводятокругленные значения, сохраненные в переменныхdbl1_temp и dbl2_temp соответственно.

Последняя строка вывода сформирована 24 строкойисходного текста программы. Надпись «Значения равны»подтверждает, что округление до сотых переменных dbl1и dbl2 произведено верно.

Приведенные выше примеры демонстрируют разноерасположение данных в ОЗУ и способы их интерпретациив зависимости от типа данных. При использованииуказателей разных типов, также необходимо выполнениеопераций приведения типа данных. Наиболее популярнаяплатформа x86 использует одинаковый размер памятидля большинства указателей разных типов, что приводитк невниманию программистов к контролю размерауказателей различных типов. Это может приводит кпоявлению ошибок в программах при написанииисходных текстов программ, переносимых на другиеплатформы.

Приведем примеры явных приведений для составных типов.

Page 362: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

362

int *array_ptr = (int []){4, 5};

Данное выражение объявляет указатель сидентификатором array_ptr на тип int, который будетуказывать на массив из двух элементов со значениями 4и 5.

const float *array_ptr = (const float []){1.0, 1.1, 1e2};

В приведенном выражении объявляется указатель натип float с идентификатором array_ptr, который будетуказывать на массив из трех элементов. Следует обратитьвнимание, последнее значение инициализируется череззначение равное 1*102.

Вопрос совместимости типов рассмотрен в пункте6.2.7 стандарта языка программирования Си. Также вэтом пункте приведены ссылки на другие разделы языкапрограммирования, в которых описаны дополнительныеправила совместимости спецификаторов, квалификаторови объявлений. В соответствии с этими правилами одинтип может сводится к другому, однако это относится куказателям на массивы и функции.

Для более детального изучения расположенияэлементов типов данных в ОЗУ можно использоватьобъединения, включающие в себя массив типа char, спомощью которого будут выводиться изменения в ОЗУ.

Неверное использование приведения типов даетсложно исправляемые ошибки, некоторые из которыхудается обнаружить только во время длительнойэксплуатации.

Page 363: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

363

5.3. Логические, битовые операции, операции сдвига, операции сравнения

Логические, битовые операции и операции сдвигаприменяются только к целочисленным значениям!

Базовых логических операций три: отрицание (!),логическое И (&&), логическое ИЛИ (||).

Логическое отрицание упоминается в стандартеязыка программирования Си один раз в разделе 6.5.3.3.Логическое И описано в разделе 6.5.13, а логическоеИЛИ в разделе 6.5.14.

char value1 = 2;printf("%d %d %d\n", value1, !value1, !(!value1));

Приведенные выше строки текста на языке Сисформируют следующий вывод

2 0 1

Первая цифра 2 соответствует значению переменнойvalue1 до выполнения операций. Цифра 0 соответствуетлогической инверсии (отрицанию) числа 2, т. к. любоезначение, отличное от 0, в Си является логическойединицей. Последняя цифра равна 1, т. к. инверсия от 2равна 0, а инверсия 0 равна 1.

Следующие строки демонстрируют применения логических И и ИЛИ.

char value1 = 2;char value2 = 0;printf("%d && %d = %d\n", value1, value2, value1 &&

value2);printf("%d || %d = %d\n", value1, value2, value1 ||

Page 364: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

364

value2);

В результате их исполнения получен следующийвывод

2 && 0 = 02 || 0 = 1

Первая строка вывода демонстрирует результатлогической операции И между значениями 2 и 0.Результатом операции является 0. Логическая операцияИ возвращает 0 или 1. Единица возвращается только втом случае, если оба операнда отличны от 0. Вприведенном примере второй операнд равен 0, значит ирезультат операции равен 0.

Вторая строка вывода является результатомлогической операции ИЛИ. Результат логическойоперации ИЛИ также 0 или 1. Ноль операция возвращаетв случае, если два операнда равны 0, во всех остальныхслучаях, возвращается 1. Так как один из операндов неравен 0, то результат операции 1.

Следующими будут рассмотрены операции сдвига.Они описаны в разделе 6.5.7 стандарта языкапрограммирования Си. К ним относятся две операции:

- операция сдвига влево << ;- операция сдвига вправо << .Операция сдвига влево заключается в перемещении

всех значений бит на один байт влево и дописывание 0 вкрайний правый бит. Значение крайнего слева байтатеряется. Арифметически данная операция соответствуетумножению на 2.

Операция сдвига вправо выполняется наоборот.Значения всех битов сдвигаются вправо с потерейкрайнего правого бита. Арифметически данная операция

Page 365: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

365

соответствует делению на 2.Ниже приведен пример использования операций

сдвига

value1 = 3;printf("%d << 2 = %d\n", value1, value1 << 2);value1 = value1 << 2;printf("%d >> 2 = %d\n", value1, value1 >> 2);value1 = value1 >> 2;

Приведенные операции приводят к следующемувыводу.

3 << 2 = 1212 >> 2 = 2

Выполняя сдвиг влево на два бита значения 3( 00000011 ), получено значение 12 ( 00001100 ).Обратный сдвиг вправо на два бита приводит кпреобразованию 12 ( 00001100 ) обратно к значению 3( 00000011 ).

Далее рассмотрим битовые операции. Битовые(побитовые) операции допустимо применять как кбитовым полям, так и к значениям других типов. Битовыеоперации и операции сдвига могут работать неочевиднодля программиста при переносе на архитектуры с другойразрядностью или просто другие архитектурымикропроцессора. Часто это связано с неуемнойпривычкой некоторых программистов строитьнагромождения битовых выражений там, где можнообойтись вполне читаемыми выражениями без потерипроизводительности. В связи с этим рекомендуетсявыносить все подобные операции в отдельныеплатформозависимые модули.

Page 366: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

366

Побитовое отрицание ( ~ ) упоминается в стандартеязыка программирования один раз в разделе 6.5.3.3.Операция битовое И ( & ) рассматривается в разделе6.5.10. Операция битовое ИЛИ ( | ) описана в разделе6.5.12. Также присутствует операция исключающегоИЛИ ( ^ ), описанная в разделе 6.5.11.

Рассмотрим операцию отрицания с помощьюприведенного ниже исходного текста на языкепрограммирования Си.

unsigned char value1 = 1;unsigned char value2 = 0;printf("%d %d %u\n", value1, ~value1, ~value1);printf("%d %d %u\n", value2, ~value2, ~value2);

Следует обратить внимание, что результат отрицаниявыводится сначала как знаковое целочисленноезначение, затем как беззнаковое значение.

В результате выполнения приведенного вышеисходного текста, будет сформирован следующий вывод.

1 -2 42949672940 -1 4294967295

Первая строка вывода соответствует инверсиизначения 1. В случае вывода инверсии 1 в виде знаковогоцелого числа получено значение, соответствующее -2,которое, в свою очередь, соответствует значению наединицу меньше максимально допустимого значения.

Вторая строка вывода соответствует инверсии числа0. Инверсии 0 соответствует знаковое целочисленноезначение -1 или максимально допустимое значение дляцелочисленного беззнакового типа.

Для демонстрации работы битовых операций

Page 367: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

367

рассмотрим результат работы следующего исходноготекста на языке Си

printf("1 & 3 = %d (%u)\n", 1 & 3, 1u & 3u);printf("1 | 3 = %d (%u)\n", 1 | 3, 1u | 3u);printf("1 ^ 3 = %d (%u)\n", 1 ^ 3, 1u ^ 3u);

Ниже показано содержание стандартного потокавывода после выполнения приведенного исходного текста

1 & 3 = 1 (1)1 | 3 = 3 (3)1 ^ 3 = 2 (2)

В результате выполнения первой строки выполненабитовая операция И над числами 1 и 3 как знакового, таки беззнакового типов. В результате получено значение 1,т. к. в значении 1 ( 00000001 ) и в значении 3( 00000011 ) младшие биты равны 1.

Вторая строка выведена как результат битовойоперации ИЛИ для тех же значений. В результирующемзначении в 1 установлены те биты, которые установленыв 1 в одном из входных операндов.

Третья строка выводит результат битовой операцииисключающее ИЛИ. Для отображения всех возможныхрезультатов данной операции ниже приведена таблицаистинности этой операции. Вывод таблицы истинностисгенерирован следующими строками текста программы

printf("0 ^ 0 = %d\n", 0 ^ 0);printf("1 ^ 0 = %d\n", 1 ^ 0);printf("0 ^ 1 = %d\n", 0 ^ 1);printf("1 ^ 1 = %d\n", 1 ^ 1);

Page 368: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

368

В результате получены следующие значения:

0 ^ 0 = 01 ^ 0 = 10 ^ 1 = 11 ^ 1 = 0

В соответствии с таблицей, значение 1 будетполучено только в том случае, если один их операндовравен 0, а другой 1.

Операторы присвоения описаны в разделе 6.5.16стандарта языка программирования Си. К ним относятсякак собственно оператор присвоения, так и сокращенныеформы записи выражений с использованием присвоения.Перечислим эти операторы

= *= /= %= += -= <<= >>= &= ^= |=

Оператор присвоения используется почти в каждомисходном тексте программы и сложностей с егоприменением не возникает. Сокращенные формывстречаются реже, но также пользуются популярностьюу программистов. Их преимущество в том, что онисодержат как минимум на одну ассемблернуюинструкцию меньше, чем полная форма.

Например:

x += 3;x -= 2;x ^= 1;

соответствует

x = x+3;

Page 369: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

369

x = x - 2;x = x^1;

Совместно с операциями присвоения стоитупомянуть операции эквивалентности, которые описаныв разделе 6.5.9 стандарта языка программирования Си исостоят из двух операций: проверка на равенство ( == ) ине равно ( != ). Результатом этих операций являетсязначение 1 или 0 типа int.

Операциям сравнения посвящен раздел 6.5.8стандарта языка программирования. К операциямсравнения относятся операторы меньше ( < ), больше( > ), меньше или равно ( <= ) и больше или равно ( >= ).

Наиболее часто битовые операции используются дляпроверки состояния одного из битов или для измененияпорядка следования байт. Для проверки состояния битаиспользуются следующие действия:

- проверка состояния бита;

char bitstatus (char data, char position) {return ((data & (1 << position)) != 0);

}

- инверсия значения бита

char bitreverse (char data, char position) {return (data ^ (1 << position));

}

Для изменения порядка следования байт можноиспользовать следующие приемы: интерпретироватьцелое число как объединение с массивом, содержащимэлементы типа char, и выполнять сдвиг после присвоениякаждого значения или произвести присвоение элементов

Page 370: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

370

массива самому себе, но в обратном порядке.Для демонстрации преобразования потребуется

объявление составного типа данных объединенияbyte_order.

union byte_order {unsigned int data;unsigned char bytes[8];

};

Сами преобразования выполняют двенижеследующие функции:

- переход от архитектуры little-endian к текущейархитектуре

unsigned int little_endian_to_memory (unsigned int value) {

int size_in_bytes = sizeof(int);int count = 0;union byte_order buffer;buffer.data = value;unsigned int result = 0;for ( ; count < size_in_bytes; count++)

result |= buffer.bytes[count] << count*8;return result;

}

- переход от архитектуры big-endian к текущийархитектуре

unsigned int big_endian_to_memory (unsigned int value){

int size_in_bytes = sizeof(int);int count1 = 0;

Page 371: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

371

int count2 = size_in_bytes-1;union byte_order buffer;buffer.data = value;unsigned int result = 0;for ( ; count1 < size_in_bytes; count1++, count2--)

result |= buffer.bytes[count2] << count1*8;return result;

}

Наиболее правильное и переносимое решениепроблемы смены порядка байт — это использованиеспециальных функций ntohl, htonl, ntohs, htons. Они неявляются частью стандарта языка программирования и всоответствии со справочной информацией описаны вarpa/inet.h, однако фактически их определение можетнаходится в другом файле.

Page 372: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

372

5.4. Квалифицирующие типы и спецификаторы функций

Квалифицирующие типы не влияют на размервыделяемой памяти, однако помогают компилятору ипрограммисту уменьшать количество ошибок в исходныхтекстах программ. Они описаны в разделе 6.7.3стандарта языка программирования и включают в себяследующие ключевые слова

constrestrictvolatile_Atomic

Квалифицирующий тип _Atomic также описан впункте 6.7.2.4, const в 6.6, а restrict в 6.7.3.1 стандартаязыка программирования.

Квалифицирующий тип const указывает на то, чтообъект не модифицируемый. Это относится как к данным,так и указателям на данные или элементам структур.Примеры объявления объектов.

- значение по адресу не изменяется, адрес можетизменяться;

const int * I;int const * I;

- значение по адресу может изменяться, адресизменяться не может;

int * const I;

- значение по адресу и сам адрес изменяться не

Page 373: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

373

могут.

const int const * I;int const * const I;

Также константой является любое число или символ.К именованным константам относят значения,определенные с помощью директивы препроцессора#define .

Восьмеричные константы допустимо объявлять спомощью следующей конструкции '\000', где 000 —любые допустимые цифры.

Для обозначения шестнадцатиричных константиспользуется последовательность '\x00', где 00 — любыедопустимые цифры и буквы.

Квалифицирующий тип restrict применим только куказателям и сообщает, что данные по этим указателямрасполагаются в разных ячейках памяти, т. е. непересекаются. Примером пересекающихся данных могутслужить несколько указателей на разные элементы какподмассивы одного массива. Особенно следует обращатьвнимание на наличие этого квалифицирующего типа прииспользовании функций для работы с памятью.

Пример объявления объекта

int * restrict a;

Квалифицирующий тип volatile указываеткомпилятору не выполнять оптимизацию даннойпеременной, даже в случае отсутствия обращения к ней.Такая необходимость часто возникает в случаепотенциальной возможности изменения значения издругого потока. Также этот квалифицирующий типиспользуется при работе с портами, в прерываниях и в

Page 374: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

374

регистрах, связанных с внешними устройствами.Переменные, используемые в этих операциях,необходимо объявлять с этим квалифицирующим типом.Пример объявления переменной.

volatile int value;

Указатель на эту переменную может быть объявленследующим образом.

volatile int * ptr;илиint volatile *ptr;

Для объявления volatile-указателя на volatile-переменную используется следующая запись

volatile int * volatile ptr;

Программисты с небольшим опытом созданиямногопоточных приложений иногда путают volatile сатомарными операциями. Операции с объектамиквалифицирующего типа volatile выполняются так же,как и все остальные операции, их выполнение можетбыть прервано в любой момент, поэтому их нельзяиспользовать для синхронизации потоков.

При использовании volatile переменной указатель нанеё также должен содержать квалифицирующий тип.

Квалифицирующий тип _Atomic используется с цельюизбежать состояний гонки данных. При этом состояниинесколько потоков получают доступ к одной и той жеобласти памяти, и в лучшем случае, значение становитсяневерным, в худшем, программа может аварийнозавершиться.

Page 375: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

375

В соответствии со стандартом языкапрограммирования, объекты атомарных типов являютсяединственными объектами, при использовании которыхневозможно состояние гонки данных, т. е. поток неможет прерывать процесс изменения значения объекта,пока его состояние изменяет другой поток. Такой эффектдостигается путем соблюдения четырех правил, которыеописаны в разделе 6.7.3 стандарта языкапрограммирования.

Следует учесть, атомарность существует только дляобъектов lvalue, т. е. тех, что указываются до знакаприсвоения. Пример использования данногоквалифицирующего типа

_Atomic const int *ptr;

Приведенное выше объявление создает указатель наатомарную константу целочисленного типа int. Также встандарте языка программирования в разделе 7.17присутствует библиотека stdatomic.h, с помощью которойвозможно использование другого вида объявленияатомарных объектов. Например, объявить атомарнуюоперацию целочисленного типа можно с помощьюприведенной ниже строки.

atomic_int value;

Базовый тип не равен базовому типу сквалифицирующим типом. Следует иметь в виду, чтоиспользование квалифицирующих типов требуетвыполнения приведения типов, в том числе к их базовымтипам.

Спецификаторы функций описаны в разделе 6.7.4стандарта языка программирования. Описание

Page 376: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

376

объявления функций рассмотрено в разделе 6.9.1. К нимотносятся два ключевых слова inline и _Noreturn.

Реализация спецификатора inline часто заключаетсяв том, что текст тела функции подставляется в место еёвызова, ускоряя выполнение программы.

Пример функции со спецификатором inline.

inline void print_int (int digit);

Спецификатор _Noreturn предписывает функции непроизводить возврат в точку вызова. Пример функции соспецификатором _Noreturn.

_Noreturn void function_name ();

Не стоит путать такое поведение с возвратомзначения пустого типа void. Отличие будетпродемонстрировано с помощью двух прототиповфункций. В соответствии с первым прототипом, функциявозвращает значение типа void, а выполнение программыпродолжается с последующего выражения.

void print_int (int digit);

Второй прототип функции объявлен в заголовочном файле setjmp.h.

_Noreturn void longjmp(jmp_buf env, int val);

Из прототипа функции следует, с её помощьювыполняется «дальний переход» в другой блок команд,при этом выполнение выражения следующего за точкойвызова этой функции невозможно.

В соответствии с пунктом 7.23 стандарта языка

Page 377: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

377

программирования в заголовочном файле stdnoreturn.hопределено макроопределение noreturn эквивалентное_Noreturn.

Далее приведен пример использования функции,которая ничего не возвращает и не передает управлениев вызвавшую её функцию.

#include <stdio.h>#include <stdlib.h>

_Noreturn void print_message(char * message) { printf("\n%s\n", message); exit(0);};

int main () { print_message("Hello"); return 0;}

Для сборки программы необходимо указыватьверсию языка программирования

gcc 03.c --std=c17

В соответствии с приведенным текстом программы,она будет завершаться вызовом функции exit() в функцииprint_message(), а не оператором return в функцииmain() .

Другая причина использования _Noretrun — этореализация длинного межсегментного перехода, прикотором производится изменение обоих регистровсчетчиков, а не только IP.

Page 378: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

378

5.5 Директивы предпроцессора

Директивы предпроцессора являются еще однимсредством, позволяющим изменять исходный текстпрограммы или комбинировать набор файлов,используемых для создания исполняемого файла доначала компиляции. Все действия предпроцессорвыполняет до этапа компиляции, что позволяет включатьв исходный текст программы конструкции,неиспользуемые в языке программирования Си.

К целям использования директив препроцессораотносится выбор фрагментов текста программы взависимости от:

- модели процессора;- аппаратной конфигурации ЭВМ;- конфигурации ПО, включая создаваемое ПО;- версии и конфигурации используемого

компилятора.Представленные цели достигаются с помощью

следующих возможностей:- замены или удаления символов;- вставки содержимого произвольного файла;- условной компиляции;- вывода сообщений о предупреждениях и ошибках;- задания режимов работы компилятора.Не стоит использовать средства предпроцессора в

следующих целях:- использовать директиву #define вместо функций во

избежания путаницы со скобками;- изменять архитектуру, логику программы без

объективной необходимости;- закладывать несколько различных архитектур

программы;- с целью корректировки этапов создания

Page 379: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

379

исполняемого файла, создавая, например, единственновозможную последовательность подстановки файловдирективами include;

- создавать сложночитаемые конструкции,определяемые и переопределяемые в разных файлаходного проекта, например, изменять синтаксис языкапрограммирования в некотором выражении;

- в других случаях использования средствпредпроцессора не по прямому назначению.

Некорректное использование директивпредпроцессора обычно происходит при обнаруженииошибок проектирования ПО на поздних этапахразработки, многолетней поддержке ПО, отсутствиичеткого технического задания, добавление новогоаппаратного обеспечения или программного окружения,неучтенного на этапе разработки архитектуры ПО.

Директивы предпроцессора описаны в разделе 6.10стандарта языка программирования.

Если строка начинается с символа # и не содержитдругих символов, то эта директива считается пустойдирективой и не обрабатывается.

#

Подключение заголовочных файлов. Прииспользовании символов меньше и больше файл долженнаходится в каталоге include. При использованиидвойных кавычек, файл должен находится в текущемкаталоге.

#include <stdio.h>#include "02.h"

Для объявления констант и выражений используется

Page 380: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

380

директива #define, которая имеет несколько формзаписи.

Первая форма записи директивы #defineиспользуется для определения глобальных констант иимеет следуюший вид

#define VALUE 100LU

или

#define VALUE2

Значение константы VALUE равно 100 и имеет типunsigned long int. Тип константы указывается с помощьюследующих символов:

- U или u представляет константу в беззнаковойформе (например, 10U);

- F или f позволяет объявить константу типа float (97.2f);

- L или l объявляет тип long (5423L);- D или d соответствует типу double (59.3E-19D);- константы в шестнадцатиричном формате

начинаются с комбинации символов 0x (0xFFFF);- константы в восмеричном формате начинаются с

нуля, например 023.Допускается помбинирование типов констант,

например 023LD.Константа VALUE2 объявлена, но значение ей не

задано. С точки зрения синтаксиса предпроцессора онасчитается объявленной. Её можно использовать вдирективах предпроцессора без проверки значения.

Вторая форма записи директивы #define позволяетпроизводить замену одной последовательности символовна другую, разделителями между которыми могут быть

Page 381: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

381

один или несколько символов пробела.

#define DIFF(a,b) (a - b)

Приведенная директива позволяет использовать висхоном тексте конструкцию, синтаксически схожую свызовом функции

int x = DIFF(15,5);

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

#define text_const(value) # value

Используя следующие строки исходного текста,например в функции main()

int x = 4;printf(text_const(x) "\n");

В стандартный поток вывода будут выведенысимволы x и переход на новую строку несмотря на то, чтоидентификатор x соответствует целочисленнойпеременной. Он передается в выражение text_const,объявленное с помощью директивы предпроцессора#define. Выражение преобразует идентификатор x встроковую константу "x", которая и будет выведена.

С помощью последовательности ## , используемой вдирективе #define или другом макросе, производитсячастичное замещение идентификатора.

#define SUMM(x,y,z) (a##x + \

Page 382: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

382

a##y + \ a##z)

Конструкция в приведенном примере позволяетиспользовать следующий текст программы

int a1 = 4, a2 = 2, a3 = 1;printf("%d\n", SUMM(1,2,3)*2);

Второй аргумент функции printf будет заменен навыражение (a1+a2+a3)*2 за счет частичной заменыидентификаторов, выполненной с помощьюпоследовательности ##. Также в примере директивы#define используется символ \ , позволяющий переноситьэлементы синтаксиса директивы на следующую строку.

Другой прием использования ##, который такжеиспользует перенос на следующую строку

#define object_property( x ) x##X, x##Y, x##Height, \ x##Width

Объявление позволяет использовать прототип следующего вида

int object_property( object );

который будет преобразован препроцессором к следующему виду:

int object_property( objectX, objectY, objectHeight, objectWigth);

Отключение объявления констант и выраженийпроизводится директивой #undef, причем применение

Page 383: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

383

директивы к неопределенному ранее идентификатору несчитается ошибкой.

#undef VALUE1

Для проверки на объявление используется директива#ifdef.

#ifdef VALUE1#define PRINT() puts("VALUE1 define");

#endif#ifndef VALUE1

#define PRINT() puts("VALUE1 undefine");#endif

Использование в исходном тексте программывыражения PRINT(); приведет к выводу сообщения"VALUE1 define", если константа VALUE1 определена или"VALUE1 undefine" в обратном случае.

Директивы #ifdef, #ifndef, #if, #elseif, #else, #endifпозволяют реализовывать условную компиляциюпрограммы до обработки текста программыкомпилятором. Каждая директива #if должназаканчиваться директивой #endif. Между ними можетиспользовать любое количество директив #elseif и толькоодна #else, причем она должна быть последней.Например:

#if VALUE == 1#define PRINT() puts("VALUE = 1");

#elif VALUE == 2#define PRINT() puts("VALUE = 2");

#else#define PRINT() puts("VALUE = undefine");

Page 384: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

384

#endif

Используя выражение PRINT(); можно определить,какое значение имеет константа VALUE.

Для перехода интерпретации директивпредпроцессора в другой файл используется директива#line.

#line 151 "02.c"

Данный пример предписывает перейти в файл 02.стекущего каталога на строку 151. В практическомпрограммировании директива используется толькоопосредовано, через другие директивы, например#include.

Для объявления токенов и их состоянийиспользуется компиляторозависимая директива#pragma.

#pragma listing on "..\dir"

Перевести некоторое абстрактное значение listing всостояние on для объекта dir, расположенного в текущемкаталоге.

Директива #error используется для выдачидиагностических собщений.

Для расширения возможностей при использованиипредпроцессора рекомендуется ознакомится савтоматически создаваемыми константами, описаннымив разделе 6.10.8 стандарта языка программирования.

В качестве общепризнанного примера грамотногоиспользования средств предпроцессора можнорассматривать заголовочный файл queue.h из каталога/usr/include/sys/, который не является частью стандарта

Page 385: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

385

языка программирования. Объявленные в нем составныетипы и функции реализуют связные списки и этареализация признается эталонной на протяжениинескольких десятилетий.

Page 386: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

386

5.6 Отличия между стандартами языка Си разных лет

История появления стандарта языкапрограммирования Си описана в Википедии достаточноподробно, чтобы получить представления об основныхэтапах его развития. В различных книгах встречаетсядополнительная информация, уточняющаяобщепринятую историю или личные переживанияучастников процесса зарождения языка Си.

Язык продолжает развиваться и сейчас.Разработчики компиляторов не всегда успевают занововведениями, публикуемыми в новых стандартах. Поэтой и другим причинам скорее всего не существует ниодного компилятора, полностью реализующего текущийстандарт Си. При этом в ближайшие годы долженпоявится следующий стандарт, с еще большимколичеством возможностей.

Во времена зарождения языка, значительная частьвремени разработки программы тратилась на описаниеопераций с ОЗУ, автоматизацию работы с регистрамимикропроцессора. Несмотря на различия в архитектурахмикропроцессоров, существует уровень абстракции этихопераций, единый для всех основных архитектурмикропроцессоров. Именно это и стало фундаментомязыка Си. Эта часть языка монолитна и не меняется напротяжении всего времени его существования.Остальные части стандарта могут подвергатьсяизменениям, поэтому крайне рекомендуется припроектировании программного обеспечения выделять всевзаимодействия с любым аппаратным обеспечением,многопоточность, сетевые взаимодействия в отдельныемодули или функции, а логику и математику программывыделять в её ядро. Таким образом можно написать

Page 387: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

387

исходный текст, который может оставаться неизменнымдесятки лет, а изменению будут подвергаться толькоотдельные модули взаимодействия с другими элементамиинформационной системы.

Изучая новые стандарты, не стоит забывать омиллионах строк исходных текстов других программ,которые, возможно, придется использовать принаписании своей программы. В связи с этим, любоеновшество или новый прием написания, используемые висходном тексте, должны обосновываться, а не братьсяза основу по причине того, что оно уже появилось.Данное правило особенно важно для языка Си, т. к.многие специализированные микропроцессорыиспользуют урезанные возможности языка. В связи сэтим, чем меньше разных дополнений будет содержатьисходный текст, тем меньше придется переписывать припереходе на новую платформу.

Наибольшее количество важных изменений былозакреплено в стандарте С99 (1999 г.). Стандарты болеераннего периода в практической работе можно непринимать во внимание. Следующей важной вехой сталстандарт С11 (2011 г.), наиболее важныминововведениями которого стала библиотекамногопоточности, функции определения смещения,улучшенная поддержка UNICODE. Стандарт С17 (2017 г.)имеет также ряд дополнений, но они относятся кдеталям и мало влияют на написание исходного текста.Часто его представляют как черновик стандарта 2018года. Стандарт C18 (2018 г.) закрепил за собой имиджуточняющего документа. Следует иметь в виду, текущийстандарт языка программирования продается подостаточно высокой цене, но в свободном бесплатномдоступе имеется последний черновик предыдущегостандарта. Информация содержащаяся в черновике,

Page 388: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

388

достаточна для написания программ, а финальныйвариант стандарта представляет большой интерес скореедля разработчиков компилятора.

Page 389: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

389

5.7. Переменные окружения. Потоки ввода-вывода. Передача параметров

В соответствии со стандартом прикладногопрограммного интерфейса для ОС POSIX, при созданиипроцесса, ОС предоставляет служебную информацию длякаждого создаваемого процесса в виде специальныхзначений, называемых переменными окружениями. Дляобеспечения обмена информацией с создаваемымпроцессом ОС регистрирует три участка памяти, которыеиспользуются для обмена информацией с этимпроцессом. Доступ к этим участкам памятиосуществляется с помощью абстракций потоков ввода,вывода и потока ошибок. С целью передачи параметров,используемых при запуске программы, реализуетсямеханизм указания ключей после названия процесса.

Поток ввода имеет обозначение stdin и имеет номер0. Поток вывода имеет обозначение stdout и имеет номер1, а поток ошибок имеет обозначение stderr и имеетномер 2.

Рассмотрим учебный пример использования всехтрех механизмов с помощью программы, исходный тексткоторой представлен на рисунке 1. Программа полученаиз этого исходного текста с помощью команды

gcc 01.c && ./a.out in.txt out.txt error.txt

Переданными параметрами являютсяпоследовательности символов: in.txt, out.txt и error.txt.Далее следует описание строк исходного текстапрограммы, поясняющих механизмы, описываемые вданном разделе.

В строке 4 используется прототип главной функцииmain, принимающей три параметра. Параметр argc

Page 390: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

390

содержит числовое значение, равное количествупереданных параметров, строкой вызова программы.Следует учесть, по стандарту POSIX первый параметр,передаваемый в программу всегда равен имениисполняемого файла программы. В связи с этим,минимальное значение argc равно 1, даже в том случае,если в строке вызова отсутствуют передаваемыезначения.

Аргумент argv является двумерным массивом,содержащим строки, в каждой из которых находится поодному переданному параметру. Соответственно, встроке argv[0] всегда находится название исполняемогофайла программы.

Аргумент env содержит двухмерный массив. В немкаждая строка соответствует некоторой переменнойокружения, которые были созданы ОС при созданиипроцесса. Последней строкой этого массива являетсястрока, не содержащая символов.

В строке 5 выполняется проверка количествапереданных параметров. Их должно быть ровно 4. Такаяпроверка необходима, т.к. в строке 7 выводится списокпереданных аргументов и если их количество несовпадет, ОС завершит программу из-за нарушения еёадресации.

В строке 6 производится вызов функции system() изстандартной библиотеки stdlib. Аргумент функции — этострока с командой "pwd > 1.txt". Выполнение даннойкоманды в ЭТ приведет к выводу текущего каталога встандартный поток вывода, а символ ">" перенаправляетстандартный поток вывода программы pwd в файл 1.txt.Вызов функции system приводит к тому, что команда,переданная в неё, исполняется так же, как и при еёвыполнении в ЭТ.

Page 391: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

391

Рисунок 1 — Использование переданных параметров,перенаправление стандартных потоков и переменныхокружения

В строках 7-8 описан вызов функция fprintf. Еёпервым аргументом является поток, в который будетвыведено форматированное сообщение. Второй аргументсоответствует шаблону вывода операторов printf, scanf.Начиная с третьего аргумента идет список переменных,значения которых будут подставлены и отформатированы

Page 392: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

392

в соответствии со спецификаторами типов шаблонавывода. В данном случае, в стандартный поток выводавыводятся имена переданных в программу параметров.

В строке 10 вызывается функция system(), котораявыполняет команду "env > 1.txt". В команде дляперенаправления потока вывода используется символ">", что приведет к перезаписи файла 1.txt строками,содержащими переменные окружения программы.

В строке 11 вызывается функция переоткрытиястандартного потока ввода stdin в режиме на чтение впоток, соответствующий файлу, имя которого переданоаргументом с индексом 1. После выполнения этоговызова, в поток ввода программы будет помещено всесодержимое файла in.txt.

В строке 12 вызывается функция переоткрытия,которая перенаправит стандартный поток вывода в файл,имя которого содержится в аргументе с индексом 2 врежиме добавления. Все данные, отправляемые встандартный поток вывода будут записываться в файлout.txt.

Выполнение вызова строки 13 приведет к записи всехданных стандартного потока ошибок в файл error.txt.

В строках 16-19 производится считываниестандартного потока ввода, присоединенного к файлуin.txt до конца файла и запись считанных значений встандартный поток вывода и стандартный поток ошибок.

В строках 22-26 производится вывод всех значенийпеременных окружения в стандартный поток вывода, приэтом соединение потока вывода с файлом out.txtсохраняется.

В строке 28 выполняется вызов команды,приводящей к отображению информационногосообщения в графическом интерфейсе. Строка 28перенесена на следующую строку. Продолжение строки

Page 393: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

393

можно отличить по отсутствию номера строки в еёначале. Следует обратить внимание, в этой строкеиспользуются символы двойных кавычек в шаблоневывода. Для их корректной интерпретации необходимоиспользовать правила экранирования символов.

В строке 29 производится вызов той же команды, чтои в строке 28, но с использованием транспортногосетевого протокола удаленного управления ssh. Для еёуспешного выполнения необходимо настроитьбезключевой доступ на устройство, сетевой адрескоторой будет указан после символа @. В этом случаесообщение в графическом интерфейсе отобразится надругом устройстве.

До выполнения программы на накопителеприсутствовали файлы in.txt следующего содержания

first stringsecond string

и файл программы.После создания и исполнения программы с помощью

указанной выше команды будут созданы файлы out.txt иerror.txt. Они будут созданы ЭТ.

В ЭТ будет выведена строка

Переданные параметры: ./a.out, in.txt, out.txt, error.txt

Строка выводится функцией fprintf, описанной встроках 7-8. На момент исполнения строк 7 и 8стандартный поток вывода еще проассоциирован стерминалом и выводит сообщения в него.

В графический интерфейс будет выведенографическое сообщение, представленное на рисунке 2.

Page 394: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

394

Рисунок 2 — Графическое сообщение

Содержимое файла in.txt не изменилось, т.к. доступ кнему предоставляется только для чтения.

Файл 1.txt, созданный строкой 6 текста программы ипересозданный строкой 10, содержит все переменныеокружения. Приведены три первые переменныеокружения.

LESSKEY=/etc/.lessXDG_VTNR=1XDG_SESSION_ID=2

Файл out.txt открыт в строке 12, а запись в негопроизводится в строках 17 и строках 23, 24. В строке 17явно указано о записи в стандартный поток выводасодержимого буфера. В строках 23, 24 используютсяоператоры printf и puts, которые выполняют вывод встандартный поток вывода. Все записи в стандартныйпоток вывода, выполняемые после 12 строки, приводят кзаписи в файл с именем, переданным argv[2], а именноout.txt. Последовательность "first string second string"перенесена из файла in.txt с помощью строки 17.Остальные данные перенесены строками 23, 24.

Первые строки файла out.txt

first string second stringXDG_VTNR=1

Page 395: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

395

LESSKEY=/etc/.lessSSH_AGENT_PID=743XDG_SESSION_ID=2

Содержимое файла error.txt

ssh: connect to host localhost port 22: Connection refused

first string second string

Наиболее интересная ситуация сложилась ссодержимым файла error.txt. Первая строка сообщает оневозможности подключится по протоколы ssh ивыполнить команду. Данное сообщение об ошибкесформировано программой ssh в ответ на её вызов встроке 29. Однако вторая строка сформирована строкой18, которая переносит содержимое стандартного потокаввода в стандартный поток ошибок, т.е. раньше. Этостало возможно в связи с тем, что данные потока ошибокнакапливались в буфере программы и были записаны вфайл error.txt только после завершения программы.Данные же потока ошибок ssh были записаны в файлраньше, т.к. работа с ssh завершена в 29 строке. Дляпринудительного сброса буфера в файл используетсяспециальная функция FLASH.

Работая с ЭТ, также можно использовать подобныеприемы. ЭТ также является процессом, а значит имеетпеременные окружения и для него создаютсястандартные потоки.

Для отображения переменных окруженияиспользуются команды printenv или env, возможностикоторых отличаются доступными ключами. Первые тристроки вывода этой команды соответствуют выводузначений строк, полученных с помощью аргумента

Page 396: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

396

функции main.

XDG_VTNR=1LESSKEY=/etc/.lessSSH_AGENT_PID=743

Примером перенаправления стандартных потоковмогут служить следующие команды. Для ихдемонстрации необходимо запустить два ЭТ. В одном ЭТнеобходимо выполнить команду

tty

Выводом команды является номер текущего ЭТ.Примерный вывод

/dev/pts/1

Во втором ЭТ выполняется команда (после "1" пробел отсутствует)

echo “Строка улетела в другой ЭТ” 1>/dev/pts/1

В результате выполнения команды в первом ЭТ будетвыведено сообщение

Строка улетела в другой ЭТ

Page 397: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

397

6. Технологии программирования. Средстваавтоматизации разработки

6.1. Жизненный цикл ПО. Методологииразработки ПО

Жизненный цикл программного обеспеченияначинается в момент осознания потребности в нем изаканчивается в момент вывода всех его элементов изэксплуатации.

Существует ряд стандартов, используемых дляразработки ПО. К ним относятся как стандарты,описывающие жизненный цикл программногообеспечения, так и стандарты, посвященные разработкесредства автоматизации или специализированныестандарты для разработки ПО с целью применения вобластях жизнедеятельности, связанных с высокимриском или особой ценностью.

К стандартам, описывающим жизненный циклпрограммного обеспечения, относятся:

- ГОСТ Р ИСО/МЭК 12207-2010 Информационнаятехнология. Системная и программная инженерия.Процессы жизненного цикла программных средств;

- ISO/IEC 12207:2008 «System and softwareengineering — Software life cycle processes»;

- ГОСТ 34.601-90 Информационная технология.Комплекс стандартов на автоматизированные системы.Автоматизированные системы. Стадии создания;

- и другие.К соответствию внутренних регламентов разработки

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

Сегодня большинство популярных программразрабатывается небольшими компаниями и малыми

Page 398: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

398

группами разработчиков, в связи с этим, стандартыразработки ПО могут показаться устаревшими иненужными. Однако существует множество областейразработки, где малыми силами решить поставленныезадачи невозможно.

При небольших трудозатратах и в небольшихпроектах нет необходимости проходит все этапыжизненного цикла программного обеспечения, чтоприводит к значительной экономии средств и ускорениюразработки. Такой взгляд на разработку прижился дажев крупных корпорациях и привел к новой идеологииразработки, которую упрощенно можно назватьпостоянная бетта версия. В конкурентной борьбе упорделается на скорость выпуска продукта, часто в ущербего качеству. Кроме потери в качестве продуктаигнорирование стандартов разработки приводит кпроблемам с поддержкой и дальнейшим развитиемпроекта, что в свою очередь приводит к удорожаниюподдержания продукта в актуальном состояниидлительное время.

Вместо соблюдения стандартов жизненного циклаПО сегодня используют различные методологииразработки, которые не охватывают весь жизненныйцикл ПО. Почти все они пришли из англоговорящихстран. На сегодняшний день их существует несколькодесятков. Перечислим некоторые из них:

- Waterfall — традиционный подход, каскаднаямодель, водопад;

- Incremental Model — инкрементная модель;- Iterative Model — итерационная модель;- Spiral Model — спиралевидная модель;- Rational Unified Process (RUP)— рациональная

модель;- Agile — общая методология гибкой разработки;

Page 399: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

399

- Crystal Clear — методология с уравниваниемразработчиков в коллективе;

- Dynamic Systems Development Model (DSDM) –динамическая модель;

- Feature Driven Development (FDD) — методология,рассматривающая будущие изменения;

- Joint Application Development (JAD) —ориентированный на пользователя подход;

- Rapid Application Development (RAD) — модельбыстрой разработки;

- Scrum — концепция работы в условиях сорванныхсроков и идеологического кризиса;

- Test-Driven Development (TDD) — разработка черезтестирование;

- Lean Development (LD) — метод, предполагающийбережное отношение ко всем участникам процесса;

- Extreme Programming (XP) — экстремальнаяразработка в динамической среде.

Информация по всем методологиям разработкидоступна в свободном доступе. У каждой методологииесть свои преимущества и ограничения. Каждой из нихможно посвятить главу книги. На практике выборметодологии зависит от многих факторов, включаяпредпочтения конкретного руководителя. Критическимслучаем является экстремальное программирование,смысл которого сводится к достижению цели любымиспособами за минимальное время.

Одним из главных документов жизненного циклапрограммного обеспечения является техническоезадание на его разработку. Первой ошибкой, которуюсовершают все начинающие самостоятельныепрограммисты — отсутствие ТЗ или его низкое качество.В некоторых случаях бывает так, что разработка ведетсяфактически без него. Также ТЗ может присутствовать в

Page 400: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

400

виде расплывчатого рамочного описания. Причинамиэтого могут стать:

- низкая квалификация составителя ТЗ;- выделение недостаточных ресурсов на создание ТЗ;- вмешательство бюрократической машины;- необходимость удовлетворения сторонних

требований, которые в данном случае ухудшают качествоПО;

- создание ТЗ на основе «рамочной договоренности».Любое отклонение от равновесия в вопросе

стоимости работ, предлагаемая оплата должно вызватьподозрение и привести к дополнительному подробномуизучению ТЗ.

Несмотря на все предостережения, разработка безкачественного ТЗ возможна. Существует ряд приемов,которые можно использовать в таком случае,повышающие вероятность успешного выполненияпроекта. К ним относятся:

- наличие этапности разработки с четкоустановленными сроками и объемами работ;

- этапы разработки должны заканчиваться оплатойдо перехода к следующему этапу разработки;

- объем оплаты этапа должен соответствоватьтрудоемкости этапа;

- наличие этапа разработки прототипа илиполнофункционального прототипа, после утверждениякоторого дальнейшее изменение ТЗ должно бытьзапрещено;

- выполнение разработки документации послевыполнения демонстрации готового ПО и егоутверждения со стороны заказчика;

- четкое определение объема и сроков работ,включенных в гарантийные обязательства;

- четкое разграничение авторских и имущественных

Page 401: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

401

прав на разработанное ПО.Все, что не вкладывается в указанные правила,

должно оплачиваться заказчиком отдельно.Проблемами, связанными с разработкой ТЗ,

архитектуры ПО должны заниматься специалисты созначительным стажем программирования. Дляначинающего программиста чаще важнее найти тотсамый проект, который поможет ему в началепрофессионального пути получить опыт реальнойразработки, повысить уровень знаний, ликвидировавимеющиеся пробелы, получить хорошие характеристикии рекомендации. Всего этого нет на «токсических»вакансиях. Одной из причин появления таких вакансий —нечестное поведение предыдущего сотрудника, который,не справляясь со своими обязанностями, тянет допоследнего и внезапно бросает проект непосредственноперед его сдачей заказчику. Приведем некоторыепризнаки «токсической должности»:

- длинный список требований к должности;- должностные обязанности, не соответствующие

специальности (погрузка, монтаж оборудования,подготовка налоговой отчетности);

- использование избыточного числа технологий(список, содержащий более 5 технологий);

- требования не соответствуют вопросам и заданиямна собеседовании (ищут специалиста высшей категории,дают решать школьные задачки или задачи из другихобластей);

- «случайный» состав людей, проводящихсобеседование;

- слабая заинтересованность в приеме новогосотрудника (долго не отвечают, проявляют общуюнезаинтересованность);

- отсутствие возможности общаться с более

Page 402: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

402

опытными разработчиками;- отсутствие наставника;- проблемный непосредственный начальник;- «серая» заработная плата (признак низкой

прибыльности компании);- сложные схемы начисления заработной платы,

бонусы в разы превышают размер заработной платы;- негативные отзывы в общедоступных источниках,

датированные разными годами.Такие должности также можно использовать с

пользой для себя, если планируется работать в компаниипродолжительное время. Они позволят зарекомендоватьсебя как настоящего бойца, не боящегося трудностей.При этом велик риск заработать негативную репутациюкак специалиста.

Перейдем непосредственно к этапам написанияисходного текста программы. Эти действия выполняетнепосредственно программист.

1. Формулирование задачи на основе ТЗ илираспоряжения непосредственного руководителя.

2. Подготовка к написанию исходного текстапрограммы (разбор технологий, библиотек, архитектур,которые планируется использовать, разработкаалгоритмов, фактическое нахождение файлов стребуемыми готовыми фрагментами исходных текстов ит.д.).

3. Определение времени, необходимого наразработку программы или функции.

4. Создание файловой структуры, каталогов, файлов,необходимых для разработки.

5. По необходимости инициировать средствоконтроля версий, например git, который будет описан вразделе 6.2 этой главы.

6. По необходимости определится с использованием

Page 403: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

403

средств автоматизации.7. Определить цели использования средств

предпроцессора.8. Перейти к написанию текста программы:

- описать все функции и требуемые действия вних обычным текстом на родном языке, желательновключать в описание ключевые слова средстваавтоматизации документирования (раздел 6.5. этойкниги);

- выполняется написание текста программы, приэтом сделанное ранее описание становитсякомментариями к тексту программы.

Таким образом, сначала будут написаныкомментарии к исходному тексту программы, а ужезатем сам текст программы.

Page 404: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

404

6.2. Система контроля версий git

На протяжении нескольких десятилетийобсуждается возможность безфайлового храненияинформации. Развитием этой идеи является технология«машина времени» корпорации AppleTM и постепенныйпереход к безфайловому хранению в мобильной ОСАндроид. Несмотря на все попытки, иерархическоехранение информации сейчас является единственнымуниверсальным общеиспользуемым способом храненияинформации. Принцип иерархического храненияреализуется в первую очередь файловой системойинформационных систем.

Наиболее удачной комбинацией двух подходовиерархического способа хранения информации ибезфайлового хранения является система контроляверсий git. Принцип её работы заключается в том, чтоона хранит отличия от предыдущего зафиксированногосостояния, а не все версии всех файлов.

Хранилище в терминологии git — репозиторий. Gitрепозитории — это каталог, содержащий какпользовательский набор файлов и каталогов, так ислужебный каталог системы контроля версий с именем.git, обычно имеющим свойство «скрытый».

Система git имеет сетевую архитектуру, однако в нейне предусмотрен выделенный сервер. Все репозитории наразных ЭВМ равнозначны. При наличиисоответствующих прав любой узел может отдатьизменения или получить их с любого узла. Кроме того,при локальном применении git доступны все егофункции.

К основным операциям, применимым крепозиториям, относятся: инициализация репозитория,отправить изменения, получить изменения,

Page 405: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

405

клонирование репозитория.Для работы с системой git необходимо знать

следующие понятия.Репозиторий по-умолчанию (origin) — имя по-

умолчанию для репозитория по-умолчанию. Можетменяться пользователем.

Изменения — отличия в файловой структуре исодержимом его элементов от состояния во времяпредыдущей фиксации изменений. Понятие используетсядля определения наличия неучтенных изменений.Выделяются красным цветом при использованиикоманды получения состояния репозитория.

Учтенные изменения (index) — изменения, учеткоторых выполнен с помощью специальной команды.Наличие учтенных изменений позволяет проводитьдальнейшие изменения или зафиксировать их в виде«коммита». Выделяются зеленым цветом прииспользовании команды получения статуса репозитория.

Коммит (commit) — зафиксированные изменения.Является единицей, которыми обмениваютсярепозитории. Используется в операциях добавитьизменения, получить изменения. К ним применимыоперации объединения мердж (merge) иавтоматическое объединение автомердж (automerge).Операции объединения используются при параллельнойработе нескольких человек с одним каталогом. Следуетобратить особое внимание! Коммит — это изменение, ане состояние, и разрабатывать стратегию обменакоммитами следует именно из этих соображений.

HEAD — указатель на текущий коммит, к которомуприменимы операции с использованием указателя на«вершину» коммитов. Единственный для текущегосостояния.

Ветка — способ логического структурирования

Page 406: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

406

коммитов. Коммиты добавляются к одной из веток, дляобъединения с коммитами других веток используютсяоперации объединения и автообъединения.

сheckout — операция смены текущей ветки инекоторые другие действия.

Ветка по-умолчанию (master) — ветка по-умолчанию, всегда присутствующая в репозитории.

Заначка (stash) — отложенные изменения, которыене входят в состав коммита. Список заначек можнопросматривать. Заначки можно применять, отбрасывать.

Рассмотрим некоторые приемы работы с системойgit.

В первую очередь необходимо создать каталогпроекта, например example

mkdir example

Следующим шагом необходимо сделать созданныйкаталог проекта текущим

cd example

Далее выполняется инициализация локальногорепозитория git командой

git init

После её успешного выполнения будет выведеносообщение

Initialized empty Git repository in example/.git/

После выполнения инициализации репозиториянеобходимо задать информацию о пользователе. Эти

Page 407: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

407

команды приведены в конце этого раздела.Также возможна инициализация проекта с помощью

клонирования уже существующего репозитория,выполнив команду

git clone пользователь@имя ЭВМ с репозиторием:путь до каталога репозитория

При выполнении локального клонированиярепозитория необходимо учитывать, по умолчаниюсоздается жесткая ссылка, а не клонированиерепозитория. Создание полноценного клонированногорепозитория выполняется с помощью ключа --no-hardlinks.

Замечание! Если репозиторий содержит нескольковеток, сначала клонируется главная master. Затемвозможен просмотр всех доступных веток с помощьюкоманды

git branch -a

Команда отображает все ветки, включая скрытые.Сделать активной другую ветку можно с помощью

перехода на неё. Переход выполняется командой

git checkout <ИМЯ ВЕТКИ>

или выполнить

git pull --all

После этого можно запросить статус проекта

git status

Page 408: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

408

В случае создания нового репозитория статуспроекта будет содержать следующие сообщения

On branch master

Initial commit

nothing to commit (create/copy files and use "git add" totrack)

В каталоге проекта example появился новыйкаталог .git. Далее в каталоге проекта был создантекстовый файл 01.c, содержащий исходный текстпрограммы на языке Си, приведенный ниже.

#include <stdio.h>

int main () { return 0;}

Далее выполняется проверка состояния проекта.Перед выполнением команды необходимо убедится о том,что текущим является каталог проекта.

git status

В результате будет получена следующая информация

On branch master

Initial commit

Page 409: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

409

Untracked files: (use "git add <file>..." to include in what will be

committed)

01.c

nothing added to commit but untracked files present (use "git add" to track)

В соответствии с полученным сообщением системаgit обнаружила в каталоге проекта новый неотслеживаемый файл 01.c. Этот файл и являетсяизменением в проекте. Для того чтобы система gitучитывала изменения в этом файле, необходимовыполнить команду регистрации всех новых объектов

git add -A

После выполнения команды, файл 01.c и егосодержимое будут отслеживаться. С этого момента онотносится к учтенным изменениям. Далее повторновыполняется следующая команда

git status

Здесь и далее будет приводиться только часть выводасистемы git из-за их объема. Сообщение системы gitбудет содержать следующую строку

new file: 01.c

Строка сообщает что файл 01.c и изменения в немотслеживаются. Далее нужно создать коммит следующейкомандой

Page 410: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

410

git commit -m "First commit"

Будет создан коммит с комментарием "First commit".Для задания комментария используется ключ -m. Будетвыведено сообщение

1 file changed, 5 insertions(+)create mode 100644 01.c

Сообщение содержит информацию об изменениях впроекте. Выполняется проверка статуса проекта.

git status

Сообщение подтверждает отсутствие изменений,требующих фиксации в коммите.

On branch masternothing to commit, working tree clean

Теперь в проекте содержится два коммита. Первыйкоммит всегда создается при инициализациирепозитория, второй был создан с помощьюсоответствующей команды. Посмотреть существующиекоммиты в виде дерева к ЭТ можно с помощьюследующей команды.

git log --graph

В результате будет запущена программаотображения сообщения системы git, содержащая двакоммита. Для выхода из программы отображениянеобходимо нажать на клавиатуре клавишу q, при

Page 411: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

411

выбранной английской раскладке.

* commit 61b94c3e8530ecbbb0c9b1994e0c2060952c68eb

Author: Valerii G. Abashin <[email protected]> Date: Sun Jan 13 16:51:29 2019 +0300 First commit

Для получения подробной информации обизменениях с помощью программы с графическиминтерфейсом необходимо использовать следующуюкоманду.

gitk

или

gitk --all

После первого запуска графический интерфейс будетнепонятен, однако после выполнения всех команд,приведенных в этом разделе, неопределенность будетустранена. Второй вариант команды отображаетинформацию не только текущей, но и всех остальныхветок. Команды git status, git add -A, git commit -m"Comment" обычно выполняются друг за другом иявляются необходимым минимумом для повседневнойработы.

Следующий шаг — внесение изменений в файл 01.c.После третьей строки добавлена указанная ниже строкаи файл сохранен

puts("Hello");

Page 412: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

412

Выполнение команды git status приведет к выводусообщения, содержащего следующую строку.

modified: 01.c

Изменения в файле 01.c определены, но не учтены.Далее выполняются приведенные ранее команды

git add -Agit commit -m «Second commit»git log --graph

Будет получен следующий вывод системы git

* commit e0b23bf6d8579985dde1970ab919d0839ab6d3b9

| Author: Valerii G.Abashin <[email protected]>| Date: Sun Jan 13 17:21:56 2019 +0300| | Second commit| * commit

61b94c3e8530ecbbb0c9b1994e0c2060952c68eb Author: Valerii G. Abashin <[email protected]> Date: Sun Jan 13 16:51:29 2019 +0300 First commit

Новые коммиты необходимо создавать послевыполнения каждой небольшой задачи.

Применение системы git позволяет осуществлятьпоиск некоторого слова по шаблону. Ниже приведенпример поиска слова «puts». Пробел перед словом

Page 413: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

413

показывает что это название функции, а не частьпроизвольного слова.

git log -S ' puts'

После выполнения команды будет запущен редактортекста в ЭТ со следующим содержанием

commite0b23bf6d8579985dde1970ab919d0839ab6d3b9

Author: Valerii G. Abashin <[email protected]>Date: Sun Jan 13 17:21:56 2019 +0300

Second commit

Выход из редактора осуществляется клавишей q свключенной английской раскладкой клавиатуры. Обычнотребуется осуществить поиск только названий коммитов.Для этого необходимо дополнить команду следующимобразом.

git log -S ' puts' --oneline

В результате будет получен компактный вывод

e0b23bf Second commit

Кроме обычного поиска система git предоставляетмножество других возможностей. Например, можноопределить, когда была изменена каждая строкаисходного текста программы или конфигурационногофайла. Для этого можно использовать следующуюкоманду.

Page 414: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

414

git blame -L 3,5 01.c

В результате будет получен вывод строк файла 01.c,до которых будет указан номер коммита, его автор ивремя её написания.

^61b94c3 (Valerii G. Abashin 2019-01-13 16:51:29+0300 3) int main () {

e0b23bf6 (Valerii G. Abashin 2019-01-13 17:21:56+0300 4) puts("Hello");

^61b94c3 (Valerii G. Abashin 2019-01-13 16:51:29+0300 5) return 0;

Символ ^ указывает на коммит, который являетсяHEAD.

Рассмотрим основные команды управлениязаначками, т. е. информацией зарегистрированной git,но отложенной и неиспользованной для созданиякоммита.

Для создания заначки необходимо модифицироватьфайл 01.c. Его модификация заключается в добавлениипятой строки со следующим содержанием.

puts("Stash");

Выполненная после этого команда git statusсообщает о наличии неучтенных изменений в файле 01.c.Без отказа от этих изменений или их добавления в новыйкоммит невозможно выполнение операций с коммитами.Выходом из ситуации является использование заначек.Для начала просмотрим список заначек с помощьюкоманды

git stash list

Page 415: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

415

Их быть не должно. Далее спрячем имеющиеся изменения следующей командой.

git stash

или

git stash apply

После выполнения команды система git выведетследующую информацию

Saved working directory and index state WIP on master:e0b23bf Second commit

HEAD is now at e0b23bf Second commit

Теперь выполнение команды git stash list приведет котображению следующей информации

stash@{0}: WIP on master: e0b23bf Second commit

Была создана заначка stash@{0}. После этогодобавленная строка в файл 01.c будет удалена, но онабудет спрятана в заначку и её можно будет вернуть спомощью команд управления заначками.

Далее приведены команды добавления и удалениязаначек, которые не следует применять кэкспериментальному репозиторию!

При этом вызов команды git status приведет кполучению сообщения об отсутствии изменений. Они всебыли спрятаны в заначку. Созданную заначку можно

Page 416: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

416

использовать разными способами. Например, чтобыприменить изменения в заначке по её номеру,необходимо выполнить команду

git stash apply stash@{0}

Для удаления заначки по её номеру используется команда

git stash drop stash@{0}

Для удаления всех заначек следует выполнить команду

git stash clean

Для дальнейшей демонстрации операций срепозиторием example необходимо применитьследующую команду, которая, используя заначку синдексом 0, создаст новую ветку с именем dev01

git stash branch dev01

Будет выведена следующая информация

Switched to a new branch 'dev01'On branch dev01…modified: 01.c...

С этого момента в репозитории существует две ветки: master и dev01. Для отображения списка веток используется команда

Page 417: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

417

git branch

Получен следующий вывод

* dev01 master

Символом * отмечена текущая ветка. Выполнениекоманды git stash list не отобразит информации, т. е.заначка, использованная для создания ветки, былаудалена после использования. В файле 01.c появиласьстрока, спрятанная в заначку, а команда git statusсообщает о наличии неучтенных изменений.

В случае наличия неучтенных изменений выполнитьпереключение на другую ветку не получится, т. к. из-заэтого может случится некоторая путаница. Дляпредотвращения такой ситуации, необходимо, например,переключившись на ветку master командой

git checkout master

подтвердить переключение командой

git branch

В выводе символ * должен быть выведен напротивветки master.

dev01* master

скрытые не выкаченные веткиgit branch —all

Page 418: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

418

Далее, выполнив команду git status, будет полученосообщение о неучтенных изменениях в файле 01.c и всамом файле будет добавлена строка из заначки. Этопроисходит потому, что переключаясь на другую ветку,выполняется перемещение по указателям коммитов.Другим изменениям репозиторий не подвергается. Воизбежания недоразумений, лучше вернуться на веткуdev01, командой

git checkout dev01

Отсутствие контроля над текущей веткой являетсяодной из главных причин проблем с репозиториями уначинающих пользователей системы git.

Далее необходимо создать третий коммит врепозитории и первый в ветке dev01 с помощью команд

git add -Agit commit -m "dev01 first commit"

После этого необходимо запустить графическоеприложение для работы с коммитами командой gitk.Отображаемая информация будет полностьюсоответствовать выполненным действиям.

Для создания новой ветки обычно используется незаначка, а коммит.

git branch <ИМЯ ВЕТКИ> <ИДЕНТИФИКАТОР КОММИТА>

Коммиты — это единицы, которыми могутобмениваться репозитории. К основным операциям пообмену коммитами относятся команды:

Page 419: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

419

- git fetch — получить коммиты удаленного репозитория;

- git push — отправить коммит в удаленный репозиторий;

- git pull — комбинация команд получения и объединения коммитов.

Примеры использования приведенных команд длярепозитория с названием по-умолчанию:

git push origin mastergit pull origin master

В случае, если выполнение команды pull ивключенной в неё команды автообъединения (automerge)завершилось ошибкой, будет выведено соответствующеесообщение. Сообщение содержит название команды,исправляющей полученные несоответствия. Такжеможно использовать команду

git mergetool

Система git имеет возможности тонкой настройки,которые сложны в освоении и используемые в основномруководителями проектов. Также присутствует рядфункций, освоение которых требует объемного описания,но они не относятся к возможностям первойнеобходимости. К ним можно отнести функциюперестроения базы коммитов git rebase или функциюполучения произвольного коммита get chyrry-pick, gitfast-forward, git reflog. Функция git rebase дописывает вкачестве продолжения все коммиты одной ветки надругую ветку. Частный случай объединения веток git fast-forward, который применим только в случае отсутствия«наложения» изменений. Функция git reflog показывает

Page 420: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

420

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

Для просмотра изменений по отношению кпоследнему коммиту используется команда

git diff filename

Способ сброса всех изменений до последнего коммита

git reset --hard HEAD

Для переключения на другой коммит с цельюпродолжения работы с него, обычно делают новую ветку

git checkout -b <НОВАЯ ВЕТКА> <ИДЕНТИФИКАТОР КОММИТА>

Опасный способ сброса изменений до последнегокоммита, потенциально способный вызвать нарушениеправильной работы коммитов

git reset --hard <ИДЕНТИФИКАТОР КОММИТА>

Команда отмены опубликованных коммитов, создаваяна каждую отмену новый коммит

git revert <ИДЕНТИФИКАТОР КОММИТА1> <ИДЕНТИФИКАТОР КОММИТА2>

Добавление последних изменений к последнему локальному коммиту

Page 421: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

421

git commit --amend

Для удаления локальной ветки используется команда

git branch -D <НАЗВАНИЕ ВЕТКИ>

Для удаления удаленной ветки

git push origin --delete <ИМЯ ВЕТКИ>

Сразу после инициализации репозитория необходимозадать некоторую глобальную конфигурационнуюинформацию.

Имя пользователя имеет особую важность длярепозитория. Выполняя создание коммитов,пользователь как бы подписывает каждую измененнуюстроку. Git позволяет отображать автора изменений длякаждой строки, что значительно упрощает совместнуюработу.

Для задания имени пользователя используетсяследующая команда

git config --global user.name "John Smit"

Также необходимо задавать адрес почтового ящикаэлектронной почты, что значительно упрощаеткоммуникации во время совместной разработки

git config --global user.email "[email protected]"

Для смены основных инструментов работы сисходными текстами программ используются команды

Page 422: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

422

git config --global core.editor vimgit config --global merge.tool meld

Первая строка задает программу редактор файлов,вторая — средство для объединения разных версийфайлов.

Для просмотра глобальных настроек используется команда

git config --list

В завершении раздела приведен список команд,необходимых для отправки файла в удаленныйрепозиторий, расположенный на популярном Интернетресурсе http://githab.com.

git initgit add <ИМЯ ФАЙЛА>git commit -m "first commit"git remote add origin

https://github.com/<РЕПОЗИТОРИЙ>/<ПРОЕКТ>git push -u origin master

Page 423: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

423

6.3. Этапы создания исполняемого файла. Типыисполняемых файлов

Исполняемый файл или файл программы — это файлс двоичной информацией в формате ELF. В каждой ОСпринят свой формат исполняемого файла. Причемформат исполняемого файла зависит от архитектурымикропроцессора, поэтому в разных версиях одной ОСможет отсутствовать переносимость исполняемыхфайлов.

Компилятор gcc может создавать как минимум 4различных вариантов исполняемых файлов,используемых для разных целей:

- исполняемый файл по умолчанию (используется впроцессе написания текста программы);

- исполняемый файл с отладочной информацией(используется для исправления логических ошибок впрограмме);

- исполняемый файл с информацией опроизводительности каждой функции программы(используется для оптимизации программы на уровнеисходного текста программы);

- оптимизированный файл для внедрения иэксплуатации, с разной степенью оптимизации.

В приведенной последовательности они обычно исоздаются.

В разделе 3.1 показан процесс созданияисполняемого файла по классической схеме. Именнотаким образом создается исполняемый файлкомпилятором gcc.

Рассмотрим создание исполняемого файла напримере файла main.c с исходным текстом программы.

Содержимое файла main.c

Page 424: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

424

#include <stdio.h>#define VALUE 3

int main () { printf("%d\n", VALUE); return 0;}

Для выполнения первого этапа — обработкипредпроцессором, выполняется команда

gcc -E main.c > main_E.c

В результате первая строка файла будет замененасодержимым файла stdio.h. Также будет заменаконстанты VALUE на значение, указанное в директиве#define. В связи с тем, что результирующий файлсодержит 856 строк, приведены только последние 7,включая пустые строки.

# 4 "main.c"int main () { printf("%d\n", 3); return 0;}

Следующим этапом выполняется компиляцияполученного исходного текста программы без директивпредпроцессора.

gcc -c main_E.c

Page 425: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

425

В результате компиляции получен объектный файлmain_E.o, в формате, определяемом конкретной версиейкомпилятора.

Для получения исполняемого файла необходимовызвать компилятор без ключей, указав ему входнымфайлом объектный файл.

gcc -o main_E.o -o main_E

В результате будет получен исполняемый файл,запускаемый из каталога, в котором он расположенкомандой

./main_E

В приведенных ранее примерах указывалось, прииспользовании математических функций во времякомпиляции необходимо указывать ключ -lm. Дляуказания этой библиотеки достаточно добавить этотключ к указанной ранее строке.

gcc -o main_E.o -lm -o main_E

Без указания специального ключа программасобирается в режиме динамической сборки. В этомслучае для запуска программы необходимо, чтобы файлывсех библиотек, используемых программой, были вналичии. При этом размер исполняемого файламинимален.

Выполнение статической сборки, когда всенеобходимые библиотеки добавляются в исполняемыйфайл, производится при использовании ключа -static.

gcc -o main_E.o -static -lm -o main_E

Page 426: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

426

В этом случае, размер файла с программой можетувеличится на два и более порядка.

Для просмотра всех настроек создания исполняемогофайла и всех использованных для этого команднеобходимо применить ключ -v.

gcc -v main.c

В полном выводе отображается вызов трех программ:../configure, cc1 и collect2 с ключами и параметрами.

С целью вывода использованных при созданиипрограммы заголовочных файлов используется команда

gcc main.c --trace

Переданный аргумент trace будет переданкомпоновщику ld. В результате будет получен вывод,содержащий фактический набор использованныхзаголовочных файлов

. /usr/include/stdio.h

.. /usr/include/features.h

... /usr/include/sys/cdefs.h

.... /usr/include/bits/wordsize.h

... /usr/include/gnu/stubs.h

.... /usr/include/gnu/stubs-64.h

.. /usr/lib64/gcc/x86_64-alt-linux/5/include/stddef.h

.. /usr/include/bits/types.h

... /usr/include/bits/wordsize.h

... /usr/include/bits/typesizes.h

.. /usr/include/libio.h

... /usr/include/_G_config.h

.... /usr/lib64/gcc/x86_64-alt-linux/5/include/stddef.h

Page 427: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

427

.... /usr/include/wchar.h

... /usr/lib64/gcc/x86_64-alt-linux/5/include/stdarg.h

.. /usr/include/bits/stdio_lim.h

.. /usr/include/bits/sys_errlist.h

. /usr/include/assert.hНесколько защит подключения может быть

полезно для:/usr/include/assert.h/usr/include/bits/stdio_lim.h/usr/include/bits/sys_errlist.h/usr/include/bits/typesizes.h/usr/include/gnu/stubs-64.h/usr/include/gnu/stubs.h/usr/include/wchar.h

Для создания программы, соответствующей текущейверсии стандарта языка программирования,используется ключ -std=c17. Без указания этого ключасинтаксические конструкции, утвержденные новымстандартом, будут помечены как ошибочные. Присоздании программ настоятельно рекомендуетсяизбегать предупреждений от компилятора. Для этого ихприравнивают к ошибкам с помощью ключей наиболеестрогой проверки синтаксиса исходного текстапрограммы (например, ключи -Wall и -pedantic). Крометого, необходимо выполнять автоматическуюоптимизацию исходных текстов программы сиспользованием ключей -O0, -O1, -O2, -O3.

Ключ -O3 использует наибольшее количество правилоптимизации исходных текстов, ключ -O0 соответствуетотключению оптимизации. Следует иметь в виду, уровеньоптимизации лучше повышать постепенно, проводяполнофункциональное тестирование всех функций.Неправильно выполненная оптимизация может изменить

Page 428: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

428

логику работы программы или привести к ошибкамисполнения.

В результате команда создания исполняемого файлас максимальной оптимизацией из исходных текстов,соответствующих последнему стандарту языкапрограммирования, должна выглядеть так:

gcc -Wall -pedantic -O3 -std=c17 main.c -o main

Исполняемый файл содержит только команды иконстантные значения. Для поиска ошибок в исходномтексте программы используется режим отладки. Этотрежим отличается отсутствием оптимизации. В этомрежиме исходный текст программы добавляетсянепосредственно в исполняемый файл, позволяя такимобразом осуществить привязку двоичных команд кстрокам исходного текста программы. Это еще однапричина, по которой каждое выражение исходноготекста нужно писать в новой строке. Для включенияотладочной информации используется ключ -g.

gcc -g main.c -o main

Файл с отладочной информацией имеет большийразмер. Он может быть запущен как отдельнаяпрограмма, которая выведет дополнительнуюинформацию в случае её разрушения в процессеисполнения. Обычно, программы с отладочнойинформацией запускают с помощью программотладчиков, например gdb. Основы работы с ней будутприведены в разделе 6.6 этой книги.

После исправления ошибок с использованиемотладочной информации, выполняется проверкапроизводительности разработанной программы. Сам

Page 429: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

429

процесс называется профилированием программы. Дляэтого в исполняемый файл добавляются вызовыпрограммы time, с помощью которой засекается времяисполнения каждой функции.

Используя ЭТ и программу time, можно засечь времявыполнения всей программы с помощью команды

time ./main

В результате будет выведено время, затраченное наисполнение программы, включая разбиение на времяисполнения в режиме пользователя и режиме ядра ОС.

Профилирование программы выполняется в несколько этапов.

1. Создание исполняемого файла с информацией дляпрофилирования с помощью команды

gcc -pg main.c -O3 -Wall -pedantic -std=c17 -o main

2. Исполнение программы, в процессе которогозамеряется время исполнения функций и сохраняется вфайл gmon.out

./main

3. выполняется преобразование в текстовый видрезультатов, сохраненных в файле gmon.out с помощьюпрограммы gprof, используя команду

gprof ./01 > 1.txt

В приведенном примере результат преобразованиясохраняется в текстовый файл 1.txt.

Page 430: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

430

Flat profile:

Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 72.07 0.05 0.05 1 50.45 50.45 calculate 28.83 0.07 0.02 1 20.18 20.18 calculate_sin 0.00 0.07 0.00 100000 0.00 0.00 my_sin

Далее идут пояснения

% the percentage of the total running time of thetime program used by this function.

cumulative a running sum of the number of seconds accounted seconds for by this function and those listed above it.

self the number of seconds accounted for by thisseconds function alone. This is the major sort for this listing.

calls the number of times this function was invoked, if this function is profiled, else blank.

self the average number of milliseconds spent in thisms/call function per call, if this function is profiled,

else blank.

total the average number of milliseconds spent in thisms/call function and its descendents per call, if this

function is profiled, else blank.

name the name of the function. This is the minor sort for this listing. The index shows the location of

the function in the gprof listing. If the index is in parenthesis it shows where it would appear in the gprof listing if it were to be printed.

Затем граф вызовов

Call graph (explanation follows)

granularity: each sample hit covers 2 byte(s) for 14.16% of 0.07 seconds

Page 431: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

431

index % time self children called name <spontaneous>[1] 100.0 0.00 0.07 main [1] 0.05 0.00 1/1 calculate [2] 0.02 0.00 1/1 calculate_sin [3]----------------------------------------------- 0.05 0.00 1/1 main [1][2] 71.4 0.05 0.00 1 calculate [2]----------------------------------------------- 0.02 0.00 1/1 main [1][3] 28.6 0.02 0.00 1 calculate_sin [3] 0.00 0.00 100000/100000 my_sin [4]----------------------------------------------- 0.00 0.00 100000/100000 calculate_sin [3][4] 0.0 0.00 0.00 100000 my_sin [4]-----------------------------------------------

Повторный вызов привел к следующим результатам

Flat profile:

Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 67.27 0.02 0.02 1 20.18 20.18 calculate 33.63 0.03 0.01 1 10.09 10.09 calculate_sin 0.00 0.03 0.00 100000 0.00 0.00 my_sin

Все действия, необходимые для получениярезультатов профилирования, можно выполнить спомощью одной команды

gcc -pg main.c -O3 -Wall -pedantic -std=c17 -o main &&./main && gprof ./main > 1.txt

Во время профилирования следует выполнитьпрограммы многократно для получения среднихзначений, т. к. продолжительность работы функцииможет отличаться на порядок, особенно если функцияисполняется быстро.

Кроме компилятора gcc существует множество

Page 432: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

432

других компиляторов. На слабопроиводительныхплатформах также используются специальныекомпиляторы.

Для разработки программ с ядром ОС Линукс такжеможет эффективно использоваться компилятор Clang. Онподдерживает почти все ключи, применяемые в gcc.Кроме того, он распространяется под лицензией,отличной от лицензии gcc, и позволяет создаватьпрограммы с закрытыми исходными текстами программыдля коммерческих целей.

Для использования компилятора Clang в командахнеобходимо заменить только название компилятораследующим образом

clang -Wall -pedantic -O3 -std=c17 main.c -o main

Для проверки качества, надежности ипереносимости разработанных исходных текстовпрограммы их можно собирать разными компиляторамии проверять возможность сборки программы из исходныхтекстов и её работоспособность.

Page 433: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

433

6.4. Автоматизация проверки исходных текстови создания исполняемых файлов

Компилятор выполняет проверку только синтаксисаисходных текстов программы, практически не проверяялогические и прочие ошибки. Для поиска более сложныхошибок используются специальные автоматизированныесредства проверки исходных текстов. Их принципиальноеотличие в том, что компилятор для программиста друг,пытающийся понять как надо, а системы статическогоанализа исходных текстов программы действуют каквраг, который указывает на все возможные ипотенциальные ошибки. Для языка Си наиболеепопулярным средством исправления ошибок являетсяпрограмма cppcheck. Рассмотрим её применение сиспользованием следующего исходного текстапрограммы (Рисунок 1).

Рисунок 1 — Исходный текст для обработки cppcheck

Из исходного текста, представленного на рисунке 1,создается исполняемый файл без единого замечаниядаже в режиме максимально строгой проверки исходноготекста.

gcc -pedantic -Wall -std=c17 01.c -o 01

Page 434: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

434

Исполнение программы привело к выводу значения1095517952. Ошибка заключается в том, что в строке 4объявляется массив из 100 элементов, каждый изкоторых инициируется значением 9, однако в строке 5производится обращение у несуществующему 1000-муэлементу.

Вывод: ошибка в тексте программы не была выявленани на этапе создания программы, ни на этапе еёисполнения.

Для выполнения проверки исходных текстовпрограммы в текущем каталоге используется следующаякоманда

cppcheck --std=c11 .

На текущий момент актуальной являлась версия1.82, поддерживающая только язык программированияСи стандарта 2011 года, что все равно позволяетприменять эту утилиту для исходных текстов,соответствующих стандарту 2017 года. В результате былополучено следующее сообщение

Checking 01.c ...[01.c:5]: (error) Array 'array[100]' accessed at index

1000, which is out of bounds.

Программа cppcheck правильно определила ошибку иместо её нахождения. Не стоит ожидать, что программатакже точно сможет определить все сложные ошибки,однако поможет исправить ряд досадных недоразумений,исправление которых потребует значительного времени.

Программа проверки имеет множествовозможностей. В первую очередь следует ознакомиться с

Page 435: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

435

возможностями:- указывать целевую платформу, например –

platform=win32A;- запускать в многопоточном режиме, например, -j4

запускает в четыре потока;- отображать большее количество информации, ключ

-v;- отображать ошибки в формате, совместимом с

компилятором gcc, задается ключом --template=gcc.Программа cppcheck может дополняться функциями

и библиотеками, но в её дистрибутиве присутствуетнебольшая поддержка всего нескольких библиотек.

Важнейшим элементом любой современнойинтегрированной среды быстрой разработки программявляется средство автоматизации компиляции программ.Для языка Си обычно это make, обрабатывающаяконфигурационный скриптовый файл Makefile. ФайлMakefile состоит из двух основных частей, списка правили списка действий, например, собрать программу,установить программу, удалить программу;

Список правил позволяет собрать одну программуили несколько независимых программ. Каждое правилопишется как бы наоборот. Сначала указывается правилосборки конечного файла программы, а дальшедетализируются команды сборки каждого из элементов,необходимого для сборки программы.

Синтаксис файла Makefile является достаточнострогим и не допускает замену символов —разделителей, их количества и прочих вольностей. Вначале правила указывается имя результирующегофайла, называемое «цель». Затем ставится двоеточие.Далее через пробел указываются «зависимости», т. е.полный список файлов, необходимых для сборки цели.Обычно зависимости также создаются в процессе

Page 436: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

436

исполнения Makefile, поэтому для создания файла,входящего в зависимости, используются команды. Водной строке должна быть строго одна команда, котораядолжна быть отделена от начала строки одним символомгоризонтальной табуляции. При этом правила Makefileмогут содержать переменные, конструкции ветвления ициклы.

Для демонстрации применения утилиты makeиспользуем исходный текст программы из пункта 3.7этой книги, который отображен на рисунке 3 (файл03_1.c), рисунке 4 (файл 03_2.h) и рисунке 5 (файл03_2.c). В том же каталоге создан Makefile следующегосодержания:

test_make: 03_1.o 03_2.ogcc 03_2.o 03_1.o -o test_make

03_1.o: 03_1.cgcc -pedantic -Wall --std=c17 -c 03_1.c

03_2.o: 03_2.h 03_2.cgcc -pedantic -Wall --std=c17 -c 03_2.c

clear:rm -f test_make 03_1.o 03_2.o

install:cp test_make ../

uninstall:rm -f ../test_make

Одним из наиболее очевидных удобств,предоставляемых Makefile, кроме отсутствиянеобходимости каждый раз писать длинные команды,является возможность многопоточного запускакомпиляции.

В Makefile используется две цели. Для ихпараллельной сборки на двух разных ядрах необходимо

Page 437: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

437

выполнить следующую команду

make -j2

При наличии множества целей, можно указыватьколичество потоков, равное количеству аппаратных ядерцентрального процессора. Причем, если микропроцессоримеет 4 аппаратных ядра, в каждом из которых можетэмулироваться по два потока, всего 8, наибольшаяпроизводительность будет достигнута при указанииколичества потоков, равное количеству аппаратных ядер,т. е. 4.

Для установки программы необходимо выполнитькоманду

make install

В приводимом примере установка заключается вкопировании исполняемого файла на каталог выше.

Для удаления вспомогательных файлов, создаваемыхв процессе сборки программы, необходимо выполнитькоманду

make clear

В данном примере будут удалены не только файлыбиблиотек, но и исполняемый файл программы. Утилитаmake не регламентирует жестко названия команд.Общепринятой практикой является использованиесочетания make clear, однако в примере последняя буквазаменена на n, что никак не сказалось на исполнениипрограммы.

Удаление файла программы и всех прочих элементовпрограммы выполняется командой

Page 438: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

438

make uninstall

В примере этой командой удаляется файл,находящийся на уровень выше в месте установки.

Использование программы make позволяет упроститьряд операций по созданию программы, однако необеспечивает легкую переносимость между ОС разныхклассов. Для решения этой проблемы используется пакетGNU Autotools. Обобщенный алгоритм использованияэтого средства автоматизации заключается в запускепрограмм autoscan, autoconf с дальнейшим заданиемконфигурационной информации в автоматическисгенерированных файлах configure.ac и Makefile.am. Длясоздания Makefile используется команда ./configure.

Далее рассматривается порядок действий дляавтоматического получения Makefile. Перед началомвыполнения последовательности действий необходимоподготовить каталог с подкаталогом src. В каталоге srcдолжны размещаться файлы с исходным текстомпрограмм. Представим вывод команды tree корневогокаталога проекта с правильно подготовленнымикаталогом и файлами

.|--src| |--03_1.c| |--03_2.h| |--03_2.c|--configure.ac|--Makefile.am

Команда tree в дистрибутиве АльтЛинукс неустанавливается при установке ОС. Её необходимо

Page 439: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

439

устанавливать дополнительно из репозитория.1. Изменить содержимое файла configure.ac на

AC_INIT(src/03_1.c)AM_INIT_AUTOMAKE(test_make,0.1)AC_PROG_CCAC_PROG_CXXAC_PROG_INSTALLAC_OUTPUT(Makefile)

Заготовку файла можно получить, выполнив командуautoscan, в корневом каталоге проекта. В результатебудет получен файл configure.scan. Онпереименовывается в configure.ac, но его содержимоебудет отлично от предлагаемого.

2. Изменить содержимое файла Makefile.am на

bin_PROGRAMS=test_maketest_make_SOURCES=src/03_2.h src/03_2.c src/03_1.c

Пояснения к командам, добавленным в измененныефайлы, доступны в сети интернет. Их освоение несоставит труда.

3. Выполнить следующие команды

aclocalautoconftouch README AUTHORS NEWS ChangeLogautomake -a./configuremake

Программа aclocal выполняет подготовительную

Page 440: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

440

работу, необходимую для генерации скрипта configure иMakefile. Программа autoconf формирует скриптconfigure. Программа touch создает файлы с именами,соответствующими переданным в неё параметрам.Программа automake генерирует файл Makefile.in, наоснове которого формируется Makefile. Скрипт configureрасполагается в корневом каталоге проекта. Еговыполнение приводит к генерации Makefile. ИспользуяMakefile, утилита make генерирует файл программы.

При подготовке пакета для распространения вместопоследнего вызова make необходимо выполнить

make dist

В результате будет собран архив test_make-0.1.tar.gz.Для установки пакета, собранного командой make dist,необходимо выполнить следующие действия

tar -xvvf test_make-0.1.tar.gzcd test_make-0.1./configuremakemake installmake cleantest_make

Для удаления установленной программыиспользуется команда

make uninstall

В случае, если проект состоит из пары десяткомфайлов, более простым выглядит создание Makefile втекстовом редакторе с целью экономии времени на

Page 441: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

441

сборку проекта. Для работы с крупнымикроссплатформенными проектами предпочтительнееиспользовать возможности, предоставляемые средствомGNU Autotools.

Page 442: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

442

6.5 Автоматическая генерация документации

Документирование исходных текстов программытребует значительных затрат времени и может приводитк задержке сдачи проекта. Основным средствомавтоматизации процесса создания документацииявляется программа doxygen.

В соответствии с жизненным циклом программ иэтапов их разработки, написание комментариевпроисходит до написания текста программы. Дляэффективного использования doxygen достаточноначинать каждый файл с исходным текстом программы скомментарием в формате doxygen, также необходимокомментировать составные типы данных и функции.

Приведем пример с использованием файлов сисходным текстом программы из пункта 3.7 этой книги,который отображен на рисунке 3 (файл 03_1.c), рисунке 4(файл 03_2.h) и рисунке 5 (файл 03_2.c).

В начало каждого файла добавлен блок комментарияпо примеру следующего фрагмента

/*!\file\brief Файл содержит точку входа в программу

Данный файл содержит в себе точку входа в программу

*/

Перед каждой функцией добавлен фрагмент по следующему шаблону

/** * \brief Точка входа

Page 443: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

443

* * Исполнение программы * начинается здесь. * * \param argc Количество аргументов * \param argv Список аргументов * * \return Статус завершения программы */

Использованными ключевыми словами являютсяследующие сочетания символов:

\file – добавляется в начале каждого файла\brief – краткое описание файла/блока/функции\param – параметр, передаваемый в функцию\return – возвращаемое значениеПосле блока \brief с отступом одна пустая строка

выполняется более подробное описание элемента.

Программа doxygen использует множество другихключевых слов, наиболее часто используемыми изкоторых являются следующие:

\authors – указание авторов\version – содержит версию фрагмента текста

программы\date – позволяет указывать дату создания текста

программы\bug – используется для перечисления известных

ошибок\warning – предупреждения для программистов\copyright – лицензионные ограничения,

действующая лицензия

Page 444: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

444

\example – содержит ссылку на примериспользования

\todo – содержит список запланированных работ

Для описания выражения после него используетсяконструкция

double value; ///< Краткое описание

Для описания составных типов можетиспользоваться следующая конструкция

/// Состояния объектаenum States {

Undefined ///< Элемент в неопределенномсостоянии

Enabled, ///< Элемент активированDisabled, ///< Элемент отключен

}

или

/// Элементstruct Items {

int on; ///< Элемент активен или нетdouble value; ///< Значение элемента

} item;

После оформления комментариев указанным ранееобразом, выполняется команда создания проекта doxygen

doxygen -g

В результате создается файл проекта с именем по

Page 445: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

445

умолчанию Doxygen. Для создания файлов с описаниемпроекта выполняется вызов программы без аргументов.

doxygen

В результате будут созданы каталоги html и latex.Для просмотра созданной документации, необходимоначать просмотр файла index.html из каталога html. Нарисунке 1 приведен пример автоматическисгенерированного описания функции main().

Рисунок 1 — Пример описания функции main

Программа doxygen имеет множество настроек,которые можно изменять как с помощью текстовогоредактора, так и используя графический интерфейс. Длязапуска графического интерфейса конфигуратораприменяется команда doxygenwizard .

Page 446: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

446

6.6. Приемы отладки программ

Рассмотрение приемов поиска ошибок в исходныхтекстах программ (отладки программы) будетпроизведено на примере исходного текста,представленного на рисунке 1.

Рисунок 1 – Исходный текст программы с ошибкой

В приведенном исходном тексте реализовано двефункции max_value() и main(). В функции max_value() встроках 4 и 6 использованы функции вывода fprintf(),первым аргументом которых указан стандартный потокошибок stderr. Соответственно весь их вывод будетпомещен в стандартный поток ошибок.

Page 447: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

447

В функции main() в строках 13 и 15 вызываетсяфункция perror(), объявленная в файле stdio.h. Функцияperror() выводит текстовый аргумент и затем текстовоеописание числового кода последней ошибки встандартный поток ошибок.

Пояснение для остальных строк будут даны по мередемонстрации способов и технологий поиска ошибок.

В случае сборки исполняемого файла и его запуска командой

gcc 01.c && a.out

будет получен вывод

Вызов функции: SuccessОшибка сегментирования

В соответствии с выводом, после запуска программыеё сегментация была разрушена и она уничтожена. Имеяпонимание синтаксиса языка Си, можно достаточнолегко найти ошибку, однако это будет сделано сиспользованием разных приемом в технологии в разделах6.6.1, 6.6.2 и 6.6.3.

Page 448: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

448

6.6.1 Отладка без специальных программ

Выполнять поиск ошибок в режиме исполненияпрограммы допустимо без специальных средств,упрощающих эту работу. В этом пункте речь идет обошибках режима исполнения, процесс исправлениякоторых часто называется отладкой. Наиболее сложнымспособом поиска и исправления ошибок пользоваласьАда Левис, первый программист на Земле. Всю работу попоиску и исправлению ошибок ей приходилосьпроизводить в уме. Некоторые разработчики наивысшейквалификации умеют находить ошибки исключительнопутем чтения исходных текстов программы. Такой подходсвойственен более старшим разработчикам, некоторыеиз которых застали время, когда написание исходныхтекстов программ велось с помощью карандаша и листабумаги. Набор текста программы производился толькопосле его написания на бумаге.

Необходимость в навыке поиска ошибок режима ис-полнения программы без специальных программ возни-кает в случае отсутствия средств отладки для некотороймалораспространенной или новой платформы.

Основными задачами поиска ошибок в программеявляются поиск места, в котором произошла ошибка, изначения, приведшего к ошибке. Используя средства ОСи средства языка программирования, применяютсяследующие приемы для поиска места ошибки изначения, которое привело к ошибке:

1) стандартные функции вывода, например puts(),printf();

2) специальные версии операторов вывода, напримерperror();

3) перенаправление стандартного потока ошибок вфайл (пункт 5.7 данной книги, рисунок, строка 13);

Page 449: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

449

4) подключаемую библиотеку assert.5) директивы предпроцессора.Первый и второй способы продемонстрированы в

исходном тексте в пункте 6.6. В этом же пункте показанвывод, производимый программой при её запуске.Первая строка вывода содержит сообщение

Вызов функции: Success

Вывод сгенерирован строкой 13 файла 01.c. Втораястрока сообщает о разрушении программы в ОЗУ. Выводв строке 15 сообщения "Вызов прошел успешно" невыполнен, из этого делается вывод, что строка 14 небыла выполнена.

В строке 14 производится вызов функции max_value().Функция начинается с вызова оператора вывода в строке4, который выводит сообщение в стандартный потокошибок. Делается вывод, функция не началавыполняться.

Определено, что ошибка произошла на строке вызовафункции, причем сама функция выполняться не начала.Значит ошибка заключается в неправильном заданииаргументов функции, что и приводит к разрушениюпрограммы.

Функция max_value() принимает два аргументацелочисленного типа int, причем к первому аргументуприменяется унарная операция разыменования,обозначаемая символом "*". В строке 11 выполняетсяобъявление переменной first как указателя нацелочисленное значение, однако переменная неинициализируется и может иметь «мусорное» значение.При выполнении проверки аргументов во время вызовафункции max_value() происходит разрушение памятипрограммы.

Page 450: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

450

Ошибка найдена. Она в строке 11. Чтобы еёисправить, необходимо заменить строку

int * first;

например, на

int a = 2;int * first = &a;

Приведенный метод отладки с использованием опе-раторов вывода является самым трудоемким и требуетповышенной внимательности. Рекомендуется применятьего только в крайних случаях.

Для проверки правильности внесенных исправленийнеобходимо выполнить пересборку программы, запустивеё заново командой

gcc 01.c && a.out

будут выведены следующие сообщения

Вызов функции: SuccessФункция запускаетсяФункция выполненаВызов прошел успешно: SuccessМаксимальное значение: 3

Следует обратить внимание на то, что сообщения,выводимые в стандартный поток ошибок, такжевыведены в стандартный поток вывода. Следуетотметить, сообщения выведены в порядке исполнениястрок по исходному тексту программы, поэтому ещеодной причиной использования такого приема является

Page 451: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

451

необходимость проверки порядка исполнения строктекста программы в разных функциях или модулях.

В случаях, когда отладочный вывод достигает сотен итысяч строк, рекомендуется перенаправлять потокошибок в файл. Если ошибки появляются не более раза внесколько секунд, возможно использование приема,продемонстрированного в конце пункта 5.7 этой книги стем отличием, что перенаправление производится настандартный поток ошибок с кодом 2.

Для демонстрации работы перенаправлениянеобходимо в одном ЭТ выполнить команду tty иполучить примерно такой вывод

/dev/pts/0

В другом терминале запустить программуобязательно с исправленной, как указано ранее, ошибкойс помощью команды

./a.out 2>/dev/pts/0

В результате в ЭТ, в котором произведен вызовпрограммы, будет выведена всего одна строка

Максимальное значение: 3

В терминале /dev/pts/0 будут выведены следующиесообщения

Вызов функции: SuccessФункция запускаетсяФункция выполненаВызов прошел успешно: Invalid argument

Page 452: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

452

Прием с двумя ЭТ позволяет очистить стандартныйпоток вывода от отладочных сообщений, позволяетсосредоточиться на выводе приложения или поискеошибки с помощью отладочных сообщений.

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

Для демонстрации четвертого способа поискаошибок используем следующий исходный текстпрограммы

#include <stdio.h>#include <assert.h>

int main (void) { FILE *fd; fd = fopen ("/home/user/file.txt", "r"); assert (fd); fclose (fd); return 0;}

При запуске программы, полученной из этогоисходного текста, будут выведены следующие сообщения

a.out: 02.c:7: main: Assertion `fd' failed.Аварийный останов

Механизм работы библиотеки assert описан вразделе 7.2 стандарта языка программирования Си. При

Page 453: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

453

использовании этой библиотеки по-умолчанию,компилятор включает её и все макросы assert() в текстепрограммы. Для их отключения необходимо использоватьследующие ключи компилятора -D NDEBUG. В этомслучае команда сборки программы будет выглядетьследующим образом

gcc 02.c -D NDEBUG

После запуска программы собранной сотключенными макросами assert(), будет получено односообщение

Ошибка сегментирования

Программа разрушилась в процессе выполнения.Такое поведение связано с отсутствием открываемогофайла /home/user/file.txt с правами на чтение. В этомслучае функция fopen() не создала структуру типа FILE ипри вызове функции fclose() в ней в качестве аргументабыл передан указатель на структуру FILE, под которуюне было выделено памяти в ОЗУ, что и привело кразрушению программы.

Наиболее гибким инструментом для поиска ошибокявляется комбинация директив предпроцессора иоператоров вывода. Такой прием позволяетпроизвольным образом изменять функциональностьпрограммы в отладочном режиме, загружать или незагружать любые библиотеки, выполнять произвольнуюработу с любыми ресурсами. Главный недостаток этогоподхода — в необходимости выполнять проектирование иразработку программы для двух режимов работы(отладочный и режим эксплуатации).

Page 454: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

454

Рисунок 1 — Исходный текст программы сдирективами предпроцессора, используемыми дляотладки программы

Переключение в режим отладки возможен двумяспособами:

- использование директивы предпроцессора суказанием выбранного ключевого слова;

- использование ключа -D при запуске программы.На рисунке 1 представлен пример исходного текста

программы из вступления к пункту 6.6. В текстеисправлена ошибка и он дополнен директивамипредпроцессора, позволяющими продемонстрироватьпереключение в отладочный режим и обратно.

Далее описаны отличия исходного текста программыфайла 03.c от исходного текста, описанного в пункте 6.6.

Page 455: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

455

В строке 3 директива предпроцессоразакомментирована. Удаление символов комментированияприведет к объявлению значения DEBUG, используемогопредпроцессором. Объявление значения с такимидентификатором приведет к включению вкомпилируемый текст программы участков исходноготекста, находящихся между директивами

#ifdef DEBUG

и ближайшим

#endif

В случае, если строка 3 закомментирована, текстмежду этими директивами включен не будет.

Второй способ переключения в режим отладкизаключается в вызове сборки программы следующимобразом:

gcc 03.c -D DEBUG

или так

gcc 03.c -D DEBUG=1

Значение константы DEBUG не имеет значения.Запуск полученной программы выполняется следующимобразом

./a.out

Если программа собрана любым из описанныхспособов без отладочной информации, после её запуска

Page 456: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

456

будет выведено одно сообщение

Максимальное значение: 3

Добавление отладочной информации любымспособом приведет к выводу отладочной информации,путем срабатывания функций в строках 7 и 11 на рисунке1.

Функция запускаетсяФункция выполненаМаксимальное значение: 3

Навык поиска ошибок режима исполнения безспециальных программ будет всегда востребован напереднем крае технологической гонки. В таких областяхвсегда сначала появляются новые информационныетехнологии, а полноценное информационное итехнологическое обеспечение к ним становитсядоступным не ранее чем через несколько лет успешныхвнедрений. К тому времени, когда полноценные средстваотладки добираются в новую область, разработка с ихпомощью обесценивается также, как и стоимость работ,проводимых с их помощью, а значит и доходовразработчиков.

Page 457: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

457

6.6.2. Отладка с использованием gdb

Наиболее популярным отладчиком в ОС Линуксявляется gdb. Для его полноценного изучения работе сним необходимо посвятить целую книгу, поэтому в этомразделе будут даны наиболее часто используемыекоманды, приведен простой пример использования gdb иописана программа с графическим интерфейсом nemiver,позволяющим выполнять отладку, постоянно держаперед глазами значения регистров, ячеек ОЗУ и прочуюинформацию.

Отладчик gdb упрощает и ускоряет поиск ошибок,допущенных программистом и пропущенныхкомпилятором и компоновщиком. Он позволяетконтролировать выполнение другой программы,выполнять её построчно, в процессе выполненияпросматривать и изменять произвольные значения в ОЗУ,перемещаться по стеку. Для работы с ним чаще другихиспользуются следующие команды:

file <ИМЯ ФАЙЛА> - загрузка в отладчик файлапрограммы;

gdb <ИМЯ ФАЙЛА> - запуск отладчика из ЭТ содновременной загрузкой исполняемого файла дляотладки;

run или r – запуск исполняемого файла;kill – завершение процесса отладки;list main.c:3,10 – отобразить исходный текст

программы из файла main.c с 3 по 10 строки;break main.c:15 – установить точку останова в

строке 15 файла main.c;break 15 – установить точку останова в строке 15

текущего файла;delete 1 или d 1 – удаление точки останова с

номером 1;

Page 458: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

458

clear – удалить все точки останова в текущей функции;

delete или d – удалить все точки останова;info breakpoints – просмотр существующих точек

останова;print variable или p variable – вывод значения

переменной в текущей точке останова, если переменнаяявляется массивом выводятся значения всех элементовмассива;

p * array@len – вывод всех значений элементовмассива с идентификатором array, объявленногоследующим образом int *array = (int *) malloc (len * sizeof(int));

display variable – вывод на экран значенияпеременной в каждой точке останова;

watch variable – останавливать выполнение программы при изменении переменной, считается контрольным выражением;

info watchpoints – просмотр всех контрольных выражений;

frame – отображение текущего кадра, при передачиадреса кадра или его номера выводится содержимоевыбранного кадра;

continue или c – продолжить выполнение программыпосле точки останова;

set variable=0 – задание значения 0 для переменнойс идентификатором variable в текущей точке останова;

step или s – пошаговое выполнение после текущейточки останова;

next или n – пошаговое выполнение в пределахфункции, в случае вызова функции переход в неё неосуществляется;

finish – прекращение пошагового исполнения;backtrace или bt – показывает список вызовов

Page 459: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

459

функций в точке останова;where – просмотр содержимого стека в точке

останова;up – подняться вверх на одну функцию по стеку

вызовов, используется для просмотра значенийпеременных и констант в вызвавшей функции;

down – опуститься по стеку вызовов на одну функциювниз;

set follow-fork-mode <parent/child> – указываетнаправление перехода при создании нового процессафункцией fork(); parent – оставаться в процессе родителе,child – идти в процесс потомок;

info registers – вывести имена и содержимое всехрегистров в текущем кадре, кроме регистров сплавающей запятой;

info all-registers – вывести имена и содержимое всехрегистров;

info registers <ИМЯ РЕГИСТРА> - список именрегистров, которые необходимо вывести;

kill – завершение отладки программы;quit или q – выход из отладчика;info float – отобразить аппаратно-зависимую

информацию о модуле поддержки вычислений сплавающей запятой;

apropos local – поиск в подсказке по слову local впроцессе работы с отладчиком gdb;

info local – поиск в подсказке пояснений к командеlocal в процессе работы с отладчиком gdb;

gdb info locals – поиск в подсказке пояснений к команде local из ЭТ.

В процессе описания команд были использованыследующие базовые понятия, характерные для всехотладчиков:

Page 460: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

460

точка останова – остановка исполнения процессапод отладкой и получение возможности просматривать иизменять значения в ОЗУ;

контрольное выражение – условие, при которомвыполняется некоторое действие, обычно остановкаисполнения программы;

кадр – область видимости, обычно значения вфункции и значения регистров при переключении вфункцию для её исполнения.

Отладка с помощью gdb возможна для любыхисполняемых файлов. Отладка файлов без отладочнойинформации делает недоступными ряд ключевыхфункций, ускоряющих отладку. Для включенияотладочной информации в исполняемый файлнеобходимо при его компиляции указывать ключ -g.

gcc 01.c -g

При использовании Makefile передать ключ -g дляего использования при компиляции каждого файламожно в коммандной строке ЭТ следующим образом:

make CFLAGS=-g

Или добавив в Makefile следующую строку

CFLAGS=-g

Для запуска gdb использована команда

gdb a.out

После этого возможен просмотр содержимого

Page 461: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

461

исходного текста текущего файла

(gdb) list 1,91 #include <stdio.h>23 int max_value (int first, int second) {4 fprintf(stderr, "Функция запускается\n");5 int value = first > second ? first : second;6 fprintf(stderr, "Функция выполнена\n");7 return value;8 }9

Для установки точки останова в строке 5используется команда

break 5

Будет выведено следующее сообщение

Breakpoint 1 at 0x400622: file 01.c, line 5.

Производится запуск программы на исполнение

r

Получено следующее сообщение

Starting program: /home/a.out Missing separate debuginfo for /lib64/ld-linux-x86-

64.so.2Try to install the hash file /usr/lib/debug/.build-

id/6c/b5953b40bba0b1f74202ae673850709ec920d4.debugMissing separate debuginfo for /lib64/libc.so.6

Page 462: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

462

Try to install the hash file /usr/lib/debug/.build-id/14/a293becbf38dc6c9e8779938147ec7c0c51f15.debug

Вызов функции: Success

Program received signal SIGSEGV, Segmentation fault.0x000000000040066f in main () at 01.c:1414 int value = max_value (*first, second);

Отладчик указал на тип ошибки и строку, котораястала её источником.

Несмотря на то, что программа разрушена, в памятиприсутствует возможность просмотра значенийаргументов в точке разрушения. Далее приведеныкоманды вывода значений всех переменных,использованных в строке 14.

(gdb) print *firstCannot access memory at address 0x0(gdb) print second$1 = 3(gdb) print value$2 = 32767

В соответствии с выводом, переменная *firstуказывает в значение по адресу 0x0, что и привело кошибке. Значение second равно 3. Значение value имеетмусорное значение 32767.

Для проверки стека вызовов использована следующая команда

bt

Стек вызовов содержит вызов только одной функции

Page 463: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

463

#0 0x000000000040066f in main () at 01.c:14

Для вывода значений регистров использована команда

info registers

Отображены следующие значения регистров.

rax 0x0 0rbx 0x0 0rcx 0x7ffff7ffcc80 140737354124416rdx 0x7ffff7dd4380140737351861120rsi 0x7ffff7dd3b58 140737351859032rdi 0x20000 131072rbp 0x7fffffffe420 0x7fffffffe420rsp 0x7fffffffe410 0x7fffffffe410r8 0x7ffff7fd0700 140737353942784r9 0x23 35r10 0x7 7r11 0x246 582r12 0x400500 4195584r13 0x7fffffffe500 140737488348416r14 0x0 0r15 0x0 0rip 0x40066f 0x40066f <main+29>eflags 0x10206 [ PF IF RF ]cs 0x33 51ss 0x2b 43ds 0x0 0es 0x0 0fs 0x0 0gs 0x0 0

Page 464: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

464

Для завершения отладки выполняется команда q исразу же завершение подтверждается нажатием y.

Преимущество консольного отладчика – ввозможности выбора графической оболочки для работы сним. Для примера выбрана оболочка nemiver. Программаимеет полноценный оконный интерфейс. Её можнозапустить как с помощью выбора в меню графическогоинтерфейса или с помощью команды

nemiver <ИМЯ ПРОГРАММЫ> <АРГУМЕНТ 1> ... <АРГУМЕНТ N>

Page 465: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

465

6.6.3. Поиск утечек памяти

Применение приемов и технологий исправленияошибок режима исполнения не всегда способна выявитьошибки, возникающие при работе с памятью.Некорректное освобождение ресурсов может порождатьскрытые ошибки, проявляющиеся только на одной изплатформ.

Наиболее часто встречающиеся ошибки объединеныодним названием – утечка памяти. К этому понятиюотносится выделение памяти ОЗУ со стороны ОС дляпрограммы и её не освобождение. Другим источникомошибок является обращение в область памяти, котораяуже возвращена в ОЗУ или никогда не выделялась.

Для проверки корректности работы с памятью ОЗУиспользуются специальные средства, самым популярнымиз которых является набор инструментов valgrind.Наиболее часто используется программа memcheck. Онаможет применяться как к программам, в которыевключена отладочная информация, так и к тем, вкоторые отладочная информация не включена.

Проверка с помощью утилит поиска утечек памятиобычно производится после отладки программы. Иногдаприходится её выполнять в процессе написания иотладки при возникновении ошибок, причину которыхвыяснить не получается другими способами.

Демонстрация поиска утечек памяти в ОЗУ будетпроводиться на примере исходного текста программы изпункта 6.6. Для этого необходимо выполнить сборкупрограммы с использованием ключа -g

gcc 01.c -g

Запуск программы выполняется следующим образом

Page 466: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

466

valgrind --leak-check=full ./a.out

Программа добавляет в стандартный поток выводаочень подробное описание. Не все найденные ошибкиявляются ошибками, возникшими по причине невернонаписанного исходного текста программы. Другимипричинами ошибок могут стать особенности платформы,отличия в версия ОС или компилятора. Также иногдаслучаются ложные срабатывания, но на практике такоепроисходит в самых редких случаях.

Наиболее важными строками вывода являются:

==2455== Command: ./a.out==2455==Вызов функции: Success==2455== Use of uninitialised value of size 8==2455== at 0x40066F: main (01.c:14)==2455== ==2455== Invalid read of size 4==2455== at 0x40066F: main (01.c:14)==2455== Address 0x0 is not stack'd, malloc'd or

(recently) free'd==2455== ==2455== ==2455== Process terminating with default action of

signal 11 (SIGSEGV)==2455== Access not within mapped region at

address 0x0==2455== at 0x40066F: main (01.c:14)...==2455== ERROR SUMMARY: 2 errors from 2

contexts (suppressed: 0 from 0)Ошибка сегментирования

Page 467: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

467

В конце вывода содержится строка ERRORSUMMARY, в которой указывается общее количествоошибок. В случае отсутствия ошибок читать длинныйвывод не имеет смысла.

В выводе инструмента поиска ошибок утечки памятиточно указана строка, имя файла с исходным текстомпрограммы, которая привела к ошибке main (01.c:14), атакже название функции и адрес в памяти ОЗУ.

В случае, когда программа не содержит отладочнойинформации, в выводе будет указано только названиефункции и адрес в ОЗУ, а также причина ошибки. Приэтом количество ошибок будет также указано правильно.

==2918== Command: ./a.out==2918== Вызов функции: Success==2918== Use of uninitialised value of size 8==2918== at 0x40066F: main (in /home/a.out)==2918== ==2918== Invalid read of size 4==2918== at 0x40066F: main (in /home/a.out)==2918== Address 0x0 is not stack'd, malloc'd or

(recently) free'd==2918== ==2918== ==2918== Process terminating with default action of

signal 11 (SIGSEGV)==2918== Access not within mapped region at

address 0x0==2918== at 0x40066F: main (in /home/a.out)...==2918== ERROR SUMMARY: 2 errors from 2

contexts (suppressed: 0 from 0)

Page 468: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

468

Ошибка сегментирования

Программа valgrind имеет множество другихвозможностей отладки и профилирования исходноготекста программы и исполняемого файла, однакоописанный способ позволяет приступить к еёиспользованию без детального изучения еёвозможностей.

Page 469: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

469

6.7. Си и ассемблер. Технологии дезасемблирования

Язык программирования Си вырос изинформационных технологий, разрабатывавшихся наязыке ассемблер. Кроме того, он изначальноиспользовался для разработки ОС, часть которой всегданаписана на ассемблере. В связи с этим язык Си легкоинтегрируется с модулями, разработанными наассемблере. В данном разделе не будет исчерпывающихпояснений исходного текста на языке ассемблер. Егоизучение требует наличие знаний в областимикропроцессорных технологий, аппаратногообеспечения ЭВМ и как минимум основ построения ОС.

Рассмотрим пример использования функции pow,написанной на языке ассемблер и размещенной в файлеpow.s.

pow.s

.globl powpow: movl -4(%rbp), %eax imull %eax, %eax # умножить само на себя ret

Для использования функции pow использованследующий текст программы на языке Си, размещенныйв файле main.c .

main.c

#include <stdio.h>

Page 470: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

470

int pow (int); /*На ассемблере*/

int main () { int i = 4; printf("Before pow i = %d\n",i); i = pow(i); printf("After pow i = %d\n",i); return 0;}

Компилятор gcc поддерживает работу с текстом наязыке ассемблер двух нотаций intel и AT&T. В первомслучае предложено скомпилировать сначала объектныйфайл из текста на языке ассемблер, затем выполнитьсборку исполняемого файла.

gcc -c pow.sgcc pow.o main.c

Для компилятора gcc ассемблер являетсяподдерживаемым языком, поэтому нет необходимостиразделять этапы сборки исполняемого файла. Онавыполняется одной командой так, как если быиспользовались файлы, написанные только на языке Си.

gcc pow.s main.c

После сборки программы её запуск осуществляется как обычно

./a.out

В результате выполнения программы будет получен следующий вывод

Page 471: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

471

Before pow i = 4After pow i = 16

Использование исходных текстов на языке Сидопускается в программах на языке ассемблер. Далееприведен пример программы на ассемблер,использующую функцию на языке Си. Файл print.cсодержит следующий исходный текст

print.c

# include <stdio.h>

void print(int i) { printf("%d\n",i);}

Текст главной функции программы реализован вфайле main.s и написан на языке ассемблер.

main.s

.globl mainmain: pushq %rbp # Кладем в стек адрес возврата movq %rsp, %rbp # Сохраняем вершину стека movl $1123, -4(%rbp) # Кладем в стек за вершиной

стека первую константу movl -4(%rbp), %eax # Из первой константы в

стеке кладем значение в eax movl %eax, %edi # Кладем значение eax в edi т.к.

это нужно для вызова функции на Си call print # вызываем функцию print

Page 472: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

472

movl $0, %eax # обнуляем значение возврата leave # востанавливаем стек тут необязательно ret # завершаем программу

Сборка и запуск программы на ассемблеревыполняется так же, как и программы на Си

gcc print.c main.s./a.out

В результате исполнения программы полученследующий вывод

Вывод1123

Третьим способом применения ассемблерных командв программе на языке Си является использованиеассемблерных вставок. В пункте j.5.10 стандарта языкапрограммирования Си указывается синтаксис ключевогослова asm для вставки ассемблерных команд в текстпрограммы на языке Си.

Далее приведен пример использования ассемблернойвставки в исходном тексте программы в файле 05.c длякомпиляции gcc (рисунок 1).

Для компиляции файла 05.c необходимодополнительно указать компилятору gcc нотацию,использованную для написания ассемблерной вставки

gcc -masm=intel 05.c

Компилятор gcc имеет специальный ключ, которыйпозволяет из текста на языке Си генерировать текст наязыке ассемблер. Для примера взять исходный текст

Page 473: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

473

программы из пункта 6.6. Для генерации текста на языкеассемблер использована команда

gcc 01.c -S

Рисунок 1 — Файл 05.c

Ниже представлены первые 10 строк функции main,сгенерированные компилятором gcc в нотации AT&T.

main:.LFB1:

.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6subq $32, %rsp

Page 474: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

474

movl $2, -20(%rbp)leaq-20(%rbp), %raxmovq %rax, -8(%rbp)

Для генерации текста на языке masm, необходимоявно указать нотацию языка ассемблер с помощьюдирективы

g++ 1.cpp -S -masm=intel

Первые 10 строк функции main, сгенерированные внотации intel

main:.LFB1:

.cfi_startprocpush rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movrbp, rsp.cfi_def_cfa_register 6sub rsp, 32movDWORD PTR [rbp-20], 2lea rax, [rbp-20]movQWORD PTR [rbp-8], rax

Технологии дизасемблирования относятся креверсинжинирингу, т.е. к способам восстановленияпринципов функционирования готового продукта. Однаиз популярных технологий в этой области — программаnm, позволяющая просматривать таблицы имен вбинарных объектах ОС Линукс.

Для демонстрации возможностей инструментовдезасемблирования будет использован исполняемый

Page 475: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

475

файл, полученный из исходного текста программы впункте 6.6. Программа nm и программы пакета binutils.

Получение имен объектов исполняемого файла a.out

nm -D a.out w __gmon_start__ U __libc_start_main U printf

Полный список объектов файла .a.out

nm a.out000000000060102c B __bss_start000000000060102c b completed.75570000000000601028 D __data_start0000000000601028 W data_start0000000000400460 t deregister_tm_clones00000000004004e0 t __do_global_dtors_aux0000000000600e18 t

__do_global_dtors_aux_fini_array_entry0000000000400618 R __dso_handle0000000000600e28 d _DYNAMIC000000000060102c D _edata0000000000601030 B _end0000000000400604 T _fini0000000000400500 t frame_dummy0000000000600e10 t __frame_dummy_init_array_entry00000000004007a0 r __FRAME_END__0000000000601000 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__0000000000400650 r __GNU_EH_FRAME_HDR00000000004003c8 T _init0000000000600e18 t __init_array_end0000000000600e10 t __init_array_start

Page 476: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

476

0000000000400610 R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable0000000000600e20 d __JCR_END__0000000000600e20 d __JCR_LIST__ w _Jv_RegisterClasses0000000000400600 T __libc_csu_fini0000000000400590 T __libc_csu_init U __libc_start_main@@GLIBC_2.2.50000000000400542 T main0000000000400526 T max_value U printf@@GLIBC_2.2.500000000004004a0 t register_tm_clones0000000000400430 T _start0000000000601030 D __TMC_END__

Получение дезасемблированного текста программына языке ассемблер возможно из исполняемого файла.Для этого можно использовать любой тип исполняемогофайла как с информацией для отладки, так и без неё.

objdump -d a.out

Далее приведены первые 10 строкдезассемблированной функции main файла a.out.

0000000000400542 <main>: 400542: 55 push %rbp 400543: 48 89 e5 mov %rsp,%rbp 400546: 48 83 ec 20 sub $0x20,%rsp 40054a: c7 45 ec 02 00 00 00 movl $0x2,-

0x14(%rbp) 400551: 48 8d 45 ec lea -0x14(%rbp),

%rax

Page 477: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

477

400555: 48 89 45 f8 mov %rax,-0x8(%rbp)

400559: c7 45 f0 03 00 00 00 movl $0x3,-0x10(%rbp)

400560: 48 8b 45 f8 mov -0x8(%rbp),%rax

400564: 8b 00 mov (%rax),%eax 400566: 8b 55 f0 mov -0x10(%rbp),%edx

Для просмотра содержимого динамическихбиблиотек используется программа readelf, например,следующим образом

readelf -l libao.so.4

Будет отображена информация, приведенная нарисунке 2.

Следует иметь в виду, преобразование из Си вассемблер возможно, но операторы Си не всегда имеютпрямое отражение на ассемблерные инструкции из-завыполняемой компилятором оптимизации. В связи сэтим, обратное преобразование ассемблерного текста вСи почти всегда невозможно. Преобразование междудвоичным файлом и ассемблерными командамивозможно в оба направления. При восстановлениипрограммы из исполняемого файла в ассемблерный тексттеряются идентификаторы переменных.

Page 478: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

478

Рисунок 2 — Вывод утилиты readelf

Page 479: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

479

6.8. Использование библиотек6.8.1. Библиотечные функции

В программах на Си часто используется механизм,предоставляемый ОС для выделения повторяющихсяфункций и общих ресурсов в двоичное хранилище,отдельное от исполняемого файла и называемоебиблиотеками.

Библиотеки, описанные в стандарте языкапрограммирования, называются стандартными исодержать набор функций, перечисленных в стандартеязыка. В пункте 4.3.2 рассматриваются функции дляработы со строками, которые составляют стандартнуюбиблиотеку, описанную в заголовочном файле string.h.Библиотека для работы со строками описана в разделе7.24 стандарта языка программирования.

Значение библиотек в языке Си настолько велико,что их описание начинается с раздела 7 стандарта языкапрограммирования и занимает около ¾ всего стандарта.

Кроме стандартных библиотек важный вклад вносятбиблиотеки, предоставляющие интерфейсы кмеханизмам по стандарту POSIX. Все взаимодействия сосновными элементами ОС выполняются именно спомощью таких библиотек.

Для демонстрации работы с библиотеками, невходящими в стандарт языка программирования,выбраны библиотеки, описанные заголовочнымифайлами dirent.h и sys/stat.h, которые используются дляработы с элементами файловой системы. Использованмодифицированный фрагмент исходного текстапрограммы, зарегистрированной с именем «ФСидентификация» с номером №2018663874, выданнойФедеральной службой по интеллектуальнойсобственности.

Page 480: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

480

Пояснения к исходному тексту программы даны ввиде комментариев к строкам, выражения в которыхиспользуют объявления заголовочных файлов dirent.hили sys/stat.h.

Рисунок 1 — Исходный текст программыотображения имен файлов и размера их содержимого втекущем каталоге

После создания исполняемого файла и его запускабыл получен вывод

./01.c size: 1076

./a.out size: 14488

Page 481: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

481

Заголовочные файлы библиотек расположены вкаталоге /usr/include, а сами библиотеки в каталогах/usr/lib, /usr/lib64 или других. Следует учесть, чтооднозначное соответствие между именем заголовочногофайла и именем библиотеки может отсутствовать.

Page 482: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

482

6.8.2 Статические библиотеки

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

Для создания статической библиотеки необходимоиспользовать следующие программы:

- компилятор gcc для компиляции;- архиватор, создающий статические библиотеки ar;- программу создания оглавления библиотеки для

ускорения вызовов функции ranlib.Для примера создания статической библиотеки

используется три файла

lib.h

void hello(void);

lib.c

#include <stdio.h>

void hello(void){ printf("Hello, library world.\n");}

main.c

Page 483: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

483

#include "lib.h"

int main(){ hello(); return 0;}

Кратчайший способ создания статическойбиблиотеки – выполнение команд

gcc -c lib.car cru lib.a lib.oranlib lib.a

В результате первой командой будет созданобъектный файл lib.o. Вторая команда создаст файлбиблиотеки lib.a, а третья обновит файл lib.a, создавтаблицу вызываемых функций. Для добавлениястатической библиотеки в исполняемый файлнеобходимо при компиляции указать компоновщику путьк каталогу с библиотеками и имя используемойбиблиотеки

gcc main.c -L. lib.a

Ключ компилятора -L. (последний символ точки)указывает на то, что библиотеки находятся в текущемкаталоге. Далее указывается имя собранной ранеестатической бибилотеки lib.a.

Запуск созданного исполняемого файла с именем поумолчанию производится как обычно

./a.out

Page 484: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

484

Файл статической библиотеки используется толькона этапе сборки программы. После этого наличие файлаlib.a для запуска программы не обязательно.

Статические библиотеки являются дополнительнымсредством структурирования программы в процессеразработки. Их применение не требует дополненияисходного текста программы.

Page 485: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

485

6.8.3 Динамические библиотеки

Динамическая библиотека запускается в момент еёвызова программой. Для её загрузки необходимо вызватьспециальную функцию загрузки библиотеки и функциюполучения адреса требуемой функции. ОС ведет счетчикиспользуемых процессов. Динамическая библиотекавыгружается, если ни один процесс её не использует.Файл библиотеки требуется поставлять совместно сисполняемым файлом.

Создание динамической библиотеки требует немногобольше усилий по сравнению со статической. Длясоздания динамической библиотеки будут использованыфайлы

lib.h

void hello(void);

lib.c

#include <stdio.h>#include "lib.h"

void hello(void){ printf("Hello, library world.\n");}

Для компиляции динамической библиотеки сначалонеобходимо создать объектный файл командой

gcc -fPIC -c lib.c

Ключ -fPIC позволяет создать объектный файл,

Page 486: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

486

содержащий код, независимый от расположения в файле.Такой эффект достигается использованиемотносительной адресации функций. Для получения болееподробной информации по этому вопросу необходимообратиться к описанию PIC (Position Independent Code)технологии исполняемых файлов.

Сборка динамической библиотеки производится спомощью команды

gcc -shared -o lib.so.0.0 lib.o -lc

Ключ -shared сообщает компилятору онеобходимости создания динамической библиотеки.Ключ -lc указывает на необходимость использованиястандартной библиотеки libc, включающей в себяреализацию функции stdio.h. Ключ -o задает имявыходного файла.

Для интеграции созданной динамическойбиблиотеки в ОС необходимо скопировать её вкаталог /lib или lib64 в зависимости от архитектуры ОС.

Следующая команда выполняет настройкусвязывания времени исполнения в динамическомкомпоновщике, т.е. объясняет ОС, где искать каталоги сдинамическими библиотеками. Комманда выполняетсятолько после копирования библиотеки в каталог /libили /lib64

/sbin/ldconfig -v -n

Такую привязку допустимо выполнятьредактированием файла /etc/ld.so.conf . В современныхдистрибутивах этот файл содержит ссылку на каталог сфайлами, содержащими пути к библиотекам. Например:include /etc/ld.so.conf.d/*.conf , где и нужно размещать

Page 487: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

487

файлы, содержащие пути к библиотекам. В файле/etc/ld.so.cache хранится кеш путей и библиотек вдвоичном виде. Для более подробного изучения ldconfigнеобходимо воспользоваться встроенной справкой man.Для этого следует выполнить команду man ldconfig.

Рисунок 1 – Исходный текст программы, вызывающейдинамическую библиотеку

Для просмотра кеша динамических библиотекиспользуется команда

/sbin/ldconfig -p

Page 488: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

488

Для этого необходимо добавить в файл пути, вкоторых следует искать динамические библиотеки.

Исходный текст программы, вызывающей функциюиз динамически подключаемой библиотеки, представленна рисунке 1.

Получение объектного файла из исходного текстапрограммы выполняется как обычно

gcc -c main.c

При компановке исполняемого файла необходимоуказать дополнительный ключ

gcc main.o -ldl

Дополнительный ключ необходим для включения висполняемый файл библиотеки, содержащей функциидля работы с динамическими библиотеками (dlopen,dlsym, dlclose).

Провести сборку исполняемого файла возможноодной командой

gcc main.c -ldl

Если библиотека не была скопирована в системнуюпапку для динамических библиотек такого типа инаходится в том же каталоге, что и файл программы,запуск полученного исполняемого файла производитсяследующим образом

LD_LIBRARY_PATH="." ./a.out

или

Page 489: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

489

export LD_LIBRARY_PATH="."./a.out

После запуска программы должен быть полученследующий вывод

Hello, library world.

При поставке программного обеспечения в качестведвоичных файлов, в случае отсутствия одной избиблиотек требуется установить, какая именнобиблиотека была недопоставлена или удалена. Для этогоподходит команда

ldd a.out

Вывод команды

linux-vdso.so.1 (0x00007fff69baf000)libc.so.6 => /lib64/libc.so.6 (0x00007fc41aba7000)/lib64/ld-linux-x86-64.so.2 (0x00007fc41b14c000)

Информация об используемых библиотекахзапущенных процессов храниться в файле maps ФС /proc/и может быть отображена командой

cat /proc/$PID/maps

Соответственно, для использования этой библиотекинеобходимо наличие еще трех библиотек.

При запуске ОС динамической библиотекипроизводится выполнение функции _init(). При выгрузкебиблиотеки выполняется функция _fini(). Следует

Page 490: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

490

обратить внимание, функции вызываются только припервом запуске программы. Если библиотеку вызываютдругие программы, повторного вызова функцииинициализации не произойдет. Если первая программауспеет завершить работу с библиотекой до того, какбиблиотеку запросит вторая программа, после запросавторой программы библиотека будет загружена заново ифункция _init() выполнится еще раз. По такому жепринципу работает функция _fini().

Для демонстрации работы функций _init(), _fini()необходимо изменить файлы lib.h и lib.c следующимобразом

lib.h

void _init(void);void hello(void);void _fini(void);

lib.c

#include <stdio.h>

void _init(void){ printf("Load library!\n");}

void hello(void){ printf("Hello, library world.\n");}

void _fini(void){ printf("Library destroy!\n");}

Page 491: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

491

Компиляция файлов производится таким же образом

gcc -fPIC -c lib.c

Компиляция должна пройти без ошибок. При сборкебиблиотеки командой будут получены следующиесообщения об ошибках

lib.o: In function `_init':lib.c:(.text+0x0): multiple definition of `_init'/usr/lib64/gcc/x86_64-alt-

linux/5/../../../../lib64/crti.o:/usr/src/RPM/BUILD/glibc-2.23-alt3.M80P.2/csu/../sysdeps/x86_64/crti.S:64: first definedhere

lib.o: In function `_fini':lib.c:(.text+0x26): multiple definition of `_fini'/usr/lib64/gcc/x86_64-alt-

linux/5/../../../../lib64/crti.o:/usr/src/RPM/BUILD/glibc-2.23-alt3.M80P.2/csu/../sysdeps/x86_64/crti.S:64: first definedhere

collect2: ошибка: выполнение ld завершилось с кодомвозврата 1

Ошибка сообщает, что функции _init() и _fini()определены в файле crti.S . Для определениябиблиотеки, в которой находится реализация даннойфункции, сборку необходимо выполнить сдополнительным ключом -v

gcc -shared -o lib.so.0.0 lib.o -lc -v

В выводе этой команды в конце присутствуют строки

Page 492: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

492

lib.c:(.text+0x0): multiple definition of `_init'/usr/lib64/gcc/x86_64-alt-

linux/5/../../../../lib64/crti.o:/usr/src/RPM/BUILD/glibc-2.23-alt3.M80P.2/csu/../sysdeps/x86_64/crti.S:64: first definedhere

lib.o: In function `_fini':lib.c:(.text+0x26): multiple definition of `_fini'/usr/lib64/gcc/x86_64-alt-

linux/5/../../../../lib64/crti.o:/usr/src/RPM/BUILD/glibc-2.23-alt3.M80P.2/csu/../sysdeps/x86_64/crti.S:64: first definedhere

Вывод сообщает нам о том, что фунции реализованыв библиотеке crti.o. Для создания библиотеки необходимовыполнить программу collect2 с ключами,сгенерированными компилятором gcc, удаливпредварительно путь к библиотеке crti.o. Была полученаследующая строка

/usr/libexec/gcc/x86_64-alt-linux/5/collect2 -plugin/usr/libexec/gcc/x86_64-alt-linux/5/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-alt-linux/5/lto-wrapper -plugin-opt=-fresolution=/tmp/.private/valerii/ccnidWIZ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s-plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu --as-needed -melf_x86_64 -shared -o lib.so.0.0 /usr/lib64/gcc/x86_64-alt-linux/5/crtbeginS.o -L/usr/lib64/gcc/x86_64-alt-linux/5-L/usr/lib64/gcc/x86_64-alt-linux/5/../../../../lib64 -L/lib/../lib64-L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-alt-linux/5/../../..lib.o -lc -lgcc --as-needed -lgcc_s -lc -lgcc --as-needed-lgcc_s /usr/lib64/gcc/x86_64-alt-linux/5/crtendS.o/usr/lib64/gcc/x86_64-alt-linux/5/../../../../lib64/crtn.o

Page 493: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

493

В файл main.c изменений вносить не требуется. Егосборка осуществуется как обычно

gcc main.c -ldl

После сборки программы её запуск производится какобычно

LD_LIBRARY_PATH="." ./a.out

В результате был получен вывод

Load library!Hello, library world.Library destroy!

Таким образом была произведена замена функций_init() и _fini() в библиотеке lib.

Также для отключения сборки стартовых функций, вкоторых присутствуют _init() и _fini(), по умолчаниюможно использовать ключ компилятора gcc -nostartfiles.

Page 494: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

494

7. Экспресс — алгоритмизация7.1. Блок-схемы и UML

Во введении приводится краткое описаниенескольких типов мышления, которые необходиморазвивать программисту для выполнения своихпрофессиональных обязанностей. Все они базируются наалгоритмическом типе мышления, который являетсяглавным для парадигмы языка программирования Си.Его формирование занимает не менее шести месяцев.Такие типы мышления как объектный, параллельный(связанный с многопоточным программированием)можно развить за месяц, но только при условии наличияалгоритмического типа мышления. Базовые понятия дляпонимания алгоритмов приведены в пункте 1.3.

Алгоритмы могут быть записаны в любомформализованном виде. Под этим подразумевается, в томчисле, текстовая запись в виде комментариев в исходномтексте программы, которые не требуют уточнения принаписании исходного текста программы. В классическомпонимании, формализованный вид — это описание спомощью математических формул.

Наиболее популярный вид представленияформализованных алгоритмов — блок-схема. Блоки, т.е.составные части и правила составления блок-схемописаны в ГОСТ 19.701-90 «Схемы алгоритмов,программ, данных и систем. Условные обозначения иправила выполнения». Развитие алгоритмическогомышления путем построения блок-схем выходит за рамкиэтой книги. Дополнительную информацию о правилахпостроения блок-схем можно найти в Википедии.Классическим произведением в этой области являетсятрехтомник Кнут Д. Э. «Искусство программирования».

Умение читать и составлять блок-схемы является

Page 495: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

495

обязательным навыком для программистаиспользующего язык Си. Многие аппаратные ипрограммные стандарты содержат пояснения к своейработе, выполненные в виде блок-схем.

Для программирования с использованием другихтипов мышления используется UML. Он применяется длясоздания абстрактных моделей и позволяет описыватьклассы, компоненты, архитектуры, а также такиепроцессы как обобщение, агрегацию.

Page 496: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

496

7.2. Реализация односвязных и многосвязных списков

Для обсуждения эффективности ипроизводительности алгоритмов в пункте 8.3предлагается использовать программу, оперирующуюсвязным списком. В структурах данных этого типа длякаждого элемента выделяются ячейки памяти в ОЗУ.Связные списки бывают разного вида. Они отличаютсяколичеством указателей на другие элементы в каждомэлементе, а также необходимостью создавать отдельныеуказатели на начало и конец связного списка.

В языке Си есть набор «лучших практик», которыерекомендованы к использованию. В отношении работы сосписками такой лучшей практикой является применениезаголовочного файла /usr/include/sys/queue.h . Файлсодержит набор макросов, выполняющие действия суказателями, т. е. операции, которые являются основнымисточником ошибок при использовании связных списков.Файл написан в 1991-1994 годах в университете Беркли.

В таблице 1 указано, какие связные спискиреализованы в файле queue.h .

Таблица 1 — Соответствие функций для работы сосписками типам связных списков

Типы соответствий:+ макрос для данного типа списка доступен;- макрос для данного типа списка недоступен;s макрос доступен, выполняется медленно (время

исполнения O(n) ).

МАКРОС \ ФУНКЦИЯ SLIST LIST STAILQTAILQ

Page 497: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

497

Таблица 1. продолжение_HEAD + + + +_CLASS_HEAD + + + +_HEAD_INITIALIZER + + + +_ENTRY + + + +_CLASS_ENTRY + + + +_INIT + + + +_EMPTY + + + +_FIRST + + + +_NEXT + + + +_PREV - + - +_LAST - - + +_FOREACH + + + +_FOREACH_FROM + + + +_FOREACH_SAFE + + + +_FOREACH_FROM_SAFE + + + +_FOREACH_REVERSE - - -+_FOREACH_REVERSE_FROM - - - +_FOREACH_REVERSE_SAFE - - - +_FOREACH_REVERSE_FROM_SAFE - - -+_INSERT_HEAD + + + +Продолжение таблицы 1

_INSERT_BEFORE - + - +_INSERT_AFTER + + + +_INSERT_TAIL - - + +_CONCAT s s + +_REMOVE_AFTER + - + -_REMOVE_HEAD + - + -_REMOVE s + s +_SWAP + + + +

Page 498: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

498

Для реализации программы используетсяоднонаправленный связный список типа SLIST.Однонаправленный список имеет функции перемещенияот начала списка к его концу, однако не позволяетвозвращаться на предыдущий элемент. Кроме того,функции _REMOVE выполняются медленнее, чем всписке LIST. Без функции _REMOVE список пригоден длянаполнения неизменными данными для использования вкачестве справочника, но не пригоден для выполненияинтенсивных операций с его элементами.

Рисунок 1 — Первая часть исходного текстапрограммы

Page 499: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

499

На рисунке 1 представлены первые 29 строкисходного текста программы, выполняющей работу сосписками.

На рисунке 2 представлено окончание исходного текста программы.

Рисунок 2 — Окончание исходного текста программы

Для реализации однонаправленного связного спискав программе используется два типа:

- ListHead — структура с данными, необходимыми

Page 500: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

500

для работы всего списка;- ListItem — для элемента списка.Тип ListHead является переопределением типа

SLIST_HEAD(ListHead, ListItem), который необходим дляработы макросов, обеспечивающих действия сосписками. Переопределение выполнено в строке 10. Впрограмме используется один список, поэтомупеременная этого типа также одна и имеетидентификатор list_head.

Тип ListItem содержит в себе указатель наследующий элемент и данные типа int сидентификатором data, которые и являются «полезнойнагрузкой» элемента списка. Объявление спискапроизведено в строках 5-8. В алгоритмах программыиспользуется переменная ni.

Программа собирается из этого исходного текстакомандой

gcc main.c

В результате выполнения программы получен следующий вывод:

Data input: 9 8 7 6 5 4 3 2 1 0 5 deleted: 9 8 7 6 4 3 2 1 0 Items destroy: Exit

Первая строка вывода сформирована строками 25-30.До этих строк выполняется подготовительная работа посозданию необходимых элементов и структур. В строках31-36 производится удаление элемента со значениемполя data = 5. В строках 37-42 производится повторныйвывод списка с удаленным элементом со значением 5. В

Page 501: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

501

строках 43-57 выполняется освобождение ресурсов,вывод соответствующих сообщений и подготовка кзавершению программы.

В стандарте языка программирования в пункте6.7.2.3 приводится пример описания структуры длясвязных списков, однако данная тема является объемнойи не будет рассматриваться в этой книге. Она включает всебя не только набор приемов по работе со связнымисписками, но и изучение алгоритмов по эффективнойобработке данных, хранимых в связных списках.

Page 502: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

502

7.3 Приемы оценки вычислительной сложностиалгоритмов

Эффективность алгоритмов является одной изсложных тем программирования. В учебных заведенияхредко имеются объемные курсы по оптимизацииалгоритмов, т.к. овладение эффективными приемамиоптимизации требует значительного времени и обычноприходит с многолетним опытом разработки.

С другой стороны оптимизация в процессеразработки любых технических решений являетсяобычным делом. Оптимизация расхода некоторогоресурса на 12% считается нормой для любой областитехнологий. Исключение составляютвысокооптимизированные решения с многолетнейисторией. К ним относятся многие узлы техники,выпускаемой серийно.

Программирование предоставляет еще большевозможностей для повышения производительности.Личным рекордом автора этой книги стало повышениескорости алгоритма в 595 раз или на 59500%. Это сталовозможно с помощью помещения всех данных в ОЗУ иотказом от использования операций по выделению иудалению участков памяти ОЗУ в процессе вычислений,которые использовались весьма интенсивно.

Производители современных микропроцессороввыполняют расширение набора аппаратных инструкцийбыстрее, чем производители компиляторов успеваютадаптировать под них алгоритмы оптимизации. Убюджетной модели микропроцессора Intel(R) Celeron(R)2955U @ 1.40GHz значение поля flags, выводимое привызове cat /proc/cpuinfo, содержит названия десятковаппаратных расширений микропроцессора, большинствоиз которых популярные программы не используют.

Page 503: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

503

Все вышесказанное демонстрирует важность какаппаратного, так и программного обеспечения дляэффективного решения вычислительных задач. Подэффективностью в данном случае понимается близкое коптимальному потребление наиболее ограниченногоресурса, например возможности сетевого интерфейсаили объем используемого ОЗУ.

Оценка потребления ресурсов является отдельнойзадачей. При оценке эффективности алгоритма обычнодостаточно определить, потребляется ли ресурсполностью и не возникает ли исключительных ситуацийиз-за превышения в его потребности. В ОС реальногомасштаба времени перегрузка любого ресурса приведет костанову ОС с возможной перегрузкой. В ОС,используемых в качестве домашних и офисных ЭВМ,такие режимы не используются.

Возвращаясь к оценке эффективности алгоритмов,необходимо обозначит самый главный критерийэффективности алгоритма – возможность получитьправильный результат. Следующие по важности ипредставляющие наибольшую трудоемкость составляетоценка эффективности использования памяти ОЗУ ивремени исполнения алгоритма и их оптимизация. Вобщем случае после разработки программы замеряетсяпродолжительность исполнения отдельных функций впрограмме, в которых потребление времени или ОЗУ несопоставимо велико по сравнению с остальнымифункциями ПО. Для каждого из таких мест принимаетсярешение о возможности оптимизации.

При выполнении оптимизации времени исполненияалгоритма общепринятым подходом является оценкаминимального, среднего и максимального времени егоисполнения. Для этого проводится сравнениепродолжительности работы как самого алгоритма с

Page 504: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

504

разными наборами данных, так и различных алгоритмовв прочих равных условиях. К условиям выполненияалгоритма здесь относится производительность ЭВМ,инструментарий, используемый для создания программыиз исходных текстов, язык программирования. Такжесчитается, что все данные, необходимые для выполненияалгоритма, загружены в ОЗУ.

Определение вычислительной эффективностиалгоритма заключается в поиске ответов на следующиевопросы:

- как зависит время работы программы от ростаобъема исходных данных;

- как быстро растет время работы в зависимости отроста объема входных данных, т.е. своего рода перваяпроизводная от первого вопроса.

Оценка производительности алгоритмовпроизводится для трех случаев:

1) при минимальном количестве исходных данных;2) при максимальном количестве данных;3) при любом другом количестве данных.Эти оценки называются оценочными границами или

симптотическими обозначениями. Они вычисляются неточно, т.к. на протекание вычислительного процессавлияет множество факторов. Время исполненияалгоритма вычисляется по аргументу с самой большойстепенью.

Зависимость продолжительности вычислений отколичества входных данных математически обозначаетсякак Θ(n) (тетта от n). Под данным обозначениемподразумеваются все возможные случаи.

Для обозначения наилучшей и наихудшейпроизводительности используют следующиеобозначения:

- Ω (n) (амега от n) дает нижную границу, т.е. Θ(1) =

Page 505: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

505

Ω(1) наилучший результат, который нельзя превзойти безсмены алгоритма;

- O(n) (омикрон от n), при n = max, дает наихудшийрезультат, т.е. Θ(n) = O(n), n = max .

Наиболее распространенными формами Θ(n)являются:

- квадратичная y=Θ(n2) ,- логарифмическая y=Θ(n∗lg(n)) , где lg — это алгоритм

по основанию 2, т.е. lg (n)=log2(n) ,- линейная y=Θ(n) .Оценку производительности допустимо выполнять не

только для программы в целом или функции, но и дляпроизвольной части исходного текста программы. Дляпримера произведем оценку производительностифрагмента программы, получаемой с помощью строквывода элементов связного списка из пункта 7.2. Этотфрагмент исходного текста расположен в файле main.c встроках 25-29, и повторяется в строках 37-41, 49-53.

Фрагмент исходного текста

/*Вывод на экран*/fprintf(stdout, "Data input: ");SLIST_FOREACH(ni, list_head, next) { fprintf(stdout, "%d ", ni->data);}fprintf(stdout, "\n");

Пусть оператор printf() выполняется за время tнезависимо от аргументов и макрос SLIST_FOREACHтакже выполняется за t. В этом случае время выполненияэтого фрагмента текста равно

t + ( t + t )*n + t = Θ(n), где n — количество итерацийцикла.

Page 506: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

506

Θ(n) = 2t + 2tn = 2t (n+1)

Таким образом можно произвести расчет Θ(n) длянекоторых значений n, а также оценочных границ этогоалгоритма. Нижняя граница в случае отсутствияэлементов в связном списке Ω (0) = 2t (0+1) = 2t+1.Делаем допущение о том, что максимальное значение n= 10. В этом случае верхняя граница O(n) = 2t (10+1) =22t.

Необходимо ответственно подходить к изучениюалгоритмизации и исследованию эффективностиалгоритмов. Приведем пример частого заблуждениясреди неопытных программистов. Во многих источникахалгоритм сортировки qsort описывается как наиболееэффективный, имеющий время исполнения от Θ (n2) доΘ (n∗lg(n)) . Однако, чем меньше данных нужно

отсортировать, тем медленнее он будет работать. Вслучае сортировки одного значения, классическийпузырьковый метод дает лучшее время, чем qsort.

Другим интересным примером является сортировкаподсчетом. Её смысл заключается в использованиивспомогательного массива всех возможных значений. Вовремя сортировки ведется подсчет количества элементовдля каждого возможного значения. В конце каждыйэлемент выводится столько раз, сколько раз онвстретился при подсчете. Данный алгоритм работаетбыстрее, чем обычная сортировка сравнением, прикоторой каждый элемент сравнивается с другимиэлементами массива. Сортировка подсчетом примениматолько для небольшого набора возможных значений.

Наиболее полным учебником по алгоритмизацииявляется классическое произведение — 4-х томникДональда Кнута Искусство программирования.

Page 507: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

507

8. Новый взгляд на программирование, «Привет, мир!»

Современное программирование — это не тольконаписание текста программы и преобразование его висполняемый файл для ОС. Причиной этого сталоповышение сложности разрабатываемых программ иувеличение количества строк в них. Сегодня редкоекоммерческое приложение имеет меньше 10 000, илидаже 100 000 строк исходного текста. Разработка такихпроектов значительно упрощается при использованиисредств автоматизации на всех этапах созданияпрограммы. Рассмотрим учебный пример использованияосновных технологий разработки программ.

Продемонстрировать сложный проект непредставляется возможным, поэтому для учебногопримера будет использована программа с минимальнымобъемом исходного текста программы.

Этап 1. Постановка задачи.Самой простой задачей, с которой начинают

знакомство с языком программирования, является выводстроки «Привет, мир!». Сформулируем задачу таким жеобразом. Условие задачи: «Вывести строку «Привет,мир!»».

Результат этого этапа — подробное описаниезадания, т. к. это то, что в реальных проектах называюттехническим заданием или ТЗ. Также это может бытьдокумент, заменяющий ТЗ :J .

Этап 2. Формализация.Одной из целей формализации может быть блок-

схема. Формализуем поставленную задачу.

Page 508: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

508

Результатом данного этапа является блок-схема.Этап 3. Проектирование файловой структуры

проекта.Проектирование файловой структуры проекта

обычно не выполняется при использованииинтегрированных сред разработки, таких как Eclipse,Visual C++. Среди использующих интегрированныесреды навык проектирования ФС прививается посленескольких лет работы. Проектирование ФС обычновыполняется с использованием стандарта POSIX.

Для текущего проекта потребуется каталог проекта.Имя каталога выбрано произвольно project. В каталогесоздан единственный файл main.c , который будетсодержать исходный текст программы.

На этом же этапе инициализируется git с помощьюкоманды

git init

Также рекомендуется добавить ветку dev дляпроведения разработки. Ветка master редко используетсяв сложных проектах.

НАЧАЛО

КОНЕЦ

Привет, мир!

Page 509: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

509

git checkout -b dev

Результат этапа — файловая структура проекта.Этап 4. Написание текста комментариев.Сначала в файле main.c пишется условие задачи,

полученное на этапе1.

/*! * \file * \brief Файл содержит программу вывода фразы

"Привет, мир!" * * Данный файл содержит программу вывода фразы

"Привет, мир!"*/

Далее исходя из условия задачи описываютсявходные и выходные данные функций. Писатькомментарий необходимо в стиле doxygen дляпоследующей автоматической генерации документации.

/** * \brief Программа вывода фразы "Привет, мир!" * * Программа выводит фразу "Привет, мир!" * и завершает свое выполнение. Программа не

принимает * аргументов. * * \param argc Количество аргументов * \param argv Список аргументов * * \return Статус завершения программы */

Page 510: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

510

Результатом этого этапа является файл с описаниемфайла и функции в формате doxygen.

Этап 5. Подготовка к компиляции и сборке.На этом этапе подготавливается файл Makefile. Он

позволяет компилировать целый проект в многопоточномрежиме одной командой.

hw: main.ogcc main.o -o hw

main.o: main.cgcc -pedantic -Wall --std=c17 -c main.c

Autotools для одного файла использован не будет.Результатом этого этапа является Makefile,

позволяющий командой make получать исполняемыйфайл.

Этап 6. Набор исходного текста программы.На этом этапе производится написание программы.

#include <stdio.h>

int main () {puts("Привет, мир!");return 0;

}

Результатом этого этапа является набранныйисходный текст программы.

Этап 7. Статическая проверка исходного текстапрограммы.

Для статической проверки исходного текстапрограммы используется cppcheck. Его применениезаключается в вводе команды

Page 511: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

511

cppcheck --std=c11 .

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

Этап 8. Компиляция и компоновка программы.Данный этап позволяет проверить возможность

сборки программы из исполняемого файла. Для этоговыполняется команда

make

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

Этап 9. Запуск для отладки.Данный этап позволяет выполнить отладку

созданной программы. Для этого вызывается отладчик ив качестве аргумента ему передается имя программы

gdb hw

Для запуска отладки нужно ввести

run

После ознакомления с отладочным выводом ввести

q

В случае нахождения ошибок, необходимовозвращаться на этап 6 и исправлять найденные ошибки.

Результатом данного этапа является программа,

Page 512: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

512

успешно выполняющая все отладочные сценарии.Этап 10. Проверка на утечки памяти.Для поиска утечек памяти в ОЗУ необходимо

выполнить команду

valgrind —leak-check=full ./hw

В случае нахождения ошибок, необходимовозвращаться на этап 6 и исправлять найденные ошибки.

Результатом этого этапа является программа, вкоторой все выделяемые участки памяти корректноосвобождаются.

Этап 11. Выполнение профилирования программы.

Для выполнения профилирования используетсякоманда

gcc -pg main.c -O3 -Wall -pedantic -std=c17 -o hw

Это сделано для того, чтобы не вносить исправлениев Makefile. Далее программа запускается на исполнение.

./hw

В результате исполнения создается двоичный файлgmon.out. Для его преобразования в человекочитаемуюформу необходимо выполнить команду

prof ./hw > 1.txt

В случае обнаружения функций, неудовлетворяющихкритерию производительности, необходимо возвращатьсяна этап от 1 до 6, по ситуации, и исправлять найденныеошибки.

Page 513: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

513

В результате выполнения данного этапа полученнаяпрограмма будет обладать необходимойпроизводительностью, т. е. не будет «тормозить».

Этап 12. Создание документации к программе.Для создания документации необходимо выполнить

две команды.1. Создать проект doxygen.

doxygen -g

2. Создать документацию

doxygen

Результатом этого этапа станет автоматическоесоздание документации к программе.

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

В приведенном примере не рассмотрены средствасовместной разработки и средства управленияразработкой.

Page 514: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

514

Заключение

Большинство вопросов в книге рассмотрены обзорно.Затронутые в книге темы требуют годы для полноценногоизучения, но и начинать работать не имея представленияобо всех этих инструментах и приемах, не эффективно.

Особое внимание следует обратить на формированиеалгоритмического мышления, практикуясь валгоритмизации. Наиболее эффективно заниматьсяалгоритмизацией, изучая готовые решения иалгоритмические приемы с помощью четырехтомника«Искусство программирования» Дональда Кнута. Однакоданное произведение имеет высокий уровень сложности.Если требуется начать с чего-то совсем простого, можновоспользоваться разделом на сайте abashin.ru в которомимеется около 100 готовых блок-схем и условий задач кним. Для обучения алгоритмизации необходимо читатьусловие задачи и пытаться построить блок-схему еёрешения, а если не получится, можно подсмотретьготовое решение. Повторять решение задачи следует дотех пор, пока блок-схема не будет построена правильно.

Page 515: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

515

Литература

1. Винер Н. Кибернетика, или управление и связь вживотном и машине. 1948-1961 [Текст]. - 2-е издание.- М.: Наука; Главная редакция изданий длязарубежных стран, 1983. - 344 с.

2. Кнут Д.Э. Искусство программирования. Том 1.Основные алгоритмы = The Art of ComputerProgramming. Volume 1. Fundamental Algorithms[Текст] / под ред. С.Г. Тригуб (гл. 1), Ю.Г. Гордиенко(гл. 2) и И.В. Красикова (разд.2.5 и 2.6). - Москва:Вильямс, 2002. - Т.1. - 720 с.

3. Кнут Д.Э. Искусство программирования. Том 2.Получисленные алгоритмы = The Art of ComputerProgramming. Volume 2. Seminumerical Algorithms[Текст] / под ред. Л.Ф.Козаченко (гл.3, разд.4.6.4 и4.7), В.Т.Тертышного (гл. 4) и И.В.Красикова(разд.4.6). - Москва: Вильямс, 2001. - Т.2. - 832 с.

4. Кнут Д.Э. Искусство программирования. Том 3.Сортировка и поиск = The Art of ComputerProgramming. Volume 3. Sorting and Searching[Текст] / под ред. В.Т.Тертышного (гл.5) иИ.В.Красикова (гл.6). - 2-е изд. - Москва: Вильямс,2007. - Т.3. - 832 с.

5. Кнут Д.Э. Искусство программирования, том 4, А.Комбинаторные алгоритмы, часть 1 = The Art ofComputer Programming, Volume 4A: CombinatorialAlgorithms, Part 1 [Текст] / под ред. Ю.В.Козаченко. -1. - Москва: Вильямс, 2013. - Т.4. - 960 с.

6. Макарова Н.В., Волков В.Б. Информатика: Учебникдля вузов [Текст] - СПб.: Питер, 2011. - 576 с.: ил.

7. Эбен Майкл, Таймэн Брайан. FreeBSD. Энциклопедияпользователя [Текст], - 3-е изд. перераб. и доп.: Пер.с англ./Майкл Эбен, Брайан Таймэн. — СПб.: ООО

Page 516: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

516

«ДиаСофтЮП», 2003. - 768 с.8. RFC 3629 UTF-8, a transformation format of ISO 10646

[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc3629 .

9. RFC 1321 The MD5 Message-Digest Algorithm[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc1321 .

10. RFC 1489 Registration of a Cyrillic Character Set(koi8-r) [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc1489 .

11. RFC 4251 The Secure Shell (SSH) ProtocolArchitecture [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc4251 .

12. RFC 4716 The Secure Shell (SSH) Public Key FileFormat [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc4716 .

13. RFC 1951 DEFLATE Compressed Data FormatSpecification version 1.3 [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc1951 .

14. RFC6986 GOST R 34.11-2012: Hash Function(ГОСТ Р 34.11-2012) [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc6986 .

15. RFC 791 INTERNET PROTOCOL (IPv4)[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc791 .

16. RFC 2460 Internet Protocol, Version 6 (IPv6)[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc2460 .

17. RFC 1700 ASSIGNED NUMBERS [Электронныйресурс]. - URL: https://tools.ietf.org/html/rfc1700 .

18. RFC 1918 Address Allocation for Private Internets[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc1918 .

19. RFC 792 INTERNET CONTROL MESSAGE

Page 517: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

517

PROTOCOL [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc792 .

20. RFC 950 Internet Standard Subnetting Procedure[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc950 .

21. RFC 793 TRANSMISSION CONTROL PROTOCOL[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc793 .

22. RFC 768 User Datagram Protocol [Электронныйресурс]. - URL: https://tools.ietf.org/html/rfc768 .

23. RFC 1945 Hypertext Transfer Protocol — HTTP/1.0[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc1945 .

24. RFC 2616 Hypertext Transfer Protocol — HTTP/1.1[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc2616 .

25. RFC 7231 Hypertext Transfer Protocol (HTTP/1.1):Semantics and Content [Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc7231 .

26. RFC 3912 WHOIS Protocol Specification[Электронный ресурс]. - URL:https://tools.ietf.org/html/rfc3912 .

27. ISO/IEC 12207:2008 System and softwareengineering — Software life cycle processes. (ИСО/МЭК12207 — 2008 Системная и программная инженерия.Процессы жизненного цикла программных средств)[Электронный ресурс]. - URL:https://www.iso.org/standard/43447.html .

28. ISO/IEC 9899:2018 Information technology --Programming languages — C [Электронный ресурс]. -URL: https://www.iso.org/ru/standard/74528.html .

29. ISO 9660:1988 Information processing -- Volumeand file structure of CD-ROM for informationinterchange [Электронный ресурс]. - URL:

Page 518: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

518

https://www.iso.org/standard/17505.html .30. ISO/IEC 10646:2017 Information technology --

Universal Coded Character Set (UCS) [Электронныйресурс]. - URL:https://www.iso.org/standard/69119.html .

31. ISO/IEC/IEEE 9945:2009 Information technology -- Portable Operating System Interface (POSIX®) Base Specifications, Issue 7 [Электронный ресурс]. - URL: https://www.iso.org/standard/50516.html .

32. ISO/IEC 7816-15:2016 Identification cards --Integrated circuit cards -- Part 15: Cryptographicinformation application (ГОСТ Р ИСО/МЭК 7816)[Электронный ресурс]. - URL:https://www.iso.org/ru/standard/65250.html.

33. ГОСТ 28147-89 Криптография ГОСТ основные понятия [Электронный ресурс]. - URL: http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=131282 .

34. ГОСТ Р ИСО/МЭК 7498-1-99 ВОС. Базоваяэталонная модель. Часть 1. Базовая модель[Электронный ресурс]. - URL:http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=124460 .

35. ГОСТ Р ИСО 7498-2-99 ВОС. Базовая эталоннаямодель. Часть 2. Архитектура защиты информации[Электронный ресурс]. - URL:http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=123561 .

Page 519: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

519

36. ГОСТ Р ИСО 7498-3-97 ВОС. Базовая эталоннаямодель. Часть 3. Присвоение имён и адресация[Электронный ресурс]. - URL:http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=125245 .

37. ГОСТ Р ИСО/МЭК 7498-4-99 ВОС. Базоваяэталонная модель. Часть 4. Основыадминистративного управления [Электронныйресурс]. - URL: http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=124253 .

38. ГОСТ Р ИСО/МЭК 12207-2010 Информационнаятехнология. Системная и программная инженерия.Процессы жизненного цикла программных средств[Электронный ресурс]. - URL:http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=169094 .

39. ГОСТ 34.601-90 Информационная технология.Комплекс стандартов на автоматизированныесистемы. Автоматизированные системы. Стадиисоздания [Электронный ресурс]. - URL:http://protect.gost.ru/v.aspx?control=8&baseC=-1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=129655 .

40. ГОСТ 19.701-90 Схемы алгоритмов, программ,данных и систем. Условные обозначения и правилавыполнения [Электронный ресурс]. - URL:http://protect.gost.ru/v.aspx?control=8&baseC=-

Page 520: В. Г. АБАШИН - Abashin.ruabashin.ru/books/c/c_draft.pdf · 2020. 2. 15. · 4 Синергия Си Введение 8 1. Базовые понятия и навыки 19

520

1&page=0&month=-1&year=-1&search=&RegNum=1&DocOnPageCount=15&id=129742 .

41. Dennis M. Ritchie and Ken Thompson "The UNIXTimesharing Operating System". Bell Laboratories[Электронный ресурс]. - URL:https://pdos.csail.mit.edu/6.828/2005/readings/ritchie74unix.pdf

42. UART: RS232 [Электронный ресурс]. - URL:https://www.camiresearch.com/Data_Com_Basics/RS232_standard.html

43. MD6 Message Digest 6 [Электронный ресурс]. -URL: https://ru.wikipedia.org/wiki/MD6 .

44. Циклический избыточный код (CRC8, CRC16,CRC32) [Электронный ресурс]. - URL:https://ru.wikipedia.org/wiki/Циклический_избыточный_код .

45. UML 2.4.1 принят в качестве международногостандарта ISO/IEC 19505-1, 19505-2 [Электронныйресурс]. - URL: https://www.omg.org/spec/UML/ .

46. Альт Линукс [Электронный ресурс]. - URL:http://altlinux.ru .

47. Форум сообщества Альт Линукс [Электронныйресурс]. - URL: http://forum.altlinux.ru .

48. Язык С/С++ (справочник на английском языке спримерами) [Электронный ресурс]. - URL:http://cplusplus.com .

49. Общение и трудоустройство сообществапрограммистов. [Электронный ресурс]. - URL:stackoverflow.com .