В чем различие между этими определениями переменной:
#define N 100
и
const int n = 100;
Что из этих двух является более предпочтительным и в чем достоинства каждого?
Это очень дискуссионный вопрос у всех. Но в целом, в с++ лучше использовать const везде, где это возможно.
Плюсы:
У define это все - недостатки. Они действуют от места определения и до ... конца. Хотя, где этот конец будет - ещё нужно хорошо подумать. Они могут переопределять друг дружку и иногда искать, где именно было в очередной раз переопределено - ещё то удовольствие. Компилятор часто выдает очень "загадочные ошибки". Классический пример с макросом min/max. Файл windows.h определяет их. И может быть очень весело. Детали - NOMINMAX.
Ещё у define есть большой недостаток - это то, что некоторые думают, что там есть скобки. А их нет.
#define add(a,b) a+b
if (add(x,y) * add(x,y)) {}
кажется, что будет посчитано (x+y) в квадрате. А на самом деле - .... на самом деле x+y + x*y.
Но мы немного отвлеклись. Такого сделать обычным const уже нельзя. Но легко сделать inline функциями. И их результат будет предсказуемый.
Поэтому:
UPD
А ещё хорошо найти книгу Эффективное использование C++. 55 верных советов улучшить структуру и код ваших программ - Скотт Майерс и почитать второй совет (в любом случае - там всю книгу можно читать и читать).
В чистом языке С++, если у вас есть выбор между этими двумя вариантами, то ясно, что предпочтительным является именно вариант с const. Однако вопрос задан несколько ограничивающе, ибо почему-то предложены к рассмотрению только эти два способа. В рамках современного языка С++ у вас есть третий способ
constexpr int N = 100;
который фактически является унифицированным вариантом, специально предназначенным для создания констант времени компиляции, как именованных, так и вычислимых.
В данном случае, если не лезть в иррелевантные детали, разницы между const и constexpr не будет, однако существует мнение, что использование constexpr предпочтительнее именно в вашем варианте - когда вас интересует именно константа времени компиляции, но совершенно не интересует ее адресная идентичность, т.е. вы никогда не будете рассматривать адрес этой константы. Вариант с const в рамках этого мнения условно "отодвигается" на роли, которые этот квалификатор играет в языке С, т.е. создание "неизменяемых переменных" в памяти.
Но, опять же, такое различие существует лишь на уровне соглашений, т.е. разницы между const int и constexpr int в тривиальных применениях вы не заметите.
Однако и у #define тоже есть свои преимущества.
Ограничение на использование только либо const, либо #define варианта возникнет тогда, когда вы будете создавать кросс-компилируемый С и С++ код (например, заголовочные файлы библиотек, предназначенных для использования в обоих языках). Тогда вам в большинстве случаев придется пользоваться именно #define, ибо в языке С квалификатор const не создает констант.
В качестве еще одного преимущества варианта с #define можно назвать очевидную (но часто забываемую) возможность использовать #define-константы в условных выражениях препроцессора, т.е. в #if. Ни const, ни constexpr вам там не помогут. Шаблонное метапрограммирование и появление в языке С++ таких C++17 свойств, как "static if" (if constexpr) тоже частично переносит такие применения из области препроцессора в область самого языка и, соответственно, снижает ценность #define-констант в С++, но тем не менее эта деталь тоже заслуживает упоминания.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости