Макросы
Макросы - инструкции препроцессора (самостоятельный яп, который ничего не знает про синтаксис С++ и работает с кодом как с обычным текстом)
Используя макросы можно написать “подобие” функции:
#define max2(x,y) ((x) > (y) ? (x) : (y))
a = max2(c,d);
// при компиляции вместо max2(c,d) препроцессор подставит строку ((c) > (d) ? (c) : (d)).
// max2(x,y) что-то типо переменной, принимающей два параметра
Параметр макроса можно превратить в строку, добавив перед ним знак #:
#define MACRO(PARAM) "Macro received: " #PARAM
int x = 5;
std::cout << MACRO(x) << "\n"; // Macro received: x
Параметр макроса можно приклеить к чему-то еще, чтобы получить новый идентификатор, для этого нужно между ними поставить знак ##:
#define MACRO(PARAM) value_##PARAM
int value_x = 5;
std::cout << MACRO(x) << "\n"; // 5
// приклеит value_ к x и выведет соответственно значение value_x
❗ Параметры макросов и сам макрос лучше нужно оборачивать круглыми скобками:
#define max2(x,y) x > y ? x : y // <- не обернули скобками
a = b + max2(c,d);
// превратится в a = b + c > d ? c : d, а это уже совсем другое условие
Но оборачивание скобками тоже не избавляет от всех проблем, например что будет, если мы передадим макросу с++ вместо c?
#define max2(x,y) ((x) > (y) ? (x) : (y))
a = b + max2(c++,d);
// превратится в a = b + ((c++) > (d) ? (c++) : (d))
// каждый раз когда в условии будет встречатся с++, будет выполнятся инкремент
// а мы ожидали что инкремент выполнится один раз, и будет передано с+1
❗ В общем говоря использовать макросы вместо функций плохая практика, поскольку макросы очень трудно грамотно написать.
Зато макросы очень удобно использовать для условной компиляции:
#ifdef DEBUG
// отладочная информация
#endif
Теперь для того что бы компилировать и вывести всю отладочную информацию достаточно вначале программы написать:
#define DEBUG
В ином случае все что между директивами условной компиляции будет стёрто на этапе препроцессинга и не попадёт в компилятор.
Снять определение:
#undef DEBUG