sourcecode

값 0 대신 NULL을 사용할 수 있습니까?

copyscript 2022. 8. 14. 12:23
반응형

값 0 대신 NULL을 사용할 수 있습니까?

를 사용할 수 있습니까?NULL값을 대체하는 포인터0?

아니면 그렇게 하는 게 잘못된 건가요?


예를 들어 다음과 같습니다.

int i = NULL;

대체품:

int i = 0;

실험으로 다음 코드를 컴파일했습니다.

#include <stdio.h>

int main(void)
{
    int i = NULL;
    printf("%d",i);

    return 0;
}

출력:

0

정말이지 이 경고는 그 자체로 완전히 옳다.

warning: initialization makes integer from pointer without a cast [-Wint-conversion] 

결과는 똑같아요.


  • '정의되지 않은 행동'으로 넘어가는 건가요?
  • 사용 가능합니까?NULL이런 식으로요?
  • 를 사용하는 데 문제가 있습니까?NULL산술식의 수치로 사용할 수 있을까요?
  • 그리고 이 경우 C++에서의 결과와 동작은 어떻게 됩니까?

'NULL, '\0', '0'과 '0'의 차이는 무엇인가'의 답변을 읽어 보았습니다.NULL,\0그리고.0하지만, 나는 거기서 간결한 정보를 얻지 못했다. 만약 그것이 꽤 허용 가능하고 또한 사용할 권리가 있다면NULL할당 및 기타 산술 연산에 사용할 값으로 사용됩니다.

값 0을 대체할 NULL 포인터를 사용할 수 있습니까?

아니요, 그렇게 하는 것은 안전하지 않습니다. NULLnull-displict 상수입니다.유형일 수 있습니다.int단, 일반적으로 타입이 있는 것은 어느 쪽입니다.void *(C에서) 또는 다른 방법으로 직접 할당할 수 없습니다.int(C++ >= 11).두 언어 모두 포인터를 정수로 변환할 수 있지만 이러한 변환이 암묵적으로 수행되도록 하지는 않습니다(단, 일부 컴파일러는 이를 확장으로 제공함).또한 값 0을 얻기 위해 늘 포인터를 정수로 변환하는 것이 일반적이지만, 표준에서는 이를 보장하지 않습니다.유형이 있는 상수를 원하는 경우int값 0을 입력해 주세요.0.

  • 내가 이걸로 정의되지 않은 행동을 하게 될까?

네, 모든 구현에서NULL유형에 따라 값으로 확장하다void *또는 직접 할당할 수 없는 다른 모든 것int표준에서는, 이러한 실장에서의 할당의 동작은 정의되어 있지 않습니다.그 동작은 정의되어 있지 않습니다.

  • 그런 식으로 NULL로 작동해도 될까요?

이것은 서투른 스타일이며, 시스템에 따라서는 상황에 따라서는 파손될 수 있습니다.GCC 를 사용하고 있는 것처럼 보이므로, GCC 를 사용해 컴파일 했을 경우는, 독자적인 예에 들어가 버립니다.-Werror선택.

  • 산술식에서 NULL을 수치로 사용하는 데 문제가 있습니까?

네. 수치가 전혀 보장되지 않습니다.0을 의미하는 경우 0을 적습니다. 0은 잘 정의되어 있을 뿐만 아니라 짧고 명료합니다.

  • 그리고 그 경우 C++의 결과는 어떻게 됩니까?

C++ 언어는 C 언어보다 변환에 대해 엄격하며 다른 규칙을 가지고 있습니다.NULL단, 실장에서는 확장을 제공할 수도 있습니다.다시 한 번, 0을 의미한다면 그렇게 써야 합니다.

NULL는 어떤 늘 포인터 상수입니다.C에서는 값이 있는 정수 상수 식일 수 있습니다.0혹은 그런 표현은void*후자의 가능성이 높아집니다. 말은 즉, 당신이 이 모든 것을NULL0과 교환할 수 있습니다.예를 들어 이 코드 샘플에서는

char const* foo = "bar"; 
foo + 0;

교환0와 함께NULL는, 2개의 포인터간의 추가(다른 포인터 타입의 추가는 말할 것도 없고)가 정의되어 있지 않기 때문에, 유효한 C 프로그램이 되는 것은 보증되지 않습니다.제약 위반으로 진단이 발행됩니다.추가할 피연산자는 유효하지 않습니다.


C++로 하다「」로부터의 .void*는, 「다음에 있다」를 의미하고 있습니다.NULL was was was was was was was was was was was was was로 되었다.0C++ 코드로 표시됩니다.C++03 에서는, 아마 회피할 수 있을 것입니다.단, C++11부터는 법적으로 키워드로 정의할 수 있습니다.다시 오류가 발생합니다.std::nullptr_t을 사용법

ifNULL되어 있습니다.nullptr당신의 실험조차도 무효가 됩니다.할 수 없다std::nullptr_t정수로 변환합니다.이것이 보다 안전한 늘 포인터 상수로 간주되는 이유입니다.

값 0을 대체하기 위해 NULL 포인터를 사용할 수 있습니까?

int i = NULL;

규칙은 언어와 버전에 따라 다릅니다. 수 있는 경우도 있고 할 수 없는 경우도 있습니다.어쨌든, 당신은 그러지 말아야 해요.운이 좋으면 컴파일러가 컴파일 실패에 대해 경고합니다.

C++에서는 C++11 이전(C++03에서 인용):

[lib.support.types]

NULL은 이 국제 표준에서 구현 정의 C++ NULL 포인터 상수입니다.

늘 포인터 상수를 정수로 사용하는 것은 의미가 없습니다.하지만...

[conv.pdr]

Null 포인터 상수는 0으로 평가되는 정수 유형의 정수 상수 식(5.19) r 값입니다.

그러니까, 이건 말도 안 되는 소리일지라도 기술적으로 효과가 있을 거야. 때문에, 「이러한 프로그램」을 하는, 기술되지 할 가능성이 .NULL.

C++11(최신 초안 인용):

[conv.pdr]

늘 포인터 상수는 값이 0인 정수 리터럴([lex.icon]) 또는 유형 std::nullptr_µt의 pr값입니다.

A std​::​nullptr_­t할 수 에, 「」를 사용합니다.NULL정수는 언어 구현에 의해 이루어진 선택에 따라 조건부로만 작동하기 때문입니다.

nullptr는 "" 유형의 입니다.std​::​nullptr_­t이 아닌 한 C++11 이전 컴파일을 해야 합니다.nullptrNULL.


C는 조금 다릅니다(C11 드래프트 N1548에서 인용).

6.3.2.3 언어 / 변환 / 기타 오퍼랜드 / 포인터

3 값이 0인 정수 상수 표현식 또는 타입에 캐스트된 표현식은 늘 포인터 상수라고 불립니다. ...

, 즉 C++11을 .NULL는 언어 구현에 의한 선택에 따라 조건부로 동작합니다.

, 하지만 구현에 따라서는 깁스가 필요할 수도 있습니다.하지만 그래, 그렇지 않으면 100% 합법이야.

정말, 정말, 정말 나쁜 스타일이지만(말할 필요도 없습니다.

NULLC++가 아닌 C입니다.단, 표준에는 많은 C레거시처럼 기술적으로 다음과 같은2개의 구([diff.null]및 [support.types.nullptr])가 있습니다.NULLC++. 구현 정의 null-pointer 상수입니다.그렇기 때문에 아무리 나쁜 스타일이라도 엄밀히 말하면 C++입니다.
각주에서 지적된 바와 같이 가능한 구현은 다음과 같습니다.0 ★★★★★★★★★★★★★★★★★」0L, 그러나 아니다. (void*)0.

NULL (에는 그렇게 입니다.)0 ★★★★★★★★★★★★★★★★★」0L가 되다.nullptr거의 그렇지 않지만 법적 가능성은 있습니다.

컴파일러가 사용자에게 보여준 경고는 컴파일러가 실제로는 비준수임을 나타냅니다(C 모드로 컴파일하지 않는 한).경고에 따르면 Null 포인터를 변환했기 때문입니다(NULL 포인터가 아님).nullptr 쪽이 좋을까nullptr_t, 즉, (그것은 구별될 것이다)의 가 되어 하는 것입니다.NULL(void*)0아닐 수도 있지만요

어느 쪽이든, 2개의 정규 케이스(파손되지 않은 컴파일러)가 있습니다.인 경우 (실제적인 경우), (실제적인 경우), (실제적인 경우), (실제적인 경우), (실제적인 경우), (인 경우),NULL뭐랄까0또는0L「0 또는 1의 정수로의 변환이 있으면, 즉시 사용할 수 있습니다.

또는NULL정말이다nullptr이 경우 비교와 정수의 명확한 변환이 보장되지만 불행히도 정수로 변환되지 않는 고유한 값이 있습니다.단, 명확하게 변환되어 있습니다.bool(에 추가)false, 및bool명확하게 정의되어 있는 정수 변환이 있다(에 기재되어 있다.0).

공교롭게도 두 개의 변환이므로 [conv]에서 지적한 바와 같이 "0 또는 1" 내에 있지 않습니다.따라서 구현에 의해 정의되는 경우NULL~하듯이nullptr코드를 올바르게 하려면 , 명시적인 캐스트를 추가할 필요가 있습니다.

C FAQ:

Q: NULL과 0이 NULL 포인터 상수와 동일한 경우 어떤 것을 사용해야 합니까?

A: 포인터 컨텍스트에서만NULL그리고.0동등합니다. NULL다른 종류의 0이 필요할 때는 사용하지 마십시오.그렇게 하면 잘못된 스타일 메시지가 전송되기 때문입니다.(또한 ANSI를 사용하면 NULL의 정의를 사용할 수 있습니다).((void *)0)는, 비패키지 콘텍스트에서는 전혀 동작하지 않습니다).특히 사용하지 마십시오.NULLASCII Null 문자(NUL)가 필요한 경우.독자적인 정의를 제공하다

http://c-faq.com/null/nullor0.html

아니요, 더 이상 사용하지 않습니다.NULL(구식 포인터 초기화 방식).

C++11 이후:

키워드nullptr는 포인터 리터럴을 나타냅니다.std::nullptr_t 유형의 prvalue입니다.에서 암묵적인 변환이 존재합니다.nullptr포인터 유형 및 멤버 유형에 대한 포인터 값을 null로 지정합니다.유형의 값을 포함하는 모든 null 포인터 상수에 대해 유사한 변환이 존재합니다.std::nullptr_t매크로뿐만 아니라NULL.

https://en.cppreference.com/w/cpp/language/nullptr

실제로 std::nullptr_t는 늘 포인터 리터럴의 유형입니다.nullptr포인터 타입이나 멤버 타입에 대한 포인터 타입이 아닌 독자적인 타입입니다.

#include <cstddef>
#include <iostream>

void f(int* pi)
{
   std::cout << "Pointer to integer overload\n";
}

void f(double* pd)
{
   std::cout << "Pointer to double overload\n";
}

void f(std::nullptr_t nullp)
{
   std::cout << "null pointer overload\n";
}

int main()
{
    int* pi; double* pd;

    f(pi);
    f(pd);
    f(nullptr);  // would be ambiguous without void f(nullptr_t)
    // f(0);  // ambiguous call: all three functions are candidates
    // f(NULL); // ambiguous if NULL is an integral null pointer constant 
                // (as is the case in most implementations)
}

출력:

Pointer to integer overload
Pointer to double overload
null pointer overload

면책사항:C++ 몰라요.내 답변은 C++의 문맥에 적용되는 것이 아니다.

'\0'는 입니다.int값이 0일 때 100% 똑같습니다.0.

for (int k = 10; k > '\0'; k--) /* void */;
for (int k = 10; k > 0; k--) /* void */;

포인터의 맥락에서 보면0그리고.NULL100% 등가:

if (ptr) /* ... */;
if (ptr != NULL) /* ... */;
if (ptr != '\0') /* ... */;
if (ptr != 0) /* ... */;

모두 100% 동등합니다.


에 대해 주의사항ptr + NULL

의 컨텍스트ptr + NULL포인터의 그런 게 아니에요.C 언어의 포인터 추가에 대한 정의는 없습니다. 포인터와 정수는 추가(또는 감산)할 수 있습니다.ptr + NULL어느 쪽이든ptr또는NULL포인터, 다른 하나는 정수여야 합니다.ptr + NULL효과적으로(int)ptr + NULL또는ptr + (int)NULL의 정의에 따라 달라집니다.ptr그리고.NULL몇 가지 동작을 예상할 수 있습니다.모든 동작, 포인터와 정수 사이의 변환에 대한 경고, 컴파일 실패 등입니다.

언급URL : https://stackoverflow.com/questions/59437282/can-i-use-null-as-substitution-for-the-value-of-0

반응형