Директивы процессора в С++

Автор: Пользователь скрыл имя, 02 Декабря 2011 в 09:03, реферат

Описание работы

Хотя Turbo C++ использует использует интегрированный однопроходный компилятор как при работе в интегрированной среде разработки (IDE), так и при вызове компилятора из командной строки, полезно тем не менее сохранить терминологию, сохранившуюся от более ранних, многопроходных компиляторов. В случае последних на первом проходе обработки исходного текста программы выполняется подключение всех имеющихсявключаемых файлов, проверка всех условных директив компиляции, расширение всех имеющихся макросов и получение промежуточного файла для обработки последующими проходами компилятора. Посколькукак интегрированная среда разработки, так и версия командной строки Turbo C++ выполняют первый проход, не создаваяпри этом каких-либо промежуточных файлов, Turbo C++ включаетв себя независимый препроцессор, CPP.EXE, который имеет на выходе такой промежуточный файл. CPP полезен на стадии отладки, посколькупоказывает в чистом виде результаты работы директив включения, условных директив компиляции и сложных макрорасширений.

Работа содержит 1 файл

Директивы препроцессора Turbo C.docx

— 48.44 Кб (Скачать)

Министерство  образования и  науки РФ

Государственное образовательное  учреждение высшего  профессионального  образования

ДАГЕСТАНСКИЙ  ГОСУДАРСТВЕННЫЙ  ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Кафедра ММвЭ 

Реферат

На  тему: Директивы процессора в С++  
 
 

Выполнил:

ст. курса, И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)

   идентификатор (без различения ключевого слова)

   константа

   строковый-литерал

   операция

   пунктуатор

   любой не-пробельный символ, не относящийся к предыдущим пунктам

   имя-заголовка:

   <последовательность-символов-заголовка>

   последовательность-символов-заголовка:

   символ-заголовка

   последовательность-символов-заголовка  символ-заголовка

   символ-заголовка:

   любой символ из исходного множества символов, за исключением символа новой-строки (\n) или символа "больше чем" (>).

   новая-строка:

   символ  новой строки

   Пустая  директива #

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

   Директивы #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 в текущий момент определен, то средняя строка не обрабатывается препроцессором; в противном же случае выполняется определение средней  строки.

   Отметим,что директива препроцессора не должна заканчиваться точкой с запятой (;). Любые символы, найденные препроцессором в последовательности лексем, включая точки с запятой, появятся в макрорасширениях. Последовательность лексем заканчивается первой встреченной новой строкой без предшествующего символа обратной наклонной черты. Любая последовательность пробельных символов, включая комментарии в последовательности лексем, заменяется на один символ пробела.

Информация о работе Директивы процессора в С++