Макросы и константы - это далеко не одно и то же, каждый из них иногда соответствует обстоятельствам, и ваш ответ только царапает поверхность разницы. Кроме того, в C ++ есть два разных вида констант.
Константу, определенную с помощью квалификатора const
, лучше всего рассматривать как неизменяемую переменную . У него есть все свойства переменной: у нее есть тип, у нее есть размер, у нее есть связь, вы можете взять ее адрес. (Компилятор может оптимизировать некоторые из этих свойств, если ему это удастся: например, константы, адрес которых никогда не используется, могут не передаваться в исполняемый образ. Но это только по милости правила «как если»). ) Единственное, что вы не можете сделать с const
датумом, это изменить его значение. Константа, определенная с помощью enum
, немного отличается. У него есть тип и размер, но у него нет связи, вы не можете взять его адрес, а его тип уникален. Обе они обрабатываются на 7-й фазе перевода, поэтому они не могут быть чем-либо, кроме lvalue или rvalue. (Прошу прощения за жаргон в предыдущем предложении, но в противном случае мне пришлось бы написать несколько абзацев.)
Макрос имеет гораздо меньше ограничений: он может распространяться на любую последовательность токенов, если общая программа остается правильно сформированной программой. Он не имеет каких-либо свойств переменной. Применение sizeof
или &
к макросу может или не может сделать что-то полезное, в зависимости от того, к чему расширяется макрос. Макросы иногда задаются для расширения до числовых литералов, и такие макросы иногда рассматриваются как как константы, но это не так: «собственно компилятор» (то есть фаза перевода 7) видит их как числовые литералы .
В настоящее время обычно считается хорошей практикой не использовать макрос, когда константа подойдет. Макросы не подчиняются тем же правилам определения области действия, что и все другие идентификаторы, что может привести к путанице, и если вы используете константу, вы даете больше информации на фазу преобразования 7 и, следовательно, также отладчику. Тем не менее, макросы позволяют вам делать то, что не может быть выполнено другим способом, и если вам нужно выполнить одно из этих действий, не стесняйтесь использовать их. (Макросы, которые увеличивают вес, в этом смысле, как правило, , а не , просто расширяются до числовых литералов, хотя я не собираюсь говорить никогда.)
EDIT: Вот пример макроса, который делает что-то интересное. Он никоим образом не формирует и не формирует константу. Вполне возможно, что можно получить тот же эффект без макроса (если вы знаете тот, в котором нет струнных потоков, мне было бы интересно услышать об этом!), Но я думаю, что это хорошая иллюстрация как силы, так и опасность макросов (для последнего подумайте, что он будет делать, если его использовать вне одного очень специфического контекста ...)
static double elapsed()
{ ... }
#define ELAPSED '[' << std::fixed << std::setprecision(2) << elapsed() << "] "
// usage:
for (vector<string>::iterator f = files.begin(); f != files.end(); f++) {
cout << ELAPSED << "reading file: " << *f << '\n';
process_file(*f);
}