programing tip

if (포인터! = NULL) 대신 if (포인터)를 사용할 수 있습니까?

itbloger 2020. 5. 30. 22:14
반응형

if (포인터! = NULL) 대신 if (포인터)를 사용할 수 있습니까?


그것은되지 않는 포인터를 확인하는 것이 안전합니다 NULL간단하게 작성하여 if(pointer)또는 내가 사용해야합니까 if(pointer != NULL)?


당신은 할 수 있습니다; 널 포인터는 내재적으로 부울 false로 변환되고 널이 아닌 포인터는 true로 변환됩니다. C ++ 11 표준에서 부울 변환 섹션에서 :

산술, 범위가 지정되지 않은 열거 형, 포인터 또는 멤버 형식에 대한 포인터의 전가는 유형의 전가로 변환 될 수 있습니다 bool. 0 값, 널 포인터 값 또는 널 멤버 포인터 값은로 변환됩니다 false. 다른 값은로 변환됩니다 true. 유형의 prvalue는 유형의 prvalue std::nullptr_t로 변환 될 수 있습니다 bool. 결과 값은 false입니다.


예, 가능합니다.

  • 널 포인터는 내재적으로 false로 변환됩니다.
  • 널이 아닌 포인터는 true로 변환됩니다.

이것은 부울 변환 절에 해당하는 C ++ 표준 변환의 일부입니다 .

4.12 부울 변환

산술, 범위가 지정되지 않은 열거 형, pointer 또는 멤버 유형에 대한 포인터의 값은 bool 유형의 prvalue로 변환 될 수 있습니다. 0 값, 널 포인터 값 또는 널 멤버 포인터 값은 false로 변환됩니다. 다른 값은 true로 변환됩니다. std :: nullptr_t 유형의 prvalue는 bool 유형의 prvalue로 변환 될 수 있습니다. 결과 값은 false입니다.


그래 넌 할수있어. 사실, if(pointer)익숙해지면 읽고 쓰는 것이 더 간단하기 때문에 사용하는 것을 선호 합니다.

또한 C ++ 11 nullptr이 더 선호 된다는 점에 유의하십시오 NULL.


질문에 대한 답변이 있지만 포인트를 추가하고 싶습니다.

난 항상 선호하는 것 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)나에게 더 분명한 것입니다 (단락을 사용한다는 것을 보여줍니다).

  • (멍청한 이유 일 수 있습니다) NULL은 매크로이기 때문에 실수로 다른 값으로 재정의한다고 가정하면.

명시 적으로 NULL을 검사하면 컴파일러가 수행하려는 작업에 대한 힌트를 제공하여 오류가 덜 발생합니다.

여기에 이미지 설명을 입력하십시오


그래 넌 할수있어. 값을 0과 비교하는 기능은 암시 적으로 C에서 상속되었으며 모든 버전의 C ++에 있습니다. if (!pointer)NULL에 대한 포인터를 확인 하는 사용할 수도 있습니다 .


널 포인터의 관련 사용 사례는 다음과 같습니다.

  • 존재하지 않거나 아직 연결되지 않은 더 깊은 트리 노드로 리디렉션 그것은 항상 헌신적 인 클래스에서 밀접하게 캡슐화 해야하는 것이므로 가독성이나 간결성은 그다지 문제가되지 않습니다.
  • 다이나믹 캐스트. 특정 파생 클래스 포인터에 기본 클래스 포인터를 캐스트하면 (다시 피하려고하지만 때때로 필요할 수도 있음) 항상 성공하지만 파생 클래스가 일치하지 않으면 널 포인터가됩니다. 이것을 확인하는 한 가지 방법은

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

    (또는 바람직하게는 auto derived_ptr = ...). 이제 이것은 안전 보호 if블록의 범위 밖에 (유효하지 않은, 즉 null) 파생 포인터를 남겨두기 때문에 좋지 않습니다 . C ++에서는 부울 변환 가능 변수 if-condition 내에 도입 할 수 있으므로 필요하지 않습니다 .

    if(auto derived_ptr = dynamic_cast<Derived*>(base_ptr)) { ... }
    

    더 짧고 범위가 안전 할뿐만 아니라 의도가 훨씬 더 명확합니다. 별도의 if 조건에서 null을 검사 할 때 독자는 "좋습니다. derived_ptr여기서 null이 아니어야합니다 ... 글쎄, 왜 그런 것입니까?" null입니까? " 한 줄 버전이 매우 분명하게 말한다 반면 "당신이 안전하게 캐스트 할 수있는 경우 base_ptrDerived*, 다음을 위해 사용 ...".

    IMO는 일반적으로 이것을 피해야하지만 포인터를 반환하는 다른 가능한 실패 작업에도 동일하게 작동합니다. 포인터가 boost::optional아닌 작업 실패의 결과에 대해 "컨테이너" 와 같은 것을 사용하는 것이 좋습니다 .

So, if the main use case for null pointers should always be written in a variation of the implicit-cast-style, I'd say it's good for consistency reasons to always use this style, i.e. I'd advocate for if(ptr) over if(ptr!=nullptr).


I'm afraid I have to end with an advert: the if(auto bla = ...) syntax is actually just a slightly cumbersome approximation to the real solution to such problems: pattern matching. Why would you first force some action (like casting a pointer) and then consider that there might be a failure... I mean, it's ridiculous, isn't it? It's like, you have some foodstuff and want to make soup. You hand it to your assistant with the task to extract the juice, if it happens to be a soft vegetable. You don't first look it at it. When you have a potato, you still give it to your assistant but they slap it back in your face with a failure note. Ah, imperative programming!

Much better: consider right away all the cases you might encounter. Then act accordingly. Haskell:

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

Haskell also has special tools for when there is really a serious possibility of failure (as well as for a whole bunch of other stuff): monads. But this isn't the place for explaining those.

⟨/advert⟩


Yes. In fact you should. If you're wondering if it creates a segmentation fault, it doesn't.


yes, of course! in fact, writing if(pointer) is a more convenient way of writing rather than if(pointer != NULL) because: 1. it is easy to debug 2. easy to understand 3. if accidently, the value of NULL is defined, then also the code will not crash


Yes, you can always do this as 'IF' condition evaluates only when the condition inside it goes true. C does not have a boolean return type and thus returns a non-zero value when the condition is true while returns 0 whenever the condition in 'IF' turns out to be false. The non zero value returned by default is 1. Thus, both ways of writing the code are correct while I will always prefer the second one.


I think as a rule of thumb, if your if-expression can be re-written as

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

such that it causes NO WARNINGS, then THAT should be the preferred style for the if-expression. (I know I get warnings when I assign an old C BOOL (#define BOOL int) to a C++ bool, let alone pointers.)


"Is it safe..?" is a question about the language standard and the generated code.

"좋은 습관입니까?" 이 문장의 독자적인 독자가 그 문장을 얼마나 잘 이해하는지에 대한 질문입니다. 이 질문을한다면, "안전한"버전은 미래의 독자와 작가에게 덜 명확하다는 것을 암시합니다.

참고 URL : https://stackoverflow.com/questions/17772103/can-i-use-if-pointer-instead-of-if-pointer-null

반응형