Студопедия — Цепочка подстановок
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Цепочка подстановок






Если в строке замещения команды #define в качестве отдельной лексемы встречается препроцессорный идентификатор, ранее определенный другой директивой #define, то выполняется цепочка последовательных подстановок. В качестве примера рассмотрим, как можно определить диапазон (RANGE) возможных значений любой целой переменной типа int в следующей программе:

 

Пример 10.2

#include < limits.h>

#define RANGE ((INT_MAX) – < INT_MIN)+1)

/* RANGE - диапазон значений для int */ ………….

int RANGE_T = RANGE/8; ………….

 

Препроцессор последовательно просматривает текст и, обнаружив директиву #include < limits.h>;, вставляет текст из файла limits.h. Там определены константы INT_MAX и INT_MIN (предельные максимальное и минимальное значения целых величин). Программа принимает следующий вид:

#define INT_MAX 32767

#define INT_MIN -32768

#define RANGE ((INT_MAX)-(INT_MIN)+1).

/* RANGE - диапазон значений для int*/

int RANGE_T = RANGE/8;

 

Обратим внимание на то, что директива #include исчезла из программы, но ее заменил соответствующий текст. Обнаружив в тексте (добытом из файла limits.h) директивы define..., препроцессор выполняет соответствующие подстановки, и программа принимает следующий вид:

 

#define RANGE ((32767)-(-32768)+1)

/* RANGE - диапазон значений для int*/

int RANGE_T = RANGE/8;

Подстановки изменили строку замещения препроцессорного идентификатора RANGE в директиве #define, размещенной ниже, чем текст, включенный из файла limits.h. Последовательно анализируя текст программы, препроцессор встречает препроцессорный идентификатор RANGE и выполняет подстановку. Программа приобретает следующий вид:

 

/* RANGE - диапазон значений для int*/

int RANGE_T - ((32767) - (-32768)+1)/8;

 

Теперь все директивы #define удалены из текста. Получен текст, пригодный для компиляции, т.е. создана «единица трансляции». Подстановка строки замещения вместо идентификатора RANGE выполнена в выражении RANGE/8, однако внутри комментария идентификатор RANGE остался без изменений и не изменился идентификатор RANGE_Т.

Этот пример иллюстрирует выполнение «цепочки» подстановок и ограничения на замены: замены не выполняются внутри комментариев, внутри строковых констант, внутри символьных констант и внутри идентификаторов (не может измениться часть идентификатора). Например, RANGE_T остался без изменений.

Если строка замещения оказывается слишком длинной, то ее можно продолжить в следующей строке текста. Для этого в конце продолжаемой строки помещается символ ‘\’. В ходе одной из стадий препроцессорной обработки этот символ вместе с последующим символом конца строки будет удален из текста программы.

Пример 10.3

#define STRING " \n Game Over! – Игра закончена! "

printf(STRING);

На экран будет выведено:

Game Over! – Игра закончена!

 

С помощью команды #define удобно выполнять настройку программы. Например, если в программе требуется работать с массивами, то их размеры можно явно определять на этапе препроцессорной обработки:

 

Пример 10.4

Исходный текст Результат препроцессорной обработки

#define К 40

void main() void main ()

{ {

int M[K][K]; int M[40][40];

float A[2*K+1], float A[2*40+l],

float B[K+3][K-3] float В[40+3][40-3];

…….. ……..

 

При таком описании очень легко изменять предельные размеры сразу всех массивов, изменив только одну константу (строку замещения) в директиве #define. Предусмотренные директивой #define препроцессорные. замены не выполняются внутри строк, символьных констант и комментариев, т.е. не распространяются на тексты, ограниченные кавычками (“), апострофами (‘) и разделителями (/*,. */). В то же время строка замещения может содержать перечисленные ограничители, например, при замене препроцессорного идентификатора STRING.

Если в программе нужно часто печатать или выводить на экран дисплея значение какой-либо переменной и, кроме того, снабжать эту печать одним и тем же пояснительным текстом, то удобно ввести сокращенное обозначение оператора печати, например:

 

Пример 10.5

#define PK printf(“\n Номер элемента=%d.”, N);

 

После этой директивы использование в программе оператора РК; будет эквивалентно (по результату) оператору из строки замещения. Например, последовательность операторов

int N = 4; РК;

приведет к выводу такого текста:

Номер элемента=4.

 

Если в строку замещения входит идентификатор, определенный в другой команде #define, то в строке замещения выполняется следующая замена (цепочка подстановок). Например, программа, содержащая команды:

Пример 10.6

#define К 50

#define PE printf (“\п Число элементов K=%d”, K);

…….

РЕ;

выведет на экран такой текст:

Число элементов К=50

Идентификатор К внутри строки замещения, обрамленной кавычками, не заменяется на 50.

 

Строку замещения, связанную с конкретным препроцессорным идентификатором, можно сменить, приписав уже определенному идентификатору новое значение другой командой #define:

 

Пример 10.7

#define M 16 /* Идентификатор М определен как 16 */

#define M ‘С’ /* М определен как символьная константа ‘С’ */

#define M “С” /* М определен как символьная строка, в которой есть два элемента ‘С’ и ‘\0’ */

 

Однако при таких сменах значений препроцессорного идентификатора некоторые компиляторы C++ выдают предупреждающее сообщение на каждую следующую директиву #define:

 

Warning..: Redefinition of ‘M’ is not identical

Замены в тексте можно отменять с помощью команды

#undef идентификатор

После выполнения такой директивы этот препроцессорный идентификатор становится неопределенным, и его можно определять повторно. Например, не вызовут предупреждающих сообщений директивы:

#define M 16

#undef M

#define M ’С’

#undef M

#define M ”С”

 

Директиву #undef удобно использовать при разработке больших программ, когда они собираются из отдельных «кусков текста», написанных в разное время или разными программистами. В этом случае могут встретиться одинаковые обозначения разных объектов. Чтобы не изменять исходных файлов, включаемый текст можно «обрамлять» подходящими директивами #define, #undef и тем самым устранять возможные ошибки.

 

Пример 10.8

…….

А = 10; / Основной текст*/

…….

#define A X

…….

А = 5; / Включенный текст */

………..

#undef A

………..

В = А; / Основной текст */

……….

 

При выполнении программы переменная В примет значение 10, несмотря на наличие оператора присваивания А = 5 во включенном тексте.







Дата добавления: 2014-11-10; просмотров: 785. Нарушение авторских прав; Мы поможем в написании вашей работы!



Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Подкожное введение сывороток по методу Безредки. С целью предупреждения развития анафилактического шока и других аллергических реак­ций при введении иммунных сывороток используют метод Безредки для определения реакции больного на введение сыворотки...

Принципы и методы управления в таможенных органах Под принципами управления понимаются идеи, правила, основные положения и нормы поведения, которыми руководствуются общие, частные и организационно-технологические принципы...

ПРОФЕССИОНАЛЬНОЕ САМОВОСПИТАНИЕ И САМООБРАЗОВАНИЕ ПЕДАГОГА Воспитывать сегодня подрастающее поколение на со­временном уровне требований общества нельзя без по­стоянного обновления и обогащения своего профессио­нального педагогического потенциала...

Краткая психологическая характеристика возрастных периодов.Первый критический период развития ребенка — период новорожденности Психоаналитики говорят, что это первая травма, которую переживает ребенок, и она настолько сильна, что вся последую­щая жизнь проходит под знаком этой травмы...

РЕВМАТИЧЕСКИЕ БОЛЕЗНИ Ревматические болезни(или диффузные болезни соединительно ткани(ДБСТ))— это группа заболеваний, характеризующихся первичным системным поражением соединительной ткани в связи с нарушением иммунного гомеостаза...

Решение Постоянные издержки (FC) не зависят от изменения объёма производства, существуют постоянно...

Studopedia.info - Студопедия - 2014-2024 год . (0.011 сек.) русская версия | украинская версия