
- •Оглавление
- •Лекция 1 Тема: Процесс построения программы.
- •Директивы #include
- •Комментарии
- •Лекция 2 Тема: Представление данных в с. Литералы
- •Встроенные типы данных
- •Типизированные константы
- •Операции и выражения
- •Семантика операций
- •Операции присваивания сама возвращает значение, что позволяет, например, написать:
- •Приведение типа
- •Смешанные выражения.
- •Поразрядные операции и сдвиги.
- •Инкремент и декремент
- •Запятая
- •Лекция 3 Управляющие конструкции с.
- •Условный оператор if... Else
- •Оператор выбора switch
- •1. Цикл while
- •2. Цикл do—while
- •3. Цикл for
- •Операторы прерывания блока
- •Escape-последовательности.
- •Лекция5 Функции
- •Задание
- •Лекция 6 Массивы и указатели
- •Последнее эквивалентно
- •Указатель на функцию
- •Лекция 7 Строки.
- •Лекция 8 Типы, определяемые пользователем.
- •Переименование типов.
- •Перечислимые типы
- •Структуры.
- •Объединения.
- •Лекция 9 Файлы.
- •Лекция 10 Связанные структуры.
- •Лекция 11 Директивы препроцессора
- •Условная компиляция
- •Директива #error
- •Директива # linе
- •Директива # pragma
- •Типичное применение препроцессорных директив Предотвращение включения файлов
- •Переключение разделов кода
- •Отладочные диагностические сообщения
- •Лекция 12 Тема: Состав проекта.
- •Лекция 13 Тема: Объектно-ориентированное программирование.
- •Лекция 14 Тема: Создание классов и их потомков. Перегрузка функций.
- •Лекция 15 Тема: Создание новых компонентов.
Лекция 11 Директивы препроцессора
Препроцессор входит в состав системы программирования С++ и обеспечивает обработку исходного текста программы перед ее компиляцией. В ходе препроцессорной обработки программы реализуются следующие действия:
выполняется подстановка макрорасширений вместо имен макросов и их аргументов;
в исходный текст программы включаются файлы, содержащие вспомогательную информацию (описание объектов, классов, прототипы функций и т.п.);
выполняется условная компиляция программы – определение окончательного вида исходного текста программы путем оставления или исключения отдельных ее фрагментов.
Задание препроцессору описывается с помощью директив препроцессора. Они начинаются со знака #, размещаемого в первой позиции строки.
Препроцессорная обработка позволяет сократить время разработки программ, пвысить их наглядность и мобильность. Например, при изменении характеристик аппаратно-программных средств достаточно изменить содержимое подключаемых файлов.
Макроопределения (макросы) определяются директивой препроцессора #define.
#define имя_макроса (список параметров) тело макроса
имя_макроса – задает имя вместо которого подставляется макрорасширение (при отсутствии параметров - тело макроса).
Можно выделить три формы макросов #define
простое определение символа;
определение символической константы;
определение макроса с параметрами.
Простое определение выглядит так:
#define H “Hello!”
#define M 100
#define kvadr(a) a*a
…….
char s(M); // расширяется в char s[100];
puts(H); //расширяется в puts(“Hello!”);
y=kvadr(x); //расширяется в y=x*x;
В сравнении с использованием функций макросредства позволяют уменьшить время выполнения программы путем исключения потерь на организацию передачи управления, но платой за это является увеличение размеров загрузочного модуля.
Если макрос задается с аргументами, то в отличие от функций, то контроль соответствия типов формальных и фактических параметров отсутствует. Например,
#define kvadr(a) a*a
int y,x=5,z,b=5;
y=kvadr(++x); //y=42; x=7;
z=pow(++b,2); //z=36; b=6;
При определении одни макросы могут ссылаться на другие.
#define PI 3.14159265
#define AREA(x) (PI *kvadr(x))
#define MAX(a, b) (<a)>(b) ? (a): (b)),circleArea = AREA(rl + r2);
Правило: каждый параметр и все определение в целом должны заключаться в скобки. Иначе при вхождении макроса в выражение могут появляться ошибки, связанные с различным приоритетом операций.
Рассмотрите такой случай:
#define SQR(x) х*х
binom = -SQR(a + b) ;
При расширении макроса получится: binom = -a + b*a + b;
Порядок оценки выражения окажется совсем не тем, что подразумевался.
В отличие от операторов С директивы препроцессора должны располагаться в одной строке, и поскольку это технически не всегда возможно для продолжения макроса на другой строке ставится \.
#define SHUTDOWN \
printf("Error!"); \
return -1
…
if (ErrorCondition()) SHUTDOWN; //Вызов макроса.
Операция конкатенации (##) в макросе с параметрами может обеспечить удаление всех символов между символами ##. В результате вызова макроса соответствующие аргументы объединяются в единую лексему, например:
#define con(k,r) k##-##r
con(y,2) //расширяется в y2
Определенный ранее макрос можно аннулировать директивой #undef:
#undef con
После этого макрос становится неопределенным, и последующие ссылки на него будут приводить к ошибке при компиляции.
В макросах может применяться специальная операция преобразования в строку (#). Если в расширении макроса параметру предшествует эта операция, то выражение-аргумент будет преобразовано в литеральную строку, заключенную в двойные кавычки. Вот один пример:
#define SHOWINT(var)
printf(#var " = %d\n", (int)(var))
int iVariable = 100;
SHOWINT(iVariable) ;
Последняя строчка расширяется и печатает iVariable = 100
printf("iVariable"" = %d\n", (int)(iVariable));
С примыкающие друг к другу литеральные строки при компиляции соединяются в одну строку.
Директива # include
Препроцессор заменяет директиву содержимым указанного в ней файла. Есть две ее формы:
#include <filename>
#include "filename"
В первом случае поиск нужного файла производится только в стандартных каталогах включаемых файлов; во втором случае этому предшествует поиск в текущем каталоге.
#include “a:\student\t1.txt”
Поиск файла выполняется в соответствии с указанной спецификацией. Если файл по спецификации не найден, то поиск его продолжается в текущем и стандартных каталогах.