Безопасно ли проверять указатель на отсутствие NULL
написания просто if(pointer)
или я должен использовать if(pointer != NULL)
?
c++
pointers
if-statement
null
null-pointer
Данияр
источник
источник
0
илиnullptr
. (NULL
является C'ism и требует включения заголовочного файла.)NULL
в C ++, потому чтоNULL
это макрос, зависящий от реализации, который может дать вам неоднозначное поведение.Ответы:
Ты можешь; нулевой указатель неявно преобразуется в логическое значение false, а ненулевые указатели преобразуются в истину. Из стандарта C ++ 11, раздел о булевых преобразованиях:
источник
Да, ты мог.
Это часть стандартного преобразования C ++, которое входит в условие преобразования Boolean :
§ 4.12. Булевы преобразования
источник
Да, ты можешь. На самом деле, я предпочитаю использовать,
if(pointer)
потому что читать и писать проще, когда вы к этому привыкнете.Также обратите внимание, что в C ++ 11 введено,
nullptr
что предпочтительнее, чемNULL
.источник
if(som_integer)
vs,if(some_integer != 0)
потому что целые числа также не булевы, верно? Я предпочитаю избегать0
илиNULL
в if-утверждении.if (pointer)
себя, но мнеif (ptr != nullptr)
кажется вполне законным. С другой стороны, если бы я увидел кого-то в моей команде, который написал,if (some_integer)
я бы заставил его изменить егоif (some_integer != 0)
. Однако я не буду притворяться, что это не относительно произвольное предпочтение с моей стороны - я просто предпочитаю не обращаться с указателями и целыми числами одинаково.if(isReady)
if(filePtr)
if(serviceNo)
? Создание неправильных имен переменных не имеет большого значения в этом случае. В любом случае, я уже понял вашу точку зрения и понял ее, но я могу сам настаивать на использовании своего собственного стиля кодирования, хорошо?На вопрос дан ответ, но я бы хотел добавить свои очки.
Я всегда буду предпочитать
if(pointer)
вместоif(pointer != NULL)
иif(!pointer)
вместоif(pointer == NULL)
:Меньше шансов написать ошибочный код, предположим, что если я неправильно опишу оператор проверки равенства
==
с=
if(pointer == NULL)
ошибкой, тоif(pointer = NULL)
я буду избегать этого, лучше всего простоif(pointer)
.(Я также предложил некоторые условия Йоды в одном ответе , но это разные вопросы)
Аналогично
while (node != NULL && node->data == key)
, я просто напишу,while (node && node->data == key)
что для меня более очевидно (показывает, что используется короткое замыкание).источник
(boolean expression)? true : false
совершенно бессмысленно. Выражение оценивает либо в,true
либо вfalse
; Вы говорите: «Если это правда, дай мне правду, если это ложь, дай мне ложь». Вкратце: это полностью эквивалентно самому логическому выражению. Обратите внимание, чтоnode == NULL
это логическое выражение. Кстати, ваши две реализации возвращают в точности противоположные друг другу. Либо вы хотите!=
в первом, или только один!
во втором.=
вместо того==
, чтобы делать ваши переменные,const
когда это возможно. Например, вы можете определить свою функцию какisEmnpy(node* const head) { ... }
, и тогда компилятор откажется компилировать ее, если вы случайно написалиnode = NULL
вместоnode == NULL
. Конечно, это работает только для переменных, которые вам не нужно менять.T* get() const
вместо того,operator T*() const
чтобы избежать неявных преобразований. Однако они имеютoperator bool() const
.Явная проверка на NULL может дать подсказку компилятору о том, что вы пытаетесь сделать, что приводит к меньшей подверженности ошибкам.
источник
Да, ты можешь. Возможность неявно сравнивать значения с нулями была унаследована от C и присутствует во всех версиях C ++. Вы также можете использовать
if (!pointer)
для проверки указателей на NULL.источник
Соответствующие варианты использования для нулевых указателей
Динамические броски. Приведение указателя базового класса к конкретному производному классу (то, что вы должны снова попытаться избежать, но иногда может оказаться необходимым) всегда завершается успешно, но приводит к нулевому указателю, если производный класс не совпадает. Один из способов проверить это
(или, предпочтительно,
auto derived_ptr = ...
). Теперь это плохо, потому что он оставляет (возможно, недопустимый, то есть нулевой) производный указатель за пределами области действия защитногоif
блока. В этом нет необходимости, поскольку C ++ позволяет вводить переменные, логически конвертируемые вif
-условии :который не только короче и безопаснее по объему, но и гораздо более понятен в своем намерении: когда вы проверяете на null в отдельном условии if, читатель задается вопросом: «
derived_ptr
Хорошо, поэтому здесь не должно быть null ... ну, зачем это будет ноль? В то время как однострочная версия говорит очень просто: «Если вы можете безопасно привестиbase_ptr
кDerived*
, то используйте ее для ...».То же самое работает и для любой другой операции возможного сбоя, которая возвращает указатель, хотя в IMO следует избегать этого: лучше использовать что-то вроде
boost::optional
«контейнера» для результатов возможных неудачных операций, а не указателей.Итак, если основной сценарий использования нулевых указателей всегда должен быть написан в варианте неявного стиля приведения, я бы сказал, что по соображениям согласованности всегда следует использовать этот стиль, т. Е. Я бы рекомендовал использовать
if(ptr)
болееif(ptr!=nullptr)
.Боюсь, я должен закончить рекламой:
if(auto bla = ...)
синтаксис - это всего лишь немного громоздкое приближение к реальному решению таких проблем: сопоставление с образцом . Зачем вам сначала предпринимать какие-то действия (например, приведение указателя), а затем считать, что может произойти сбой ... Я имею в виду, это смешно, не правда ли? Как будто у вас есть продукты и вы хотите приготовить суп. Вы передаете его своему помощнику с задачей извлечь сок, если он окажется мягким овощем. Вы сначала не смотрите на это. Когда у вас есть картошка, вы все равно отдаете ее своему помощнику, но они бьют ее по лицу с запиской об ошибке. Ах, императивное программирование!Намного лучше: рассмотрите сразу все случаи, с которыми вы можете столкнуться. Тогда действуй соответственно. Haskell:
На Haskell также есть специальные инструменты для случаев, когда существует серьезная вероятность отказа (как и для целого ряда других вещей): монады. Но это не место для объяснения этого.
⟨/объявление⟩
источник
if(ptr)
а не тоif(ptr != nullptr)
, на что есть что сказать.Ну конечно; естественно! на самом деле запись if (указатель) является более удобным способом записи, чем if (pointer! = NULL), потому что: 1. это легко отладить 2. легко понять 3. если случайно, значение NULL определено, тогда и код не вылетит
источник
Да. На самом деле вы должны. Если вам интересно, если это создает ошибку сегментации , это не так.
источник
Как уже хорошо ответили другие, они оба взаимозаменяемы.
Тем не менее, стоит отметить , что может быть случай , когда вы можете использовать явное заявление, то есть
pointer != NULL
.Смотрите также https://stackoverflow.com/a/60891279/2463963
источник
Да, вы всегда можете сделать это, поскольку условие «ЕСЛИ» оценивается только тогда, когда условие внутри него сбывается. C не имеет логического возвращаемого типа и, таким образом, возвращает ненулевое значение, когда условие истинно, и возвращает 0 всякий раз, когда условие в 'IF' оказывается ложным. Ненулевое значение, возвращаемое по умолчанию, равно 1. Таким образом, оба способа написания кода верны, а я всегда предпочитаю второй.
источник
Я думаю, как правило, если ваше if-выражение может быть переписано как
так что это не вызывает никаких предупреждений, то это должно быть предпочтительным стилем для выражения if . (Я знаю, что получаю предупреждения, когда назначаю старый C
BOOL
(#define BOOL int
) для C ++bool
, не говоря уже о указателях.)источник
"Это безопасно..?" это вопрос о стандарте языка и сгенерированном коде.
"Это хорошая практика?" это вопрос о том, насколько хорошо это утверждение понято любым произвольным человеком, читающим это утверждение. Если вы задаете этот вопрос, это говорит о том, что «безопасная» версия менее понятна будущим читателям и писателям.
источник