Подтвердить что ты не робот

C + + тройка равна?

Мне нужно уметь различать NULL и 0 в С++.

Есть ли способ использовать что-то вроде оператора === для определения разницы между NULL и 0 в С++?

4b9b3361

Ответ 1

NULL является макросом препроцессора и будет заменен непосредственно на 0 при запуске препроцессора. Короче говоря, нет.

Ответ 2

Такой оператор не нужен в С++, потому что нет встроенного типа, который мог бы хранить оба эти значения осмысленно различимым образом. Более того, NULL не требуется в С++, потому что вы можете заменить его нулем 0 везде a NULL. Бьярне Страуструп даже предлагает избегать NULL вообще:

В С++ определение NULL равно 0, поэтому существует только эстетическая разница. Я предпочитаю избегать макросов, поэтому я использую 0. Еще одна проблема с NULL заключается в том, что люди иногда ошибочно полагают, что он отличается от 0 и/или не целого. В предстандартном коде NULL был/иногда определен чем-то неподходящим и поэтому ее/ее следует избегать. Это менее распространено в наши дни.

Ответ 3

Существует без разницы - NULL требуется определить как константу с целым числом со значением 0. Тип целочисленного типа обычно выбирается таким же, как указатель, но который фактически не нужен. В C он часто определяется как (void *)0, но это не разрешено в С++ (в C это разумно, потому что указатель на void поддерживает неявное преобразование в любой другой тип указателя, но на С++, который не разрешен, поэтому, если NULL были определяемый как указатель на void, вам нужно будет использовать его для получения любого другого типа указателя).

Если/если вы хотите нулевой указатель, отличающийся от 0, вы, вероятно, захотите использовать nullptr. nullptr может быть назначена переменной любого типа указателя, но не может быть назначена целочисленному типу (например, int, long, size_t и т.д.)

Ответ 4

Я думаю, что вы спрашиваете:

Если у меня есть переменная 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 */ }
    

Ответ 5

В общем случае 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.

Ответ 6

На самом деле это зависит от того, что вы сравниваете NULL или 0 с... если вы сравниваете целое число, тогда NULL должно работать как 0, если вы сравниваете с адресом 0, будет работать как NULL.