#define задаёт макрос или символическую константу (это наиболее часто используемая и простейшая макроподстановка). Пример использования макроса:
#define MAX_SIZE 9999
Несмотря на всю забавность примера, построить на макрос-подстановках полноценный транслятор Си в Pascal не получится.
Макросы допустимо использовать только для определения символьных констант!
При этом такие константы всегда называют ЗАГЛАВНЫМИ БУКВАМИ, чтобы было понятно, что это МАКРОС ПРЕПРОЦЕССОРА.
Макросы в языке Си иногда используются для определения небольших фрагментов кода.
Во время обработки кода препроцессором, каждый макрос заменяется соответствующим ему определением.
Если макрос имеет параметры, то они указываются в теле макроса. Этим они могут походить на Си-функции, но их не стоит путать с функциями.
Нужно постараться избегать макросов везде, где это возможно!
Например,
#define max(a,b) ((a) > (b) ? (a) : (b))
определяет макрос max, использующий два аргумента a и b. Этот макрос можно вызывать как любую Си-функцию, используя схожий синтаксис. То есть, после обработки препроцессором,
z = max(x,y);
становится
z = ((x) > (y) ? (x) : (y));
Однако, наряду с преимуществами использования макросов в языке Си, например, для определения типобезопасных общих типов данных или отладочных инструментов, они также несколько снижают эффективность их применения и даже могут привести к ошибкам.
Например, если f и g — две функции, вызов
z = max(f(), g());
вычислит одну из функций дважды, и если эта функция имеет побочные эффекты, то её поведение, вероятно, будет отличаться от ожидаемого.
Ошибки, порождаемые использованием макросов, никак не могут быть отслежены компилятором, поэтому макросов следует избегать!
Отладка в программе, в которой используются макросы — один из самых страшных снов разработчика ПО.