Автор: Пользователь скрыл имя, 02 Декабря 2011 в 09:03, реферат
Хотя Turbo C++ использует использует интегрированный однопроходный компилятор как при работе в интегрированной среде разработки (IDE), так и при вызове компилятора из командной строки, полезно тем не менее сохранить терминологию, сохранившуюся от более ранних, многопроходных компиляторов. В случае последних на первом проходе обработки исходного текста программы выполняется подключение всех имеющихсявключаемых файлов, проверка всех условных директив компиляции, расширение всех имеющихся макросов и получение промежуточного файла для обработки последующими проходами компилятора. Посколькукак интегрированная среда разработки, так и версия командной строки Turbo C++ выполняют первый проход, не создаваяпри этом каких-либо промежуточных файлов, Turbo C++ включаетв себя независимый препроцессор, CPP.EXE, который имеет на выходе такой промежуточный файл. CPP полезен на стадии отладки, посколькупоказывает в чистом виде результаты работы директив включения, условных директив компиляции и сложных макрорасширений.
Министерство образования и науки РФ
Государственное образовательное учреждение высшего профессионального образования
ДАГЕСТАНСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра
ММвЭ
Реферат
На
тему: Директивы процессора в С++
Выполнил:
ст. курса, И912 гр. Келеметов С.Ш.
Руководитель практики:
Зав. каф.
Махачкала 2011 г.
Директивы препроцессора Turbo C++
Хотя Turbo C++ использует использует интегрированный однопроходный компилятор как при работе в интегрированной среде разработки (IDE), так и при вызове компилятора из командной строки, полезно тем не менее сохранить терминологию, сохранившуюся от более ранних, многопроходных компиляторов. В случае последних на первом проходе обработки исходного текста программы выполняется подключение всех имеющихсявключаемых файлов, проверка всех условных директив компиляции, расширение всех имеющихся макросов и получение промежуточного файла для обработки последующими проходами компилятора. Посколькукак интегрированная среда разработки, так и версия командной строки Turbo C++ выполняют первый проход, не создаваяпри этом каких-либо промежуточных файлов, Turbo C++ включаетв себя независимый препроцессор, CPP.EXE, который имеет на выходе такой промежуточный файл. CPP полезен на стадии отладки, посколькупоказывает в чистом виде результаты работы директив включения, условных директив компиляции и сложных макрорасширений.
CPP позволяет обращение к документации по нему в диалоговом режиме.
Следующее обсуждение директив препроцессора, их синтаксис и семантика, применимы, следовательно, как к самому препроцессору CPP, так и к его функциям, встроенным в компиляторы Turbo C++.
Препроцессор
находит директивы
Препроцессор Turbo C++ включаетв себя сложный процессор макросов, сканирующий исходный код перед обработкойего компилятором.Препроцессор обеспечивает мощные средства и гибкость, заключающиеся в следующем:
-
Определение макросов, которые служат
для снижения трудоемкости
-
Включение текстов из других
файлов, таких как файлы заголовка,
в которых содержатся
-
Установка условной компиляции
для улучшения мобильности
Директивы препроцессора обычно помещаются в начало исходного кода, но допустимы в любой точке программы.
Любая
строка с ведущим символом # рассматриваетсякак
директива препроцессора, еслитолько#
не входит в строковый литерал, символьную
константу или комментарий. Ведущему символу
# может предшествовать, либо следовать
за ним,пробельные символы (за исключением
символа новой строки).
файл-для-препроцессора:
группа
группа:
часть группы
группа часть-группы
часть-группы:
<лексемы-препроцессора> новая-строка
if-раздел
управляющая строка
if-раздел:
if-группа <elif-группы> <else-группа> endif-строка
if-группа:
#if выражение-типа-константы новая-строка <группа>
#ifdef идентификатор новая-строка <группа>
#ifndef идентификатор новая-строка <группа>
elif-группы:
elif-группа
elif-группы elif-группа
elif-группа:
#elif выражение-типа-константы <группа>
else-группа:
#else новая-строка <группа>
endif-строка:
#endif новая-строка
управляющая-строка:
#include лексемы-препроцессора новая-строка
#define идентификатор список-замены новая-строка
#define идентификатор левая-круглая-
<список-идентификаторов>) список-замены новая-строка
#undef идентификатор новая-строка
#line <лексемы-
#pragma <лексемы-
#pragma warn действие сокращение новая-строка
#pragma inline новая-строка
? новая-строка
действие: одно из
+ - .
сокращение:
amb ampapt aus big cincpt
def dupelf mod par piapro
rch retrng rpt rvf sigstr
stu stvsus ucp use volzst
левая-круглая-скобка:
символ левой круглой скобки без предшествующих пробельных символов
список-замены:
<лексемы-препроцессора>
лексемы-препроцессора:
имя-заголовка (только для директивы #include)
идентификатор (без различения ключевого слова)
константа
строковый-литерал
операция
пунктуатор
любой не-пробельный символ, не относящийся к предыдущим пунктам
имя-заголовка:
<последовательность-
последовательность-
символ-заголовка
последовательность-
символ-заголовка:
любой
символ из исходного множества символов,
за исключением символа новой-
новая-строка:
символ новой строки
Пустая директива #
Пустая директива состоитиз строки, вкоторой содержится единственныйсимвол #. Эта директива всегда игнорируется препроцессором.
Директивы #define и #undef
Директива #define определяет макрос. Макросы обеспечивают механизм замены лексемы набором формальных, подобных используемых в функциях параметров, либо пустой замены.
Простые макросы #define
В простых случаях, без параметров, синтаксис данной директивы следующий:
#define идентификатор_макроса <последовательность_лексем>
Каждое
вхождение идентификатора_
Любые
вхожденияидентификаторамакроса
Пустая последовательность лексем позволяетэффективное удаление всех найденных идентификаторов макросов из исходного кода:
#define HI "Добрый день!"
#define empty
#define NIL ""
...
puts(HI); /* расширяется в: puts("Добрый день!"); */
puts(NIL); /* расширяется в: puts(""); */
puts("empty"); /* расширения empty не происходит ! */
/* расширение empty не будет выполнено и в комментариях! */
После расширения каждого конкретного макроса дальнейшее сканирование продолжится уже для нового, расширенного текста. Это дает возможность организации вложенных макросов: расширенный текст может в свою очередь содержать подлежащие расширению идентификаторы макросов. Однако, если макрос при расширении образует директиву препроцессора, то такая директива препроцессором уже не распознается:
#define GETSTD #include <stdio.h>
...
GETSTD /* ошибка компиляции */
GETSTD будет расширен в #include<stdio.h>. Однако, препроцессор не станет сам обрабатывать эту вполне допустимую в других условиях директиву, а передаст ее в таком виде компилятору. Компилятор воспримет#include <stdio.h> как недопустимый ввод. Макрос не может быть расширен во время собственногорасширения. Поэтому выражения типа #define A A недопустимы вследствие неопределенности результата.
Директива #undef
Можно отменить определение макроса при помощи директивы #undef:
#undef идентификатор_макроса
Данная строка удаляетлюбую ранее введенную последовательность лексем из идентификатора макроса;определение макроса теряется, и идентификатор его становится неопределенным.
Макрорасширения внутри строк #undef не выполняются.
Состояние определенности и неопределенности является важным свойством идентификатора, независимо от его фактического определения. Условные директивы препроцессора #ifdef и #ifndef, которые служат для проверки того, является ли идентификатор в текущий момент определенным, или нет, представляют собой гибкий механизм управления многими аспектами компиляции.
После
того, как идентификатор
неопределенным,
он может бытьдалеепереопределендиректив
#define, с использованием той же самой или другой последовательности лексем.
#define BLOCK_SIZE 512
...
buff = BLOCK_SIZE*blks; /* расширяется в: 512*blks */ ...
#undef BLOCK_SIZE
/* использование BLOCK_SIZE теперь невозможно - это "неизвестный" препроцессору идентификатор */
...
#define BLOCK_SIZE 128 /*переопределение размера блока*/
...
buf = BLOCK_SIZE*blks; /* расширяется в: 128*blks */
...
Попыткапереопределения уже определенного идентификатора макроса приведет к сообщению уровня предупреждения, если только новоеопределения не повторяет текущее с точностью до последней лексемы. Предпочтительный способ работы с теми же определениями в других файлах заголовка следующий:
#ifndef BLOCK_SIZE
#define BLOCK_SIZE 512
#endif
Если
идентификатор BLOCK_SIZE в текущий момент
определен, то средняя строка не обрабатывается
препроцессором; в противном же случае
выполняется определение
Отметим,что директива препроцессора не должна заканчиваться точкой с запятой (;). Любые символы, найденные препроцессором в последовательности лексем, включая точки с запятой, появятся в макрорасширениях. Последовательность лексем заканчивается первой встреченной новой строкой без предшествующего символа обратной наклонной черты. Любая последовательность пробельных символов, включая комментарии в последовательности лексем, заменяется на один символ пробела.