Содержимое заголовочного файла

Заголовочные файлы стандартной библиотеки языка С++

Содержимое заголовочного файла

Заголовочные файлы стандартной библиотеки языка С++ расположены в специальном каталоге (каталогах) включаемых файлов. Например, в IDE Microsoft Visual Studio C++ 6.0 таким каталогом является каталог ..Program FilesMicrosoft Visual StudioVC98Include. Классификация заголовочных файлов стандартной библиотеки языка С++ приведена на рис. П1.1.

Рис. П1.1

Функциональное назначение перечисленных на этом рис. заголовочных файлов указано в таблицах П1.1-П1.6.

Еще раз обращаем Ваше внимание на то, что заголовочные файлы без расширения определяют имена в пространстве имен std, а включаемые файлы с расширением .h определяют имена в глобальном пространстве имен.

Таблица П1.1. Заголовочные файлы, поддерживающие ввод-вывод

Функции ввода-вывода в стиле языка Си
Функции для работы с символами в стиле языка Си
Функции ввода-вывода в стиле языка Си для многобайтовых символов
Файловые потоки
Манипуляторы с параметрами
Базовые классы потоков ввода-вывода
Предварительное объявление средств ввода-вывода
Стандартные потоки и операции с потоками ввода-вывода
Входные потоки
Выходные потоки
Строковые потоки
Буферизация потоков Функции ввода-вывода в стиле языка Си

Таблица П1.2. Заголовочные файлы для работы со строками

Функции классификации символов
Функции для работы со строками в стиле языка Си
Функции для работы с символами в стиле языка Си
Строковый класс

Таблица П1.3. Заголовочные файлы для контейнерных классов

Битовое множество
Двусторонняя очередь
Двусвязный список
Словарь, словарь с дубликатами
Очередь, очередь с приоритетами
Множество, множество с дубликатами
Стек
Одномерный массив
Битовое множество
Двусторонняя очередь
Двусвязный список
Словарь, словарь с дубликатами
Очередь, очередь с приоритетами
Множество, множество с дубликатами
Стек
Одномерный массив

Таблица П1.4. Заголовочные файлы для алгоритмов, итераторов и утилит

Алгоритмы
Сортировка и поиск средствами библиотеки языка Си
Дата и время в стиле языка Си
Функциональные объекты
Итераторы
Распределение памяти для контейнеров
Операторы и пары

Таблица П1.5. Заголовочные файлы для численных расчетов

Математические функции
Комплексные числа
Случайные числа в стиле языка Си
Числовые операции
Классы для численных расчетов

Таблица П1.6. Заголовочные файлы для диагностики, поддержки языка, локализации и др.

Макрос assert
Обработка ошибок в стиле языка Си
Макросы предельных значений в стиле языка Си
Макросы предельных значений в стиле языка Си
Локализация в стиле языка Си
Обработка сигналов в стиле языка Си
Поддержка функций с переменным числом аргументов
Поддержка языка Си
Завершение программы
Системные часы
Поддержка исключений
Числовые ограничения
Классы локализации
Работа с динамической памятью
Стандартные исключения
Динамическая идентификация типов

Приложение 2. константы, макросы и типы данных стандартной библиотеки

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

assert                                                             ,<\p>

Макровызов assert( expression ); прерывает выполнение программы, если значение выражения expression является ложным (нулевым). При завершении программы выводится сообщение об ошибке вида:

Assertion failed:expression, file , line .

BUFSIZ                                                              ,<\p>

Константа BUFSIZ задает размер буфера потока данных в байтах. При открытии потока данных к нему автоматически присоединяется буфер длиной BUFSIZ байтов.

CHAR_BIT                                                        ,<\p>

Константа CHAR_BIT задает размер в битах для наиболее короткого типа данных (по стандарту – это тип char). Минимальное значение CHAR_BIT – 8 бит.

cin, cout, cerr, clog                                                        <\p>

Источник: https://vunivere.ru/work11869

“Клуб программистов” – материалы по Delphi и С++ » Blog Archive » УРОК 2. БОЛЕЕ ВНИМАТЕЛЬНЫЙ ВЗГЛЯД НА C++?>

  • Оператор # include обеспечивает преимущества использования заголовочных файлов, которые содержат операторы C++ или программные определения.
  • Основная часть программы на C++ начинается с оператора void main(void).
  • Программы состоят из одной или нескольких функций, которые, в свою очередь, состоят из операторов, предназначенных для решения определенной задачи.
  • При выводе на экран ваши программы будут широко использовать выходной поток cout.

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

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

Взгляд на операторы программы

В уроке 1 вы создали на C++ программу FIRST.CPP, которая содержала следующие операторы:

В данном случае программа содержит три оператора. Фигурные скобки (называемые группирующими символами) группируют связанные операторы:

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

Представление об операторе #include

Каждая программа, представленная в уроке 1, начинается со следующего оператора # include:

При создании программ на C++ вы получаете преимущества от использования операторов и определений, которые обеспечивает вам компилятор. При компиляции программы оператор # include заставляет компилятор включить содержимое заданного файла в начало вашей программы. В данном случае компилятор включит содержимое файлаiostream.h.

Файлы с расширением h, которые вы включаете в начало (или заголовок)вашей программы, называются заголовочными файлами.

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

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

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

Просто поймите, что оператор # include позволяет вам использовать эти файлы.

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

Что такое void main(void)

При создании программы на C++ ваш исходный файл будет содержать множество операторов.

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

Каждая программа на C++ имеет один вход, с которого начинается выполнение программы, — главную программу. В программах на C++ оператор void main(void) указывает стартовую точку вашей программы.

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

Использование void

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

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

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

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

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

Читайте также:  Co-потенциометр обратной связи

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

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

Значение статуса Смысл
Успех
1 Файл не найден
2 В принтере нет бумаги

Внутри командного файла MS-DOS вы можете проверить результат работы программы, используя команду IF ERRORLEVEL:

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

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

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

Представление о группирующих операторах { }

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

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

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

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

Использование cout для отображения вывода на экран

Все программы на C++, созданные вами в уроке 1, выводили сообщения на экран. Чтобы вывести сообщение, программы использовали cout и двойной знак «меньше» (

Источник: http://www.programmersclub.ru/02/

C: Заголовочные файлы

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

Заголовочные файлы подключаются к файлам исходного кода приложения по мере необходимости с помощью директивы #include.

#include “sums.h”

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

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

#ifndef SUMS_H
#define SUMS_H

#endif /*SUMS_H*/

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

#if x86_64
#include “system64.h”
#elif x86
#include “system32.h”
#endif

Пример

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

Это содержимое файла исходного кода hello.c:

Загрузить исходный код примера

Это — содержимое файла исходного кода hello.h:

Загрузить исходный код примера

А это — содержимое файла исходного кода hellomain.c:

Загрузить исходный код примера

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

$ gcc -c hello.c -o hello.o
$ gcc -c hellomain.c -o hellomain.o
$ gcc hello.o hellomain.o -o hello

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

Источник: https://linux-faq.ru/page/c-zagolovochnye-fajly

HEX и ASCII-дескрипторы заголовка файла: что это такое и чем они могут быть полезны

Все файлы на диске хранятся в виде двоичного (бинарного) кода. Последовательность цифр 1 и 0 определяет содержимое файла.

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

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

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

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

Эта часть отвечает за формат файла, для удобства назовем ее «дескриптор заголовка файла» (description с англ. – описание).

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

HEX и ASCII. Чтобы определить дескриптор заголовка файла и, соответственно, формат файла, необходима программа, которая представляет файл в виде HEX (шестнадцатеричного кода). Это может быть любой HEX-редактор. Но лучше всего для наших целей подойдет программа MiniDumper (20 Кб).

Скачиваем программу, распаковываем ее, открываем. Далее нажимаем кнопку «Select file…», выбираем файл и видим следующее:

Берем первые 2-3 блока из левой колонки (HEX) или первые символы (точки не учитываем) из правой колонки (ASCII), как показано на рисунке; вводим в соответствующее поле расширенного поиска и получаем результат:

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

ASCII (расширенный). ASCII с расширенной таблицей символов – кириллицей и специальными символами. Этот вариант специально создан для ленивых: просто откройте файл с помощью блокнота и ищите первые от начала значащие символы. Например:

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

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

Читайте также:  Память данных eeprom

Источник: https://open-file.ru/articles/file-header

Как оформлять модули [PIC24]

Available Languages?:

Скачать в PDF-формате

Виктор Тимофеев, июль, 2010 osa@pic24.ru

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

Итак, создается пара файлов с одинаковыми именами и с расширениями .c и .h (одинаковые имена – необязательное условие, но его нарушение приведет к путанице), например new_module.c и new_module.h. Формат и содержание их описан ниже.

//******************************************************************************
// Секция include: здесь подключается заголовочный файл к модулю
//******************************************************************************
 
#include “new_module.h” // Включаем файл заголовка для нашего модуля
 
//******************************************************************************
// Секция определения переменных, используемых в модуле
//******************************************************************************
 
//——————————————————————————
// Глобальные
//——————————————————————————
 
char GlobalVar1;
char GlobalVar2;

 
//——————————————————————————
// Локальные
//——————————————————————————
 
static char LocalVar1;
static char LocalVar2;

 
//******************************************************************************
// Секция прототипов локальных функций
//******************************************************************************
 
void local_func1 (void);
void local_func2 (void);

 
//******************************************************************************
// Секция описания функций (сначала глобальных, потом локальных)
//******************************************************************************
 
void global_func1 (void)
{ …;
}
 
void global_func1 (void)
{ …;
}
 

 
void local_func1 (void)
{ …;
}
 
void local_func1 (void)
{ …;
}
 

 
 
//******************************************************************************
// ENF OF FILE
//******************************************************************************

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

#ifndef _NEW_MODULE_H // Блокируем повторное включение этого модуля
#define _NEW_MODULE_H
 
//******************************************************************************
// Секция include: здесь подключаются заголовочные файлы используемых модулей
//******************************************************************************
 
#include
#include

 
 
//******************************************************************************
// Секция определения констант
//******************************************************************************
 
#define MY_CONST1 1
#define MY_CONST2 2
#define …
 
//******************************************************************************
// Секция определения типов
//******************************************************************************
 
typedef struct
{ …
} T_STRUCT;
 
typedef …
 
//******************************************************************************
// Секция определения глобальных переменных
//******************************************************************************
 
extern char GlobalVar1;
extern char GlobalVar2;
extern …
 
//******************************************************************************
// Секция прототипов глобальных функций
//******************************************************************************
 
void global_func1 (void);
void global_func2 (void);

 
//******************************************************************************
// Секция определения макросов
//******************************************************************************
 
#define MACRO1 …
#define MACRO2 …
#define …
 
#endif // Закрывающий #endif к блокировке повторного включения
 
//******************************************************************************
// ENF OF FILE
//******************************************************************************

  • Блокировка повторного включение этого модуля – один и тот же h-файл может быть включен в несколько модулей, которые также включают заголовочные файлы друг друга. Таким образом получается, что с точки зрения компилятора файл может быть включен в другой файл два или более раз. Тогда бы получалось, что все типы и константы также описаны более одного раза, что вызовет ошибку компилятора (переопределение констант, переопределение типов и т.п.). Чтобы этого не происходило, весь заголовочный файл заключается в скобки #ifndef…#endif. Если компилятор видит, что константа _NEW_MODULE_H не определена, то он включает весь текст файла, в котором, помимо всего прочего, и определяется константа _NEW_MODULE_H. При повторном включении файла компилятор уже видит, что эта константа включена, и все, что заключено в скобки #ifndef…#endif, будет им проигнорировано. (Примечание: имя константы _NEW_MODULE_H должно быть свое для каждого модуля. Для исключения путаницы и возможного повторения имен рекомендуется в качестве имени этой константы брать имя файла в верхнем регистре с суффиксом _H. Ннапример: в файле my_module.h определяем константу _MY_MODULE_H; в файле keyboard.h определяем константу _KEYBOARD_H и т.д.)
  • Секция include – здесь подключаются заголовочные файлы модулей, используемых нашим модулем.
  • Секция определения констант – определяются константы, используемые модулем (или определяющие режим работы модуля). Эти константы будут доступны как самому модулю, так и все модулям, включающим этот файл. Если какую-то константу нужно скрыть (например, она используется только в этом модуле, а есть вероятность, что в каком-нибудь стороннем модуле встретится константа с таким же именем), то ее определение можно перенести в основной файл.
  • Секция определения типов – здесь определяются все специфичные для этого модуля типы данных.
  • Секция определения глобальных переменных – здесь описываются переменные, которые будут доступны из других модулей. Следует обратить внимание на то, что в заголовочном файле переменные описываются с обязательным квалификатором extern.
  • Секция прототипов глобальных функций – Здесь описываются прототипы функций, которые будут видны другим модулям, чтобы компилятор знал, с какими параметрами их можно вызывать.
  • Секция определения макросов – здесь можно описать какие-то присущие модулю макроопределения.

Чтобы включить созданные файлы в свой проект нужно:

  1. В интегрированной среде добавить в проект оба файла (new_module.c и new_module.h). Можно ограничиться только си-файлом, но для удобства работы с рабочей областью (workspace) лучше добавлять оба. (Например, в MPLAB добавление файлов делается через меню: Project/Add Files to Project).

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

#include “new_module.h”

Примечание 1

  • Все секции, кроме “include” в си-файле и “блокировки повторного включения” в h-файле, являются необязательными, однако, даже если какой-то секции нет (например, в модуле нет локальных функций), то лучше комментарий, описывающий секцию оставить, чтобы при просмотре файла не возникало вопросов: а где эти локальные функции могут быть описаны? а вдруг они где-то в другом месте? и т.п. А так сразу видно, что есть секция, но она пустая, следовательно, локальных функций нет.

Примечание 2

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

Примечание 3

  • При необходимости можно добавлять другие секции (напрмер, иногда нужно описать несколько констант внутри основного си-файла).

Примечание 4

  • Обратим внимание, что в си-файле нет секции описания прототипов глобальных функций. Их туда можно было бы добавить, но получится, что они просто будут дублировать уже описанные прототипы в h-файле (тут они должны быть обязательно, иначе остальные модули не будут знать про эти функции). Это несколько неудобно, т.к. при смене спецификации функций исправления в прототипах придется делать в двух местах.
Читайте также:  Счётчик реактивной энергии

Источник: http://www.pic24.ru/doku.php/osa/articles/modules

Arduino.ru

Данный документ описывает создание библиотеки для Arduino. Объяснение начнется с написания скетча передачи кода Морзе посредством светодиода. Затем будет показано как конвертировать скетч в библиотеку. Это позволит другим пользователям легко использовать созданный код, обновлять и дополнять его.

Скетч, воспроизводящий код Морзе:

int pin = 13; void setup()
{ pinMode(pin, OUTPUT);
} void loop()
{ dot(); dot(); dot(); dash(); dash(); dash(); dot(); dot(); dot(); delay(3000);
} void dot()
{ digitalWrite(pin, HIGH); delay(250); digitalWrite(pin, LOW); delay(250);
} void dash()
{ digitalWrite(pin, HIGH); delay(1000); digitalWrite(pin, LOW); delay(250);
}

Данный скетч посредством мигания светодиода на выводе 13 выдает сигнал SOS.

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

Во-вторых, это переменная ledPin, определяющая какой порт ввод/вывода использовать.

И наконец, вызов функции pinMode(), устанавливающий режим вывода на используемом порту ввода/вывода.

Процесс конвертации скетча в библиотеку

Библиотека содержит два файла: заголовочный файл (с расширением .h) и файлы реализации (с расширением .cpp). Заголовочный файл содержит характеристики библиотеки, т.е. список всего что содержится в ней. Создаваемый заголовочный файл будет называться Morse.h. Для дальнейшей работы с заголовочным файлом необходимо просмотреть содержание файла реализации.

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

class Morse
{ public: Morse(int pin); void dot(); void dash(); private: int _pin;
};

Класс в данном случае это набор функций и переменных, объеденных в одном месте.

Функции и переменные могут быть публичными (public), что означает общий доступ к ним всех, кто использует библиотеку, или частными (private), что означает доступ к ним только внутри класса.

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

Также заголовочный файл содержит еще несколько дополнительных строк. Во-первых, это директива #include, которая дает доступ к стандартным типам и постоянным языка программирования Arduino (директива по умолчанию добавляется к каждому скетчу, но не к библиотеке). Директива выглядит следующим образом (и находится выше объявления класса):

#include “WProgram.h”

В версиях Arduino 1.0 и выше нужно еще добавить:

#include Arduino.h

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

#ifndef Morse_h
#define Morse_h // директивы #include и код помещается здесь #endif

Это предотвращает повторное подключение нашей библиотеки, если кто-то по ошибке дважды подключит библиотеку директивой #include.

В начале кода библиотеки принято помещать комментарий о ее предназначении, авторе, дате и лицензии на библиотеку.

Готовый заголовочный файл содержит:

/* Morse.h – Library for flashing Morse code. Created by David A. Mellis, November 2, 2007. Released into the public domain.
*/
#ifndef Morse_h
#define Morse_h #include “WProgram.h” class Morse
{ public: Morse(int pin); void dot(); void dash(); private: int _pin;
}; #endif

Рассмотрим файл реализации Morse.cpp.

В начале кода находятся несколько директив #include. Данными директивами разрешается доступ к стандартным функциям Arduino и к характеристикам в головном файле библиотеки:

#include “WProgram.h”
#include “Morse.h”

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

Morse::Morse(int pin)
{ pinMode(pin, OUTPUT); _pin = pin;
}

Код Morse:: означает, что функция принадлежит классу Morse.

 Нижний пробел в начале имени переменной _pin — принятое обозначение для частных переменных.

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

Далее код, который конвертируется в библиотеку из изначального скетча, добавилось только Morse:: и изменилось имя переменной с pin, на _pin:

void Morse::dot()
{ digitalWrite(_pin, HIGH); delay(250); digitalWrite(_pin, LOW); delay(250); } void Morse::dash()
{ digitalWrite(_pin, HIGH); delay(1000); digitalWrite(_pin, LOW); delay(250);
}

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

/* Morse.cpp – Library for flashing Morse code. Created by David A. Mellis, November 2, 2007. Released into the public domain.
*/ #include “WProgram.h”
#include “Morse.h” Morse::Morse(int pin)
{ pinMode(pin, OUTPUT); _pin = pin;
} void Morse::dot()
{ digitalWrite(_pin, HIGH); delay(250); digitalWrite(_pin, LOW); delay(250); } void Morse::dash()
{ digitalWrite(_pin, HIGH); delay(1000); digitalWrite(_pin, LOW); delay(250);
}

Использование библиотеки

Во-первых, необходимо создать папку Morse в подпапке libraries директории блокнота. Во-вторых, требуется скопировать файлы Morse.h и Morse.cpp в созданную папку.

После запуска программы Arduino в меню Sketch > ImportLibrary будет находиться библиотека Morse. Библиотека будет компилироваться совместно со скетчами, использующими ее.

Если при компиляции библиотеки возникли проблемы, то необходимо проверить, чтобы ее файлы были с расширениями .cpp и .h (не должно быть никаких дополнительных расширений .pde и .txt).

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

#include Morse morse(13); void setup()
{
} void loop()
{ morse.dot(); morse.dot(); morse.dot(); morse.dash(); morse.dash(); morse.dash(); morse.dot(); morse.dot(); morse.dot(); delay(3000);
}

Несколько отличий от изначального скетча:

Во-первых, добавлена директивы #include в начало скетча. Таким образом определяется доступность библиотеки Morse и ее подключение. Неиспользуемую библиотеку можно удалить, убрав директиву #include.

Во-вторых, создается экземпляр класса Morse, называемый morse:

Morse morse(13);

При выполнении данной строки (перед выполнением функции setup()) вызывается конструктор для класса Morse и принимает аргумент, данный в примере (13).

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

В-третьих, для вызова функций dot() и dash() необходимо прибавить префикс morse. – имя используемого экземпляра.

Может быть несколько экземпляров класса Morse, каждый со своим номером порта, хранящимся в локальной переменной _pin.

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

Morse morse(13);
Morse morse2(12);

внутри вызова morse2.dot(), переменная _pin будет иметь значение 12.

К сожалению автоматическая подсветка кода не работает с подключаемыми библиотеками. Для того чтобы подсветка заработала необходимо создать файл с названием keywords.txt. Пример:

Morse KEYWORD1
dash KEYWORD2
dot KEYWORD2

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

Созданную библиотеку желательно всегда сопровождают примером ее применения. Для этого создается папка examples в директории Morse. Затем копируется созданный ранее скетч SOS в данную папку.

(Файл скетча можно найти через меню Sketch > ShowSketchFolder). После перезапуска Arduino в меню File > Sketchbook > Examples будет находиться пункт Library-Morse, содержащий пример.

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

Источник: http://arduino.ru/Hacking/LibraryTutorial

Ссылка на основную публикацию
Adblock
detector