Мне нужно уметь различать NULL
и 0
в С++.
Есть ли способ использовать что-то вроде оператора ===
для определения разницы между NULL
и 0
в С++?
Мне нужно уметь различать NULL
и 0
в С++.
Есть ли способ использовать что-то вроде оператора ===
для определения разницы между NULL
и 0
в С++?
NULL
является макросом препроцессора и будет заменен непосредственно на 0 при запуске препроцессора. Короче говоря, нет.
Такой оператор не нужен в С++, потому что нет встроенного типа, который мог бы хранить оба эти значения осмысленно различимым образом. Более того, NULL
не требуется в С++, потому что вы можете заменить его нулем 0
везде a NULL
. Бьярне Страуструп даже предлагает избегать NULL
вообще:
В С++ определение NULL равно 0, поэтому существует только эстетическая разница. Я предпочитаю избегать макросов, поэтому я использую 0. Еще одна проблема с NULL заключается в том, что люди иногда ошибочно полагают, что он отличается от 0 и/или не целого. В предстандартном коде NULL был/иногда определен чем-то неподходящим и поэтому ее/ее следует избегать. Это менее распространено в наши дни.
Существует без разницы - NULL
требуется определить как константу с целым числом со значением 0
. Тип целочисленного типа обычно выбирается таким же, как указатель, но который фактически не нужен. В C он часто определяется как (void *)0
, но это не разрешено в С++ (в C это разумно, потому что указатель на void поддерживает неявное преобразование в любой другой тип указателя, но на С++, который не разрешен, поэтому, если NULL
были определяемый как указатель на void, вам нужно будет использовать его для получения любого другого типа указателя).
Если/если вы хотите нулевой указатель, отличающийся от 0
, вы, вероятно, захотите использовать nullptr
. nullptr
может быть назначена переменной любого типа указателя, но не может быть назначена целочисленному типу (например, int
, long
, size_t
и т.д.)
Я думаю, что вы спрашиваете:
Если у меня есть переменная
x
, как я могу различать
x
содержит числовое значение0
x
отсутствует /no value/null указатель
С++ имеет сильно типизированные переменные, поэтому необычно даже иметь переменную, где обе эти возможности. Но NULL -значная логика полезна в базах данных, поэтому давайте рассмотрим несколько способов представления этого в С++.
Ситуация: x == 0
обнаруживается в коде шаблона, где значение 0
нечеткое.
Ответ. Используйте черту типа, чтобы узнать, является ли x
указателем (случай # 2) или нет (случай # 1).
if (is_pointer(x))
Ситуация: p
- логическая переменная NULL-значения C-стиля, которая является указателем на числовое значение.
Ответ: проверьте, является ли указатель нулевым. Если нет, вы можете проверить объект с указателем.
if (p == NULL) { /* case 2 */ }
else if (*p == 0) { /* case 1 */ }
Ситуация: v
- это Win32 VARIANT, который является дискриминационным объединением, используемым для реализации переменных на языках сценариев.
Ответ: Проверьте дискриминирующий ключ.
if (v.vt == VT_EMPTY) { /* case 2a */ }
else if (v.vt == VT_NULL) { /* case 2b */ }
else if (v.vt == VT_I4 && v.lVal == 0) { /* case 1 */ }
else if (v.vt == VT_I2 && v.iVal == 0) { /* case 1 */ }
// and so on
Ситуация: o
является представлением С++-типа NULL-значной логики, например boost::optional
.
Ответ: Эти классы С++ для NULL-значной логики обеспечивают способ обнаружения отсутствующих значений. Конкретный пример с boost::optional<int>
показывает, что он предназначен для доступа точно так же, как указатель:
boost::optional<int> o;
if (!o) { /* case 2 */ }
else if (*o == 0) { /* case 1 */ }
В общем случае NULL
и 0
- одно и то же в С++ (оба являются нулевым указателем).
Я собираюсь предположить, что вы спрашиваете, как получить интегральный тип в С++, который может иметь значения NULL
и 0
, и иметь возможность сказать разницу.
Вы можете сделать это с помощью boost::optional
:
boost::optional<int> val;
if(!val)
std::cout << "null" << std::endl;
else
std::cout << "val=" << *val << std::endl;
val = 0;
if(!val)
std::cout << "null" << std::endl;
else
std::cout << "val=" << *val << std::endl;
Это должно печатать NULL
и val=0
.
На самом деле это зависит от того, что вы сравниваете NULL
или 0
с... если вы сравниваете целое число, тогда NULL
должно работать как 0
, если вы сравниваете с адресом 0
, будет работать как NULL
.