- •Часть 2. Модульное программирование
- •Екатеринбург
- •Введение
- •Функции Объявление и определение функций
- •Глобальные переменные
- •Возвращаемое значение
- •Параметры функции
- •Передача массивов в качестве параметров
- •Передача имен функций в качестве параметров
- •Параметры со значениями по умолчанию
- •Перегрузка функций
- •Правила описания перегруженных функций
- •Функции стандартной библиотеки
- •Функции ввода/вывода
- •Открытие потока
- •Ввод/вывод
- •Закрытие потока
- •Обработка ошибок
- •Функции работы со строками и символами
- •Математические функции
- •Директивы препроцессора
- •Директива #include
- •Директива #define
- •Директивы условной компиляции
- •Директива #undef
- •Предопределенные макросы
- •Области действия и пространства имен
- •Внешние объявления
- •Поименованные области
- •Библиографический список
- •Оглавление
- •Часть 2. Модульное программирование
- •620002, Екатеринбург, ул.Мира, 19
- •620002, Екатеринбург, ул.Мира, 19
Директива #define
Данная директива определяет подстановку в тексте программы. Она используется для определения:
- символических констант:
#define имя текст_подстановки;
- макросов, которые выглядят как функции, но реализуются подстановкой их текста в текст программы:
#define имя(параметры) текст_подстановки;
- символов, управляющих условной компиляцией. Эти символы используются вместе с директивами #ifdef #ifndef. Формат:
#define имя;
Примеры
#define VASIA "Василий"
#define MAX(x,y) ((x)>(y)? (x): (y))
Имена рекомендуется писать большими буквами, чтобы зрительно отличать их от имен переменных и функций. С макросом работают как с обычной функцией, например, макрос MAX может быть вызван как y=MAX(sum1,sum2); в тексте программы он будет заменен на выражение y= ((sum1)>(sum2)? (sum1): (sum2));
!!! Макросы и символические константы унаследованы из языка С, при написании программ на С++ лучше их избегать. Вместо символических констант лучше использовать const и enum, а вместо макросов − встроенные функции или шаблоны. Встроенную функцию определяют с помощью модификатора inline, который помещается перед типом функции. Код встроенной функции помещается в каждую точку вызова, это сокращает расходы на вызов функции.
Директивы условной компиляции
Директивы условной компиляции #if, #ifdef и #ifndef применяются для того, чтобы исключить компиляцию отдельных частей программы. Это бывает полезным при отладке или, например, при поддержке нескольких версий программы для различных платформ.
Формат директивы #if:
#if константное_выражение
...
[ #elif константное_выражение
...]
[ #elif константное_выражение
...]
[# else
...]
#endif
Количество директив #elif произвольное. Исключаемые блоки кода могут содержать как описания, так и исполняемые операторы.
Пример
#if 0 //временно закомментирован фрагмент кода
int i, j;
double x,y;
#endif
Директивы #ifdef и #ifndef часто применяются для того, чтобы управлять компиляцией в зависимости от того, определен ли с помощью директивы #define указанный ней символ (хотя бы как пустая строка).
Директива #ifndef часто применяется для того, чтобы обеспечить включение заголовочного файла только один раз (в случае многофайлового проекта возможно образование перекрестных ссылок на заголовочные файлы - это приведет к ошибке компиляции):
#ifndef HEADER_INCLUDED
# include "myheader.h"
#define HEADER_INCLUDED
#endif
Директива #undef
Данная директива удаляет определение символа.
Предопределенные макросы
В С++ определено несколько макросов, предназначенных в основном для того, чтобы выдавать служебную информацию
_DATE_ − содержит строку с текущей датой в формате день месяц год.
_FILE_ − содержит строку с полным именем текущего файла.
_LINE_ − текущая строка исходного текста.
_TIME_ − текущее время.
Пример
printf("Текущая дата -%s\n", _DATE_);
Области действия и пространства имен
Каждый программный объект имеет область действия, которая определяется видом и местом его объявления. Существуют следующие категории области действия: блок, файл, функция, прототип, класс и поименованная область действия.
Блок. Идентификаторы, описанные внутри блока, являются локальными. Область действия идентификатора начинается в точке определения и заканчивается в конце блока, видимость − в пределах блока и внутренних блоков, время жизни − до конца блока. После выхода из блока память освобождается.
Файл. Идентификаторы, описанные вне любого блока, функции или пространства имен, имеют глобальную видимость и постоянное время жизни.
Функция. Единственными идентификаторами, имеющими такую область действия, являются метки операторов. В одной функции все метки должны различаться.
Прототип функции. Идентификаторы, указанные в списке параметров прототипа (объявления функции), имеют областью действия только прототип функции.
Класс. Элементы структур, объединений и классов (за исключением статических элементов) являются видимыми лишь в пределах класса.
Поименованная область. С++ позволяет явным образом задать область определения имен как часть глобальной области с помощью оператора namespace.
В каждой области действия различают так называемые пространства имен. Пространство имен − это область, в пределах которой идентификатор должен быть уникальным. В разных пространствах имен имена могут совпадать, например:
struct Node {
int Node;
int i;
} Node;
В данном примере ощибки нет, поскольку имена типа, переменной и элемента структуры относятся к различным пространствам. В С++ определено четыре реальных класса идентификаторов, в пределах каждого из которых имена должны быть уникальными:
- имена переменных, функций, типов, определенных пользователем, и констант перечислений в пределах одной области видимости;
- имена типов перечислений, структур, классов и объединений;
- имена элементов каждой структуры, класса и объединения;
- имена меток.