Читаем Справочное руководство по C++ полностью

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

Команда вида

идентификатор ( идентификатор , … , идентификатор ) строка-лексем

называется макроопределением с параметрами или "функциональным" макроопределением. В нем недопустимы пробелы между первым идентификатором и символом (. Определенный таким способом идентификатор можно переопределить с помощью другого функционального макроопределения, но при условии, что во втором определении то же число и те же наименования параметров, что и в первом, а обе строки замены совпадают. Все символы обобщенного пробела, разделяющие лексемы, считаются идентичными.

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

После идентификации параметров для функционального макроопределения происходит подстановка фактических параметров. После выполнения подстановок в параметре (если они были) этот параметр в строке замены замещается фактическим параметром из макровызова (§R.16.3.3); исключения составляют случаи, когда параметру предшествует лексема # (§R.16.3.1), или с ним соседствует лексема ## (§R.16.3.2).

Приведем пример. Пусть есть макроопределения

#define index_mask 0XFF00

#define extract(word,mask) word & mask

Тогда макровызов

index = extract(packed_data,index_mask);

после подстановки примет вид

index = packed_data & 0XFF00;

Для обоих видов макроопределений строка замены проверяется на наличие других макроопределений (§R.16.3.3).

<p>R.16.3.1 Операция #</p></span><span>

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

Например, если есть макроопределения

#define path(logid,cmd) "/usr/" #logid "/bin/" #cmd

то макровызов

char* mytool=path(joe,readmail);

приведет к такому результату:

char* mytool="/usr/" "joe" "/bin/" "readmail";

После конкатенации соседних строк (§R.16.1) получим:

char* mytool="/usr/joe/bin/readmail";

<p>R.16.3.2 Операция ##</p></span><span>

Если в строке замены между двумя лексемами, одна из которых представляет параметр макроопределения, появляется операция ##, то сама операция ## и окружающие ее обобщенные пробелы удаляются. Таким образом, результат операции ## состоит в конкатенации.

Пусть есть макроопределение,

#define inherit(basenum) public Pubbase ## basenum, \

 private Privbase ## basenum

тогда макровызов

class D: inherit(1) {};

приведет к такому результату:

class D: public Pubbase1, Privbase1 {};

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

#define concat(a) a ## ball

#define base B

#define baseball sport

Тогда макровызов

concat(base)

даст в результате

sport

а вовсе не

Bball

<p>R.16.3.3 Повторный просмотр и дальнейшие подстановки</p></span><span>

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

Рекурсивную подстановку нельзя выполнить как команду препроцессора, хотя она кажется для него естественной командой.

<p>R.16.3.4 Область видимости макроимен и конструкция #undef</p></span><span>
Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT