Разделы
- 1. Введение
- 2. Описание языка
- 3. Интерфейс программирования приложений (API)
- 3.1. Стек
- 3.2. Резервация памяти
- 3.3. Сообщения
- 3.4. Типы данных
- 3.5. Функции
- 3.5.1. Базовые функции скриптоввой системы
- 3.5.2. Функции для вставки на вершину стека значения
- 3.5.3. Перевод значений со стека в скриптовую ситему (экспорт (stack => script))
- 3.5.4. Функции для получения со стека (stack => C(++))
- 3.5.5. Функции для работы с аргументами в вызванной C(++) функции из скриптовой системы (script => C(++) function)
- 3.5.6. Функции отладки (DEBUG)
- 3.5.7. Функции для работы с препроцессом
- 4. Стандартная библиотека
2.11. Препроцесс
Директивы препроцессора - строки кода, начинающиеся с символа решетки #
. Эти строки не являются программными выражениями, и обрабатываются препроцессором. Препроцессор осуществляет обработку кода до компиляции и выполняет все подстановки.
Директива препроцессора располагается в одной строке и заканчивается символом конца строки. В конце директивы не требуется точка с запятой (;
). Чтобы расширить директиву на более чем одну строку - нужно поместить в конце строки обратный слеш (\
).
Макроопределения (#define, #undef)
Чтобы задать определение для препроцессора, используется директива #define
, ее синтаксис:
#define identifier replacement
Когда препроцессор встречает эту директиву, он заменяет все встреченные identifier
на replacement
далее по тексту программы. replacement
может быть выражением, конструкцией, блоком, или вообще ничем. Препроцессор просто заменяет identifier
на replacement
.
#define SIZE 100 $some_size = SIZE; $some_more_size = SIZE + 10;
После обработки препроцессором код будет выглядеть так:
$some_size = 100; $some_more_size = 100 + 10;
#define
так же может принимать параметры для определения макроса.
#define getsum(a,b) a+b
Это заменит все встреченные getsum с двумя аргументами на выражение замены, и каждый аргумент на его значение.
#define getsum(a,b) a+b $a = getsum(1,2); //после подстановки станет $a = 1+2;
Заданный макрос не зависит от структуры блоков. Он существует до тех пор, пока не будет отменен с помощью директивы #undef
#define SIZE 100 $some_size = SIZE; #undef SIZE #define SIZE 200 $some_more_size = SIZE;
сгенерирует такой же код, как
$some_size = 100; $some_more_size = 200;
Функциональные макросы так же поддерживают два специальных оператора (#
, ##
) в выражении замены.
Оператор #
, стоящий перед именем параметра, заменяется на строковый литерал, содержащий переданный аргумент.
#define str(x) #x print(str(test));
будет преобразовано в
print("test");
Оператор ##
соединяет два аргумента, не оставляя пробелов между ними:
#define concat(a,b) a ## b concat(pri, nt)("text");
Будет преобразовано в
print("text");
Так как препроцессорные замены осуществляются до проверки синтаксиса s4g, они позволяют осуществлять различные хитрые вещи. Но будьте осторожны, большие сложные макросы сложно читать человеку, и в них трудно будет найти ошибку.
Условные включения (#ifdef, #ifndef, #if, #endif, #else)
Эти директивы позволяют включать либо исключать части кода из компиляции, в зависимости от выполнения каких-то условий.
#ifdef
позволяет участку кода скомпилироваться только в том случае, если макрос, указанный в параметре, определен, в не зависимости от его значения.ъ
#ifdef SIZE a = SIZE; #endif
В этом примере, строка кода a = SIZE;
будет скомпилирована только в том случае, если макрос SIZE
был предварительно определен с помощью #define
, независимо от его значения.
#ifndef
является противоположностью #ifdef
- код будет скомпилирован только если макрос не определен.
#ifndef SIZE #define SIZE 100 #endif a = SIZE;
В этом примере, макрос SIZE определяется только в том случае, если он не был ранее определен.
Директивы #if
, #else
служат для задания специальных условий. Условные выражения должны включать только константные значения, включая макросы.
#if SIZE>200 #undef SIZE #define SIZE 200 #else #if SIZE<50 #undef SIZE #define SIZE 50 #endif #else #undef SIZE #define SIZE 100 #endif $a = SIZE;
Поведение #ifdef
и #ifndef
так же может быть достигнуто с помощью операторов defined()
и !defined()
в директиве #if
#if defined(ARRAY_SIZE) #define SIZE ARRAY_SIZE #else #if !defined(BUFFER_SIZE) #define SIZE 128 #else #define SIZE BUFFER_SIZE #endif #endif
Включения файлов кода (#include)
Когда препроцессор встречает директиву #include
, он заменяет ее на содержимое файла, указанного в аргументе.
#include "file"
Поиск осуществляется относительно текущей директории файла с кодом, а так же в заданных путях поиска.