- •Предисловие
- •Глава 1. Основные понятия
- •1.1. Элементы языка программирования
- •1.2. Процесс создания программы
- •1.3. Первая программа
- •1.4. Состав программы
- •Глава 2. Средства разработки на C++
- •2.1. Системы Turbo C++ 3.0/Borland C++ 3.1
- •2.2. Система C++ Builder
- •Глава 3. Работа с числовыми данными
- •3.1. Целые типы
- •3.2. Числа с плавающей точкой
- •3.3. Ввод и вывод чисел
- •3.4. Логический тип и логические операции
- •3.5. Математические функции
- •Глава 4. Операторы. Ключевые слова
- •4.1. Операторы
- •4.2. Приоритеты операторов
- •4.3. Ключевые слова
- •4.4. Структура программы
- •4.5. Константы
- •Задачи - . Простейшие вычисления
- •Глава 5. Управление и циклы
- •5.1. Условный оператор
- •5.2. Операторы цикла
- •5.3. Переключатель
- •5.4. Операторы break и continue
- •Задачи -. Выбор и циклы
- •Глава 6. Массивы
- •6.1. Одномерные массивы
- •6.2. Двумерные массивы
- •Задачи -. Одно- и двумерные массивы
- •Глава 7. Функции
- •7.1. Определение функции
- •7.2. Формальные параметры и фактические аргументы
- •7.3. Автоматические и статические переменные
- •7.4. Прототипы функций
- •7.5. Массивы как аргументы функций
- •7.6. Внешние переменные
- •7.7. Рекурсия
- •7.8. Перегруженные имена функций
- •7.9. Аргументы функций по умолчанию
- •Задачи -. Функции
- •Глава 8. Символы и строки
- •8.1. Символы
- •8.2. Строки символов
- •Задачи -. Символы и строки
- •Глава 9. Препроцессор
- •9.1. Директивы препроцессора
- •9.2. Макросы
- •Задачи -. Макросы
- •Глава 10. Указатели и ссылки
- •10.1. Указатели и адреса
- •10.2. Указатели и массивы
- •10.3. Адресная арифметика
- •10.4. Символьные указатели
- •10.5. Массивы указателей
- •10.6. Указатели на функции
- •10.7. Ссылки
- •10.8. Операторы new и delete
- •Задачи -. Указатели и ссылки
- •Глава 11. О файлах и командной строке
- •11.1. Знакомство с файлами
- •11.2. Командная строка
- •11.3. Перенаправление стандартного ввода и вывода на файл
- •11.4. Аргументы командной строки
- •Задачи -. Файлы и командная строка
- •Глава 12. Работа с экраном дисплея
- •12.1. Текстовый режим
- •12.2. Графический режим
- •Задачи -. Работа с экраном
- •Глава 13. Внутреннее представление чисел
- •13.1. Двоичная система счисления
- •13.2. Беззнаковые целые
- •13.3. Двоичный дополнительный код
- •13.4. Двоичный код с избытком
- •13.5. Побитовые операторы
- •13.6. Дробные числа в двоичной системе
- •13.7. Внутреннее представление плавающих типов
- •13.8. Преобразование типов
- •Задачи -. Побитовые операторы
- •Глава 14. Структуры, перечисления, объединения
- •14.1. Объявление структур
- •14.2. Структуры и функции
- •14.3. Указатели на структуры
- •14.4. Массивы структур
- •14.5. Перечисления
- •14.6. Объединения
- •14.7. Битовые поля
- •14.8. О бинарных файлах
- •Задачи -. Структуры
- •Глава 15. Классы
- •15.1. Структуры в C++. Инкапсуляция
- •15.2. Встроенные функции
- •15.3. Классы. Скрытие данных
- •15.4. Конструкторы
- •15.5. Статические члены класса
- •15.6. Друзья класса
- •15.7. Копирование объектов класса
- •15.8. Управление доступом
- •15.9. Ссылка на себя
- •15.10. Деструкторы
- •Задачи -. Работа с классами
- •Глава 16. Программы из нескольких файлов
- •16.1. Работа с проектами
- •16.2. Область действия имен
- •16.3. Заголовочные файлы
- •16.4. Пространства имен
- •Задачи -. Работа со стеком
- •Глава 17. Перегрузка операторов
- •17.1. Правила перегрузки операторов
- •Задачи -. Перегрузка операторов
- •Глава 18. Конструктор копирования и оператор присваивания
- •18.1. Проблемы при копировании
- •Задачи -. Конструктор копирования
- •Глава 19. Ввод и вывод
- •19.1. Вывод
- •19.2. Ввод
- •19.3. Ввод и вывод определяемых пользователем типов
- •19.4. Работа с файлами
- •Глава 20. Взаимоотношения классов
- •20.1. Объекты как члены класса
- •20.2. Конструкторы встроенных типов
- •20.3. Наследование
- •20.4. Виртуальные функции
- •20.5. Абстрактные классы
- •20.6. Совместимость типов
- •20.7. Множественное наследование
- •Задачи -. Наследование классов
- •Глава 21. Шаблоны, исключения
- •21.1. Шаблоны
- •21.2. Шаблоны функций
- •21.3. Классы и шаблоны
- •21.4. Обработка исключений
- •21.5. Стандартная библиотека шаблонов
- •Литература
- •Предметный указатель
112
Глава 9. Препроцессор
Препроцессор готовит текст программы к его последующей обработке компилятором: удаляет комментарии и выполняет директивы препроцессора, которыми являются строки, начинающиеся со знака #.
Как правило, препроцессор встроен в компилятор, но существуют и автономные препроцессоры, с помощью которых можно получить файл, обработанный препроцессором.
9.1. Директивы препроцессора
Директивы препроцессора имеют следующий формат
# [имя_директивы] [лексемы_препроцессора]
Препроцессор не относится к языку программирования, его назначение состоит в обработке исходного текста программы, поэтому препроцессорные лексемы не совпадают с рассмотренными ранее лексемами языка C++. Набор препроцессорных лексем включает: символьную константу, имя объекта-заголовка, идентификатор, знак операции, препроцессорное число, строку символов и каждый символ, не являющийся пробелом, который нельзя отнести к перечисленным выше.
При записи директив допускаются пробелы перед знаком #, между этим знаком и именем директивы, а также перед лексемами препроцессора, между ними и после них.
Директивы могут стоять в любом месте программы, они оказывают влияние от точки их появления до конца транслируемой компоненты.
Директивы препроцессора перечислены в табл.31.
|
Таблица 32. Директивы препроцессора |
|
|
Имя |
Назначение |
#define |
Определение макроса |
#undef |
Отмена определения макроса |
#include |
Подстановка текста из внешнего файла |
#if |
Компиляция, если выражение истинно |
#ifdef |
Компиляция, если макрос определен |
#ifndef |
Компиляция, если макрос не определен |
#else |
Альтернатива для #if, #ifdef, #ifndef |
#elif |
Составная директива else/if |
#endif |
Окончание группы компиляции по условию |
#line |
Замена новым значением номера строки или имени текущего файла |
|
|
Препроцессор 113 |
|
|
|
|
|
|
|
|
|
|
#error |
Прерывает компиляцию с выдачей сообщения об ошибке |
|
|
#pragma |
Действие определяется реализацией системы программирования |
#Пустая директива
Директивы препроцессора можно располагать в нескольких строках, используя в качестве знака переноса символ обратной наклонной черты (\), то есть можно, например, писать:
#include \ <iostream.h>
Директива #pragma имеет следующий синтаксис:
#pragma ДИРЕКТИВА_pragma
Различные реализации языка C++ имеют различные наборы команд ДИРЕКТИВА_pragma, учитывающие конкретные особенности компилятора и операционной системы.
9.2. Макросы
Макросом или макроопределением называется идентификатор, связанный директивой #define с лексемой или последовательностью лексем. Определение макроса имеет вид:
#define МАКРОС ЗНАЧЕНИЕ
Здесь МАКРОС – это имя макроса. В имени макроса пробелы не допускаются. Препроцессор заменяет всякое вхождение макроса в текст программы значением, связанным с ним директивой #define, всюду от точки его определения в программе до конца файла. Если макрос входит в состав символьной или строковой константы, то замена не производится. Например, в стандартном заголовочном файле math.h определены макросы M_E и M_PI для чисел e и π, округленные до 21 значащей цифры:
#define M_E |
2.71828182845904523536 |
#define M_PI |
3.14159265358979323846 |
Строку программы: y = sin(M_PI / 3) / M_E;
препроцессор преобразует в строку:
y = sin(3.14159265358979323846 / 3) / 2.71828182845904523536;
которую затем будет обрабатывать компилятор.
Имеется возможность определять макросы с параметрами. Пример такого макроса приведен в программе 24.
114 9
Стандартом языка C++ предусмотрено несколько встроенных макросов, часть из них перечислена в табл.33.
|
|
|
Препроцессор |
115 |
|
|
|
|
|
|
|
|
|
Таблица 34. Встроенные макросы языка C++ |
|
|
|
|
|
|
|
|
|
|
Макрос |
|
Описание |
|
|
|
_ _ DATE_ _ |
|
Строка, представляющая в форме mmm dd yyyy дату, когда |
|
|
|
|
|
данный файл обрабатывался препроцессором |
|
|
|
_ _ FILE_ _ |
|
Строка, представляющая имя текущего файла |
|
|
|
_ _ LINE_ _ |
|
Целое, равное номеру текущей строки исходного файла |
|
|
|
_ _ TIME_ _ |
|
Строка, представляющая в форме hh:mm:ss время, когда данный |
|
|
|
|
|
файл обрабатывался препроцессором |
|
|
|
|
|
|
|
|
Кроме стандартных макросов, системы программирования могут включать специфичные для них макроопределения, которые можно изучить по документации.
Программа 24. Возможности препроцессора
Приводимая далее программа дает образцы использования различных директив препроцессора.
//Файл Preproc.cpp.
//Демонстрация работы директив препроцессора #include <iostream.h>
#include <conio.h>
/* greater_than(a,b) - макрос с параметрами, проверяющий, больше ли первый аргумент второго? Аргументы в определении макроса следует заключать в скобки во избежание ошибок */
#define greater_than(a,b) |
((a) > (b) ? 1 : 0) |
#define SMALL |
// SMALL - пустой макрос |
void main() |
|
{ |
|
int c = 5, d = 7; |
|
if(greater_than(c, d)) |
|
cout << "\nc больше d"; |
|
else |
|
cout << "\nc меньше d"; |
|
#ifdef SMALL |
// Использование директивы ifdef |
cout << "\nМакрос SMALL определен"; |
|
#else |
|
cout << "\nМакрос SMALL не определен"; |
|
#endif |
|
#undef SMALL |
// Отмена определения макроса SMALL |
#ifndef SMALL |
// Использование директивы ifndef |
cout << "\nМакрос SMALL не определен"; #else
cout << "\nМакрос SMALL определен"; #endif