programing

C 포인터를 NULL로 초기화할 수 있습니까?

goodsources 2022. 8. 30. 22:31
반응형

C 포인터를 NULL로 초기화할 수 있습니까?

이런 걸 쓰고 있었는데

char *x=NULL;

라는 가정하에

 char *x=2;

를 생성한다.char2번입니다.

그러나 GNU C 프로그래밍 튜토리얼에는 다음과 같이 쓰여 있습니다.int *my_int_ptr = 2; '이러다'를 합니다.2, 「」에 임의의 합니다.my_int_ptr할당되었을 때.

은 나 하는 것 .char *x=NULL하든 상관없습니다.NULL to에 char메모리 내의 임의의 주소에 대한 것입니다.

하는 동안에

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char *x=NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

실제로 인쇄가 이루어지다

특수한 순서입니다.

컴파일하여 실행할 때, 정의되지 않은 동작 또는 적어도 충분히 지정되지 않은 동작에 의존하고 있는 것이 염려됩니다.또, 이 동작에 대해서,

char *x;
x=NULL;

대신.

C 포인터를 NULL로 초기화할 수 있습니까?

, 아주 많이요. 네, 아주 많이요.


가이드의 실제 주장은 다음과 같습니다.

첫 인 '나'와 '나'만 하면,int *my_int_ptr = 2;, 프로그램은, 에 의해서 지시된 메모리 위치의 내용을 채우려고 합니다.my_int_ptr2번입니다.★★my_int_ptr 차 . ...] 로 、 is 、 is 、 쓰 is 。 [...]

글쎄, 그들이 틀렸어, 네 말이 맞아.

스테이트먼트에 대해서는 (현재로서는 정수 변환 포인터가 구현 정의 동작이라는 사실을 무시합니다.)

int * my_int_ptr = 2;

my_int_ptr)입니다.int 정수 를, 값 "는 "(정수를 저장합니다2주소로요.

그럼 이제 ㅇㅇㅇㄹㄹㄹㄹ,my_int_ptr포인터 타입이라고 할 수 있습니다.이것은 메모리 위치에 있는 "type"의 값을 가리키고 있습니다.my_int_ptr따라서 포인터가 가리키는 메모리 위치의 값이 아니라 포인터 변수의 을 할당합니다.

그래서 결론적으로 말하면

 char *x=NULL;

변수 "Initialize" 를 합니다.x로로 합니다.NULL, 포인터가 가리키는 메모리주소의 값이 아닙니다.

이것은 와 같다.

 char *x;
 x = NULL;    

확장:

자, 엄격히 준거한다면, 이런 진술은

 int * my_int_ptr = 2;

제약 위반을 수반하기 때문에 불법입니다.분명히 말씀드리면

  • my_int_ptr변수입니다.하면 됩니다.int *
  • 상수, θθ,2은 ★★★★★★★★★★★★★int으로는, 「」입니다

또, 「호환성이 있는」타입이 아니기 때문에, 이 초기화는 Lundin의 회답에 기재되어 있는 「6.5.16.1/P1」의 장에 기재되어 있는 단순한 할당의 룰에 위반되기 때문에 무효입니다.

가 간단한 되어 있는지 분이, ''를 인용하여 주십시오.C11 「」6.7.9, P11

스칼라 이니셜라이저는 단일 표현식이어야 하며 선택적으로 괄호로 묶어야 한다.객체의 초기값은 식(변환 후)의 값입니다.단순한 할당과 같은 유형의 제약변환이 적용되며 스칼라 유형이 선언된 유형의 미적용 버전이 됩니다.

튜토리얼이 틀렸다.C에서는 ISO C 서 in inint *my_int_ptr = 2;에서는 GNU C와 같은 입니다.int *my_int_ptr = (int *)2; 정수가 2컴파일러에 의해 결정되는 어떤 방식으로든 메모리 주소로 이동합니다.

그 주소(있는 경우)로 주소 지정된 위치에 아무것도 저장하려고 하지 않습니다. 계속 쓴다면,*my_int_ptr = 5;5해당 주소로 주소 지정된 위치에 있습니다.

하기 을 하십시오.int *my_int_ptr = 2;는 " 위반컴파일이 했을 때 해야 합니다.

6.5.16.1에 따라 간단한 할당:

제약

다음 중 하나가 유지되어야 한다.

  • 왼쪽 피연산자는 원자, 적격 또는 부적격 산술 유형을 가지며, 오른쪽 피연산자는 산술 유형을 가진다.
  • 왼쪽 피연산자는 오른쪽 유형과 호환되는 구조 또는 결합 유형의 원자, 적격 또는 부적격 버전을 가진다.
  • 왼쪽 피연산자는 원자성, 정규화 또는 비수식 포인터 타입을 가지고 있으며 (lvalue 변환 후 왼쪽 피연산자가 가질 수 있는 타입을 고려하여) 양쪽 피연산자는 호환 가능한 타입의 정규화 또는 비수식 버전을 가리키는 포인터이며 왼쪽 피연산자는 오른쪽을 가리키는 타입의 모든 수식자를 가집니다.
  • 왼쪽 피연산자는 원자성, 정규화 또는 비수식 포인터 타입을 가지고 있으며 (lvalue 변환 후 왼쪽 피연산자가 가질 수 있는 타입을 고려하여) 한쪽 피연산자는 오브젝트 타입에 대한 포인터이며 다른 한쪽 피연산자는 정규화 또는 비수식 버전의 void에 대한 포인터이며 왼쪽 피연산자는 에 의해 지시된 타입의 모든 수식자를 가지고 있습니다.오른쪽
  • 왼쪽 피연산자는 원자성, 수식 또는 비수식 포인터이며 오른쪽은 늘 포인터 상수입니다.
  • 왼쪽 오퍼랜드에는 atomic, qualified 또는 unqualified _Bool 유형이 있으며 오른쪽은 포인터입니다.

이 경우 왼쪽 피연산자는 한정되지 않은 포인터입니다.오른쪽 피연산자가 정수(산술형)가 될 수 있다는 것은 어디에도 언급되어 있지 않습니다.그래서 코드가 C 기준을 위반하는군요.

GCC는 표준 C 컴파일러라고 명시적으로 지시하지 않는 한 제대로 동작하지 않는 것으로 알려져 있습니다.코드를 다음과 같이 컴파일하면-std=c11 -pedantic-errors필요한 대로 진단할 수 있습니다.

나는 많은 훌륭한 답변에 직교적인 것을 추가하고 싶다.실제로 초기화 중NULL는 잘못된 관행과는 거리가 멀며 동적으로 할당된 메모리 블록을 저장하기 위해 포인터를 사용할 수도 있고 사용하지 않을 수도 있습니다.

int * p = NULL;
...
if (...) {
    p = (int*) malloc(...);
    ...
}
...
free(p);

ISO-IEC 9899 표준에 따라 free일 경우 .NULL 같은 행에 더 있는 것한 코드입니다.

이게 맞아요.

int main()
{
    char * x = NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

이 함수는 그 기능에 대해 정확합니다.char pointer x 에 주소 0 을 할당합니다.즉, 포인터x 가 메모리주소 0 을 가리키고 있습니다.

다른 방법:

int main()
{
    char* x = 0;

    if ( !x )
        printf(" x points to NULL\n");

    return EXIT_SUCCESS;
}

당신이 원하는 것은 다음과 같습니다.

int main()
{
    char* x = NULL;
    x = alloc( sizeof( char ));
    *x = '2';

    if ( *x == '2' )
        printf(" x points to an address/location that contains a '2' \n");

    return EXIT_SUCCESS;
}

x is the street address of a house. *x examines the contents of that house.

C 포인터에 대한 많은 혼란은 원래 코딩 스타일에 관해 만들어진 매우 나쁜 선택에서 비롯되며, 이는 언어의 구문에서 매우 나쁜 작은 선택으로 증명됩니다.

int *x = NULL;C는 맞지만, 그것은 매우 오해의 소지가 있다, 심지어 말도 안 된다고 말할 수 있다, 그리고 그것은 많은 초보자들에게 언어의 이해를 방해하고 있다..*x = NULL;론론불불불불불불은 「」이 int 변수 이 '아니다'가 '아니다.*x 「 」도, 「 」*에, in in in in in in in in in in in in in in in in in in in 와 연계하여 역할을 한다.=그것은 순전히 선언적인 것이다.그래서 더 말이 되는 것은 다음과 같습니다.

int* x = NULL;또한 C가 맞지만 원래의 K&R 코딩 스타일에 부합하지는 않습니다. 알 수 있다.int*는 '먹다' 입니다x 처음 에게도 그 NULL is is is is is is 。xint

또한 이 기능을 사용하면 규칙 도출이 쉬워집니다.별이 변수 이름에서 떨어져 있으면 선언이 되고 이름에 연결된 별은 포인터 참조가 됩니다.

이제 좀 더 더 할 수 것 같아요.x = NULL; ★★★★★★★★★★★★★★★★★」*x = 2;, 알 수 .variable = expressionpointer-type variable = pointer-expression ★★★★★★★★★★★★★★★★★」dereferenced-pointer-variable = expression('rvalue'는 'rvalue'는 'rvalue'는 'rvalue'가 되다)

은 지역 때 '어느 쪽으로 가야 한다'고 말할 수 입니다.int i, *p;에 '정수', ' '정수', '정수', '정수', '정수', '정수'를 알 수.*는 이름의 유용한 부분입니다.하지만 그렇지 않습니다. 그리고 이 구문은 단지 편의상 추가된 기발한 특수한 경우일 뿐이고, 제 생각에는 존재하지 말았어야 했습니다. 왜냐하면 그것은 제가 위에서 제안한 규칙을 무효화시키기 때문입니다.제가 알기로는 이 구문이 의미가 있는 언어는 다른 곳도 없습니다만, 의미가 있다고 해도 포인터 타입이 C에서 정의되는 방법의 불일치를 나타내고 있습니다.이외의 단일 선언, 목록구조체 멤버 를 " ", ", ", ", ", ", ", ", "로 선언할 수 .type* pointer-variabletype *pointer-variable; 그것은 완벽하게 합법적이고 더 말이 된다.

int *my_int_ptr = 2

는 정수값 2를 할당 시 my_int_ptr 내의 임의의 임의의 주소에 저장합니다.

이건 완전히 잘못됐어.만약 이것이 실제로 쓰여져 있다면 더 좋은 책이나 튜토리얼을 구해주세요.

int *my_int_ptr = 2, 2. 의 2 를 하는 합니다. 에 이 높습니다.2

*my_int_ptr = 2 (예: 미포, the the)를 사용하지 )int값 를 임의의 2에 합니다.my_int_ptr을 사용하다 나면 ' 때', '어느 때', '어느 때'를 수 있어요.NULL포인터가 정의되면 포인터로 이동합니다. char *x=NULL;다니다

편집: 이 글을 쓰는 동안 포인터로 변환하는 정수가 구현 정의 동작인지 몰랐습니다.@M의 좋은 답변을 보세요.자세한 내용은 M 및 @SouravGhosh를 참조하십시오.

이것은 늘 포인터입니다.

int * nullPtr = (void*) 0;

언급URL : https://stackoverflow.com/questions/43338084/is-it-possible-to-initialize-a-c-pointer-to-null

반응형