0으로 채워진 포인터를 표시하기 위해 printf를 사용하는 올바른 방법은 무엇입니까?
C에서는 printf를 사용하여 포인터를 표시하고 올바르게 정렬할 수 있도록 0으로 패딩하고 싶습니다.
적절한 방법은 다음과 같습니다.
printf(%)%016p", printf (%016p),
이것은 동작합니다만, 이 gcc는 다음과 같은 메시지로 불만을 제기합니다.
경고: '0' 플래그가 '%p' gnu_printf 형식과 함께 사용되었습니다.
구글에서 검색해 봤는데 다음 스레드는 같은 주제에 있지만 해결 방법이 없습니다.
http://gcc.gnu.org/ml/gcc-bugs/2003-05/msg00484.html
읽어보니 gcc가 불만을 제기하는 이유는 제가 제시한 구문이 C99에 정의되어 있지 않기 때문인 것 같습니다.하지만 표준 승인된 방법으로 동일한 작업을 수행할 수 있는 다른 방법을 찾을 수 없을 것 같습니다.
여기 두 가지 질문이 있습니다.
- 이 동작은 C99 규격에 의해 정의되지 않은 것으로 알고 있습니까?
- 그렇다면 표준으로 승인된 휴대용 방법이 있습니까?
#include <inttypes.h>
#include <stdint.h>
printf("%016" PRIxPTR "\n", (uintptr_t)ptr);
그러나 구현 정의 방식으로는 포인터가 인쇄되지 않습니다(예:DEAD:BEEF
8086 세그먼트 모드).
이 답변은 https://stackoverflow.com/a/1255185/1905491에서 이전에 제시한 답변과 비슷하지만 가능한 폭도 고려합니다(https://stackoverflow.com/a/6904396/1905491에서 설명한 바와 같이, 답변이 아래에 렌더링될 때까지 몰랐습니다).다음 슬라이드는 sane*머신에서 포인터를 8개의 0-pass 16진수로 인쇄합니다.이러한 포인터는 32비트(64b에서는 16비트, 16b 시스템에서는 4비트)로 나타낼 수 있습니다.
#include <inttypes.h>
#define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))
printf("0x%0*" PRIxPTR, PRIxPTR_WIDTH, (uintptr_t)pointer);
아스타리스크 문자의 사용에 주의해 주세요.다음 인수는 C99(아마도 이전?)이지만, "야생"에서는 거의 볼 수 없습니다.이 방법은 이 기능을 사용하는 것보다 훨씬 우수합니다.p
변환은 구현 정의되어 있기 때문입니다.
* 표준에서는uintptr_t
최소값보다 클 수 있지만 최소값을 사용하지 않는 구현은 없을 것입니다.
용도:
#include <inttypes.h>
printf("0x%016" PRIXPTR "\n", (uintptr_t) pointer);
또는 해당 헤더의 다른 배리언트 매크로를 사용합니다.
또, 일부의 실장은,printf()
'를 인쇄하다0x
'는 포인터 앞에 표시됩니다.다른 것은 그렇지 않습니다(둘 다 C 표준에 따라 정확합니다).
포인터 값을 인쇄하는 유일한 휴대용 방법은"%p"
구현 정의 출력을 생성하는 지정자(변환 중)uintptr_t
및 사용PRIxPTR
효과가 있을 것 같습니다만, (a)uintptr_t
는 C99에서 도입되었기 때문에 일부 컴파일러는 지원하지 않을 수 있습니다.또 (b) C99에서도 존재하지 않을 수 있습니다(가능한 모든 포인터 값을 저장할 수 있을 만큼 큰 정수 타입은 존재하지 않을 수 있습니다).
사용방법"%p"
와 함께sprintf()
(또는snprintf()
(있는 경우)를 문자열로 인쇄하고 문자열 패딩을 선행 공백으로 인쇄합니다.
한 가지 문제는 에 의해 생성되는 문자열의 최대 길이를 결정할 수 있는 좋은 방법이 없다는 것입니다."%p"
.
이것은 확실히 불편합니다(물론 함수로 포장할 수 있습니다).100% 휴대성이 필요 없는 경우, 저는 포인터를 던지기 위해 시스템을 사용해 본 적이 없습니다.unsigned long
결과를 인쇄합니다."0x%16lx"
안 먹혔어[업데이트: 있습니다.64비트 Windows에는 64비트 포인터와 32비트가 있습니다.unsigned long
.] (또는"0x%*lx"
너비를 계산하면 아마 다음과 같은 것이 될 것입니다.sizeof (void*) * 2
정말 편집증적인 경우, 다음과 같은 시스템을 설명할 수 있습니다.CHAR_BIT > 8
바이트당 16진수를 2자리 이상 얻을 수 있습니다.)
긴 글씨로 포인터를 던지면 쉽게 풀 수 있습니다.문제는 포인터가 긴 안쪽에 들어갈 수 있고 포인터가 16자(64비트)로 표시될 수 있다고 가정하기 때문에 모든 플랫폼에서는 작동하지 않는다는 것입니다.단, 이는 대부분의 플랫폼에서 해당됩니다.
그러면 다음과 같이 됩니다.
printf("%016lx", (unsigned long) ptr);
링크에서 이미 알 수 있듯이 동작은 정의되어 있지 않습니다.%p 자체는 작업 중인 플랫폼에 따라 다르기 때문에 휴대용 방법은 없는 것 같습니다.물론 포인터를 int에 던져 16진수로 표시할 수도 있습니다.
printf("0x%016lx", (unsigned long)ptr);
아마 이것은 흥미로울 것입니다(32비트 Windows 머신에서 mingw를 사용).
rjeq@RJEQXPD /u
$ cat test.c
#include <stdio.h>
int main()
{
char c;
printf("p: %016p\n", &c);
printf("x: %016llx\n", (unsigned long long) (unsigned long) &c);
return 0;
}
rjeq@RJEQXPD /u
$ gcc -Wall -o test test.c
test.c: In function `main':
test.c:7: warning: `0' flag used with `%p' printf format
rjeq@RJEQXPD /u
$ ./test.exe
p: 0022FF77
x: 000000000022ff77
보시는 바와 같이 %p 버전은 포인터 크기까지 0으로 채워진 후 지정된 크기로 공백이 생기지만 %x 및 캐스트(캐스트 및 형식 지정자는 매우 이동 불가능)를 사용하는 경우 0만 사용합니다.
포인터가 "0x" 접두사로 인쇄되면 "%018p"을 대체하여 보정해야 합니다.
저는 보통 포인터를 표시할 때 %x를 사용합니다.64비트 시스템에서는 사용할 수 없지만 32비트 시스템에서는 정상적으로 작동합니다.
포인터 표현은 정확하게 휴대할 수 없기 때문에 휴대용 솔루션에 대한 답변이 있는지 알고 싶습니다.
언급URL : https://stackoverflow.com/questions/1255099/whats-the-proper-use-of-printf-to-display-pointers-padded-with-0s
'programing' 카테고리의 다른 글
Vuex에서 모듈을 가져오고 재설정하는 방법 (0) | 2022.07.03 |
---|---|
경로가 파일 또는 폴더를 나타내는지 확인합니다. (0) | 2022.07.02 |
비트 연산자를 사용하여 정수가 짝수인지 홀수인지 확인하는 방법 (0) | 2022.07.02 |
Vue2 - Vanilla ONKEYPRESS 함수를 메서드로 변환 (0) | 2022.07.02 |
VueJS 줄바꿈 문자가 올바르게 렌더링되지 않음 (0) | 2022.07.02 |