C 포인터를 NULL로 초기화할 수 있습니까?
이런 걸 쓰고 있었는데
char *x=NULL;
라는 가정하에
char *x=2;
를 생성한다.char
2번입니다.
그러나 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_ptr
2번입니다.★★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 。x
int
또한 이 기능을 사용하면 규칙 도출이 쉬워집니다.별이 변수 이름에서 떨어져 있으면 선언이 되고 이름에 연결된 별은 포인터 참조가 됩니다.
이제 좀 더 더 할 수 것 같아요.x = NULL;
★★★★★★★★★★★★★★★★★」*x = 2;
, 알 수 .variable = expression
pointer-type variable = pointer-expression
★★★★★★★★★★★★★★★★★」dereferenced-pointer-variable = expression
('rvalue'는 'rvalue'는 'rvalue'는 'rvalue'가 되다)
은 지역 때 '어느 쪽으로 가야 한다'고 말할 수 입니다.int i, *p;
에 '정수', ' '정수', '정수', '정수', '정수', '정수'를 알 수.*
는 이름의 유용한 부분입니다.하지만 그렇지 않습니다. 그리고 이 구문은 단지 편의상 추가된 기발한 특수한 경우일 뿐이고, 제 생각에는 존재하지 말았어야 했습니다. 왜냐하면 그것은 제가 위에서 제안한 규칙을 무효화시키기 때문입니다.제가 알기로는 이 구문이 의미가 있는 언어는 다른 곳도 없습니다만, 의미가 있다고 해도 포인터 타입이 C에서 정의되는 방법의 불일치를 나타내고 있습니다.이외의 단일 선언, 목록구조체 멤버 를 " ", ", ", ", ", ", ", ", "로 선언할 수 .type* pointer-variable
type *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
'programing' 카테고리의 다른 글
상태 변경 시 Vuex getter가 업데이트되지 않음 (0) | 2022.08.30 |
---|---|
디렉토리를 소스 트리에서 바이너리 트리로 복사하는 방법 (0) | 2022.08.30 |
C 포인터에서 어레이 크기를 가져오려면 어떻게 해야 합니까? (0) | 2022.08.30 |
파일을 압축/해동하기 좋은 Java 라이브러리는 무엇입니까? (0) | 2022.08.30 |
VueJ는 프로포트를 데이터 속성 가치로 사용 (0) | 2022.08.30 |