Могу ли я использовать if (указатель) вместо if (pointer! = NULL)?

Можно ли проверить указатель на отсутствие NULL , просто написав, if(pointer) или мне нужно использовать if(pointer != NULL) ?

Ты можешь; нулевой указатель неявно преобразуется в логическое значение false, а непустые указатели преобразуются в true. Из стандарта C ++ 11, раздел « Логические преобразования»:

Присвоение арифметики, неперечисленного enums, указателя или указателя на тип члена может быть преобразовано в prvalue типа bool . Значение нуля, значение нулевого указателя или значение указателя нулевого элемента преобразуется в значение false ; любое другое значение преобразуется в значение true . Значение типа std::nullptr_t может быть преобразовано в prvalue типа bool ; результирующее значение false .

Да, можно.

  • Нулевой указатель преобразуется в false неявно
  • ненулевой указатель преобразуется в true.

Это часть стандартного преобразования C ++, которое относится к разделу Boolean conversion :

§ 4.12 Логические преобразования

Присвоение арифметики, неперечисленного enums, указателя или указателя на тип члена может быть преобразовано в prvalue типа bool. Значение нуля, значение нулевого указателя или значение указателя нулевого элемента преобразуется в значение false; любое другое значение преобразуется в значение true. Значение типа std :: nullptr_t может быть преобразовано в prvalue типа bool; результирующее значение ложно.

Да, ты можешь. На самом деле, я предпочитаю использовать if(pointer) потому что его проще читать и писать, как только вы привыкнете к нему.

Также обратите внимание, что C ++ 11 ввел nullptr который предпочтителен над NULL .

Ответ на вопрос, но я хотел бы добавить свои баллы.

Я всегда буду предпочитать, if(pointer) вместо if(pointer != NULL) и if(!pointer) вместо if(pointer == NULL) :

  • Это просто, мало
  • Меньше шансов написать багги-код, предположим, если я ошибочно поставил оператор проверки равенства == with =
    if(pointer == NULL) может быть орфографическим, if(pointer = NULL) Поэтому я его избегу, лучше всего, if(pointer) .
    (Я также предложил некоторые условия Йоды в одном ответе , но это разное дело)

  • Аналогично для while (node != NULL && node->data == key) , я просто напишу while (node && node->data == key) что более очевидно для меня (показывает, что с использованием короткого замыкания).

  • (может быть, глупая причина) Поскольку NULL является макросом, если предположить, что кто-то переопределяет по ошибке с другим значением.

Да, ты можешь. Способность сравнивать значения с нулями неявно была унаследована от C и существует во всех версиях C ++. Вы также можете использовать if (!pointer) для проверки указателей на NULL.

Явная проверка NULL может дать подсказку компилятору о том, что вы пытаетесь сделать, что приводит к тому, что он менее подвержен ошибкам.

введите описание изображения здесь

Соответствующими вариантами использования для нулевых указателей являются

  • Перенаправление на нечто вроде более глубокого узла дерева, который может не существовать или еще не был связан. Это то, что вы всегда должны держать в инкапсулированном виде в специальном classе, поэтому читабельность или краткость не так уж и важны.
  • Динамические отливки. Приведение указателя базового classа к определенному производному classу (что-то, что вы должны снова попытаться избежать, но иногда найти обязательно) всегда преуспевает, но приводит к нулевому указателю, если производный class не соответствует. Один из способов проверить это

     Derived* derived_ptr = dynamic_cast(base_ptr); if(derived_ptr != nullptr) { ... } 

    (или, предпочтительнее, auto derived_ptr = ... ). Теперь это плохо, потому что он оставляет указатель (возможно, недействительный, т. Е. Нуль) за пределами области безопасности, if область действия блока. Это необязательно, так как C ++ позволяет вводить переменные типа boolean-convertable внутри if -condition :

     if(auto derived_ptr = dynamic_cast(base_ptr)) { ... } 

    который не только короче и безопасен по размеру, он также намного более ясен в его намерениях: когда вы проверяете значение null в отдельном условии if, читатель задается вопросом «ok», поэтому derived_ptr не должен быть здесь null … ну, почему это было бы нулевым? ” В то время как однострочная версия говорит очень просто: «Если вы можете безопасно base_ptr до Derived* , тогда используйте его для …».

    То же самое можно сделать и для любой другой операции с возможным сбоем, которая возвращает указатель, хотя ИМО вы, как правило, избегаете этого: лучше использовать что-то вроде boost::optional как «контейнер» для результатов возможных сбоев, а не указатели.

Таким образом, если основной вариант использования для нулевых указателей всегда должен быть написан в вариации неявного литья, я бы сказал, что для удобства всегда полезно использовать этот стиль, т. Е. Я бы защищал, if(ptr) over if(ptr!=nullptr) .


Боюсь, мне нужно закончить объявление: синтаксис if(auto bla = ...) самом деле просто немного громоздкое приближение к реальному решению таких проблем: сопоставление шаблонов . Зачем вам сначала навязывать какое-то действие (например, бросать указатель), а потом считать, что может быть провал … Я имею в виду, это смешно, не так ли? Это похоже на то, что у вас есть продукты питания и вы хотите приготовить суп. Вы передаете его своему помощнику с задачей извлечь сок, если это будет мягкий овощ. Вы сначала не смотрите на это. Когда у вас есть картофель, вы все равно отдаете его своему помощнику, но они ударяют его по лицу с запиской об отказе. Ах, императивное программирование!

Гораздо лучше: сразу рассмотрите все случаи, с которыми вы можете столкнуться. Затем действуйте соответствующим образом. Haskell:

 makeSoupOf :: Foodstuff -> Liquid makeSoupOf [email protected](Potato{..}) = mash (boil p) <> water makeSoupOf vegetable | isSoft vegetable = squeeze vegetable <> salt makeSoupOf stuff = boil (throwIn (water<>salt) stuff) 

У Haskell также есть специальные инструменты, когда есть действительно серьезная возможность неудачи (а также целая куча других вещей): монады. Но это не объясняет это.

⟨/объявление⟩

Да. На самом деле вы должны. Если вам интересно, создает ли он ошибку сегментации , это не так.

Да, конечно! на самом деле, запись if (pointer) является более удобным способом написания, а не if (pointer! = NULL), потому что: 1. легко отлаживать 2. легко понять 3. если случайно определено значение NULL, то и код не сработает

Да, вы всегда можете это сделать, поскольку условие «IF» оценивается только тогда, когда условие внутри него действует. C не имеет типа логического возврата и, следовательно, возвращает ненулевое значение, когда условие истинно, а возвращает 0, когда условие в «IF» оказывается ложным. Возвращаемое по умолчанию ненулевое значение равно 1. Таким образом, оба способа написания кода верны, в то время как я всегда предпочитаю второй.

Я думаю, как правило, если ваше if-выражение можно переписать как

 const bool local_predicate = *if-expression*; if (local_predicate) ... 

так что он вызывает NO WARNINGS, тогда THAT должен быть предпочтительным стилем для if-выражения . (Я знаю, что получаю предупреждения, когда я назначаю старый C BOOL ( #define BOOL int ) в C ++ bool , не говоря уже о указателях.)

“Это безопасно..?” это вопрос о стандарте языка и сгенерированном коде.

«Это хорошая практика?» это вопрос о том, насколько хорошо это утверждение понимается любым произвольным человеческим читателем заявления. Если вы задаете этот вопрос, это говорит о том, что «безопасная» версия менее понятна будущим читателям и писателям.

  • Нарезка указателя среза, переданного в качестве аргумента
  • Можно ли рассматривать 2D-массив как непрерывный массив 1D?
  • Что является результатом NULL + int?
  • C ++ передает массив по ссылке
  • Почему я могу изменить локальную константную переменную с помощью указателей, но не глобальную в C?
  • В обработчиках HTTP Go, почему ResponseWriter имеет значение, но запрашивает указатель?
  • Полиморфизм и указатели на массивы
  • Что означает «имя массива» в случае массива указателей на символы?
  • Почему cudaMalloc () использует указатель на указатель?
  • Различия между unique_ptr и shared_ptr
  • Является ли указатель с правильным адресом и типом все еще всегда действительным указателем с C ++ 17?
  • Давайте будем гением компьютера.