препроцессор c — мне следует избегать использования #define в C ++? Почему и какие альтернативы я могу использовать?

Для некоторых видов программ мне нужно использовать постоянное высокое значение, чтобы указать некоторые свойства некоторых переменных. Я имею ввиду color[i] = 1000000; если i узел в дереве неисследован. Но я довольно часто неправильно пишу число 0 в конце, поэтому я просто удивился, лучше ли это делать так:

#define UNEXPLORED 1000000;
color[i] = UNEXPLORED;

Я помню, что где-то я читал, что лучше избегать использования #define. Это правильно? Как бы вы решили эту проблему?

2

Решение

Для простых констант вы можете использовать либо const или новый constexpr:

constexpr unsigned int UNEXPLORED = 1000000;

В таком случае нет разницы между const а также constexpr, Тем не менее, «переменные» отмечены constexpr оцениваются во время компиляции, а не во время выполнения, и могут использоваться в местах, которые в противном случае принимают только литералы.

4

Другие решения

Например используйте константы.

const unsigned int UNEXPLORED = 1000000;

или перечисления

enum { UNEXPLORED = 1000000 };
3

При использовании констант два ответа выше верны, однако #define не ограничивается только этим использованием. Еще один пример использования #define это макросы.

макрос

Макросы — это части кода, используемые препроцессором, и они работают точно так же, как и другие #define заявления на этот счет. Препроцессор буквально поменяет местами вхождение вашего определенного символа с кодом макроса. Пример:

#define HELLO_MAC do{ std::cout << "Hello World" << std::endl; }while(false)

int main(int argc, char** argv)
{
HELLO_MAC;
}

Это буквально поменяет HELLO_MAC символ с кодом, который я объявил. Если бы это была константа, она бы сделала то же самое. Так что вы можете думать о #defineдля констант как особого вида макросов.

С помощью макросов вы также можете передавать параметры, и это особенно полезно для применения политик ведения журналов / исключений над кодом.
Например

#define THROW_EXCEPT( ex_type, ex_msg ) /
do{ throw ex_type( buildExString( (ex_msg), __LINE__, __FILE__ ) ); }while(false)

...
// somewhere else
THROW_EXCEPT( std::runtime_error, "Unsupported operation in current state" );

Этот код позволяет мне гарантировать, что каждый регистрируется со строкой файла, который вызвал исключение.

Шаблоны часто являются лучшим выбором вместо макросов, но я не могу использовать функции шаблонов для этого примера, потому что мне нужно использовать __LINE__ а также __FILE__ функции с места броска, а не с места расположения функции шаблона.

Где вы не должны использовать макросы? В любом месте вы можете использовать что-то еще. Макросы, как и любой #define предварительно обработаны, поэтому компилятор их вообще не видит. Это означает, что нет никаких символов, созданных для HELLO_MAC или же THROW_EXCEPTи поэтому их нельзя увидеть в отладчике. Они также могут сбивать с толку, если вы получаете ошибки компиляции, особенно если это длинные макросы.

0
По вопросам рекламы [email protected]