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

Презентация:



Advertisements
Похожие презентации
Условная компиляция Условная компиляция C / С++Pascal Условная компиляция выполняется с помощью специальных директив и позволяет выборочно компилировать.
Advertisements

Лекция 10 Препроцессор. Препроцессор языка Си Препроцессор работает на первом шаге компиляции. Директивы препроцессора: #include#define#undef #ifdef#if#else.
Тема урока Переменная. Тип данных. Ввод и вывод данных.
ЦИКЛИЧЕСКИЙ АЛГОРИТМ Цели: -Познакомиться с понятием циклического алгоритма. -Освоить языковые средства для реализации циклических алгоритмов.
Объектно-ориентированный язык программирования. Переменная - эта поименованная ячейка памяти, хранящая какое-либо одно значение (одно число, один фрагмент.
Обработка исключительных ситуаций Исключительная ситуация (исключение) – это ошибка, возникающая во время выполнения программы. Например, ошибка работы.
Урок по теме: «Условный оператор» Автор: Алексеева Е.В., Учитель информатики и ИКТ МОУ «Сланцевская СОШ 3» 2/1/2014.
Лекция 7. Структура языка С/С++. Операторы ветвления: условный оператор if. Полное ветвление. Неполное ветвление. Оператор множественного выбора switch.
Глава 6. УПРАВЛЯЮЩИЕ СТРУКТУРЫ Оператор присваивания Простой и составной операторы Условный оператор Оператор множественного выбора Оператор цикла с предусловием.
Презентация на тему: «Программирование Разветвляющихся структур». Составила: учитель информатики Чура Н.А. 1.
Тема: Управление потоком в PHP Изучить возможности языка PHP при решении задач, требующих использования условного оператора. Рассмотреть примеры управления.
1 Организация программ разветвляющейся структуры. Организация программ разветвляющейся структуры. Условный оператор.
Шутилина Л.А. В жизни часто приходится принимать решения в зависимости от сложившейся ситуации, когда нужно сделать тот или иной.
Лекция 4 Программирование на Паскале. Элементы языка Турбо Паскаль 7.0. Типы данных. Управляющие конструкции.
Тема урока: Виды алгоритмов и их реализация. Образовательные задачи: 1. Ввести понятия: полная форма ветвления и условный оператор ветвления. 2. Научить.
Теперь, когда вы постигли азы программирования, будем учиться писать программы, которые позволяют вести диалог между компьютером и человеком (пользователем).
Символьный тип данных Char. Оператор варианта case.
Понятие переменной Переменная – это величина, которая изменяется в процессе работы программы. Для описания переменной следует указать имя переменной,
Ключевая тема этого задания ЕГЭ – использование вложенных условных операторов, причем в тексте задания фрагмент программы обычно записан без отступов «лесенкой»
Понятие оператора и программы 11 класс. Программирование.
Транксрипт:

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

Директива #define Эта директива, позволяющая присваивать текстовым строкам символические имена, может иметь один из следующих форматов: #define identifier или #define identifier(parameter-list) где угловыми скобками ( ) обозначена необязательная часть конструкций Первая форма интерпретируется препроцессором как простая литеральная подстановка, выполняемая перед фактическим обращением к компилятору Вторая служит для создания макроопределений, семантически подобных определению обычных функций

Замена выполняется лишь для отдельно стоящих имен и не имеет места в тех случаях, когда identifier входит в состав текстовых строк или является составной частью более длинного идентификатора Список аргументов parameter-list включает в себя один или большее число формальных параметров, разделенных запятыми и имеющих уникальные имена. В этом случае препроцессор заменяет имена параметров, входящие в text, именами соответствующих фактических аргументов, и лишь после этого будет выполнена реальная подстановка текста на место идентификатора Символьная строка text может иметь произвольную длину, возможно даже превосходящую длину одной строки экрана Для формирования длинного текста необходимо набрать символ \, нажать клавишу Enter и продолжить ввод символов с начала новой экранной строки С другой стороны, параметр text может вообще отсутствовать в составе директивы, что соответствует определению идентификатора identifier без присвоения ему какого-либо конкретного значения

Приведем несколько примеров использования директивы #define для задания имен текстовых цепочек и формирования макроопределений функций 1. Наиболее характерным применением этой директивы является назначение символических имен констант: #define WIDTH 100 #define LENGTH (WIDTH + 30) Здесь идентификатор WIDTH объявлен числовой константой, равной 100, а имя LENGTH определено при помощи WIDTH и целого числа 30, причем круглые скобки во втором случае являются существенными

2. Программисты, желающие видеть свою программу синтаксически похожей, например, на исходный текст программы на языке типа Паскаль или Алгол, могут воспользоваться директивой #define для замены ключевых слов и специальных символов, принятых в языке Си: #define begin { #define end ;} #define integer int #define real float #define then В этом примере последняя инструкция определяет идентификатор then, не присваивая ему никакого значения. Эффектом такого определения является простое извлечение из текста программы всех вхождений имени then, что позволяет записать условный оператор в таком виде if (a >= b) then begin max = a; min = b; end не нарушая тем самым синтаксических правил языка Си

3. Вместо определения функции abs(x), вычисляющей абсолютную величину переменной x, в программе можно иметь семантически эквивалентное ему макроопределение вида #define abs(x) ((x) >= 0) ? (x) : (-x) обращение к которому внешне ничем не будет отличаться от обращения к обычной функции Директива #define может встречаться в произвольном месте файла, содержащего исходный текст Си-программы, однако обычно их принято помещать в начало этого файла

Директива #undef Данная директива имеет формат #undef identifier и заставляет препроцессор игнорировать все последующие вхождения определенного ранее в инструкции #define имени identifier Это позволяет ограничить область исходной программы, в пределах которой identifier обрабатывается препроцессором и имеет специальное значение

В следующум примере область действия идентификаторов WIDTH и ADD ограничена лишь частью исходного файла, в пределах которой они принимаются во внимание препроцессором языка Си: #define WIDTH 100 #define ADD(x, y) (x) + (y)... #undef WIDTH #undef ADD... Инструкция #undef может быть помещена в произвольное место файла, содержащего исходный текст программы

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

Если pathname задает полное имя файла от корневого каталога, то две приведенные выше формы записи директивы эквивалентны В том же случае, когда задано относительное имя файла, использование двойных кавычек ( " " ) заставляет препроцессор прежде всего искать требуемый файл в текущем каталоге, затем просматривать каталог, определенный в команде вызова компилятора и, наконец, в случае необходимости продолжить поиск в стандартном каталоге Однако при заключении имени файла в угловые скобки текущий каталог не просматривается Препроцессор допускает последовательные вложения инструкций #include максимально до десяти уровней. Это означает, что всякий файл, подключаемый с помощью этой директивы, может содержать внутри себя новое обращение к #include В составе исходного текста программы директива #include может размещаться в произвольном месте содержащего ее файла

Директивы #if, #ifdef, #ifndef, #else, #elif и #endif Директивы #if, #ifdef, #ifndef, #else, #elif и #endif используются для условной избирательной компиляции различных фрагментов программы Главная идея состоит в том, что если выражение, стоящие после директив #if, #ifdef и #ifndef, оказывается истинным, то будет скомпилирован код, расположенный между одной из этих трех директив и директивой #endif. В противном случае данный код будет опущен Директива #endif используется для обозначения конца блока Директиву #else можно использовать с любой из перечисленных выше директив для предоставления альтернативного варианта компиляции

Общая форма записи директивы #if : #if константное выражение Если константное_выражение является истинным, будет скомпилирован код, расположенный непосредственно за этой директивой Общая форма записи директивы #ifdef : #ifdef имя_макроса Если имя_макроса определено в операторе #define, то будет скомпилирован блок кода, следующий за оператором #ifdef

С помощью директив #if и #elif и оператора препроцессорной обработки #defined можно также выяснить, определено ли имя конкретного макроса директивой препроцессора #define. Для этого используется следующая общая форма записи: #if defined имя_макроса последовательность операторов #endif Если имя_макроса определено, последовательность_операторов будет скомпилирована. В противном случае она будет опущена Оператор #defined можно также предварить оператором отрицания (!), и тогда условная компиляция будет выполнена в том случае, если заданное имя макроса не определено

Например: чтобы застраховаться от повторного включения заголовочного файла hdr.h, его можно оформить следующим образом: #if !defined(HDR) #define HDR /* здесь содержимое hdr.h */ #endif При первом включении файла hdr.h будет определено имя HDR, а при последующих включениях препроцессор обнаружит, что имя HDR уже определено, и перескочит сразу на #endif Этот прием может оказаться полезным, когда нужно избежать многократного включения одного и того же файла. Если им пользоваться систематически, то в результате каждый заголовочный файл будет сам включать заголовочные файлы, от которых он зависит, освободив от этого занятия пользователя.

Общая форма записи #ifndef имя_макроса : #ifndef имя_макроса Если имя_макроса не определено в операторе #define, то будет скомпилирован блок кода, следующий за оператором #ifndef #ifndef HDR #define HDR /* здесь содержимое hdr.h */ #endif

Общая форма записи директивы #elif : #elif выражение_константа Данная директива используется для создания оператора if-else-if Для обработки сразу нескольких альтернатив можно использовать ряд директив #elif

Вот пример цепочки проверок имени SYSTEM, позволяющей выбрать нужный файл для включения: #if SYSTEM == SYSV #define HDR "sysv.h" #elif SYSTEM == BSD #define HDR "bsd.h« #elif SYSTEM == MSDOS #define HDR "msdos.h" #else #define HDR "default.h" #endif #include HDR

Директива #line Директива #line используется для изменения содержимого псевдопеременных __LINE__ и __FILE__, которые являются зарегистрированными идентификаторами. Общая форма записи директивы: #line номер "имя_файла" Здесь номер - это любое положительное число, а имя файла - любой допустимый идентификатор файла. Значение элемента номер становится номером текущей исходной строки, а значение элемента имя_файла - именем исходного файла. Имя файла - элемент необязательный Директива #line используется, главным образом, в целях отладки и в специальных приложениях.

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

Директива #pragma Работа директивы #pragma зависит от конкретной реализации компилятора. Она позволяет выдавать компилятору различные инструкции. Например, компилятор способен поддерживать трассировку выполнения программы. Заставить компилятор работать в режиме трассировки можно именно с помощью оператора #pragma. Общая форма записи: #pragma ("директива") Здесь элемент директива означает задаваемую инструкцию (прагму) Компилятор Си, в котором данная команда не реализована, ее игнорирует