그것은되지 않는 포인터를 확인하는 것이 안전합니다 NULL간단하게 작성하여 if(pointer)또는 내가 사용해야합니까 if(pointer != NULL)?
NULL이므로 C ++ 에서는 사용하지 않아야합니다 NULL.
그것은되지 않는 포인터를 확인하는 것이 안전합니다 NULL간단하게 작성하여 if(pointer)또는 내가 사용해야합니까 if(pointer != NULL)?
NULL이므로 C ++ 에서는 사용하지 않아야합니다 NULL.
답변:
당신은 할 수 있습니다; 널 포인터는 내재적으로 부울 false로 변환되고 널이 아닌 포인터는 true로 변환됩니다. C ++ 11 표준에서 부울 변환 섹션에서 :
산술, 범위가 지정되지 않은 열거 형, 포인터 또는 멤버 형식에 대한 포인터의 전가는 유형의 전가로 변환 될 수 있습니다
bool. 0 값, 널 포인터 값 또는 널 멤버 포인터 값은로 변환됩니다false. 다른 값은로 변환됩니다true. 유형의 prvalue는 유형의 prvaluestd::nullptr_t로 변환 될 수 있습니다bool. 결과 값은false입니다.
예, 가능합니다.
이것은 부울 변환 절에 해당하는 C ++ 표준 변환의 일부입니다 .
4.12 부울 변환
산술, 범위가 지정되지 않은 열거 형, pointer 또는 멤버 유형에 대한 포인터의 값은 bool 유형의 prvalue로 변환 될 수 있습니다. 0 값, 널 포인터 값 또는 널 멤버 포인터 값은 false로 변환됩니다. 다른 값은 true로 변환됩니다. std :: nullptr_t 유형의 prvalue는 bool 유형의 prvalue로 변환 될 수 있습니다. 결과 값은 false입니다.
그래 넌 할수있어. 사실, if(pointer)익숙해지면 읽고 쓰는 것이 더 간단하기 때문에 사용하는 것을 선호 합니다.
또한 C ++ 11 nullptr이 더 선호 된다는 점에 유의하십시오 NULL.
if(som_integer)vs에 적용 할 수 있습니다 if(some_integer != 0). 나는 진술 을 피 0하거나 NULL진술하는 것을 선호 합니다.
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부울 식입니다. BTW, 두 구현은 서로 정확히 반대를 반환합니다. !=첫 번째 또는 !두 번째 중 하나만 원합니다 .
=대신 가능한 하나의 보호는 가능할 때마다 ==변수를 만드는 것 const입니다. 예를 들어 함수를로 정의한 isEmnpy(node* const head) { ... }다음 실수로 node = NULL대신 쓰면 컴파일러에서 컴파일을 거부합니다 node == NULL. 물론 변경하지 않아도되는 변수에 대해서만 작동합니다.
T* get() const대신 operator T*() const암시 적 변환을 방지 할 수 있습니다. 그러나 그들은 있습니다 operator bool() const.
그래 넌 할수있어. 값을 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_ptr에 Derived*, 다음을 위해 사용 ...".
IMO는 일반적으로 이것을 피해야하지만 포인터를 반환하는 다른 가능한 실패 작업에도 동일하게 작동합니다. 포인터가 boost::optional아닌 작업 실패의 결과에 대해 "컨테이너" 와 같은 것을 사용하는 것이 좋습니다 .
널 포인터의 주요 사용 사례는 항상 암시 적 캐스트 스타일의 변화에 작성해야한다면, 나는에 일관성 이유로 그것의 좋은 말하고 싶지만 항상 내가 옹호 것 즉,이 스타일을 사용하는 if(ptr)동안 if(ptr!=nullptr).
나는 광고로 끝내야 할 것을 두려워합니다. if(auto bla = ...)구문은 실제로 그러한 문제 에 대한 실제 솔루션에 약간의 성가신 근사치입니다 : 패턴 일치 . 왜 먼저 (포인터 캐스팅과 같은) 어떤 행동을 강요하고 실패가 있다고 생각합니까? 마치 음식이 있고 수프를 만들고 싶어하는 것과 같습니다. 주스가 부드러운 채소 인 경우 주스 추출 작업을 통해 조수에게 전달합니다. 먼저 보지 마십시오. 감자를 먹었을 때 여전히 조수에게 먹이를 주지만 실패 메모와 함께 얼굴에 다시 때립니다. 아, 명령형 프로그래밍!
훨씬 낫습니다. 발생할 수있는 모든 사례를 즉시 고려하십시오. 그런 다음 그에 따라 행동하십시오. 하스켈 :
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은 또한 심각한 장애 가능성이있을 때 (그리고 다른 많은 것들도 포함) 모나드를위한 특별한 도구를 가지고 있습니다. 그러나 이것은 그것들을 설명하는 장소가 아닙니다.
⟨/ 광고
if(ptr)하는 이유를 알기 위해 적절한 이유를 제시하려고 노력했습니다 if(ptr != nullptr).
다른 사람들이 이미 잘 대답 했으므로 둘 다 상호 교환 가능합니다.
그럼에도 불구하고 명시 적 진술을 사용하고 싶을 수도 있습니다 pointer != NULL.
"안전 해요..?" 언어 표준과 생성 된 코드에 대한 질문입니다.
"좋은 습관입니까?" 이 문장의 독자적인 독자가 그 문장을 얼마나 잘 이해하는지에 대한 질문입니다. 이 질문을한다면, "안전한"버전은 미래의 독자와 작가에게 덜 명확하다는 것을 암시합니다.
0또는 에 대해 테스트하는 것만큼이나 효과적nullptr입니다. (NULLC'ism이며 헤더 파일을 포함해야합니다.)