programing

포인터 또는 주소를 인쇄할 올바른 형식 지정자입니까?

coolbiz 2022. 7. 4. 23:08
반응형

포인터 또는 주소를 인쇄할 올바른 형식 지정자입니까?

변수의 주소를 인쇄하려면 어떤 형식 지정자를 사용해야 합니까?나는 아래 로트를 헷갈린다.

%u - 부호 없는 정수

%x - 16진수 값

%p - 보이드 포인터

주소를 인쇄하는 데 가장 적합한 형식은 무엇입니까?

은 플랫폼마다의 할 때 입니다.%p표기법

C99 표준(ISO/IEC 9899:1999)은 § 7.19.6.1 8에 다음과 같이 기술되어 있다.

p는 그수는 the the the the the to to to to to to to에 대한 .void포인터의 값은 구현 정의 방식으로 일련의 인쇄 문자로 변환됩니다.

(C11 - ISO/IEC 9899:2011 )7.21.6.1 8에 기재되어 있습니다).

, 의 「」가 포함됩니다.0x그 외의 경우는 그렇지 않습니다.이치노C 규격에서는 16진수 출력이라고 정의되어 있지 않습니다.C 규격에서는 16진수 출력이라고 정의되어 있지 않습니다.

여부는 가 있습니다.(void *)명료하게 , 것(가 하는 일이고, ''라고. 그것은 보통 좋은 것이다(그래서 그것은 내가 하는 것이다). 그리고 기준은 '논쟁은 에 대한 포인터가 되어야 한다'고 말한다.void배역을 합니다.' 대부분의 기계에서 명시적 배역을 생략해도 무방합니다.에서는 ,, 신, 신, 신의 표현이 중요합니다.char *지정된 메모리 위치의 주소가 동일한 메모리 위치의 'anything other pointer' 주소와 다릅니다.이것은 바이트 주소가 아닌 워드 주소가 지정된 기계입니다.요즘은 그런 기계가 흔하지 않지만(아마도 구할 수 없을 것입니다), 대학 졸업 후 처음 작업한 기계는 그런 기계(ICL Perq)였습니다.

의 구현 정의 %p C99 를 <inttypes.h> ★★★★★★★★★★★★★★★★★」uintptr_t★★★★

printf("0x%" PRIXPTR "\n", (uintptr_t)your_pointer);

이를 통해 사용자 자신에게 맞게 표현을 미세 조정할 수 있습니다. 16진수 했습니다.0xA1B2CDEF 식으로 0xa1b2cdef번호에 따라 위아래로 내려갑니다.하지만 아주 넓은 범위 내에서 선택할 수 있습니다.(uintptr_t) 수 에 의해 됩니다.출연자를 요청하는 것이 옳다고 생각하지만, 경고를 무시하고 넘어가는 사람들도 있을 거예요.


Kerrek은 코멘트에서 다음과 같이 묻습니다.

나는 표준 승진과 변종 논쟁에 대해 조금 혼란스럽다.모든 포인터는 표준 프로모션으로 void*로 되어 있습니까? 이외의 「」의 경우.int*를 들어와 "입니다.void*인수에서 가 .4.바이트라면 인수에서 4바이트를 읽는 것은 분명히 오류일 것입니다.

의 사이즈는것 때문에, C의 사이즈는 해야 한다, 라고 착각하고 있습니다.void * ★★★★★★★★★★★★★★★★★」int *사이즈는 다를 수 없습니다.되어 있지 잘 만): 99 、 C99 표 、 c 、 지 、 지 、 (지 ( 가 however지 ) 。

§ 6.2.5 타입

26 무효 포인터는 문자 39)형식의 포인터와 동일한 표현 및 정렬 요건을 가져야 한다.마찬가지로 호환 가능한 형식의 적격 또는 비적격 버전에 대한 포인터는 동일한 표현 및 정렬 요건을 가져야 한다.구조물 형식에 대한 모든 포인터는 서로 동일한 표현 및 정렬 요건을 가져야 한다.조합 형식에 대한 모든 포인터는 서로 동일한 표현 및 정렬 요건을 가져야 한다.다른 유형에 대한 포인터는 표현 또는 정렬 요건이 같을 필요는 없습니다.

39) 동일한 표현 및 정렬 요건은 함수에 대한 인수, 함수의 반환 값 및 조합의 구성원과 같은 상호 호환성을 암시하는 것을 의미한다.

(C11은 제6.2.5절, 제28절 및 각주48절에서도 동일하게 기술되어 있습니다).

그러므로, 포인터가 가리키는 구조가 다른 정렬 요건을 가질 수 있더라도 구조물에 대한 모든 포인터는 서로 같은 크기여야 하며 동일한 정렬 요건을 공유해야 한다.노조도 마찬가지입니다.문자 포인터와 보이드 포인터는 크기 및 정렬 요구 사항이 같아야 합니다.「 」의 에 대한 .int)unsigned int ★★★★★★★★★★★★★★★★★」signed int은 서로 타입에서도 의 크기와 정렬 요건은 서로 동일해야 합니다.하다으로 C라고 있지 .sizeof(int *) == sizeof(void *)

C 표준에서는 함수 포인터가 오브젝트 포인터와 같은 크기일 필요는 없습니다.이것은 DOS와 같은 시스템에서 다른 메모리 모델을 파손하지 않기 위해 필요했습니다.여기에는 16비트 데이터 포인터가 있지만 32비트 함수 포인터가 있거나 그 반대일 수 있습니다.이것이 C 표준이 함수 포인터를 오브젝트 포인터로 변환할 수 있는 것을 요구하지 않는 이유이다.

다행히 (POSIX를 타깃으로 하는 프로그래머의 경우) POSIX는 침해에 개입하여 함수 포인터와 데이터 포인터의 크기를 동일하게 하도록 명령합니다.

§ 2.12.3 포인터 타입

모든 기능 포인터 유형은 보이드에 대한 형식 포인터와 동일한 표현을 가져야 한다.의 「」로의 void *이치노 a.void *이러한 변환으로 인한 값은 정보의 손실 없이 명시적 캐스트를 사용하여 원래 함수 포인터 유형으로 다시 변환할 수 있습니다.

주의: ISO C 규격에서는 이것이 필요하지 않지만 POSIX 준거를 위해서는 필요합니다.

래서, 실 so to to to에 명시적인 이 있는 것 요.void * to 、 음음 、 음 are 、 are are such such such such such such are such are are such are such are are such such are 、와 같은 때 높이는 권장됩니다.printf()POSIX 시스템에서는 함수 포인터를 보이드 포인터에 던져 인쇄하는 것이 안전합니다.에서는 그렇게하다고는 할 수 이외의 안전하다고는 할 수 없습니다.void *깁스 없이

p는 포인터를 인쇄하기 위한 변환 지정자입니다.이걸 쓰세요.

int a = 42;

printf("%p\n", (void *) &a);

되지 않은 이며, 에는 '배역하다', '배역하다', '배역하다'가 사용된다는 .p변환 지정자는 구현 정의 방식으로 수행됩니다.

%p " " "여유", "여유", "여유", "여유", "여유", "를 특정 수 되지 않기 되지 않은 을 얻을 수 를 들어, 예를 들면, 「정수」는 「정수」로 되어 있습니다).%u기대하다unsigned int하지만 만약void*크기 또는 정렬 요건이 다르다unsigned int?)

*) [조나단의 정답 보기]다른 방법으로는%p, 에서 포인터 고유의 매크로를 사용할 수 있습니다.<inttypes.h>C99에 추가되었습니다.

모든 객체 포인터는 암묵적으로 다음과 같이 변환할 수 있습니다.void*C에서는 포인터를 바리안트 인수로 전달하려면 명시적으로 캐스트해야 합니다(임의 객체 포인터는 변환만 가능하며 void 포인터와 동일하지는 않습니다).

printf("x lives at %p.\n", (void*)&x);

다른 (매우 좋은) 답변에 대한 대안으로 다음을 선택할 수 있습니다.uintptr_t또는intptr_t(출처:stdint.h/inttypes.h대응하는 정수 변환 지정자를 사용합니다.이것에 의해, 포인터의 포맷이 보다 유연해집니다만, 엄밀하게 말하면, 이러한 typedef를 제공하기 위해서 실장이 필요한 것은 아닙니다.

사용할 수 있습니다.%x또는%X또는%p; 모두 정답입니다.

  • 사용하시는 경우%x주소는 소문자로 표시됩니다.다음은 예를 제시하겠습니다.a3bfbc4
  • 사용하시는 경우%X주소는 대문자로 지정됩니다.다음은 예를 제시하겠습니다.A3BFBC4

둘 다 맞습니다.

사용하시는 경우%x또는%X주소를 위해 6개의 위치를 고려하고 있습니다. 그리고 만약 당신이%p주소를 위해 8개의 위치를 고려하고 있습니다예를 들어 다음과 같습니다.

언급URL : https://stackoverflow.com/questions/9053658/correct-format-specifier-to-print-pointer-or-address

반응형